^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Bridge netlink control interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Authors:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Stephen Hemminger <shemminger@osdl.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/etherdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <net/rtnetlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <net/net_namespace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <net/sock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <uapi/linux/if_bridge.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "br_private.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "br_private_stp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "br_private_tunnel.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) static int __get_num_vlan_infos(struct net_bridge_vlan_group *vg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) u32 filter_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) struct net_bridge_vlan *v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) u16 vid_range_start = 0, vid_range_end = 0, vid_range_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) u16 flags, pvid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) int num_vlans = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) if (!(filter_mask & RTEXT_FILTER_BRVLAN_COMPRESSED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) pvid = br_get_pvid(vg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) /* Count number of vlan infos */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) list_for_each_entry_rcu(v, &vg->vlan_list, vlist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) /* only a context, bridge vlan not activated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) if (!br_vlan_should_use(v))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) if (v->vid == pvid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) flags |= BRIDGE_VLAN_INFO_PVID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) if (v->flags & BRIDGE_VLAN_INFO_UNTAGGED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) flags |= BRIDGE_VLAN_INFO_UNTAGGED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) if (vid_range_start == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) goto initvars;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) } else if ((v->vid - vid_range_end) == 1 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) flags == vid_range_flags) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) vid_range_end = v->vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) if ((vid_range_end - vid_range_start) > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) num_vlans += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) num_vlans += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) initvars:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) vid_range_start = v->vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) vid_range_end = v->vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) vid_range_flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) if (vid_range_start != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) if ((vid_range_end - vid_range_start) > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) num_vlans += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) num_vlans += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) return num_vlans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) static int br_get_num_vlan_infos(struct net_bridge_vlan_group *vg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) u32 filter_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) int num_vlans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) if (!vg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) if (filter_mask & RTEXT_FILTER_BRVLAN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) return vg->num_vlans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) num_vlans = __get_num_vlan_infos(vg, filter_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) return num_vlans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) static size_t br_get_link_af_size_filtered(const struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) u32 filter_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) struct net_bridge_vlan_group *vg = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) struct net_bridge_port *p = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) struct net_bridge *br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) int num_vlan_infos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) size_t vinfo_sz = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) if (netif_is_bridge_port(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) p = br_port_get_check_rcu(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) if (p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) vg = nbp_vlan_group_rcu(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) } else if (dev->priv_flags & IFF_EBRIDGE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) br = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) vg = br_vlan_group_rcu(br);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) num_vlan_infos = br_get_num_vlan_infos(vg, filter_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) if (p && (p->flags & BR_VLAN_TUNNEL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) vinfo_sz += br_get_vlan_tunnel_info_size(vg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) /* Each VLAN is returned in bridge_vlan_info along with flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) vinfo_sz += num_vlan_infos * nla_total_size(sizeof(struct bridge_vlan_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) return vinfo_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) static inline size_t br_port_info_size(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) return nla_total_size(1) /* IFLA_BRPORT_STATE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) + nla_total_size(2) /* IFLA_BRPORT_PRIORITY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) + nla_total_size(4) /* IFLA_BRPORT_COST */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) + nla_total_size(1) /* IFLA_BRPORT_MODE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) + nla_total_size(1) /* IFLA_BRPORT_GUARD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) + nla_total_size(1) /* IFLA_BRPORT_PROTECT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) + nla_total_size(1) /* IFLA_BRPORT_FAST_LEAVE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) + nla_total_size(1) /* IFLA_BRPORT_MCAST_TO_UCAST */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) + nla_total_size(1) /* IFLA_BRPORT_LEARNING */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) + nla_total_size(1) /* IFLA_BRPORT_UNICAST_FLOOD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) + nla_total_size(1) /* IFLA_BRPORT_MCAST_FLOOD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) + nla_total_size(1) /* IFLA_BRPORT_BCAST_FLOOD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) + nla_total_size(1) /* IFLA_BRPORT_PROXYARP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) + nla_total_size(1) /* IFLA_BRPORT_PROXYARP_WIFI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) + nla_total_size(1) /* IFLA_BRPORT_VLAN_TUNNEL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) + nla_total_size(1) /* IFLA_BRPORT_NEIGH_SUPPRESS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) + nla_total_size(1) /* IFLA_BRPORT_ISOLATED */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) + nla_total_size(sizeof(struct ifla_bridge_id)) /* IFLA_BRPORT_ROOT_ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) + nla_total_size(sizeof(struct ifla_bridge_id)) /* IFLA_BRPORT_BRIDGE_ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) + nla_total_size(sizeof(u16)) /* IFLA_BRPORT_DESIGNATED_PORT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) + nla_total_size(sizeof(u16)) /* IFLA_BRPORT_DESIGNATED_COST */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) + nla_total_size(sizeof(u16)) /* IFLA_BRPORT_ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) + nla_total_size(sizeof(u16)) /* IFLA_BRPORT_NO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) + nla_total_size(sizeof(u8)) /* IFLA_BRPORT_TOPOLOGY_CHANGE_ACK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) + nla_total_size(sizeof(u8)) /* IFLA_BRPORT_CONFIG_PENDING */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) + nla_total_size_64bit(sizeof(u64)) /* IFLA_BRPORT_MESSAGE_AGE_TIMER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) + nla_total_size_64bit(sizeof(u64)) /* IFLA_BRPORT_FORWARD_DELAY_TIMER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) + nla_total_size_64bit(sizeof(u64)) /* IFLA_BRPORT_HOLD_TIMER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) + nla_total_size(sizeof(u8)) /* IFLA_BRPORT_MULTICAST_ROUTER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) + nla_total_size(sizeof(u16)) /* IFLA_BRPORT_GROUP_FWD_MASK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) + nla_total_size(sizeof(u8)) /* IFLA_BRPORT_MRP_RING_OPEN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) + nla_total_size(sizeof(u8)) /* IFLA_BRPORT_MRP_IN_OPEN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) + 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) static inline size_t br_nlmsg_size(struct net_device *dev, u32 filter_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) return NLMSG_ALIGN(sizeof(struct ifinfomsg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) + nla_total_size(MAX_ADDR_LEN) /* IFLA_ADDRESS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) + nla_total_size(4) /* IFLA_MASTER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) + nla_total_size(4) /* IFLA_MTU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) + nla_total_size(4) /* IFLA_LINK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) + nla_total_size(1) /* IFLA_OPERSTATE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) + nla_total_size(br_port_info_size()) /* IFLA_PROTINFO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) + nla_total_size(br_get_link_af_size_filtered(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) filter_mask)) /* IFLA_AF_SPEC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) + nla_total_size(4); /* IFLA_BRPORT_BACKUP_PORT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) static int br_port_fill_attrs(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) const struct net_bridge_port *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) u8 mode = !!(p->flags & BR_HAIRPIN_MODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) struct net_bridge_port *backup_p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) u64 timerval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) if (nla_put_u8(skb, IFLA_BRPORT_STATE, p->state) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) nla_put_u16(skb, IFLA_BRPORT_PRIORITY, p->priority) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) nla_put_u32(skb, IFLA_BRPORT_COST, p->path_cost) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) nla_put_u8(skb, IFLA_BRPORT_MODE, mode) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) nla_put_u8(skb, IFLA_BRPORT_GUARD, !!(p->flags & BR_BPDU_GUARD)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) nla_put_u8(skb, IFLA_BRPORT_PROTECT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) !!(p->flags & BR_ROOT_BLOCK)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) nla_put_u8(skb, IFLA_BRPORT_FAST_LEAVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) !!(p->flags & BR_MULTICAST_FAST_LEAVE)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) nla_put_u8(skb, IFLA_BRPORT_MCAST_TO_UCAST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) !!(p->flags & BR_MULTICAST_TO_UNICAST)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) nla_put_u8(skb, IFLA_BRPORT_LEARNING, !!(p->flags & BR_LEARNING)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) nla_put_u8(skb, IFLA_BRPORT_UNICAST_FLOOD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) !!(p->flags & BR_FLOOD)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) nla_put_u8(skb, IFLA_BRPORT_MCAST_FLOOD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) !!(p->flags & BR_MCAST_FLOOD)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) nla_put_u8(skb, IFLA_BRPORT_BCAST_FLOOD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) !!(p->flags & BR_BCAST_FLOOD)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) nla_put_u8(skb, IFLA_BRPORT_PROXYARP, !!(p->flags & BR_PROXYARP)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) nla_put_u8(skb, IFLA_BRPORT_PROXYARP_WIFI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) !!(p->flags & BR_PROXYARP_WIFI)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) nla_put(skb, IFLA_BRPORT_ROOT_ID, sizeof(struct ifla_bridge_id),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) &p->designated_root) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) nla_put(skb, IFLA_BRPORT_BRIDGE_ID, sizeof(struct ifla_bridge_id),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) &p->designated_bridge) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) nla_put_u16(skb, IFLA_BRPORT_DESIGNATED_PORT, p->designated_port) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) nla_put_u16(skb, IFLA_BRPORT_DESIGNATED_COST, p->designated_cost) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) nla_put_u16(skb, IFLA_BRPORT_ID, p->port_id) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) nla_put_u16(skb, IFLA_BRPORT_NO, p->port_no) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) nla_put_u8(skb, IFLA_BRPORT_TOPOLOGY_CHANGE_ACK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) p->topology_change_ack) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) nla_put_u8(skb, IFLA_BRPORT_CONFIG_PENDING, p->config_pending) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) nla_put_u8(skb, IFLA_BRPORT_VLAN_TUNNEL, !!(p->flags &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) BR_VLAN_TUNNEL)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) nla_put_u16(skb, IFLA_BRPORT_GROUP_FWD_MASK, p->group_fwd_mask) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) nla_put_u8(skb, IFLA_BRPORT_NEIGH_SUPPRESS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) !!(p->flags & BR_NEIGH_SUPPRESS)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) nla_put_u8(skb, IFLA_BRPORT_MRP_RING_OPEN, !!(p->flags &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) BR_MRP_LOST_CONT)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) nla_put_u8(skb, IFLA_BRPORT_MRP_IN_OPEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) !!(p->flags & BR_MRP_LOST_IN_CONT)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) nla_put_u8(skb, IFLA_BRPORT_ISOLATED, !!(p->flags & BR_ISOLATED)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) timerval = br_timer_value(&p->message_age_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if (nla_put_u64_64bit(skb, IFLA_BRPORT_MESSAGE_AGE_TIMER, timerval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) IFLA_BRPORT_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) timerval = br_timer_value(&p->forward_delay_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) if (nla_put_u64_64bit(skb, IFLA_BRPORT_FORWARD_DELAY_TIMER, timerval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) IFLA_BRPORT_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) timerval = br_timer_value(&p->hold_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) if (nla_put_u64_64bit(skb, IFLA_BRPORT_HOLD_TIMER, timerval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) IFLA_BRPORT_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) if (nla_put_u8(skb, IFLA_BRPORT_MULTICAST_ROUTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) p->multicast_router))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) /* we might be called only with br->lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) backup_p = rcu_dereference(p->backup_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) if (backup_p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) nla_put_u32(skb, IFLA_BRPORT_BACKUP_PORT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) backup_p->dev->ifindex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) static int br_fill_ifvlaninfo_range(struct sk_buff *skb, u16 vid_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) u16 vid_end, u16 flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) struct bridge_vlan_info vinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if ((vid_end - vid_start) > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) /* add range to skb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) vinfo.vid = vid_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) vinfo.flags = flags | BRIDGE_VLAN_INFO_RANGE_BEGIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (nla_put(skb, IFLA_BRIDGE_VLAN_INFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) sizeof(vinfo), &vinfo))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) vinfo.vid = vid_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) vinfo.flags = flags | BRIDGE_VLAN_INFO_RANGE_END;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) if (nla_put(skb, IFLA_BRIDGE_VLAN_INFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) sizeof(vinfo), &vinfo))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) vinfo.vid = vid_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) vinfo.flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) if (nla_put(skb, IFLA_BRIDGE_VLAN_INFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) sizeof(vinfo), &vinfo))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) static int br_fill_ifvlaninfo_compressed(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) struct net_bridge_vlan_group *vg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) struct net_bridge_vlan *v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) u16 vid_range_start = 0, vid_range_end = 0, vid_range_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) u16 flags, pvid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) /* Pack IFLA_BRIDGE_VLAN_INFO's for every vlan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) * and mark vlan info with begin and end flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) * if vlaninfo represents a range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) pvid = br_get_pvid(vg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) list_for_each_entry_rcu(v, &vg->vlan_list, vlist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) if (!br_vlan_should_use(v))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if (v->vid == pvid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) flags |= BRIDGE_VLAN_INFO_PVID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) if (v->flags & BRIDGE_VLAN_INFO_UNTAGGED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) flags |= BRIDGE_VLAN_INFO_UNTAGGED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) if (vid_range_start == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) goto initvars;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) } else if ((v->vid - vid_range_end) == 1 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) flags == vid_range_flags) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) vid_range_end = v->vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) err = br_fill_ifvlaninfo_range(skb, vid_range_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) vid_range_end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) vid_range_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) initvars:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) vid_range_start = v->vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) vid_range_end = v->vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) vid_range_flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) if (vid_range_start != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) /* Call it once more to send any left over vlans */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) err = br_fill_ifvlaninfo_range(skb, vid_range_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) vid_range_end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) vid_range_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) static int br_fill_ifvlaninfo(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) struct net_bridge_vlan_group *vg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) struct bridge_vlan_info vinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) struct net_bridge_vlan *v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) u16 pvid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) pvid = br_get_pvid(vg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) list_for_each_entry_rcu(v, &vg->vlan_list, vlist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) if (!br_vlan_should_use(v))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) vinfo.vid = v->vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) vinfo.flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) if (v->vid == pvid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) vinfo.flags |= BRIDGE_VLAN_INFO_PVID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) if (v->flags & BRIDGE_VLAN_INFO_UNTAGGED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) vinfo.flags |= BRIDGE_VLAN_INFO_UNTAGGED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) if (nla_put(skb, IFLA_BRIDGE_VLAN_INFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) sizeof(vinfo), &vinfo))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) * Create one netlink message for one interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) * Contains port and master info as well as carrier and bridge state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) static int br_fill_ifinfo(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) const struct net_bridge_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) u32 pid, u32 seq, int event, unsigned int flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) u32 filter_mask, const struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) u8 operstate = netif_running(dev) ? dev->operstate : IF_OPER_DOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) struct nlattr *af = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) struct net_bridge *br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) struct ifinfomsg *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) struct nlmsghdr *nlh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) if (port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) br = port->br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) br = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) br_debug(br, "br_fill_info event %d port %s master %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) event, dev->name, br->dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) nlh = nlmsg_put(skb, pid, seq, event, sizeof(*hdr), flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) if (nlh == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) hdr = nlmsg_data(nlh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) hdr->ifi_family = AF_BRIDGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) hdr->__ifi_pad = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) hdr->ifi_type = dev->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) hdr->ifi_index = dev->ifindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) hdr->ifi_flags = dev_get_flags(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) hdr->ifi_change = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) if (nla_put_string(skb, IFLA_IFNAME, dev->name) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) nla_put_u32(skb, IFLA_MASTER, br->dev->ifindex) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) nla_put_u32(skb, IFLA_MTU, dev->mtu) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) nla_put_u8(skb, IFLA_OPERSTATE, operstate) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) (dev->addr_len &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) nla_put(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) (dev->ifindex != dev_get_iflink(dev) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) nla_put_u32(skb, IFLA_LINK, dev_get_iflink(dev))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (event == RTM_NEWLINK && port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) struct nlattr *nest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) nest = nla_nest_start(skb, IFLA_PROTINFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) if (nest == NULL || br_port_fill_attrs(skb, port) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) nla_nest_end(skb, nest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) if (filter_mask & (RTEXT_FILTER_BRVLAN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) RTEXT_FILTER_BRVLAN_COMPRESSED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) RTEXT_FILTER_MRP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) af = nla_nest_start_noflag(skb, IFLA_AF_SPEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) if (!af)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) /* Check if the VID information is requested */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) if ((filter_mask & RTEXT_FILTER_BRVLAN) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) (filter_mask & RTEXT_FILTER_BRVLAN_COMPRESSED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) struct net_bridge_vlan_group *vg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) /* RCU needed because of the VLAN locking rules (rcu || rtnl) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) if (port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) vg = nbp_vlan_group_rcu(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) vg = br_vlan_group_rcu(br);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) if (!vg || !vg->num_vlans) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) if (filter_mask & RTEXT_FILTER_BRVLAN_COMPRESSED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) err = br_fill_ifvlaninfo_compressed(skb, vg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) err = br_fill_ifvlaninfo(skb, vg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) if (port && (port->flags & BR_VLAN_TUNNEL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) err = br_fill_vlan_tunnel_info(skb, vg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) if (filter_mask & RTEXT_FILTER_MRP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) if (!br_mrp_enabled(br) || port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) err = br_mrp_fill_info(skb, br);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) if (af)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) nla_nest_end(skb, af);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) nlmsg_end(skb, nlh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) nlmsg_cancel(skb, nlh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) /* Notify listeners of a change in bridge or port information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) void br_ifinfo_notify(int event, const struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) const struct net_bridge_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) u32 filter = RTEXT_FILTER_BRVLAN_COMPRESSED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) int err = -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) struct net *net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) u16 port_no = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) if (WARN_ON(!port && !br))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) if (port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) dev = port->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) br = port->br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) port_no = port->port_no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) dev = br->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) net = dev_net(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) br_debug(br, "port %u(%s) event %d\n", port_no, dev->name, event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) skb = nlmsg_new(br_nlmsg_size(dev, filter), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) if (skb == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) goto errout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) err = br_fill_ifinfo(skb, port, 0, 0, event, 0, filter, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) /* -EMSGSIZE implies BUG in br_nlmsg_size() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) WARN_ON(err == -EMSGSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) goto errout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) errout:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) rtnl_set_sk_err(net, RTNLGRP_LINK, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) * Dump information about all ports, in response to GETLINK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) int br_getlink(struct sk_buff *skb, u32 pid, u32 seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) struct net_device *dev, u32 filter_mask, int nlflags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) struct net_bridge_port *port = br_port_get_rtnl(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) if (!port && !(filter_mask & RTEXT_FILTER_BRVLAN) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) !(filter_mask & RTEXT_FILTER_BRVLAN_COMPRESSED) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) !(filter_mask & RTEXT_FILTER_MRP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) return br_fill_ifinfo(skb, port, pid, seq, RTM_NEWLINK, nlflags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) filter_mask, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) static int br_vlan_info(struct net_bridge *br, struct net_bridge_port *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) int cmd, struct bridge_vlan_info *vinfo, bool *changed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) struct netlink_ext_ack *extack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) bool curr_change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) case RTM_SETLINK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) if (p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) /* if the MASTER flag is set this will act on the global
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) * per-VLAN entry as well
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) err = nbp_vlan_add(p, vinfo->vid, vinfo->flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) &curr_change, extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) vinfo->flags |= BRIDGE_VLAN_INFO_BRENTRY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) err = br_vlan_add(br, vinfo->vid, vinfo->flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) &curr_change, extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) if (curr_change)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) *changed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) case RTM_DELLINK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) if (p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) if (!nbp_vlan_delete(p, vinfo->vid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) *changed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) if ((vinfo->flags & BRIDGE_VLAN_INFO_MASTER) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) !br_vlan_delete(p->br, vinfo->vid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) *changed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) } else if (!br_vlan_delete(br, vinfo->vid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) *changed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) int br_process_vlan_info(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) struct net_bridge_port *p, int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) struct bridge_vlan_info *vinfo_curr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) struct bridge_vlan_info **vinfo_last,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) bool *changed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) struct netlink_ext_ack *extack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) int err, rtm_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) if (!br_vlan_valid_id(vinfo_curr->vid, extack))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) /* needed for vlan-only NEWVLAN/DELVLAN notifications */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) rtm_cmd = br_afspec_cmd_to_rtm(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) if (vinfo_curr->flags & BRIDGE_VLAN_INFO_RANGE_BEGIN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) if (!br_vlan_valid_range(vinfo_curr, *vinfo_last, extack))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) *vinfo_last = vinfo_curr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) if (*vinfo_last) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) struct bridge_vlan_info tmp_vinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) int v, v_change_start = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) if (!br_vlan_valid_range(vinfo_curr, *vinfo_last, extack))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) memcpy(&tmp_vinfo, *vinfo_last,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) sizeof(struct bridge_vlan_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) for (v = (*vinfo_last)->vid; v <= vinfo_curr->vid; v++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) bool curr_change = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) tmp_vinfo.vid = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) err = br_vlan_info(br, p, cmd, &tmp_vinfo, &curr_change,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) if (curr_change) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) *changed = curr_change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) if (!v_change_start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) v_change_start = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) /* nothing to notify yet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) if (!v_change_start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) br_vlan_notify(br, p, v_change_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) v - 1, rtm_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) v_change_start = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) cond_resched();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) /* v_change_start is set only if the last/whole range changed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) if (v_change_start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) br_vlan_notify(br, p, v_change_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) v - 1, rtm_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) *vinfo_last = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) err = br_vlan_info(br, p, cmd, vinfo_curr, changed, extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) if (*changed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) br_vlan_notify(br, p, vinfo_curr->vid, 0, rtm_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) static int br_afspec(struct net_bridge *br,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) struct net_bridge_port *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) struct nlattr *af_spec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) int cmd, bool *changed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) struct netlink_ext_ack *extack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) struct bridge_vlan_info *vinfo_curr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) struct bridge_vlan_info *vinfo_last = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) struct nlattr *attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) struct vtunnel_info tinfo_last = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) struct vtunnel_info tinfo_curr = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) int err = 0, rem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) nla_for_each_nested(attr, af_spec, rem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) switch (nla_type(attr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) case IFLA_BRIDGE_VLAN_TUNNEL_INFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) if (!p || !(p->flags & BR_VLAN_TUNNEL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) err = br_parse_vlan_tunnel_info(attr, &tinfo_curr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) err = br_process_vlan_tunnel_info(br, p, cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) &tinfo_curr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) &tinfo_last,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) changed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) case IFLA_BRIDGE_VLAN_INFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) if (nla_len(attr) != sizeof(struct bridge_vlan_info))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) vinfo_curr = nla_data(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) err = br_process_vlan_info(br, p, cmd, vinfo_curr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) &vinfo_last, changed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) case IFLA_BRIDGE_MRP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) err = br_mrp_parse(br, p, attr, cmd, extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) static const struct nla_policy br_port_policy[IFLA_BRPORT_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) [IFLA_BRPORT_STATE] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) [IFLA_BRPORT_COST] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) [IFLA_BRPORT_PRIORITY] = { .type = NLA_U16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) [IFLA_BRPORT_MODE] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) [IFLA_BRPORT_GUARD] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) [IFLA_BRPORT_PROTECT] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) [IFLA_BRPORT_FAST_LEAVE]= { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) [IFLA_BRPORT_LEARNING] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) [IFLA_BRPORT_UNICAST_FLOOD] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) [IFLA_BRPORT_PROXYARP] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) [IFLA_BRPORT_PROXYARP_WIFI] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) [IFLA_BRPORT_MULTICAST_ROUTER] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) [IFLA_BRPORT_MCAST_TO_UCAST] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) [IFLA_BRPORT_MCAST_FLOOD] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) [IFLA_BRPORT_BCAST_FLOOD] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) [IFLA_BRPORT_VLAN_TUNNEL] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) [IFLA_BRPORT_GROUP_FWD_MASK] = { .type = NLA_U16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) [IFLA_BRPORT_NEIGH_SUPPRESS] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) [IFLA_BRPORT_ISOLATED] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) [IFLA_BRPORT_BACKUP_PORT] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) /* Change the state of the port and notify spanning tree */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) static int br_set_port_state(struct net_bridge_port *p, u8 state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) if (state > BR_STATE_BLOCKING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) /* if kernel STP is running, don't allow changes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) if (p->br->stp_enabled == BR_KERNEL_STP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) /* if device is not up, change is not allowed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) * if link is not present, only allowable state is disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) if (!netif_running(p->dev) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) (!netif_oper_up(p->dev) && state != BR_STATE_DISABLED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) return -ENETDOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) br_set_state(p, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) br_port_state_selection(p->br);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) /* Set/clear or port flags based on attribute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) static int br_set_port_flag(struct net_bridge_port *p, struct nlattr *tb[],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) int attrtype, unsigned long mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) if (!tb[attrtype])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) if (nla_get_u8(tb[attrtype]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) flags = p->flags | mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) flags = p->flags & ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) err = br_switchdev_set_port_flag(p, flags, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) p->flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) /* Process bridge protocol info on port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) static int br_setport(struct net_bridge_port *p, struct nlattr *tb[])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) unsigned long old_flags = p->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) bool br_vlan_tunnel_old = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) err = br_set_port_flag(p, tb, IFLA_BRPORT_MODE, BR_HAIRPIN_MODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) err = br_set_port_flag(p, tb, IFLA_BRPORT_GUARD, BR_BPDU_GUARD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) err = br_set_port_flag(p, tb, IFLA_BRPORT_FAST_LEAVE, BR_MULTICAST_FAST_LEAVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) err = br_set_port_flag(p, tb, IFLA_BRPORT_PROTECT, BR_ROOT_BLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) err = br_set_port_flag(p, tb, IFLA_BRPORT_LEARNING, BR_LEARNING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) err = br_set_port_flag(p, tb, IFLA_BRPORT_UNICAST_FLOOD, BR_FLOOD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) err = br_set_port_flag(p, tb, IFLA_BRPORT_MCAST_FLOOD, BR_MCAST_FLOOD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) err = br_set_port_flag(p, tb, IFLA_BRPORT_MCAST_TO_UCAST, BR_MULTICAST_TO_UNICAST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) err = br_set_port_flag(p, tb, IFLA_BRPORT_BCAST_FLOOD, BR_BCAST_FLOOD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) err = br_set_port_flag(p, tb, IFLA_BRPORT_PROXYARP, BR_PROXYARP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) err = br_set_port_flag(p, tb, IFLA_BRPORT_PROXYARP_WIFI, BR_PROXYARP_WIFI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) br_vlan_tunnel_old = (p->flags & BR_VLAN_TUNNEL) ? true : false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) err = br_set_port_flag(p, tb, IFLA_BRPORT_VLAN_TUNNEL, BR_VLAN_TUNNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) if (br_vlan_tunnel_old && !(p->flags & BR_VLAN_TUNNEL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) nbp_vlan_tunnel_info_flush(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) if (tb[IFLA_BRPORT_COST]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) err = br_stp_set_path_cost(p, nla_get_u32(tb[IFLA_BRPORT_COST]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) if (tb[IFLA_BRPORT_PRIORITY]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) err = br_stp_set_port_priority(p, nla_get_u16(tb[IFLA_BRPORT_PRIORITY]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) if (tb[IFLA_BRPORT_STATE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) err = br_set_port_state(p, nla_get_u8(tb[IFLA_BRPORT_STATE]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) if (tb[IFLA_BRPORT_FLUSH])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) br_fdb_delete_by_port(p->br, p, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) if (tb[IFLA_BRPORT_MULTICAST_ROUTER]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) u8 mcast_router = nla_get_u8(tb[IFLA_BRPORT_MULTICAST_ROUTER]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) err = br_multicast_set_port_router(p, mcast_router);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) if (tb[IFLA_BRPORT_GROUP_FWD_MASK]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) u16 fwd_mask = nla_get_u16(tb[IFLA_BRPORT_GROUP_FWD_MASK]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) if (fwd_mask & BR_GROUPFWD_MACPAUSE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) p->group_fwd_mask = fwd_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) err = br_set_port_flag(p, tb, IFLA_BRPORT_NEIGH_SUPPRESS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) BR_NEIGH_SUPPRESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) err = br_set_port_flag(p, tb, IFLA_BRPORT_ISOLATED, BR_ISOLATED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) if (tb[IFLA_BRPORT_BACKUP_PORT]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) struct net_device *backup_dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) u32 backup_ifindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) backup_ifindex = nla_get_u32(tb[IFLA_BRPORT_BACKUP_PORT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) if (backup_ifindex) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) backup_dev = __dev_get_by_index(dev_net(p->dev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) backup_ifindex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) if (!backup_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) err = nbp_backup_change(p, backup_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) br_port_flags_change(p, old_flags ^ p->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) /* Change state and parameters on port. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) int br_setlink(struct net_device *dev, struct nlmsghdr *nlh, u16 flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) struct netlink_ext_ack *extack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) struct net_bridge *br = (struct net_bridge *)netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) struct nlattr *tb[IFLA_BRPORT_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) struct net_bridge_port *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) struct nlattr *protinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) struct nlattr *afspec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) bool changed = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) protinfo = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_PROTINFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) afspec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) if (!protinfo && !afspec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) p = br_port_get_rtnl(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) /* We want to accept dev as bridge itself if the AF_SPEC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) * is set to see if someone is setting vlan info on the bridge
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) if (!p && !afspec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) if (p && protinfo) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) if (protinfo->nla_type & NLA_F_NESTED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) err = nla_parse_nested_deprecated(tb, IFLA_BRPORT_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) protinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) br_port_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) spin_lock_bh(&p->br->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) err = br_setport(p, tb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) spin_unlock_bh(&p->br->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) /* Binary compatibility with old RSTP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) if (nla_len(protinfo) < sizeof(u8))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) spin_lock_bh(&p->br->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) err = br_set_port_state(p, nla_get_u8(protinfo));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) spin_unlock_bh(&p->br->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) changed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) if (afspec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) err = br_afspec(br, p, afspec, RTM_SETLINK, &changed, extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) if (changed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) br_ifinfo_notify(RTM_NEWLINK, br, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) /* Delete port information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) int br_dellink(struct net_device *dev, struct nlmsghdr *nlh, u16 flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) struct net_bridge *br = (struct net_bridge *)netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) struct net_bridge_port *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) struct nlattr *afspec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) bool changed = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) afspec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) if (!afspec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) p = br_port_get_rtnl(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) /* We want to accept dev as bridge itself as well */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) if (!p && !(dev->priv_flags & IFF_EBRIDGE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) err = br_afspec(br, p, afspec, RTM_DELLINK, &changed, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) if (changed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) /* Send RTM_NEWLINK because userspace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) * expects RTM_NEWLINK for vlan dels
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) br_ifinfo_notify(RTM_NEWLINK, br, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) static int br_validate(struct nlattr *tb[], struct nlattr *data[],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) struct netlink_ext_ack *extack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) if (tb[IFLA_ADDRESS]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) return -EADDRNOTAVAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) #ifdef CONFIG_BRIDGE_VLAN_FILTERING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) if (data[IFLA_BR_VLAN_PROTOCOL]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) switch (nla_get_be16(data[IFLA_BR_VLAN_PROTOCOL])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) case htons(ETH_P_8021Q):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) case htons(ETH_P_8021AD):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) return -EPROTONOSUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) if (data[IFLA_BR_VLAN_DEFAULT_PVID]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) __u16 defpvid = nla_get_u16(data[IFLA_BR_VLAN_DEFAULT_PVID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) if (defpvid >= VLAN_VID_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) static int br_port_slave_changelink(struct net_device *brdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) struct nlattr *tb[],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) struct nlattr *data[],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) struct netlink_ext_ack *extack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) struct net_bridge *br = netdev_priv(brdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) spin_lock_bh(&br->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) ret = br_setport(br_port_get_rtnl(dev), data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) spin_unlock_bh(&br->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) static int br_port_fill_slave_info(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) const struct net_device *brdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) const struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) return br_port_fill_attrs(skb, br_port_get_rtnl(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) static size_t br_port_get_slave_size(const struct net_device *brdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) const struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) return br_port_info_size();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) static const struct nla_policy br_policy[IFLA_BR_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) [IFLA_BR_FORWARD_DELAY] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) [IFLA_BR_HELLO_TIME] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) [IFLA_BR_MAX_AGE] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) [IFLA_BR_AGEING_TIME] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) [IFLA_BR_STP_STATE] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) [IFLA_BR_PRIORITY] = { .type = NLA_U16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) [IFLA_BR_VLAN_FILTERING] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) [IFLA_BR_VLAN_PROTOCOL] = { .type = NLA_U16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) [IFLA_BR_GROUP_FWD_MASK] = { .type = NLA_U16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) [IFLA_BR_GROUP_ADDR] = { .type = NLA_BINARY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) .len = ETH_ALEN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) [IFLA_BR_MCAST_ROUTER] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) [IFLA_BR_MCAST_SNOOPING] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) [IFLA_BR_MCAST_QUERY_USE_IFADDR] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) [IFLA_BR_MCAST_QUERIER] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) [IFLA_BR_MCAST_HASH_ELASTICITY] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) [IFLA_BR_MCAST_HASH_MAX] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) [IFLA_BR_MCAST_LAST_MEMBER_CNT] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) [IFLA_BR_MCAST_STARTUP_QUERY_CNT] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) [IFLA_BR_MCAST_LAST_MEMBER_INTVL] = { .type = NLA_U64 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) [IFLA_BR_MCAST_MEMBERSHIP_INTVL] = { .type = NLA_U64 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) [IFLA_BR_MCAST_QUERIER_INTVL] = { .type = NLA_U64 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) [IFLA_BR_MCAST_QUERY_INTVL] = { .type = NLA_U64 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) [IFLA_BR_MCAST_QUERY_RESPONSE_INTVL] = { .type = NLA_U64 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) [IFLA_BR_MCAST_STARTUP_QUERY_INTVL] = { .type = NLA_U64 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) [IFLA_BR_NF_CALL_IPTABLES] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) [IFLA_BR_NF_CALL_IP6TABLES] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) [IFLA_BR_NF_CALL_ARPTABLES] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) [IFLA_BR_VLAN_DEFAULT_PVID] = { .type = NLA_U16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) [IFLA_BR_VLAN_STATS_ENABLED] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) [IFLA_BR_MCAST_STATS_ENABLED] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) [IFLA_BR_MCAST_IGMP_VERSION] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) [IFLA_BR_MCAST_MLD_VERSION] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) [IFLA_BR_VLAN_STATS_PER_PORT] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) [IFLA_BR_MULTI_BOOLOPT] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) NLA_POLICY_EXACT_LEN(sizeof(struct br_boolopt_multi)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) static int br_changelink(struct net_device *brdev, struct nlattr *tb[],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) struct nlattr *data[],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) struct netlink_ext_ack *extack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) struct net_bridge *br = netdev_priv(brdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) if (data[IFLA_BR_FORWARD_DELAY]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) err = br_set_forward_delay(br, nla_get_u32(data[IFLA_BR_FORWARD_DELAY]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) if (data[IFLA_BR_HELLO_TIME]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) err = br_set_hello_time(br, nla_get_u32(data[IFLA_BR_HELLO_TIME]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) if (data[IFLA_BR_MAX_AGE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) err = br_set_max_age(br, nla_get_u32(data[IFLA_BR_MAX_AGE]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) if (data[IFLA_BR_AGEING_TIME]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) err = br_set_ageing_time(br, nla_get_u32(data[IFLA_BR_AGEING_TIME]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) if (data[IFLA_BR_STP_STATE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) u32 stp_enabled = nla_get_u32(data[IFLA_BR_STP_STATE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) err = br_stp_set_enabled(br, stp_enabled, extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) if (data[IFLA_BR_PRIORITY]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) u32 priority = nla_get_u16(data[IFLA_BR_PRIORITY]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) br_stp_set_bridge_priority(br, priority);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) if (data[IFLA_BR_VLAN_FILTERING]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) u8 vlan_filter = nla_get_u8(data[IFLA_BR_VLAN_FILTERING]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) err = __br_vlan_filter_toggle(br, vlan_filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) #ifdef CONFIG_BRIDGE_VLAN_FILTERING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) if (data[IFLA_BR_VLAN_PROTOCOL]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) __be16 vlan_proto = nla_get_be16(data[IFLA_BR_VLAN_PROTOCOL]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) err = __br_vlan_set_proto(br, vlan_proto);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) if (data[IFLA_BR_VLAN_DEFAULT_PVID]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) __u16 defpvid = nla_get_u16(data[IFLA_BR_VLAN_DEFAULT_PVID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) err = __br_vlan_set_default_pvid(br, defpvid, extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) if (data[IFLA_BR_VLAN_STATS_ENABLED]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) __u8 vlan_stats = nla_get_u8(data[IFLA_BR_VLAN_STATS_ENABLED]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) err = br_vlan_set_stats(br, vlan_stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) if (data[IFLA_BR_VLAN_STATS_PER_PORT]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) __u8 per_port = nla_get_u8(data[IFLA_BR_VLAN_STATS_PER_PORT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) err = br_vlan_set_stats_per_port(br, per_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) if (data[IFLA_BR_GROUP_FWD_MASK]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) u16 fwd_mask = nla_get_u16(data[IFLA_BR_GROUP_FWD_MASK]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) if (fwd_mask & BR_GROUPFWD_RESTRICTED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) br->group_fwd_mask = fwd_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) if (data[IFLA_BR_GROUP_ADDR]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) u8 new_addr[ETH_ALEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) if (nla_len(data[IFLA_BR_GROUP_ADDR]) != ETH_ALEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) memcpy(new_addr, nla_data(data[IFLA_BR_GROUP_ADDR]), ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) if (!is_link_local_ether_addr(new_addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) if (new_addr[5] == 1 || /* 802.3x Pause address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) new_addr[5] == 2 || /* 802.3ad Slow protocols */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) new_addr[5] == 3) /* 802.1X PAE address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) spin_lock_bh(&br->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) memcpy(br->group_addr, new_addr, sizeof(br->group_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) spin_unlock_bh(&br->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) br_opt_toggle(br, BROPT_GROUP_ADDR_SET, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) br_recalculate_fwd_mask(br);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) if (data[IFLA_BR_FDB_FLUSH])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) br_fdb_flush(br);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) if (data[IFLA_BR_MCAST_ROUTER]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) u8 multicast_router = nla_get_u8(data[IFLA_BR_MCAST_ROUTER]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) err = br_multicast_set_router(br, multicast_router);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) if (data[IFLA_BR_MCAST_SNOOPING]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) u8 mcast_snooping = nla_get_u8(data[IFLA_BR_MCAST_SNOOPING]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) br_multicast_toggle(br, mcast_snooping);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) if (data[IFLA_BR_MCAST_QUERY_USE_IFADDR]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) val = nla_get_u8(data[IFLA_BR_MCAST_QUERY_USE_IFADDR]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) br_opt_toggle(br, BROPT_MULTICAST_QUERY_USE_IFADDR, !!val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) if (data[IFLA_BR_MCAST_QUERIER]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) u8 mcast_querier = nla_get_u8(data[IFLA_BR_MCAST_QUERIER]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) err = br_multicast_set_querier(br, mcast_querier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) if (data[IFLA_BR_MCAST_HASH_ELASTICITY])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) br_warn(br, "the hash_elasticity option has been deprecated and is always %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) RHT_ELASTICITY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) if (data[IFLA_BR_MCAST_HASH_MAX])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) br->hash_max = nla_get_u32(data[IFLA_BR_MCAST_HASH_MAX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) if (data[IFLA_BR_MCAST_LAST_MEMBER_CNT]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) u32 val = nla_get_u32(data[IFLA_BR_MCAST_LAST_MEMBER_CNT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) br->multicast_last_member_count = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) if (data[IFLA_BR_MCAST_STARTUP_QUERY_CNT]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) u32 val = nla_get_u32(data[IFLA_BR_MCAST_STARTUP_QUERY_CNT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) br->multicast_startup_query_count = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) if (data[IFLA_BR_MCAST_LAST_MEMBER_INTVL]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) u64 val = nla_get_u64(data[IFLA_BR_MCAST_LAST_MEMBER_INTVL]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) br->multicast_last_member_interval = clock_t_to_jiffies(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) if (data[IFLA_BR_MCAST_MEMBERSHIP_INTVL]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) u64 val = nla_get_u64(data[IFLA_BR_MCAST_MEMBERSHIP_INTVL]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) br->multicast_membership_interval = clock_t_to_jiffies(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) if (data[IFLA_BR_MCAST_QUERIER_INTVL]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) u64 val = nla_get_u64(data[IFLA_BR_MCAST_QUERIER_INTVL]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) br->multicast_querier_interval = clock_t_to_jiffies(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) if (data[IFLA_BR_MCAST_QUERY_INTVL]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) u64 val = nla_get_u64(data[IFLA_BR_MCAST_QUERY_INTVL]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) br->multicast_query_interval = clock_t_to_jiffies(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) if (data[IFLA_BR_MCAST_QUERY_RESPONSE_INTVL]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) u64 val = nla_get_u64(data[IFLA_BR_MCAST_QUERY_RESPONSE_INTVL]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) br->multicast_query_response_interval = clock_t_to_jiffies(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) if (data[IFLA_BR_MCAST_STARTUP_QUERY_INTVL]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) u64 val = nla_get_u64(data[IFLA_BR_MCAST_STARTUP_QUERY_INTVL]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) br->multicast_startup_query_interval = clock_t_to_jiffies(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) if (data[IFLA_BR_MCAST_STATS_ENABLED]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) __u8 mcast_stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) mcast_stats = nla_get_u8(data[IFLA_BR_MCAST_STATS_ENABLED]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) br_opt_toggle(br, BROPT_MULTICAST_STATS_ENABLED, !!mcast_stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) if (data[IFLA_BR_MCAST_IGMP_VERSION]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) __u8 igmp_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) igmp_version = nla_get_u8(data[IFLA_BR_MCAST_IGMP_VERSION]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) err = br_multicast_set_igmp_version(br, igmp_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) if (data[IFLA_BR_MCAST_MLD_VERSION]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) __u8 mld_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) mld_version = nla_get_u8(data[IFLA_BR_MCAST_MLD_VERSION]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) err = br_multicast_set_mld_version(br, mld_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) if (data[IFLA_BR_NF_CALL_IPTABLES]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) u8 val = nla_get_u8(data[IFLA_BR_NF_CALL_IPTABLES]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) br_opt_toggle(br, BROPT_NF_CALL_IPTABLES, !!val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) if (data[IFLA_BR_NF_CALL_IP6TABLES]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) u8 val = nla_get_u8(data[IFLA_BR_NF_CALL_IP6TABLES]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) br_opt_toggle(br, BROPT_NF_CALL_IP6TABLES, !!val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) if (data[IFLA_BR_NF_CALL_ARPTABLES]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) u8 val = nla_get_u8(data[IFLA_BR_NF_CALL_ARPTABLES]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) br_opt_toggle(br, BROPT_NF_CALL_ARPTABLES, !!val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) if (data[IFLA_BR_MULTI_BOOLOPT]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) struct br_boolopt_multi *bm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) bm = nla_data(data[IFLA_BR_MULTI_BOOLOPT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) err = br_boolopt_multi_toggle(br, bm, extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) static int br_dev_newlink(struct net *src_net, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) struct nlattr *tb[], struct nlattr *data[],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) struct netlink_ext_ack *extack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) struct net_bridge *br = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) err = register_netdevice(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) if (tb[IFLA_ADDRESS]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) spin_lock_bh(&br->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) br_stp_change_bridge_id(br, nla_data(tb[IFLA_ADDRESS]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) spin_unlock_bh(&br->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) err = br_changelink(dev, tb, data, extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) br_dev_delete(dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) static size_t br_get_size(const struct net_device *brdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) return nla_total_size(sizeof(u32)) + /* IFLA_BR_FORWARD_DELAY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) nla_total_size(sizeof(u32)) + /* IFLA_BR_HELLO_TIME */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) nla_total_size(sizeof(u32)) + /* IFLA_BR_MAX_AGE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) nla_total_size(sizeof(u32)) + /* IFLA_BR_AGEING_TIME */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) nla_total_size(sizeof(u32)) + /* IFLA_BR_STP_STATE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) nla_total_size(sizeof(u16)) + /* IFLA_BR_PRIORITY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) nla_total_size(sizeof(u8)) + /* IFLA_BR_VLAN_FILTERING */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) #ifdef CONFIG_BRIDGE_VLAN_FILTERING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) nla_total_size(sizeof(__be16)) + /* IFLA_BR_VLAN_PROTOCOL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) nla_total_size(sizeof(u16)) + /* IFLA_BR_VLAN_DEFAULT_PVID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) nla_total_size(sizeof(u8)) + /* IFLA_BR_VLAN_STATS_ENABLED */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) nla_total_size(sizeof(u8)) + /* IFLA_BR_VLAN_STATS_PER_PORT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) nla_total_size(sizeof(u16)) + /* IFLA_BR_GROUP_FWD_MASK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) nla_total_size(sizeof(struct ifla_bridge_id)) + /* IFLA_BR_ROOT_ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) nla_total_size(sizeof(struct ifla_bridge_id)) + /* IFLA_BR_BRIDGE_ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) nla_total_size(sizeof(u16)) + /* IFLA_BR_ROOT_PORT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) nla_total_size(sizeof(u32)) + /* IFLA_BR_ROOT_PATH_COST */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) nla_total_size(sizeof(u8)) + /* IFLA_BR_TOPOLOGY_CHANGE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) nla_total_size(sizeof(u8)) + /* IFLA_BR_TOPOLOGY_CHANGE_DETECTED */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) nla_total_size_64bit(sizeof(u64)) + /* IFLA_BR_HELLO_TIMER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) nla_total_size_64bit(sizeof(u64)) + /* IFLA_BR_TCN_TIMER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) nla_total_size_64bit(sizeof(u64)) + /* IFLA_BR_TOPOLOGY_CHANGE_TIMER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) nla_total_size_64bit(sizeof(u64)) + /* IFLA_BR_GC_TIMER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) nla_total_size(ETH_ALEN) + /* IFLA_BR_GROUP_ADDR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) nla_total_size(sizeof(u8)) + /* IFLA_BR_MCAST_ROUTER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) nla_total_size(sizeof(u8)) + /* IFLA_BR_MCAST_SNOOPING */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) nla_total_size(sizeof(u8)) + /* IFLA_BR_MCAST_QUERY_USE_IFADDR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) nla_total_size(sizeof(u8)) + /* IFLA_BR_MCAST_QUERIER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) nla_total_size(sizeof(u8)) + /* IFLA_BR_MCAST_STATS_ENABLED */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) nla_total_size(sizeof(u32)) + /* IFLA_BR_MCAST_HASH_ELASTICITY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) nla_total_size(sizeof(u32)) + /* IFLA_BR_MCAST_HASH_MAX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) nla_total_size(sizeof(u32)) + /* IFLA_BR_MCAST_LAST_MEMBER_CNT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) nla_total_size(sizeof(u32)) + /* IFLA_BR_MCAST_STARTUP_QUERY_CNT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) nla_total_size_64bit(sizeof(u64)) + /* IFLA_BR_MCAST_LAST_MEMBER_INTVL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) nla_total_size_64bit(sizeof(u64)) + /* IFLA_BR_MCAST_MEMBERSHIP_INTVL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) nla_total_size_64bit(sizeof(u64)) + /* IFLA_BR_MCAST_QUERIER_INTVL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) nla_total_size_64bit(sizeof(u64)) + /* IFLA_BR_MCAST_QUERY_INTVL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) nla_total_size_64bit(sizeof(u64)) + /* IFLA_BR_MCAST_QUERY_RESPONSE_INTVL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) nla_total_size_64bit(sizeof(u64)) + /* IFLA_BR_MCAST_STARTUP_QUERY_INTVL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) nla_total_size(sizeof(u8)) + /* IFLA_BR_MCAST_IGMP_VERSION */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) nla_total_size(sizeof(u8)) + /* IFLA_BR_MCAST_MLD_VERSION */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) nla_total_size(sizeof(u8)) + /* IFLA_BR_NF_CALL_IPTABLES */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) nla_total_size(sizeof(u8)) + /* IFLA_BR_NF_CALL_IP6TABLES */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) nla_total_size(sizeof(u8)) + /* IFLA_BR_NF_CALL_ARPTABLES */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) nla_total_size(sizeof(struct br_boolopt_multi)) + /* IFLA_BR_MULTI_BOOLOPT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) static int br_fill_info(struct sk_buff *skb, const struct net_device *brdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) struct net_bridge *br = netdev_priv(brdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) u32 forward_delay = jiffies_to_clock_t(br->forward_delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) u32 hello_time = jiffies_to_clock_t(br->hello_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) u32 age_time = jiffies_to_clock_t(br->max_age);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) u32 ageing_time = jiffies_to_clock_t(br->ageing_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) u32 stp_enabled = br->stp_enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) u16 priority = (br->bridge_id.prio[0] << 8) | br->bridge_id.prio[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) u8 vlan_enabled = br_vlan_enabled(br->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) struct br_boolopt_multi bm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) u64 clockval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) clockval = br_timer_value(&br->hello_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) if (nla_put_u64_64bit(skb, IFLA_BR_HELLO_TIMER, clockval, IFLA_BR_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) clockval = br_timer_value(&br->tcn_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) if (nla_put_u64_64bit(skb, IFLA_BR_TCN_TIMER, clockval, IFLA_BR_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) clockval = br_timer_value(&br->topology_change_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) if (nla_put_u64_64bit(skb, IFLA_BR_TOPOLOGY_CHANGE_TIMER, clockval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) IFLA_BR_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) clockval = br_timer_value(&br->gc_work.timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) if (nla_put_u64_64bit(skb, IFLA_BR_GC_TIMER, clockval, IFLA_BR_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) br_boolopt_multi_get(br, &bm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) if (nla_put_u32(skb, IFLA_BR_FORWARD_DELAY, forward_delay) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) nla_put_u32(skb, IFLA_BR_HELLO_TIME, hello_time) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) nla_put_u32(skb, IFLA_BR_MAX_AGE, age_time) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) nla_put_u32(skb, IFLA_BR_AGEING_TIME, ageing_time) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) nla_put_u32(skb, IFLA_BR_STP_STATE, stp_enabled) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) nla_put_u16(skb, IFLA_BR_PRIORITY, priority) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) nla_put_u8(skb, IFLA_BR_VLAN_FILTERING, vlan_enabled) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) nla_put_u16(skb, IFLA_BR_GROUP_FWD_MASK, br->group_fwd_mask) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) nla_put(skb, IFLA_BR_BRIDGE_ID, sizeof(struct ifla_bridge_id),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) &br->bridge_id) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) nla_put(skb, IFLA_BR_ROOT_ID, sizeof(struct ifla_bridge_id),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) &br->designated_root) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) nla_put_u16(skb, IFLA_BR_ROOT_PORT, br->root_port) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) nla_put_u32(skb, IFLA_BR_ROOT_PATH_COST, br->root_path_cost) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) nla_put_u8(skb, IFLA_BR_TOPOLOGY_CHANGE, br->topology_change) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) nla_put_u8(skb, IFLA_BR_TOPOLOGY_CHANGE_DETECTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) br->topology_change_detected) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) nla_put(skb, IFLA_BR_GROUP_ADDR, ETH_ALEN, br->group_addr) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) nla_put(skb, IFLA_BR_MULTI_BOOLOPT, sizeof(bm), &bm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) #ifdef CONFIG_BRIDGE_VLAN_FILTERING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) if (nla_put_be16(skb, IFLA_BR_VLAN_PROTOCOL, br->vlan_proto) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) nla_put_u16(skb, IFLA_BR_VLAN_DEFAULT_PVID, br->default_pvid) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) nla_put_u8(skb, IFLA_BR_VLAN_STATS_ENABLED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) br_opt_get(br, BROPT_VLAN_STATS_ENABLED)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) nla_put_u8(skb, IFLA_BR_VLAN_STATS_PER_PORT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) br_opt_get(br, BROPT_VLAN_STATS_PER_PORT)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) if (nla_put_u8(skb, IFLA_BR_MCAST_ROUTER, br->multicast_router) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) nla_put_u8(skb, IFLA_BR_MCAST_SNOOPING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) br_opt_get(br, BROPT_MULTICAST_ENABLED)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) nla_put_u8(skb, IFLA_BR_MCAST_QUERY_USE_IFADDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) br_opt_get(br, BROPT_MULTICAST_QUERY_USE_IFADDR)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) nla_put_u8(skb, IFLA_BR_MCAST_QUERIER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) br_opt_get(br, BROPT_MULTICAST_QUERIER)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) nla_put_u8(skb, IFLA_BR_MCAST_STATS_ENABLED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) br_opt_get(br, BROPT_MULTICAST_STATS_ENABLED)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) nla_put_u32(skb, IFLA_BR_MCAST_HASH_ELASTICITY, RHT_ELASTICITY) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) nla_put_u32(skb, IFLA_BR_MCAST_HASH_MAX, br->hash_max) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) nla_put_u32(skb, IFLA_BR_MCAST_LAST_MEMBER_CNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) br->multicast_last_member_count) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) nla_put_u32(skb, IFLA_BR_MCAST_STARTUP_QUERY_CNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) br->multicast_startup_query_count) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) nla_put_u8(skb, IFLA_BR_MCAST_IGMP_VERSION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) br->multicast_igmp_version))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) if (nla_put_u8(skb, IFLA_BR_MCAST_MLD_VERSION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) br->multicast_mld_version))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) clockval = jiffies_to_clock_t(br->multicast_last_member_interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) if (nla_put_u64_64bit(skb, IFLA_BR_MCAST_LAST_MEMBER_INTVL, clockval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) IFLA_BR_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) clockval = jiffies_to_clock_t(br->multicast_membership_interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) if (nla_put_u64_64bit(skb, IFLA_BR_MCAST_MEMBERSHIP_INTVL, clockval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) IFLA_BR_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) clockval = jiffies_to_clock_t(br->multicast_querier_interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) if (nla_put_u64_64bit(skb, IFLA_BR_MCAST_QUERIER_INTVL, clockval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) IFLA_BR_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) clockval = jiffies_to_clock_t(br->multicast_query_interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) if (nla_put_u64_64bit(skb, IFLA_BR_MCAST_QUERY_INTVL, clockval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) IFLA_BR_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) clockval = jiffies_to_clock_t(br->multicast_query_response_interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) if (nla_put_u64_64bit(skb, IFLA_BR_MCAST_QUERY_RESPONSE_INTVL, clockval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) IFLA_BR_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) clockval = jiffies_to_clock_t(br->multicast_startup_query_interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) if (nla_put_u64_64bit(skb, IFLA_BR_MCAST_STARTUP_QUERY_INTVL, clockval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) IFLA_BR_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) if (nla_put_u8(skb, IFLA_BR_NF_CALL_IPTABLES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) br_opt_get(br, BROPT_NF_CALL_IPTABLES) ? 1 : 0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) nla_put_u8(skb, IFLA_BR_NF_CALL_IP6TABLES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) br_opt_get(br, BROPT_NF_CALL_IP6TABLES) ? 1 : 0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) nla_put_u8(skb, IFLA_BR_NF_CALL_ARPTABLES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) br_opt_get(br, BROPT_NF_CALL_ARPTABLES) ? 1 : 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) static size_t br_get_linkxstats_size(const struct net_device *dev, int attr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) struct net_bridge_port *p = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) struct net_bridge_vlan_group *vg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) struct net_bridge_vlan *v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) struct net_bridge *br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) int numvls = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) switch (attr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) case IFLA_STATS_LINK_XSTATS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) br = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) vg = br_vlan_group(br);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) case IFLA_STATS_LINK_XSTATS_SLAVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) p = br_port_get_rtnl(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) br = p->br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) vg = nbp_vlan_group(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) if (vg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) /* we need to count all, even placeholder entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) list_for_each_entry(v, &vg->vlan_list, vlist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) numvls++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) return numvls * nla_total_size(sizeof(struct bridge_vlan_xstats)) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) nla_total_size_64bit(sizeof(struct br_mcast_stats)) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) (p ? nla_total_size_64bit(sizeof(p->stp_xstats)) : 0) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) nla_total_size(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) static int br_fill_linkxstats(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) const struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) int *prividx, int attr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) struct nlattr *nla __maybe_unused;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) struct net_bridge_port *p = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) struct net_bridge_vlan_group *vg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) struct net_bridge_vlan *v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) struct net_bridge *br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) struct nlattr *nest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) int vl_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) switch (attr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) case IFLA_STATS_LINK_XSTATS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) br = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) vg = br_vlan_group(br);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) case IFLA_STATS_LINK_XSTATS_SLAVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) p = br_port_get_rtnl(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) br = p->br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) vg = nbp_vlan_group(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) nest = nla_nest_start_noflag(skb, LINK_XSTATS_TYPE_BRIDGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) if (!nest)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) if (vg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) u16 pvid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) pvid = br_get_pvid(vg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) list_for_each_entry(v, &vg->vlan_list, vlist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) struct bridge_vlan_xstats vxi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) struct br_vlan_stats stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) if (++vl_idx < *prividx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) memset(&vxi, 0, sizeof(vxi));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) vxi.vid = v->vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) vxi.flags = v->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) if (v->vid == pvid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) vxi.flags |= BRIDGE_VLAN_INFO_PVID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) br_vlan_get_stats(v, &stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) vxi.rx_bytes = stats.rx_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) vxi.rx_packets = stats.rx_packets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) vxi.tx_bytes = stats.tx_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) vxi.tx_packets = stats.tx_packets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) if (nla_put(skb, BRIDGE_XSTATS_VLAN, sizeof(vxi), &vxi))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) if (++vl_idx >= *prividx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) nla = nla_reserve_64bit(skb, BRIDGE_XSTATS_MCAST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) sizeof(struct br_mcast_stats),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) BRIDGE_XSTATS_PAD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) if (!nla)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) br_multicast_get_stats(br, p, nla_data(nla));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) if (p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) nla = nla_reserve_64bit(skb, BRIDGE_XSTATS_STP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) sizeof(p->stp_xstats),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) BRIDGE_XSTATS_PAD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) if (!nla)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) spin_lock_bh(&br->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) memcpy(nla_data(nla), &p->stp_xstats, sizeof(p->stp_xstats));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) spin_unlock_bh(&br->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) nla_nest_end(skb, nest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) *prividx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) nla_nest_end(skb, nest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) *prividx = vl_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) static struct rtnl_af_ops br_af_ops __read_mostly = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) .family = AF_BRIDGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) .get_link_af_size = br_get_link_af_size_filtered,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) struct rtnl_link_ops br_link_ops __read_mostly = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) .kind = "bridge",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) .priv_size = sizeof(struct net_bridge),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) .setup = br_dev_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) .maxtype = IFLA_BR_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) .policy = br_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) .validate = br_validate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) .newlink = br_dev_newlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) .changelink = br_changelink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) .dellink = br_dev_delete,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) .get_size = br_get_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) .fill_info = br_fill_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) .fill_linkxstats = br_fill_linkxstats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) .get_linkxstats_size = br_get_linkxstats_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) .slave_maxtype = IFLA_BRPORT_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) .slave_policy = br_port_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) .slave_changelink = br_port_slave_changelink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) .get_slave_size = br_port_get_slave_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) .fill_slave_info = br_port_fill_slave_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) int __init br_netlink_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) br_mdb_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) br_vlan_rtnl_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) rtnl_af_register(&br_af_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) err = rtnl_link_register(&br_link_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) goto out_af;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) out_af:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) rtnl_af_unregister(&br_af_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) br_mdb_uninit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) void br_netlink_fini(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) br_mdb_uninit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) br_vlan_rtnl_uninit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) rtnl_af_unregister(&br_af_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) rtnl_link_unregister(&br_link_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) }