xenserver: Store XAPI dbcache as XML in interface-reconfigure.
[sliver-openvswitch.git] / datapath / brc_sysfs_if.c
1 /*
2  * Copyright (c) 2009 Nicira Networks.
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
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>
21 #include "brc_sysfs.h"
22 #include "datapath.h"
23
24 #ifdef CONFIG_SYSFS
25
26 struct brport_attribute {
27         struct attribute        attr;
28         ssize_t (*show)(struct net_bridge_port *, char *);
29         ssize_t (*store)(struct net_bridge_port *, unsigned long);
30 };
31
32 #define BRPORT_ATTR(_name,_mode,_show,_store)                   \
33 struct brport_attribute brport_attr_##_name = {                 \
34         .attr = {.name = __stringify(_name),                    \
35                  .mode = _mode,                                 \
36                  .owner = THIS_MODULE, },                       \
37         .show   = _show,                                        \
38         .store  = _store,                                       \
39 };
40
41 static ssize_t show_path_cost(struct net_bridge_port *p, char *buf)
42 {
43 #if 0
44         return sprintf(buf, "%d\n", p->path_cost);
45 #else
46         return sprintf(buf, "%d\n", 0);
47 #endif
48 }
49 static ssize_t store_path_cost(struct net_bridge_port *p, unsigned long v)
50 {
51 #if 0
52         br_stp_set_path_cost(p, v);
53 #endif
54         return 0;
55 }
56 static BRPORT_ATTR(path_cost, S_IRUGO | S_IWUSR,
57                    show_path_cost, store_path_cost);
58
59 static ssize_t show_priority(struct net_bridge_port *p, char *buf)
60 {
61 #if 0
62         return sprintf(buf, "%d\n", p->priority);
63 #else
64         return sprintf(buf, "%d\n", 0);
65 #endif
66 }
67 static ssize_t store_priority(struct net_bridge_port *p, unsigned long v)
68 {
69 #if 0
70         if (v >= (1<<(16-BR_PORT_BITS)))
71                 return -ERANGE;
72         br_stp_set_port_priority(p, v);
73 #endif
74         return 0;
75 }
76 static BRPORT_ATTR(priority, S_IRUGO | S_IWUSR,
77                          show_priority, store_priority);
78
79 static ssize_t show_designated_root(struct net_bridge_port *p, char *buf)
80 {
81 #if 0
82         return br_show_bridge_id(buf, &p->designated_root);
83 #else
84         return sprintf(buf, "0000.010203040506\n");
85 #endif
86 }
87 static BRPORT_ATTR(designated_root, S_IRUGO, show_designated_root, NULL);
88
89 static ssize_t show_designated_bridge(struct net_bridge_port *p, char *buf)
90 {
91 #if 0
92         return br_show_bridge_id(buf, &p->designated_bridge);
93 #else
94         return sprintf(buf, "0000.060504030201\n");
95 #endif
96 }
97 static BRPORT_ATTR(designated_bridge, S_IRUGO, show_designated_bridge, NULL);
98
99 static ssize_t show_designated_port(struct net_bridge_port *p, char *buf)
100 {
101 #if 0
102         return sprintf(buf, "%d\n", p->designated_port);
103 #else
104         return sprintf(buf, "%d\n", 0);
105 #endif
106 }
107 static BRPORT_ATTR(designated_port, S_IRUGO, show_designated_port, NULL);
108
109 static ssize_t show_designated_cost(struct net_bridge_port *p, char *buf)
110 {
111 #if 0
112         return sprintf(buf, "%d\n", p->designated_cost);
113 #else
114         return sprintf(buf, "%d\n", 0);
115 #endif
116 }
117 static BRPORT_ATTR(designated_cost, S_IRUGO, show_designated_cost, NULL);
118
119 static ssize_t show_port_id(struct net_bridge_port *p, char *buf)
120 {
121 #if 0
122         return sprintf(buf, "0x%x\n", p->port_id);
123 #else
124         return sprintf(buf, "0x%x\n", 0);
125 #endif
126 }
127 static BRPORT_ATTR(port_id, S_IRUGO, show_port_id, NULL);
128
129 static ssize_t show_port_no(struct net_bridge_port *p, char *buf)
130 {
131         return sprintf(buf, "0x%x\n", p->port_no);
132 }
133
134 static BRPORT_ATTR(port_no, S_IRUGO, show_port_no, NULL);
135
136 static ssize_t show_change_ack(struct net_bridge_port *p, char *buf)
137 {
138 #if 0
139         return sprintf(buf, "%d\n", p->topology_change_ack);
140 #else
141         return sprintf(buf, "%d\n", 0);
142 #endif
143 }
144 static BRPORT_ATTR(change_ack, S_IRUGO, show_change_ack, NULL);
145
146 static ssize_t show_config_pending(struct net_bridge_port *p, char *buf)
147 {
148 #if 0
149         return sprintf(buf, "%d\n", p->config_pending);
150 #else
151         return sprintf(buf, "%d\n", 0);
152 #endif
153 }
154 static BRPORT_ATTR(config_pending, S_IRUGO, show_config_pending, NULL);
155
156 static ssize_t show_port_state(struct net_bridge_port *p, char *buf)
157 {
158 #if 0
159         return sprintf(buf, "%d\n", p->state);
160 #else
161         return sprintf(buf, "%d\n", 0);
162 #endif
163 }
164 static BRPORT_ATTR(state, S_IRUGO, show_port_state, NULL);
165
166 static ssize_t show_message_age_timer(struct net_bridge_port *p,
167                                             char *buf)
168 {
169 #if 0
170         return sprintf(buf, "%ld\n", br_timer_value(&p->message_age_timer));
171 #else
172         return sprintf(buf, "%d\n", 0);
173 #endif
174 }
175 static BRPORT_ATTR(message_age_timer, S_IRUGO, show_message_age_timer, NULL);
176
177 static ssize_t show_forward_delay_timer(struct net_bridge_port *p,
178                                             char *buf)
179 {
180 #if 0
181         return sprintf(buf, "%ld\n", br_timer_value(&p->forward_delay_timer));
182 #else
183         return sprintf(buf, "%d\n", 0);
184 #endif
185 }
186 static BRPORT_ATTR(forward_delay_timer, S_IRUGO, show_forward_delay_timer, NULL);
187
188 static ssize_t show_hold_timer(struct net_bridge_port *p,
189                                             char *buf)
190 {
191 #if 0
192         return sprintf(buf, "%ld\n", br_timer_value(&p->hold_timer));
193 #else
194         return sprintf(buf, "%d\n", 0);
195 #endif
196 }
197 static BRPORT_ATTR(hold_timer, S_IRUGO, show_hold_timer, NULL);
198
199 static struct brport_attribute *brport_attrs[] = {
200         &brport_attr_path_cost,
201         &brport_attr_priority,
202         &brport_attr_port_id,
203         &brport_attr_port_no,
204         &brport_attr_designated_root,
205         &brport_attr_designated_bridge,
206         &brport_attr_designated_port,
207         &brport_attr_designated_cost,
208         &brport_attr_state,
209         &brport_attr_change_ack,
210         &brport_attr_config_pending,
211         &brport_attr_message_age_timer,
212         &brport_attr_forward_delay_timer,
213         &brport_attr_hold_timer,
214         NULL
215 };
216
217 #define to_brport_attr(_at) container_of(_at, struct brport_attribute, attr)
218 #define to_brport(obj)  container_of(obj, struct net_bridge_port, kobj)
219
220 static ssize_t brport_show(struct kobject * kobj,
221                            struct attribute * attr, char * buf)
222 {
223         struct brport_attribute * brport_attr = to_brport_attr(attr);
224         struct net_bridge_port * p = to_brport(kobj);
225
226         return brport_attr->show(p, buf);
227 }
228
229 static ssize_t brport_store(struct kobject * kobj,
230                             struct attribute * attr,
231                             const char * buf, size_t count)
232 {
233         struct net_bridge_port * p = to_brport(kobj);
234 #if 0
235         struct brport_attribute * brport_attr = to_brport_attr(attr);
236         char *endp;
237         unsigned long val;
238 #endif
239         ssize_t ret = -EINVAL;
240
241         if (!capable(CAP_NET_ADMIN))
242                 return -EPERM;
243
244 #if 0
245         val = simple_strtoul(buf, &endp, 0);
246         if (endp != buf) {
247                 rtnl_lock();
248                 if (p->dev && p->br && brport_attr->store) {
249                         spin_lock_bh(&p->br->lock);
250                         ret = brport_attr->store(p, val);
251                         spin_unlock_bh(&p->br->lock);
252                         if (ret == 0)
253                                 ret = count;
254                 }
255                 rtnl_unlock();
256         }
257 #else
258         printk("%s: xxx writing port parms not supported yet!\n", 
259                dp_name(p->dp));
260 #endif
261         return ret;
262 }
263
264 struct sysfs_ops brport_sysfs_ops = {
265         .show = brport_show,
266         .store = brport_store,
267 };
268
269 static void release_nbp(struct kobject *kobj)
270 {
271         struct net_bridge_port *p
272                 = container_of(kobj, struct net_bridge_port, kobj);
273         kfree(p);
274 }
275
276 struct kobj_type brport_ktype = {
277         .sysfs_ops = &brport_sysfs_ops,
278         .release = release_nbp
279 };
280
281 /*
282  * Add sysfs entries to ethernet device added to a bridge.
283  * Creates a brport subdirectory with bridge attributes.
284  * Puts symlink in bridge's brport subdirectory
285  */
286 int brc_sysfs_add_if(struct net_bridge_port *p)
287 {
288         struct datapath *dp = p->dp;
289         struct brport_attribute **a;
290         int err;
291
292         err = kobject_init_and_add(&p->kobj, &brport_ktype,
293                                    &(p->dev->NETDEV_DEV_MEMBER.kobj),
294                                    SYSFS_BRIDGE_PORT_ATTR);
295         if (err)
296                 goto err;
297
298         err = sysfs_create_link(&p->kobj,
299                                 &dp->ports[ODPP_LOCAL]->dev->NETDEV_DEV_MEMBER.kobj,
300                                 SYSFS_BRIDGE_PORT_LINK);
301         if (err)
302                 goto err_del;
303
304         for (a = brport_attrs; *a; ++a) {
305                 err = sysfs_create_file(&p->kobj, &((*a)->attr));
306                 if (err)
307                         goto err_del;
308         }
309
310 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)
311         err = sysfs_create_link(&dp->ifobj, &p->kobj, p->dev->name);
312 #else
313         err = sysfs_create_link(dp->ifobj, &p->kobj, p->dev->name);
314 #endif
315         if (err)
316                 goto err_del;
317
318         kobject_uevent(&p->kobj, KOBJ_ADD);
319
320         return err;
321
322 err_del:
323         kobject_del(&p->kobj);
324         kobject_put(&p->kobj);
325 err:
326         return err;
327 }
328
329 int brc_sysfs_del_if(struct net_bridge_port *p)
330 {
331         struct net_device *dev = p->dev;
332
333         kobject_uevent(&p->kobj, KOBJ_REMOVE);
334         kobject_del(&p->kobj);
335
336         dev_put(dev);
337
338         kobject_put(&p->kobj);
339
340         return 0;
341 }
342 #endif /* CONFIG_SYSFS */