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
6868 u8 tos; /* TOS override */
6969 union geneve_addr remote; /* IP address for link partner */
7070 struct list_head next; /* geneve's per namespace list */
71+ __be32 label; /* IPv6 flowlabel override */
7172 __be16 dst_port;
7273 bool collect_md;
7374 struct gro_cells gro_cells;
@@ -846,6 +847,7 @@ static struct dst_entry *geneve_get_v6_dst(struct sk_buff *skb, · 772 unmodified lines
846847 fl6->daddr = info->key.u.ipv6.dst;
847848 fl6->saddr = info->key.u.ipv6.src;
848849 fl6->flowi6_tos = RT_TOS(info->key.tos);
850+ fl6->flowlabel = info->key.label;
849851 dst_cache = &info->dst_cache;
850852 } else {
851853 prio = geneve->tos;
@@ -857,6 +859,7 @@ static struct dst_entry *geneve_get_v6_dst(struct sk_buff *skb, · 5 unmodified lines
857859 }
858860
859861 fl6->flowi6_tos = RT_TOS(prio);
862+ fl6->flowlabel = geneve->label;
860863 fl6->daddr = geneve->remote.sin6.sin6_addr;
861864 dst_cache = &geneve->dst_cache;
862865 }
@@ -998,6 +1001,7 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev, · 135 unmodified lines
9981001 struct flowi6 fl6;
9991002 __u8 prio, ttl;
10001003 __be16 sport;
1004+ __be32 label;
10011005 bool xnet = !net_eq(geneve->net, dev_net(geneve->dev));
10021006 u32 flags = geneve->flags;
10031007
@@ -1041,6 +1045,7 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev, · 37 unmodified lines
10411045
10421046 prio = ip_tunnel_ecn_encap(key->tos, iip, skb);
10431047 ttl = key->ttl;
1048+ label = info->key.label;
10441049 } else {
10451050 err = geneve6_build_skb(dst, skb, 0, geneve->vni,
10461051 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
10521057 if (!ttl && ipv6_addr_is_multicast(&fl6.daddr))
10531058 ttl = 1;
10541059 ttl = ttl ? : ip6_dst_hoplimit(dst);
1060+ label = geneve->label;
10551061 }
1062+
10561063 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,
10581065 sport, geneve->dst_port,
10591066 !!(flags & GENEVE_F_UDP_ZERO_CSUM6_TX));
10601067 return NETDEV_TX_OK;
@@ -1238,6 +1245,7 @@ static const struct nla_policy geneve_policy[IFLA_GENEVE_MAX + 1] = { · 177 unmodified lines
12381245 [IFLA_GENEVE_REMOTE6] = { .len = sizeof(struct in6_addr) },
12391246 [IFLA_GENEVE_TTL] = { .type = NLA_U8 },
12401247 [IFLA_GENEVE_TOS] = { .type = NLA_U8 },
1248+ [IFLA_GENEVE_LABEL] = { .type = NLA_U32 },
12411249 [IFLA_GENEVE_PORT] = { .type = NLA_U16 },
12421250 [IFLA_GENEVE_COLLECT_METADATA] = { .type = NLA_FLAG },
12431251 [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
12951303
12961304 static int geneve_configure(struct net *net, struct net_device *dev,
12971305 union geneve_addr *remote,
1298− __u32 vni, __u8 ttl, __u8 tos, __be16 dst_port,
1299− bool metadata, u32 flags)
1306+ __u32 vni, __u8 ttl, __u8 tos, __be32 label,
1307+ __be16 dst_port, bool metadata, u32 flags)
13001308 {
13011309 struct geneve_net *gn = net_generic(net, geneve_net_id);
13021310 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
13061314 if (!remote)
13071315 return -EINVAL;
13081316 if (metadata &&
1309− (remote->sa.sa_family != AF_UNSPEC || vni || tos || ttl))
1317+ (remote->sa.sa_family != AF_UNSPEC || vni || tos || ttl || label))
13101318 return -EINVAL;
13111319
13121320 geneve->net = net;
@@ -1321,10 +1329,14 @@ static int geneve_configure(struct net *net, struct net_device *dev, · 8 unmodified lines
13211329 (remote->sa.sa_family == AF_INET6 &&
13221330 ipv6_addr_is_multicast(&remote->sin6.sin6_addr)))
13231331 return -EINVAL;
1332+ if (label && remote->sa.sa_family != AF_INET6)
1333+ return -EINVAL;
1334+
13241335 geneve->remote = *remote;
13251336
13261337 geneve->ttl = ttl;
13271338 geneve->tos = tos;
1339+ geneve->label = label;
13281340 geneve->dst_port = dst_port;
13291341 geneve->collect_md = metadata;
13301342 geneve->flags = flags;
@@ -1367,6 +1379,7 @@ static int geneve_newlink(struct net *net, struct net_device *dev, · 36 unmodified lines
13671379 __u8 ttl = 0, tos = 0;
13681380 bool metadata = false;
13691381 union geneve_addr remote = geneve_remote_unspec;
1382+ __be32 label = 0;
13701383 __u32 vni = 0;
13711384 u32 flags = 0;
13721385
@@ -1403,6 +1416,10 @@ static int geneve_newlink(struct net *net, struct net_device *dev, · 30 unmodified lines
14031416 if (data[IFLA_GENEVE_TOS])
14041417 tos = nla_get_u8(data[IFLA_GENEVE_TOS]);
14051418
1419+ if (data[IFLA_GENEVE_LABEL])
1420+ label = nla_get_be32(data[IFLA_GENEVE_LABEL]) &
1421+ IPV6_FLOWLABEL_MASK;
1422+
14061423 if (data[IFLA_GENEVE_PORT])
14071424 dst_port = nla_get_be16(data[IFLA_GENEVE_PORT]);
14081425
@@ -1421,8 +1438,8 @@ static int geneve_newlink(struct net *net, struct net_device *dev, · 12 unmodified lines
14211438 nla_get_u8(data[IFLA_GENEVE_UDP_ZERO_CSUM6_RX]))
14221439 flags |= GENEVE_F_UDP_ZERO_CSUM6_RX;
14231440
1424− return geneve_configure(net, dev, &remote, vni, ttl, tos, dst_port,
1425− metadata, flags);
1441+ return geneve_configure(net, dev, &remote, vni, ttl, tos, label,
1442+ dst_port, metadata, flags);
14261443 }
14271444
14281445 static 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
14391456 nla_total_size(sizeof(struct in6_addr)) + /* IFLA_GENEVE_REMOTE{6} */
14401457 nla_total_size(sizeof(__u8)) + /* IFLA_GENEVE_TTL */
14411458 nla_total_size(sizeof(__u8)) + /* IFLA_GENEVE_TOS */
1459+ nla_total_size(sizeof(__be32)) + /* IFLA_GENEVE_LABEL */
14421460 nla_total_size(sizeof(__be16)) + /* IFLA_GENEVE_PORT */
14431461 nla_total_size(0) + /* IFLA_GENEVE_COLLECT_METADATA */
14441462 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
14691487 }
14701488
14711489 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))
14731492 goto nla_put_failure;
14741493
14751494 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
15211540 return dev;
15221541
15231542 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,
15251544 GENEVE_F_UDP_ZERO_CSUM6_RX);
15261545 if (err)
15271546 goto err;
include/uapi/linux/if_link.h+1−0
@@ -479,6 +479,7 @@ enum { · 478 unmodified lines
479479 IFLA_GENEVE_UDP_CSUM,
480480 IFLA_GENEVE_UDP_ZERO_CSUM6_TX,
481481 IFLA_GENEVE_UDP_ZERO_CSUM6_RX,
482+ IFLA_GENEVE_LABEL,
482483 __IFLA_GENEVE_MAX
483484 };
484485 #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