2 * Copyright (c) 2007-2012 Nicira Networks.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of version 2 of the GNU General Public
6 * License as published by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
21 #include <linux/capability.h>
22 #include <linux/kernel.h>
23 #include <linux/netdevice.h>
24 #include <linux/if_bridge.h>
25 #include <linux/rtnetlink.h>
33 struct brport_attribute
{
34 struct attribute attr
;
35 ssize_t (*show
)(struct vport
*, char *);
36 ssize_t (*store
)(struct vport
*, unsigned long);
39 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
40 #define BRPORT_ATTR(_name, _mode, _show, _store) \
41 struct brport_attribute brport_attr_##_name = { \
42 .attr = {.name = __stringify(_name), \
48 #define BRPORT_ATTR(_name, _mode, _show, _store) \
49 struct brport_attribute brport_attr_##_name = { \
50 .attr = {.name = __stringify(_name), \
52 .owner = THIS_MODULE, }, \
58 static ssize_t
show_path_cost(struct vport
*p
, char *buf
)
60 return sprintf(buf
, "%d\n", 0);
62 static ssize_t
store_path_cost(struct vport
*p
, unsigned long v
)
66 static BRPORT_ATTR(path_cost
, S_IRUGO
| S_IWUSR
,
67 show_path_cost
, store_path_cost
);
69 static ssize_t
show_priority(struct vport
*p
, char *buf
)
71 return sprintf(buf
, "%d\n", 0);
73 static ssize_t
store_priority(struct vport
*p
, unsigned long v
)
77 static BRPORT_ATTR(priority
, S_IRUGO
| S_IWUSR
,
78 show_priority
, store_priority
);
80 static ssize_t
show_designated_root(struct vport
*p
, char *buf
)
82 return sprintf(buf
, "0000.010203040506\n");
84 static BRPORT_ATTR(designated_root
, S_IRUGO
, show_designated_root
, NULL
);
86 static ssize_t
show_designated_bridge(struct vport
*p
, char *buf
)
88 return sprintf(buf
, "0000.060504030201\n");
90 static BRPORT_ATTR(designated_bridge
, S_IRUGO
, show_designated_bridge
, NULL
);
92 static ssize_t
show_designated_port(struct vport
*p
, char *buf
)
94 return sprintf(buf
, "%d\n", 0);
96 static BRPORT_ATTR(designated_port
, S_IRUGO
, show_designated_port
, NULL
);
98 static ssize_t
show_designated_cost(struct vport
*p
, char *buf
)
100 return sprintf(buf
, "%d\n", 0);
102 static BRPORT_ATTR(designated_cost
, S_IRUGO
, show_designated_cost
, NULL
);
104 static ssize_t
show_port_id(struct vport
*p
, char *buf
)
106 return sprintf(buf
, "0x%x\n", 0);
108 static BRPORT_ATTR(port_id
, S_IRUGO
, show_port_id
, NULL
);
110 static ssize_t
show_port_no(struct vport
*p
, char *buf
)
112 return sprintf(buf
, "0x%x\n", p
->port_no
);
115 static BRPORT_ATTR(port_no
, S_IRUGO
, show_port_no
, NULL
);
117 static ssize_t
show_change_ack(struct vport
*p
, char *buf
)
119 return sprintf(buf
, "%d\n", 0);
121 static BRPORT_ATTR(change_ack
, S_IRUGO
, show_change_ack
, NULL
);
123 static ssize_t
show_config_pending(struct vport
*p
, char *buf
)
125 return sprintf(buf
, "%d\n", 0);
127 static BRPORT_ATTR(config_pending
, S_IRUGO
, show_config_pending
, NULL
);
129 static ssize_t
show_port_state(struct vport
*p
, char *buf
)
131 return sprintf(buf
, "%d\n", 0);
133 static BRPORT_ATTR(state
, S_IRUGO
, show_port_state
, NULL
);
135 static ssize_t
show_message_age_timer(struct vport
*p
, char *buf
)
137 return sprintf(buf
, "%d\n", 0);
139 static BRPORT_ATTR(message_age_timer
, S_IRUGO
, show_message_age_timer
, NULL
);
141 static ssize_t
show_forward_delay_timer(struct vport
*p
, char *buf
)
143 return sprintf(buf
, "%d\n", 0);
145 static BRPORT_ATTR(forward_delay_timer
, S_IRUGO
, show_forward_delay_timer
, NULL
);
147 static ssize_t
show_hold_timer(struct vport
*p
, char *buf
)
149 return sprintf(buf
, "%d\n", 0);
151 static BRPORT_ATTR(hold_timer
, S_IRUGO
, show_hold_timer
, NULL
);
153 static struct brport_attribute
*brport_attrs
[] = {
154 &brport_attr_path_cost
,
155 &brport_attr_priority
,
156 &brport_attr_port_id
,
157 &brport_attr_port_no
,
158 &brport_attr_designated_root
,
159 &brport_attr_designated_bridge
,
160 &brport_attr_designated_port
,
161 &brport_attr_designated_cost
,
163 &brport_attr_change_ack
,
164 &brport_attr_config_pending
,
165 &brport_attr_message_age_timer
,
166 &brport_attr_forward_delay_timer
,
167 &brport_attr_hold_timer
,
171 #define to_vport_attr(_at) container_of(_at, struct brport_attribute, attr)
172 #define to_vport(obj) container_of(obj, struct vport, kobj)
174 static ssize_t
brport_show(struct kobject
*kobj
,
175 struct attribute
*attr
, char *buf
)
177 struct brport_attribute
*brport_attr
= to_vport_attr(attr
);
178 struct vport
*p
= to_vport(kobj
);
180 return brport_attr
->show(p
, buf
);
183 static ssize_t
brport_store(struct kobject
*kobj
,
184 struct attribute
*attr
,
185 const char *buf
, size_t count
)
187 struct vport
*p
= to_vport(kobj
);
188 ssize_t ret
= -EINVAL
;
190 if (!capable(CAP_NET_ADMIN
))
193 pr_warning("%s: xxx writing port parms not supported yet!\n",
199 struct sysfs_ops ovs_brport_sysfs_ops
= {
201 .store
= brport_store
,
205 * Add sysfs entries to ethernet device added to a bridge.
206 * Creates a brport subdirectory with bridge attributes.
207 * Puts symlink in bridge's brport subdirectory
209 int ovs_dp_sysfs_add_if(struct vport
*p
)
211 struct datapath
*dp
= p
->dp
;
212 struct vport
*local_port
= ovs_vport_rtnl(dp
, OVSP_LOCAL
);
213 struct brport_attribute
**a
;
216 /* Create /sys/class/net/<devname>/brport directory. */
217 if (!p
->ops
->get_kobj
)
221 /* Due to bug in 2.6.32 kernel, sysfs_create_group() could panic
222 * in other namespace than init_net. Following check is to avoid it. */
228 err
= kobject_add(&p
->kobj
, p
->ops
->get_kobj(p
),
229 SYSFS_BRIDGE_PORT_ATTR
);
233 /* Create symlink from /sys/class/net/<devname>/brport/bridge to
234 * /sys/class/net/<bridgename>. */
235 err
= sysfs_create_link(&p
->kobj
, local_port
->ops
->get_kobj(local_port
),
236 SYSFS_BRIDGE_PORT_LINK
); /* "bridge" */
240 /* Populate /sys/class/net/<devname>/brport directory with files. */
241 for (a
= brport_attrs
; *a
; ++a
) {
242 err
= sysfs_create_file(&p
->kobj
, &((*a
)->attr
));
247 /* Create symlink from /sys/class/net/<bridgename>/brif/<devname> to
248 * /sys/class/net/<devname>/brport. */
249 err
= sysfs_create_link(&dp
->ifobj
, &p
->kobj
, p
->ops
->get_name(p
));
252 strcpy(p
->linkname
, p
->ops
->get_name(p
));
254 kobject_uevent(&p
->kobj
, KOBJ_ADD
);
259 kobject_del(&p
->kobj
);
265 int ovs_dp_sysfs_del_if(struct vport
*p
)
267 if (p
->linkname
[0]) {
268 sysfs_remove_link(&p
->dp
->ifobj
, p
->linkname
);
269 kobject_uevent(&p
->kobj
, KOBJ_REMOVE
);
270 kobject_del(&p
->kobj
);
271 p
->linkname
[0] = '\0';
275 #endif /* CONFIG_SYSFS */