History

net: geneve: support IPv4/IPv6 as inner protocol

This patch adds support for encapsulating IPv4/IPv6 within GENEVE. In order to use this, a new IFLA_GENEVE_INNER_PROTO_INHERIT flag needs to be provided at device creation. This property cannot be changed for the time being. In case IP traffic is received on a non-tun device the drop count is increased.

Eyal Birger committed 4 years ago

Commit 435fe1c1 parent 82192c42 files · +64 −19Browse files

Unified · Split

2 files
  1. drivers/net/geneve.c +63 −19
  2. include/uapi/linux/if_link.h +1 −0
drivers/net/geneve.c+63−19
@@ -56,6 +56,7 @@ struct geneve_config { · 55 unmodified lines
5656 bool use_udp6_rx_checksums;
5757 bool ttl_inherit;
5858 enum ifla_geneve_df df;
59+ bool inner_proto_inherit;
5960 };
6061
6162 /* Pseudo network device */
@@ -251,17 +252,24 @@ static void geneve_rx(struct geneve_dev *geneve, struct geneve_sock *gs, · 189 unmodified lines
251252 }
252253 }
253254
254− skb_reset_mac_header(skb);
255− skb->protocol = eth_type_trans(skb, geneve->dev);
256− skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
257−
258255 if (tun_dst)
259256 skb_dst_set(skb, &tun_dst->dst);
260257
261− /* Ignore packet loops (and multicast echo) */
262− if (ether_addr_equal(eth_hdr(skb)->h_source, geneve->dev->dev_addr)) {
263− geneve->dev->stats.rx_errors++;
264− goto drop;
258+ if (gnvh->proto_type == htons(ETH_P_TEB)) {
259+ skb_reset_mac_header(skb);
260+ skb->protocol = eth_type_trans(skb, geneve->dev);
261+ skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
262+
263+ /* Ignore packet loops (and multicast echo) */
264+ if (ether_addr_equal(eth_hdr(skb)->h_source,
265+ geneve->dev->dev_addr)) {
266+ geneve->dev->stats.rx_errors++;
267+ goto drop;
268+ }
269+ } else {
270+ skb_reset_mac_header(skb);
271+ skb->dev = geneve->dev;
272+ skb->pkt_type = PACKET_HOST;
265273 }
266274
267275 oiph = skb_network_header(skb);
@@ -345,6 +353,7 @@ static int geneve_udp_encap_recv(struct sock *sk, struct sk_buff *skb) · 77 unmodified lines
345353 struct genevehdr *geneveh;
346354 struct geneve_dev *geneve;
347355 struct geneve_sock *gs;
356+ __be16 inner_proto;
348357 int opts_len;
349358
350359 /* Need UDP and Geneve header to be present */
@@ -356,7 +365,11 @@ static int geneve_udp_encap_recv(struct sock *sk, struct sk_buff *skb) · 5 unmodified lines
356365 if (unlikely(geneveh->ver != GENEVE_VER))
357366 goto drop;
358367
359− if (unlikely(geneveh->proto_type != htons(ETH_P_TEB)))
368+ inner_proto = geneveh->proto_type;
369+
370+ if (unlikely((inner_proto != htons(ETH_P_TEB) &&
371+ inner_proto != htons(ETH_P_IP) &&
372+ inner_proto != htons(ETH_P_IPV6))))
360373 goto drop;
361374
362375 gs = rcu_dereference_sk_user_data(sk);
@@ -367,9 +380,14 @@ static int geneve_udp_encap_recv(struct sock *sk, struct sk_buff *skb) · 4 unmodified lines
367380 if (!geneve)
368381 goto drop;
369382
383+ if (unlikely((!geneve->cfg.inner_proto_inherit &&
384+ inner_proto != htons(ETH_P_TEB)))) {
385+ geneve->dev->stats.rx_dropped++;
386+ goto drop;
387+ }
388+
370389 opts_len = geneveh->opt_len * 4;
371− if (iptunnel_pull_header(skb, GENEVE_BASE_HLEN + opts_len,
372− htons(ETH_P_TEB),
390+ if (iptunnel_pull_header(skb, GENEVE_BASE_HLEN + opts_len, inner_proto,
373391 !net_eq(geneve->net, dev_net(geneve->dev)))) {
374392 geneve->dev->stats.rx_dropped++;
375393 goto drop;
@@ -717,7 +735,8 @@ static int geneve_stop(struct net_device *dev) · 341 unmodified lines
717735 }
718736
719737 static void geneve_build_header(struct genevehdr *geneveh,
720− const struct ip_tunnel_info *info)
738+ const struct ip_tunnel_info *info,
739+ __be16 inner_proto)
721740 {
722741 geneveh->ver = GENEVE_VER;
723742 geneveh->opt_len = info->options_len / 4;
@@ -725,7 +744,7 @@ static void geneve_build_header(struct genevehdr *geneveh, · 1 unmodified line
725744 geneveh->critical = !!(info->key.tun_flags & TUNNEL_CRIT_OPT);
726745 geneveh->rsvd1 = 0;
727746 tunnel_id_to_vni(info->key.tun_id, geneveh->vni);
728− geneveh->proto_type = htons(ETH_P_TEB);
747+ geneveh->proto_type = inner_proto;
729748 geneveh->rsvd2 = 0;
730749
731750 if (info->key.tun_flags & TUNNEL_GENEVE_OPT)
@@ -734,10 +753,12 @@ static void geneve_build_header(struct genevehdr *geneveh, · 2 unmodified lines
734753
735754 static int geneve_build_skb(struct dst_entry *dst, struct sk_buff *skb,
736755 const struct ip_tunnel_info *info,
737− bool xnet, int ip_hdr_len)
756+ bool xnet, int ip_hdr_len,
757+ bool inner_proto_inherit)
738758 {
739759 bool udp_sum = !!(info->key.tun_flags & TUNNEL_CSUM);
740760 struct genevehdr *gnvh;
761+ __be16 inner_proto;
741762 int min_headroom;
742763 int err;
743764
@@ -755,8 +776,9 @@ static int geneve_build_skb(struct dst_entry *dst, struct sk_buff *skb, · 11 unmodified lines
755776 goto free_dst;
756777
757778 gnvh = __skb_push(skb, sizeof(*gnvh) + info->options_len);
758− geneve_build_header(gnvh, info);
759− skb_set_inner_protocol(skb, htons(ETH_P_TEB));
779+ inner_proto = inner_proto_inherit ? skb->protocol : htons(ETH_P_TEB);
780+ geneve_build_header(gnvh, info, inner_proto);
781+ skb_set_inner_protocol(skb, inner_proto);
760782 return 0;
761783
762784 free_dst:
@@ -959,7 +981,8 @@ static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev, · 196 unmodified lines
959981 }
960982 }
961983
962− err = geneve_build_skb(&rt->dst, skb, info, xnet, sizeof(struct iphdr));
984+ err = geneve_build_skb(&rt->dst, skb, info, xnet, sizeof(struct iphdr),
985+ geneve->cfg.inner_proto_inherit);
963986 if (unlikely(err))
964987 return err;
965988
@@ -1038,7 +1061,8 @@ static int geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev, · 72 unmodified lines
10381061 ttl = key->ttl;
10391062 ttl = ttl ? : ip6_dst_hoplimit(dst);
10401063 }
1041− err = geneve_build_skb(dst, skb, info, xnet, sizeof(struct ipv6hdr));
1064+ err = geneve_build_skb(dst, skb, info, xnet, sizeof(struct ipv6hdr),
1065+ geneve->cfg.inner_proto_inherit);
10421066 if (unlikely(err))
10431067 return err;
10441068
@@ -1388,6 +1412,14 @@ static int geneve_configure(struct net *net, struct net_device *dev, · 343 unmodified lines
13881412 dst_cache_reset(&geneve->cfg.info.dst_cache);
13891413 memcpy(&geneve->cfg, cfg, sizeof(*cfg));
13901414
1415+ if (geneve->cfg.inner_proto_inherit) {
1416+ dev->header_ops = NULL;
1417+ dev->type = ARPHRD_NONE;
1418+ dev->hard_header_len = 0;
1419+ dev->addr_len = 0;
1420+ dev->flags = IFF_NOARP;
1421+ }
1422+
13911423 err = register_netdevice(dev);
13921424 if (err)
13931425 return err;
@@ -1561,10 +1593,18 @@ static int geneve_nl2info(struct nlattr *tb[], struct nlattr *data[], · 167 unmodified lines
15611593 #endif
15621594 }
15631595
1596+ if (data[IFLA_GENEVE_INNER_PROTO_INHERIT]) {
1597+ if (changelink) {
1598+ attrtype = IFLA_GENEVE_INNER_PROTO_INHERIT;
1599+ goto change_notsup;
1600+ }
1601+ cfg->inner_proto_inherit = true;
1602+ }
1603+
15641604 return 0;
15651605 change_notsup:
15661606 NL_SET_ERR_MSG_ATTR(extack, data[attrtype],
1567− "Changing VNI, Port, endpoint IP address family, external, and UDP checksum attributes are not supported");
1607+ "Changing VNI, Port, endpoint IP address family, external, inner_proto_inherit, and UDP checksum attributes are not supported");
15681608 return -EOPNOTSUPP;
15691609 }
15701610
@@ -1799,6 +1839,10 @@ static int geneve_fill_info(struct sk_buff *skb, const struct net_device *dev) · 228 unmodified lines
17991839 if (nla_put_u8(skb, IFLA_GENEVE_TTL_INHERIT, ttl_inherit))
18001840 goto nla_put_failure;
18011841
1842+ if (geneve->cfg.inner_proto_inherit &&
1843+ nla_put_flag(skb, IFLA_GENEVE_INNER_PROTO_INHERIT))
1844+ goto nla_put_failure;
1845+
18021846 return 0;
18031847
18041848 nla_put_failure:
include/uapi/linux/if_link.h+1−0
@@ -842,6 +842,7 @@ enum { · 841 unmodified lines
842842 IFLA_GENEVE_LABEL,
843843 IFLA_GENEVE_TTL_INHERIT,
844844 IFLA_GENEVE_DF,
845+ IFLA_GENEVE_INNER_PROTO_INHERIT,
845846 __IFLA_GENEVE_MAX
846847 };
847848 #define IFLA_GENEVE_MAX (__IFLA_GENEVE_MAX - 1)