@@ -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 {
@@ -387,6 +388,57 @@ static int geneve_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
387
388
return 0 ;
388
389
}
389
390
391
+ /* Callback from net/ipv{4,6}/udp.c to check that we have a tunnel for errors */
392
+ static int geneve_udp_encap_err_lookup (struct sock * sk , struct sk_buff * skb )
393
+ {
394
+ struct genevehdr * geneveh ;
395
+ struct geneve_sock * gs ;
396
+ u8 zero_vni [3 ] = { 0 };
397
+ u8 * vni = zero_vni ;
398
+
399
+ if (skb -> len < GENEVE_BASE_HLEN )
400
+ return - EINVAL ;
401
+
402
+ geneveh = geneve_hdr (skb );
403
+ if (geneveh -> ver != GENEVE_VER )
404
+ return - EINVAL ;
405
+
406
+ if (geneveh -> proto_type != htons (ETH_P_TEB ))
407
+ return - EINVAL ;
408
+
409
+ gs = rcu_dereference_sk_user_data (sk );
410
+ if (!gs )
411
+ return - ENOENT ;
412
+
413
+ if (geneve_get_sk_family (gs ) == AF_INET ) {
414
+ struct iphdr * iph = ip_hdr (skb );
415
+ __be32 addr4 = 0 ;
416
+
417
+ if (!gs -> collect_md ) {
418
+ vni = geneve_hdr (skb )-> vni ;
419
+ addr4 = iph -> daddr ;
420
+ }
421
+
422
+ return geneve_lookup (gs , addr4 , vni ) ? 0 : - ENOENT ;
423
+ }
424
+
425
+ #if IS_ENABLED (CONFIG_IPV6 )
426
+ if (geneve_get_sk_family (gs ) == AF_INET6 ) {
427
+ struct ipv6hdr * ip6h = ipv6_hdr (skb );
428
+ struct in6_addr addr6 = { 0 };
429
+
430
+ if (!gs -> collect_md ) {
431
+ vni = geneve_hdr (skb )-> vni ;
432
+ addr6 = ip6h -> daddr ;
433
+ }
434
+
435
+ return geneve6_lookup (gs , addr6 , vni ) ? 0 : - ENOENT ;
436
+ }
437
+ #endif
438
+
439
+ return - EPFNOSUPPORT ;
440
+ }
441
+
390
442
static struct socket * geneve_create_sock (struct net * net , bool ipv6 ,
391
443
__be16 port , bool ipv6_rx_csum )
392
444
{
@@ -544,6 +596,7 @@ static struct geneve_sock *geneve_socket_create(struct net *net, __be16 port,
544
596
tunnel_cfg .gro_receive = geneve_gro_receive ;
545
597
tunnel_cfg .gro_complete = geneve_gro_complete ;
546
598
tunnel_cfg .encap_rcv = geneve_udp_encap_recv ;
599
+ tunnel_cfg .encap_err_lookup = geneve_udp_encap_err_lookup ;
547
600
tunnel_cfg .encap_destroy = NULL ;
548
601
setup_udp_tunnel_sock (net , sock , & tunnel_cfg );
549
602
list_add (& gs -> list , & gn -> sock_list );
@@ -823,8 +876,8 @@ static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
823
876
struct rtable * rt ;
824
877
struct flowi4 fl4 ;
825
878
__u8 tos , ttl ;
879
+ __be16 df = 0 ;
826
880
__be16 sport ;
827
- __be16 df ;
828
881
int err ;
829
882
830
883
rt = geneve_get_v4_rt (skb , dev , gs4 , & fl4 , info );
@@ -838,15 +891,31 @@ static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
838
891
if (geneve -> collect_md ) {
839
892
tos = ip_tunnel_ecn_encap (key -> tos , ip_hdr (skb ), skb );
840
893
ttl = key -> ttl ;
894
+
895
+ df = key -> tun_flags & TUNNEL_DONT_FRAGMENT ? htons (IP_DF ) : 0 ;
841
896
} else {
842
897
tos = ip_tunnel_ecn_encap (fl4 .flowi4_tos , ip_hdr (skb ), skb );
843
898
if (geneve -> ttl_inherit )
844
899
ttl = ip_tunnel_get_ttl (ip_hdr (skb ), skb );
845
900
else
846
901
ttl = key -> ttl ;
847
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
+ }
848
918
}
849
- df = key -> tun_flags & TUNNEL_DONT_FRAGMENT ? htons (IP_DF ) : 0 ;
850
919
851
920
err = geneve_build_skb (& rt -> dst , skb , info , xnet , sizeof (struct iphdr ));
852
921
if (unlikely (err ))
@@ -1093,6 +1162,7 @@ static const struct nla_policy geneve_policy[IFLA_GENEVE_MAX + 1] = {
1093
1162
[IFLA_GENEVE_UDP_ZERO_CSUM6_TX ] = { .type = NLA_U8 },
1094
1163
[IFLA_GENEVE_UDP_ZERO_CSUM6_RX ] = { .type = NLA_U8 },
1095
1164
[IFLA_GENEVE_TTL_INHERIT ] = { .type = NLA_U8 },
1165
+ [IFLA_GENEVE_DF ] = { .type = NLA_U8 },
1096
1166
};
1097
1167
1098
1168
static int geneve_validate (struct nlattr * tb [], struct nlattr * data [],
@@ -1128,6 +1198,16 @@ static int geneve_validate(struct nlattr *tb[], struct nlattr *data[],
1128
1198
}
1129
1199
}
1130
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
+
1131
1211
return 0 ;
1132
1212
}
1133
1213
@@ -1173,7 +1253,7 @@ static int geneve_configure(struct net *net, struct net_device *dev,
1173
1253
struct netlink_ext_ack * extack ,
1174
1254
const struct ip_tunnel_info * info ,
1175
1255
bool metadata , bool ipv6_rx_csum ,
1176
- bool ttl_inherit )
1256
+ bool ttl_inherit , enum ifla_geneve_df df )
1177
1257
{
1178
1258
struct geneve_net * gn = net_generic (net , geneve_net_id );
1179
1259
struct geneve_dev * t , * geneve = netdev_priv (dev );
@@ -1223,6 +1303,7 @@ static int geneve_configure(struct net *net, struct net_device *dev,
1223
1303
geneve -> collect_md = metadata ;
1224
1304
geneve -> use_udp6_rx_checksums = ipv6_rx_csum ;
1225
1305
geneve -> ttl_inherit = ttl_inherit ;
1306
+ geneve -> df = df ;
1226
1307
1227
1308
err = register_netdevice (dev );
1228
1309
if (err )
@@ -1242,7 +1323,7 @@ static int geneve_nl2info(struct nlattr *tb[], struct nlattr *data[],
1242
1323
struct netlink_ext_ack * extack ,
1243
1324
struct ip_tunnel_info * info , bool * metadata ,
1244
1325
bool * use_udp6_rx_checksums , bool * ttl_inherit ,
1245
- bool changelink )
1326
+ enum ifla_geneve_df * df , bool changelink )
1246
1327
{
1247
1328
int attrtype ;
1248
1329
@@ -1330,6 +1411,9 @@ static int geneve_nl2info(struct nlattr *tb[], struct nlattr *data[],
1330
1411
if (data [IFLA_GENEVE_TOS ])
1331
1412
info -> key .tos = nla_get_u8 (data [IFLA_GENEVE_TOS ]);
1332
1413
1414
+ if (data [IFLA_GENEVE_DF ])
1415
+ * df = nla_get_u8 (data [IFLA_GENEVE_DF ]);
1416
+
1333
1417
if (data [IFLA_GENEVE_LABEL ]) {
1334
1418
info -> key .label = nla_get_be32 (data [IFLA_GENEVE_LABEL ]) &
1335
1419
IPV6_FLOWLABEL_MASK ;
@@ -1448,6 +1532,7 @@ static int geneve_newlink(struct net *net, struct net_device *dev,
1448
1532
struct nlattr * tb [], struct nlattr * data [],
1449
1533
struct netlink_ext_ack * extack )
1450
1534
{
1535
+ enum ifla_geneve_df df = GENEVE_DF_UNSET ;
1451
1536
bool use_udp6_rx_checksums = false;
1452
1537
struct ip_tunnel_info info ;
1453
1538
bool ttl_inherit = false;
@@ -1456,12 +1541,12 @@ static int geneve_newlink(struct net *net, struct net_device *dev,
1456
1541
1457
1542
init_tnl_info (& info , GENEVE_UDP_PORT );
1458
1543
err = geneve_nl2info (tb , data , extack , & info , & metadata ,
1459
- & use_udp6_rx_checksums , & ttl_inherit , false);
1544
+ & use_udp6_rx_checksums , & ttl_inherit , & df , false);
1460
1545
if (err )
1461
1546
return err ;
1462
1547
1463
1548
err = geneve_configure (net , dev , extack , & info , metadata ,
1464
- use_udp6_rx_checksums , ttl_inherit );
1549
+ use_udp6_rx_checksums , ttl_inherit , df );
1465
1550
if (err )
1466
1551
return err ;
1467
1552
@@ -1524,6 +1609,7 @@ static int geneve_changelink(struct net_device *dev, struct nlattr *tb[],
1524
1609
struct ip_tunnel_info info ;
1525
1610
bool metadata ;
1526
1611
bool use_udp6_rx_checksums ;
1612
+ enum ifla_geneve_df df ;
1527
1613
bool ttl_inherit ;
1528
1614
int err ;
1529
1615
@@ -1539,7 +1625,7 @@ static int geneve_changelink(struct net_device *dev, struct nlattr *tb[],
1539
1625
use_udp6_rx_checksums = geneve -> use_udp6_rx_checksums ;
1540
1626
ttl_inherit = geneve -> ttl_inherit ;
1541
1627
err = geneve_nl2info (tb , data , extack , & info , & metadata ,
1542
- & use_udp6_rx_checksums , & ttl_inherit , true);
1628
+ & use_udp6_rx_checksums , & ttl_inherit , & df , true);
1543
1629
if (err )
1544
1630
return err ;
1545
1631
@@ -1572,6 +1658,7 @@ static size_t geneve_get_size(const struct net_device *dev)
1572
1658
nla_total_size (sizeof (struct in6_addr )) + /* IFLA_GENEVE_REMOTE{6} */
1573
1659
nla_total_size (sizeof (__u8 )) + /* IFLA_GENEVE_TTL */
1574
1660
nla_total_size (sizeof (__u8 )) + /* IFLA_GENEVE_TOS */
1661
+ nla_total_size (sizeof (__u8 )) + /* IFLA_GENEVE_DF */
1575
1662
nla_total_size (sizeof (__be32 )) + /* IFLA_GENEVE_LABEL */
1576
1663
nla_total_size (sizeof (__be16 )) + /* IFLA_GENEVE_PORT */
1577
1664
nla_total_size (0 ) + /* IFLA_GENEVE_COLLECT_METADATA */
@@ -1620,6 +1707,9 @@ static int geneve_fill_info(struct sk_buff *skb, const struct net_device *dev)
1620
1707
nla_put_be32 (skb , IFLA_GENEVE_LABEL , info -> key .label ))
1621
1708
goto nla_put_failure ;
1622
1709
1710
+ if (nla_put_u8 (skb , IFLA_GENEVE_DF , geneve -> df ))
1711
+ goto nla_put_failure ;
1712
+
1623
1713
if (nla_put_be16 (skb , IFLA_GENEVE_PORT , info -> key .tp_dst ))
1624
1714
goto nla_put_failure ;
1625
1715
@@ -1671,7 +1761,8 @@ struct net_device *geneve_dev_create_fb(struct net *net, const char *name,
1671
1761
return dev ;
1672
1762
1673
1763
init_tnl_info (& info , dst_port );
1674
- 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 );
1675
1766
if (err ) {
1676
1767
free_netdev (dev );
1677
1768
return ERR_PTR (err );
0 commit comments