br_mdb.c (8f8cb77e0b22d9044d8d57ab3bb18ea8d0474752) br_mdb.c (085b53c8beabf9b379762f73aaac562d6c428923)
1// SPDX-License-Identifier: GPL-2.0
2#include <linux/err.h>
3#include <linux/igmp.h>
4#include <linux/kernel.h>
5#include <linux/netdevice.h>
6#include <linux/rculist.h>
7#include <linux/skbuff.h>
8#include <linux/if_ether.h>

--- 87 unchanged lines hidden (view full) ---

96 if (hlist_empty(&p->src_list))
97 return 0;
98
99 nest = nla_nest_start(skb, MDBA_MDB_EATTR_SRC_LIST);
100 if (!nest)
101 return -EMSGSIZE;
102
103 hlist_for_each_entry_rcu(ent, &p->src_list, node,
1// SPDX-License-Identifier: GPL-2.0
2#include <linux/err.h>
3#include <linux/igmp.h>
4#include <linux/kernel.h>
5#include <linux/netdevice.h>
6#include <linux/rculist.h>
7#include <linux/skbuff.h>
8#include <linux/if_ether.h>

--- 87 unchanged lines hidden (view full) ---

96 if (hlist_empty(&p->src_list))
97 return 0;
98
99 nest = nla_nest_start(skb, MDBA_MDB_EATTR_SRC_LIST);
100 if (!nest)
101 return -EMSGSIZE;
102
103 hlist_for_each_entry_rcu(ent, &p->src_list, node,
104 lockdep_is_held(&p->port->br->multicast_lock)) {
104 lockdep_is_held(&p->key.port->br->multicast_lock)) {
105 nest_ent = nla_nest_start(skb, MDBA_MDB_SRCLIST_ENTRY);
106 if (!nest_ent)
107 goto out_cancel_err;
108 switch (ent->addr.proto) {
109 case htons(ETH_P_IP):
110 if (nla_put_in_addr(skb, MDBA_MDB_SRCATTR_ADDRESS,
111 ent->addr.src.ip4)) {
112 nla_nest_cancel(skb, nest_ent);

--- 38 unchanged lines hidden (view full) ---

151 struct timer_list *mtimer;
152 struct nlattr *nest_ent;
153 struct br_mdb_entry e;
154 u8 flags = 0;
155 int ifindex;
156
157 memset(&e, 0, sizeof(e));
158 if (p) {
105 nest_ent = nla_nest_start(skb, MDBA_MDB_SRCLIST_ENTRY);
106 if (!nest_ent)
107 goto out_cancel_err;
108 switch (ent->addr.proto) {
109 case htons(ETH_P_IP):
110 if (nla_put_in_addr(skb, MDBA_MDB_SRCATTR_ADDRESS,
111 ent->addr.src.ip4)) {
112 nla_nest_cancel(skb, nest_ent);

--- 38 unchanged lines hidden (view full) ---

151 struct timer_list *mtimer;
152 struct nlattr *nest_ent;
153 struct br_mdb_entry e;
154 u8 flags = 0;
155 int ifindex;
156
157 memset(&e, 0, sizeof(e));
158 if (p) {
159 ifindex = p->port->dev->ifindex;
159 ifindex = p->key.port->dev->ifindex;
160 mtimer = &p->timer;
161 flags = p->flags;
162 } else {
163 ifindex = mp->br->dev->ifindex;
164 mtimer = &mp->timer;
165 }
166
167 __mdb_entry_fill_flags(&e, flags);

--- 90 unchanged lines hidden (view full) ---

258 if (err) {
259 nla_nest_cancel(skb, nest2);
260 break;
261 }
262 }
263
264 for (pp = &mp->ports; (p = rcu_dereference(*pp)) != NULL;
265 pp = &p->next) {
160 mtimer = &p->timer;
161 flags = p->flags;
162 } else {
163 ifindex = mp->br->dev->ifindex;
164 mtimer = &mp->timer;
165 }
166
167 __mdb_entry_fill_flags(&e, flags);

--- 90 unchanged lines hidden (view full) ---

258 if (err) {
259 nla_nest_cancel(skb, nest2);
260 break;
261 }
262 }
263
264 for (pp = &mp->ports; (p = rcu_dereference(*pp)) != NULL;
265 pp = &p->next) {
266 if (!p->port)
266 if (!p->key.port)
267 continue;
268 if (pidx < s_pidx)
269 goto skip_pg;
270
271 err = __mdb_fill_info(skb, mp, p);
272 if (err) {
273 nla_nest_end(skb, nest2);
274 goto out;

--- 143 unchanged lines hidden (view full) ---

418 size_t addr_size = 0;
419
420 if (!pg)
421 goto out;
422
423 /* MDBA_MDB_EATTR_RTPROT */
424 nlmsg_size += nla_total_size(sizeof(u8));
425
267 continue;
268 if (pidx < s_pidx)
269 goto skip_pg;
270
271 err = __mdb_fill_info(skb, mp, p);
272 if (err) {
273 nla_nest_end(skb, nest2);
274 goto out;

--- 143 unchanged lines hidden (view full) ---

418 size_t addr_size = 0;
419
420 if (!pg)
421 goto out;
422
423 /* MDBA_MDB_EATTR_RTPROT */
424 nlmsg_size += nla_total_size(sizeof(u8));
425
426 switch (pg->addr.proto) {
426 switch (pg->key.addr.proto) {
427 case htons(ETH_P_IP):
428 /* MDBA_MDB_EATTR_SOURCE */
427 case htons(ETH_P_IP):
428 /* MDBA_MDB_EATTR_SOURCE */
429 if (pg->addr.src.ip4)
429 if (pg->key.addr.src.ip4)
430 nlmsg_size += nla_total_size(sizeof(__be32));
430 nlmsg_size += nla_total_size(sizeof(__be32));
431 if (pg->port->br->multicast_igmp_version == 2)
431 if (pg->key.port->br->multicast_igmp_version == 2)
432 goto out;
433 addr_size = sizeof(__be32);
434 break;
435#if IS_ENABLED(CONFIG_IPV6)
436 case htons(ETH_P_IPV6):
437 /* MDBA_MDB_EATTR_SOURCE */
432 goto out;
433 addr_size = sizeof(__be32);
434 break;
435#if IS_ENABLED(CONFIG_IPV6)
436 case htons(ETH_P_IPV6):
437 /* MDBA_MDB_EATTR_SOURCE */
438 if (!ipv6_addr_any(&pg->addr.src.ip6))
438 if (!ipv6_addr_any(&pg->key.addr.src.ip6))
439 nlmsg_size += nla_total_size(sizeof(struct in6_addr));
439 nlmsg_size += nla_total_size(sizeof(struct in6_addr));
440 if (pg->port->br->multicast_mld_version == 1)
440 if (pg->key.port->br->multicast_mld_version == 1)
441 goto out;
442 addr_size = sizeof(struct in6_addr);
443 break;
444#endif
445 }
446
447 /* MDBA_MDB_EATTR_GROUP_MODE */
448 nlmsg_size += nla_total_size(sizeof(u8));

--- 32 unchanged lines hidden (view full) ---

481 goto err;
482
483 spin_lock_bh(&br->multicast_lock);
484 mp = br_mdb_ip_get(br, &data->ip);
485 if (!mp)
486 goto out;
487 for (pp = &mp->ports; (p = mlock_dereference(*pp, br)) != NULL;
488 pp = &p->next) {
441 goto out;
442 addr_size = sizeof(struct in6_addr);
443 break;
444#endif
445 }
446
447 /* MDBA_MDB_EATTR_GROUP_MODE */
448 nlmsg_size += nla_total_size(sizeof(u8));

--- 32 unchanged lines hidden (view full) ---

481 goto err;
482
483 spin_lock_bh(&br->multicast_lock);
484 mp = br_mdb_ip_get(br, &data->ip);
485 if (!mp)
486 goto out;
487 for (pp = &mp->ports; (p = mlock_dereference(*pp, br)) != NULL;
488 pp = &p->next) {
489 if (p->port != port)
489 if (p->key.port != port)
490 continue;
491 p->flags |= MDB_PG_FLAGS_OFFLOAD;
492 }
493out:
494 spin_unlock_bh(&br->multicast_lock);
495err:
496 kfree(priv);
497}

--- 58 unchanged lines hidden (view full) ---

556
557 if (pg) {
558 if (mp->addr.proto == htons(ETH_P_IP))
559 ip_eth_mc_map(mp->addr.dst.ip4, mdb.addr);
560#if IS_ENABLED(CONFIG_IPV6)
561 else
562 ipv6_eth_mc_map(&mp->addr.dst.ip6, mdb.addr);
563#endif
490 continue;
491 p->flags |= MDB_PG_FLAGS_OFFLOAD;
492 }
493out:
494 spin_unlock_bh(&br->multicast_lock);
495err:
496 kfree(priv);
497}

--- 58 unchanged lines hidden (view full) ---

556
557 if (pg) {
558 if (mp->addr.proto == htons(ETH_P_IP))
559 ip_eth_mc_map(mp->addr.dst.ip4, mdb.addr);
560#if IS_ENABLED(CONFIG_IPV6)
561 else
562 ipv6_eth_mc_map(&mp->addr.dst.ip6, mdb.addr);
563#endif
564 mdb.obj.orig_dev = pg->port->dev;
564 mdb.obj.orig_dev = pg->key.port->dev;
565 switch (type) {
566 case RTM_NEWMDB:
567 complete_info = kmalloc(sizeof(*complete_info), GFP_ATOMIC);
568 if (!complete_info)
569 break;
565 switch (type) {
566 case RTM_NEWMDB:
567 complete_info = kmalloc(sizeof(*complete_info), GFP_ATOMIC);
568 if (!complete_info)
569 break;
570 complete_info->port = pg->port;
570 complete_info->port = pg->key.port;
571 complete_info->ip = mp->addr;
572 mdb.obj.complete_priv = complete_info;
573 mdb.obj.complete = br_mdb_complete;
571 complete_info->ip = mp->addr;
572 mdb.obj.complete_priv = complete_info;
573 mdb.obj.complete = br_mdb_complete;
574 if (switchdev_port_obj_add(pg->port->dev, &mdb.obj, NULL))
574 if (switchdev_port_obj_add(pg->key.port->dev, &mdb.obj, NULL))
575 kfree(complete_info);
576 break;
577 case RTM_DELMDB:
575 kfree(complete_info);
576 break;
577 case RTM_DELMDB:
578 switchdev_port_obj_del(pg->port->dev, &mdb.obj);
578 switchdev_port_obj_del(pg->key.port->dev, &mdb.obj);
579 break;
580 }
581 } else {
582 br_mdb_switchdev_host(dev, mp, type);
583 }
584
585 skb = nlmsg_new(rtnl_mdb_nlmsg_size(pg), GFP_ATOMIC);
586 if (!skb)

--- 277 unchanged lines hidden (view full) ---

864 br_mdb_notify(br->dev, mp, NULL, RTM_NEWMDB);
865
866 return 0;
867 }
868
869 for (pp = &mp->ports;
870 (p = mlock_dereference(*pp, br)) != NULL;
871 pp = &p->next) {
579 break;
580 }
581 } else {
582 br_mdb_switchdev_host(dev, mp, type);
583 }
584
585 skb = nlmsg_new(rtnl_mdb_nlmsg_size(pg), GFP_ATOMIC);
586 if (!skb)

--- 277 unchanged lines hidden (view full) ---

864 br_mdb_notify(br->dev, mp, NULL, RTM_NEWMDB);
865
866 return 0;
867 }
868
869 for (pp = &mp->ports;
870 (p = mlock_dereference(*pp, br)) != NULL;
871 pp = &p->next) {
872 if (p->port == port) {
872 if (p->key.port == port) {
873 NL_SET_ERR_MSG_MOD(extack, "Group is already joined by port");
874 return -EEXIST;
875 }
873 NL_SET_ERR_MSG_MOD(extack, "Group is already joined by port");
874 return -EEXIST;
875 }
876 if ((unsigned long)p->port < (unsigned long)port)
876 if ((unsigned long)p->key.port < (unsigned long)port)
877 break;
878 }
879
880 filter_mode = br_multicast_is_star_g(&group) ? MCAST_EXCLUDE :
881 MCAST_INCLUDE;
882
883 p = br_multicast_new_port_group(port, &group, *pp, entry->state, NULL,
884 filter_mode, RTPROT_STATIC);

--- 123 unchanged lines hidden (view full) ---

1008 if (!mp->ports && netif_running(br->dev))
1009 mod_timer(&mp->timer, jiffies);
1010 goto unlock;
1011 }
1012
1013 for (pp = &mp->ports;
1014 (p = mlock_dereference(*pp, br)) != NULL;
1015 pp = &p->next) {
877 break;
878 }
879
880 filter_mode = br_multicast_is_star_g(&group) ? MCAST_EXCLUDE :
881 MCAST_INCLUDE;
882
883 p = br_multicast_new_port_group(port, &group, *pp, entry->state, NULL,
884 filter_mode, RTPROT_STATIC);

--- 123 unchanged lines hidden (view full) ---

1008 if (!mp->ports && netif_running(br->dev))
1009 mod_timer(&mp->timer, jiffies);
1010 goto unlock;
1011 }
1012
1013 for (pp = &mp->ports;
1014 (p = mlock_dereference(*pp, br)) != NULL;
1015 pp = &p->next) {
1016 if (!p->port || p->port->dev->ifindex != entry->ifindex)
1016 if (!p->key.port || p->key.port->dev->ifindex != entry->ifindex)
1017 continue;
1018
1017 continue;
1018
1019 if (p->port->state == BR_STATE_DISABLED)
1019 if (p->key.port->state == BR_STATE_DISABLED)
1020 goto unlock;
1021
1022 br_multicast_del_pg(mp, p, pp);
1023 err = 0;
1024 break;
1025 }
1026
1027unlock:

--- 64 unchanged lines hidden ---
1020 goto unlock;
1021
1022 br_multicast_del_pg(mp, p, pp);
1023 err = 0;
1024 break;
1025 }
1026
1027unlock:

--- 64 unchanged lines hidden ---