Merge tag 'irq_urgent_for_v6.3' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / net / bridge / br_vlan_options.c
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 }