X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2Fbridge%2Fbr_sysfs_br.c;h=de9d1a9473f264cd2d61d6897ffad8ce89e0d2d4;hb=refs%2Fheads%2Fvserver;hp=61f00fa3b6a8a4b2dd7d5f72521d10289c779a97;hpb=e812ccbe0c915857ebea6a632bfadc631f7504a9;p=linux-2.6.git diff --git a/net/bridge/br_sysfs_br.c b/net/bridge/br_sysfs_br.c index 61f00fa3b..de9d1a947 100644 --- a/net/bridge/br_sysfs_br.c +++ b/net/bridge/br_sysfs_br.c @@ -11,6 +11,7 @@ * 2 of the License, or (at your option) any later version. */ +#include #include #include #include @@ -241,6 +242,54 @@ static ssize_t show_gc_timer(struct class_device *cd, char *buf) } static CLASS_DEVICE_ATTR(gc_timer, S_IRUGO, show_gc_timer, NULL); +static ssize_t show_group_addr(struct class_device *cd, char *buf) +{ + struct net_bridge *br = to_bridge(cd); + return sprintf(buf, "%x:%x:%x:%x:%x:%x\n", + br->group_addr[0], br->group_addr[1], + br->group_addr[2], br->group_addr[3], + br->group_addr[4], br->group_addr[5]); +} + +static ssize_t store_group_addr(struct class_device *cd, const char *buf, + size_t len) +{ + struct net_bridge *br = to_bridge(cd); + unsigned new_addr[6]; + int i; + + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + + if (sscanf(buf, "%x:%x:%x:%x:%x:%x", + &new_addr[0], &new_addr[1], &new_addr[2], + &new_addr[3], &new_addr[4], &new_addr[5]) != 6) + return -EINVAL; + + /* Must be 01:80:c2:00:00:0X */ + for (i = 0; i < 5; i++) + if (new_addr[i] != br_group_address[i]) + return -EINVAL; + + if (new_addr[5] & ~0xf) + return -EINVAL; + + if (new_addr[5] == 1 /* 802.3x Pause address */ + || new_addr[5] == 2 /* 802.3ad Slow protocols */ + || new_addr[5] == 3) /* 802.1X PAE address */ + return -EINVAL; + + spin_lock_bh(&br->lock); + for (i = 0; i < 6; i++) + br->group_addr[i] = new_addr[i]; + spin_unlock_bh(&br->lock); + return len; +} + +static CLASS_DEVICE_ATTR(group_addr, S_IRUGO | S_IWUSR, + show_group_addr, store_group_addr); + + static struct attribute *bridge_attrs[] = { &class_device_attr_forward_delay.attr, &class_device_attr_hello_time.attr, @@ -258,6 +307,7 @@ static struct attribute *bridge_attrs[] = { &class_device_attr_tcn_timer.attr, &class_device_attr_topology_change_timer.attr, &class_device_attr_gc_timer.attr, + &class_device_attr_group_addr.attr, NULL }; @@ -300,25 +350,6 @@ static struct bin_attribute bridge_forward = { .read = brforward_read, }; - -/* - * This is a dummy kset so bridge objects don't cause - * hotplug events - */ -struct subsystem bridge_subsys = { - .kset = { .hotplug_ops = NULL }, -}; - -void br_sysfs_init(void) -{ - subsystem_register(&bridge_subsys); -} - -void br_sysfs_fini(void) -{ - subsystem_unregister(&bridge_subsys); -} - /* * Add entries in sysfs onto the existing network class device * for the bridge. @@ -345,7 +376,7 @@ int br_sysfs_addbr(struct net_device *dev) err = sysfs_create_bin_file(brobj, &bridge_forward); if (err) { - pr_info("%s: can't create attribue file %s/%s\n", + pr_info("%s: can't create attribute file %s/%s\n", __FUNCTION__, dev->name, bridge_forward.attr.name); goto out2; } @@ -353,7 +384,7 @@ int br_sysfs_addbr(struct net_device *dev) kobject_set_name(&br->ifobj, SYSFS_BRIDGE_PORT_SUBDIR); br->ifobj.ktype = NULL; - br->ifobj.kset = &bridge_subsys.kset; + br->ifobj.kset = NULL; br->ifobj.parent = brobj; err = kobject_register(&br->ifobj);