^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) * Sysfs attributes of bridge
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Linux ethernet bridge
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Authors:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Stephen Hemminger <shemminger@osdl.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/capability.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/etherdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/if_bridge.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/rtnetlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/times.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/sched/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "br_private.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define to_bridge(cd) ((struct net_bridge *)netdev_priv(to_net_dev(cd)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * Common code for storing bridge parameters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) static ssize_t store_bridge_parm(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) const char *buf, size_t len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) int (*set)(struct net_bridge *, unsigned long))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) struct net_bridge *br = to_bridge(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) char *endp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) if (!ns_capable(dev_net(br->dev)->user_ns, CAP_NET_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) val = simple_strtoul(buf, &endp, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) if (endp == buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) if (!rtnl_trylock())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) return restart_syscall();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) err = (*set)(br, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) netdev_state_change(br->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) return err ? err : len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) static ssize_t forward_delay_show(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) struct net_bridge *br = to_bridge(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) return sprintf(buf, "%lu\n", jiffies_to_clock_t(br->forward_delay));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) static ssize_t forward_delay_store(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) const char *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) return store_bridge_parm(d, buf, len, br_set_forward_delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) static DEVICE_ATTR_RW(forward_delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) static ssize_t hello_time_show(struct device *d, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) return sprintf(buf, "%lu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) jiffies_to_clock_t(to_bridge(d)->hello_time));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) static ssize_t hello_time_store(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) struct device_attribute *attr, const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) return store_bridge_parm(d, buf, len, br_set_hello_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) static DEVICE_ATTR_RW(hello_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) static ssize_t max_age_show(struct device *d, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) return sprintf(buf, "%lu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) jiffies_to_clock_t(to_bridge(d)->max_age));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) static ssize_t max_age_store(struct device *d, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) const char *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) return store_bridge_parm(d, buf, len, br_set_max_age);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) static DEVICE_ATTR_RW(max_age);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) static ssize_t ageing_time_show(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct net_bridge *br = to_bridge(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) return sprintf(buf, "%lu\n", jiffies_to_clock_t(br->ageing_time));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) static int set_ageing_time(struct net_bridge *br, unsigned long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) return br_set_ageing_time(br, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) static ssize_t ageing_time_store(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) const char *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) return store_bridge_parm(d, buf, len, set_ageing_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) static DEVICE_ATTR_RW(ageing_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) static ssize_t stp_state_show(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct net_bridge *br = to_bridge(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) return sprintf(buf, "%d\n", br->stp_enabled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) static int set_stp_state(struct net_bridge *br, unsigned long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) return br_stp_set_enabled(br, val, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) static ssize_t stp_state_store(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) struct device_attribute *attr, const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) return store_bridge_parm(d, buf, len, set_stp_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) static DEVICE_ATTR_RW(stp_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) static ssize_t group_fwd_mask_show(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) struct net_bridge *br = to_bridge(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return sprintf(buf, "%#x\n", br->group_fwd_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) static int set_group_fwd_mask(struct net_bridge *br, unsigned long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (val & BR_GROUPFWD_RESTRICTED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) br->group_fwd_mask = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) static ssize_t group_fwd_mask_store(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) return store_bridge_parm(d, buf, len, set_group_fwd_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) static DEVICE_ATTR_RW(group_fwd_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) static ssize_t priority_show(struct device *d, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) struct net_bridge *br = to_bridge(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) return sprintf(buf, "%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) (br->bridge_id.prio[0] << 8) | br->bridge_id.prio[1]);
^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 set_priority(struct net_bridge *br, unsigned long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) br_stp_set_bridge_priority(br, (u16) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) static ssize_t priority_store(struct device *d, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) const char *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) return store_bridge_parm(d, buf, len, set_priority);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) static DEVICE_ATTR_RW(priority);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) static ssize_t root_id_show(struct device *d, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) return br_show_bridge_id(buf, &to_bridge(d)->designated_root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) static DEVICE_ATTR_RO(root_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) static ssize_t bridge_id_show(struct device *d, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) return br_show_bridge_id(buf, &to_bridge(d)->bridge_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) static DEVICE_ATTR_RO(bridge_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) static ssize_t root_port_show(struct device *d, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) return sprintf(buf, "%d\n", to_bridge(d)->root_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) static DEVICE_ATTR_RO(root_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) static ssize_t root_path_cost_show(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) return sprintf(buf, "%d\n", to_bridge(d)->root_path_cost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) static DEVICE_ATTR_RO(root_path_cost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) static ssize_t topology_change_show(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) return sprintf(buf, "%d\n", to_bridge(d)->topology_change);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) static DEVICE_ATTR_RO(topology_change);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) static ssize_t topology_change_detected_show(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) struct net_bridge *br = to_bridge(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) return sprintf(buf, "%d\n", br->topology_change_detected);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) static DEVICE_ATTR_RO(topology_change_detected);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) static ssize_t hello_timer_show(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) struct net_bridge *br = to_bridge(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) return sprintf(buf, "%ld\n", br_timer_value(&br->hello_timer));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) static DEVICE_ATTR_RO(hello_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) static ssize_t tcn_timer_show(struct device *d, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) struct net_bridge *br = to_bridge(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) return sprintf(buf, "%ld\n", br_timer_value(&br->tcn_timer));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) static DEVICE_ATTR_RO(tcn_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) static ssize_t topology_change_timer_show(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) struct net_bridge *br = to_bridge(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) return sprintf(buf, "%ld\n", br_timer_value(&br->topology_change_timer));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) static DEVICE_ATTR_RO(topology_change_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) static ssize_t gc_timer_show(struct device *d, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) struct net_bridge *br = to_bridge(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) return sprintf(buf, "%ld\n", br_timer_value(&br->gc_work.timer));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) static DEVICE_ATTR_RO(gc_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) static ssize_t group_addr_show(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) struct net_bridge *br = to_bridge(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) return sprintf(buf, "%pM\n", br->group_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) static ssize_t group_addr_store(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) const char *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) struct net_bridge *br = to_bridge(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) u8 new_addr[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) if (!ns_capable(dev_net(br->dev)->user_ns, CAP_NET_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) if (!mac_pton(buf, new_addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) if (!is_link_local_ether_addr(new_addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (new_addr[5] == 1 || /* 802.3x Pause address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) new_addr[5] == 2 || /* 802.3ad Slow protocols */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) new_addr[5] == 3) /* 802.1X PAE address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) if (!rtnl_trylock())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) return restart_syscall();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) spin_lock_bh(&br->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) ether_addr_copy(br->group_addr, new_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) spin_unlock_bh(&br->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) br_opt_toggle(br, BROPT_GROUP_ADDR_SET, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) br_recalculate_fwd_mask(br);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) netdev_state_change(br->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) static DEVICE_ATTR_RW(group_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) static int set_flush(struct net_bridge *br, unsigned long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) br_fdb_flush(br);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) static ssize_t flush_store(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) const char *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) return store_bridge_parm(d, buf, len, set_flush);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) static DEVICE_ATTR_WO(flush);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) static ssize_t no_linklocal_learn_show(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) struct net_bridge *br = to_bridge(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) return sprintf(buf, "%d\n", br_boolopt_get(br, BR_BOOLOPT_NO_LL_LEARN));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) static int set_no_linklocal_learn(struct net_bridge *br, unsigned long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) return br_boolopt_toggle(br, BR_BOOLOPT_NO_LL_LEARN, !!val, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) static ssize_t no_linklocal_learn_store(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) const char *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) return store_bridge_parm(d, buf, len, set_no_linklocal_learn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) static DEVICE_ATTR_RW(no_linklocal_learn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) static ssize_t multicast_router_show(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) struct net_bridge *br = to_bridge(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) return sprintf(buf, "%d\n", br->multicast_router);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) static ssize_t multicast_router_store(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) const char *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) return store_bridge_parm(d, buf, len, br_multicast_set_router);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) static DEVICE_ATTR_RW(multicast_router);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) static ssize_t multicast_snooping_show(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) struct net_bridge *br = to_bridge(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) return sprintf(buf, "%d\n", br_opt_get(br, BROPT_MULTICAST_ENABLED));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) static ssize_t multicast_snooping_store(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) const char *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) return store_bridge_parm(d, buf, len, br_multicast_toggle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) static DEVICE_ATTR_RW(multicast_snooping);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) static ssize_t multicast_query_use_ifaddr_show(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) struct net_bridge *br = to_bridge(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) return sprintf(buf, "%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) br_opt_get(br, BROPT_MULTICAST_QUERY_USE_IFADDR));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) static int set_query_use_ifaddr(struct net_bridge *br, unsigned long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) br_opt_toggle(br, BROPT_MULTICAST_QUERY_USE_IFADDR, !!val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) multicast_query_use_ifaddr_store(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) const char *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) return store_bridge_parm(d, buf, len, set_query_use_ifaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) static DEVICE_ATTR_RW(multicast_query_use_ifaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) static ssize_t multicast_querier_show(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) struct net_bridge *br = to_bridge(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) return sprintf(buf, "%d\n", br_opt_get(br, BROPT_MULTICAST_QUERIER));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) static ssize_t multicast_querier_store(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) const char *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) return store_bridge_parm(d, buf, len, br_multicast_set_querier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) static DEVICE_ATTR_RW(multicast_querier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) static ssize_t hash_elasticity_show(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) return sprintf(buf, "%u\n", RHT_ELASTICITY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) static int set_elasticity(struct net_bridge *br, unsigned long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) br_warn(br, "the hash_elasticity option has been deprecated and is always %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) RHT_ELASTICITY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) static ssize_t hash_elasticity_store(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) const char *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) return store_bridge_parm(d, buf, len, set_elasticity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) static DEVICE_ATTR_RW(hash_elasticity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) static ssize_t hash_max_show(struct device *d, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) struct net_bridge *br = to_bridge(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) return sprintf(buf, "%u\n", br->hash_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) static int set_hash_max(struct net_bridge *br, unsigned long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) br->hash_max = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) static ssize_t hash_max_store(struct device *d, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) const char *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) return store_bridge_parm(d, buf, len, set_hash_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) static DEVICE_ATTR_RW(hash_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) static ssize_t multicast_igmp_version_show(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) struct net_bridge *br = to_bridge(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) return sprintf(buf, "%u\n", br->multicast_igmp_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) static ssize_t multicast_igmp_version_store(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) const char *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) return store_bridge_parm(d, buf, len, br_multicast_set_igmp_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) static DEVICE_ATTR_RW(multicast_igmp_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) static ssize_t multicast_last_member_count_show(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) struct net_bridge *br = to_bridge(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) return sprintf(buf, "%u\n", br->multicast_last_member_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) static int set_last_member_count(struct net_bridge *br, unsigned long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) br->multicast_last_member_count = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) return 0;
^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) static ssize_t multicast_last_member_count_store(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) const char *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) return store_bridge_parm(d, buf, len, set_last_member_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) static DEVICE_ATTR_RW(multicast_last_member_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) static ssize_t multicast_startup_query_count_show(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) struct device *d, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) struct net_bridge *br = to_bridge(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) return sprintf(buf, "%u\n", br->multicast_startup_query_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) static int set_startup_query_count(struct net_bridge *br, unsigned long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) br->multicast_startup_query_count = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) static ssize_t multicast_startup_query_count_store(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) struct device *d, struct device_attribute *attr, const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) return store_bridge_parm(d, buf, len, set_startup_query_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) static DEVICE_ATTR_RW(multicast_startup_query_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) static ssize_t multicast_last_member_interval_show(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) struct device *d, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) struct net_bridge *br = to_bridge(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) return sprintf(buf, "%lu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) jiffies_to_clock_t(br->multicast_last_member_interval));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) static int set_last_member_interval(struct net_bridge *br, unsigned long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) br->multicast_last_member_interval = clock_t_to_jiffies(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) return 0;
^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) static ssize_t multicast_last_member_interval_store(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) struct device *d, struct device_attribute *attr, const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) return store_bridge_parm(d, buf, len, set_last_member_interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) static DEVICE_ATTR_RW(multicast_last_member_interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) static ssize_t multicast_membership_interval_show(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) struct device *d, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) struct net_bridge *br = to_bridge(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) return sprintf(buf, "%lu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) jiffies_to_clock_t(br->multicast_membership_interval));
^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 set_membership_interval(struct net_bridge *br, unsigned long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) br->multicast_membership_interval = clock_t_to_jiffies(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) static ssize_t multicast_membership_interval_store(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) struct device *d, struct device_attribute *attr, const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) return store_bridge_parm(d, buf, len, set_membership_interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) static DEVICE_ATTR_RW(multicast_membership_interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) static ssize_t multicast_querier_interval_show(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) struct net_bridge *br = to_bridge(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) return sprintf(buf, "%lu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) jiffies_to_clock_t(br->multicast_querier_interval));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) static int set_querier_interval(struct net_bridge *br, unsigned long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) br->multicast_querier_interval = clock_t_to_jiffies(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) static ssize_t multicast_querier_interval_store(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) const char *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) return store_bridge_parm(d, buf, len, set_querier_interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) static DEVICE_ATTR_RW(multicast_querier_interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) static ssize_t multicast_query_interval_show(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) struct net_bridge *br = to_bridge(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) return sprintf(buf, "%lu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) jiffies_to_clock_t(br->multicast_query_interval));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) static int set_query_interval(struct net_bridge *br, unsigned long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) br->multicast_query_interval = clock_t_to_jiffies(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) static ssize_t multicast_query_interval_store(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) const char *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) return store_bridge_parm(d, buf, len, set_query_interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) static DEVICE_ATTR_RW(multicast_query_interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) static ssize_t multicast_query_response_interval_show(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) struct device *d, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) struct net_bridge *br = to_bridge(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) return sprintf(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) buf, "%lu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) jiffies_to_clock_t(br->multicast_query_response_interval));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) static int set_query_response_interval(struct net_bridge *br, unsigned long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) br->multicast_query_response_interval = clock_t_to_jiffies(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) static ssize_t multicast_query_response_interval_store(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) struct device *d, struct device_attribute *attr, const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) return store_bridge_parm(d, buf, len, set_query_response_interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) static DEVICE_ATTR_RW(multicast_query_response_interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) static ssize_t multicast_startup_query_interval_show(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) struct device *d, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) struct net_bridge *br = to_bridge(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) return sprintf(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) buf, "%lu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) jiffies_to_clock_t(br->multicast_startup_query_interval));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) static int set_startup_query_interval(struct net_bridge *br, unsigned long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) br->multicast_startup_query_interval = clock_t_to_jiffies(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) static ssize_t multicast_startup_query_interval_store(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) struct device *d, struct device_attribute *attr, const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) return store_bridge_parm(d, buf, len, set_startup_query_interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) static DEVICE_ATTR_RW(multicast_startup_query_interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) static ssize_t multicast_stats_enabled_show(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) struct net_bridge *br = to_bridge(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) return sprintf(buf, "%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) br_opt_get(br, BROPT_MULTICAST_STATS_ENABLED));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) static int set_stats_enabled(struct net_bridge *br, unsigned long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) br_opt_toggle(br, BROPT_MULTICAST_STATS_ENABLED, !!val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) static ssize_t multicast_stats_enabled_store(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) return store_bridge_parm(d, buf, len, set_stats_enabled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) static DEVICE_ATTR_RW(multicast_stats_enabled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) static ssize_t multicast_mld_version_show(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) struct net_bridge *br = to_bridge(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) return sprintf(buf, "%u\n", br->multicast_mld_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) static ssize_t multicast_mld_version_store(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) const char *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) return store_bridge_parm(d, buf, len, br_multicast_set_mld_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) static DEVICE_ATTR_RW(multicast_mld_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) static ssize_t nf_call_iptables_show(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) struct device *d, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) struct net_bridge *br = to_bridge(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) return sprintf(buf, "%u\n", br_opt_get(br, BROPT_NF_CALL_IPTABLES));
^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) static int set_nf_call_iptables(struct net_bridge *br, unsigned long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) br_opt_toggle(br, BROPT_NF_CALL_IPTABLES, !!val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) static ssize_t nf_call_iptables_store(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) struct device *d, struct device_attribute *attr, const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) return store_bridge_parm(d, buf, len, set_nf_call_iptables);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) static DEVICE_ATTR_RW(nf_call_iptables);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) static ssize_t nf_call_ip6tables_show(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) struct device *d, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) struct net_bridge *br = to_bridge(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) return sprintf(buf, "%u\n", br_opt_get(br, BROPT_NF_CALL_IP6TABLES));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) static int set_nf_call_ip6tables(struct net_bridge *br, unsigned long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) br_opt_toggle(br, BROPT_NF_CALL_IP6TABLES, !!val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) static ssize_t nf_call_ip6tables_store(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) struct device *d, struct device_attribute *attr, const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) return store_bridge_parm(d, buf, len, set_nf_call_ip6tables);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) static DEVICE_ATTR_RW(nf_call_ip6tables);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) static ssize_t nf_call_arptables_show(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) struct device *d, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) struct net_bridge *br = to_bridge(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) return sprintf(buf, "%u\n", br_opt_get(br, BROPT_NF_CALL_ARPTABLES));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) static int set_nf_call_arptables(struct net_bridge *br, unsigned long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) br_opt_toggle(br, BROPT_NF_CALL_ARPTABLES, !!val);
^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) static ssize_t nf_call_arptables_store(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) struct device *d, struct device_attribute *attr, const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) return store_bridge_parm(d, buf, len, set_nf_call_arptables);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) static DEVICE_ATTR_RW(nf_call_arptables);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) #ifdef CONFIG_BRIDGE_VLAN_FILTERING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) static ssize_t vlan_filtering_show(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) struct net_bridge *br = to_bridge(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) return sprintf(buf, "%d\n", br_opt_get(br, BROPT_VLAN_ENABLED));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) static ssize_t vlan_filtering_store(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) const char *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) return store_bridge_parm(d, buf, len, br_vlan_filter_toggle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) static DEVICE_ATTR_RW(vlan_filtering);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) static ssize_t vlan_protocol_show(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) struct net_bridge *br = to_bridge(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) return sprintf(buf, "%#06x\n", ntohs(br->vlan_proto));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) static ssize_t vlan_protocol_store(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) const char *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) return store_bridge_parm(d, buf, len, br_vlan_set_proto);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) static DEVICE_ATTR_RW(vlan_protocol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) static ssize_t default_pvid_show(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) struct net_bridge *br = to_bridge(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) return sprintf(buf, "%d\n", br->default_pvid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) static ssize_t default_pvid_store(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) const char *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) return store_bridge_parm(d, buf, len, br_vlan_set_default_pvid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) static DEVICE_ATTR_RW(default_pvid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) static ssize_t vlan_stats_enabled_show(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) struct net_bridge *br = to_bridge(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) return sprintf(buf, "%u\n", br_opt_get(br, BROPT_VLAN_STATS_ENABLED));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) static ssize_t vlan_stats_enabled_store(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) const char *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) return store_bridge_parm(d, buf, len, br_vlan_set_stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) static DEVICE_ATTR_RW(vlan_stats_enabled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) static ssize_t vlan_stats_per_port_show(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) struct net_bridge *br = to_bridge(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) return sprintf(buf, "%u\n", br_opt_get(br, BROPT_VLAN_STATS_PER_PORT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) static ssize_t vlan_stats_per_port_store(struct device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) const char *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) return store_bridge_parm(d, buf, len, br_vlan_set_stats_per_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) static DEVICE_ATTR_RW(vlan_stats_per_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) static struct attribute *bridge_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) &dev_attr_forward_delay.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) &dev_attr_hello_time.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) &dev_attr_max_age.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) &dev_attr_ageing_time.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) &dev_attr_stp_state.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) &dev_attr_group_fwd_mask.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) &dev_attr_priority.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) &dev_attr_bridge_id.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) &dev_attr_root_id.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) &dev_attr_root_path_cost.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) &dev_attr_root_port.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) &dev_attr_topology_change.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) &dev_attr_topology_change_detected.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) &dev_attr_hello_timer.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) &dev_attr_tcn_timer.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) &dev_attr_topology_change_timer.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) &dev_attr_gc_timer.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) &dev_attr_group_addr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) &dev_attr_flush.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) &dev_attr_no_linklocal_learn.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) &dev_attr_multicast_router.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) &dev_attr_multicast_snooping.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) &dev_attr_multicast_querier.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) &dev_attr_multicast_query_use_ifaddr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) &dev_attr_hash_elasticity.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) &dev_attr_hash_max.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) &dev_attr_multicast_last_member_count.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) &dev_attr_multicast_startup_query_count.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) &dev_attr_multicast_last_member_interval.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) &dev_attr_multicast_membership_interval.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) &dev_attr_multicast_querier_interval.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) &dev_attr_multicast_query_interval.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) &dev_attr_multicast_query_response_interval.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) &dev_attr_multicast_startup_query_interval.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) &dev_attr_multicast_stats_enabled.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) &dev_attr_multicast_igmp_version.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) &dev_attr_multicast_mld_version.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) &dev_attr_nf_call_iptables.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) &dev_attr_nf_call_ip6tables.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) &dev_attr_nf_call_arptables.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) #ifdef CONFIG_BRIDGE_VLAN_FILTERING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) &dev_attr_vlan_filtering.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) &dev_attr_vlan_protocol.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) &dev_attr_default_pvid.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) &dev_attr_vlan_stats_enabled.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) &dev_attr_vlan_stats_per_port.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) NULL
^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) static const struct attribute_group bridge_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) .name = SYSFS_BRIDGE_ATTR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) .attrs = bridge_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) * Export the forwarding information table as a binary file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) * The records are struct __fdb_entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) * Returns the number of bytes read.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) static ssize_t brforward_read(struct file *filp, struct kobject *kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) struct bin_attribute *bin_attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) char *buf, loff_t off, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) struct device *dev = kobj_to_dev(kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) struct net_bridge *br = to_bridge(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) int n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) /* must read whole records */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) if (off % sizeof(struct __fdb_entry) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) n = br_fdb_fillbuf(br, buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) count / sizeof(struct __fdb_entry),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) off / sizeof(struct __fdb_entry));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) if (n > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) n *= sizeof(struct __fdb_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) return n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) static struct bin_attribute bridge_forward = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) .attr = { .name = SYSFS_BRIDGE_FDB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) .mode = 0444, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) .read = brforward_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) * Add entries in sysfs onto the existing network class device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) * for the bridge.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) * Adds a attribute group "bridge" containing tuning parameters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) * Binary attribute containing the forward table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) * Sub directory to hold links to interfaces.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) * Note: the ifobj exists only to be a subdirectory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) * to hold links. The ifobj exists in same data structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) * as it's parent the bridge so reference counting works.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) int br_sysfs_addbr(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) struct kobject *brobj = &dev->dev.kobj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) struct net_bridge *br = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) err = sysfs_create_group(brobj, &bridge_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) pr_info("%s: can't create group %s/%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) __func__, dev->name, bridge_group.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) goto out1;
^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) err = sysfs_create_bin_file(brobj, &bridge_forward);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) pr_info("%s: can't create attribute file %s/%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) __func__, dev->name, bridge_forward.attr.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) goto out2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) br->ifobj = kobject_create_and_add(SYSFS_BRIDGE_PORT_SUBDIR, brobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) if (!br->ifobj) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) pr_info("%s: can't add kobject (directory) %s/%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) __func__, dev->name, SYSFS_BRIDGE_PORT_SUBDIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) goto out3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) out3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) sysfs_remove_bin_file(&dev->dev.kobj, &bridge_forward);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) out2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) sysfs_remove_group(&dev->dev.kobj, &bridge_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) out1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) void br_sysfs_delbr(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) struct kobject *kobj = &dev->dev.kobj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) struct net_bridge *br = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) kobject_put(br->ifobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) sysfs_remove_bin_file(kobj, &bridge_forward);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) sysfs_remove_group(kobj, &bridge_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) }