1 // SPDX-License-Identifier: GPL-2.0-only 2 // Copyright (c) 2020, Nikolay Aleksandrov <nikolay@cumulusnetworks.com> 3 #include <linux/kernel.h> 4 #include <linux/netdevice.h> 5 #include <linux/rtnetlink.h> 6 #include <linux/slab.h> 7 #include <net/ip_tunnels.h> 8 9 #include "br_private.h" 10 #include "br_private_tunnel.h" 11 12 static bool __vlan_tun_put(struct sk_buff *skb, const struct net_bridge_vlan *v) 13 { 14 __be32 tid = tunnel_id_to_key32(v->tinfo.tunnel_id); 15 struct nlattr *nest; 16 17 if (!v->tinfo.tunnel_dst) 18 return true; 19 20 nest = nla_nest_start(skb, BRIDGE_VLANDB_ENTRY_TUNNEL_INFO); 21 if (!nest) 22 return false; 23 if (nla_put_u32(skb, BRIDGE_VLANDB_TINFO_ID, be32_to_cpu(tid))) { 24 nla_nest_cancel(skb, nest); 25 return false; 26 } 27 nla_nest_end(skb, nest); 28 29 return true; 30 } 31 32 static bool __vlan_tun_can_enter_range(const struct net_bridge_vlan *v_curr, 33 const struct net_bridge_vlan *range_end) 34 { 35 return (!v_curr->tinfo.tunnel_dst && !range_end->tinfo.tunnel_dst) || 36 vlan_tunid_inrange(v_curr, range_end); 37 } 38 39 /* check if the options' state of v_curr allow it to enter the range */ 40 bool br_vlan_opts_eq_range(const struct net_bridge_vlan *v_curr, 41 const struct net_bridge_vlan *range_end) 42 { 43 u8 range_mc_rtr = br_vlan_multicast_router(range_end); 44 u8 curr_mc_rtr = br_vlan_multicast_router(v_curr); 45 46 return v_curr->state == range_end->state && 47 __vlan_tun_can_enter_range(v_curr, range_end) && 48 curr_mc_rtr == range_mc_rtr; 49 } 50 51 bool br_vlan_opts_fill(struct sk_buff *skb, const struct net_bridge_vlan *v, 52 const struct net_bridge_port *p) 53 { 54 if (nla_put_u8(skb, BRIDGE_VLANDB_ENTRY_STATE, br_vlan_get_state(v)) || 55 !__vlan_tun_put(skb, v)) 56 return false; 57 58 #ifdef CONFIG_BRIDGE_IGMP_SNOOPING 59 if (nla_put_u8(skb, BRIDGE_VLANDB_ENTRY_MCAST_ROUTER, 60 br_vlan_multicast_router(v))) 61 return false; 62 if (p && !br_multicast_port_ctx_vlan_disabled(&v->port_mcast_ctx) && 63 (nla_put_u32(skb, BRIDGE_VLANDB_ENTRY_MCAST_N_GROUPS, 64 br_multicast_ngroups_get(&v->port_mcast_ctx)) || 65 nla_put_u32(skb, BRIDGE_VLANDB_ENTRY_MCAST_MAX_GROUPS, 66 br_multicast_ngroups_get_max(&v->port_mcast_ctx)))) 67 return false; 68 #endif 69 70 return true; 71 } 72 73 size_t br_vlan_opts_nl_size(void) 74 { 75 return nla_total_size(sizeof(u8)) /* BRIDGE_VLANDB_ENTRY_STATE */ 76 + nla_total_size(0) /* BRIDGE_VLANDB_ENTRY_TUNNEL_INFO */ 77 + nla_total_size(sizeof(u32)) /* BRIDGE_VLANDB_TINFO_ID */ 78 #ifdef CONFIG_BRIDGE_IGMP_SNOOPING 79 + nla_total_size(sizeof(u8)) /* BRIDGE_VLANDB_ENTRY_MCAST_ROUTER */ 80 + nla_total_size(sizeof(u32)) /* BRIDGE_VLANDB_ENTRY_MCAST_N_GROUPS */ 81 + nla_total_size(sizeof(u32)) /* BRIDGE_VLANDB_ENTRY_MCAST_MAX_GROUPS */ 82 #endif 83 + 0; 84 } 85 86 static int br_vlan_modify_state(struct net_bridge_vlan_group *vg, 87 struct net_bridge_vlan *v, 88 u8 state, 89 bool *changed, 90 struct netlink_ext_ack *extack) 91 { 92 struct net_bridge *br; 93 94 ASSERT_RTNL(); 95 96 if (state > BR_STATE_BLOCKING) { 97 NL_SET_ERR_MSG_MOD(extack, "Invalid vlan state"); 98 return -EINVAL; 99 } 100 101 if (br_vlan_is_brentry(v)) 102 br = v->br; 103 else 104 br = v->port->br; 105 106 if (br->stp_enabled == BR_KERNEL_STP) { 107 NL_SET_ERR_MSG_MOD(extack, "Can't modify vlan state when using kernel STP"); 108 return -EBUSY; 109 } 110 111 if (br_opt_get(br, BROPT_MST_ENABLED)) { 112 NL_SET_ERR_MSG_MOD(extack, "Can't modify vlan state directly when MST is enabled"); 113 return -EBUSY; 114 } 115 116 if (v->state == state) 117 return 0; 118 119 if (v->vid == br_get_pvid(vg)) 120 br_vlan_set_pvid_state(vg, state); 121 122 br_vlan_set_state(v, state); 123 *changed = true; 124 125 return 0; 126 } 127 128 static const struct nla_policy br_vlandb_tinfo_pol[BRIDGE_VLANDB_TINFO_MAX + 1] = { 129 [BRIDGE_VLANDB_TINFO_ID] = { .type = NLA_U32 }, 130 [BRIDGE_VLANDB_TINFO_CMD] = { .type = NLA_U32 }, 131 }; 132 133 static int br_vlan_modify_tunnel(const struct net_bridge_port *p, 134 struct net_bridge_vlan *v, 135 struct nlattr **tb, 136 bool *changed, 137 struct netlink_ext_ack *extack) 138 { 139 struct nlattr *tun_tb[BRIDGE_VLANDB_TINFO_MAX + 1], *attr; 140 struct bridge_vlan_info *vinfo; 141 u32 tun_id = 0; 142 int cmd, err; 143 144 if (!p) { 145 NL_SET_ERR_MSG_MOD(extack, "Can't modify tunnel mapping of non-port vlans"); 146 return -EINVAL; 147 } 148 if (!(p->flags & BR_VLAN_TUNNEL)) { 149 NL_SET_ERR_MSG_MOD(extack, "Port doesn't have tunnel flag set"); 150 return -EINVAL; 151 } 152 153 attr = tb[BRIDGE_VLANDB_ENTRY_TUNNEL_INFO]; 154 err = nla_parse_nested(tun_tb, BRIDGE_VLANDB_TINFO_MAX, attr, 155 br_vlandb_tinfo_pol, extack); 156 if (err) 157 return err; 158 159 if (!tun_tb[BRIDGE_VLANDB_TINFO_CMD]) { 160 NL_SET_ERR_MSG_MOD(extack, "Missing tunnel command attribute"); 161 return -ENOENT; 162 } 163 cmd = nla_get_u32(tun_tb[BRIDGE_VLANDB_TINFO_CMD]); 164 switch (cmd) { 165 case RTM_SETLINK: 166 if (!tun_tb[BRIDGE_VLANDB_TINFO_ID]) { 167 NL_SET_ERR_MSG_MOD(extack, "Missing tunnel id attribute"); 168 return -ENOENT; 169 } 170 /* when working on vlan ranges this is the starting tunnel id */ 171 tun_id = nla_get_u32(tun_tb[BRIDGE_VLANDB_TINFO_ID]); 172 /* vlan info attr is guaranteed by br_vlan_rtm_process_one */ 173 vinfo = nla_data(tb[BRIDGE_VLANDB_ENTRY_INFO]); 174 /* tunnel ids are mapped to each vlan in increasing order, 175 * the starting vlan is in BRIDGE_VLANDB_ENTRY_INFO and v is the 176 * current vlan, so we compute: tun_id + v - vinfo->vid 177 */ 178 tun_id += v->vid - vinfo->vid; 179 break; 180 case RTM_DELLINK: 181 break; 182 default: 183 NL_SET_ERR_MSG_MOD(extack, "Unsupported tunnel command"); 184 return -EINVAL; 185 } 186 187 return br_vlan_tunnel_info(p, cmd, v->vid, tun_id, changed); 188 } 189 190 static int br_vlan_process_one_opts(const struct net_bridge *br, 191 const struct net_bridge_port *p, 192 struct net_bridge_vlan_group *vg, 193 struct net_bridge_vlan *v, 194 struct nlattr **tb, 195 bool *changed, 196 struct netlink_ext_ack *extack) 197 { 198 int err; 199 200 *changed = false; 201 if (tb[BRIDGE_VLANDB_ENTRY_STATE]) { 202 u8 state = nla_get_u8(tb[BRIDGE_VLANDB_ENTRY_STATE]); 203 204 err = br_vlan_modify_state(vg, v, state, changed, extack); 205 if (err) 206 return err; 207 } 208 if (tb[BRIDGE_VLANDB_ENTRY_TUNNEL_INFO]) { 209 err = br_vlan_modify_tunnel(p, v, tb, changed, extack); 210 if (err) 211 return err; 212 } 213 214 #ifdef CONFIG_BRIDGE_IGMP_SNOOPING 215 if (tb[BRIDGE_VLANDB_ENTRY_MCAST_ROUTER]) { 216 u8 val; 217 218 val = nla_get_u8(tb[BRIDGE_VLANDB_ENTRY_MCAST_ROUTER]); 219 err = br_multicast_set_vlan_router(v, val); 220 if (err) 221 return err; 222 *changed = true; 223 } 224 if (tb[BRIDGE_VLANDB_ENTRY_MCAST_MAX_GROUPS]) { 225 u32 val; 226 227 if (!p) { 228 NL_SET_ERR_MSG_MOD(extack, "Can't set mcast_max_groups for non-port vlans"); 229 return -EINVAL; 230 } 231 if (br_multicast_port_ctx_vlan_disabled(&v->port_mcast_ctx)) { 232 NL_SET_ERR_MSG_MOD(extack, "Multicast snooping disabled on this VLAN"); 233 return -EINVAL; 234 } 235 236 val = nla_get_u32(tb[BRIDGE_VLANDB_ENTRY_MCAST_MAX_GROUPS]); 237 br_multicast_ngroups_set_max(&v->port_mcast_ctx, val); 238 *changed = true; 239 } 240 #endif 241 242 return 0; 243 } 244 245 int br_vlan_process_options(const struct net_bridge *br, 246 const struct net_bridge_port *p, 247 struct net_bridge_vlan *range_start, 248 struct net_bridge_vlan *range_end, 249 struct nlattr **tb, 250 struct netlink_ext_ack *extack) 251 { 252 struct net_bridge_vlan *v, *curr_start = NULL, *curr_end = NULL; 253 struct net_bridge_vlan_group *vg; 254 int vid, err = 0; 255 u16 pvid; 256 257 if (p) 258 vg = nbp_vlan_group(p); 259 else 260 vg = br_vlan_group(br); 261 262 if (!range_start || !br_vlan_should_use(range_start)) { 263 NL_SET_ERR_MSG_MOD(extack, "Vlan range start doesn't exist, can't process options"); 264 return -ENOENT; 265 } 266 if (!range_end || !br_vlan_should_use(range_end)) { 267 NL_SET_ERR_MSG_MOD(extack, "Vlan range end doesn't exist, can't process options"); 268 return -ENOENT; 269 } 270 271 pvid = br_get_pvid(vg); 272 for (vid = range_start->vid; vid <= range_end->vid; vid++) { 273 bool changed = false; 274 275 v = br_vlan_find(vg, vid); 276 if (!v || !br_vlan_should_use(v)) { 277 NL_SET_ERR_MSG_MOD(extack, "Vlan in range doesn't exist, can't process options"); 278 err = -ENOENT; 279 break; 280 } 281 282 err = br_vlan_process_one_opts(br, p, vg, v, tb, &changed, 283 extack); 284 if (err) 285 break; 286 287 if (changed) { 288 /* vlan options changed, check for range */ 289 if (!curr_start) { 290 curr_start = v; 291 curr_end = v; 292 continue; 293 } 294 295 if (v->vid == pvid || 296 !br_vlan_can_enter_range(v, curr_end)) { 297 br_vlan_notify(br, p, curr_start->vid, 298 curr_end->vid, RTM_NEWVLAN); 299 curr_start = v; 300 } 301 curr_end = v; 302 } else { 303 /* nothing changed and nothing to notify yet */ 304 if (!curr_start) 305 continue; 306 307 br_vlan_notify(br, p, curr_start->vid, curr_end->vid, 308 RTM_NEWVLAN); 309 curr_start = NULL; 310 curr_end = NULL; 311 } 312 } 313 if (curr_start) 314 br_vlan_notify(br, p, curr_start->vid, curr_end->vid, 315 RTM_NEWVLAN); 316 317 return err; 318 } 319 320 bool br_vlan_global_opts_can_enter_range(const struct net_bridge_vlan *v_curr, 321 const struct net_bridge_vlan *r_end) 322 { 323 return v_curr->vid - r_end->vid == 1 && 324 v_curr->msti == r_end->msti && 325 ((v_curr->priv_flags ^ r_end->priv_flags) & 326 BR_VLFLAG_GLOBAL_MCAST_ENABLED) == 0 && 327 br_multicast_ctx_options_equal(&v_curr->br_mcast_ctx, 328 &r_end->br_mcast_ctx); 329 } 330 331 bool br_vlan_global_opts_fill(struct sk_buff *skb, u16 vid, u16 vid_range, 332 const struct net_bridge_vlan *v_opts) 333 { 334 struct nlattr *nest2 __maybe_unused; 335 u64 clockval __maybe_unused; 336 struct nlattr *nest; 337 338 nest = nla_nest_start(skb, BRIDGE_VLANDB_GLOBAL_OPTIONS); 339 if (!nest) 340 return false; 341 342 if (nla_put_u16(skb, BRIDGE_VLANDB_GOPTS_ID, vid)) 343 goto out_err; 344 345 if (vid_range && vid < vid_range && 346 nla_put_u16(skb, BRIDGE_VLANDB_GOPTS_RANGE, vid_range)) 347 goto out_err; 348 349 #ifdef CONFIG_BRIDGE_IGMP_SNOOPING 350 if (nla_put_u8(skb, BRIDGE_VLANDB_GOPTS_MCAST_SNOOPING, 351 !!(v_opts->priv_flags & BR_VLFLAG_GLOBAL_MCAST_ENABLED)) || 352 nla_put_u8(skb, BRIDGE_VLANDB_GOPTS_MCAST_IGMP_VERSION, 353 v_opts->br_mcast_ctx.multicast_igmp_version) || 354 nla_put_u32(skb, BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_CNT, 355 v_opts->br_mcast_ctx.multicast_last_member_count) || 356 nla_put_u32(skb, BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_CNT, 357 v_opts->br_mcast_ctx.multicast_startup_query_count) || 358 nla_put_u8(skb, BRIDGE_VLANDB_GOPTS_MCAST_QUERIER, 359 v_opts->br_mcast_ctx.multicast_querier) || 360 br_multicast_dump_querier_state(skb, &v_opts->br_mcast_ctx, 361 BRIDGE_VLANDB_GOPTS_MCAST_QUERIER_STATE)) 362 goto out_err; 363 364 clockval = jiffies_to_clock_t(v_opts->br_mcast_ctx.multicast_last_member_interval); 365 if (nla_put_u64_64bit(skb, BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_INTVL, 366 clockval, BRIDGE_VLANDB_GOPTS_PAD)) 367 goto out_err; 368 clockval = jiffies_to_clock_t(v_opts->br_mcast_ctx.multicast_membership_interval); 369 if (nla_put_u64_64bit(skb, BRIDGE_VLANDB_GOPTS_MCAST_MEMBERSHIP_INTVL, 370 clockval, BRIDGE_VLANDB_GOPTS_PAD)) 371 goto out_err; 372 clockval = jiffies_to_clock_t(v_opts->br_mcast_ctx.multicast_querier_interval); 373 if (nla_put_u64_64bit(skb, BRIDGE_VLANDB_GOPTS_MCAST_QUERIER_INTVL, 374 clockval, BRIDGE_VLANDB_GOPTS_PAD)) 375 goto out_err; 376 clockval = jiffies_to_clock_t(v_opts->br_mcast_ctx.multicast_query_interval); 377 if (nla_put_u64_64bit(skb, BRIDGE_VLANDB_GOPTS_MCAST_QUERY_INTVL, 378 clockval, BRIDGE_VLANDB_GOPTS_PAD)) 379 goto out_err; 380 clockval = jiffies_to_clock_t(v_opts->br_mcast_ctx.multicast_query_response_interval); 381 if (nla_put_u64_64bit(skb, BRIDGE_VLANDB_GOPTS_MCAST_QUERY_RESPONSE_INTVL, 382 clockval, BRIDGE_VLANDB_GOPTS_PAD)) 383 goto out_err; 384 clockval = jiffies_to_clock_t(v_opts->br_mcast_ctx.multicast_startup_query_interval); 385 if (nla_put_u64_64bit(skb, BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_INTVL, 386 clockval, BRIDGE_VLANDB_GOPTS_PAD)) 387 goto out_err; 388 389 if (br_rports_have_mc_router(&v_opts->br_mcast_ctx)) { 390 nest2 = nla_nest_start(skb, 391 BRIDGE_VLANDB_GOPTS_MCAST_ROUTER_PORTS); 392 if (!nest2) 393 goto out_err; 394 395 rcu_read_lock(); 396 if (br_rports_fill_info(skb, &v_opts->br_mcast_ctx)) { 397 rcu_read_unlock(); 398 nla_nest_cancel(skb, nest2); 399 goto out_err; 400 } 401 rcu_read_unlock(); 402 403 nla_nest_end(skb, nest2); 404 } 405 406 #if IS_ENABLED(CONFIG_IPV6) 407 if (nla_put_u8(skb, BRIDGE_VLANDB_GOPTS_MCAST_MLD_VERSION, 408 v_opts->br_mcast_ctx.multicast_mld_version)) 409 goto out_err; 410 #endif 411 #endif 412 413 if (nla_put_u16(skb, BRIDGE_VLANDB_GOPTS_MSTI, v_opts->msti)) 414 goto out_err; 415 416 nla_nest_end(skb, nest); 417 418 return true; 419 420 out_err: 421 nla_nest_cancel(skb, nest); 422 return false; 423 } 424 425 static size_t rtnl_vlan_global_opts_nlmsg_size(const struct net_bridge_vlan *v) 426 { 427 return NLMSG_ALIGN(sizeof(struct br_vlan_msg)) 428 + nla_total_size(0) /* BRIDGE_VLANDB_GLOBAL_OPTIONS */ 429 + nla_total_size(sizeof(u16)) /* BRIDGE_VLANDB_GOPTS_ID */ 430 #ifdef CONFIG_BRIDGE_IGMP_SNOOPING 431 + nla_total_size(sizeof(u8)) /* BRIDGE_VLANDB_GOPTS_MCAST_SNOOPING */ 432 + nla_total_size(sizeof(u8)) /* BRIDGE_VLANDB_GOPTS_MCAST_IGMP_VERSION */ 433 + nla_total_size(sizeof(u8)) /* BRIDGE_VLANDB_GOPTS_MCAST_MLD_VERSION */ 434 + nla_total_size(sizeof(u32)) /* BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_CNT */ 435 + nla_total_size(sizeof(u32)) /* BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_CNT */ 436 + nla_total_size(sizeof(u64)) /* BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_INTVL */ 437 + nla_total_size(sizeof(u64)) /* BRIDGE_VLANDB_GOPTS_MCAST_MEMBERSHIP_INTVL */ 438 + nla_total_size(sizeof(u64)) /* BRIDGE_VLANDB_GOPTS_MCAST_QUERIER_INTVL */ 439 + nla_total_size(sizeof(u64)) /* BRIDGE_VLANDB_GOPTS_MCAST_QUERY_INTVL */ 440 + nla_total_size(sizeof(u64)) /* BRIDGE_VLANDB_GOPTS_MCAST_QUERY_RESPONSE_INTVL */ 441 + nla_total_size(sizeof(u64)) /* BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_INTVL */ 442 + nla_total_size(sizeof(u8)) /* BRIDGE_VLANDB_GOPTS_MCAST_QUERIER */ 443 + br_multicast_querier_state_size() /* BRIDGE_VLANDB_GOPTS_MCAST_QUERIER_STATE */ 444 + nla_total_size(0) /* BRIDGE_VLANDB_GOPTS_MCAST_ROUTER_PORTS */ 445 + br_rports_size(&v->br_mcast_ctx) /* BRIDGE_VLANDB_GOPTS_MCAST_ROUTER_PORTS */ 446 #endif 447 + nla_total_size(sizeof(u16)) /* BRIDGE_VLANDB_GOPTS_MSTI */ 448 + nla_total_size(sizeof(u16)); /* BRIDGE_VLANDB_GOPTS_RANGE */ 449 } 450 451 static void br_vlan_global_opts_notify(const struct net_bridge *br, 452 u16 vid, u16 vid_range) 453 { 454 struct net_bridge_vlan *v; 455 struct br_vlan_msg *bvm; 456 struct nlmsghdr *nlh; 457 struct sk_buff *skb; 458 int err = -ENOBUFS; 459 460 /* right now notifications are done only with rtnl held */ 461 ASSERT_RTNL(); 462 463 /* need to find the vlan due to flags/options */ 464 v = br_vlan_find(br_vlan_group(br), vid); 465 if (!v) 466 return; 467 468 skb = nlmsg_new(rtnl_vlan_global_opts_nlmsg_size(v), GFP_KERNEL); 469 if (!skb) 470 goto out_err; 471 472 err = -EMSGSIZE; 473 nlh = nlmsg_put(skb, 0, 0, RTM_NEWVLAN, sizeof(*bvm), 0); 474 if (!nlh) 475 goto out_err; 476 bvm = nlmsg_data(nlh); 477 memset(bvm, 0, sizeof(*bvm)); 478 bvm->family = AF_BRIDGE; 479 bvm->ifindex = br->dev->ifindex; 480 481 if (!br_vlan_global_opts_fill(skb, vid, vid_range, v)) 482 goto out_err; 483 484 nlmsg_end(skb, nlh); 485 rtnl_notify(skb, dev_net(br->dev), 0, RTNLGRP_BRVLAN, NULL, GFP_KERNEL); 486 return; 487 488 out_err: 489 rtnl_set_sk_err(dev_net(br->dev), RTNLGRP_BRVLAN, err); 490 kfree_skb(skb); 491 } 492 493 static int br_vlan_process_global_one_opts(const struct net_bridge *br, 494 struct net_bridge_vlan_group *vg, 495 struct net_bridge_vlan *v, 496 struct nlattr **tb, 497 bool *changed, 498 struct netlink_ext_ack *extack) 499 { 500 int err __maybe_unused; 501 502 *changed = false; 503 #ifdef CONFIG_BRIDGE_IGMP_SNOOPING 504 if (tb[BRIDGE_VLANDB_GOPTS_MCAST_SNOOPING]) { 505 u8 mc_snooping; 506 507 mc_snooping = nla_get_u8(tb[BRIDGE_VLANDB_GOPTS_MCAST_SNOOPING]); 508 if (br_multicast_toggle_global_vlan(v, !!mc_snooping)) 509 *changed = true; 510 } 511 if (tb[BRIDGE_VLANDB_GOPTS_MCAST_IGMP_VERSION]) { 512 u8 ver; 513 514 ver = nla_get_u8(tb[BRIDGE_VLANDB_GOPTS_MCAST_IGMP_VERSION]); 515 err = br_multicast_set_igmp_version(&v->br_mcast_ctx, ver); 516 if (err) 517 return err; 518 *changed = true; 519 } 520 if (tb[BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_CNT]) { 521 u32 cnt; 522 523 cnt = nla_get_u32(tb[BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_CNT]); 524 v->br_mcast_ctx.multicast_last_member_count = cnt; 525 *changed = true; 526 } 527 if (tb[BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_CNT]) { 528 u32 cnt; 529 530 cnt = nla_get_u32(tb[BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_CNT]); 531 v->br_mcast_ctx.multicast_startup_query_count = cnt; 532 *changed = true; 533 } 534 if (tb[BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_INTVL]) { 535 u64 val; 536 537 val = nla_get_u64(tb[BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_INTVL]); 538 v->br_mcast_ctx.multicast_last_member_interval = clock_t_to_jiffies(val); 539 *changed = true; 540 } 541 if (tb[BRIDGE_VLANDB_GOPTS_MCAST_MEMBERSHIP_INTVL]) { 542 u64 val; 543 544 val = nla_get_u64(tb[BRIDGE_VLANDB_GOPTS_MCAST_MEMBERSHIP_INTVL]); 545 v->br_mcast_ctx.multicast_membership_interval = clock_t_to_jiffies(val); 546 *changed = true; 547 } 548 if (tb[BRIDGE_VLANDB_GOPTS_MCAST_QUERIER_INTVL]) { 549 u64 val; 550 551 val = nla_get_u64(tb[BRIDGE_VLANDB_GOPTS_MCAST_QUERIER_INTVL]); 552 v->br_mcast_ctx.multicast_querier_interval = clock_t_to_jiffies(val); 553 *changed = true; 554 } 555 if (tb[BRIDGE_VLANDB_GOPTS_MCAST_QUERY_INTVL]) { 556 u64 val; 557 558 val = nla_get_u64(tb[BRIDGE_VLANDB_GOPTS_MCAST_QUERY_INTVL]); 559 br_multicast_set_query_intvl(&v->br_mcast_ctx, val); 560 *changed = true; 561 } 562 if (tb[BRIDGE_VLANDB_GOPTS_MCAST_QUERY_RESPONSE_INTVL]) { 563 u64 val; 564 565 val = nla_get_u64(tb[BRIDGE_VLANDB_GOPTS_MCAST_QUERY_RESPONSE_INTVL]); 566 v->br_mcast_ctx.multicast_query_response_interval = clock_t_to_jiffies(val); 567 *changed = true; 568 } 569 if (tb[BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_INTVL]) { 570 u64 val; 571 572 val = nla_get_u64(tb[BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_INTVL]); 573 br_multicast_set_startup_query_intvl(&v->br_mcast_ctx, val); 574 *changed = true; 575 } 576 if (tb[BRIDGE_VLANDB_GOPTS_MCAST_QUERIER]) { 577 u8 val; 578 579 val = nla_get_u8(tb[BRIDGE_VLANDB_GOPTS_MCAST_QUERIER]); 580 err = br_multicast_set_querier(&v->br_mcast_ctx, val); 581 if (err) 582 return err; 583 *changed = true; 584 } 585 #if IS_ENABLED(CONFIG_IPV6) 586 if (tb[BRIDGE_VLANDB_GOPTS_MCAST_MLD_VERSION]) { 587 u8 ver; 588 589 ver = nla_get_u8(tb[BRIDGE_VLANDB_GOPTS_MCAST_MLD_VERSION]); 590 err = br_multicast_set_mld_version(&v->br_mcast_ctx, ver); 591 if (err) 592 return err; 593 *changed = true; 594 } 595 #endif 596 #endif 597 if (tb[BRIDGE_VLANDB_GOPTS_MSTI]) { 598 u16 msti; 599 600 msti = nla_get_u16(tb[BRIDGE_VLANDB_GOPTS_MSTI]); 601 err = br_mst_vlan_set_msti(v, msti); 602 if (err) 603 return err; 604 *changed = true; 605 } 606 607 return 0; 608 } 609 610 static const struct nla_policy br_vlan_db_gpol[BRIDGE_VLANDB_GOPTS_MAX + 1] = { 611 [BRIDGE_VLANDB_GOPTS_ID] = { .type = NLA_U16 }, 612 [BRIDGE_VLANDB_GOPTS_RANGE] = { .type = NLA_U16 }, 613 [BRIDGE_VLANDB_GOPTS_MCAST_SNOOPING] = { .type = NLA_U8 }, 614 [BRIDGE_VLANDB_GOPTS_MCAST_MLD_VERSION] = { .type = NLA_U8 }, 615 [BRIDGE_VLANDB_GOPTS_MCAST_QUERY_INTVL] = { .type = NLA_U64 }, 616 [BRIDGE_VLANDB_GOPTS_MCAST_QUERIER] = { .type = NLA_U8 }, 617 [BRIDGE_VLANDB_GOPTS_MCAST_IGMP_VERSION] = { .type = NLA_U8 }, 618 [BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_CNT] = { .type = NLA_U32 }, 619 [BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_CNT] = { .type = NLA_U32 }, 620 [BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_INTVL] = { .type = NLA_U64 }, 621 [BRIDGE_VLANDB_GOPTS_MCAST_MEMBERSHIP_INTVL] = { .type = NLA_U64 }, 622 [BRIDGE_VLANDB_GOPTS_MCAST_QUERIER_INTVL] = { .type = NLA_U64 }, 623 [BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_INTVL] = { .type = NLA_U64 }, 624 [BRIDGE_VLANDB_GOPTS_MCAST_QUERY_RESPONSE_INTVL] = { .type = NLA_U64 }, 625 [BRIDGE_VLANDB_GOPTS_MSTI] = NLA_POLICY_MAX(NLA_U16, VLAN_N_VID - 1), 626 }; 627 628 int br_vlan_rtm_process_global_options(struct net_device *dev, 629 const struct nlattr *attr, 630 int cmd, 631 struct netlink_ext_ack *extack) 632 { 633 struct net_bridge_vlan *v, *curr_start = NULL, *curr_end = NULL; 634 struct nlattr *tb[BRIDGE_VLANDB_GOPTS_MAX + 1]; 635 struct net_bridge_vlan_group *vg; 636 u16 vid, vid_range = 0; 637 struct net_bridge *br; 638 int err = 0; 639 640 if (cmd != RTM_NEWVLAN) { 641 NL_SET_ERR_MSG_MOD(extack, "Global vlan options support only set operation"); 642 return -EINVAL; 643 } 644 if (!netif_is_bridge_master(dev)) { 645 NL_SET_ERR_MSG_MOD(extack, "Global vlan options can only be set on bridge device"); 646 return -EINVAL; 647 } 648 br = netdev_priv(dev); 649 vg = br_vlan_group(br); 650 if (WARN_ON(!vg)) 651 return -ENODEV; 652 653 err = nla_parse_nested(tb, BRIDGE_VLANDB_GOPTS_MAX, attr, 654 br_vlan_db_gpol, extack); 655 if (err) 656 return err; 657 658 if (!tb[BRIDGE_VLANDB_GOPTS_ID]) { 659 NL_SET_ERR_MSG_MOD(extack, "Missing vlan entry id"); 660 return -EINVAL; 661 } 662 vid = nla_get_u16(tb[BRIDGE_VLANDB_GOPTS_ID]); 663 if (!br_vlan_valid_id(vid, extack)) 664 return -EINVAL; 665 666 if (tb[BRIDGE_VLANDB_GOPTS_RANGE]) { 667 vid_range = nla_get_u16(tb[BRIDGE_VLANDB_GOPTS_RANGE]); 668 if (!br_vlan_valid_id(vid_range, extack)) 669 return -EINVAL; 670 if (vid >= vid_range) { 671 NL_SET_ERR_MSG_MOD(extack, "End vlan id is less than or equal to start vlan id"); 672 return -EINVAL; 673 } 674 } else { 675 vid_range = vid; 676 } 677 678 for (; vid <= vid_range; vid++) { 679 bool changed = false; 680 681 v = br_vlan_find(vg, vid); 682 if (!v) { 683 NL_SET_ERR_MSG_MOD(extack, "Vlan in range doesn't exist, can't process global options"); 684 err = -ENOENT; 685 break; 686 } 687 688 err = br_vlan_process_global_one_opts(br, vg, v, tb, &changed, 689 extack); 690 if (err) 691 break; 692 693 if (changed) { 694 /* vlan options changed, check for range */ 695 if (!curr_start) { 696 curr_start = v; 697 curr_end = v; 698 continue; 699 } 700 701 if (!br_vlan_global_opts_can_enter_range(v, curr_end)) { 702 br_vlan_global_opts_notify(br, curr_start->vid, 703 curr_end->vid); 704 curr_start = v; 705 } 706 curr_end = v; 707 } else { 708 /* nothing changed and nothing to notify yet */ 709 if (!curr_start) 710 continue; 711 712 br_vlan_global_opts_notify(br, curr_start->vid, 713 curr_end->vid); 714 curr_start = NULL; 715 curr_end = NULL; 716 } 717 } 718 if (curr_start) 719 br_vlan_global_opts_notify(br, curr_start->vid, curr_end->vid); 720 721 return err; 722 } 723