@@ -74,6 +74,14 @@ struct vxlan_mdb_config {
7474 u8 rt_protocol ;
7575};
7676
77+ struct vxlan_mdb_flush_desc {
78+ union vxlan_addr remote_ip ;
79+ __be32 src_vni ;
80+ __be32 remote_vni ;
81+ __be16 remote_port ;
82+ u8 rt_protocol ;
83+ };
84+
7785static const struct rhashtable_params vxlan_mdb_rht_params = {
7886 .head_offset = offsetof(struct vxlan_mdb_entry , rhnode ),
7987 .key_offset = offsetof(struct vxlan_mdb_entry , key ),
@@ -1306,6 +1314,145 @@ int vxlan_mdb_del(struct net_device *dev, struct nlattr *tb[],
13061314 return err ;
13071315}
13081316
1317+ static const struct nla_policy
1318+ vxlan_mdbe_attrs_del_bulk_pol [MDBE_ATTR_MAX + 1 ] = {
1319+ [MDBE_ATTR_RTPROT ] = NLA_POLICY_MIN (NLA_U8 , RTPROT_STATIC ),
1320+ [MDBE_ATTR_DST ] = NLA_POLICY_RANGE (NLA_BINARY ,
1321+ sizeof (struct in_addr ),
1322+ sizeof (struct in6_addr )),
1323+ [MDBE_ATTR_DST_PORT ] = { .type = NLA_U16 },
1324+ [MDBE_ATTR_VNI ] = NLA_POLICY_FULL_RANGE (NLA_U32 , & vni_range ),
1325+ [MDBE_ATTR_SRC_VNI ] = NLA_POLICY_FULL_RANGE (NLA_U32 , & vni_range ),
1326+ [MDBE_ATTR_STATE_MASK ] = NLA_POLICY_MASK (NLA_U8 , MDB_PERMANENT ),
1327+ };
1328+
1329+ static int vxlan_mdb_flush_desc_init (struct vxlan_dev * vxlan ,
1330+ struct vxlan_mdb_flush_desc * desc ,
1331+ struct nlattr * tb [],
1332+ struct netlink_ext_ack * extack )
1333+ {
1334+ struct br_mdb_entry * entry = nla_data (tb [MDBA_SET_ENTRY ]);
1335+ struct nlattr * mdbe_attrs [MDBE_ATTR_MAX + 1 ];
1336+ int err ;
1337+
1338+ if (entry -> ifindex && entry -> ifindex != vxlan -> dev -> ifindex ) {
1339+ NL_SET_ERR_MSG_MOD (extack , "Invalid port net device" );
1340+ return - EINVAL ;
1341+ }
1342+
1343+ if (entry -> vid ) {
1344+ NL_SET_ERR_MSG_MOD (extack , "VID must not be specified" );
1345+ return - EINVAL ;
1346+ }
1347+
1348+ if (!tb [MDBA_SET_ENTRY_ATTRS ])
1349+ return 0 ;
1350+
1351+ err = nla_parse_nested (mdbe_attrs , MDBE_ATTR_MAX ,
1352+ tb [MDBA_SET_ENTRY_ATTRS ],
1353+ vxlan_mdbe_attrs_del_bulk_pol , extack );
1354+ if (err )
1355+ return err ;
1356+
1357+ if (mdbe_attrs [MDBE_ATTR_STATE_MASK ]) {
1358+ u8 state_mask = nla_get_u8 (mdbe_attrs [MDBE_ATTR_STATE_MASK ]);
1359+
1360+ if ((state_mask & MDB_PERMANENT ) && !(entry -> state & MDB_PERMANENT )) {
1361+ NL_SET_ERR_MSG_MOD (extack , "Only permanent MDB entries are supported" );
1362+ return - EINVAL ;
1363+ }
1364+ }
1365+
1366+ if (mdbe_attrs [MDBE_ATTR_RTPROT ])
1367+ desc -> rt_protocol = nla_get_u8 (mdbe_attrs [MDBE_ATTR_RTPROT ]);
1368+
1369+ if (mdbe_attrs [MDBE_ATTR_DST ])
1370+ vxlan_nla_get_addr (& desc -> remote_ip , mdbe_attrs [MDBE_ATTR_DST ]);
1371+
1372+ if (mdbe_attrs [MDBE_ATTR_DST_PORT ])
1373+ desc -> remote_port =
1374+ cpu_to_be16 (nla_get_u16 (mdbe_attrs [MDBE_ATTR_DST_PORT ]));
1375+
1376+ if (mdbe_attrs [MDBE_ATTR_VNI ])
1377+ desc -> remote_vni =
1378+ cpu_to_be32 (nla_get_u32 (mdbe_attrs [MDBE_ATTR_VNI ]));
1379+
1380+ if (mdbe_attrs [MDBE_ATTR_SRC_VNI ])
1381+ desc -> src_vni =
1382+ cpu_to_be32 (nla_get_u32 (mdbe_attrs [MDBE_ATTR_SRC_VNI ]));
1383+
1384+ return 0 ;
1385+ }
1386+
1387+ static void vxlan_mdb_remotes_flush (struct vxlan_dev * vxlan ,
1388+ struct vxlan_mdb_entry * mdb_entry ,
1389+ const struct vxlan_mdb_flush_desc * desc )
1390+ {
1391+ struct vxlan_mdb_remote * remote , * tmp ;
1392+
1393+ list_for_each_entry_safe (remote , tmp , & mdb_entry -> remotes , list ) {
1394+ struct vxlan_rdst * rd = rtnl_dereference (remote -> rd );
1395+ __be32 remote_vni ;
1396+
1397+ if (desc -> remote_ip .sa .sa_family &&
1398+ !vxlan_addr_equal (& desc -> remote_ip , & rd -> remote_ip ))
1399+ continue ;
1400+
1401+ /* Encapsulation is performed with source VNI if remote VNI
1402+ * is not set.
1403+ */
1404+ remote_vni = rd -> remote_vni ? : mdb_entry -> key .vni ;
1405+ if (desc -> remote_vni && desc -> remote_vni != remote_vni )
1406+ continue ;
1407+
1408+ if (desc -> remote_port && desc -> remote_port != rd -> remote_port )
1409+ continue ;
1410+
1411+ if (desc -> rt_protocol &&
1412+ desc -> rt_protocol != remote -> rt_protocol )
1413+ continue ;
1414+
1415+ vxlan_mdb_remote_del (vxlan , mdb_entry , remote );
1416+ }
1417+ }
1418+
1419+ static void vxlan_mdb_flush (struct vxlan_dev * vxlan ,
1420+ const struct vxlan_mdb_flush_desc * desc )
1421+ {
1422+ struct vxlan_mdb_entry * mdb_entry ;
1423+ struct hlist_node * tmp ;
1424+
1425+ /* The removal of an entry cannot trigger the removal of another entry
1426+ * since entries are always added to the head of the list.
1427+ */
1428+ hlist_for_each_entry_safe (mdb_entry , tmp , & vxlan -> mdb_list , mdb_node ) {
1429+ if (desc -> src_vni && desc -> src_vni != mdb_entry -> key .vni )
1430+ continue ;
1431+
1432+ vxlan_mdb_remotes_flush (vxlan , mdb_entry , desc );
1433+ /* Entry will only be removed if its remotes list is empty. */
1434+ vxlan_mdb_entry_put (vxlan , mdb_entry );
1435+ }
1436+ }
1437+
1438+ int vxlan_mdb_del_bulk (struct net_device * dev , struct nlattr * tb [],
1439+ struct netlink_ext_ack * extack )
1440+ {
1441+ struct vxlan_dev * vxlan = netdev_priv (dev );
1442+ struct vxlan_mdb_flush_desc desc = {};
1443+ int err ;
1444+
1445+ ASSERT_RTNL ();
1446+
1447+ err = vxlan_mdb_flush_desc_init (vxlan , & desc , tb , extack );
1448+ if (err )
1449+ return err ;
1450+
1451+ vxlan_mdb_flush (vxlan , & desc );
1452+
1453+ return 0 ;
1454+ }
1455+
13091456static const struct nla_policy vxlan_mdbe_attrs_get_pol [MDBE_ATTR_MAX + 1 ] = {
13101457 [MDBE_ATTR_SOURCE ] = NLA_POLICY_RANGE (NLA_BINARY ,
13111458 sizeof (struct in_addr ),
@@ -1575,29 +1722,6 @@ static void vxlan_mdb_check_empty(void *ptr, void *arg)
15751722 WARN_ON_ONCE (1 );
15761723}
15771724
1578- static void vxlan_mdb_remotes_flush (struct vxlan_dev * vxlan ,
1579- struct vxlan_mdb_entry * mdb_entry )
1580- {
1581- struct vxlan_mdb_remote * remote , * tmp ;
1582-
1583- list_for_each_entry_safe (remote , tmp , & mdb_entry -> remotes , list )
1584- vxlan_mdb_remote_del (vxlan , mdb_entry , remote );
1585- }
1586-
1587- static void vxlan_mdb_entries_flush (struct vxlan_dev * vxlan )
1588- {
1589- struct vxlan_mdb_entry * mdb_entry ;
1590- struct hlist_node * tmp ;
1591-
1592- /* The removal of an entry cannot trigger the removal of another entry
1593- * since entries are always added to the head of the list.
1594- */
1595- hlist_for_each_entry_safe (mdb_entry , tmp , & vxlan -> mdb_list , mdb_node ) {
1596- vxlan_mdb_remotes_flush (vxlan , mdb_entry );
1597- vxlan_mdb_entry_put (vxlan , mdb_entry );
1598- }
1599- }
1600-
16011725int vxlan_mdb_init (struct vxlan_dev * vxlan )
16021726{
16031727 int err ;
@@ -1613,7 +1737,9 @@ int vxlan_mdb_init(struct vxlan_dev *vxlan)
16131737
16141738void vxlan_mdb_fini (struct vxlan_dev * vxlan )
16151739{
1616- vxlan_mdb_entries_flush (vxlan );
1740+ struct vxlan_mdb_flush_desc desc = {};
1741+
1742+ vxlan_mdb_flush (vxlan , & desc );
16171743 WARN_ON_ONCE (vxlan -> cfg .flags & VXLAN_F_MDB );
16181744 rhashtable_free_and_destroy (& vxlan -> mdb_tbl , vxlan_mdb_check_empty ,
16191745 NULL );
0 commit comments