]> git.proxmox.com Git - ovs.git/blame - datapath/dp_sysfs_if.c
datapath: Add generic virtual port layer.
[ovs.git] / datapath / dp_sysfs_if.c
CommitLineData
a14bc59f 1/*
f2459fe7 2 * Copyright (c) 2009, 2010 Nicira Networks.
a14bc59f
BP
3 * Distributed under the terms of the GNU GPL version 2.
4 *
5 * Significant portions of this file may be copied from parts of the Linux
6 * kernel, by Linus Torvalds and others.
7 */
8
064af421
BP
9/*
10 * Sysfs attributes of bridge ports for Open vSwitch
11 *
12 * This has been shamelessly copied from the kernel sources.
13 */
14
15#include <linux/capability.h>
16#include <linux/kernel.h>
17#include <linux/netdevice.h>
18#include <linux/if_bridge.h>
19#include <linux/rtnetlink.h>
20#include <linux/spinlock.h>
f2459fe7 21
064af421 22#include "datapath.h"
f2459fe7
JG
23#include "dp_sysfs.h"
24#include "vport.h"
064af421 25
806e39cf 26#ifdef CONFIG_SYSFS
064af421
BP
27
28struct brport_attribute {
29 struct attribute attr;
f2459fe7
JG
30 ssize_t (*show)(struct dp_port *, char *);
31 ssize_t (*store)(struct dp_port *, unsigned long);
064af421
BP
32};
33
34#define BRPORT_ATTR(_name,_mode,_show,_store) \
35struct brport_attribute brport_attr_##_name = { \
36 .attr = {.name = __stringify(_name), \
37 .mode = _mode, \
38 .owner = THIS_MODULE, }, \
39 .show = _show, \
40 .store = _store, \
41};
42
f2459fe7 43static ssize_t show_path_cost(struct dp_port *p, char *buf)
064af421
BP
44{
45#if 0
46 return sprintf(buf, "%d\n", p->path_cost);
47#else
48 return sprintf(buf, "%d\n", 0);
49#endif
50}
f2459fe7 51static ssize_t store_path_cost(struct dp_port *p, unsigned long v)
064af421
BP
52{
53#if 0
54 br_stp_set_path_cost(p, v);
55#endif
56 return 0;
57}
58static BRPORT_ATTR(path_cost, S_IRUGO | S_IWUSR,
59 show_path_cost, store_path_cost);
60
f2459fe7 61static ssize_t show_priority(struct dp_port *p, char *buf)
064af421
BP
62{
63#if 0
64 return sprintf(buf, "%d\n", p->priority);
65#else
66 return sprintf(buf, "%d\n", 0);
67#endif
68}
f2459fe7 69static ssize_t store_priority(struct dp_port *p, unsigned long v)
064af421
BP
70{
71#if 0
72 if (v >= (1<<(16-BR_PORT_BITS)))
73 return -ERANGE;
74 br_stp_set_port_priority(p, v);
75#endif
76 return 0;
77}
78static BRPORT_ATTR(priority, S_IRUGO | S_IWUSR,
79 show_priority, store_priority);
80
f2459fe7 81static ssize_t show_designated_root(struct dp_port *p, char *buf)
064af421
BP
82{
83#if 0
84 return br_show_bridge_id(buf, &p->designated_root);
85#else
86 return sprintf(buf, "0000.010203040506\n");
87#endif
88}
89static BRPORT_ATTR(designated_root, S_IRUGO, show_designated_root, NULL);
90
f2459fe7 91static ssize_t show_designated_bridge(struct dp_port *p, char *buf)
064af421
BP
92{
93#if 0
94 return br_show_bridge_id(buf, &p->designated_bridge);
95#else
96 return sprintf(buf, "0000.060504030201\n");
97#endif
98}
99static BRPORT_ATTR(designated_bridge, S_IRUGO, show_designated_bridge, NULL);
100
f2459fe7 101static ssize_t show_designated_port(struct dp_port *p, char *buf)
064af421
BP
102{
103#if 0
104 return sprintf(buf, "%d\n", p->designated_port);
105#else
106 return sprintf(buf, "%d\n", 0);
107#endif
108}
109static BRPORT_ATTR(designated_port, S_IRUGO, show_designated_port, NULL);
110
f2459fe7 111static ssize_t show_designated_cost(struct dp_port *p, char *buf)
064af421
BP
112{
113#if 0
114 return sprintf(buf, "%d\n", p->designated_cost);
115#else
116 return sprintf(buf, "%d\n", 0);
117#endif
118}
119static BRPORT_ATTR(designated_cost, S_IRUGO, show_designated_cost, NULL);
120
f2459fe7 121static ssize_t show_port_id(struct dp_port *p, char *buf)
064af421
BP
122{
123#if 0
124 return sprintf(buf, "0x%x\n", p->port_id);
125#else
126 return sprintf(buf, "0x%x\n", 0);
127#endif
128}
129static BRPORT_ATTR(port_id, S_IRUGO, show_port_id, NULL);
130
f2459fe7 131static ssize_t show_port_no(struct dp_port *p, char *buf)
064af421
BP
132{
133 return sprintf(buf, "0x%x\n", p->port_no);
134}
135
136static BRPORT_ATTR(port_no, S_IRUGO, show_port_no, NULL);
137
f2459fe7 138static ssize_t show_change_ack(struct dp_port *p, char *buf)
064af421
BP
139{
140#if 0
141 return sprintf(buf, "%d\n", p->topology_change_ack);
142#else
143 return sprintf(buf, "%d\n", 0);
144#endif
145}
146static BRPORT_ATTR(change_ack, S_IRUGO, show_change_ack, NULL);
147
f2459fe7 148static ssize_t show_config_pending(struct dp_port *p, char *buf)
064af421
BP
149{
150#if 0
151 return sprintf(buf, "%d\n", p->config_pending);
152#else
153 return sprintf(buf, "%d\n", 0);
154#endif
155}
156static BRPORT_ATTR(config_pending, S_IRUGO, show_config_pending, NULL);
157
f2459fe7 158static ssize_t show_port_state(struct dp_port *p, char *buf)
064af421
BP
159{
160#if 0
161 return sprintf(buf, "%d\n", p->state);
162#else
163 return sprintf(buf, "%d\n", 0);
164#endif
165}
166static BRPORT_ATTR(state, S_IRUGO, show_port_state, NULL);
167
f2459fe7 168static ssize_t show_message_age_timer(struct dp_port *p,
064af421
BP
169 char *buf)
170{
171#if 0
172 return sprintf(buf, "%ld\n", br_timer_value(&p->message_age_timer));
173#else
174 return sprintf(buf, "%d\n", 0);
175#endif
176}
177static BRPORT_ATTR(message_age_timer, S_IRUGO, show_message_age_timer, NULL);
178
f2459fe7 179static ssize_t show_forward_delay_timer(struct dp_port *p,
064af421
BP
180 char *buf)
181{
182#if 0
183 return sprintf(buf, "%ld\n", br_timer_value(&p->forward_delay_timer));
184#else
185 return sprintf(buf, "%d\n", 0);
186#endif
187}
188static BRPORT_ATTR(forward_delay_timer, S_IRUGO, show_forward_delay_timer, NULL);
189
f2459fe7 190static ssize_t show_hold_timer(struct dp_port *p,
064af421
BP
191 char *buf)
192{
193#if 0
194 return sprintf(buf, "%ld\n", br_timer_value(&p->hold_timer));
195#else
196 return sprintf(buf, "%d\n", 0);
197#endif
198}
199static BRPORT_ATTR(hold_timer, S_IRUGO, show_hold_timer, NULL);
200
201static struct brport_attribute *brport_attrs[] = {
202 &brport_attr_path_cost,
203 &brport_attr_priority,
204 &brport_attr_port_id,
205 &brport_attr_port_no,
206 &brport_attr_designated_root,
207 &brport_attr_designated_bridge,
208 &brport_attr_designated_port,
209 &brport_attr_designated_cost,
210 &brport_attr_state,
211 &brport_attr_change_ack,
212 &brport_attr_config_pending,
213 &brport_attr_message_age_timer,
214 &brport_attr_forward_delay_timer,
215 &brport_attr_hold_timer,
216 NULL
217};
218
219#define to_brport_attr(_at) container_of(_at, struct brport_attribute, attr)
f2459fe7 220#define to_brport(obj) container_of(obj, struct dp_port, kobj)
064af421
BP
221
222static ssize_t brport_show(struct kobject * kobj,
223 struct attribute * attr, char * buf)
224{
225 struct brport_attribute * brport_attr = to_brport_attr(attr);
f2459fe7 226 struct dp_port * p = to_brport(kobj);
064af421
BP
227
228 return brport_attr->show(p, buf);
229}
230
231static ssize_t brport_store(struct kobject * kobj,
232 struct attribute * attr,
233 const char * buf, size_t count)
234{
f2459fe7 235 struct dp_port * p = to_brport(kobj);
064af421
BP
236#if 0
237 struct brport_attribute * brport_attr = to_brport_attr(attr);
238 char *endp;
239 unsigned long val;
240#endif
241 ssize_t ret = -EINVAL;
242
243 if (!capable(CAP_NET_ADMIN))
244 return -EPERM;
245
246#if 0
247 val = simple_strtoul(buf, &endp, 0);
248 if (endp != buf) {
249 rtnl_lock();
250 if (p->dev && p->br && brport_attr->store) {
251 spin_lock_bh(&p->br->lock);
252 ret = brport_attr->store(p, val);
253 spin_unlock_bh(&p->br->lock);
254 if (ret == 0)
255 ret = count;
256 }
257 rtnl_unlock();
258 }
259#else
260 printk("%s: xxx writing port parms not supported yet!\n",
261 dp_name(p->dp));
262#endif
263 return ret;
264}
265
266struct sysfs_ops brport_sysfs_ops = {
267 .show = brport_show,
268 .store = brport_store,
269};
270
064af421
BP
271/*
272 * Add sysfs entries to ethernet device added to a bridge.
273 * Creates a brport subdirectory with bridge attributes.
274 * Puts symlink in bridge's brport subdirectory
275 */
f2459fe7 276int dp_sysfs_add_if(struct dp_port *p)
064af421 277{
f2459fe7 278 struct kobject *kobj = vport_get_kobj(p->vport);
064af421
BP
279 struct datapath *dp = p->dp;
280 struct brport_attribute **a;
281 int err;
282
5e93df1c 283 /* Create /sys/class/net/<devname>/brport directory. */
f2459fe7
JG
284 if (!kobj)
285 return -ENOENT;
286
287 err = kobject_add(&p->kobj, kobj, SYSFS_BRIDGE_PORT_ATTR);
064af421 288 if (err)
806e39cf 289 goto err;
064af421 290
5e93df1c
BP
291 /* Create symlink from /sys/class/net/<devname>/brport/bridge to
292 * /sys/class/net/<bridgename>. */
f2459fe7 293 err = sysfs_create_link(&p->kobj, vport_get_kobj(dp->ports[ODPP_LOCAL]->vport),
5e93df1c 294 SYSFS_BRIDGE_PORT_LINK); /* "bridge" */
064af421
BP
295 if (err)
296 goto err_del;
297
5e93df1c 298 /* Populate /sys/class/net/<devname>/brport directory with files. */
064af421
BP
299 for (a = brport_attrs; *a; ++a) {
300 err = sysfs_create_file(&p->kobj, &((*a)->attr));
301 if (err)
302 goto err_del;
303 }
304
5e93df1c
BP
305 /* Create symlink from /sys/class/net/<bridgename>/brif/<devname> to
306 * /sys/class/net/<devname>/brport. */
f2459fe7 307 err = sysfs_create_link(&dp->ifobj, &p->kobj, vport_get_name(p->vport));
064af421
BP
308 if (err)
309 goto err_del;
f2459fe7 310 strcpy(p->linkname, vport_get_name(p->vport));
064af421
BP
311
312 kobject_uevent(&p->kobj, KOBJ_ADD);
313
8fef8c71 314 return 0;
064af421
BP
315
316err_del:
317 kobject_del(&p->kobj);
806e39cf 318err:
8fef8c71 319 p->linkname[0] = 0;
064af421
BP
320 return err;
321}
322
f2459fe7 323int dp_sysfs_del_if(struct dp_port *p)
064af421 324{
0515ceb3
BP
325 if (p->linkname[0]) {
326 sysfs_remove_link(&p->dp->ifobj, p->linkname);
58c342f6
BP
327 kobject_uevent(&p->kobj, KOBJ_REMOVE);
328 kobject_del(&p->kobj);
8fef8c71 329 p->linkname[0] = '\0';
58c342f6 330 }
064af421
BP
331 return 0;
332}
806e39cf 333#endif /* CONFIG_SYSFS */