@@ -80,6 +80,8 @@ MODULE_PARM_DESC(log_ecn_error, "Log packets received with corrupted ECN");
80
80
81
81
static int vxlan_net_id ;
82
82
83
+ static const u8 all_zeros_mac [ETH_ALEN ];
84
+
83
85
/* per UDP socket information */
84
86
struct vxlan_sock {
85
87
struct hlist_node hlist ;
@@ -1151,7 +1153,7 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
1151
1153
struct vxlan_dev * vxlan = netdev_priv (dev );
1152
1154
struct ethhdr * eth ;
1153
1155
bool did_rsc = false;
1154
- struct vxlan_rdst * rdst0 , * rdst ;
1156
+ struct vxlan_rdst * rdst ;
1155
1157
struct vxlan_fdb * f ;
1156
1158
1157
1159
skb_reset_mac_header (skb );
@@ -1171,26 +1173,27 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
1171
1173
}
1172
1174
1173
1175
if (f == NULL ) {
1174
- rdst0 = & vxlan -> default_dst ;
1175
-
1176
- if (rdst0 -> remote_ip == htonl (INADDR_ANY ) &&
1177
- (vxlan -> flags & VXLAN_F_L2MISS ) &&
1178
- !is_multicast_ether_addr (eth -> h_dest ))
1179
- vxlan_fdb_miss (vxlan , eth -> h_dest );
1180
- } else {
1181
- rdst = rdst0 = first_remote (f );
1176
+ f = vxlan_find_mac (vxlan , all_zeros_mac );
1177
+ if (f == NULL ) {
1178
+ if ((vxlan -> flags & VXLAN_F_L2MISS ) &&
1179
+ !is_multicast_ether_addr (eth -> h_dest ))
1180
+ vxlan_fdb_miss (vxlan , eth -> h_dest );
1181
+
1182
+ dev -> stats .tx_dropped ++ ;
1183
+ dev_kfree_skb (skb );
1184
+ return NETDEV_TX_OK ;
1185
+ }
1186
+ }
1182
1187
1183
- /* if there are multiple destinations, send copies */
1184
- list_for_each_entry_continue_rcu (rdst , & f -> remotes , list ) {
1185
- struct sk_buff * skb1 ;
1188
+ list_for_each_entry_rcu (rdst , & f -> remotes , list ) {
1189
+ struct sk_buff * skb1 ;
1186
1190
1187
- skb1 = skb_clone (skb , GFP_ATOMIC );
1188
- if (skb1 )
1189
- vxlan_xmit_one (skb1 , dev , rdst , did_rsc );
1190
- }
1191
+ skb1 = skb_clone (skb , GFP_ATOMIC );
1192
+ if (skb1 )
1193
+ vxlan_xmit_one (skb1 , dev , rdst , did_rsc );
1191
1194
}
1192
1195
1193
- vxlan_xmit_one (skb , dev , rdst0 , did_rsc );
1196
+ dev_kfree_skb (skb );
1194
1197
return NETDEV_TX_OK ;
1195
1198
}
1196
1199
@@ -1260,12 +1263,25 @@ static int vxlan_init(struct net_device *dev)
1260
1263
return 0 ;
1261
1264
}
1262
1265
1266
+ static void vxlan_fdb_delete_defualt (struct vxlan_dev * vxlan )
1267
+ {
1268
+ struct vxlan_fdb * f ;
1269
+
1270
+ spin_lock_bh (& vxlan -> hash_lock );
1271
+ f = __vxlan_find_mac (vxlan , all_zeros_mac );
1272
+ if (f )
1273
+ vxlan_fdb_destroy (vxlan , f );
1274
+ spin_unlock_bh (& vxlan -> hash_lock );
1275
+ }
1276
+
1263
1277
static void vxlan_uninit (struct net_device * dev )
1264
1278
{
1265
1279
struct vxlan_dev * vxlan = netdev_priv (dev );
1266
1280
struct vxlan_net * vn = net_generic (dev_net (dev ), vxlan_net_id );
1267
1281
struct vxlan_sock * vs = vxlan -> vn_sock ;
1268
1282
1283
+ vxlan_fdb_delete_defualt (vxlan );
1284
+
1269
1285
if (vs )
1270
1286
vxlan_sock_release (vn , vs );
1271
1287
free_percpu (dev -> tstats );
@@ -1304,7 +1320,9 @@ static void vxlan_flush(struct vxlan_dev *vxlan)
1304
1320
hlist_for_each_safe (p , n , & vxlan -> fdb_head [h ]) {
1305
1321
struct vxlan_fdb * f
1306
1322
= container_of (p , struct vxlan_fdb , hlist );
1307
- vxlan_fdb_destroy (vxlan , f );
1323
+ /* the all_zeros_mac entry is deleted at vxlan_uninit */
1324
+ if (!is_zero_ether_addr (f -> eth_addr ))
1325
+ vxlan_fdb_destroy (vxlan , f );
1308
1326
}
1309
1327
}
1310
1328
spin_unlock_bh (& vxlan -> hash_lock );
@@ -1657,10 +1675,22 @@ static int vxlan_newlink(struct net *net, struct net_device *dev,
1657
1675
1658
1676
SET_ETHTOOL_OPS (dev , & vxlan_ethtool_ops );
1659
1677
1660
- err = register_netdevice (dev );
1678
+ /* create an fdb entry for default destination */
1679
+ err = vxlan_fdb_create (vxlan , all_zeros_mac ,
1680
+ vxlan -> default_dst .remote_ip ,
1681
+ NUD_REACHABLE |NUD_PERMANENT ,
1682
+ NLM_F_EXCL |NLM_F_CREATE ,
1683
+ vxlan -> dst_port , vxlan -> default_dst .remote_vni ,
1684
+ vxlan -> default_dst .remote_ifindex , NTF_SELF );
1661
1685
if (err )
1662
1686
return err ;
1663
1687
1688
+ err = register_netdevice (dev );
1689
+ if (err ) {
1690
+ vxlan_fdb_delete_defualt (vxlan );
1691
+ return err ;
1692
+ }
1693
+
1664
1694
list_add (& vxlan -> next , & vn -> vxlan_list );
1665
1695
1666
1696
return 0 ;
0 commit comments