0001
0002
0003 #include <linux/kernel.h>
0004 #include <linux/netdevice.h>
0005 #include <linux/rtnetlink.h>
0006 #include <linux/slab.h>
0007 #include <net/ip_tunnels.h>
0008
0009 #include "br_private.h"
0010 #include "br_private_tunnel.h"
0011
0012 static bool __vlan_tun_put(struct sk_buff *skb, const struct net_bridge_vlan *v)
0013 {
0014 __be32 tid = tunnel_id_to_key32(v->tinfo.tunnel_id);
0015 struct nlattr *nest;
0016
0017 if (!v->tinfo.tunnel_dst)
0018 return true;
0019
0020 nest = nla_nest_start(skb, BRIDGE_VLANDB_ENTRY_TUNNEL_INFO);
0021 if (!nest)
0022 return false;
0023 if (nla_put_u32(skb, BRIDGE_VLANDB_TINFO_ID, be32_to_cpu(tid))) {
0024 nla_nest_cancel(skb, nest);
0025 return false;
0026 }
0027 nla_nest_end(skb, nest);
0028
0029 return true;
0030 }
0031
0032 static bool __vlan_tun_can_enter_range(const struct net_bridge_vlan *v_curr,
0033 const struct net_bridge_vlan *range_end)
0034 {
0035 return (!v_curr->tinfo.tunnel_dst && !range_end->tinfo.tunnel_dst) ||
0036 vlan_tunid_inrange(v_curr, range_end);
0037 }
0038
0039
0040 bool br_vlan_opts_eq_range(const struct net_bridge_vlan *v_curr,
0041 const struct net_bridge_vlan *range_end)
0042 {
0043 u8 range_mc_rtr = br_vlan_multicast_router(range_end);
0044 u8 curr_mc_rtr = br_vlan_multicast_router(v_curr);
0045
0046 return v_curr->state == range_end->state &&
0047 __vlan_tun_can_enter_range(v_curr, range_end) &&
0048 curr_mc_rtr == range_mc_rtr;
0049 }
0050
0051 bool br_vlan_opts_fill(struct sk_buff *skb, const struct net_bridge_vlan *v)
0052 {
0053 if (nla_put_u8(skb, BRIDGE_VLANDB_ENTRY_STATE, br_vlan_get_state(v)) ||
0054 !__vlan_tun_put(skb, v))
0055 return false;
0056
0057 #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
0058 if (nla_put_u8(skb, BRIDGE_VLANDB_ENTRY_MCAST_ROUTER,
0059 br_vlan_multicast_router(v)))
0060 return false;
0061 #endif
0062
0063 return true;
0064 }
0065
0066 size_t br_vlan_opts_nl_size(void)
0067 {
0068 return nla_total_size(sizeof(u8))
0069 + nla_total_size(0)
0070 + nla_total_size(sizeof(u32))
0071 #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
0072 + nla_total_size(sizeof(u8))
0073 #endif
0074 + 0;
0075 }
0076
0077 static int br_vlan_modify_state(struct net_bridge_vlan_group *vg,
0078 struct net_bridge_vlan *v,
0079 u8 state,
0080 bool *changed,
0081 struct netlink_ext_ack *extack)
0082 {
0083 struct net_bridge *br;
0084
0085 ASSERT_RTNL();
0086
0087 if (state > BR_STATE_BLOCKING) {
0088 NL_SET_ERR_MSG_MOD(extack, "Invalid vlan state");
0089 return -EINVAL;
0090 }
0091
0092 if (br_vlan_is_brentry(v))
0093 br = v->br;
0094 else
0095 br = v->port->br;
0096
0097 if (br->stp_enabled == BR_KERNEL_STP) {
0098 NL_SET_ERR_MSG_MOD(extack, "Can't modify vlan state when using kernel STP");
0099 return -EBUSY;
0100 }
0101
0102 if (br_opt_get(br, BROPT_MST_ENABLED)) {
0103 NL_SET_ERR_MSG_MOD(extack, "Can't modify vlan state directly when MST is enabled");
0104 return -EBUSY;
0105 }
0106
0107 if (v->state == state)
0108 return 0;
0109
0110 if (v->vid == br_get_pvid(vg))
0111 br_vlan_set_pvid_state(vg, state);
0112
0113 br_vlan_set_state(v, state);
0114 *changed = true;
0115
0116 return 0;
0117 }
0118
0119 static const struct nla_policy br_vlandb_tinfo_pol[BRIDGE_VLANDB_TINFO_MAX + 1] = {
0120 [BRIDGE_VLANDB_TINFO_ID] = { .type = NLA_U32 },
0121 [BRIDGE_VLANDB_TINFO_CMD] = { .type = NLA_U32 },
0122 };
0123
0124 static int br_vlan_modify_tunnel(const struct net_bridge_port *p,
0125 struct net_bridge_vlan *v,
0126 struct nlattr **tb,
0127 bool *changed,
0128 struct netlink_ext_ack *extack)
0129 {
0130 struct nlattr *tun_tb[BRIDGE_VLANDB_TINFO_MAX + 1], *attr;
0131 struct bridge_vlan_info *vinfo;
0132 u32 tun_id = 0;
0133 int cmd, err;
0134
0135 if (!p) {
0136 NL_SET_ERR_MSG_MOD(extack, "Can't modify tunnel mapping of non-port vlans");
0137 return -EINVAL;
0138 }
0139 if (!(p->flags & BR_VLAN_TUNNEL)) {
0140 NL_SET_ERR_MSG_MOD(extack, "Port doesn't have tunnel flag set");
0141 return -EINVAL;
0142 }
0143
0144 attr = tb[BRIDGE_VLANDB_ENTRY_TUNNEL_INFO];
0145 err = nla_parse_nested(tun_tb, BRIDGE_VLANDB_TINFO_MAX, attr,
0146 br_vlandb_tinfo_pol, extack);
0147 if (err)
0148 return err;
0149
0150 if (!tun_tb[BRIDGE_VLANDB_TINFO_CMD]) {
0151 NL_SET_ERR_MSG_MOD(extack, "Missing tunnel command attribute");
0152 return -ENOENT;
0153 }
0154 cmd = nla_get_u32(tun_tb[BRIDGE_VLANDB_TINFO_CMD]);
0155 switch (cmd) {
0156 case RTM_SETLINK:
0157 if (!tun_tb[BRIDGE_VLANDB_TINFO_ID]) {
0158 NL_SET_ERR_MSG_MOD(extack, "Missing tunnel id attribute");
0159 return -ENOENT;
0160 }
0161
0162 tun_id = nla_get_u32(tun_tb[BRIDGE_VLANDB_TINFO_ID]);
0163
0164 vinfo = nla_data(tb[BRIDGE_VLANDB_ENTRY_INFO]);
0165
0166
0167
0168
0169 tun_id += v->vid - vinfo->vid;
0170 break;
0171 case RTM_DELLINK:
0172 break;
0173 default:
0174 NL_SET_ERR_MSG_MOD(extack, "Unsupported tunnel command");
0175 return -EINVAL;
0176 }
0177
0178 return br_vlan_tunnel_info(p, cmd, v->vid, tun_id, changed);
0179 }
0180
0181 static int br_vlan_process_one_opts(const struct net_bridge *br,
0182 const struct net_bridge_port *p,
0183 struct net_bridge_vlan_group *vg,
0184 struct net_bridge_vlan *v,
0185 struct nlattr **tb,
0186 bool *changed,
0187 struct netlink_ext_ack *extack)
0188 {
0189 int err;
0190
0191 *changed = false;
0192 if (tb[BRIDGE_VLANDB_ENTRY_STATE]) {
0193 u8 state = nla_get_u8(tb[BRIDGE_VLANDB_ENTRY_STATE]);
0194
0195 err = br_vlan_modify_state(vg, v, state, changed, extack);
0196 if (err)
0197 return err;
0198 }
0199 if (tb[BRIDGE_VLANDB_ENTRY_TUNNEL_INFO]) {
0200 err = br_vlan_modify_tunnel(p, v, tb, changed, extack);
0201 if (err)
0202 return err;
0203 }
0204
0205 #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
0206 if (tb[BRIDGE_VLANDB_ENTRY_MCAST_ROUTER]) {
0207 u8 val;
0208
0209 val = nla_get_u8(tb[BRIDGE_VLANDB_ENTRY_MCAST_ROUTER]);
0210 err = br_multicast_set_vlan_router(v, val);
0211 if (err)
0212 return err;
0213 *changed = true;
0214 }
0215 #endif
0216
0217 return 0;
0218 }
0219
0220 int br_vlan_process_options(const struct net_bridge *br,
0221 const struct net_bridge_port *p,
0222 struct net_bridge_vlan *range_start,
0223 struct net_bridge_vlan *range_end,
0224 struct nlattr **tb,
0225 struct netlink_ext_ack *extack)
0226 {
0227 struct net_bridge_vlan *v, *curr_start = NULL, *curr_end = NULL;
0228 struct net_bridge_vlan_group *vg;
0229 int vid, err = 0;
0230 u16 pvid;
0231
0232 if (p)
0233 vg = nbp_vlan_group(p);
0234 else
0235 vg = br_vlan_group(br);
0236
0237 if (!range_start || !br_vlan_should_use(range_start)) {
0238 NL_SET_ERR_MSG_MOD(extack, "Vlan range start doesn't exist, can't process options");
0239 return -ENOENT;
0240 }
0241 if (!range_end || !br_vlan_should_use(range_end)) {
0242 NL_SET_ERR_MSG_MOD(extack, "Vlan range end doesn't exist, can't process options");
0243 return -ENOENT;
0244 }
0245
0246 pvid = br_get_pvid(vg);
0247 for (vid = range_start->vid; vid <= range_end->vid; vid++) {
0248 bool changed = false;
0249
0250 v = br_vlan_find(vg, vid);
0251 if (!v || !br_vlan_should_use(v)) {
0252 NL_SET_ERR_MSG_MOD(extack, "Vlan in range doesn't exist, can't process options");
0253 err = -ENOENT;
0254 break;
0255 }
0256
0257 err = br_vlan_process_one_opts(br, p, vg, v, tb, &changed,
0258 extack);
0259 if (err)
0260 break;
0261
0262 if (changed) {
0263
0264 if (!curr_start) {
0265 curr_start = v;
0266 curr_end = v;
0267 continue;
0268 }
0269
0270 if (v->vid == pvid ||
0271 !br_vlan_can_enter_range(v, curr_end)) {
0272 br_vlan_notify(br, p, curr_start->vid,
0273 curr_end->vid, RTM_NEWVLAN);
0274 curr_start = v;
0275 }
0276 curr_end = v;
0277 } else {
0278
0279 if (!curr_start)
0280 continue;
0281
0282 br_vlan_notify(br, p, curr_start->vid, curr_end->vid,
0283 RTM_NEWVLAN);
0284 curr_start = NULL;
0285 curr_end = NULL;
0286 }
0287 }
0288 if (curr_start)
0289 br_vlan_notify(br, p, curr_start->vid, curr_end->vid,
0290 RTM_NEWVLAN);
0291
0292 return err;
0293 }
0294
0295 bool br_vlan_global_opts_can_enter_range(const struct net_bridge_vlan *v_curr,
0296 const struct net_bridge_vlan *r_end)
0297 {
0298 return v_curr->vid - r_end->vid == 1 &&
0299 v_curr->msti == r_end->msti &&
0300 ((v_curr->priv_flags ^ r_end->priv_flags) &
0301 BR_VLFLAG_GLOBAL_MCAST_ENABLED) == 0 &&
0302 br_multicast_ctx_options_equal(&v_curr->br_mcast_ctx,
0303 &r_end->br_mcast_ctx);
0304 }
0305
0306 bool br_vlan_global_opts_fill(struct sk_buff *skb, u16 vid, u16 vid_range,
0307 const struct net_bridge_vlan *v_opts)
0308 {
0309 struct nlattr *nest2 __maybe_unused;
0310 u64 clockval __maybe_unused;
0311 struct nlattr *nest;
0312
0313 nest = nla_nest_start(skb, BRIDGE_VLANDB_GLOBAL_OPTIONS);
0314 if (!nest)
0315 return false;
0316
0317 if (nla_put_u16(skb, BRIDGE_VLANDB_GOPTS_ID, vid))
0318 goto out_err;
0319
0320 if (vid_range && vid < vid_range &&
0321 nla_put_u16(skb, BRIDGE_VLANDB_GOPTS_RANGE, vid_range))
0322 goto out_err;
0323
0324 #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
0325 if (nla_put_u8(skb, BRIDGE_VLANDB_GOPTS_MCAST_SNOOPING,
0326 !!(v_opts->priv_flags & BR_VLFLAG_GLOBAL_MCAST_ENABLED)) ||
0327 nla_put_u8(skb, BRIDGE_VLANDB_GOPTS_MCAST_IGMP_VERSION,
0328 v_opts->br_mcast_ctx.multicast_igmp_version) ||
0329 nla_put_u32(skb, BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_CNT,
0330 v_opts->br_mcast_ctx.multicast_last_member_count) ||
0331 nla_put_u32(skb, BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_CNT,
0332 v_opts->br_mcast_ctx.multicast_startup_query_count) ||
0333 nla_put_u8(skb, BRIDGE_VLANDB_GOPTS_MCAST_QUERIER,
0334 v_opts->br_mcast_ctx.multicast_querier) ||
0335 br_multicast_dump_querier_state(skb, &v_opts->br_mcast_ctx,
0336 BRIDGE_VLANDB_GOPTS_MCAST_QUERIER_STATE))
0337 goto out_err;
0338
0339 clockval = jiffies_to_clock_t(v_opts->br_mcast_ctx.multicast_last_member_interval);
0340 if (nla_put_u64_64bit(skb, BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_INTVL,
0341 clockval, BRIDGE_VLANDB_GOPTS_PAD))
0342 goto out_err;
0343 clockval = jiffies_to_clock_t(v_opts->br_mcast_ctx.multicast_membership_interval);
0344 if (nla_put_u64_64bit(skb, BRIDGE_VLANDB_GOPTS_MCAST_MEMBERSHIP_INTVL,
0345 clockval, BRIDGE_VLANDB_GOPTS_PAD))
0346 goto out_err;
0347 clockval = jiffies_to_clock_t(v_opts->br_mcast_ctx.multicast_querier_interval);
0348 if (nla_put_u64_64bit(skb, BRIDGE_VLANDB_GOPTS_MCAST_QUERIER_INTVL,
0349 clockval, BRIDGE_VLANDB_GOPTS_PAD))
0350 goto out_err;
0351 clockval = jiffies_to_clock_t(v_opts->br_mcast_ctx.multicast_query_interval);
0352 if (nla_put_u64_64bit(skb, BRIDGE_VLANDB_GOPTS_MCAST_QUERY_INTVL,
0353 clockval, BRIDGE_VLANDB_GOPTS_PAD))
0354 goto out_err;
0355 clockval = jiffies_to_clock_t(v_opts->br_mcast_ctx.multicast_query_response_interval);
0356 if (nla_put_u64_64bit(skb, BRIDGE_VLANDB_GOPTS_MCAST_QUERY_RESPONSE_INTVL,
0357 clockval, BRIDGE_VLANDB_GOPTS_PAD))
0358 goto out_err;
0359 clockval = jiffies_to_clock_t(v_opts->br_mcast_ctx.multicast_startup_query_interval);
0360 if (nla_put_u64_64bit(skb, BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_INTVL,
0361 clockval, BRIDGE_VLANDB_GOPTS_PAD))
0362 goto out_err;
0363
0364 if (br_rports_have_mc_router(&v_opts->br_mcast_ctx)) {
0365 nest2 = nla_nest_start(skb,
0366 BRIDGE_VLANDB_GOPTS_MCAST_ROUTER_PORTS);
0367 if (!nest2)
0368 goto out_err;
0369
0370 rcu_read_lock();
0371 if (br_rports_fill_info(skb, &v_opts->br_mcast_ctx)) {
0372 rcu_read_unlock();
0373 nla_nest_cancel(skb, nest2);
0374 goto out_err;
0375 }
0376 rcu_read_unlock();
0377
0378 nla_nest_end(skb, nest2);
0379 }
0380
0381 #if IS_ENABLED(CONFIG_IPV6)
0382 if (nla_put_u8(skb, BRIDGE_VLANDB_GOPTS_MCAST_MLD_VERSION,
0383 v_opts->br_mcast_ctx.multicast_mld_version))
0384 goto out_err;
0385 #endif
0386 #endif
0387
0388 if (nla_put_u16(skb, BRIDGE_VLANDB_GOPTS_MSTI, v_opts->msti))
0389 goto out_err;
0390
0391 nla_nest_end(skb, nest);
0392
0393 return true;
0394
0395 out_err:
0396 nla_nest_cancel(skb, nest);
0397 return false;
0398 }
0399
0400 static size_t rtnl_vlan_global_opts_nlmsg_size(const struct net_bridge_vlan *v)
0401 {
0402 return NLMSG_ALIGN(sizeof(struct br_vlan_msg))
0403 + nla_total_size(0)
0404 + nla_total_size(sizeof(u16))
0405 #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
0406 + nla_total_size(sizeof(u8))
0407 + nla_total_size(sizeof(u8))
0408 + nla_total_size(sizeof(u8))
0409 + nla_total_size(sizeof(u32))
0410 + nla_total_size(sizeof(u32))
0411 + nla_total_size(sizeof(u64))
0412 + nla_total_size(sizeof(u64))
0413 + nla_total_size(sizeof(u64))
0414 + nla_total_size(sizeof(u64))
0415 + nla_total_size(sizeof(u64))
0416 + nla_total_size(sizeof(u64))
0417 + nla_total_size(sizeof(u8))
0418 + br_multicast_querier_state_size()
0419 + nla_total_size(0)
0420 + br_rports_size(&v->br_mcast_ctx)
0421 #endif
0422 + nla_total_size(sizeof(u16))
0423 + nla_total_size(sizeof(u16));
0424 }
0425
0426 static void br_vlan_global_opts_notify(const struct net_bridge *br,
0427 u16 vid, u16 vid_range)
0428 {
0429 struct net_bridge_vlan *v;
0430 struct br_vlan_msg *bvm;
0431 struct nlmsghdr *nlh;
0432 struct sk_buff *skb;
0433 int err = -ENOBUFS;
0434
0435
0436 ASSERT_RTNL();
0437
0438
0439 v = br_vlan_find(br_vlan_group(br), vid);
0440 if (!v)
0441 return;
0442
0443 skb = nlmsg_new(rtnl_vlan_global_opts_nlmsg_size(v), GFP_KERNEL);
0444 if (!skb)
0445 goto out_err;
0446
0447 err = -EMSGSIZE;
0448 nlh = nlmsg_put(skb, 0, 0, RTM_NEWVLAN, sizeof(*bvm), 0);
0449 if (!nlh)
0450 goto out_err;
0451 bvm = nlmsg_data(nlh);
0452 memset(bvm, 0, sizeof(*bvm));
0453 bvm->family = AF_BRIDGE;
0454 bvm->ifindex = br->dev->ifindex;
0455
0456 if (!br_vlan_global_opts_fill(skb, vid, vid_range, v))
0457 goto out_err;
0458
0459 nlmsg_end(skb, nlh);
0460 rtnl_notify(skb, dev_net(br->dev), 0, RTNLGRP_BRVLAN, NULL, GFP_KERNEL);
0461 return;
0462
0463 out_err:
0464 rtnl_set_sk_err(dev_net(br->dev), RTNLGRP_BRVLAN, err);
0465 kfree_skb(skb);
0466 }
0467
0468 static int br_vlan_process_global_one_opts(const struct net_bridge *br,
0469 struct net_bridge_vlan_group *vg,
0470 struct net_bridge_vlan *v,
0471 struct nlattr **tb,
0472 bool *changed,
0473 struct netlink_ext_ack *extack)
0474 {
0475 int err __maybe_unused;
0476
0477 *changed = false;
0478 #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
0479 if (tb[BRIDGE_VLANDB_GOPTS_MCAST_SNOOPING]) {
0480 u8 mc_snooping;
0481
0482 mc_snooping = nla_get_u8(tb[BRIDGE_VLANDB_GOPTS_MCAST_SNOOPING]);
0483 if (br_multicast_toggle_global_vlan(v, !!mc_snooping))
0484 *changed = true;
0485 }
0486 if (tb[BRIDGE_VLANDB_GOPTS_MCAST_IGMP_VERSION]) {
0487 u8 ver;
0488
0489 ver = nla_get_u8(tb[BRIDGE_VLANDB_GOPTS_MCAST_IGMP_VERSION]);
0490 err = br_multicast_set_igmp_version(&v->br_mcast_ctx, ver);
0491 if (err)
0492 return err;
0493 *changed = true;
0494 }
0495 if (tb[BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_CNT]) {
0496 u32 cnt;
0497
0498 cnt = nla_get_u32(tb[BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_CNT]);
0499 v->br_mcast_ctx.multicast_last_member_count = cnt;
0500 *changed = true;
0501 }
0502 if (tb[BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_CNT]) {
0503 u32 cnt;
0504
0505 cnt = nla_get_u32(tb[BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_CNT]);
0506 v->br_mcast_ctx.multicast_startup_query_count = cnt;
0507 *changed = true;
0508 }
0509 if (tb[BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_INTVL]) {
0510 u64 val;
0511
0512 val = nla_get_u64(tb[BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_INTVL]);
0513 v->br_mcast_ctx.multicast_last_member_interval = clock_t_to_jiffies(val);
0514 *changed = true;
0515 }
0516 if (tb[BRIDGE_VLANDB_GOPTS_MCAST_MEMBERSHIP_INTVL]) {
0517 u64 val;
0518
0519 val = nla_get_u64(tb[BRIDGE_VLANDB_GOPTS_MCAST_MEMBERSHIP_INTVL]);
0520 v->br_mcast_ctx.multicast_membership_interval = clock_t_to_jiffies(val);
0521 *changed = true;
0522 }
0523 if (tb[BRIDGE_VLANDB_GOPTS_MCAST_QUERIER_INTVL]) {
0524 u64 val;
0525
0526 val = nla_get_u64(tb[BRIDGE_VLANDB_GOPTS_MCAST_QUERIER_INTVL]);
0527 v->br_mcast_ctx.multicast_querier_interval = clock_t_to_jiffies(val);
0528 *changed = true;
0529 }
0530 if (tb[BRIDGE_VLANDB_GOPTS_MCAST_QUERY_INTVL]) {
0531 u64 val;
0532
0533 val = nla_get_u64(tb[BRIDGE_VLANDB_GOPTS_MCAST_QUERY_INTVL]);
0534 br_multicast_set_query_intvl(&v->br_mcast_ctx, val);
0535 *changed = true;
0536 }
0537 if (tb[BRIDGE_VLANDB_GOPTS_MCAST_QUERY_RESPONSE_INTVL]) {
0538 u64 val;
0539
0540 val = nla_get_u64(tb[BRIDGE_VLANDB_GOPTS_MCAST_QUERY_RESPONSE_INTVL]);
0541 v->br_mcast_ctx.multicast_query_response_interval = clock_t_to_jiffies(val);
0542 *changed = true;
0543 }
0544 if (tb[BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_INTVL]) {
0545 u64 val;
0546
0547 val = nla_get_u64(tb[BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_INTVL]);
0548 br_multicast_set_startup_query_intvl(&v->br_mcast_ctx, val);
0549 *changed = true;
0550 }
0551 if (tb[BRIDGE_VLANDB_GOPTS_MCAST_QUERIER]) {
0552 u8 val;
0553
0554 val = nla_get_u8(tb[BRIDGE_VLANDB_GOPTS_MCAST_QUERIER]);
0555 err = br_multicast_set_querier(&v->br_mcast_ctx, val);
0556 if (err)
0557 return err;
0558 *changed = true;
0559 }
0560 #if IS_ENABLED(CONFIG_IPV6)
0561 if (tb[BRIDGE_VLANDB_GOPTS_MCAST_MLD_VERSION]) {
0562 u8 ver;
0563
0564 ver = nla_get_u8(tb[BRIDGE_VLANDB_GOPTS_MCAST_MLD_VERSION]);
0565 err = br_multicast_set_mld_version(&v->br_mcast_ctx, ver);
0566 if (err)
0567 return err;
0568 *changed = true;
0569 }
0570 #endif
0571 #endif
0572 if (tb[BRIDGE_VLANDB_GOPTS_MSTI]) {
0573 u16 msti;
0574
0575 msti = nla_get_u16(tb[BRIDGE_VLANDB_GOPTS_MSTI]);
0576 err = br_mst_vlan_set_msti(v, msti);
0577 if (err)
0578 return err;
0579 *changed = true;
0580 }
0581
0582 return 0;
0583 }
0584
0585 static const struct nla_policy br_vlan_db_gpol[BRIDGE_VLANDB_GOPTS_MAX + 1] = {
0586 [BRIDGE_VLANDB_GOPTS_ID] = { .type = NLA_U16 },
0587 [BRIDGE_VLANDB_GOPTS_RANGE] = { .type = NLA_U16 },
0588 [BRIDGE_VLANDB_GOPTS_MCAST_SNOOPING] = { .type = NLA_U8 },
0589 [BRIDGE_VLANDB_GOPTS_MCAST_MLD_VERSION] = { .type = NLA_U8 },
0590 [BRIDGE_VLANDB_GOPTS_MCAST_QUERY_INTVL] = { .type = NLA_U64 },
0591 [BRIDGE_VLANDB_GOPTS_MCAST_QUERIER] = { .type = NLA_U8 },
0592 [BRIDGE_VLANDB_GOPTS_MCAST_IGMP_VERSION] = { .type = NLA_U8 },
0593 [BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_CNT] = { .type = NLA_U32 },
0594 [BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_CNT] = { .type = NLA_U32 },
0595 [BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_INTVL] = { .type = NLA_U64 },
0596 [BRIDGE_VLANDB_GOPTS_MCAST_MEMBERSHIP_INTVL] = { .type = NLA_U64 },
0597 [BRIDGE_VLANDB_GOPTS_MCAST_QUERIER_INTVL] = { .type = NLA_U64 },
0598 [BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_INTVL] = { .type = NLA_U64 },
0599 [BRIDGE_VLANDB_GOPTS_MCAST_QUERY_RESPONSE_INTVL] = { .type = NLA_U64 },
0600 [BRIDGE_VLANDB_GOPTS_MSTI] = NLA_POLICY_MAX(NLA_U16, VLAN_N_VID - 1),
0601 };
0602
0603 int br_vlan_rtm_process_global_options(struct net_device *dev,
0604 const struct nlattr *attr,
0605 int cmd,
0606 struct netlink_ext_ack *extack)
0607 {
0608 struct net_bridge_vlan *v, *curr_start = NULL, *curr_end = NULL;
0609 struct nlattr *tb[BRIDGE_VLANDB_GOPTS_MAX + 1];
0610 struct net_bridge_vlan_group *vg;
0611 u16 vid, vid_range = 0;
0612 struct net_bridge *br;
0613 int err = 0;
0614
0615 if (cmd != RTM_NEWVLAN) {
0616 NL_SET_ERR_MSG_MOD(extack, "Global vlan options support only set operation");
0617 return -EINVAL;
0618 }
0619 if (!netif_is_bridge_master(dev)) {
0620 NL_SET_ERR_MSG_MOD(extack, "Global vlan options can only be set on bridge device");
0621 return -EINVAL;
0622 }
0623 br = netdev_priv(dev);
0624 vg = br_vlan_group(br);
0625 if (WARN_ON(!vg))
0626 return -ENODEV;
0627
0628 err = nla_parse_nested(tb, BRIDGE_VLANDB_GOPTS_MAX, attr,
0629 br_vlan_db_gpol, extack);
0630 if (err)
0631 return err;
0632
0633 if (!tb[BRIDGE_VLANDB_GOPTS_ID]) {
0634 NL_SET_ERR_MSG_MOD(extack, "Missing vlan entry id");
0635 return -EINVAL;
0636 }
0637 vid = nla_get_u16(tb[BRIDGE_VLANDB_GOPTS_ID]);
0638 if (!br_vlan_valid_id(vid, extack))
0639 return -EINVAL;
0640
0641 if (tb[BRIDGE_VLANDB_GOPTS_RANGE]) {
0642 vid_range = nla_get_u16(tb[BRIDGE_VLANDB_GOPTS_RANGE]);
0643 if (!br_vlan_valid_id(vid_range, extack))
0644 return -EINVAL;
0645 if (vid >= vid_range) {
0646 NL_SET_ERR_MSG_MOD(extack, "End vlan id is less than or equal to start vlan id");
0647 return -EINVAL;
0648 }
0649 } else {
0650 vid_range = vid;
0651 }
0652
0653 for (; vid <= vid_range; vid++) {
0654 bool changed = false;
0655
0656 v = br_vlan_find(vg, vid);
0657 if (!v) {
0658 NL_SET_ERR_MSG_MOD(extack, "Vlan in range doesn't exist, can't process global options");
0659 err = -ENOENT;
0660 break;
0661 }
0662
0663 err = br_vlan_process_global_one_opts(br, vg, v, tb, &changed,
0664 extack);
0665 if (err)
0666 break;
0667
0668 if (changed) {
0669
0670 if (!curr_start) {
0671 curr_start = v;
0672 curr_end = v;
0673 continue;
0674 }
0675
0676 if (!br_vlan_global_opts_can_enter_range(v, curr_end)) {
0677 br_vlan_global_opts_notify(br, curr_start->vid,
0678 curr_end->vid);
0679 curr_start = v;
0680 }
0681 curr_end = v;
0682 } else {
0683
0684 if (!curr_start)
0685 continue;
0686
0687 br_vlan_global_opts_notify(br, curr_start->vid,
0688 curr_end->vid);
0689 curr_start = NULL;
0690 curr_end = NULL;
0691 }
0692 }
0693 if (curr_start)
0694 br_vlan_global_opts_notify(br, curr_start->vid, curr_end->vid);
0695
0696 return err;
0697 }