@@ -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 ;
@@ -723,15 +741,16 @@ static int geneve_stop(struct net_device *dev)
723741}
724742
725743static void geneve_build_header (struct genevehdr * geneveh ,
726- const struct ip_tunnel_info * info )
744+ const struct ip_tunnel_info * info ,
745+ __be16 inner_proto )
727746{
728747 geneveh -> ver = GENEVE_VER ;
729748 geneveh -> opt_len = info -> options_len / 4 ;
730749 geneveh -> oam = !!(info -> key .tun_flags & TUNNEL_OAM );
731750 geneveh -> critical = !!(info -> key .tun_flags & TUNNEL_CRIT_OPT );
732751 geneveh -> rsvd1 = 0 ;
733752 tunnel_id_to_vni (info -> key .tun_id , geneveh -> vni );
734- geneveh -> proto_type = htons ( ETH_P_TEB ) ;
753+ geneveh -> proto_type = inner_proto ;
735754 geneveh -> rsvd2 = 0 ;
736755
737756 if (info -> key .tun_flags & TUNNEL_GENEVE_OPT )
@@ -740,10 +759,12 @@ static void geneve_build_header(struct genevehdr *geneveh,
740759
741760static int geneve_build_skb (struct dst_entry * dst , struct sk_buff * skb ,
742761 const struct ip_tunnel_info * info ,
743- bool xnet , int ip_hdr_len )
762+ bool xnet , int ip_hdr_len ,
763+ bool inner_proto_inherit )
744764{
745765 bool udp_sum = !!(info -> key .tun_flags & TUNNEL_CSUM );
746766 struct genevehdr * gnvh ;
767+ __be16 inner_proto ;
747768 int min_headroom ;
748769 int err ;
749770
@@ -761,8 +782,9 @@ static int geneve_build_skb(struct dst_entry *dst, struct sk_buff *skb,
761782 goto free_dst ;
762783
763784 gnvh = __skb_push (skb , sizeof (* gnvh ) + info -> options_len );
764- geneve_build_header (gnvh , info );
765- skb_set_inner_protocol (skb , htons (ETH_P_TEB ));
785+ inner_proto = inner_proto_inherit ? skb -> protocol : htons (ETH_P_TEB );
786+ geneve_build_header (gnvh , info , inner_proto );
787+ skb_set_inner_protocol (skb , inner_proto );
766788 return 0 ;
767789
768790free_dst :
@@ -969,7 +991,8 @@ static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
969991 }
970992 }
971993
972- err = geneve_build_skb (& rt -> dst , skb , info , xnet , sizeof (struct iphdr ));
994+ err = geneve_build_skb (& rt -> dst , skb , info , xnet , sizeof (struct iphdr ),
995+ geneve -> cfg .inner_proto_inherit );
973996 if (unlikely (err ))
974997 return err ;
975998
@@ -1048,7 +1071,8 @@ static int geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
10481071 ttl = key -> ttl ;
10491072 ttl = ttl ? : ip6_dst_hoplimit (dst );
10501073 }
1051- err = geneve_build_skb (dst , skb , info , xnet , sizeof (struct ipv6hdr ));
1074+ err = geneve_build_skb (dst , skb , info , xnet , sizeof (struct ipv6hdr ),
1075+ geneve -> cfg .inner_proto_inherit );
10521076 if (unlikely (err ))
10531077 return err ;
10541078
@@ -1398,6 +1422,14 @@ static int geneve_configure(struct net *net, struct net_device *dev,
13981422 dst_cache_reset (& geneve -> cfg .info .dst_cache );
13991423 memcpy (& geneve -> cfg , cfg , sizeof (* cfg ));
14001424
1425+ if (geneve -> cfg .inner_proto_inherit ) {
1426+ dev -> header_ops = NULL ;
1427+ dev -> type = ARPHRD_NONE ;
1428+ dev -> hard_header_len = 0 ;
1429+ dev -> addr_len = 0 ;
1430+ dev -> flags = IFF_NOARP ;
1431+ }
1432+
14011433 err = register_netdevice (dev );
14021434 if (err )
14031435 return err ;
@@ -1571,10 +1603,18 @@ static int geneve_nl2info(struct nlattr *tb[], struct nlattr *data[],
15711603#endif
15721604 }
15731605
1606+ if (data [IFLA_GENEVE_INNER_PROTO_INHERIT ]) {
1607+ if (changelink ) {
1608+ attrtype = IFLA_GENEVE_INNER_PROTO_INHERIT ;
1609+ goto change_notsup ;
1610+ }
1611+ cfg -> inner_proto_inherit = true;
1612+ }
1613+
15741614 return 0 ;
15751615change_notsup :
15761616 NL_SET_ERR_MSG_ATTR (extack , data [attrtype ],
1577- "Changing VNI, Port, endpoint IP address family, external, and UDP checksum attributes are not supported" );
1617+ "Changing VNI, Port, endpoint IP address family, external, inner_proto_inherit, and UDP checksum attributes are not supported" );
15781618 return - EOPNOTSUPP ;
15791619}
15801620
@@ -1809,6 +1849,10 @@ static int geneve_fill_info(struct sk_buff *skb, const struct net_device *dev)
18091849 if (nla_put_u8 (skb , IFLA_GENEVE_TTL_INHERIT , ttl_inherit ))
18101850 goto nla_put_failure ;
18111851
1852+ if (geneve -> cfg .inner_proto_inherit &&
1853+ nla_put_flag (skb , IFLA_GENEVE_INNER_PROTO_INHERIT ))
1854+ goto nla_put_failure ;
1855+
18121856 return 0 ;
18131857
18141858nla_put_failure :
0 commit comments