X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=datapath%2Fdp_sysfs_dp.c;h=16aa787908175b8f4312f0e292f9dc8bcb84b9b5;hb=dfbf7f354416264a0b84b09bf882ac0932e78c8b;hp=8214c604e39d5956d7f7002e60dba6e73010f1dd;hpb=b4a7d61582ef3a09a666106a926c8912201dfe72;p=openvswitch diff --git a/datapath/dp_sysfs_dp.c b/datapath/dp_sysfs_dp.c index 8214c604..16aa7879 100644 --- a/datapath/dp_sysfs_dp.c +++ b/datapath/dp_sysfs_dp.c @@ -6,6 +6,8 @@ * kernel, by Linus Torvalds and others. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include /* @@ -41,11 +43,11 @@ #define DEV_ATTR(NAME) dev_attr_##NAME #endif -struct datapath *sysfs_get_dp(struct net_device *netdev) +static struct datapath *sysfs_get_dp(struct net_device *netdev) { - return vport_get_dp_port(internal_dev_get_vport(netdev))->dp; + struct vport *vport = internal_dev_get_vport(netdev); + return vport ? vport->dp : NULL; } - /* * Common code for storing bridge parameters. */ @@ -53,9 +55,9 @@ static ssize_t store_bridge_parm(DEVICE_PARAMS, const char *buf, size_t len, void (*set)(struct datapath *, unsigned long)) { - struct datapath *dp = sysfs_get_dp(to_net_dev(d)); char *endp; unsigned long val; + ssize_t result = len; if (!capable(CAP_NET_ADMIN)) return -EPERM; @@ -66,14 +68,24 @@ static ssize_t store_bridge_parm(DEVICE_PARAMS, /* xxx We use a default value of 0 for all fields. If the caller is * xxx attempting to set the value to our default, just silently - * xxx ignore the request. + * xxx ignore the request. */ if (val != 0) { - printk("%s: xxx writing dp parms not supported yet!\n", - dp_name(dp)); + struct datapath *dp; + + rcu_read_lock(); + + dp = sysfs_get_dp(to_net_dev(d)); + if (dp) + printk("%s: xxx writing dp parms not supported yet!\n", + dp_name(dp)); + else + result = -ENODEV; + + rcu_read_unlock(); } - return len; + return result; } @@ -159,11 +171,20 @@ static ssize_t store_stp_state(DEVICE_PARAMS, const char *buf, size_t len) { - struct datapath *dp = sysfs_get_dp(to_net_dev(d)); + struct datapath *dp; + ssize_t result = len; + + rcu_read_lock(); + + dp = sysfs_get_dp(to_net_dev(d)); + if (dp) + printk("%s: xxx attempt to set_stp_state()\n", dp_name(dp)); + else + result = -ENODEV; - printk("%s: xxx attempt to set_stp_state()\n", dp_name(dp)); + rcu_read_unlock(); - return len; + return result; } static INTERNAL_DEVICE_ATTR(stp_state, S_IRUGO | S_IWUSR, show_stp_state, store_stp_state); @@ -193,12 +214,24 @@ static INTERNAL_DEVICE_ATTR(root_id, S_IRUGO, show_root_id, NULL); static ssize_t show_bridge_id(DEVICE_PARAMS, char *buf) { - struct datapath *dp = sysfs_get_dp(to_net_dev(d)); - const unsigned char *addr = vport_get_addr(dp->ports[ODPP_LOCAL]->vport); + struct vport *vport; + ssize_t result; - /* xxx Do we need a lock of some sort? */ - return sprintf(buf, "%.2x%.2x.%.2x%.2x%.2x%.2x%.2x%.2x\n", - 0, 0, addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); + rcu_read_lock(); + + vport = internal_dev_get_vport(to_net_dev(d)); + if (vport) { + const unsigned char *addr; + + addr = vport_get_addr(vport); + result = sprintf(buf, "%.2x%.2x.%.2x%.2x%.2x%.2x%.2x%.2x\n", + 0, 0, addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); + } else + result = -ENODEV; + + rcu_read_unlock(); + + return result; } static INTERNAL_DEVICE_ATTR(bridge_id, S_IRUGO, show_bridge_id, NULL); @@ -260,10 +293,20 @@ static ssize_t show_group_addr(DEVICE_PARAMS, char *buf) static ssize_t store_group_addr(DEVICE_PARAMS, const char *buf, size_t len) { - struct datapath *dp = sysfs_get_dp(to_net_dev(d)); + struct datapath *dp; + ssize_t result = len; + + rcu_read_lock(); + + dp = sysfs_get_dp(to_net_dev(d)); + if (dp) + printk("%s: xxx attempt to store_group_addr()\n", dp_name(dp)); + else + result = -ENODEV; + + rcu_read_unlock(); - printk("%s: xxx attempt to store_group_addr()\n", dp_name(dp)); - return len; + return result; } static INTERNAL_DEVICE_ATTR(group_addr, S_IRUGO | S_IWUSR, @@ -307,7 +350,8 @@ static struct attribute_group bridge_group = { */ int dp_sysfs_add_dp(struct datapath *dp) { - struct kobject *kobj = vport_get_kobj(dp->ports[ODPP_LOCAL]->vport); + struct kobject *kobj = + vport_get_kobj(rtnl_dereference(dp->ports[OVSP_LOCAL])); int err; /* Create /sys/class/net//bridge directory. */ @@ -336,7 +380,8 @@ int dp_sysfs_add_dp(struct datapath *dp) int dp_sysfs_del_dp(struct datapath *dp) { - struct kobject *kobj = vport_get_kobj(dp->ports[ODPP_LOCAL]->vport); + struct kobject *kobj = + vport_get_kobj(rtnl_dereference(dp->ports[OVSP_LOCAL])); kobject_del(&dp->ifobj); sysfs_remove_group(kobj, &bridge_group); @@ -346,6 +391,6 @@ int dp_sysfs_del_dp(struct datapath *dp) #else /* !CONFIG_SYSFS */ int dp_sysfs_add_dp(struct datapath *dp) { return 0; } int dp_sysfs_del_dp(struct datapath *dp) { return 0; } -int dp_sysfs_add_if(struct dp_port *p) { return 0; } -int dp_sysfs_del_if(struct dp_port *p) { return 0; } +int dp_sysfs_add_if(struct vport *p) { return 0; } +int dp_sysfs_del_if(struct vport *p) { return 0; } #endif /* !CONFIG_SYSFS */