hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/net/bridge/br_netlink.c
....@@ -1,13 +1,9 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Bridge netlink control interface
34 *
45 * Authors:
56 * Stephen Hemminger <shemminger@osdl.org>
6
- *
7
- * This program is free software; you can redistribute it and/or
8
- * modify it under the terms of the GNU General Public License
9
- * as published by the Free Software Foundation; either version
10
- * 2 of the License, or (at your option) any later version.
117 */
128
139 #include <linux/kernel.h>
....@@ -102,9 +98,10 @@
10298 size_t vinfo_sz = 0;
10399
104100 rcu_read_lock();
105
- if (br_port_exists(dev)) {
106
- p = br_port_get_rcu(dev);
107
- vg = nbp_vlan_group_rcu(p);
101
+ if (netif_is_bridge_port(dev)) {
102
+ p = br_port_get_check_rcu(dev);
103
+ if (p)
104
+ vg = nbp_vlan_group_rcu(p);
108105 } else if (dev->priv_flags & IFF_EBRIDGE) {
109106 br = netdev_priv(dev);
110107 vg = br_vlan_group_rcu(br);
....@@ -155,6 +152,8 @@
155152 + nla_total_size(sizeof(u8)) /* IFLA_BRPORT_MULTICAST_ROUTER */
156153 #endif
157154 + nla_total_size(sizeof(u16)) /* IFLA_BRPORT_GROUP_FWD_MASK */
155
+ + nla_total_size(sizeof(u8)) /* IFLA_BRPORT_MRP_RING_OPEN */
156
+ + nla_total_size(sizeof(u8)) /* IFLA_BRPORT_MRP_IN_OPEN */
158157 + 0;
159158 }
160159
....@@ -217,6 +216,10 @@
217216 nla_put_u16(skb, IFLA_BRPORT_GROUP_FWD_MASK, p->group_fwd_mask) ||
218217 nla_put_u8(skb, IFLA_BRPORT_NEIGH_SUPPRESS,
219218 !!(p->flags & BR_NEIGH_SUPPRESS)) ||
219
+ nla_put_u8(skb, IFLA_BRPORT_MRP_RING_OPEN, !!(p->flags &
220
+ BR_MRP_LOST_CONT)) ||
221
+ nla_put_u8(skb, IFLA_BRPORT_MRP_IN_OPEN,
222
+ !!(p->flags & BR_MRP_LOST_IN_CONT)) ||
220223 nla_put_u8(skb, IFLA_BRPORT_ISOLATED, !!(p->flags & BR_ISOLATED)))
221224 return -EMSGSIZE;
222225
....@@ -378,6 +381,7 @@
378381 u32 filter_mask, const struct net_device *dev)
379382 {
380383 u8 operstate = netif_running(dev) ? dev->operstate : IF_OPER_DOWN;
384
+ struct nlattr *af = NULL;
381385 struct net_bridge *br;
382386 struct ifinfomsg *hdr;
383387 struct nlmsghdr *nlh;
....@@ -413,19 +417,26 @@
413417 goto nla_put_failure;
414418
415419 if (event == RTM_NEWLINK && port) {
416
- struct nlattr *nest
417
- = nla_nest_start(skb, IFLA_PROTINFO | NLA_F_NESTED);
420
+ struct nlattr *nest;
418421
422
+ nest = nla_nest_start(skb, IFLA_PROTINFO);
419423 if (nest == NULL || br_port_fill_attrs(skb, port) < 0)
420424 goto nla_put_failure;
421425 nla_nest_end(skb, nest);
426
+ }
427
+
428
+ if (filter_mask & (RTEXT_FILTER_BRVLAN |
429
+ RTEXT_FILTER_BRVLAN_COMPRESSED |
430
+ RTEXT_FILTER_MRP)) {
431
+ af = nla_nest_start_noflag(skb, IFLA_AF_SPEC);
432
+ if (!af)
433
+ goto nla_put_failure;
422434 }
423435
424436 /* Check if the VID information is requested */
425437 if ((filter_mask & RTEXT_FILTER_BRVLAN) ||
426438 (filter_mask & RTEXT_FILTER_BRVLAN_COMPRESSED)) {
427439 struct net_bridge_vlan_group *vg;
428
- struct nlattr *af;
429440 int err;
430441
431442 /* RCU needed because of the VLAN locking rules (rcu || rtnl) */
....@@ -439,11 +450,6 @@
439450 rcu_read_unlock();
440451 goto done;
441452 }
442
- af = nla_nest_start(skb, IFLA_AF_SPEC);
443
- if (!af) {
444
- rcu_read_unlock();
445
- goto nla_put_failure;
446
- }
447453 if (filter_mask & RTEXT_FILTER_BRVLAN_COMPRESSED)
448454 err = br_fill_ifvlaninfo_compressed(skb, vg);
449455 else
....@@ -454,10 +460,25 @@
454460 rcu_read_unlock();
455461 if (err)
456462 goto nla_put_failure;
457
- nla_nest_end(skb, af);
463
+ }
464
+
465
+ if (filter_mask & RTEXT_FILTER_MRP) {
466
+ int err;
467
+
468
+ if (!br_mrp_enabled(br) || port)
469
+ goto done;
470
+
471
+ rcu_read_lock();
472
+ err = br_mrp_fill_info(skb, br);
473
+ rcu_read_unlock();
474
+
475
+ if (err)
476
+ goto nla_put_failure;
458477 }
459478
460479 done:
480
+ if (af)
481
+ nla_nest_end(skb, af);
461482 nlmsg_end(skb, nlh);
462483 return 0;
463484
....@@ -517,7 +538,8 @@
517538 struct net_bridge_port *port = br_port_get_rtnl(dev);
518539
519540 if (!port && !(filter_mask & RTEXT_FILTER_BRVLAN) &&
520
- !(filter_mask & RTEXT_FILTER_BRVLAN_COMPRESSED))
541
+ !(filter_mask & RTEXT_FILTER_BRVLAN_COMPRESSED) &&
542
+ !(filter_mask & RTEXT_FILTER_MRP))
521543 return 0;
522544
523545 return br_fill_ifinfo(skb, port, pid, seq, RTM_NEWLINK, nlflags,
....@@ -525,7 +547,8 @@
525547 }
526548
527549 static int br_vlan_info(struct net_bridge *br, struct net_bridge_port *p,
528
- int cmd, struct bridge_vlan_info *vinfo, bool *changed)
550
+ int cmd, struct bridge_vlan_info *vinfo, bool *changed,
551
+ struct netlink_ext_ack *extack)
529552 {
530553 bool curr_change;
531554 int err = 0;
....@@ -537,11 +560,11 @@
537560 * per-VLAN entry as well
538561 */
539562 err = nbp_vlan_add(p, vinfo->vid, vinfo->flags,
540
- &curr_change);
563
+ &curr_change, extack);
541564 } else {
542565 vinfo->flags |= BRIDGE_VLAN_INFO_BRENTRY;
543566 err = br_vlan_add(br, vinfo->vid, vinfo->flags,
544
- &curr_change);
567
+ &curr_change, extack);
545568 }
546569 if (curr_change)
547570 *changed = true;
....@@ -564,56 +587,81 @@
564587 return err;
565588 }
566589
567
-static int br_process_vlan_info(struct net_bridge *br,
568
- struct net_bridge_port *p, int cmd,
569
- struct bridge_vlan_info *vinfo_curr,
570
- struct bridge_vlan_info **vinfo_last,
571
- bool *changed)
590
+int br_process_vlan_info(struct net_bridge *br,
591
+ struct net_bridge_port *p, int cmd,
592
+ struct bridge_vlan_info *vinfo_curr,
593
+ struct bridge_vlan_info **vinfo_last,
594
+ bool *changed,
595
+ struct netlink_ext_ack *extack)
572596 {
573
- if (!vinfo_curr->vid || vinfo_curr->vid >= VLAN_VID_MASK)
597
+ int err, rtm_cmd;
598
+
599
+ if (!br_vlan_valid_id(vinfo_curr->vid, extack))
574600 return -EINVAL;
575601
602
+ /* needed for vlan-only NEWVLAN/DELVLAN notifications */
603
+ rtm_cmd = br_afspec_cmd_to_rtm(cmd);
604
+
576605 if (vinfo_curr->flags & BRIDGE_VLAN_INFO_RANGE_BEGIN) {
577
- /* check if we are already processing a range */
578
- if (*vinfo_last)
606
+ if (!br_vlan_valid_range(vinfo_curr, *vinfo_last, extack))
579607 return -EINVAL;
580608 *vinfo_last = vinfo_curr;
581
- /* don't allow range of pvids */
582
- if ((*vinfo_last)->flags & BRIDGE_VLAN_INFO_PVID)
583
- return -EINVAL;
584609 return 0;
585610 }
586611
587612 if (*vinfo_last) {
588613 struct bridge_vlan_info tmp_vinfo;
589
- int v, err;
614
+ int v, v_change_start = 0;
590615
591
- if (!(vinfo_curr->flags & BRIDGE_VLAN_INFO_RANGE_END))
592
- return -EINVAL;
593
-
594
- if (vinfo_curr->vid <= (*vinfo_last)->vid)
616
+ if (!br_vlan_valid_range(vinfo_curr, *vinfo_last, extack))
595617 return -EINVAL;
596618
597619 memcpy(&tmp_vinfo, *vinfo_last,
598620 sizeof(struct bridge_vlan_info));
599621 for (v = (*vinfo_last)->vid; v <= vinfo_curr->vid; v++) {
622
+ bool curr_change = false;
623
+
600624 tmp_vinfo.vid = v;
601
- err = br_vlan_info(br, p, cmd, &tmp_vinfo, changed);
625
+ err = br_vlan_info(br, p, cmd, &tmp_vinfo, &curr_change,
626
+ extack);
602627 if (err)
603628 break;
629
+ if (curr_change) {
630
+ *changed = curr_change;
631
+ if (!v_change_start)
632
+ v_change_start = v;
633
+ } else {
634
+ /* nothing to notify yet */
635
+ if (!v_change_start)
636
+ continue;
637
+ br_vlan_notify(br, p, v_change_start,
638
+ v - 1, rtm_cmd);
639
+ v_change_start = 0;
640
+ }
641
+ cond_resched();
604642 }
643
+ /* v_change_start is set only if the last/whole range changed */
644
+ if (v_change_start)
645
+ br_vlan_notify(br, p, v_change_start,
646
+ v - 1, rtm_cmd);
647
+
605648 *vinfo_last = NULL;
606649
607650 return err;
608651 }
609652
610
- return br_vlan_info(br, p, cmd, vinfo_curr, changed);
653
+ err = br_vlan_info(br, p, cmd, vinfo_curr, changed, extack);
654
+ if (*changed)
655
+ br_vlan_notify(br, p, vinfo_curr->vid, 0, rtm_cmd);
656
+
657
+ return err;
611658 }
612659
613660 static int br_afspec(struct net_bridge *br,
614661 struct net_bridge_port *p,
615662 struct nlattr *af_spec,
616
- int cmd, bool *changed)
663
+ int cmd, bool *changed,
664
+ struct netlink_ext_ack *extack)
617665 {
618666 struct bridge_vlan_info *vinfo_curr = NULL;
619667 struct bridge_vlan_info *vinfo_last = NULL;
....@@ -643,7 +691,13 @@
643691 return -EINVAL;
644692 vinfo_curr = nla_data(attr);
645693 err = br_process_vlan_info(br, p, cmd, vinfo_curr,
646
- &vinfo_last, changed);
694
+ &vinfo_last, changed,
695
+ extack);
696
+ if (err)
697
+ return err;
698
+ break;
699
+ case IFLA_BRIDGE_MRP:
700
+ err = br_mrp_parse(br, p, attr, cmd, extack);
647701 if (err)
648702 return err;
649703 break;
....@@ -850,7 +904,8 @@
850904 }
851905
852906 /* Change state and parameters on port. */
853
-int br_setlink(struct net_device *dev, struct nlmsghdr *nlh, u16 flags)
907
+int br_setlink(struct net_device *dev, struct nlmsghdr *nlh, u16 flags,
908
+ struct netlink_ext_ack *extack)
854909 {
855910 struct net_bridge *br = (struct net_bridge *)netdev_priv(dev);
856911 struct nlattr *tb[IFLA_BRPORT_MAX + 1];
....@@ -874,8 +929,10 @@
874929
875930 if (p && protinfo) {
876931 if (protinfo->nla_type & NLA_F_NESTED) {
877
- err = nla_parse_nested(tb, IFLA_BRPORT_MAX, protinfo,
878
- br_port_policy, NULL);
932
+ err = nla_parse_nested_deprecated(tb, IFLA_BRPORT_MAX,
933
+ protinfo,
934
+ br_port_policy,
935
+ NULL);
879936 if (err)
880937 return err;
881938
....@@ -897,7 +954,7 @@
897954 }
898955
899956 if (afspec)
900
- err = br_afspec(br, p, afspec, RTM_SETLINK, &changed);
957
+ err = br_afspec(br, p, afspec, RTM_SETLINK, &changed, extack);
901958
902959 if (changed)
903960 br_ifinfo_notify(RTM_NEWLINK, br, p);
....@@ -923,7 +980,7 @@
923980 if (!p && !(dev->priv_flags & IFF_EBRIDGE))
924981 return -EINVAL;
925982
926
- err = br_afspec(br, p, afspec, RTM_DELLINK, &changed);
983
+ err = br_afspec(br, p, afspec, RTM_DELLINK, &changed, NULL);
927984 if (changed)
928985 /* Send RTM_NEWLINK because userspace
929986 * expects RTM_NEWLINK for vlan dels
....@@ -1034,6 +1091,9 @@
10341091 [IFLA_BR_MCAST_STATS_ENABLED] = { .type = NLA_U8 },
10351092 [IFLA_BR_MCAST_IGMP_VERSION] = { .type = NLA_U8 },
10361093 [IFLA_BR_MCAST_MLD_VERSION] = { .type = NLA_U8 },
1094
+ [IFLA_BR_VLAN_STATS_PER_PORT] = { .type = NLA_U8 },
1095
+ [IFLA_BR_MULTI_BOOLOPT] =
1096
+ NLA_POLICY_EXACT_LEN(sizeof(struct br_boolopt_multi)),
10371097 };
10381098
10391099 static int br_changelink(struct net_device *brdev, struct nlattr *tb[],
....@@ -1073,7 +1133,9 @@
10731133 if (data[IFLA_BR_STP_STATE]) {
10741134 u32 stp_enabled = nla_get_u32(data[IFLA_BR_STP_STATE]);
10751135
1076
- br_stp_set_enabled(br, stp_enabled);
1136
+ err = br_stp_set_enabled(br, stp_enabled, extack);
1137
+ if (err)
1138
+ return err;
10771139 }
10781140
10791141 if (data[IFLA_BR_PRIORITY]) {
....@@ -1102,7 +1164,7 @@
11021164 if (data[IFLA_BR_VLAN_DEFAULT_PVID]) {
11031165 __u16 defpvid = nla_get_u16(data[IFLA_BR_VLAN_DEFAULT_PVID]);
11041166
1105
- err = __br_vlan_set_default_pvid(br, defpvid);
1167
+ err = __br_vlan_set_default_pvid(br, defpvid, extack);
11061168 if (err)
11071169 return err;
11081170 }
....@@ -1111,6 +1173,14 @@
11111173 __u8 vlan_stats = nla_get_u8(data[IFLA_BR_VLAN_STATS_ENABLED]);
11121174
11131175 err = br_vlan_set_stats(br, vlan_stats);
1176
+ if (err)
1177
+ return err;
1178
+ }
1179
+
1180
+ if (data[IFLA_BR_VLAN_STATS_PER_PORT]) {
1181
+ __u8 per_port = nla_get_u8(data[IFLA_BR_VLAN_STATS_PER_PORT]);
1182
+
1183
+ err = br_vlan_set_stats_per_port(br, per_port);
11141184 if (err)
11151185 return err;
11161186 }
....@@ -1139,7 +1209,7 @@
11391209 spin_lock_bh(&br->lock);
11401210 memcpy(br->group_addr, new_addr, sizeof(br->group_addr));
11411211 spin_unlock_bh(&br->lock);
1142
- br->group_addr_set = true;
1212
+ br_opt_toggle(br, BROPT_GROUP_ADDR_SET, true);
11431213 br_recalculate_fwd_mask(br);
11441214 }
11451215
....@@ -1158,16 +1228,14 @@
11581228 if (data[IFLA_BR_MCAST_SNOOPING]) {
11591229 u8 mcast_snooping = nla_get_u8(data[IFLA_BR_MCAST_SNOOPING]);
11601230
1161
- err = br_multicast_toggle(br, mcast_snooping);
1162
- if (err)
1163
- return err;
1231
+ br_multicast_toggle(br, mcast_snooping);
11641232 }
11651233
11661234 if (data[IFLA_BR_MCAST_QUERY_USE_IFADDR]) {
11671235 u8 val;
11681236
11691237 val = nla_get_u8(data[IFLA_BR_MCAST_QUERY_USE_IFADDR]);
1170
- br->multicast_query_use_ifaddr = !!val;
1238
+ br_opt_toggle(br, BROPT_MULTICAST_QUERY_USE_IFADDR, !!val);
11711239 }
11721240
11731241 if (data[IFLA_BR_MCAST_QUERIER]) {
....@@ -1178,19 +1246,12 @@
11781246 return err;
11791247 }
11801248
1181
- if (data[IFLA_BR_MCAST_HASH_ELASTICITY]) {
1182
- u32 val = nla_get_u32(data[IFLA_BR_MCAST_HASH_ELASTICITY]);
1249
+ if (data[IFLA_BR_MCAST_HASH_ELASTICITY])
1250
+ br_warn(br, "the hash_elasticity option has been deprecated and is always %u\n",
1251
+ RHT_ELASTICITY);
11831252
1184
- br->hash_elasticity = val;
1185
- }
1186
-
1187
- if (data[IFLA_BR_MCAST_HASH_MAX]) {
1188
- u32 hash_max = nla_get_u32(data[IFLA_BR_MCAST_HASH_MAX]);
1189
-
1190
- err = br_multicast_set_hash_max(br, hash_max);
1191
- if (err)
1192
- return err;
1193
- }
1253
+ if (data[IFLA_BR_MCAST_HASH_MAX])
1254
+ br->hash_max = nla_get_u32(data[IFLA_BR_MCAST_HASH_MAX]);
11941255
11951256 if (data[IFLA_BR_MCAST_LAST_MEMBER_CNT]) {
11961257 u32 val = nla_get_u32(data[IFLA_BR_MCAST_LAST_MEMBER_CNT]);
....@@ -1244,7 +1305,7 @@
12441305 __u8 mcast_stats;
12451306
12461307 mcast_stats = nla_get_u8(data[IFLA_BR_MCAST_STATS_ENABLED]);
1247
- br->multicast_stats_enabled = !!mcast_stats;
1308
+ br_opt_toggle(br, BROPT_MULTICAST_STATS_ENABLED, !!mcast_stats);
12481309 }
12491310
12501311 if (data[IFLA_BR_MCAST_IGMP_VERSION]) {
....@@ -1271,21 +1332,30 @@
12711332 if (data[IFLA_BR_NF_CALL_IPTABLES]) {
12721333 u8 val = nla_get_u8(data[IFLA_BR_NF_CALL_IPTABLES]);
12731334
1274
- br->nf_call_iptables = val ? true : false;
1335
+ br_opt_toggle(br, BROPT_NF_CALL_IPTABLES, !!val);
12751336 }
12761337
12771338 if (data[IFLA_BR_NF_CALL_IP6TABLES]) {
12781339 u8 val = nla_get_u8(data[IFLA_BR_NF_CALL_IP6TABLES]);
12791340
1280
- br->nf_call_ip6tables = val ? true : false;
1341
+ br_opt_toggle(br, BROPT_NF_CALL_IP6TABLES, !!val);
12811342 }
12821343
12831344 if (data[IFLA_BR_NF_CALL_ARPTABLES]) {
12841345 u8 val = nla_get_u8(data[IFLA_BR_NF_CALL_ARPTABLES]);
12851346
1286
- br->nf_call_arptables = val ? true : false;
1347
+ br_opt_toggle(br, BROPT_NF_CALL_ARPTABLES, !!val);
12871348 }
12881349 #endif
1350
+
1351
+ if (data[IFLA_BR_MULTI_BOOLOPT]) {
1352
+ struct br_boolopt_multi *bm;
1353
+
1354
+ bm = nla_data(data[IFLA_BR_MULTI_BOOLOPT]);
1355
+ err = br_boolopt_multi_toggle(br, bm, extack);
1356
+ if (err)
1357
+ return err;
1358
+ }
12891359
12901360 return 0;
12911361 }
....@@ -1327,6 +1397,7 @@
13271397 nla_total_size(sizeof(__be16)) + /* IFLA_BR_VLAN_PROTOCOL */
13281398 nla_total_size(sizeof(u16)) + /* IFLA_BR_VLAN_DEFAULT_PVID */
13291399 nla_total_size(sizeof(u8)) + /* IFLA_BR_VLAN_STATS_ENABLED */
1400
+ nla_total_size(sizeof(u8)) + /* IFLA_BR_VLAN_STATS_PER_PORT */
13301401 #endif
13311402 nla_total_size(sizeof(u16)) + /* IFLA_BR_GROUP_FWD_MASK */
13321403 nla_total_size(sizeof(struct ifla_bridge_id)) + /* IFLA_BR_ROOT_ID */
....@@ -1364,6 +1435,7 @@
13641435 nla_total_size(sizeof(u8)) + /* IFLA_BR_NF_CALL_IP6TABLES */
13651436 nla_total_size(sizeof(u8)) + /* IFLA_BR_NF_CALL_ARPTABLES */
13661437 #endif
1438
+ nla_total_size(sizeof(struct br_boolopt_multi)) + /* IFLA_BR_MULTI_BOOLOPT */
13671439 0;
13681440 }
13691441
....@@ -1377,6 +1449,7 @@
13771449 u32 stp_enabled = br->stp_enabled;
13781450 u16 priority = (br->bridge_id.prio[0] << 8) | br->bridge_id.prio[1];
13791451 u8 vlan_enabled = br_vlan_enabled(br->dev);
1452
+ struct br_boolopt_multi bm;
13801453 u64 clockval;
13811454
13821455 clockval = br_timer_value(&br->hello_timer);
....@@ -1393,6 +1466,7 @@
13931466 if (nla_put_u64_64bit(skb, IFLA_BR_GC_TIMER, clockval, IFLA_BR_PAD))
13941467 return -EMSGSIZE;
13951468
1469
+ br_boolopt_multi_get(br, &bm);
13961470 if (nla_put_u32(skb, IFLA_BR_FORWARD_DELAY, forward_delay) ||
13971471 nla_put_u32(skb, IFLA_BR_HELLO_TIME, hello_time) ||
13981472 nla_put_u32(skb, IFLA_BR_MAX_AGE, age_time) ||
....@@ -1410,25 +1484,30 @@
14101484 nla_put_u8(skb, IFLA_BR_TOPOLOGY_CHANGE, br->topology_change) ||
14111485 nla_put_u8(skb, IFLA_BR_TOPOLOGY_CHANGE_DETECTED,
14121486 br->topology_change_detected) ||
1413
- nla_put(skb, IFLA_BR_GROUP_ADDR, ETH_ALEN, br->group_addr))
1487
+ nla_put(skb, IFLA_BR_GROUP_ADDR, ETH_ALEN, br->group_addr) ||
1488
+ nla_put(skb, IFLA_BR_MULTI_BOOLOPT, sizeof(bm), &bm))
14141489 return -EMSGSIZE;
14151490
14161491 #ifdef CONFIG_BRIDGE_VLAN_FILTERING
14171492 if (nla_put_be16(skb, IFLA_BR_VLAN_PROTOCOL, br->vlan_proto) ||
14181493 nla_put_u16(skb, IFLA_BR_VLAN_DEFAULT_PVID, br->default_pvid) ||
1419
- nla_put_u8(skb, IFLA_BR_VLAN_STATS_ENABLED, br->vlan_stats_enabled))
1494
+ nla_put_u8(skb, IFLA_BR_VLAN_STATS_ENABLED,
1495
+ br_opt_get(br, BROPT_VLAN_STATS_ENABLED)) ||
1496
+ nla_put_u8(skb, IFLA_BR_VLAN_STATS_PER_PORT,
1497
+ br_opt_get(br, BROPT_VLAN_STATS_PER_PORT)))
14201498 return -EMSGSIZE;
14211499 #endif
14221500 #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
14231501 if (nla_put_u8(skb, IFLA_BR_MCAST_ROUTER, br->multicast_router) ||
1424
- nla_put_u8(skb, IFLA_BR_MCAST_SNOOPING, !br->multicast_disabled) ||
1502
+ nla_put_u8(skb, IFLA_BR_MCAST_SNOOPING,
1503
+ br_opt_get(br, BROPT_MULTICAST_ENABLED)) ||
14251504 nla_put_u8(skb, IFLA_BR_MCAST_QUERY_USE_IFADDR,
1426
- br->multicast_query_use_ifaddr) ||
1427
- nla_put_u8(skb, IFLA_BR_MCAST_QUERIER, br->multicast_querier) ||
1505
+ br_opt_get(br, BROPT_MULTICAST_QUERY_USE_IFADDR)) ||
1506
+ nla_put_u8(skb, IFLA_BR_MCAST_QUERIER,
1507
+ br_opt_get(br, BROPT_MULTICAST_QUERIER)) ||
14281508 nla_put_u8(skb, IFLA_BR_MCAST_STATS_ENABLED,
1429
- br->multicast_stats_enabled) ||
1430
- nla_put_u32(skb, IFLA_BR_MCAST_HASH_ELASTICITY,
1431
- br->hash_elasticity) ||
1509
+ br_opt_get(br, BROPT_MULTICAST_STATS_ENABLED)) ||
1510
+ nla_put_u32(skb, IFLA_BR_MCAST_HASH_ELASTICITY, RHT_ELASTICITY) ||
14321511 nla_put_u32(skb, IFLA_BR_MCAST_HASH_MAX, br->hash_max) ||
14331512 nla_put_u32(skb, IFLA_BR_MCAST_LAST_MEMBER_CNT,
14341513 br->multicast_last_member_count) ||
....@@ -1469,11 +1548,11 @@
14691548 #endif
14701549 #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
14711550 if (nla_put_u8(skb, IFLA_BR_NF_CALL_IPTABLES,
1472
- br->nf_call_iptables ? 1 : 0) ||
1551
+ br_opt_get(br, BROPT_NF_CALL_IPTABLES) ? 1 : 0) ||
14731552 nla_put_u8(skb, IFLA_BR_NF_CALL_IP6TABLES,
1474
- br->nf_call_ip6tables ? 1 : 0) ||
1553
+ br_opt_get(br, BROPT_NF_CALL_IP6TABLES) ? 1 : 0) ||
14751554 nla_put_u8(skb, IFLA_BR_NF_CALL_ARPTABLES,
1476
- br->nf_call_arptables ? 1 : 0))
1555
+ br_opt_get(br, BROPT_NF_CALL_ARPTABLES) ? 1 : 0))
14771556 return -EMSGSIZE;
14781557 #endif
14791558
....@@ -1512,6 +1591,7 @@
15121591
15131592 return numvls * nla_total_size(sizeof(struct bridge_vlan_xstats)) +
15141593 nla_total_size_64bit(sizeof(struct br_mcast_stats)) +
1594
+ (p ? nla_total_size_64bit(sizeof(p->stp_xstats)) : 0) +
15151595 nla_total_size(0);
15161596 }
15171597
....@@ -1543,7 +1623,7 @@
15431623 return -EINVAL;
15441624 }
15451625
1546
- nest = nla_nest_start(skb, LINK_XSTATS_TYPE_BRIDGE);
1626
+ nest = nla_nest_start_noflag(skb, LINK_XSTATS_TYPE_BRIDGE);
15471627 if (!nest)
15481628 return -EMSGSIZE;
15491629
....@@ -1583,6 +1663,19 @@
15831663 br_multicast_get_stats(br, p, nla_data(nla));
15841664 }
15851665 #endif
1666
+
1667
+ if (p) {
1668
+ nla = nla_reserve_64bit(skb, BRIDGE_XSTATS_STP,
1669
+ sizeof(p->stp_xstats),
1670
+ BRIDGE_XSTATS_PAD);
1671
+ if (!nla)
1672
+ goto nla_put_failure;
1673
+
1674
+ spin_lock_bh(&br->lock);
1675
+ memcpy(nla_data(nla), &p->stp_xstats, sizeof(p->stp_xstats));
1676
+ spin_unlock_bh(&br->lock);
1677
+ }
1678
+
15861679 nla_nest_end(skb, nest);
15871680 *prividx = 0;
15881681
....@@ -1627,6 +1720,7 @@
16271720 int err;
16281721
16291722 br_mdb_init();
1723
+ br_vlan_rtnl_init();
16301724 rtnl_af_register(&br_af_ops);
16311725
16321726 err = rtnl_link_register(&br_link_ops);
....@@ -1644,6 +1738,7 @@
16441738 void br_netlink_fini(void)
16451739 {
16461740 br_mdb_uninit();
1741
+ br_vlan_rtnl_uninit();
16471742 rtnl_af_unregister(&br_af_ops);
16481743 rtnl_link_unregister(&br_link_ops);
16491744 }