@@ -56,6 +56,7 @@ struct geneve_config {
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,
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)
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)
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)
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,15 +735,16 @@ static int geneve_stop(struct net_device *dev)
717735}
718736
719737static 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 ;
724743 geneveh -> oam = !!(info -> key .tun_flags & TUNNEL_OAM );
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,
734753
735754static 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,
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
762784free_dst :
@@ -959,7 +981,8 @@ static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
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,
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,
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[],
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 ;
15651605change_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)
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
18041848nla_put_failure :
0 commit comments