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