@@ -70,6 +70,7 @@ struct geneve_dev {
70
70
bool collect_md ;
71
71
bool use_udp6_rx_checksums ;
72
72
bool ttl_inherit ;
73
+ enum ifla_geneve_df df ;
73
74
};
74
75
75
76
struct geneve_sock {
@@ -875,8 +876,8 @@ static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
875
876
struct rtable * rt ;
876
877
struct flowi4 fl4 ;
877
878
__u8 tos , ttl ;
879
+ __be16 df = 0 ;
878
880
__be16 sport ;
879
- __be16 df ;
880
881
int err ;
881
882
882
883
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,
890
891
if (geneve -> collect_md ) {
891
892
tos = ip_tunnel_ecn_encap (key -> tos , ip_hdr (skb ), skb );
892
893
ttl = key -> ttl ;
894
+
895
+ df = key -> tun_flags & TUNNEL_DONT_FRAGMENT ? htons (IP_DF ) : 0 ;
893
896
} else {
894
897
tos = ip_tunnel_ecn_encap (fl4 .flowi4_tos , ip_hdr (skb ), skb );
895
898
if (geneve -> ttl_inherit )
896
899
ttl = ip_tunnel_get_ttl (ip_hdr (skb ), skb );
897
900
else
898
901
ttl = key -> ttl ;
899
902
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
+ }
900
918
}
901
- df = key -> tun_flags & TUNNEL_DONT_FRAGMENT ? htons (IP_DF ) : 0 ;
902
919
903
920
err = geneve_build_skb (& rt -> dst , skb , info , xnet , sizeof (struct iphdr ));
904
921
if (unlikely (err ))
@@ -1145,6 +1162,7 @@ static const struct nla_policy geneve_policy[IFLA_GENEVE_MAX + 1] = {
1145
1162
[IFLA_GENEVE_UDP_ZERO_CSUM6_TX ] = { .type = NLA_U8 },
1146
1163
[IFLA_GENEVE_UDP_ZERO_CSUM6_RX ] = { .type = NLA_U8 },
1147
1164
[IFLA_GENEVE_TTL_INHERIT ] = { .type = NLA_U8 },
1165
+ [IFLA_GENEVE_DF ] = { .type = NLA_U8 },
1148
1166
};
1149
1167
1150
1168
static int geneve_validate (struct nlattr * tb [], struct nlattr * data [],
@@ -1180,6 +1198,16 @@ static int geneve_validate(struct nlattr *tb[], struct nlattr *data[],
1180
1198
}
1181
1199
}
1182
1200
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
+
1183
1211
return 0 ;
1184
1212
}
1185
1213
@@ -1225,7 +1253,7 @@ static int geneve_configure(struct net *net, struct net_device *dev,
1225
1253
struct netlink_ext_ack * extack ,
1226
1254
const struct ip_tunnel_info * info ,
1227
1255
bool metadata , bool ipv6_rx_csum ,
1228
- bool ttl_inherit )
1256
+ bool ttl_inherit , enum ifla_geneve_df df )
1229
1257
{
1230
1258
struct geneve_net * gn = net_generic (net , geneve_net_id );
1231
1259
struct geneve_dev * t , * geneve = netdev_priv (dev );
@@ -1275,6 +1303,7 @@ static int geneve_configure(struct net *net, struct net_device *dev,
1275
1303
geneve -> collect_md = metadata ;
1276
1304
geneve -> use_udp6_rx_checksums = ipv6_rx_csum ;
1277
1305
geneve -> ttl_inherit = ttl_inherit ;
1306
+ geneve -> df = df ;
1278
1307
1279
1308
err = register_netdevice (dev );
1280
1309
if (err )
@@ -1294,7 +1323,7 @@ static int geneve_nl2info(struct nlattr *tb[], struct nlattr *data[],
1294
1323
struct netlink_ext_ack * extack ,
1295
1324
struct ip_tunnel_info * info , bool * metadata ,
1296
1325
bool * use_udp6_rx_checksums , bool * ttl_inherit ,
1297
- bool changelink )
1326
+ enum ifla_geneve_df * df , bool changelink )
1298
1327
{
1299
1328
int attrtype ;
1300
1329
@@ -1382,6 +1411,9 @@ static int geneve_nl2info(struct nlattr *tb[], struct nlattr *data[],
1382
1411
if (data [IFLA_GENEVE_TOS ])
1383
1412
info -> key .tos = nla_get_u8 (data [IFLA_GENEVE_TOS ]);
1384
1413
1414
+ if (data [IFLA_GENEVE_DF ])
1415
+ * df = nla_get_u8 (data [IFLA_GENEVE_DF ]);
1416
+
1385
1417
if (data [IFLA_GENEVE_LABEL ]) {
1386
1418
info -> key .label = nla_get_be32 (data [IFLA_GENEVE_LABEL ]) &
1387
1419
IPV6_FLOWLABEL_MASK ;
@@ -1500,6 +1532,7 @@ static int geneve_newlink(struct net *net, struct net_device *dev,
1500
1532
struct nlattr * tb [], struct nlattr * data [],
1501
1533
struct netlink_ext_ack * extack )
1502
1534
{
1535
+ enum ifla_geneve_df df = GENEVE_DF_UNSET ;
1503
1536
bool use_udp6_rx_checksums = false;
1504
1537
struct ip_tunnel_info info ;
1505
1538
bool ttl_inherit = false;
@@ -1508,12 +1541,12 @@ static int geneve_newlink(struct net *net, struct net_device *dev,
1508
1541
1509
1542
init_tnl_info (& info , GENEVE_UDP_PORT );
1510
1543
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);
1512
1545
if (err )
1513
1546
return err ;
1514
1547
1515
1548
err = geneve_configure (net , dev , extack , & info , metadata ,
1516
- use_udp6_rx_checksums , ttl_inherit );
1549
+ use_udp6_rx_checksums , ttl_inherit , df );
1517
1550
if (err )
1518
1551
return err ;
1519
1552
@@ -1576,6 +1609,7 @@ static int geneve_changelink(struct net_device *dev, struct nlattr *tb[],
1576
1609
struct ip_tunnel_info info ;
1577
1610
bool metadata ;
1578
1611
bool use_udp6_rx_checksums ;
1612
+ enum ifla_geneve_df df ;
1579
1613
bool ttl_inherit ;
1580
1614
int err ;
1581
1615
@@ -1591,7 +1625,7 @@ static int geneve_changelink(struct net_device *dev, struct nlattr *tb[],
1591
1625
use_udp6_rx_checksums = geneve -> use_udp6_rx_checksums ;
1592
1626
ttl_inherit = geneve -> ttl_inherit ;
1593
1627
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);
1595
1629
if (err )
1596
1630
return err ;
1597
1631
@@ -1624,6 +1658,7 @@ static size_t geneve_get_size(const struct net_device *dev)
1624
1658
nla_total_size (sizeof (struct in6_addr )) + /* IFLA_GENEVE_REMOTE{6} */
1625
1659
nla_total_size (sizeof (__u8 )) + /* IFLA_GENEVE_TTL */
1626
1660
nla_total_size (sizeof (__u8 )) + /* IFLA_GENEVE_TOS */
1661
+ nla_total_size (sizeof (__u8 )) + /* IFLA_GENEVE_DF */
1627
1662
nla_total_size (sizeof (__be32 )) + /* IFLA_GENEVE_LABEL */
1628
1663
nla_total_size (sizeof (__be16 )) + /* IFLA_GENEVE_PORT */
1629
1664
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)
1672
1707
nla_put_be32 (skb , IFLA_GENEVE_LABEL , info -> key .label ))
1673
1708
goto nla_put_failure ;
1674
1709
1710
+ if (nla_put_u8 (skb , IFLA_GENEVE_DF , geneve -> df ))
1711
+ goto nla_put_failure ;
1712
+
1675
1713
if (nla_put_be16 (skb , IFLA_GENEVE_PORT , info -> key .tp_dst ))
1676
1714
goto nla_put_failure ;
1677
1715
@@ -1723,7 +1761,8 @@ struct net_device *geneve_dev_create_fb(struct net *net, const char *name,
1723
1761
return dev ;
1724
1762
1725
1763
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 );
1727
1766
if (err ) {
1728
1767
free_netdev (dev );
1729
1768
return ERR_PTR (err );
0 commit comments