History

geneve: support setting IPv6 flow label

This work adds support for setting the IPv6 flow label for geneve per device and through collect metadata (ip_tunnel_key) frontends. Also here, the geneve dst cache does not need any special considerations, for the cases where caches can be used, the label is static per cache.

Daniel Borkmann committed 10 years ago

Commit 8eb3b991 parent e7f70af2 files · +28 −8Browse files

Unified · Split

2 files
  1. drivers/net/geneve.c +27 −8
  2. include/uapi/linux/if_link.h +1 −0
drivers/net/geneve.c+27−8
@@ -68,6 +68,7 @@ struct geneve_dev { · 67 unmodified lines
68 u8 tos; /* TOS override */68 u8 tos; /* TOS override */
69 union geneve_addr remote; /* IP address for link partner */69 union geneve_addr remote; /* IP address for link partner */
70 struct list_head next; /* geneve's per namespace list */70 struct list_head next; /* geneve's per namespace list */
71 __be32 label; /* IPv6 flowlabel override */
71 __be16 dst_port;72 __be16 dst_port;
72 bool collect_md;73 bool collect_md;
73 struct gro_cells gro_cells;74 struct gro_cells gro_cells;
@@ -846,6 +847,7 @@ static struct dst_entry *geneve_get_v6_dst(struct sk_buff *skb, · 772 unmodified lines
846 fl6->daddr = info->key.u.ipv6.dst;847 fl6->daddr = info->key.u.ipv6.dst;
847 fl6->saddr = info->key.u.ipv6.src;848 fl6->saddr = info->key.u.ipv6.src;
848 fl6->flowi6_tos = RT_TOS(info->key.tos);849 fl6->flowi6_tos = RT_TOS(info->key.tos);
850 fl6->flowlabel = info->key.label;
849 dst_cache = &info->dst_cache;851 dst_cache = &info->dst_cache;
850 } else {852 } else {
851 prio = geneve->tos;853 prio = geneve->tos;
@@ -857,6 +859,7 @@ static struct dst_entry *geneve_get_v6_dst(struct sk_buff *skb, · 5 unmodified lines
857 }859 }
858 860
859 fl6->flowi6_tos = RT_TOS(prio);861 fl6->flowi6_tos = RT_TOS(prio);
862 fl6->flowlabel = geneve->label;
860 fl6->daddr = geneve->remote.sin6.sin6_addr;863 fl6->daddr = geneve->remote.sin6.sin6_addr;
861 dst_cache = &geneve->dst_cache;864 dst_cache = &geneve->dst_cache;
862 }865 }
@@ -998,6 +1001,7 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev, · 135 unmodified lines
998 struct flowi6 fl6;1001 struct flowi6 fl6;
999 __u8 prio, ttl;1002 __u8 prio, ttl;
1000 __be16 sport;1003 __be16 sport;
1004 __be32 label;
1001 bool xnet = !net_eq(geneve->net, dev_net(geneve->dev));1005 bool xnet = !net_eq(geneve->net, dev_net(geneve->dev));
1002 u32 flags = geneve->flags;1006 u32 flags = geneve->flags;
1003 1007
@@ -1041,6 +1045,7 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev, · 37 unmodified lines
1041 1045
1042 prio = ip_tunnel_ecn_encap(key->tos, iip, skb);1046 prio = ip_tunnel_ecn_encap(key->tos, iip, skb);
1043 ttl = key->ttl;1047 ttl = key->ttl;
1048 label = info->key.label;
1044 } else {1049 } else {
1045 err = geneve6_build_skb(dst, skb, 0, geneve->vni,1050 err = geneve6_build_skb(dst, skb, 0, geneve->vni,
1046 0, NULL, flags, xnet);1051 0, NULL, flags, xnet);
@@ -1052,9 +1057,11 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev, · 5 unmodified lines
1052 if (!ttl && ipv6_addr_is_multicast(&fl6.daddr))1057 if (!ttl && ipv6_addr_is_multicast(&fl6.daddr))
1053 ttl = 1;1058 ttl = 1;
1054 ttl = ttl ? : ip6_dst_hoplimit(dst);1059 ttl = ttl ? : ip6_dst_hoplimit(dst);
1060 label = geneve->label;
1055 }1061 }
1062
1056 udp_tunnel6_xmit_skb(dst, gs6->sock->sk, skb, dev,1063 udp_tunnel6_xmit_skb(dst, gs6->sock->sk, skb, dev,
1057 &fl6.saddr, &fl6.daddr, prio, ttl, 0,1064 &fl6.saddr, &fl6.daddr, prio, ttl, label,
1058 sport, geneve->dst_port,1065 sport, geneve->dst_port,
1059 !!(flags & GENEVE_F_UDP_ZERO_CSUM6_TX));1066 !!(flags & GENEVE_F_UDP_ZERO_CSUM6_TX));
1060 return NETDEV_TX_OK;1067 return NETDEV_TX_OK;
@@ -1238,6 +1245,7 @@ static const struct nla_policy geneve_policy[IFLA_GENEVE_MAX + 1] = { · 177 unmodified lines
1238 [IFLA_GENEVE_REMOTE6] = { .len = sizeof(struct in6_addr) },1245 [IFLA_GENEVE_REMOTE6] = { .len = sizeof(struct in6_addr) },
1239 [IFLA_GENEVE_TTL] = { .type = NLA_U8 },1246 [IFLA_GENEVE_TTL] = { .type = NLA_U8 },
1240 [IFLA_GENEVE_TOS] = { .type = NLA_U8 },1247 [IFLA_GENEVE_TOS] = { .type = NLA_U8 },
1248 [IFLA_GENEVE_LABEL] = { .type = NLA_U32 },
1241 [IFLA_GENEVE_PORT] = { .type = NLA_U16 },1249 [IFLA_GENEVE_PORT] = { .type = NLA_U16 },
1242 [IFLA_GENEVE_COLLECT_METADATA] = { .type = NLA_FLAG },1250 [IFLA_GENEVE_COLLECT_METADATA] = { .type = NLA_FLAG },
1243 [IFLA_GENEVE_UDP_CSUM] = { .type = NLA_U8 },1251 [IFLA_GENEVE_UDP_CSUM] = { .type = NLA_U8 },
@@ -1295,8 +1303,8 @@ static struct geneve_dev *geneve_find_dev(struct geneve_net *gn, · 51 unmodified lines
1295 1303
1296static int geneve_configure(struct net *net, struct net_device *dev,1304static int geneve_configure(struct net *net, struct net_device *dev,
1297 union geneve_addr *remote,1305 union geneve_addr *remote,
1298 __u32 vni, __u8 ttl, __u8 tos, __be16 dst_port,1306 __u32 vni, __u8 ttl, __u8 tos, __be32 label,
1299 bool metadata, u32 flags)1307 __be16 dst_port, bool metadata, u32 flags)
1300{1308{
1301 struct geneve_net *gn = net_generic(net, geneve_net_id);1309 struct geneve_net *gn = net_generic(net, geneve_net_id);
1302 struct geneve_dev *t, *geneve = netdev_priv(dev);1310 struct geneve_dev *t, *geneve = netdev_priv(dev);
@@ -1306,7 +1314,7 @@ static int geneve_configure(struct net *net, struct net_device *dev, · 3 unmodified lines
1306 if (!remote)1314 if (!remote)
1307 return -EINVAL;1315 return -EINVAL;
1308 if (metadata &&1316 if (metadata &&
1309 (remote->sa.sa_family != AF_UNSPEC || vni || tos || ttl))1317 (remote->sa.sa_family != AF_UNSPEC || vni || tos || ttl || label))
1310 return -EINVAL;1318 return -EINVAL;
1311 1319
1312 geneve->net = net;1320 geneve->net = net;
@@ -1321,10 +1329,14 @@ static int geneve_configure(struct net *net, struct net_device *dev, · 8 unmodified lines
1321 (remote->sa.sa_family == AF_INET6 &&1329 (remote->sa.sa_family == AF_INET6 &&
1322 ipv6_addr_is_multicast(&remote->sin6.sin6_addr)))1330 ipv6_addr_is_multicast(&remote->sin6.sin6_addr)))
1323 return -EINVAL;1331 return -EINVAL;
1332 if (label && remote->sa.sa_family != AF_INET6)
1333 return -EINVAL;
1334
1324 geneve->remote = *remote;1335 geneve->remote = *remote;
1325 1336
1326 geneve->ttl = ttl;1337 geneve->ttl = ttl;
1327 geneve->tos = tos;1338 geneve->tos = tos;
1339 geneve->label = label;
1328 geneve->dst_port = dst_port;1340 geneve->dst_port = dst_port;
1329 geneve->collect_md = metadata;1341 geneve->collect_md = metadata;
1330 geneve->flags = flags;1342 geneve->flags = flags;
@@ -1367,6 +1379,7 @@ static int geneve_newlink(struct net *net, struct net_device *dev, · 36 unmodified lines
1367 __u8 ttl = 0, tos = 0;1379 __u8 ttl = 0, tos = 0;
1368 bool metadata = false;1380 bool metadata = false;
1369 union geneve_addr remote = geneve_remote_unspec;1381 union geneve_addr remote = geneve_remote_unspec;
1382 __be32 label = 0;
1370 __u32 vni = 0;1383 __u32 vni = 0;
1371 u32 flags = 0;1384 u32 flags = 0;
1372 1385
@@ -1403,6 +1416,10 @@ static int geneve_newlink(struct net *net, struct net_device *dev, · 30 unmodified lines
1403 if (data[IFLA_GENEVE_TOS])1416 if (data[IFLA_GENEVE_TOS])
1404 tos = nla_get_u8(data[IFLA_GENEVE_TOS]);1417 tos = nla_get_u8(data[IFLA_GENEVE_TOS]);
1405 1418
1419 if (data[IFLA_GENEVE_LABEL])
1420 label = nla_get_be32(data[IFLA_GENEVE_LABEL]) &
1421 IPV6_FLOWLABEL_MASK;
1422
1406 if (data[IFLA_GENEVE_PORT])1423 if (data[IFLA_GENEVE_PORT])
1407 dst_port = nla_get_be16(data[IFLA_GENEVE_PORT]);1424 dst_port = nla_get_be16(data[IFLA_GENEVE_PORT]);
1408 1425
@@ -1421,8 +1438,8 @@ static int geneve_newlink(struct net *net, struct net_device *dev, · 12 unmodified lines
1421 nla_get_u8(data[IFLA_GENEVE_UDP_ZERO_CSUM6_RX]))1438 nla_get_u8(data[IFLA_GENEVE_UDP_ZERO_CSUM6_RX]))
1422 flags |= GENEVE_F_UDP_ZERO_CSUM6_RX;1439 flags |= GENEVE_F_UDP_ZERO_CSUM6_RX;
1423 1440
1424 return geneve_configure(net, dev, &remote, vni, ttl, tos, dst_port,1441 return geneve_configure(net, dev, &remote, vni, ttl, tos, label,
1425 metadata, flags);1442 dst_port, metadata, flags);
1426}1443}
1427 1444
1428static void geneve_dellink(struct net_device *dev, struct list_head *head)1445static void geneve_dellink(struct net_device *dev, struct list_head *head)
@@ -1439,6 +1456,7 @@ static size_t geneve_get_size(const struct net_device *dev) · 10 unmodified lines
1439 nla_total_size(sizeof(struct in6_addr)) + /* IFLA_GENEVE_REMOTE{6} */1456 nla_total_size(sizeof(struct in6_addr)) + /* IFLA_GENEVE_REMOTE{6} */
1440 nla_total_size(sizeof(__u8)) + /* IFLA_GENEVE_TTL */1457 nla_total_size(sizeof(__u8)) + /* IFLA_GENEVE_TTL */
1441 nla_total_size(sizeof(__u8)) + /* IFLA_GENEVE_TOS */1458 nla_total_size(sizeof(__u8)) + /* IFLA_GENEVE_TOS */
1459 nla_total_size(sizeof(__be32)) + /* IFLA_GENEVE_LABEL */
1442 nla_total_size(sizeof(__be16)) + /* IFLA_GENEVE_PORT */1460 nla_total_size(sizeof(__be16)) + /* IFLA_GENEVE_PORT */
1443 nla_total_size(0) + /* IFLA_GENEVE_COLLECT_METADATA */1461 nla_total_size(0) + /* IFLA_GENEVE_COLLECT_METADATA */
1444 nla_total_size(sizeof(__u8)) + /* IFLA_GENEVE_UDP_CSUM */1462 nla_total_size(sizeof(__u8)) + /* IFLA_GENEVE_UDP_CSUM */
@@ -1469,7 +1487,8 @@ static int geneve_fill_info(struct sk_buff *skb, const struct net_device *dev) · 24 unmodified lines
1469 }1487 }
1470 1488
1471 if (nla_put_u8(skb, IFLA_GENEVE_TTL, geneve->ttl) ||1489 if (nla_put_u8(skb, IFLA_GENEVE_TTL, geneve->ttl) ||
1472 nla_put_u8(skb, IFLA_GENEVE_TOS, geneve->tos))1490 nla_put_u8(skb, IFLA_GENEVE_TOS, geneve->tos) ||
1491 nla_put_be32(skb, IFLA_GENEVE_LABEL, geneve->label))
1473 goto nla_put_failure;1492 goto nla_put_failure;
1474 1493
1475 if (nla_put_be16(skb, IFLA_GENEVE_PORT, geneve->dst_port))1494 if (nla_put_be16(skb, IFLA_GENEVE_PORT, geneve->dst_port))
@@ -1521,7 +1540,7 @@ struct net_device *geneve_dev_create_fb(struct net *net, const char *name, · 45 unmodified lines
1521 return dev;1540 return dev;
1522 1541
1523 err = geneve_configure(net, dev, &geneve_remote_unspec,1542 err = geneve_configure(net, dev, &geneve_remote_unspec,
1524 0, 0, 0, htons(dst_port), true,1543 0, 0, 0, 0, htons(dst_port), true,
1525 GENEVE_F_UDP_ZERO_CSUM6_RX);1544 GENEVE_F_UDP_ZERO_CSUM6_RX);
1526 if (err)1545 if (err)
1527 goto err;1546 goto err;
include/uapi/linux/if_link.h+1−0
@@ -479,6 +479,7 @@ enum { · 478 unmodified lines
479 IFLA_GENEVE_UDP_CSUM,479 IFLA_GENEVE_UDP_CSUM,
480 IFLA_GENEVE_UDP_ZERO_CSUM6_TX,480 IFLA_GENEVE_UDP_ZERO_CSUM6_TX,
481 IFLA_GENEVE_UDP_ZERO_CSUM6_RX,481 IFLA_GENEVE_UDP_ZERO_CSUM6_RX,
482 IFLA_GENEVE_LABEL,
482 __IFLA_GENEVE_MAX483 __IFLA_GENEVE_MAX
483};484};
484#define IFLA_GENEVE_MAX (__IFLA_GENEVE_MAX - 1)485#define IFLA_GENEVE_MAX (__IFLA_GENEVE_MAX - 1)

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t