Lines Matching +full:- +full:cfg
1 // SPDX-License-Identifier: GPL-2.0
23 *timer = br_timer_value(&pmctx->ip4_mc_router_timer); in br_ip4_rports_get_timer()
24 return !hlist_unhashed(&pmctx->ip4_rlist); in br_ip4_rports_get_timer()
32 *timer = br_timer_value(&pmctx->ip6_mc_router_timer); in br_ip6_rports_get_timer()
33 return !hlist_unhashed(&pmctx->ip6_rlist); in br_ip6_rports_get_timer()
56 hlist_for_each_entry_rcu(pmctx, &brmctx->ip4_mc_router_list, in br_rports_size()
61 hlist_for_each_entry_rcu(pmctx, &brmctx->ip6_mc_router_list, in br_rports_size()
73 u16 vid = brmctx->vlan ? brmctx->vlan->vid : 0; in br_rports_fill_info()
79 if (!brmctx->multicast_router || !br_rports_have_mc_router(brmctx)) in br_rports_fill_info()
84 return -EMSGSIZE; in br_rports_fill_info()
86 list_for_each_entry_rcu(p, &brmctx->br->port_list, list) { in br_rports_fill_info()
95 pmctx = &v->port_mcast_ctx; in br_rports_fill_info()
97 pmctx = &p->multicast_ctx; in br_rports_fill_info()
110 if (nla_put_nohdr(skb, sizeof(u32), &p->dev->ifindex) || in br_rports_fill_info()
114 p->multicast_ctx.multicast_router) || in br_rports_fill_info()
132 return -EMSGSIZE; in br_rports_fill_info()
137 e->state = flags & MDB_PG_FLAGS_PERMANENT; in __mdb_entry_fill_flags()
138 e->flags = 0; in __mdb_entry_fill_flags()
140 e->flags |= MDB_FLAGS_OFFLOAD; in __mdb_entry_fill_flags()
142 e->flags |= MDB_FLAGS_FAST_LEAVE; in __mdb_entry_fill_flags()
144 e->flags |= MDB_FLAGS_STAR_EXCL; in __mdb_entry_fill_flags()
146 e->flags |= MDB_FLAGS_BLOCKED; in __mdb_entry_fill_flags()
153 ip->vid = entry->vid; in __mdb_entry_to_br_ip()
154 ip->proto = entry->addr.proto; in __mdb_entry_to_br_ip()
155 switch (ip->proto) { in __mdb_entry_to_br_ip()
157 ip->dst.ip4 = entry->addr.u.ip4; in __mdb_entry_to_br_ip()
159 ip->src.ip4 = nla_get_in_addr(mdb_attrs[MDBE_ATTR_SOURCE]); in __mdb_entry_to_br_ip()
163 ip->dst.ip6 = entry->addr.u.ip6; in __mdb_entry_to_br_ip()
165 ip->src.ip6 = nla_get_in6_addr(mdb_attrs[MDBE_ATTR_SOURCE]); in __mdb_entry_to_br_ip()
169 ether_addr_copy(ip->dst.mac_addr, entry->addr.u.mac_addr); in __mdb_entry_to_br_ip()
180 if (hlist_empty(&p->src_list)) in __mdb_fill_srcs()
185 return -EMSGSIZE; in __mdb_fill_srcs()
187 hlist_for_each_entry_rcu(ent, &p->src_list, node, in __mdb_fill_srcs()
188 lockdep_is_held(&p->key.port->br->multicast_lock)) { in __mdb_fill_srcs()
192 switch (ent->addr.proto) { in __mdb_fill_srcs()
195 ent->addr.src.ip4)) { in __mdb_fill_srcs()
203 &ent->addr.src.ip6)) { in __mdb_fill_srcs()
214 br_timer_value(&ent->timer))) { in __mdb_fill_srcs()
227 return -EMSGSIZE; in __mdb_fill_srcs()
243 ifindex = p->key.port->dev->ifindex; in __mdb_fill_info()
244 mtimer = &p->timer; in __mdb_fill_info()
245 flags = p->flags; in __mdb_fill_info()
247 ifindex = mp->br->dev->ifindex; in __mdb_fill_info()
248 mtimer = &mp->timer; in __mdb_fill_info()
253 e.vid = mp->addr.vid; in __mdb_fill_info()
254 if (mp->addr.proto == htons(ETH_P_IP)) { in __mdb_fill_info()
255 e.addr.u.ip4 = mp->addr.dst.ip4; in __mdb_fill_info()
257 } else if (mp->addr.proto == htons(ETH_P_IPV6)) { in __mdb_fill_info()
258 e.addr.u.ip6 = mp->addr.dst.ip6; in __mdb_fill_info()
261 ether_addr_copy(e.addr.u.mac_addr, mp->addr.dst.mac_addr); in __mdb_fill_info()
264 e.addr.proto = mp->addr.proto; in __mdb_fill_info()
268 return -EMSGSIZE; in __mdb_fill_info()
276 switch (mp->addr.proto) { in __mdb_fill_info()
278 dump_srcs_mode = !!(mp->br->multicast_ctx.multicast_igmp_version == 3); in __mdb_fill_info()
279 if (mp->addr.src.ip4) { in __mdb_fill_info()
281 mp->addr.src.ip4)) in __mdb_fill_info()
288 dump_srcs_mode = !!(mp->br->multicast_ctx.multicast_mld_version == 2); in __mdb_fill_info()
289 if (!ipv6_addr_any(&mp->addr.src.ip6)) { in __mdb_fill_info()
291 &mp->addr.src.ip6)) in __mdb_fill_info()
298 ether_addr_copy(e.addr.u.mac_addr, mp->addr.dst.mac_addr); in __mdb_fill_info()
301 if (nla_put_u8(skb, MDBA_MDB_EATTR_RTPROT, p->rt_protocol)) in __mdb_fill_info()
306 p->filter_mode))) in __mdb_fill_info()
315 return -EMSGSIZE; in __mdb_fill_info()
321 int idx = 0, s_idx = cb->args[1], err = 0, pidx = 0, s_pidx = cb->args[2]; in br_mdb_fill_info()
328 return -EMSGSIZE; in br_mdb_fill_info()
330 hlist_for_each_entry_rcu(mp, &br->mdb_list, mdb_node) { in br_mdb_fill_info()
339 err = -EMSGSIZE; in br_mdb_fill_info()
343 if (!s_pidx && mp->host_joined) { in br_mdb_fill_info()
351 for (pp = &mp->ports; (p = rcu_dereference(*pp)) != NULL; in br_mdb_fill_info()
352 pp = &p->next) { in br_mdb_fill_info()
353 if (!p->key.port) in br_mdb_fill_info()
374 cb->args[1] = idx; in br_mdb_fill_info()
375 cb->args[2] = pidx; in br_mdb_fill_info()
388 nlh = nlmsg_put(skb, NETLINK_CB(cb->skb).portid, in br_mdb_dump()
389 cb->nlh->nlmsg_seq, RTM_GETMDB, sizeof(*bpm), in br_mdb_dump()
392 return -EMSGSIZE; in br_mdb_dump()
396 bpm->ifindex = dev->ifindex; in br_mdb_dump()
403 err = br_rports_fill_info(skb, &br->multicast_ctx); in br_mdb_dump()
425 return -EMSGSIZE; in nlmsg_populate_mdb_fill()
429 bpm->family = AF_BRIDGE; in nlmsg_populate_mdb_fill()
430 bpm->ifindex = dev->ifindex; in nlmsg_populate_mdb_fill()
450 return -EMSGSIZE; in nlmsg_populate_mdb_fill()
469 switch (pg->key.addr.proto) { in rtnl_mdb_nlmsg_pg_size()
472 if (pg->key.addr.src.ip4) in rtnl_mdb_nlmsg_pg_size()
474 if (pg->key.port->br->multicast_ctx.multicast_igmp_version == 2) in rtnl_mdb_nlmsg_pg_size()
481 if (!ipv6_addr_any(&pg->key.addr.src.ip6)) in rtnl_mdb_nlmsg_pg_size()
483 if (pg->key.port->br->multicast_ctx.multicast_mld_version == 1) in rtnl_mdb_nlmsg_pg_size()
494 if (!hlist_empty(&pg->src_list)) in rtnl_mdb_nlmsg_pg_size()
497 hlist_for_each_entry(ent, &pg->src_list, node) { in rtnl_mdb_nlmsg_pg_size()
527 int err = -ENOBUFS; in br_mdb_notify()
558 return -EMSGSIZE; in nlmsg_populate_rtr_fill()
562 bpm->family = AF_BRIDGE; in nlmsg_populate_rtr_fill()
563 bpm->ifindex = dev->ifindex; in nlmsg_populate_rtr_fill()
589 return -EMSGSIZE; in nlmsg_populate_rtr_fill()
604 int err = -ENOBUFS; in br_rtr_notify()
608 ifindex = pmctx ? pmctx->port->dev->ifindex : 0; in br_rtr_notify()
609 vid = pmctx && br_multicast_port_ctx_is_vlan(pmctx) ? pmctx->vlan->vid : in br_rtr_notify()
698 brmctx = &br->multicast_ctx; in __br_mdb_choose_context()
702 if (!entry->vid) { in __br_mdb_choose_context()
707 v = br_vlan_find(br_vlan_group(br), entry->vid); in __br_mdb_choose_context()
712 if (br_multicast_ctx_vlan_global_disabled(&v->br_mcast_ctx)) { in __br_mdb_choose_context()
716 brmctx = &v->br_mcast_ctx; in __br_mdb_choose_context()
721 static int br_mdb_replace_group_sg(const struct br_mdb_config *cfg, in br_mdb_replace_group_sg() argument
729 pg->flags = flags; in br_mdb_replace_group_sg()
730 pg->rt_protocol = cfg->rt_protocol; in br_mdb_replace_group_sg()
731 if (!(flags & MDB_PG_FLAGS_PERMANENT) && !cfg->src_entry) in br_mdb_replace_group_sg()
732 mod_timer(&pg->timer, in br_mdb_replace_group_sg()
733 now + brmctx->multicast_membership_interval); in br_mdb_replace_group_sg()
735 del_timer(&pg->timer); in br_mdb_replace_group_sg()
737 br_mdb_notify(cfg->br->dev, mp, pg, RTM_NEWMDB); in br_mdb_replace_group_sg()
742 static int br_mdb_add_group_sg(const struct br_mdb_config *cfg, in br_mdb_add_group_sg() argument
752 for (pp = &mp->ports; in br_mdb_add_group_sg()
753 (p = mlock_dereference(*pp, cfg->br)) != NULL; in br_mdb_add_group_sg()
754 pp = &p->next) { in br_mdb_add_group_sg()
755 if (p->key.port == cfg->p) { in br_mdb_add_group_sg()
756 if (!(cfg->nlflags & NLM_F_REPLACE)) { in br_mdb_add_group_sg()
758 return -EEXIST; in br_mdb_add_group_sg()
760 return br_mdb_replace_group_sg(cfg, mp, p, brmctx, in br_mdb_add_group_sg()
763 if ((unsigned long)p->key.port < (unsigned long)cfg->p) in br_mdb_add_group_sg()
767 p = br_multicast_new_port_group(cfg->p, &cfg->group, *pp, flags, NULL, in br_mdb_add_group_sg()
768 MCAST_INCLUDE, cfg->rt_protocol, extack); in br_mdb_add_group_sg()
770 return -ENOMEM; in br_mdb_add_group_sg()
773 if (!(flags & MDB_PG_FLAGS_PERMANENT) && !cfg->src_entry) in br_mdb_add_group_sg()
774 mod_timer(&p->timer, in br_mdb_add_group_sg()
775 now + brmctx->multicast_membership_interval); in br_mdb_add_group_sg()
776 br_mdb_notify(cfg->br->dev, mp, p, RTM_NEWMDB); in br_mdb_add_group_sg()
781 if (br_multicast_should_handle_mode(brmctx, cfg->group.proto)) { in br_mdb_add_group_sg()
785 star_group = p->key.addr; in br_mdb_add_group_sg()
787 star_mp = br_mdb_ip_get(cfg->br, &star_group); in br_mdb_add_group_sg()
795 static int br_mdb_add_group_src_fwd(const struct br_mdb_config *cfg, in br_mdb_add_group_src_fwd() argument
805 sg_ip = cfg->group; in br_mdb_add_group_src_fwd()
806 sg_ip.src = src_ip->src; in br_mdb_add_group_src_fwd()
807 sgmp = br_multicast_new_group(cfg->br, &sg_ip); in br_mdb_add_group_src_fwd()
813 if (cfg->entry->state == MDB_PERMANENT) in br_mdb_add_group_src_fwd()
815 if (cfg->filter_mode == MCAST_EXCLUDE) in br_mdb_add_group_src_fwd()
819 sg_cfg.br = cfg->br; in br_mdb_add_group_src_fwd()
820 sg_cfg.p = cfg->p; in br_mdb_add_group_src_fwd()
821 sg_cfg.entry = cfg->entry; in br_mdb_add_group_src_fwd()
825 sg_cfg.rt_protocol = cfg->rt_protocol; in br_mdb_add_group_src_fwd()
826 sg_cfg.nlflags = cfg->nlflags; in br_mdb_add_group_src_fwd()
830 static int br_mdb_add_group_src(const struct br_mdb_config *cfg, in br_mdb_add_group_src() argument
840 ent = br_multicast_find_group_src(pg, &src->addr); in br_mdb_add_group_src()
842 ent = br_multicast_new_group_src(pg, &src->addr); in br_mdb_add_group_src()
845 return -ENOSPC; in br_mdb_add_group_src()
847 } else if (!(cfg->nlflags & NLM_F_REPLACE)) { in br_mdb_add_group_src()
849 return -EEXIST; in br_mdb_add_group_src()
852 if (cfg->filter_mode == MCAST_INCLUDE && in br_mdb_add_group_src()
853 cfg->entry->state == MDB_TEMPORARY) in br_mdb_add_group_src()
854 mod_timer(&ent->timer, now + br_multicast_gmi(brmctx)); in br_mdb_add_group_src()
856 del_timer(&ent->timer); in br_mdb_add_group_src()
859 err = br_mdb_add_group_src_fwd(cfg, &src->addr, brmctx, extack); in br_mdb_add_group_src()
863 ent->flags = BR_SGRP_F_INSTALLED | BR_SGRP_F_USER_ADDED; in br_mdb_add_group_src()
877 ent = br_multicast_find_group_src(pg, &src->addr); in br_mdb_del_group_src()
883 static int br_mdb_add_group_srcs(const struct br_mdb_config *cfg, in br_mdb_add_group_srcs() argument
890 for (i = 0; i < cfg->num_src_entries; i++) { in br_mdb_add_group_srcs()
891 err = br_mdb_add_group_src(cfg, pg, brmctx, in br_mdb_add_group_srcs()
892 &cfg->src_entries[i], extack); in br_mdb_add_group_srcs()
900 for (i--; i >= 0; i--) in br_mdb_add_group_srcs()
901 br_mdb_del_group_src(pg, &cfg->src_entries[i]); in br_mdb_add_group_srcs()
905 static int br_mdb_replace_group_srcs(const struct br_mdb_config *cfg, in br_mdb_replace_group_srcs() argument
914 hlist_for_each_entry(ent, &pg->src_list, node) in br_mdb_replace_group_srcs()
915 ent->flags |= BR_SGRP_F_DELETE; in br_mdb_replace_group_srcs()
917 err = br_mdb_add_group_srcs(cfg, pg, brmctx, extack); in br_mdb_replace_group_srcs()
921 hlist_for_each_entry_safe(ent, tmp, &pg->src_list, node) { in br_mdb_replace_group_srcs()
922 if (ent->flags & BR_SGRP_F_DELETE) in br_mdb_replace_group_srcs()
929 hlist_for_each_entry(ent, &pg->src_list, node) in br_mdb_replace_group_srcs()
930 ent->flags &= ~BR_SGRP_F_DELETE; in br_mdb_replace_group_srcs()
934 static int br_mdb_replace_group_star_g(const struct br_mdb_config *cfg, in br_mdb_replace_group_star_g() argument
944 err = br_mdb_replace_group_srcs(cfg, pg, brmctx, extack); in br_mdb_replace_group_star_g()
948 pg->flags = flags; in br_mdb_replace_group_star_g()
949 pg->filter_mode = cfg->filter_mode; in br_mdb_replace_group_star_g()
950 pg->rt_protocol = cfg->rt_protocol; in br_mdb_replace_group_star_g()
952 cfg->filter_mode == MCAST_EXCLUDE) in br_mdb_replace_group_star_g()
953 mod_timer(&pg->timer, in br_mdb_replace_group_star_g()
954 now + brmctx->multicast_membership_interval); in br_mdb_replace_group_star_g()
956 del_timer(&pg->timer); in br_mdb_replace_group_star_g()
958 br_mdb_notify(cfg->br->dev, mp, pg, RTM_NEWMDB); in br_mdb_replace_group_star_g()
960 if (br_multicast_should_handle_mode(brmctx, cfg->group.proto)) in br_mdb_replace_group_star_g()
961 br_multicast_star_g_handle_mode(pg, cfg->filter_mode); in br_mdb_replace_group_star_g()
966 static int br_mdb_add_group_star_g(const struct br_mdb_config *cfg, in br_mdb_add_group_star_g() argument
977 for (pp = &mp->ports; in br_mdb_add_group_star_g()
978 (p = mlock_dereference(*pp, cfg->br)) != NULL; in br_mdb_add_group_star_g()
979 pp = &p->next) { in br_mdb_add_group_star_g()
980 if (p->key.port == cfg->p) { in br_mdb_add_group_star_g()
981 if (!(cfg->nlflags & NLM_F_REPLACE)) { in br_mdb_add_group_star_g()
983 return -EEXIST; in br_mdb_add_group_star_g()
985 return br_mdb_replace_group_star_g(cfg, mp, p, brmctx, in br_mdb_add_group_star_g()
988 if ((unsigned long)p->key.port < (unsigned long)cfg->p) in br_mdb_add_group_star_g()
992 p = br_multicast_new_port_group(cfg->p, &cfg->group, *pp, flags, NULL, in br_mdb_add_group_star_g()
993 cfg->filter_mode, cfg->rt_protocol, in br_mdb_add_group_star_g()
996 return -ENOMEM; in br_mdb_add_group_star_g()
998 err = br_mdb_add_group_srcs(cfg, p, brmctx, extack); in br_mdb_add_group_star_g()
1004 cfg->filter_mode == MCAST_EXCLUDE) in br_mdb_add_group_star_g()
1005 mod_timer(&p->timer, in br_mdb_add_group_star_g()
1006 now + brmctx->multicast_membership_interval); in br_mdb_add_group_star_g()
1007 br_mdb_notify(cfg->br->dev, mp, p, RTM_NEWMDB); in br_mdb_add_group_star_g()
1011 if (br_multicast_should_handle_mode(brmctx, cfg->group.proto) && in br_mdb_add_group_star_g()
1012 cfg->filter_mode == MCAST_EXCLUDE) in br_mdb_add_group_star_g()
1022 static int br_mdb_add_group(const struct br_mdb_config *cfg, in br_mdb_add_group() argument
1025 struct br_mdb_entry *entry = cfg->entry; in br_mdb_add_group()
1026 struct net_bridge_port *port = cfg->p; in br_mdb_add_group()
1028 struct net_bridge *br = cfg->br; in br_mdb_add_group()
1030 struct br_ip group = cfg->group; in br_mdb_add_group()
1035 return -EINVAL; in br_mdb_add_group()
1043 if (mp->host_joined) { in br_mdb_add_group()
1045 return -EEXIST; in br_mdb_add_group()
1049 br_mdb_notify(br->dev, mp, NULL, RTM_NEWMDB); in br_mdb_add_group()
1054 if (entry->state == MDB_PERMANENT) in br_mdb_add_group()
1058 return br_mdb_add_group_star_g(cfg, mp, brmctx, flags, extack); in br_mdb_add_group()
1060 return br_mdb_add_group_sg(cfg, mp, brmctx, flags, extack); in br_mdb_add_group()
1063 static int __br_mdb_add(const struct br_mdb_config *cfg, in __br_mdb_add() argument
1068 spin_lock_bh(&cfg->br->multicast_lock); in __br_mdb_add()
1069 ret = br_mdb_add_group(cfg, extack); in __br_mdb_add()
1070 spin_unlock_bh(&cfg->br->multicast_lock); in __br_mdb_add()
1089 return -EINVAL; in br_mdb_config_src_entry_init()
1092 return -EINVAL; in br_mdb_config_src_entry_init()
1094 src->addr.proto = proto; in br_mdb_config_src_entry_init()
1095 nla_memcpy(&src->addr.src, tb[MDBE_SRCATTR_ADDRESS], in br_mdb_config_src_entry_init()
1102 struct br_mdb_config *cfg, in br_mdb_config_src_list_init() argument
1110 cfg->num_src_entries++; in br_mdb_config_src_list_init()
1112 if (cfg->num_src_entries >= PG_SRC_ENT_LIMIT) { in br_mdb_config_src_list_init()
1114 PG_SRC_ENT_LIMIT - 1); in br_mdb_config_src_list_init()
1115 return -EINVAL; in br_mdb_config_src_list_init()
1118 cfg->src_entries = kcalloc(cfg->num_src_entries, in br_mdb_config_src_list_init()
1120 if (!cfg->src_entries) in br_mdb_config_src_list_init()
1121 return -ENOMEM; in br_mdb_config_src_list_init()
1125 &cfg->src_entries[i], in br_mdb_config_src_list_init()
1126 cfg->entry->addr.proto, in br_mdb_config_src_list_init()
1136 kfree(cfg->src_entries); in br_mdb_config_src_list_init()
1140 static void br_mdb_config_src_list_fini(struct br_mdb_config *cfg) in br_mdb_config_src_list_fini() argument
1142 kfree(cfg->src_entries); in br_mdb_config_src_list_fini()
1146 struct br_mdb_config *cfg, in br_mdb_config_attrs_init() argument
1159 cfg->entry->addr.proto, extack)) in br_mdb_config_attrs_init()
1160 return -EINVAL; in br_mdb_config_attrs_init()
1162 __mdb_entry_to_br_ip(cfg->entry, &cfg->group, mdb_attrs); in br_mdb_config_attrs_init()
1165 if (!cfg->p) { in br_mdb_config_attrs_init()
1167 return -EINVAL; in br_mdb_config_attrs_init()
1169 if (!br_multicast_is_star_g(&cfg->group)) { in br_mdb_config_attrs_init()
1171 return -EINVAL; in br_mdb_config_attrs_init()
1173 cfg->filter_mode = nla_get_u8(mdb_attrs[MDBE_ATTR_GROUP_MODE]); in br_mdb_config_attrs_init()
1175 cfg->filter_mode = MCAST_EXCLUDE; in br_mdb_config_attrs_init()
1179 if (!cfg->p) { in br_mdb_config_attrs_init()
1181 return -EINVAL; in br_mdb_config_attrs_init()
1183 if (!br_multicast_is_star_g(&cfg->group)) { in br_mdb_config_attrs_init()
1185 return -EINVAL; in br_mdb_config_attrs_init()
1189 return -EINVAL; in br_mdb_config_attrs_init()
1192 cfg, extack); in br_mdb_config_attrs_init()
1197 if (!cfg->num_src_entries && cfg->filter_mode == MCAST_INCLUDE) { in br_mdb_config_attrs_init()
1199 return -EINVAL; in br_mdb_config_attrs_init()
1203 if (!cfg->p) { in br_mdb_config_attrs_init()
1205 return -EINVAL; in br_mdb_config_attrs_init()
1207 cfg->rt_protocol = nla_get_u8(mdb_attrs[MDBE_ATTR_RTPROT]); in br_mdb_config_attrs_init()
1213 static int br_mdb_config_init(struct br_mdb_config *cfg, struct net_device *dev, in br_mdb_config_init() argument
1219 memset(cfg, 0, sizeof(*cfg)); in br_mdb_config_init()
1220 cfg->filter_mode = MCAST_EXCLUDE; in br_mdb_config_init()
1221 cfg->rt_protocol = RTPROT_STATIC; in br_mdb_config_init()
1222 cfg->nlflags = nlmsg_flags; in br_mdb_config_init()
1224 cfg->br = netdev_priv(dev); in br_mdb_config_init()
1226 if (!netif_running(cfg->br->dev)) { in br_mdb_config_init()
1228 return -EINVAL; in br_mdb_config_init()
1231 if (!br_opt_get(cfg->br, BROPT_MULTICAST_ENABLED)) { in br_mdb_config_init()
1233 return -EINVAL; in br_mdb_config_init()
1236 cfg->entry = nla_data(tb[MDBA_SET_ENTRY]); in br_mdb_config_init()
1238 if (cfg->entry->ifindex != cfg->br->dev->ifindex) { in br_mdb_config_init()
1241 pdev = __dev_get_by_index(net, cfg->entry->ifindex); in br_mdb_config_init()
1244 return -ENODEV; in br_mdb_config_init()
1247 cfg->p = br_port_get_rtnl(pdev); in br_mdb_config_init()
1248 if (!cfg->p) { in br_mdb_config_init()
1250 return -EINVAL; in br_mdb_config_init()
1253 if (cfg->p->br != cfg->br) { in br_mdb_config_init()
1255 return -EINVAL; in br_mdb_config_init()
1259 if (cfg->entry->addr.proto == htons(ETH_P_IP) && in br_mdb_config_init()
1260 ipv4_is_zeronet(cfg->entry->addr.u.ip4)) { in br_mdb_config_init()
1262 return -EINVAL; in br_mdb_config_init()
1266 return br_mdb_config_attrs_init(tb[MDBA_SET_ENTRY_ATTRS], cfg, in br_mdb_config_init()
1269 __mdb_entry_to_br_ip(cfg->entry, &cfg->group, NULL); in br_mdb_config_init()
1274 static void br_mdb_config_fini(struct br_mdb_config *cfg) in br_mdb_config_fini() argument
1276 br_mdb_config_src_list_fini(cfg); in br_mdb_config_fini()
1284 struct br_mdb_config cfg; in br_mdb_add() local
1287 err = br_mdb_config_init(&cfg, dev, tb, nlmsg_flags, extack); in br_mdb_add()
1291 err = -EINVAL; in br_mdb_add()
1293 if (!cfg.p && !br_group_is_l2(&cfg.group)) { in br_mdb_add()
1294 /* don't allow any flags for host-joined IP groups */ in br_mdb_add()
1295 if (cfg.entry->state) { in br_mdb_add()
1299 if (!br_multicast_is_star_g(&cfg.group)) { in br_mdb_add()
1305 if (br_group_is_l2(&cfg.group) && cfg.entry->state != MDB_PERMANENT) { in br_mdb_add()
1310 if (cfg.p) { in br_mdb_add()
1311 if (cfg.p->state == BR_STATE_DISABLED && cfg.entry->state != MDB_PERMANENT) { in br_mdb_add()
1315 vg = nbp_vlan_group(cfg.p); in br_mdb_add()
1317 vg = br_vlan_group(cfg.br); in br_mdb_add()
1323 if (br_vlan_enabled(cfg.br->dev) && vg && cfg.entry->vid == 0) { in br_mdb_add()
1324 list_for_each_entry(v, &vg->vlan_list, vlist) { in br_mdb_add()
1325 cfg.entry->vid = v->vid; in br_mdb_add()
1326 cfg.group.vid = v->vid; in br_mdb_add()
1327 err = __br_mdb_add(&cfg, extack); in br_mdb_add()
1332 err = __br_mdb_add(&cfg, extack); in br_mdb_add()
1336 br_mdb_config_fini(&cfg); in br_mdb_add()
1340 static int __br_mdb_del(const struct br_mdb_config *cfg) in __br_mdb_del() argument
1342 struct br_mdb_entry *entry = cfg->entry; in __br_mdb_del()
1343 struct net_bridge *br = cfg->br; in __br_mdb_del()
1347 struct br_ip ip = cfg->group; in __br_mdb_del()
1348 int err = -EINVAL; in __br_mdb_del()
1350 spin_lock_bh(&br->multicast_lock); in __br_mdb_del()
1356 if (entry->ifindex == mp->br->dev->ifindex && mp->host_joined) { in __br_mdb_del()
1359 br_mdb_notify(br->dev, mp, NULL, RTM_DELMDB); in __br_mdb_del()
1360 if (!mp->ports && netif_running(br->dev)) in __br_mdb_del()
1361 mod_timer(&mp->timer, jiffies); in __br_mdb_del()
1365 for (pp = &mp->ports; in __br_mdb_del()
1367 pp = &p->next) { in __br_mdb_del()
1368 if (!p->key.port || p->key.port->dev->ifindex != entry->ifindex) in __br_mdb_del()
1377 spin_unlock_bh(&br->multicast_lock); in __br_mdb_del()
1386 struct br_mdb_config cfg; in br_mdb_del() local
1389 err = br_mdb_config_init(&cfg, dev, tb, 0, extack); in br_mdb_del()
1393 if (cfg.p) in br_mdb_del()
1394 vg = nbp_vlan_group(cfg.p); in br_mdb_del()
1396 vg = br_vlan_group(cfg.br); in br_mdb_del()
1401 if (br_vlan_enabled(cfg.br->dev) && vg && cfg.entry->vid == 0) { in br_mdb_del()
1402 list_for_each_entry(v, &vg->vlan_list, vlist) { in br_mdb_del()
1403 cfg.entry->vid = v->vid; in br_mdb_del()
1404 cfg.group.vid = v->vid; in br_mdb_del()
1405 err = __br_mdb_del(&cfg); in br_mdb_del()
1408 err = __br_mdb_del(&cfg); in br_mdb_del()
1411 br_mdb_config_fini(&cfg); in br_mdb_del()
1436 desc->port_ifindex = entry->ifindex; in br_mdb_flush_desc_init()
1437 desc->vid = entry->vid; in br_mdb_flush_desc_init()
1438 desc->state = entry->state; in br_mdb_flush_desc_init()
1450 desc->state_mask = nla_get_u8(mdbe_attrs[MDBE_ATTR_STATE_MASK]); in br_mdb_flush_desc_init()
1453 desc->rt_protocol = nla_get_u8(mdbe_attrs[MDBE_ATTR_RTPROT]); in br_mdb_flush_desc_init()
1464 if (desc->port_ifindex && desc->port_ifindex != br->dev->ifindex) in br_mdb_flush_host()
1467 if (desc->rt_protocol) in br_mdb_flush_host()
1470 state = br_group_is_l2(&mp->addr) ? MDB_PERMANENT : 0; in br_mdb_flush_host()
1471 if (desc->state_mask && (state & desc->state_mask) != desc->state) in br_mdb_flush_host()
1475 if (!mp->ports && netif_running(br->dev)) in br_mdb_flush_host()
1476 mod_timer(&mp->timer, jiffies); in br_mdb_flush_host()
1486 for (pp = &mp->ports; (p = mlock_dereference(*pp, br)) != NULL;) { in br_mdb_flush_pgs()
1489 if (desc->port_ifindex && in br_mdb_flush_pgs()
1490 desc->port_ifindex != p->key.port->dev->ifindex) { in br_mdb_flush_pgs()
1491 pp = &p->next; in br_mdb_flush_pgs()
1495 if (desc->rt_protocol && desc->rt_protocol != p->rt_protocol) { in br_mdb_flush_pgs()
1496 pp = &p->next; in br_mdb_flush_pgs()
1500 state = p->flags & MDB_PG_FLAGS_PERMANENT ? MDB_PERMANENT : 0; in br_mdb_flush_pgs()
1501 if (desc->state_mask && in br_mdb_flush_pgs()
1502 (state & desc->state_mask) != desc->state) { in br_mdb_flush_pgs()
1503 pp = &p->next; in br_mdb_flush_pgs()
1516 spin_lock_bh(&br->multicast_lock); in br_mdb_flush()
1521 hlist_for_each_entry(mp, &br->mdb_list, mdb_node) { in br_mdb_flush()
1522 if (desc->vid && desc->vid != mp->addr.vid) in br_mdb_flush()
1529 spin_unlock_bh(&br->multicast_lock); in br_mdb_flush()
1574 entry->addr.proto, extack)) in br_mdb_get_parse()
1575 return -EINVAL; in br_mdb_get_parse()
1594 if (mp->host_joined) in br_mdb_get_reply_alloc()
1597 for (pg = mlock_dereference(mp->ports, mp->br); pg; in br_mdb_get_reply_alloc()
1598 pg = mlock_dereference(pg->next, mp->br)) in br_mdb_get_reply_alloc()
1616 return -EMSGSIZE; in br_mdb_get_reply_fill()
1620 bpm->family = AF_BRIDGE; in br_mdb_get_reply_fill()
1621 bpm->ifindex = mp->br->dev->ifindex; in br_mdb_get_reply_fill()
1624 err = -EMSGSIZE; in br_mdb_get_reply_fill()
1629 err = -EMSGSIZE; in br_mdb_get_reply_fill()
1633 if (mp->host_joined) { in br_mdb_get_reply_fill()
1639 for (pg = mlock_dereference(mp->ports, mp->br); pg; in br_mdb_get_reply_fill()
1640 pg = mlock_dereference(pg->next, mp->br)) { in br_mdb_get_reply_fill()
1674 spin_lock_bh(&br->multicast_lock); in br_mdb_get()
1677 if (!mp || (!mp->ports && !mp->host_joined)) { in br_mdb_get()
1679 err = -ENOENT; in br_mdb_get()
1685 err = -ENOMEM; in br_mdb_get()
1695 spin_unlock_bh(&br->multicast_lock); in br_mdb_get()
1702 spin_unlock_bh(&br->multicast_lock); in br_mdb_get()