1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Sysfs attributes of bridge ports 4 * Linux ethernet bridge 5 * 6 * Authors: 7 * Stephen Hemminger <shemminger@osdl.org> 8 */ 9 10 #include <linux/capability.h> 11 #include <linux/kernel.h> 12 #include <linux/netdevice.h> 13 #include <linux/if_bridge.h> 14 #include <linux/rtnetlink.h> 15 #include <linux/spinlock.h> 16 #include <linux/sched/signal.h> 17 18 #include "br_private.h" 19 20 struct brport_attribute { 21 struct attribute attr; 22 ssize_t (*show)(struct net_bridge_port *, char *); 23 int (*store)(struct net_bridge_port *, unsigned long); 24 int (*store_raw)(struct net_bridge_port *, char *); 25 }; 26 27 #define BRPORT_ATTR_RAW(_name, _mode, _show, _store) \ 28 const struct brport_attribute brport_attr_##_name = { \ 29 .attr = {.name = __stringify(_name), \ 30 .mode = _mode }, \ 31 .show = _show, \ 32 .store_raw = _store, \ 33 }; 34 35 #define BRPORT_ATTR(_name, _mode, _show, _store) \ 36 const struct brport_attribute brport_attr_##_name = { \ 37 .attr = {.name = __stringify(_name), \ 38 .mode = _mode }, \ 39 .show = _show, \ 40 .store = _store, \ 41 }; 42 43 #define BRPORT_ATTR_FLAG(_name, _mask) \ 44 static ssize_t show_##_name(struct net_bridge_port *p, char *buf) \ 45 { \ 46 return sprintf(buf, "%d\n", !!(p->flags & _mask)); \ 47 } \ 48 static int store_##_name(struct net_bridge_port *p, unsigned long v) \ 49 { \ 50 return store_flag(p, v, _mask); \ 51 } \ 52 static BRPORT_ATTR(_name, 0644, \ 53 show_##_name, store_##_name) 54 55 static int store_flag(struct net_bridge_port *p, unsigned long v, 56 unsigned long mask) 57 { 58 unsigned long flags; 59 60 flags = p->flags; 61 62 if (v) 63 flags |= mask; 64 else 65 flags &= ~mask; 66 67 if (flags != p->flags) { 68 p->flags = flags; 69 br_port_flags_change(p, mask); 70 } 71 return 0; 72 } 73 74 static ssize_t show_path_cost(struct net_bridge_port *p, char *buf) 75 { 76 return sprintf(buf, "%d\n", p->path_cost); 77 } 78 79 static BRPORT_ATTR(path_cost, 0644, 80 show_path_cost, br_stp_set_path_cost); 81 82 static ssize_t show_priority(struct net_bridge_port *p, char *buf) 83 { 84 return sprintf(buf, "%d\n", p->priority); 85 } 86 87 static BRPORT_ATTR(priority, 0644, 88 show_priority, br_stp_set_port_priority); 89 90 static ssize_t show_designated_root(struct net_bridge_port *p, char *buf) 91 { 92 return br_show_bridge_id(buf, &p->designated_root); 93 } 94 static BRPORT_ATTR(designated_root, 0444, show_designated_root, NULL); 95 96 static ssize_t show_designated_bridge(struct net_bridge_port *p, char *buf) 97 { 98 return br_show_bridge_id(buf, &p->designated_bridge); 99 } 100 static BRPORT_ATTR(designated_bridge, 0444, show_designated_bridge, NULL); 101 102 static ssize_t show_designated_port(struct net_bridge_port *p, char *buf) 103 { 104 return sprintf(buf, "%d\n", p->designated_port); 105 } 106 static BRPORT_ATTR(designated_port, 0444, show_designated_port, NULL); 107 108 static ssize_t show_designated_cost(struct net_bridge_port *p, char *buf) 109 { 110 return sprintf(buf, "%d\n", p->designated_cost); 111 } 112 static BRPORT_ATTR(designated_cost, 0444, show_designated_cost, NULL); 113 114 static ssize_t show_port_id(struct net_bridge_port *p, char *buf) 115 { 116 return sprintf(buf, "0x%x\n", p->port_id); 117 } 118 static BRPORT_ATTR(port_id, 0444, show_port_id, NULL); 119 120 static ssize_t show_port_no(struct net_bridge_port *p, char *buf) 121 { 122 return sprintf(buf, "0x%x\n", p->port_no); 123 } 124 125 static BRPORT_ATTR(port_no, 0444, show_port_no, NULL); 126 127 static ssize_t show_change_ack(struct net_bridge_port *p, char *buf) 128 { 129 return sprintf(buf, "%d\n", p->topology_change_ack); 130 } 131 static BRPORT_ATTR(change_ack, 0444, show_change_ack, NULL); 132 133 static ssize_t show_config_pending(struct net_bridge_port *p, char *buf) 134 { 135 return sprintf(buf, "%d\n", p->config_pending); 136 } 137 static BRPORT_ATTR(config_pending, 0444, show_config_pending, NULL); 138 139 static ssize_t show_port_state(struct net_bridge_port *p, char *buf) 140 { 141 return sprintf(buf, "%d\n", p->state); 142 } 143 static BRPORT_ATTR(state, 0444, show_port_state, NULL); 144 145 static ssize_t show_message_age_timer(struct net_bridge_port *p, 146 char *buf) 147 { 148 return sprintf(buf, "%ld\n", br_timer_value(&p->message_age_timer)); 149 } 150 static BRPORT_ATTR(message_age_timer, 0444, show_message_age_timer, NULL); 151 152 static ssize_t show_forward_delay_timer(struct net_bridge_port *p, 153 char *buf) 154 { 155 return sprintf(buf, "%ld\n", br_timer_value(&p->forward_delay_timer)); 156 } 157 static BRPORT_ATTR(forward_delay_timer, 0444, show_forward_delay_timer, NULL); 158 159 static ssize_t show_hold_timer(struct net_bridge_port *p, 160 char *buf) 161 { 162 return sprintf(buf, "%ld\n", br_timer_value(&p->hold_timer)); 163 } 164 static BRPORT_ATTR(hold_timer, 0444, show_hold_timer, NULL); 165 166 static int store_flush(struct net_bridge_port *p, unsigned long v) 167 { 168 br_fdb_delete_by_port(p->br, p, 0, 0); // Don't delete local entry 169 return 0; 170 } 171 static BRPORT_ATTR(flush, 0200, NULL, store_flush); 172 173 static ssize_t show_group_fwd_mask(struct net_bridge_port *p, char *buf) 174 { 175 return sprintf(buf, "%#x\n", p->group_fwd_mask); 176 } 177 178 static int store_group_fwd_mask(struct net_bridge_port *p, 179 unsigned long v) 180 { 181 if (v & BR_GROUPFWD_MACPAUSE) 182 return -EINVAL; 183 p->group_fwd_mask = v; 184 185 return 0; 186 } 187 static BRPORT_ATTR(group_fwd_mask, 0644, show_group_fwd_mask, 188 store_group_fwd_mask); 189 190 static ssize_t show_backup_port(struct net_bridge_port *p, char *buf) 191 { 192 struct net_bridge_port *backup_p; 193 int ret = 0; 194 195 rcu_read_lock(); 196 backup_p = rcu_dereference(p->backup_port); 197 if (backup_p) 198 ret = sprintf(buf, "%s\n", backup_p->dev->name); 199 rcu_read_unlock(); 200 201 return ret; 202 } 203 204 static int store_backup_port(struct net_bridge_port *p, char *buf) 205 { 206 struct net_device *backup_dev = NULL; 207 char *nl = strchr(buf, '\n'); 208 209 if (nl) 210 *nl = '\0'; 211 212 if (strlen(buf) > 0) { 213 backup_dev = __dev_get_by_name(dev_net(p->dev), buf); 214 if (!backup_dev) 215 return -ENOENT; 216 } 217 218 return nbp_backup_change(p, backup_dev); 219 } 220 static BRPORT_ATTR_RAW(backup_port, 0644, show_backup_port, store_backup_port); 221 222 BRPORT_ATTR_FLAG(hairpin_mode, BR_HAIRPIN_MODE); 223 BRPORT_ATTR_FLAG(bpdu_guard, BR_BPDU_GUARD); 224 BRPORT_ATTR_FLAG(root_block, BR_ROOT_BLOCK); 225 BRPORT_ATTR_FLAG(learning, BR_LEARNING); 226 BRPORT_ATTR_FLAG(unicast_flood, BR_FLOOD); 227 BRPORT_ATTR_FLAG(proxyarp, BR_PROXYARP); 228 BRPORT_ATTR_FLAG(proxyarp_wifi, BR_PROXYARP_WIFI); 229 BRPORT_ATTR_FLAG(multicast_flood, BR_MCAST_FLOOD); 230 BRPORT_ATTR_FLAG(broadcast_flood, BR_BCAST_FLOOD); 231 BRPORT_ATTR_FLAG(neigh_suppress, BR_NEIGH_SUPPRESS); 232 BRPORT_ATTR_FLAG(isolated, BR_ISOLATED); 233 234 #ifdef CONFIG_BRIDGE_IGMP_SNOOPING 235 static ssize_t show_multicast_router(struct net_bridge_port *p, char *buf) 236 { 237 return sprintf(buf, "%d\n", p->multicast_router); 238 } 239 240 static int store_multicast_router(struct net_bridge_port *p, 241 unsigned long v) 242 { 243 return br_multicast_set_port_router(p, v); 244 } 245 static BRPORT_ATTR(multicast_router, 0644, show_multicast_router, 246 store_multicast_router); 247 248 BRPORT_ATTR_FLAG(multicast_fast_leave, BR_MULTICAST_FAST_LEAVE); 249 BRPORT_ATTR_FLAG(multicast_to_unicast, BR_MULTICAST_TO_UNICAST); 250 #endif 251 252 static const struct brport_attribute *brport_attrs[] = { 253 &brport_attr_path_cost, 254 &brport_attr_priority, 255 &brport_attr_port_id, 256 &brport_attr_port_no, 257 &brport_attr_designated_root, 258 &brport_attr_designated_bridge, 259 &brport_attr_designated_port, 260 &brport_attr_designated_cost, 261 &brport_attr_state, 262 &brport_attr_change_ack, 263 &brport_attr_config_pending, 264 &brport_attr_message_age_timer, 265 &brport_attr_forward_delay_timer, 266 &brport_attr_hold_timer, 267 &brport_attr_flush, 268 &brport_attr_hairpin_mode, 269 &brport_attr_bpdu_guard, 270 &brport_attr_root_block, 271 &brport_attr_learning, 272 &brport_attr_unicast_flood, 273 #ifdef CONFIG_BRIDGE_IGMP_SNOOPING 274 &brport_attr_multicast_router, 275 &brport_attr_multicast_fast_leave, 276 &brport_attr_multicast_to_unicast, 277 #endif 278 &brport_attr_proxyarp, 279 &brport_attr_proxyarp_wifi, 280 &brport_attr_multicast_flood, 281 &brport_attr_broadcast_flood, 282 &brport_attr_group_fwd_mask, 283 &brport_attr_neigh_suppress, 284 &brport_attr_isolated, 285 &brport_attr_backup_port, 286 NULL 287 }; 288 289 #define to_brport_attr(_at) container_of(_at, struct brport_attribute, attr) 290 291 static ssize_t brport_show(struct kobject *kobj, 292 struct attribute *attr, char *buf) 293 { 294 struct brport_attribute *brport_attr = to_brport_attr(attr); 295 struct net_bridge_port *p = kobj_to_brport(kobj); 296 297 if (!brport_attr->show) 298 return -EINVAL; 299 300 return brport_attr->show(p, buf); 301 } 302 303 static ssize_t brport_store(struct kobject *kobj, 304 struct attribute *attr, 305 const char *buf, size_t count) 306 { 307 struct brport_attribute *brport_attr = to_brport_attr(attr); 308 struct net_bridge_port *p = kobj_to_brport(kobj); 309 ssize_t ret = -EINVAL; 310 unsigned long val; 311 char *endp; 312 313 if (!ns_capable(dev_net(p->dev)->user_ns, CAP_NET_ADMIN)) 314 return -EPERM; 315 316 if (!rtnl_trylock()) 317 return restart_syscall(); 318 319 if (brport_attr->store_raw) { 320 char *buf_copy; 321 322 buf_copy = kstrndup(buf, count, GFP_KERNEL); 323 if (!buf_copy) { 324 ret = -ENOMEM; 325 goto out_unlock; 326 } 327 spin_lock_bh(&p->br->lock); 328 ret = brport_attr->store_raw(p, buf_copy); 329 spin_unlock_bh(&p->br->lock); 330 kfree(buf_copy); 331 } else if (brport_attr->store) { 332 val = simple_strtoul(buf, &endp, 0); 333 if (endp == buf) 334 goto out_unlock; 335 spin_lock_bh(&p->br->lock); 336 ret = brport_attr->store(p, val); 337 spin_unlock_bh(&p->br->lock); 338 } 339 340 if (!ret) { 341 br_ifinfo_notify(RTM_NEWLINK, NULL, p); 342 ret = count; 343 } 344 out_unlock: 345 rtnl_unlock(); 346 347 return ret; 348 } 349 350 const struct sysfs_ops brport_sysfs_ops = { 351 .show = brport_show, 352 .store = brport_store, 353 }; 354 355 /* 356 * Add sysfs entries to ethernet device added to a bridge. 357 * Creates a brport subdirectory with bridge attributes. 358 * Puts symlink in bridge's brif subdirectory 359 */ 360 int br_sysfs_addif(struct net_bridge_port *p) 361 { 362 struct net_bridge *br = p->br; 363 const struct brport_attribute **a; 364 int err; 365 366 err = sysfs_create_link(&p->kobj, &br->dev->dev.kobj, 367 SYSFS_BRIDGE_PORT_LINK); 368 if (err) 369 return err; 370 371 for (a = brport_attrs; *a; ++a) { 372 err = sysfs_create_file(&p->kobj, &((*a)->attr)); 373 if (err) 374 return err; 375 } 376 377 strlcpy(p->sysfs_name, p->dev->name, IFNAMSIZ); 378 return sysfs_create_link(br->ifobj, &p->kobj, p->sysfs_name); 379 } 380 381 /* Rename bridge's brif symlink */ 382 int br_sysfs_renameif(struct net_bridge_port *p) 383 { 384 struct net_bridge *br = p->br; 385 int err; 386 387 /* If a rename fails, the rollback will cause another 388 * rename call with the existing name. 389 */ 390 if (!strncmp(p->sysfs_name, p->dev->name, IFNAMSIZ)) 391 return 0; 392 393 err = sysfs_rename_link(br->ifobj, &p->kobj, 394 p->sysfs_name, p->dev->name); 395 if (err) 396 netdev_notice(br->dev, "unable to rename link %s to %s", 397 p->sysfs_name, p->dev->name); 398 else 399 strlcpy(p->sysfs_name, p->dev->name, IFNAMSIZ); 400 401 return err; 402 } 403