datapath: Fix coding style issues.
[sliver-openvswitch.git] / datapath / dp_sysfs_if.c
1 /*
2  * Copyright (c) 2009, 2010 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 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
16
17 #include <linux/capability.h>
18 #include <linux/kernel.h>
19 #include <linux/netdevice.h>
20 #include <linux/if_bridge.h>
21 #include <linux/rtnetlink.h>
22
23 #include "datapath.h"
24 #include "dp_sysfs.h"
25 #include "vport.h"
26
27 #ifdef CONFIG_SYSFS
28
29 struct brport_attribute {
30         struct attribute        attr;
31         ssize_t (*show)(struct vport *, char *);
32         ssize_t (*store)(struct vport *, unsigned long);
33 };
34
35 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
36 #define BRPORT_ATTR(_name, _mode, _show, _store)                \
37 struct brport_attribute brport_attr_##_name = {                 \
38         .attr = {.name = __stringify(_name),                    \
39                  .mode = _mode },                               \
40         .show   = _show,                                        \
41         .store  = _store,                                       \
42 };
43 #else
44 #define BRPORT_ATTR(_name, _mode, _show, _store)                \
45 struct brport_attribute brport_attr_##_name = {                 \
46         .attr = {.name = __stringify(_name),                    \
47                  .mode = _mode,                                 \
48                  .owner = THIS_MODULE, },                       \
49         .show   = _show,                                        \
50         .store  = _store,                                       \
51 };
52 #endif
53
54 static ssize_t show_path_cost(struct vport *p, char *buf)
55 {
56         return sprintf(buf, "%d\n", 0);
57 }
58 static ssize_t store_path_cost(struct vport *p, unsigned long v)
59 {
60         return 0;
61 }
62 static BRPORT_ATTR(path_cost, S_IRUGO | S_IWUSR,
63                    show_path_cost, store_path_cost);
64
65 static ssize_t show_priority(struct vport *p, char *buf)
66 {
67         return sprintf(buf, "%d\n", 0);
68 }
69 static ssize_t store_priority(struct vport *p, unsigned long v)
70 {
71         return 0;
72 }
73 static BRPORT_ATTR(priority, S_IRUGO | S_IWUSR,
74                          show_priority, store_priority);
75
76 static ssize_t show_designated_root(struct vport *p, char *buf)
77 {
78         return sprintf(buf, "0000.010203040506\n");
79 }
80 static BRPORT_ATTR(designated_root, S_IRUGO, show_designated_root, NULL);
81
82 static ssize_t show_designated_bridge(struct vport *p, char *buf)
83 {
84         return sprintf(buf, "0000.060504030201\n");
85 }
86 static BRPORT_ATTR(designated_bridge, S_IRUGO, show_designated_bridge, NULL);
87
88 static ssize_t show_designated_port(struct vport *p, char *buf)
89 {
90         return sprintf(buf, "%d\n", 0);
91 }
92 static BRPORT_ATTR(designated_port, S_IRUGO, show_designated_port, NULL);
93
94 static ssize_t show_designated_cost(struct vport *p, char *buf)
95 {
96         return sprintf(buf, "%d\n", 0);
97 }
98 static BRPORT_ATTR(designated_cost, S_IRUGO, show_designated_cost, NULL);
99
100 static ssize_t show_port_id(struct vport *p, char *buf)
101 {
102         return sprintf(buf, "0x%x\n", 0);
103 }
104 static BRPORT_ATTR(port_id, S_IRUGO, show_port_id, NULL);
105
106 static ssize_t show_port_no(struct vport *p, char *buf)
107 {
108         return sprintf(buf, "0x%x\n", p->port_no);
109 }
110
111 static BRPORT_ATTR(port_no, S_IRUGO, show_port_no, NULL);
112
113 static ssize_t show_change_ack(struct vport *p, char *buf)
114 {
115         return sprintf(buf, "%d\n", 0);
116 }
117 static BRPORT_ATTR(change_ack, S_IRUGO, show_change_ack, NULL);
118
119 static ssize_t show_config_pending(struct vport *p, char *buf)
120 {
121         return sprintf(buf, "%d\n", 0);
122 }
123 static BRPORT_ATTR(config_pending, S_IRUGO, show_config_pending, NULL);
124
125 static ssize_t show_port_state(struct vport *p, char *buf)
126 {
127         return sprintf(buf, "%d\n", 0);
128 }
129 static BRPORT_ATTR(state, S_IRUGO, show_port_state, NULL);
130
131 static ssize_t show_message_age_timer(struct vport *p, char *buf)
132 {
133         return sprintf(buf, "%d\n", 0);
134 }
135 static BRPORT_ATTR(message_age_timer, S_IRUGO, show_message_age_timer, NULL);
136
137 static ssize_t show_forward_delay_timer(struct vport *p, char *buf)
138 {
139         return sprintf(buf, "%d\n", 0);
140 }
141 static BRPORT_ATTR(forward_delay_timer, S_IRUGO, show_forward_delay_timer, NULL);
142
143 static ssize_t show_hold_timer(struct vport *p, char *buf)
144 {
145         return sprintf(buf, "%d\n", 0);
146 }
147 static BRPORT_ATTR(hold_timer, S_IRUGO, show_hold_timer, NULL);
148
149 static struct brport_attribute *brport_attrs[] = {
150         &brport_attr_path_cost,
151         &brport_attr_priority,
152         &brport_attr_port_id,
153         &brport_attr_port_no,
154         &brport_attr_designated_root,
155         &brport_attr_designated_bridge,
156         &brport_attr_designated_port,
157         &brport_attr_designated_cost,
158         &brport_attr_state,
159         &brport_attr_change_ack,
160         &brport_attr_config_pending,
161         &brport_attr_message_age_timer,
162         &brport_attr_forward_delay_timer,
163         &brport_attr_hold_timer,
164         NULL
165 };
166
167 #define to_vport_attr(_at) container_of(_at, struct brport_attribute, attr)
168 #define to_vport(obj)   container_of(obj, struct vport, kobj)
169
170 static ssize_t brport_show(struct kobject *kobj,
171                            struct attribute *attr, char *buf)
172 {
173         struct brport_attribute *brport_attr = to_vport_attr(attr);
174         struct vport *p = to_vport(kobj);
175
176         return brport_attr->show(p, buf);
177 }
178
179 static ssize_t brport_store(struct kobject *kobj,
180                             struct attribute *attr,
181                             const char *buf, size_t count)
182 {
183         struct vport *p = to_vport(kobj);
184         ssize_t ret = -EINVAL;
185
186         if (!capable(CAP_NET_ADMIN))
187                 return -EPERM;
188
189         pr_warning("%s: xxx writing port parms not supported yet!\n",
190                    dp_name(p->dp));
191
192         return ret;
193 }
194
195 const struct sysfs_ops brport_sysfs_ops = {
196         .show = brport_show,
197         .store = brport_store,
198 };
199
200 /*
201  * Add sysfs entries to ethernet device added to a bridge.
202  * Creates a brport subdirectory with bridge attributes.
203  * Puts symlink in bridge's brport subdirectory
204  */
205 int dp_sysfs_add_if(struct vport *p)
206 {
207         struct kobject *kobj = vport_get_kobj(p);
208         struct datapath *dp = p->dp;
209         struct brport_attribute **a;
210         int err;
211
212         /* Create /sys/class/net/<devname>/brport directory. */
213         if (!kobj)
214                 return -ENOENT;
215
216         err = kobject_add(&p->kobj, kobj, SYSFS_BRIDGE_PORT_ATTR);
217         if (err)
218                 goto err;
219
220         /* Create symlink from /sys/class/net/<devname>/brport/bridge to
221          * /sys/class/net/<bridgename>. */
222         err = sysfs_create_link(&p->kobj,
223                 vport_get_kobj(rtnl_dereference(dp->ports[OVSP_LOCAL])),
224                 SYSFS_BRIDGE_PORT_LINK); /* "bridge" */
225         if (err)
226                 goto err_del;
227
228         /* Populate /sys/class/net/<devname>/brport directory with files. */
229         for (a = brport_attrs; *a; ++a) {
230                 err = sysfs_create_file(&p->kobj, &((*a)->attr));
231                 if (err)
232                         goto err_del;
233         }
234
235         /* Create symlink from /sys/class/net/<bridgename>/brif/<devname> to
236          * /sys/class/net/<devname>/brport.  */
237         err = sysfs_create_link(&dp->ifobj, &p->kobj, vport_get_name(p));
238         if (err)
239                 goto err_del;
240         strcpy(p->linkname, vport_get_name(p));
241
242         kobject_uevent(&p->kobj, KOBJ_ADD);
243
244         return 0;
245
246 err_del:
247         kobject_del(&p->kobj);
248 err:
249         p->linkname[0] = 0;
250         return err;
251 }
252
253 int dp_sysfs_del_if(struct vport *p)
254 {
255         if (p->linkname[0]) {
256                 sysfs_remove_link(&p->dp->ifobj, p->linkname);
257                 kobject_uevent(&p->kobj, KOBJ_REMOVE);
258                 kobject_del(&p->kobj);
259                 p->linkname[0] = '\0';
260         }
261         return 0;
262 }
263 #endif /* CONFIG_SYSFS */