[ovs-dev] brport_sysfs_ops

Simon Horman horms at verge.net.au
Wed Sep 1 02:55:59 UTC 2010


On Tue, Aug 31, 2010 at 12:53:38PM -0700, Jesse Gross wrote:
> On Tue, Aug 31, 2010 at 12:53 AM, Simon Horman <horms at verge.net.au> wrote:
> > Hi Jesse,
> >
> > I just came across the following error:
> >
> > net/openvswitch/built-in.o:(.data+0x610): multiple definition of `brport_sysfs_ops'
> > net/bridge/built-in.o:(.rodata+0x1140): first defined here
> >
> > I seem to recall some discussion of these sysfs entries at the meeting in
> > Boston. Was the decision to remove them?
> 
> I'm not sure that we actually reached a decision regarding sysfs
> entries.  However, I would be inclined to remove them now and then
> perhaps add a few back in later if needed.  A lot of them are purely
> for bridge compatibility and will most likely never make sense for
> Open vSwitch.  For the ones that do, we can figure it out once we know
> exactly how they will be used in their own right.

I think that is a good strategy.

> Unfortunately, this can probably only be done for the upstreamed
> version.  Since a number of people are using bridge compatibility from
> the Open vSwitch tree, we'll need to leave the sysfs code there.  I'm
> hoping that this won't be too difficult as the sysfs code is
> relatively self contained.

Understood.

The following patch seems to do the trick.
I'll include it in the merge.

Index: net-next-2.6/net/openvswitch/dp_notify.c
===================================================================
--- net-next-2.6.orig/net/openvswitch/dp_notify.c	2010-09-01 11:46:31.000000000 +0900
+++ net-next-2.6/net/openvswitch/dp_notify.c	2010-09-01 11:47:06.000000000 +0900
@@ -43,15 +43,6 @@ static int dp_device_event(struct notifi
 		mutex_unlock(&dp->mutex);
 		break;
 
-	case NETDEV_CHANGENAME:
-		if (p->port_no != ODPP_LOCAL) {
-			mutex_lock(&dp->mutex);
-			dp_sysfs_del_if(p);
-			dp_sysfs_add_if(p);
-			mutex_unlock(&dp->mutex);
-		}
-		break;
-
 	case NETDEV_CHANGEMTU:
 		if (!is_internal_dev(dev))
 			set_internal_devs_mtu(dp);
Index: net-next-2.6/net/openvswitch/datapath.c
===================================================================
--- net-next-2.6.orig/net/openvswitch/datapath.c	2010-09-01 11:46:31.000000000 +0900
+++ net-next-2.6/net/openvswitch/datapath.c	2010-09-01 11:47:06.000000000 +0900
@@ -286,8 +286,6 @@ static int create_dp(int dp_idx, const c
 	mutex_unlock(&dp_mutex);
 	rtnl_unlock();
 
-	dp_sysfs_add_dp(dp);
-
 	return 0;
 
 err_destroy_local_port:
@@ -314,8 +312,6 @@ static void do_destroy_dp(struct datapat
 		if (p->port_no != ODPP_LOCAL)
 			dp_detach_port(p, 1);
 
-	dp_sysfs_del_dp(dp);
-
 	rcu_assign_pointer(dps[dp->dp_idx], NULL);
 
 	dp_detach_port(dp->ports[ODPP_LOCAL], 1);
@@ -359,9 +355,6 @@ static void release_dp_port(struct kobje
 }
 
 static struct kobj_type brport_ktype = {
-#ifdef CONFIG_SYSFS
-	.sysfs_ops = &brport_sysfs_ops,
-#endif
 	.release = release_dp_port
 };
 
@@ -446,7 +439,6 @@ got_port_no:
 		goto out_unlock_dp;
 
 	set_internal_devs_mtu(dp);
-	dp_sysfs_add_if(dp->ports[port_no]);
 
 	err = put_user(port_no, &portp->port);
 
@@ -465,8 +457,6 @@ int dp_detach_port(struct dp_port *p, in
 
 	ASSERT_RTNL();
 
-	if (p->port_no != ODPP_LOCAL)
-		dp_sysfs_del_if(p);
 	dp_ifinfo_notify(RTM_DELLINK, p);
 
 	/* First drop references to device. */
Index: net-next-2.6/net/openvswitch/datapath.h
===================================================================
--- net-next-2.6.orig/net/openvswitch/datapath.h	2010-09-01 11:46:31.000000000 +0900
+++ net-next-2.6/net/openvswitch/datapath.h	2010-09-01 11:47:06.000000000 +0900
@@ -20,7 +20,6 @@
 #include <linux/skbuff.h>
 #include <linux/version.h>
 #include "flow.h"
-#include "dp_sysfs.h"
 
 struct vport;
 struct dp_port;
Index: net-next-2.6/net/openvswitch/dp_sysfs.h
===================================================================
--- net-next-2.6.orig/net/openvswitch/dp_sysfs.h	2010-09-01 11:46:31.000000000 +0900
+++ /dev/null	1970-01-01 00:00:00.000000000 +0000
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2009, 2010 Nicira Networks.
- * Distributed under the terms of the GNU GPL version 2.
- *
- * Significant portions of this file may be copied from parts of the Linux
- * kernel, by Linus Torvalds and others.
- */
-
-#ifndef DP_SYSFS_H
-#define DP_SYSFS_H 1
-
-struct datapath;
-struct dp_port;
-
-/* dp_sysfs_dp.c */
-int dp_sysfs_add_dp(struct datapath *dp);
-int dp_sysfs_del_dp(struct datapath *dp);
-
-/* dp_sysfs_if.c */
-int dp_sysfs_add_if(struct dp_port *p);
-int dp_sysfs_del_if(struct dp_port *p);
-
-#ifdef CONFIG_SYSFS
-extern struct sysfs_ops brport_sysfs_ops;
-#endif
-
-#endif /* dp_sysfs.h */
-
Index: net-next-2.6/net/openvswitch/dp_sysfs_dp.c
===================================================================
--- net-next-2.6.orig/net/openvswitch/dp_sysfs_dp.c	2010-09-01 11:46:31.000000000 +0900
+++ /dev/null	1970-01-01 00:00:00.000000000 +0000
@@ -1,403 +0,0 @@
-/*
- * Copyright (c) 2009, 2010 Nicira Networks.
- * Distributed under the terms of the GNU GPL version 2.
- *
- * Significant portions of this file may be copied from parts of the Linux
- * kernel, by Linus Torvalds and others.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/version.h>
-
-/*
- *	Sysfs attributes of bridge for Open vSwitch
- *
- *  This has been shamelessly copied from the kernel sources.
- */
-
-#include <linux/capability.h>
-#include <linux/device.h>
-#include <linux/kernel.h>
-#include <linux/netdevice.h>
-#include <linux/if_bridge.h>
-#include <linux/rtnetlink.h>
-#include <linux/version.h>
-
-#include "dp_sysfs.h"
-#include "datapath.h"
-#include "vport-internal_dev.h"
-
-#ifdef CONFIG_SYSFS
-
-/* Hack to attempt to build on more platforms. */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)
-#define INTERNAL_DEVICE_ATTR CLASS_DEVICE_ATTR
-#define DEVICE_PARAMS struct class_device *d
-#define DEVICE_ARGS d
-#define DEV_ATTR(NAME) class_device_attr_##NAME
-#else
-#define INTERNAL_DEVICE_ATTR DEVICE_ATTR
-#define DEVICE_PARAMS struct device *d, struct device_attribute *attr
-#define DEVICE_ARGS d, attr
-#define DEV_ATTR(NAME) dev_attr_##NAME
-#endif
-
-struct datapath *sysfs_get_dp(struct net_device *netdev)
-{
-	struct vport *vport = internal_dev_get_vport(netdev);
-	struct dp_port *dp_port;
-
-	if (!vport)
-		return NULL;
-
-	dp_port = vport_get_dp_port(vport);
-	if (!dp_port)
-		return NULL;
-
-	return dp_port->dp;
-}
-/*
- * Common code for storing bridge parameters.
- */
-static ssize_t store_bridge_parm(DEVICE_PARAMS,
-				 const char *buf, size_t len,
-				 void (*set)(struct datapath *, unsigned long))
-{
-	char *endp;
-	unsigned long val;
-	ssize_t result = len;
-
-	if (!capable(CAP_NET_ADMIN))
-		return -EPERM;
-
-	val = simple_strtoul(buf, &endp, 0);
-	if (endp == buf)
-		return -EINVAL;
-
-	/* 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.
-	 */
-	if (val != 0) {
-		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 result;
-}
-
-
-static ssize_t show_forward_delay(DEVICE_PARAMS, char *buf)
-{
-	return sprintf(buf, "%d\n", 0);
-}
-
-static void set_forward_delay(struct datapath *dp, unsigned long val)
-{
-	printk("%s: xxx attempt to set_forward_delay()\n", dp_name(dp));
-}
-
-static ssize_t store_forward_delay(DEVICE_PARAMS,
-				   const char *buf, size_t len)
-{
-	return store_bridge_parm(DEVICE_ARGS, buf, len, set_forward_delay);
-}
-static INTERNAL_DEVICE_ATTR(forward_delay, S_IRUGO | S_IWUSR,
-		   show_forward_delay, store_forward_delay);
-
-static ssize_t show_hello_time(DEVICE_PARAMS, char *buf)
-{
-	return sprintf(buf, "%d\n", 0);
-}
-
-static void set_hello_time(struct datapath *dp, unsigned long val)
-{
-	printk("%s: xxx attempt to set_hello_time()\n", dp_name(dp));
-}
-
-static ssize_t store_hello_time(DEVICE_PARAMS,
-				const char *buf,
-				size_t len)
-{
-	return store_bridge_parm(DEVICE_ARGS, buf, len, set_hello_time);
-}
-static INTERNAL_DEVICE_ATTR(hello_time, S_IRUGO | S_IWUSR, show_hello_time,
-		   store_hello_time);
-
-static ssize_t show_max_age(DEVICE_PARAMS, char *buf)
-{
-	return sprintf(buf, "%d\n", 0);
-}
-
-static void set_max_age(struct datapath *dp, unsigned long val)
-{
-	printk("%s: xxx attempt to set_max_age()\n", dp_name(dp));
-}
-
-static ssize_t store_max_age(DEVICE_PARAMS,
-			     const char *buf, size_t len)
-{
-	return store_bridge_parm(DEVICE_ARGS, buf, len, set_max_age);
-}
-static INTERNAL_DEVICE_ATTR(max_age, S_IRUGO | S_IWUSR, show_max_age, store_max_age);
-
-static ssize_t show_ageing_time(DEVICE_PARAMS, char *buf)
-{
-	return sprintf(buf, "%d\n", 0);
-}
-
-static void set_ageing_time(struct datapath *dp, unsigned long val)
-{
-	printk("%s: xxx attempt to set_ageing_time()\n", dp_name(dp));
-}
-
-static ssize_t store_ageing_time(DEVICE_PARAMS,
-				 const char *buf, size_t len)
-{
-	return store_bridge_parm(DEVICE_ARGS, buf, len, set_ageing_time);
-}
-static INTERNAL_DEVICE_ATTR(ageing_time, S_IRUGO | S_IWUSR, show_ageing_time,
-		   store_ageing_time);
-
-static ssize_t show_stp_state(DEVICE_PARAMS, char *buf)
-{
-	return sprintf(buf, "%d\n", 0);
-}
-
-
-static ssize_t store_stp_state(DEVICE_PARAMS,
-			       const char *buf,
-			       size_t len)
-{
-	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;
-
-	rcu_read_unlock();
-
-	return result;
-}
-static INTERNAL_DEVICE_ATTR(stp_state, S_IRUGO | S_IWUSR, show_stp_state,
-		   store_stp_state);
-
-static ssize_t show_priority(DEVICE_PARAMS, char *buf)
-{
-	return sprintf(buf, "%d\n", 0);
-}
-
-static void set_priority(struct datapath *dp, unsigned long val)
-{
-	printk("%s: xxx attempt to set_priority()\n", dp_name(dp));
-}
-
-static ssize_t store_priority(DEVICE_PARAMS,
-			       const char *buf, size_t len)
-{
-	return store_bridge_parm(DEVICE_ARGS, buf, len, set_priority);
-}
-static INTERNAL_DEVICE_ATTR(priority, S_IRUGO | S_IWUSR, show_priority, store_priority);
-
-static ssize_t show_root_id(DEVICE_PARAMS, char *buf)
-{
-	return sprintf(buf, "0000.010203040506\n");
-}
-static INTERNAL_DEVICE_ATTR(root_id, S_IRUGO, show_root_id, NULL);
-
-static ssize_t show_bridge_id(DEVICE_PARAMS, char *buf)
-{
-	struct vport *vport;
-	ssize_t result;
-
-	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);
-
-static ssize_t show_root_port(DEVICE_PARAMS, char *buf)
-{
-	return sprintf(buf, "%d\n", 0);
-}
-static INTERNAL_DEVICE_ATTR(root_port, S_IRUGO, show_root_port, NULL);
-
-static ssize_t show_root_path_cost(DEVICE_PARAMS, char *buf)
-{
-	return sprintf(buf, "%d\n", 0);
-}
-static INTERNAL_DEVICE_ATTR(root_path_cost, S_IRUGO, show_root_path_cost, NULL);
-
-static ssize_t show_topology_change(DEVICE_PARAMS, char *buf)
-{
-	return sprintf(buf, "%d\n", 0);
-}
-static INTERNAL_DEVICE_ATTR(topology_change, S_IRUGO, show_topology_change, NULL);
-
-static ssize_t show_topology_change_detected(DEVICE_PARAMS, char *buf)
-{
-	return sprintf(buf, "%d\n", 0);
-}
-static INTERNAL_DEVICE_ATTR(topology_change_detected, S_IRUGO,
-		   show_topology_change_detected, NULL);
-
-static ssize_t show_hello_timer(DEVICE_PARAMS, char *buf)
-{
-	return sprintf(buf, "%d\n", 0);
-}
-static INTERNAL_DEVICE_ATTR(hello_timer, S_IRUGO, show_hello_timer, NULL);
-
-static ssize_t show_tcn_timer(DEVICE_PARAMS, char *buf)
-{
-	return sprintf(buf, "%d\n", 0);
-}
-static INTERNAL_DEVICE_ATTR(tcn_timer, S_IRUGO, show_tcn_timer, NULL);
-
-static ssize_t show_topology_change_timer(DEVICE_PARAMS, char *buf)
-{
-	return sprintf(buf, "%d\n", 0);
-}
-static INTERNAL_DEVICE_ATTR(topology_change_timer, S_IRUGO, show_topology_change_timer,
-		   NULL);
-
-static ssize_t show_gc_timer(DEVICE_PARAMS, char *buf)
-{
-	return sprintf(buf, "%d\n", 0);
-}
-static INTERNAL_DEVICE_ATTR(gc_timer, S_IRUGO, show_gc_timer, NULL);
-
-static ssize_t show_group_addr(DEVICE_PARAMS, char *buf)
-{
-	return sprintf(buf, "00:01:02:03:04:05\n");
-}
-
-static ssize_t store_group_addr(DEVICE_PARAMS,
-				const char *buf, size_t len)
-{
-	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();
-
-	return result;
-}
-
-static INTERNAL_DEVICE_ATTR(group_addr, S_IRUGO | S_IWUSR,
-		   show_group_addr, store_group_addr);
-
-static struct attribute *bridge_attrs[] = {
-	&DEV_ATTR(forward_delay).attr,
-	&DEV_ATTR(hello_time).attr,
-	&DEV_ATTR(max_age).attr,
-	&DEV_ATTR(ageing_time).attr,
-	&DEV_ATTR(stp_state).attr,
-	&DEV_ATTR(priority).attr,
-	&DEV_ATTR(bridge_id).attr,
-	&DEV_ATTR(root_id).attr,
-	&DEV_ATTR(root_path_cost).attr,
-	&DEV_ATTR(root_port).attr,
-	&DEV_ATTR(topology_change).attr,
-	&DEV_ATTR(topology_change_detected).attr,
-	&DEV_ATTR(hello_timer).attr,
-	&DEV_ATTR(tcn_timer).attr,
-	&DEV_ATTR(topology_change_timer).attr,
-	&DEV_ATTR(gc_timer).attr,
-	&DEV_ATTR(group_addr).attr,
-	NULL
-};
-
-static struct attribute_group bridge_group = {
-	.name = SYSFS_BRIDGE_ATTR, /* "bridge" */
-	.attrs = bridge_attrs,
-};
-
-/*
- * Add entries in sysfs onto the existing network class device
- * for the bridge.
- *   Adds a attribute group "bridge" containing tuning parameters.
- *   Sub directory to hold links to interfaces.
- *
- * Note: the ifobj exists only to be a subdirectory
- *   to hold links.  The ifobj exists in the same data structure
- *   as its parent the bridge so reference counting works.
- */
-int dp_sysfs_add_dp(struct datapath *dp)
-{
-	struct kobject *kobj = vport_get_kobj(dp->ports[ODPP_LOCAL]->vport);
-	int err;
-
-	/* Create /sys/class/net/<devname>/bridge directory. */
-	err = sysfs_create_group(kobj, &bridge_group);
-	if (err) {
-		pr_info("%s: can't create group %s/%s\n",
-			__func__, dp_name(dp), bridge_group.name);
-		goto out1;
-	}
-
-	/* Create /sys/class/net/<devname>/brif directory. */
-	err = kobject_add(&dp->ifobj, kobj, SYSFS_BRIDGE_PORT_SUBDIR);
-	if (err) {
-		pr_info("%s: can't add kobject (directory) %s/%s\n",
-			__FUNCTION__, dp_name(dp), kobject_name(&dp->ifobj));
-		goto out2;
-	}
-	kobject_uevent(&dp->ifobj, KOBJ_ADD);
-	return 0;
-
- out2:
-	sysfs_remove_group(kobj, &bridge_group);
- out1:
-	return err;
-}
-
-int dp_sysfs_del_dp(struct datapath *dp)
-{
-	struct kobject *kobj = vport_get_kobj(dp->ports[ODPP_LOCAL]->vport);
-
-	kobject_del(&dp->ifobj);
-	sysfs_remove_group(kobj, &bridge_group);
-
-	return 0;
-}
-#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; }
-#endif /* !CONFIG_SYSFS */
Index: net-next-2.6/net/openvswitch/dp_sysfs_if.c
===================================================================
--- net-next-2.6.orig/net/openvswitch/dp_sysfs_if.c	2010-09-01 11:46:31.000000000 +0900
+++ /dev/null	1970-01-01 00:00:00.000000000 +0000
@@ -1,263 +0,0 @@
-/*
- * Copyright (c) 2009, 2010 Nicira Networks.
- * Distributed under the terms of the GNU GPL version 2.
- *
- * Significant portions of this file may be copied from parts of the Linux
- * kernel, by Linus Torvalds and others.
- */
-
-/*
- *	Sysfs attributes of bridge ports for Open vSwitch
- *
- *  This has been shamelessly copied from the kernel sources.
- */
-
-#include <linux/capability.h>
-#include <linux/kernel.h>
-#include <linux/netdevice.h>
-#include <linux/if_bridge.h>
-#include <linux/rtnetlink.h>
-
-#include "datapath.h"
-#include "dp_sysfs.h"
-#include "vport.h"
-
-#ifdef CONFIG_SYSFS
-
-struct brport_attribute {
-	struct attribute	attr;
-	ssize_t (*show)(struct dp_port *, char *);
-	ssize_t (*store)(struct dp_port *, unsigned long);
-};
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
-#define BRPORT_ATTR(_name,_mode,_show,_store)		        \
-struct brport_attribute brport_attr_##_name = {		        \
-	.attr = {.name = __stringify(_name),			\
-		 .mode = _mode },				\
-	.show	= _show,					\
-	.store	= _store,					\
-};
-#else
-#define BRPORT_ATTR(_name,_mode,_show,_store)		        \
-struct brport_attribute brport_attr_##_name = { 	        \
-	.attr = {.name = __stringify(_name), 			\
-		 .mode = _mode, 				\
-		 .owner = THIS_MODULE, },			\
-	.show	= _show,					\
-	.store	= _store,					\
-};
-#endif
-
-static ssize_t show_path_cost(struct dp_port *p, char *buf)
-{
-	return sprintf(buf, "%d\n", 0);
-}
-static ssize_t store_path_cost(struct dp_port *p, unsigned long v)
-{
-	return 0;
-}
-static BRPORT_ATTR(path_cost, S_IRUGO | S_IWUSR,
-		   show_path_cost, store_path_cost);
-
-static ssize_t show_priority(struct dp_port *p, char *buf)
-{
-	return sprintf(buf, "%d\n", 0);
-}
-static ssize_t store_priority(struct dp_port *p, unsigned long v)
-{
-	return 0;
-}
-static BRPORT_ATTR(priority, S_IRUGO | S_IWUSR,
-			 show_priority, store_priority);
-
-static ssize_t show_designated_root(struct dp_port *p, char *buf)
-{
-	return sprintf(buf, "0000.010203040506\n");
-}
-static BRPORT_ATTR(designated_root, S_IRUGO, show_designated_root, NULL);
-
-static ssize_t show_designated_bridge(struct dp_port *p, char *buf)
-{
-	return sprintf(buf, "0000.060504030201\n");
-}
-static BRPORT_ATTR(designated_bridge, S_IRUGO, show_designated_bridge, NULL);
-
-static ssize_t show_designated_port(struct dp_port *p, char *buf)
-{
-	return sprintf(buf, "%d\n", 0);
-}
-static BRPORT_ATTR(designated_port, S_IRUGO, show_designated_port, NULL);
-
-static ssize_t show_designated_cost(struct dp_port *p, char *buf)
-{
-	return sprintf(buf, "%d\n", 0);
-}
-static BRPORT_ATTR(designated_cost, S_IRUGO, show_designated_cost, NULL);
-
-static ssize_t show_port_id(struct dp_port *p, char *buf)
-{
-	return sprintf(buf, "0x%x\n", 0);
-}
-static BRPORT_ATTR(port_id, S_IRUGO, show_port_id, NULL);
-
-static ssize_t show_port_no(struct dp_port *p, char *buf)
-{
-	return sprintf(buf, "0x%x\n", p->port_no);
-}
-
-static BRPORT_ATTR(port_no, S_IRUGO, show_port_no, NULL);
-
-static ssize_t show_change_ack(struct dp_port *p, char *buf)
-{
-	return sprintf(buf, "%d\n", 0);
-}
-static BRPORT_ATTR(change_ack, S_IRUGO, show_change_ack, NULL);
-
-static ssize_t show_config_pending(struct dp_port *p, char *buf)
-{
-	return sprintf(buf, "%d\n", 0);
-}
-static BRPORT_ATTR(config_pending, S_IRUGO, show_config_pending, NULL);
-
-static ssize_t show_port_state(struct dp_port *p, char *buf)
-{
-	return sprintf(buf, "%d\n", 0);
-}
-static BRPORT_ATTR(state, S_IRUGO, show_port_state, NULL);
-
-static ssize_t show_message_age_timer(struct dp_port *p,
-					    char *buf)
-{
-	return sprintf(buf, "%d\n", 0);
-}
-static BRPORT_ATTR(message_age_timer, S_IRUGO, show_message_age_timer, NULL);
-
-static ssize_t show_forward_delay_timer(struct dp_port *p,
-					    char *buf)
-{
-	return sprintf(buf, "%d\n", 0);
-}
-static BRPORT_ATTR(forward_delay_timer, S_IRUGO, show_forward_delay_timer, NULL);
-
-static ssize_t show_hold_timer(struct dp_port *p,
-					    char *buf)
-{
-	return sprintf(buf, "%d\n", 0);
-}
-static BRPORT_ATTR(hold_timer, S_IRUGO, show_hold_timer, NULL);
-
-static struct brport_attribute *brport_attrs[] = {
-	&brport_attr_path_cost,
-	&brport_attr_priority,
-	&brport_attr_port_id,
-	&brport_attr_port_no,
-	&brport_attr_designated_root,
-	&brport_attr_designated_bridge,
-	&brport_attr_designated_port,
-	&brport_attr_designated_cost,
-	&brport_attr_state,
-	&brport_attr_change_ack,
-	&brport_attr_config_pending,
-	&brport_attr_message_age_timer,
-	&brport_attr_forward_delay_timer,
-	&brport_attr_hold_timer,
-	NULL
-};
-
-#define to_brport_attr(_at) container_of(_at, struct brport_attribute, attr)
-#define to_brport(obj)	container_of(obj, struct dp_port, kobj)
-
-static ssize_t brport_show(struct kobject * kobj,
-			   struct attribute * attr, char * buf)
-{
-	struct brport_attribute * brport_attr = to_brport_attr(attr);
-	struct dp_port * p = to_brport(kobj);
-
-	return brport_attr->show(p, buf);
-}
-
-static ssize_t brport_store(struct kobject * kobj,
-			    struct attribute * attr,
-			    const char * buf, size_t count)
-{
-	struct dp_port * p = to_brport(kobj);
-	ssize_t ret = -EINVAL;
-
-	if (!capable(CAP_NET_ADMIN))
-		return -EPERM;
-
-	printk("%s: xxx writing port parms not supported yet!\n",
-	       dp_name(p->dp));
-
-	return ret;
-}
-
-struct sysfs_ops brport_sysfs_ops = {
-	.show = brport_show,
-	.store = brport_store,
-};
-
-/*
- * Add sysfs entries to ethernet device added to a bridge.
- * Creates a brport subdirectory with bridge attributes.
- * Puts symlink in bridge's brport subdirectory
- */
-int dp_sysfs_add_if(struct dp_port *p)
-{
-	struct kobject *kobj = vport_get_kobj(p->vport);
-	struct datapath *dp = p->dp;
-	struct brport_attribute **a;
-	int err;
-
-	/* Create /sys/class/net/<devname>/brport directory. */
-	if (!kobj)
-		return -ENOENT;
-
-	err = kobject_add(&p->kobj, kobj, SYSFS_BRIDGE_PORT_ATTR);
-	if (err)
-		goto err;
-
-	/* Create symlink from /sys/class/net/<devname>/brport/bridge to
-	 * /sys/class/net/<bridgename>. */
-	err = sysfs_create_link(&p->kobj, vport_get_kobj(dp->ports[ODPP_LOCAL]->vport),
-				SYSFS_BRIDGE_PORT_LINK); /* "bridge" */
-	if (err)
-		goto err_del;
-
-	/* Populate /sys/class/net/<devname>/brport directory with files. */
-	for (a = brport_attrs; *a; ++a) {
-		err = sysfs_create_file(&p->kobj, &((*a)->attr));
-		if (err)
-			goto err_del;
-	}
-
-	/* Create symlink from /sys/class/net/<bridgename>/brif/<devname> to
-	 * /sys/class/net/<devname>/brport.  */
-	err = sysfs_create_link(&dp->ifobj, &p->kobj, vport_get_name(p->vport));
-	if (err)
-		goto err_del;
-	strcpy(p->linkname, vport_get_name(p->vport));
-
-	kobject_uevent(&p->kobj, KOBJ_ADD);
-
-	return 0;
-
-err_del:
-	kobject_del(&p->kobj);
-err:
-	p->linkname[0] = 0;
-	return err;
-}
-
-int dp_sysfs_del_if(struct dp_port *p)
-{
-	if (p->linkname[0]) {
-		sysfs_remove_link(&p->dp->ifobj, p->linkname);
-		kobject_uevent(&p->kobj, KOBJ_REMOVE);
-		kobject_del(&p->kobj);
-		p->linkname[0] = '\0';
-	}
-	return 0;
-}
-#endif /* CONFIG_SYSFS */




More information about the dev mailing list