@@ -70,6 +70,7 @@ struct geneve_dev {
7070 bool collect_md ;
7171 bool use_udp6_rx_checksums ;
7272 bool ttl_inherit ;
73+ enum ifla_geneve_df df ;
7374};
7475
7576struct geneve_sock {
@@ -875,8 +876,8 @@ static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
875876 struct rtable * rt ;
876877 struct flowi4 fl4 ;
877878 __u8 tos , ttl ;
879+ __be16 df = 0 ;
878880 __be16 sport ;
879- __be16 df ;
880881 int err ;
881882
882883 rt = geneve_get_v4_rt (skb , dev , gs4 , & fl4 , info );
@@ -890,15 +891,31 @@ static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
890891 if (geneve -> collect_md ) {
891892 tos = ip_tunnel_ecn_encap (key -> tos , ip_hdr (skb ), skb );
892893 ttl = key -> ttl ;
894+
895+ df = key -> tun_flags & TUNNEL_DONT_FRAGMENT ? htons (IP_DF ) : 0 ;
893896 } else {
894897 tos = ip_tunnel_ecn_encap (fl4 .flowi4_tos , ip_hdr (skb ), skb );
895898 if (geneve -> ttl_inherit )
896899 ttl = ip_tunnel_get_ttl (ip_hdr (skb ), skb );
897900 else
898901 ttl = key -> ttl ;
899902 ttl = ttl ? : ip4_dst_hoplimit (& rt -> dst );
903+
904+ if (geneve -> df == GENEVE_DF_SET ) {
905+ df = htons (IP_DF );
906+ } else if (geneve -> df == GENEVE_DF_INHERIT ) {
907+ struct ethhdr * eth = eth_hdr (skb );
908+
909+ if (ntohs (eth -> h_proto ) == ETH_P_IPV6 ) {
910+ df = htons (IP_DF );
911+ } else if (ntohs (eth -> h_proto ) == ETH_P_IP ) {
912+ struct iphdr * iph = ip_hdr (skb );
913+
914+ if (iph -> frag_off & htons (IP_DF ))
915+ df = htons (IP_DF );
916+ }
917+ }
900918 }
901- df = key -> tun_flags & TUNNEL_DONT_FRAGMENT ? htons (IP_DF ) : 0 ;
902919
903920 err = geneve_build_skb (& rt -> dst , skb , info , xnet , sizeof (struct iphdr ));
904921 if (unlikely (err ))
@@ -1145,6 +1162,7 @@ static const struct nla_policy geneve_policy[IFLA_GENEVE_MAX + 1] = {
11451162 [IFLA_GENEVE_UDP_ZERO_CSUM6_TX ] = { .type = NLA_U8 },
11461163 [IFLA_GENEVE_UDP_ZERO_CSUM6_RX ] = { .type = NLA_U8 },
11471164 [IFLA_GENEVE_TTL_INHERIT ] = { .type = NLA_U8 },
1165+ [IFLA_GENEVE_DF ] = { .type = NLA_U8 },
11481166};
11491167
11501168static int geneve_validate (struct nlattr * tb [], struct nlattr * data [],
@@ -1180,6 +1198,16 @@ static int geneve_validate(struct nlattr *tb[], struct nlattr *data[],
11801198 }
11811199 }
11821200
1201+ if (data [IFLA_GENEVE_DF ]) {
1202+ enum ifla_geneve_df df = nla_get_u8 (data [IFLA_GENEVE_DF ]);
1203+
1204+ if (df < 0 || df > GENEVE_DF_MAX ) {
1205+ NL_SET_ERR_MSG_ATTR (extack , tb [IFLA_GENEVE_DF ],
1206+ "Invalid DF attribute" );
1207+ return - EINVAL ;
1208+ }
1209+ }
1210+
11831211 return 0 ;
11841212}
11851213
@@ -1225,7 +1253,7 @@ static int geneve_configure(struct net *net, struct net_device *dev,
12251253 struct netlink_ext_ack * extack ,
12261254 const struct ip_tunnel_info * info ,
12271255 bool metadata , bool ipv6_rx_csum ,
1228- bool ttl_inherit )
1256+ bool ttl_inherit , enum ifla_geneve_df df )
12291257{
12301258 struct geneve_net * gn = net_generic (net , geneve_net_id );
12311259 struct geneve_dev * t , * geneve = netdev_priv (dev );
@@ -1275,6 +1303,7 @@ static int geneve_configure(struct net *net, struct net_device *dev,
12751303 geneve -> collect_md = metadata ;
12761304 geneve -> use_udp6_rx_checksums = ipv6_rx_csum ;
12771305 geneve -> ttl_inherit = ttl_inherit ;
1306+ geneve -> df = df ;
12781307
12791308 err = register_netdevice (dev );
12801309 if (err )
@@ -1294,7 +1323,7 @@ static int geneve_nl2info(struct nlattr *tb[], struct nlattr *data[],
12941323 struct netlink_ext_ack * extack ,
12951324 struct ip_tunnel_info * info , bool * metadata ,
12961325 bool * use_udp6_rx_checksums , bool * ttl_inherit ,
1297- bool changelink )
1326+ enum ifla_geneve_df * df , bool changelink )
12981327{
12991328 int attrtype ;
13001329
@@ -1382,6 +1411,9 @@ static int geneve_nl2info(struct nlattr *tb[], struct nlattr *data[],
13821411 if (data [IFLA_GENEVE_TOS ])
13831412 info -> key .tos = nla_get_u8 (data [IFLA_GENEVE_TOS ]);
13841413
1414+ if (data [IFLA_GENEVE_DF ])
1415+ * df = nla_get_u8 (data [IFLA_GENEVE_DF ]);
1416+
13851417 if (data [IFLA_GENEVE_LABEL ]) {
13861418 info -> key .label = nla_get_be32 (data [IFLA_GENEVE_LABEL ]) &
13871419 IPV6_FLOWLABEL_MASK ;
@@ -1500,6 +1532,7 @@ static int geneve_newlink(struct net *net, struct net_device *dev,
15001532 struct nlattr * tb [], struct nlattr * data [],
15011533 struct netlink_ext_ack * extack )
15021534{
1535+ enum ifla_geneve_df df = GENEVE_DF_UNSET ;
15031536 bool use_udp6_rx_checksums = false;
15041537 struct ip_tunnel_info info ;
15051538 bool ttl_inherit = false;
@@ -1508,12 +1541,12 @@ static int geneve_newlink(struct net *net, struct net_device *dev,
15081541
15091542 init_tnl_info (& info , GENEVE_UDP_PORT );
15101543 err = geneve_nl2info (tb , data , extack , & info , & metadata ,
1511- & use_udp6_rx_checksums , & ttl_inherit , false);
1544+ & use_udp6_rx_checksums , & ttl_inherit , & df , false);
15121545 if (err )
15131546 return err ;
15141547
15151548 err = geneve_configure (net , dev , extack , & info , metadata ,
1516- use_udp6_rx_checksums , ttl_inherit );
1549+ use_udp6_rx_checksums , ttl_inherit , df );
15171550 if (err )
15181551 return err ;
15191552
@@ -1576,6 +1609,7 @@ static int geneve_changelink(struct net_device *dev, struct nlattr *tb[],
15761609 struct ip_tunnel_info info ;
15771610 bool metadata ;
15781611 bool use_udp6_rx_checksums ;
1612+ enum ifla_geneve_df df ;
15791613 bool ttl_inherit ;
15801614 int err ;
15811615
@@ -1591,7 +1625,7 @@ static int geneve_changelink(struct net_device *dev, struct nlattr *tb[],
15911625 use_udp6_rx_checksums = geneve -> use_udp6_rx_checksums ;
15921626 ttl_inherit = geneve -> ttl_inherit ;
15931627 err = geneve_nl2info (tb , data , extack , & info , & metadata ,
1594- & use_udp6_rx_checksums , & ttl_inherit , true);
1628+ & use_udp6_rx_checksums , & ttl_inherit , & df , true);
15951629 if (err )
15961630 return err ;
15971631
@@ -1624,6 +1658,7 @@ static size_t geneve_get_size(const struct net_device *dev)
16241658 nla_total_size (sizeof (struct in6_addr )) + /* IFLA_GENEVE_REMOTE{6} */
16251659 nla_total_size (sizeof (__u8 )) + /* IFLA_GENEVE_TTL */
16261660 nla_total_size (sizeof (__u8 )) + /* IFLA_GENEVE_TOS */
1661+ nla_total_size (sizeof (__u8 )) + /* IFLA_GENEVE_DF */
16271662 nla_total_size (sizeof (__be32 )) + /* IFLA_GENEVE_LABEL */
16281663 nla_total_size (sizeof (__be16 )) + /* IFLA_GENEVE_PORT */
16291664 nla_total_size (0 ) + /* IFLA_GENEVE_COLLECT_METADATA */
@@ -1672,6 +1707,9 @@ static int geneve_fill_info(struct sk_buff *skb, const struct net_device *dev)
16721707 nla_put_be32 (skb , IFLA_GENEVE_LABEL , info -> key .label ))
16731708 goto nla_put_failure ;
16741709
1710+ if (nla_put_u8 (skb , IFLA_GENEVE_DF , geneve -> df ))
1711+ goto nla_put_failure ;
1712+
16751713 if (nla_put_be16 (skb , IFLA_GENEVE_PORT , info -> key .tp_dst ))
16761714 goto nla_put_failure ;
16771715
@@ -1723,7 +1761,8 @@ struct net_device *geneve_dev_create_fb(struct net *net, const char *name,
17231761 return dev ;
17241762
17251763 init_tnl_info (& info , dst_port );
1726- err = geneve_configure (net , dev , NULL , & info , true, true, false);
1764+ err = geneve_configure (net , dev , NULL , & info ,
1765+ true, true, false, GENEVE_DF_UNSET );
17271766 if (err ) {
17281767 free_netdev (dev );
17291768 return ERR_PTR (err );
0 commit comments