1 // SPDX-License-Identifier: GPL-2.0
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>
10 #include <net/netlink.h>
11 #include <net/switchdev.h>
12 #if IS_ENABLED(CONFIG_IPV6)
14 #include <net/addrconf.h>
17 #include "br_private.h"
19 static int br_rports_fill_info(struct sk_buff
*skb
, struct netlink_callback
*cb
,
20 struct net_device
*dev
)
22 struct net_bridge
*br
= netdev_priv(dev
);
23 struct net_bridge_port
*p
;
24 struct nlattr
*nest
, *port_nest
;
26 if (!br
->multicast_router
|| hlist_empty(&br
->router_list
))
29 nest
= nla_nest_start_noflag(skb
, MDBA_ROUTER
);
33 hlist_for_each_entry_rcu(p
, &br
->router_list
, rlist
) {
36 port_nest
= nla_nest_start_noflag(skb
, MDBA_ROUTER_PORT
);
39 if (nla_put_nohdr(skb
, sizeof(u32
), &p
->dev
->ifindex
) ||
40 nla_put_u32(skb
, MDBA_ROUTER_PATTR_TIMER
,
41 br_timer_value(&p
->multicast_router_timer
)) ||
42 nla_put_u8(skb
, MDBA_ROUTER_PATTR_TYPE
,
43 p
->multicast_router
)) {
44 nla_nest_cancel(skb
, port_nest
);
47 nla_nest_end(skb
, port_nest
);
50 nla_nest_end(skb
, nest
);
53 nla_nest_cancel(skb
, nest
);
57 static void __mdb_entry_fill_flags(struct br_mdb_entry
*e
, unsigned char flags
)
59 e
->state
= flags
& MDB_PG_FLAGS_PERMANENT
;
61 if (flags
& MDB_PG_FLAGS_OFFLOAD
)
62 e
->flags
|= MDB_FLAGS_OFFLOAD
;
63 if (flags
& MDB_PG_FLAGS_FAST_LEAVE
)
64 e
->flags
|= MDB_FLAGS_FAST_LEAVE
;
67 static void __mdb_entry_to_br_ip(struct br_mdb_entry
*entry
, struct br_ip
*ip
)
69 memset(ip
, 0, sizeof(struct br_ip
));
71 ip
->proto
= entry
->addr
.proto
;
72 if (ip
->proto
== htons(ETH_P_IP
))
73 ip
->u
.ip4
= entry
->addr
.u
.ip4
;
74 #if IS_ENABLED(CONFIG_IPV6)
76 ip
->u
.ip6
= entry
->addr
.u
.ip6
;
80 static int __mdb_fill_info(struct sk_buff
*skb
,
81 struct net_bridge_mdb_entry
*mp
,
82 struct net_bridge_port_group
*p
)
84 struct timer_list
*mtimer
;
85 struct nlattr
*nest_ent
;
86 struct br_mdb_entry e
;
90 memset(&e
, 0, sizeof(e
));
92 ifindex
= p
->port
->dev
->ifindex
;
96 ifindex
= mp
->br
->dev
->ifindex
;
100 __mdb_entry_fill_flags(&e
, flags
);
102 e
.vid
= mp
->addr
.vid
;
103 if (mp
->addr
.proto
== htons(ETH_P_IP
))
104 e
.addr
.u
.ip4
= mp
->addr
.u
.ip4
;
105 #if IS_ENABLED(CONFIG_IPV6)
106 if (mp
->addr
.proto
== htons(ETH_P_IPV6
))
107 e
.addr
.u
.ip6
= mp
->addr
.u
.ip6
;
109 e
.addr
.proto
= mp
->addr
.proto
;
110 nest_ent
= nla_nest_start_noflag(skb
,
111 MDBA_MDB_ENTRY_INFO
);
115 if (nla_put_nohdr(skb
, sizeof(e
), &e
) ||
117 MDBA_MDB_EATTR_TIMER
,
118 br_timer_value(mtimer
))) {
119 nla_nest_cancel(skb
, nest_ent
);
122 nla_nest_end(skb
, nest_ent
);
127 static int br_mdb_fill_info(struct sk_buff
*skb
, struct netlink_callback
*cb
,
128 struct net_device
*dev
)
130 int idx
= 0, s_idx
= cb
->args
[1], err
= 0;
131 struct net_bridge
*br
= netdev_priv(dev
);
132 struct net_bridge_mdb_entry
*mp
;
133 struct nlattr
*nest
, *nest2
;
135 if (!br_opt_get(br
, BROPT_MULTICAST_ENABLED
))
138 nest
= nla_nest_start_noflag(skb
, MDBA_MDB
);
142 hlist_for_each_entry_rcu(mp
, &br
->mdb_list
, mdb_node
) {
143 struct net_bridge_port_group
*p
;
144 struct net_bridge_port_group __rcu
**pp
;
149 nest2
= nla_nest_start_noflag(skb
, MDBA_MDB_ENTRY
);
155 if (mp
->host_joined
) {
156 err
= __mdb_fill_info(skb
, mp
, NULL
);
158 nla_nest_cancel(skb
, nest2
);
163 for (pp
= &mp
->ports
; (p
= rcu_dereference(*pp
)) != NULL
;
168 err
= __mdb_fill_info(skb
, mp
, p
);
170 nla_nest_cancel(skb
, nest2
);
174 nla_nest_end(skb
, nest2
);
181 nla_nest_end(skb
, nest
);
185 static int br_mdb_valid_dump_req(const struct nlmsghdr
*nlh
,
186 struct netlink_ext_ack
*extack
)
188 struct br_port_msg
*bpm
;
190 if (nlh
->nlmsg_len
< nlmsg_msg_size(sizeof(*bpm
))) {
191 NL_SET_ERR_MSG_MOD(extack
, "Invalid header for mdb dump request");
195 bpm
= nlmsg_data(nlh
);
197 NL_SET_ERR_MSG_MOD(extack
, "Filtering by device index is not supported for mdb dump request");
200 if (nlmsg_attrlen(nlh
, sizeof(*bpm
))) {
201 NL_SET_ERR_MSG(extack
, "Invalid data after header in mdb dump request");
208 static int br_mdb_dump(struct sk_buff
*skb
, struct netlink_callback
*cb
)
210 struct net_device
*dev
;
211 struct net
*net
= sock_net(skb
->sk
);
212 struct nlmsghdr
*nlh
= NULL
;
215 if (cb
->strict_check
) {
216 int err
= br_mdb_valid_dump_req(cb
->nlh
, cb
->extack
);
226 cb
->seq
= net
->dev_base_seq
;
228 for_each_netdev_rcu(net
, dev
) {
229 if (dev
->priv_flags
& IFF_EBRIDGE
) {
230 struct br_port_msg
*bpm
;
235 nlh
= nlmsg_put(skb
, NETLINK_CB(cb
->skb
).portid
,
236 cb
->nlh
->nlmsg_seq
, RTM_GETMDB
,
237 sizeof(*bpm
), NLM_F_MULTI
);
241 bpm
= nlmsg_data(nlh
);
242 memset(bpm
, 0, sizeof(*bpm
));
243 bpm
->ifindex
= dev
->ifindex
;
244 if (br_mdb_fill_info(skb
, cb
, dev
) < 0)
246 if (br_rports_fill_info(skb
, cb
, dev
) < 0)
264 static int nlmsg_populate_mdb_fill(struct sk_buff
*skb
,
265 struct net_device
*dev
,
266 struct br_mdb_entry
*entry
, u32 pid
,
267 u32 seq
, int type
, unsigned int flags
)
269 struct nlmsghdr
*nlh
;
270 struct br_port_msg
*bpm
;
271 struct nlattr
*nest
, *nest2
;
273 nlh
= nlmsg_put(skb
, pid
, seq
, type
, sizeof(*bpm
), 0);
277 bpm
= nlmsg_data(nlh
);
278 memset(bpm
, 0, sizeof(*bpm
));
279 bpm
->family
= AF_BRIDGE
;
280 bpm
->ifindex
= dev
->ifindex
;
281 nest
= nla_nest_start_noflag(skb
, MDBA_MDB
);
284 nest2
= nla_nest_start_noflag(skb
, MDBA_MDB_ENTRY
);
288 if (nla_put(skb
, MDBA_MDB_ENTRY_INFO
, sizeof(*entry
), entry
))
291 nla_nest_end(skb
, nest2
);
292 nla_nest_end(skb
, nest
);
297 nla_nest_end(skb
, nest
);
299 nlmsg_cancel(skb
, nlh
);
303 static inline size_t rtnl_mdb_nlmsg_size(void)
305 return NLMSG_ALIGN(sizeof(struct br_port_msg
))
306 + nla_total_size(sizeof(struct br_mdb_entry
));
309 struct br_mdb_complete_info
{
310 struct net_bridge_port
*port
;
314 static void br_mdb_complete(struct net_device
*dev
, int err
, void *priv
)
316 struct br_mdb_complete_info
*data
= priv
;
317 struct net_bridge_port_group __rcu
**pp
;
318 struct net_bridge_port_group
*p
;
319 struct net_bridge_mdb_entry
*mp
;
320 struct net_bridge_port
*port
= data
->port
;
321 struct net_bridge
*br
= port
->br
;
326 spin_lock_bh(&br
->multicast_lock
);
327 mp
= br_mdb_ip_get(br
, &data
->ip
);
330 for (pp
= &mp
->ports
; (p
= mlock_dereference(*pp
, br
)) != NULL
;
334 p
->flags
|= MDB_PG_FLAGS_OFFLOAD
;
337 spin_unlock_bh(&br
->multicast_lock
);
342 static void br_mdb_switchdev_host_port(struct net_device
*dev
,
343 struct net_device
*lower_dev
,
344 struct br_mdb_entry
*entry
, int type
)
346 struct switchdev_obj_port_mdb mdb
= {
348 .id
= SWITCHDEV_OBJ_ID_HOST_MDB
,
349 .flags
= SWITCHDEV_F_DEFER
,
354 if (entry
->addr
.proto
== htons(ETH_P_IP
))
355 ip_eth_mc_map(entry
->addr
.u
.ip4
, mdb
.addr
);
356 #if IS_ENABLED(CONFIG_IPV6)
358 ipv6_eth_mc_map(&entry
->addr
.u
.ip6
, mdb
.addr
);
361 mdb
.obj
.orig_dev
= dev
;
364 switchdev_port_obj_add(lower_dev
, &mdb
.obj
, NULL
);
367 switchdev_port_obj_del(lower_dev
, &mdb
.obj
);
372 static void br_mdb_switchdev_host(struct net_device
*dev
,
373 struct br_mdb_entry
*entry
, int type
)
375 struct net_device
*lower_dev
;
376 struct list_head
*iter
;
378 netdev_for_each_lower_dev(dev
, lower_dev
, iter
)
379 br_mdb_switchdev_host_port(dev
, lower_dev
, entry
, type
);
382 static void __br_mdb_notify(struct net_device
*dev
, struct net_bridge_port
*p
,
383 struct br_mdb_entry
*entry
, int type
)
385 struct br_mdb_complete_info
*complete_info
;
386 struct switchdev_obj_port_mdb mdb
= {
388 .id
= SWITCHDEV_OBJ_ID_PORT_MDB
,
389 .flags
= SWITCHDEV_F_DEFER
,
393 struct net_device
*port_dev
;
394 struct net
*net
= dev_net(dev
);
398 port_dev
= __dev_get_by_index(net
, entry
->ifindex
);
399 if (entry
->addr
.proto
== htons(ETH_P_IP
))
400 ip_eth_mc_map(entry
->addr
.u
.ip4
, mdb
.addr
);
401 #if IS_ENABLED(CONFIG_IPV6)
403 ipv6_eth_mc_map(&entry
->addr
.u
.ip6
, mdb
.addr
);
406 mdb
.obj
.orig_dev
= port_dev
;
407 if (p
&& port_dev
&& type
== RTM_NEWMDB
) {
408 complete_info
= kmalloc(sizeof(*complete_info
), GFP_ATOMIC
);
410 complete_info
->port
= p
;
411 __mdb_entry_to_br_ip(entry
, &complete_info
->ip
);
412 mdb
.obj
.complete_priv
= complete_info
;
413 mdb
.obj
.complete
= br_mdb_complete
;
414 if (switchdev_port_obj_add(port_dev
, &mdb
.obj
, NULL
))
415 kfree(complete_info
);
417 } else if (p
&& port_dev
&& type
== RTM_DELMDB
) {
418 switchdev_port_obj_del(port_dev
, &mdb
.obj
);
422 br_mdb_switchdev_host(dev
, entry
, type
);
424 skb
= nlmsg_new(rtnl_mdb_nlmsg_size(), GFP_ATOMIC
);
428 err
= nlmsg_populate_mdb_fill(skb
, dev
, entry
, 0, 0, type
, NTF_SELF
);
434 rtnl_notify(skb
, net
, 0, RTNLGRP_MDB
, NULL
, GFP_ATOMIC
);
437 rtnl_set_sk_err(net
, RTNLGRP_MDB
, err
);
440 void br_mdb_notify(struct net_device
*dev
, struct net_bridge_port
*port
,
441 struct br_ip
*group
, int type
, u8 flags
)
443 struct br_mdb_entry entry
;
445 memset(&entry
, 0, sizeof(entry
));
447 entry
.ifindex
= port
->dev
->ifindex
;
449 entry
.ifindex
= dev
->ifindex
;
450 entry
.addr
.proto
= group
->proto
;
451 entry
.addr
.u
.ip4
= group
->u
.ip4
;
452 #if IS_ENABLED(CONFIG_IPV6)
453 entry
.addr
.u
.ip6
= group
->u
.ip6
;
455 entry
.vid
= group
->vid
;
456 __mdb_entry_fill_flags(&entry
, flags
);
457 __br_mdb_notify(dev
, port
, &entry
, type
);
460 static int nlmsg_populate_rtr_fill(struct sk_buff
*skb
,
461 struct net_device
*dev
,
462 int ifindex
, u32 pid
,
463 u32 seq
, int type
, unsigned int flags
)
465 struct br_port_msg
*bpm
;
466 struct nlmsghdr
*nlh
;
469 nlh
= nlmsg_put(skb
, pid
, seq
, type
, sizeof(*bpm
), 0);
473 bpm
= nlmsg_data(nlh
);
474 memset(bpm
, 0, sizeof(*bpm
));
475 bpm
->family
= AF_BRIDGE
;
476 bpm
->ifindex
= dev
->ifindex
;
477 nest
= nla_nest_start_noflag(skb
, MDBA_ROUTER
);
481 if (nla_put_u32(skb
, MDBA_ROUTER_PORT
, ifindex
))
484 nla_nest_end(skb
, nest
);
489 nla_nest_end(skb
, nest
);
491 nlmsg_cancel(skb
, nlh
);
495 static inline size_t rtnl_rtr_nlmsg_size(void)
497 return NLMSG_ALIGN(sizeof(struct br_port_msg
))
498 + nla_total_size(sizeof(__u32
));
501 void br_rtr_notify(struct net_device
*dev
, struct net_bridge_port
*port
,
504 struct net
*net
= dev_net(dev
);
509 ifindex
= port
? port
->dev
->ifindex
: 0;
510 skb
= nlmsg_new(rtnl_rtr_nlmsg_size(), GFP_ATOMIC
);
514 err
= nlmsg_populate_rtr_fill(skb
, dev
, ifindex
, 0, 0, type
, NTF_SELF
);
520 rtnl_notify(skb
, net
, 0, RTNLGRP_MDB
, NULL
, GFP_ATOMIC
);
524 rtnl_set_sk_err(net
, RTNLGRP_MDB
, err
);
527 static bool is_valid_mdb_entry(struct br_mdb_entry
*entry
)
529 if (entry
->ifindex
== 0)
532 if (entry
->addr
.proto
== htons(ETH_P_IP
)) {
533 if (!ipv4_is_multicast(entry
->addr
.u
.ip4
))
535 if (ipv4_is_local_multicast(entry
->addr
.u
.ip4
))
537 #if IS_ENABLED(CONFIG_IPV6)
538 } else if (entry
->addr
.proto
== htons(ETH_P_IPV6
)) {
539 if (ipv6_addr_is_ll_all_nodes(&entry
->addr
.u
.ip6
))
544 if (entry
->state
!= MDB_PERMANENT
&& entry
->state
!= MDB_TEMPORARY
)
546 if (entry
->vid
>= VLAN_VID_MASK
)
552 static int br_mdb_parse(struct sk_buff
*skb
, struct nlmsghdr
*nlh
,
553 struct net_device
**pdev
, struct br_mdb_entry
**pentry
)
555 struct net
*net
= sock_net(skb
->sk
);
556 struct br_mdb_entry
*entry
;
557 struct br_port_msg
*bpm
;
558 struct nlattr
*tb
[MDBA_SET_ENTRY_MAX
+1];
559 struct net_device
*dev
;
562 err
= nlmsg_parse_deprecated(nlh
, sizeof(*bpm
), tb
,
563 MDBA_SET_ENTRY_MAX
, NULL
, NULL
);
567 bpm
= nlmsg_data(nlh
);
568 if (bpm
->ifindex
== 0) {
569 pr_info("PF_BRIDGE: br_mdb_parse() with invalid ifindex\n");
573 dev
= __dev_get_by_index(net
, bpm
->ifindex
);
575 pr_info("PF_BRIDGE: br_mdb_parse() with unknown ifindex\n");
579 if (!(dev
->priv_flags
& IFF_EBRIDGE
)) {
580 pr_info("PF_BRIDGE: br_mdb_parse() with non-bridge\n");
586 if (!tb
[MDBA_SET_ENTRY
] ||
587 nla_len(tb
[MDBA_SET_ENTRY
]) != sizeof(struct br_mdb_entry
)) {
588 pr_info("PF_BRIDGE: br_mdb_parse() with invalid attr\n");
592 entry
= nla_data(tb
[MDBA_SET_ENTRY
]);
593 if (!is_valid_mdb_entry(entry
)) {
594 pr_info("PF_BRIDGE: br_mdb_parse() with invalid entry\n");
602 static int br_mdb_add_group(struct net_bridge
*br
, struct net_bridge_port
*port
,
603 struct br_ip
*group
, unsigned char state
)
605 struct net_bridge_mdb_entry
*mp
;
606 struct net_bridge_port_group
*p
;
607 struct net_bridge_port_group __rcu
**pp
;
608 unsigned long now
= jiffies
;
611 mp
= br_mdb_ip_get(br
, group
);
613 mp
= br_multicast_new_group(br
, group
);
614 err
= PTR_ERR_OR_ZERO(mp
);
621 /* don't allow any flags for host-joined groups */
627 br_multicast_host_join(mp
, false);
632 for (pp
= &mp
->ports
;
633 (p
= mlock_dereference(*pp
, br
)) != NULL
;
637 if ((unsigned long)p
->port
< (unsigned long)port
)
641 p
= br_multicast_new_port_group(port
, group
, *pp
, state
, NULL
);
644 rcu_assign_pointer(*pp
, p
);
645 if (state
== MDB_TEMPORARY
)
646 mod_timer(&p
->timer
, now
+ br
->multicast_membership_interval
);
651 static int __br_mdb_add(struct net
*net
, struct net_bridge
*br
,
652 struct br_mdb_entry
*entry
)
655 struct net_device
*dev
;
656 struct net_bridge_port
*p
= NULL
;
659 if (!netif_running(br
->dev
) || !br_opt_get(br
, BROPT_MULTICAST_ENABLED
))
662 if (entry
->ifindex
!= br
->dev
->ifindex
) {
663 dev
= __dev_get_by_index(net
, entry
->ifindex
);
667 p
= br_port_get_rtnl(dev
);
668 if (!p
|| p
->br
!= br
|| p
->state
== BR_STATE_DISABLED
)
672 __mdb_entry_to_br_ip(entry
, &ip
);
674 spin_lock_bh(&br
->multicast_lock
);
675 ret
= br_mdb_add_group(br
, p
, &ip
, entry
->state
);
676 spin_unlock_bh(&br
->multicast_lock
);
680 static int br_mdb_add(struct sk_buff
*skb
, struct nlmsghdr
*nlh
,
681 struct netlink_ext_ack
*extack
)
683 struct net
*net
= sock_net(skb
->sk
);
684 struct net_bridge_vlan_group
*vg
;
685 struct net_bridge_port
*p
= NULL
;
686 struct net_device
*dev
, *pdev
;
687 struct br_mdb_entry
*entry
;
688 struct net_bridge_vlan
*v
;
689 struct net_bridge
*br
;
692 err
= br_mdb_parse(skb
, nlh
, &dev
, &entry
);
696 br
= netdev_priv(dev
);
698 if (entry
->ifindex
!= br
->dev
->ifindex
) {
699 pdev
= __dev_get_by_index(net
, entry
->ifindex
);
703 p
= br_port_get_rtnl(pdev
);
704 if (!p
|| p
->br
!= br
|| p
->state
== BR_STATE_DISABLED
)
706 vg
= nbp_vlan_group(p
);
708 vg
= br_vlan_group(br
);
711 /* If vlan filtering is enabled and VLAN is not specified
712 * install mdb entry on all vlans configured on the port.
714 if (br_vlan_enabled(br
->dev
) && vg
&& entry
->vid
== 0) {
715 list_for_each_entry(v
, &vg
->vlan_list
, vlist
) {
717 err
= __br_mdb_add(net
, br
, entry
);
720 __br_mdb_notify(dev
, p
, entry
, RTM_NEWMDB
);
723 err
= __br_mdb_add(net
, br
, entry
);
725 __br_mdb_notify(dev
, p
, entry
, RTM_NEWMDB
);
731 static int __br_mdb_del(struct net_bridge
*br
, struct br_mdb_entry
*entry
)
733 struct net_bridge_mdb_entry
*mp
;
734 struct net_bridge_port_group
*p
;
735 struct net_bridge_port_group __rcu
**pp
;
739 if (!netif_running(br
->dev
) || !br_opt_get(br
, BROPT_MULTICAST_ENABLED
))
742 __mdb_entry_to_br_ip(entry
, &ip
);
744 spin_lock_bh(&br
->multicast_lock
);
745 mp
= br_mdb_ip_get(br
, &ip
);
750 if (entry
->ifindex
== mp
->br
->dev
->ifindex
&& mp
->host_joined
) {
751 br_multicast_host_leave(mp
, false);
753 if (!mp
->ports
&& netif_running(br
->dev
))
754 mod_timer(&mp
->timer
, jiffies
);
758 for (pp
= &mp
->ports
;
759 (p
= mlock_dereference(*pp
, br
)) != NULL
;
761 if (!p
->port
|| p
->port
->dev
->ifindex
!= entry
->ifindex
)
764 if (p
->port
->state
== BR_STATE_DISABLED
)
767 __mdb_entry_fill_flags(entry
, p
->flags
);
768 rcu_assign_pointer(*pp
, p
->next
);
769 hlist_del_init(&p
->mglist
);
770 del_timer(&p
->timer
);
774 if (!mp
->ports
&& !mp
->host_joined
&&
775 netif_running(br
->dev
))
776 mod_timer(&mp
->timer
, jiffies
);
781 spin_unlock_bh(&br
->multicast_lock
);
785 static int br_mdb_del(struct sk_buff
*skb
, struct nlmsghdr
*nlh
,
786 struct netlink_ext_ack
*extack
)
788 struct net
*net
= sock_net(skb
->sk
);
789 struct net_bridge_vlan_group
*vg
;
790 struct net_bridge_port
*p
= NULL
;
791 struct net_device
*dev
, *pdev
;
792 struct br_mdb_entry
*entry
;
793 struct net_bridge_vlan
*v
;
794 struct net_bridge
*br
;
797 err
= br_mdb_parse(skb
, nlh
, &dev
, &entry
);
801 br
= netdev_priv(dev
);
803 if (entry
->ifindex
!= br
->dev
->ifindex
) {
804 pdev
= __dev_get_by_index(net
, entry
->ifindex
);
808 p
= br_port_get_rtnl(pdev
);
809 if (!p
|| p
->br
!= br
|| p
->state
== BR_STATE_DISABLED
)
811 vg
= nbp_vlan_group(p
);
813 vg
= br_vlan_group(br
);
816 /* If vlan filtering is enabled and VLAN is not specified
817 * delete mdb entry on all vlans configured on the port.
819 if (br_vlan_enabled(br
->dev
) && vg
&& entry
->vid
== 0) {
820 list_for_each_entry(v
, &vg
->vlan_list
, vlist
) {
822 err
= __br_mdb_del(br
, entry
);
824 __br_mdb_notify(dev
, p
, entry
, RTM_DELMDB
);
827 err
= __br_mdb_del(br
, entry
);
829 __br_mdb_notify(dev
, p
, entry
, RTM_DELMDB
);
835 void br_mdb_init(void)
837 rtnl_register_module(THIS_MODULE
, PF_BRIDGE
, RTM_GETMDB
, NULL
, br_mdb_dump
, 0);
838 rtnl_register_module(THIS_MODULE
, PF_BRIDGE
, RTM_NEWMDB
, br_mdb_add
, NULL
, 0);
839 rtnl_register_module(THIS_MODULE
, PF_BRIDGE
, RTM_DELMDB
, br_mdb_del
, NULL
, 0);
842 void br_mdb_uninit(void)
844 rtnl_unregister(PF_BRIDGE
, RTM_GETMDB
);
845 rtnl_unregister(PF_BRIDGE
, RTM_NEWMDB
);
846 rtnl_unregister(PF_BRIDGE
, RTM_DELMDB
);