blob: f14816b80b804054ea0f36805f53f5c3ff805650 [file] [log] [blame]
Jesse Grossccb13522011-10-25 19:26:31 -07001/*
Raju Subramaniancaf2ee12012-05-03 18:55:23 -07002 * Copyright (c) 2007-2012 Nicira, Inc.
Jesse Grossccb13522011-10-25 19:26:31 -07003 *
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.
7 *
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.
12 *
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
16 * 02110-1301, USA
17 */
18
19#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
20
21#include <linux/init.h>
22#include <linux/module.h>
23#include <linux/if_arp.h>
24#include <linux/if_vlan.h>
25#include <linux/in.h>
26#include <linux/ip.h>
27#include <linux/jhash.h>
28#include <linux/delay.h>
29#include <linux/time.h>
30#include <linux/etherdevice.h>
31#include <linux/genetlink.h>
32#include <linux/kernel.h>
33#include <linux/kthread.h>
34#include <linux/mutex.h>
35#include <linux/percpu.h>
36#include <linux/rcupdate.h>
37#include <linux/tcp.h>
38#include <linux/udp.h>
Jesse Grossccb13522011-10-25 19:26:31 -070039#include <linux/ethtool.h>
40#include <linux/wait.h>
Jesse Grossccb13522011-10-25 19:26:31 -070041#include <asm/div64.h>
42#include <linux/highmem.h>
43#include <linux/netfilter_bridge.h>
44#include <linux/netfilter_ipv4.h>
45#include <linux/inetdevice.h>
46#include <linux/list.h>
Pravin B Shelar8e4e1712013-04-15 13:23:03 -070047#include <linux/lockdep.h>
Jesse Grossccb13522011-10-25 19:26:31 -070048#include <linux/openvswitch.h>
49#include <linux/rculist.h>
50#include <linux/dmi.h>
51#include <linux/workqueue.h>
52#include <net/genetlink.h>
Pravin B Shelar46df7b82012-02-22 19:58:59 -080053#include <net/net_namespace.h>
54#include <net/netns/generic.h>
Jesse Grossccb13522011-10-25 19:26:31 -070055
56#include "datapath.h"
57#include "flow.h"
58#include "vport-internal_dev.h"
Thomas Grafcff63a52013-04-29 13:06:41 +000059#include "vport-netdev.h"
Jesse Grossccb13522011-10-25 19:26:31 -070060
Pravin B Shelar46df7b82012-02-22 19:58:59 -080061
62#define REHASH_FLOW_INTERVAL (10 * 60 * HZ)
63static void rehash_flow_table(struct work_struct *work);
64static DECLARE_DELAYED_WORK(rehash_flow_wq, rehash_flow_table);
65
Pravin B Shelar8e4e1712013-04-15 13:23:03 -070066int ovs_net_id __read_mostly;
67
Thomas Grafed661182013-03-29 14:46:50 +010068static void ovs_notify(struct sk_buff *skb, struct genl_info *info,
69 struct genl_multicast_group *grp)
70{
71 genl_notify(skb, genl_info_net(info), info->snd_portid,
72 grp->id, info->nlhdr, GFP_KERNEL);
73}
74
Pravin B Shelar46df7b82012-02-22 19:58:59 -080075/**
Jesse Grossccb13522011-10-25 19:26:31 -070076 * DOC: Locking:
77 *
Pravin B Shelar8e4e1712013-04-15 13:23:03 -070078 * All writes e.g. Writes to device state (add/remove datapath, port, set
79 * operations on vports, etc.), Writes to other state (flow table
80 * modifications, set miscellaneous datapath parameters, etc.) are protected
81 * by ovs_lock.
Jesse Grossccb13522011-10-25 19:26:31 -070082 *
83 * Reads are protected by RCU.
84 *
85 * There are a few special cases (mostly stats) that have their own
86 * synchronization but they nest under all of above and don't interact with
87 * each other.
Pravin B Shelar8e4e1712013-04-15 13:23:03 -070088 *
89 * The RTNL lock nests inside ovs_mutex.
Jesse Grossccb13522011-10-25 19:26:31 -070090 */
91
Pravin B Shelar8e4e1712013-04-15 13:23:03 -070092static DEFINE_MUTEX(ovs_mutex);
93
94void ovs_lock(void)
95{
96 mutex_lock(&ovs_mutex);
97}
98
99void ovs_unlock(void)
100{
101 mutex_unlock(&ovs_mutex);
102}
103
104#ifdef CONFIG_LOCKDEP
105int lockdep_ovsl_is_held(void)
106{
107 if (debug_locks)
108 return lockdep_is_held(&ovs_mutex);
109 else
110 return 1;
111}
112#endif
113
Jesse Grossccb13522011-10-25 19:26:31 -0700114static struct vport *new_vport(const struct vport_parms *);
Pravin B Shelar46df7b82012-02-22 19:58:59 -0800115static int queue_gso_packets(struct net *, int dp_ifindex, struct sk_buff *,
Jesse Grossccb13522011-10-25 19:26:31 -0700116 const struct dp_upcall_info *);
Pravin B Shelar46df7b82012-02-22 19:58:59 -0800117static int queue_userspace_packet(struct net *, int dp_ifindex,
118 struct sk_buff *,
Jesse Grossccb13522011-10-25 19:26:31 -0700119 const struct dp_upcall_info *);
120
Pravin B Shelar8e4e1712013-04-15 13:23:03 -0700121/* Must be called with rcu_read_lock or ovs_mutex. */
Pravin B Shelar46df7b82012-02-22 19:58:59 -0800122static struct datapath *get_dp(struct net *net, int dp_ifindex)
Jesse Grossccb13522011-10-25 19:26:31 -0700123{
124 struct datapath *dp = NULL;
125 struct net_device *dev;
126
127 rcu_read_lock();
Pravin B Shelar46df7b82012-02-22 19:58:59 -0800128 dev = dev_get_by_index_rcu(net, dp_ifindex);
Jesse Grossccb13522011-10-25 19:26:31 -0700129 if (dev) {
130 struct vport *vport = ovs_internal_dev_get_vport(dev);
131 if (vport)
132 dp = vport->dp;
133 }
134 rcu_read_unlock();
135
136 return dp;
137}
138
Pravin B Shelar8e4e1712013-04-15 13:23:03 -0700139/* Must be called with rcu_read_lock or ovs_mutex. */
Jesse Grossccb13522011-10-25 19:26:31 -0700140const char *ovs_dp_name(const struct datapath *dp)
141{
Pravin B Shelar8e4e1712013-04-15 13:23:03 -0700142 struct vport *vport = ovs_vport_ovsl_rcu(dp, OVSP_LOCAL);
Jesse Grossccb13522011-10-25 19:26:31 -0700143 return vport->ops->get_name(vport);
144}
145
146static int get_dpifindex(struct datapath *dp)
147{
148 struct vport *local;
149 int ifindex;
150
151 rcu_read_lock();
152
Pravin B Shelar15eac2a2012-08-23 12:40:54 -0700153 local = ovs_vport_rcu(dp, OVSP_LOCAL);
Jesse Grossccb13522011-10-25 19:26:31 -0700154 if (local)
Thomas Grafcff63a52013-04-29 13:06:41 +0000155 ifindex = netdev_vport_priv(local)->dev->ifindex;
Jesse Grossccb13522011-10-25 19:26:31 -0700156 else
157 ifindex = 0;
158
159 rcu_read_unlock();
160
161 return ifindex;
162}
163
164static void destroy_dp_rcu(struct rcu_head *rcu)
165{
166 struct datapath *dp = container_of(rcu, struct datapath, rcu);
167
168 ovs_flow_tbl_destroy((__force struct flow_table *)dp->table);
169 free_percpu(dp->stats_percpu);
Pravin B Shelar46df7b82012-02-22 19:58:59 -0800170 release_net(ovs_dp_get_net(dp));
Pravin B Shelar15eac2a2012-08-23 12:40:54 -0700171 kfree(dp->ports);
Jesse Grossccb13522011-10-25 19:26:31 -0700172 kfree(dp);
173}
174
Pravin B Shelar15eac2a2012-08-23 12:40:54 -0700175static struct hlist_head *vport_hash_bucket(const struct datapath *dp,
176 u16 port_no)
177{
178 return &dp->ports[port_no & (DP_VPORT_HASH_BUCKETS - 1)];
179}
180
181struct vport *ovs_lookup_vport(const struct datapath *dp, u16 port_no)
182{
183 struct vport *vport;
Pravin B Shelar15eac2a2012-08-23 12:40:54 -0700184 struct hlist_head *head;
185
186 head = vport_hash_bucket(dp, port_no);
Sasha Levinb67bfe02013-02-27 17:06:00 -0800187 hlist_for_each_entry_rcu(vport, head, dp_hash_node) {
Pravin B Shelar15eac2a2012-08-23 12:40:54 -0700188 if (vport->port_no == port_no)
189 return vport;
190 }
191 return NULL;
192}
193
Pravin B Shelar8e4e1712013-04-15 13:23:03 -0700194/* Called with ovs_mutex. */
Jesse Grossccb13522011-10-25 19:26:31 -0700195static struct vport *new_vport(const struct vport_parms *parms)
196{
197 struct vport *vport;
198
199 vport = ovs_vport_add(parms);
200 if (!IS_ERR(vport)) {
201 struct datapath *dp = parms->dp;
Pravin B Shelar15eac2a2012-08-23 12:40:54 -0700202 struct hlist_head *head = vport_hash_bucket(dp, vport->port_no);
Jesse Grossccb13522011-10-25 19:26:31 -0700203
Pravin B Shelar15eac2a2012-08-23 12:40:54 -0700204 hlist_add_head_rcu(&vport->dp_hash_node, head);
Jesse Grossccb13522011-10-25 19:26:31 -0700205 }
Jesse Grossccb13522011-10-25 19:26:31 -0700206 return vport;
207}
208
Jesse Grossccb13522011-10-25 19:26:31 -0700209void ovs_dp_detach_port(struct vport *p)
210{
Pravin B Shelar8e4e1712013-04-15 13:23:03 -0700211 ASSERT_OVSL();
Jesse Grossccb13522011-10-25 19:26:31 -0700212
213 /* First drop references to device. */
Pravin B Shelar15eac2a2012-08-23 12:40:54 -0700214 hlist_del_rcu(&p->dp_hash_node);
Jesse Grossccb13522011-10-25 19:26:31 -0700215
216 /* Then destroy it. */
217 ovs_vport_del(p);
218}
219
220/* Must be called with rcu_read_lock. */
221void ovs_dp_process_received_packet(struct vport *p, struct sk_buff *skb)
222{
223 struct datapath *dp = p->dp;
224 struct sw_flow *flow;
225 struct dp_stats_percpu *stats;
226 struct sw_flow_key key;
227 u64 *stats_counter;
228 int error;
229 int key_len;
230
Shan Wei404f2f12012-11-13 09:52:25 +0800231 stats = this_cpu_ptr(dp->stats_percpu);
Jesse Grossccb13522011-10-25 19:26:31 -0700232
233 /* Extract flow from 'skb' into 'key'. */
234 error = ovs_flow_extract(skb, p->port_no, &key, &key_len);
235 if (unlikely(error)) {
236 kfree_skb(skb);
237 return;
238 }
239
240 /* Look up flow. */
241 flow = ovs_flow_tbl_lookup(rcu_dereference(dp->table), &key, key_len);
242 if (unlikely(!flow)) {
243 struct dp_upcall_info upcall;
244
245 upcall.cmd = OVS_PACKET_CMD_MISS;
246 upcall.key = &key;
247 upcall.userdata = NULL;
Eric W. Biederman15e47302012-09-07 20:12:54 +0000248 upcall.portid = p->upcall_portid;
Jesse Grossccb13522011-10-25 19:26:31 -0700249 ovs_dp_upcall(dp, skb, &upcall);
250 consume_skb(skb);
251 stats_counter = &stats->n_missed;
252 goto out;
253 }
254
255 OVS_CB(skb)->flow = flow;
256
257 stats_counter = &stats->n_hit;
258 ovs_flow_used(OVS_CB(skb)->flow, skb);
259 ovs_execute_actions(dp, skb);
260
261out:
262 /* Update datapath statistics. */
263 u64_stats_update_begin(&stats->sync);
264 (*stats_counter)++;
265 u64_stats_update_end(&stats->sync);
266}
267
268static struct genl_family dp_packet_genl_family = {
269 .id = GENL_ID_GENERATE,
270 .hdrsize = sizeof(struct ovs_header),
271 .name = OVS_PACKET_FAMILY,
272 .version = OVS_PACKET_VERSION,
Pravin B Shelar46df7b82012-02-22 19:58:59 -0800273 .maxattr = OVS_PACKET_ATTR_MAX,
Pravin B Shelar3a4e0d62013-04-23 07:48:48 +0000274 .netnsok = true,
275 .parallel_ops = true,
Jesse Grossccb13522011-10-25 19:26:31 -0700276};
277
278int ovs_dp_upcall(struct datapath *dp, struct sk_buff *skb,
Pravin B Shelar46df7b82012-02-22 19:58:59 -0800279 const struct dp_upcall_info *upcall_info)
Jesse Grossccb13522011-10-25 19:26:31 -0700280{
281 struct dp_stats_percpu *stats;
282 int dp_ifindex;
283 int err;
284
Eric W. Biederman15e47302012-09-07 20:12:54 +0000285 if (upcall_info->portid == 0) {
Jesse Grossccb13522011-10-25 19:26:31 -0700286 err = -ENOTCONN;
287 goto err;
288 }
289
290 dp_ifindex = get_dpifindex(dp);
291 if (!dp_ifindex) {
292 err = -ENODEV;
293 goto err;
294 }
295
296 if (!skb_is_gso(skb))
Pravin B Shelar46df7b82012-02-22 19:58:59 -0800297 err = queue_userspace_packet(ovs_dp_get_net(dp), dp_ifindex, skb, upcall_info);
Jesse Grossccb13522011-10-25 19:26:31 -0700298 else
Pravin B Shelar46df7b82012-02-22 19:58:59 -0800299 err = queue_gso_packets(ovs_dp_get_net(dp), dp_ifindex, skb, upcall_info);
Jesse Grossccb13522011-10-25 19:26:31 -0700300 if (err)
301 goto err;
302
303 return 0;
304
305err:
Shan Wei404f2f12012-11-13 09:52:25 +0800306 stats = this_cpu_ptr(dp->stats_percpu);
Jesse Grossccb13522011-10-25 19:26:31 -0700307
308 u64_stats_update_begin(&stats->sync);
309 stats->n_lost++;
310 u64_stats_update_end(&stats->sync);
311
312 return err;
313}
314
Pravin B Shelar46df7b82012-02-22 19:58:59 -0800315static int queue_gso_packets(struct net *net, int dp_ifindex,
316 struct sk_buff *skb,
Jesse Grossccb13522011-10-25 19:26:31 -0700317 const struct dp_upcall_info *upcall_info)
318{
Ben Pfaffa1b5d0d2012-07-20 14:47:54 -0700319 unsigned short gso_type = skb_shinfo(skb)->gso_type;
Jesse Grossccb13522011-10-25 19:26:31 -0700320 struct dp_upcall_info later_info;
321 struct sw_flow_key later_key;
322 struct sk_buff *segs, *nskb;
323 int err;
324
Cong Wang12b00042013-02-05 16:36:38 +0000325 segs = __skb_gso_segment(skb, NETIF_F_SG | NETIF_F_HW_CSUM, false);
Pravin B Shelar92e5dfc2012-07-20 14:46:29 -0700326 if (IS_ERR(segs))
327 return PTR_ERR(segs);
Jesse Grossccb13522011-10-25 19:26:31 -0700328
329 /* Queue all of the segments. */
330 skb = segs;
331 do {
Pravin B Shelar46df7b82012-02-22 19:58:59 -0800332 err = queue_userspace_packet(net, dp_ifindex, skb, upcall_info);
Jesse Grossccb13522011-10-25 19:26:31 -0700333 if (err)
334 break;
335
Ben Pfaffa1b5d0d2012-07-20 14:47:54 -0700336 if (skb == segs && gso_type & SKB_GSO_UDP) {
Jesse Grossccb13522011-10-25 19:26:31 -0700337 /* The initial flow key extracted by ovs_flow_extract()
338 * in this case is for a first fragment, so we need to
339 * properly mark later fragments.
340 */
341 later_key = *upcall_info->key;
342 later_key.ip.frag = OVS_FRAG_TYPE_LATER;
343
344 later_info = *upcall_info;
345 later_info.key = &later_key;
346 upcall_info = &later_info;
347 }
348 } while ((skb = skb->next));
349
350 /* Free all of the segments. */
351 skb = segs;
352 do {
353 nskb = skb->next;
354 if (err)
355 kfree_skb(skb);
356 else
357 consume_skb(skb);
358 } while ((skb = nskb));
359 return err;
360}
361
Thomas Grafc3ff8cf2013-03-29 14:46:49 +0100362static size_t key_attr_size(void)
363{
364 return nla_total_size(4) /* OVS_KEY_ATTR_PRIORITY */
365 + nla_total_size(4) /* OVS_KEY_ATTR_IN_PORT */
366 + nla_total_size(4) /* OVS_KEY_ATTR_SKB_MARK */
367 + nla_total_size(12) /* OVS_KEY_ATTR_ETHERNET */
368 + nla_total_size(2) /* OVS_KEY_ATTR_ETHERTYPE */
369 + nla_total_size(4) /* OVS_KEY_ATTR_8021Q */
370 + nla_total_size(0) /* OVS_KEY_ATTR_ENCAP */
371 + nla_total_size(2) /* OVS_KEY_ATTR_ETHERTYPE */
372 + nla_total_size(40) /* OVS_KEY_ATTR_IPV6 */
373 + nla_total_size(2) /* OVS_KEY_ATTR_ICMPV6 */
374 + nla_total_size(28); /* OVS_KEY_ATTR_ND */
375}
376
377static size_t upcall_msg_size(const struct sk_buff *skb,
378 const struct nlattr *userdata)
379{
380 size_t size = NLMSG_ALIGN(sizeof(struct ovs_header))
381 + nla_total_size(skb->len) /* OVS_PACKET_ATTR_PACKET */
382 + nla_total_size(key_attr_size()); /* OVS_PACKET_ATTR_KEY */
383
384 /* OVS_PACKET_ATTR_USERDATA */
385 if (userdata)
386 size += NLA_ALIGN(userdata->nla_len);
387
388 return size;
389}
390
Pravin B Shelar46df7b82012-02-22 19:58:59 -0800391static int queue_userspace_packet(struct net *net, int dp_ifindex,
392 struct sk_buff *skb,
Jesse Grossccb13522011-10-25 19:26:31 -0700393 const struct dp_upcall_info *upcall_info)
394{
395 struct ovs_header *upcall;
396 struct sk_buff *nskb = NULL;
397 struct sk_buff *user_skb; /* to be queued to userspace */
398 struct nlattr *nla;
Jesse Grossccb13522011-10-25 19:26:31 -0700399 int err;
400
401 if (vlan_tx_tag_present(skb)) {
402 nskb = skb_clone(skb, GFP_ATOMIC);
403 if (!nskb)
404 return -ENOMEM;
405
Patrick McHardy86a9bad2013-04-19 02:04:30 +0000406 nskb = __vlan_put_tag(nskb, nskb->vlan_proto, vlan_tx_tag_get(nskb));
Dan Carpenter8aa51d62012-05-13 08:44:18 +0000407 if (!nskb)
Jesse Grossccb13522011-10-25 19:26:31 -0700408 return -ENOMEM;
409
410 nskb->vlan_tci = 0;
411 skb = nskb;
412 }
413
414 if (nla_attr_size(skb->len) > USHRT_MAX) {
415 err = -EFBIG;
416 goto out;
417 }
418
Thomas Grafc3ff8cf2013-03-29 14:46:49 +0100419 user_skb = genlmsg_new(upcall_msg_size(skb, upcall_info->userdata), GFP_ATOMIC);
Jesse Grossccb13522011-10-25 19:26:31 -0700420 if (!user_skb) {
421 err = -ENOMEM;
422 goto out;
423 }
424
425 upcall = genlmsg_put(user_skb, 0, 0, &dp_packet_genl_family,
426 0, upcall_info->cmd);
427 upcall->dp_ifindex = dp_ifindex;
428
429 nla = nla_nest_start(user_skb, OVS_PACKET_ATTR_KEY);
430 ovs_flow_to_nlattrs(upcall_info->key, user_skb);
431 nla_nest_end(user_skb, nla);
432
433 if (upcall_info->userdata)
Ben Pfaff44901082013-02-15 17:29:22 -0800434 __nla_put(user_skb, OVS_PACKET_ATTR_USERDATA,
435 nla_len(upcall_info->userdata),
436 nla_data(upcall_info->userdata));
Jesse Grossccb13522011-10-25 19:26:31 -0700437
438 nla = __nla_reserve(user_skb, OVS_PACKET_ATTR_PACKET, skb->len);
439
440 skb_copy_and_csum_dev(skb, nla_data(nla));
441
Rich Lanea15ff762013-02-15 11:07:43 -0800442 genlmsg_end(user_skb, upcall);
Eric W. Biederman15e47302012-09-07 20:12:54 +0000443 err = genlmsg_unicast(net, user_skb, upcall_info->portid);
Jesse Grossccb13522011-10-25 19:26:31 -0700444
445out:
446 kfree_skb(nskb);
447 return err;
448}
449
Pravin B Shelar8e4e1712013-04-15 13:23:03 -0700450/* Called with ovs_mutex. */
Pravin B Shelar46df7b82012-02-22 19:58:59 -0800451static int flush_flows(struct datapath *dp)
Jesse Grossccb13522011-10-25 19:26:31 -0700452{
453 struct flow_table *old_table;
454 struct flow_table *new_table;
Jesse Grossccb13522011-10-25 19:26:31 -0700455
Pravin B Shelar8e4e1712013-04-15 13:23:03 -0700456 old_table = ovsl_dereference(dp->table);
Jesse Grossccb13522011-10-25 19:26:31 -0700457 new_table = ovs_flow_tbl_alloc(TBL_MIN_BUCKETS);
458 if (!new_table)
459 return -ENOMEM;
460
461 rcu_assign_pointer(dp->table, new_table);
462
463 ovs_flow_tbl_deferred_destroy(old_table);
464 return 0;
465}
466
Pravin B Shelar74f84a52013-06-17 17:50:12 -0700467static struct nlattr *reserve_sfa_size(struct sw_flow_actions **sfa, int attr_len)
468{
Jesse Grossccb13522011-10-25 19:26:31 -0700469
Pravin B Shelar74f84a52013-06-17 17:50:12 -0700470 struct sw_flow_actions *acts;
471 int new_acts_size;
472 int req_size = NLA_ALIGN(attr_len);
473 int next_offset = offsetof(struct sw_flow_actions, actions) +
474 (*sfa)->actions_len;
475
476 if (req_size <= (ksize(*sfa) - next_offset))
477 goto out;
478
479 new_acts_size = ksize(*sfa) * 2;
480
481 if (new_acts_size > MAX_ACTIONS_BUFSIZE) {
482 if ((MAX_ACTIONS_BUFSIZE - next_offset) < req_size)
483 return ERR_PTR(-EMSGSIZE);
484 new_acts_size = MAX_ACTIONS_BUFSIZE;
485 }
486
487 acts = ovs_flow_actions_alloc(new_acts_size);
488 if (IS_ERR(acts))
489 return (void *)acts;
490
491 memcpy(acts->actions, (*sfa)->actions, (*sfa)->actions_len);
492 acts->actions_len = (*sfa)->actions_len;
493 kfree(*sfa);
494 *sfa = acts;
495
496out:
497 (*sfa)->actions_len += req_size;
498 return (struct nlattr *) ((unsigned char *)(*sfa) + next_offset);
499}
500
501static int add_action(struct sw_flow_actions **sfa, int attrtype, void *data, int len)
502{
503 struct nlattr *a;
504
505 a = reserve_sfa_size(sfa, nla_attr_size(len));
506 if (IS_ERR(a))
507 return PTR_ERR(a);
508
509 a->nla_type = attrtype;
510 a->nla_len = nla_attr_size(len);
511
512 if (data)
513 memcpy(nla_data(a), data, len);
514 memset((unsigned char *) a + a->nla_len, 0, nla_padlen(len));
515
516 return 0;
517}
518
519static inline int add_nested_action_start(struct sw_flow_actions **sfa, int attrtype)
520{
521 int used = (*sfa)->actions_len;
522 int err;
523
524 err = add_action(sfa, attrtype, NULL, 0);
525 if (err)
526 return err;
527
528 return used;
529}
530
531static inline void add_nested_action_end(struct sw_flow_actions *sfa, int st_offset)
532{
533 struct nlattr *a = (struct nlattr *) ((unsigned char *)sfa->actions + st_offset);
534
535 a->nla_len = sfa->actions_len - st_offset;
536}
537
538static int validate_and_copy_actions(const struct nlattr *attr,
539 const struct sw_flow_key *key, int depth,
540 struct sw_flow_actions **sfa);
541
542static int validate_and_copy_sample(const struct nlattr *attr,
543 const struct sw_flow_key *key, int depth,
544 struct sw_flow_actions **sfa)
Jesse Grossccb13522011-10-25 19:26:31 -0700545{
546 const struct nlattr *attrs[OVS_SAMPLE_ATTR_MAX + 1];
547 const struct nlattr *probability, *actions;
548 const struct nlattr *a;
Pravin B Shelar74f84a52013-06-17 17:50:12 -0700549 int rem, start, err, st_acts;
Jesse Grossccb13522011-10-25 19:26:31 -0700550
551 memset(attrs, 0, sizeof(attrs));
552 nla_for_each_nested(a, attr, rem) {
553 int type = nla_type(a);
554 if (!type || type > OVS_SAMPLE_ATTR_MAX || attrs[type])
555 return -EINVAL;
556 attrs[type] = a;
557 }
558 if (rem)
559 return -EINVAL;
560
561 probability = attrs[OVS_SAMPLE_ATTR_PROBABILITY];
562 if (!probability || nla_len(probability) != sizeof(u32))
563 return -EINVAL;
564
565 actions = attrs[OVS_SAMPLE_ATTR_ACTIONS];
566 if (!actions || (nla_len(actions) && nla_len(actions) < NLA_HDRLEN))
567 return -EINVAL;
Pravin B Shelar74f84a52013-06-17 17:50:12 -0700568
569 /* validation done, copy sample action. */
570 start = add_nested_action_start(sfa, OVS_ACTION_ATTR_SAMPLE);
571 if (start < 0)
572 return start;
573 err = add_action(sfa, OVS_SAMPLE_ATTR_PROBABILITY, nla_data(probability), sizeof(u32));
574 if (err)
575 return err;
576 st_acts = add_nested_action_start(sfa, OVS_SAMPLE_ATTR_ACTIONS);
577 if (st_acts < 0)
578 return st_acts;
579
580 err = validate_and_copy_actions(actions, key, depth + 1, sfa);
581 if (err)
582 return err;
583
584 add_nested_action_end(*sfa, st_acts);
585 add_nested_action_end(*sfa, start);
586
587 return 0;
Jesse Grossccb13522011-10-25 19:26:31 -0700588}
589
Pravin B Shelar072ae632012-05-07 17:21:53 -0700590static int validate_tp_port(const struct sw_flow_key *flow_key)
591{
592 if (flow_key->eth.type == htons(ETH_P_IP)) {
Jesse Gross41853922012-08-06 15:49:47 -0700593 if (flow_key->ipv4.tp.src || flow_key->ipv4.tp.dst)
Pravin B Shelar072ae632012-05-07 17:21:53 -0700594 return 0;
595 } else if (flow_key->eth.type == htons(ETH_P_IPV6)) {
Jesse Gross41853922012-08-06 15:49:47 -0700596 if (flow_key->ipv6.tp.src || flow_key->ipv6.tp.dst)
Pravin B Shelar072ae632012-05-07 17:21:53 -0700597 return 0;
598 }
599
600 return -EINVAL;
601}
602
Jesse Grossccb13522011-10-25 19:26:31 -0700603static int validate_set(const struct nlattr *a,
604 const struct sw_flow_key *flow_key)
605{
606 const struct nlattr *ovs_key = nla_data(a);
607 int key_type = nla_type(ovs_key);
608
609 /* There can be only one key in a action */
610 if (nla_total_size(nla_len(ovs_key)) != nla_len(a))
611 return -EINVAL;
612
613 if (key_type > OVS_KEY_ATTR_MAX ||
614 nla_len(ovs_key) != ovs_key_lens[key_type])
615 return -EINVAL;
616
617 switch (key_type) {
618 const struct ovs_key_ipv4 *ipv4_key;
Ansis Atteka3fdbd1c2012-11-13 15:44:14 -0800619 const struct ovs_key_ipv6 *ipv6_key;
Jesse Grossccb13522011-10-25 19:26:31 -0700620
621 case OVS_KEY_ATTR_PRIORITY:
Ansis Atteka39c7caeb2012-11-26 11:24:11 -0800622 case OVS_KEY_ATTR_SKB_MARK:
Jesse Grossccb13522011-10-25 19:26:31 -0700623 case OVS_KEY_ATTR_ETHERNET:
624 break;
625
626 case OVS_KEY_ATTR_IPV4:
627 if (flow_key->eth.type != htons(ETH_P_IP))
628 return -EINVAL;
629
Jesse Gross41853922012-08-06 15:49:47 -0700630 if (!flow_key->ip.proto)
Jesse Grossccb13522011-10-25 19:26:31 -0700631 return -EINVAL;
632
633 ipv4_key = nla_data(ovs_key);
634 if (ipv4_key->ipv4_proto != flow_key->ip.proto)
635 return -EINVAL;
636
637 if (ipv4_key->ipv4_frag != flow_key->ip.frag)
638 return -EINVAL;
639
640 break;
641
Ansis Atteka3fdbd1c2012-11-13 15:44:14 -0800642 case OVS_KEY_ATTR_IPV6:
643 if (flow_key->eth.type != htons(ETH_P_IPV6))
644 return -EINVAL;
645
646 if (!flow_key->ip.proto)
647 return -EINVAL;
648
649 ipv6_key = nla_data(ovs_key);
650 if (ipv6_key->ipv6_proto != flow_key->ip.proto)
651 return -EINVAL;
652
653 if (ipv6_key->ipv6_frag != flow_key->ip.frag)
654 return -EINVAL;
655
656 if (ntohl(ipv6_key->ipv6_label) & 0xFFF00000)
657 return -EINVAL;
658
659 break;
660
Jesse Grossccb13522011-10-25 19:26:31 -0700661 case OVS_KEY_ATTR_TCP:
662 if (flow_key->ip.proto != IPPROTO_TCP)
663 return -EINVAL;
664
Pravin B Shelar072ae632012-05-07 17:21:53 -0700665 return validate_tp_port(flow_key);
Jesse Grossccb13522011-10-25 19:26:31 -0700666
667 case OVS_KEY_ATTR_UDP:
668 if (flow_key->ip.proto != IPPROTO_UDP)
669 return -EINVAL;
670
Pravin B Shelar072ae632012-05-07 17:21:53 -0700671 return validate_tp_port(flow_key);
Jesse Grossccb13522011-10-25 19:26:31 -0700672
673 default:
674 return -EINVAL;
675 }
676
677 return 0;
678}
679
680static int validate_userspace(const struct nlattr *attr)
681{
682 static const struct nla_policy userspace_policy[OVS_USERSPACE_ATTR_MAX + 1] = {
683 [OVS_USERSPACE_ATTR_PID] = {.type = NLA_U32 },
Ben Pfaff44901082013-02-15 17:29:22 -0800684 [OVS_USERSPACE_ATTR_USERDATA] = {.type = NLA_UNSPEC },
Jesse Grossccb13522011-10-25 19:26:31 -0700685 };
686 struct nlattr *a[OVS_USERSPACE_ATTR_MAX + 1];
687 int error;
688
689 error = nla_parse_nested(a, OVS_USERSPACE_ATTR_MAX,
690 attr, userspace_policy);
691 if (error)
692 return error;
693
694 if (!a[OVS_USERSPACE_ATTR_PID] ||
695 !nla_get_u32(a[OVS_USERSPACE_ATTR_PID]))
696 return -EINVAL;
697
698 return 0;
699}
700
Pravin B Shelar74f84a52013-06-17 17:50:12 -0700701static int copy_action(const struct nlattr *from,
702 struct sw_flow_actions **sfa)
703{
704 int totlen = NLA_ALIGN(from->nla_len);
705 struct nlattr *to;
706
707 to = reserve_sfa_size(sfa, from->nla_len);
708 if (IS_ERR(to))
709 return PTR_ERR(to);
710
711 memcpy(to, from, totlen);
712 return 0;
713}
714
715static int validate_and_copy_actions(const struct nlattr *attr,
716 const struct sw_flow_key *key,
717 int depth,
718 struct sw_flow_actions **sfa)
Jesse Grossccb13522011-10-25 19:26:31 -0700719{
720 const struct nlattr *a;
721 int rem, err;
722
723 if (depth >= SAMPLE_ACTION_DEPTH)
724 return -EOVERFLOW;
725
726 nla_for_each_nested(a, attr, rem) {
727 /* Expected argument lengths, (u32)-1 for variable length. */
728 static const u32 action_lens[OVS_ACTION_ATTR_MAX + 1] = {
729 [OVS_ACTION_ATTR_OUTPUT] = sizeof(u32),
730 [OVS_ACTION_ATTR_USERSPACE] = (u32)-1,
731 [OVS_ACTION_ATTR_PUSH_VLAN] = sizeof(struct ovs_action_push_vlan),
732 [OVS_ACTION_ATTR_POP_VLAN] = 0,
733 [OVS_ACTION_ATTR_SET] = (u32)-1,
734 [OVS_ACTION_ATTR_SAMPLE] = (u32)-1
735 };
736 const struct ovs_action_push_vlan *vlan;
737 int type = nla_type(a);
Pravin B Shelar74f84a52013-06-17 17:50:12 -0700738 bool skip_copy;
Jesse Grossccb13522011-10-25 19:26:31 -0700739
740 if (type > OVS_ACTION_ATTR_MAX ||
741 (action_lens[type] != nla_len(a) &&
742 action_lens[type] != (u32)-1))
743 return -EINVAL;
744
Pravin B Shelar74f84a52013-06-17 17:50:12 -0700745 skip_copy = false;
Jesse Grossccb13522011-10-25 19:26:31 -0700746 switch (type) {
747 case OVS_ACTION_ATTR_UNSPEC:
748 return -EINVAL;
749
750 case OVS_ACTION_ATTR_USERSPACE:
751 err = validate_userspace(a);
752 if (err)
753 return err;
754 break;
755
756 case OVS_ACTION_ATTR_OUTPUT:
757 if (nla_get_u32(a) >= DP_MAX_PORTS)
758 return -EINVAL;
759 break;
760
761
762 case OVS_ACTION_ATTR_POP_VLAN:
763 break;
764
765 case OVS_ACTION_ATTR_PUSH_VLAN:
766 vlan = nla_data(a);
767 if (vlan->vlan_tpid != htons(ETH_P_8021Q))
768 return -EINVAL;
769 if (!(vlan->vlan_tci & htons(VLAN_TAG_PRESENT)))
770 return -EINVAL;
771 break;
772
773 case OVS_ACTION_ATTR_SET:
774 err = validate_set(a, key);
775 if (err)
776 return err;
777 break;
778
779 case OVS_ACTION_ATTR_SAMPLE:
Pravin B Shelar74f84a52013-06-17 17:50:12 -0700780 err = validate_and_copy_sample(a, key, depth, sfa);
Jesse Grossccb13522011-10-25 19:26:31 -0700781 if (err)
782 return err;
Pravin B Shelar74f84a52013-06-17 17:50:12 -0700783 skip_copy = true;
Jesse Grossccb13522011-10-25 19:26:31 -0700784 break;
785
786 default:
787 return -EINVAL;
788 }
Pravin B Shelar74f84a52013-06-17 17:50:12 -0700789 if (!skip_copy) {
790 err = copy_action(a, sfa);
791 if (err)
792 return err;
793 }
Jesse Grossccb13522011-10-25 19:26:31 -0700794 }
795
796 if (rem > 0)
797 return -EINVAL;
798
799 return 0;
800}
801
802static void clear_stats(struct sw_flow *flow)
803{
804 flow->used = 0;
805 flow->tcp_flags = 0;
806 flow->packet_count = 0;
807 flow->byte_count = 0;
808}
809
810static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info)
811{
812 struct ovs_header *ovs_header = info->userhdr;
813 struct nlattr **a = info->attrs;
814 struct sw_flow_actions *acts;
815 struct sk_buff *packet;
816 struct sw_flow *flow;
817 struct datapath *dp;
818 struct ethhdr *eth;
819 int len;
820 int err;
821 int key_len;
822
823 err = -EINVAL;
824 if (!a[OVS_PACKET_ATTR_PACKET] || !a[OVS_PACKET_ATTR_KEY] ||
Thomas Grafdded45fc2013-03-29 14:46:47 +0100825 !a[OVS_PACKET_ATTR_ACTIONS])
Jesse Grossccb13522011-10-25 19:26:31 -0700826 goto err;
827
828 len = nla_len(a[OVS_PACKET_ATTR_PACKET]);
829 packet = __dev_alloc_skb(NET_IP_ALIGN + len, GFP_KERNEL);
830 err = -ENOMEM;
831 if (!packet)
832 goto err;
833 skb_reserve(packet, NET_IP_ALIGN);
834
Thomas Graf32686a92013-03-29 14:46:48 +0100835 nla_memcpy(__skb_put(packet, len), a[OVS_PACKET_ATTR_PACKET], len);
Jesse Grossccb13522011-10-25 19:26:31 -0700836
837 skb_reset_mac_header(packet);
838 eth = eth_hdr(packet);
839
840 /* Normally, setting the skb 'protocol' field would be handled by a
841 * call to eth_type_trans(), but it assumes there's a sending
842 * device, which we may not have. */
Simon Hormane5c5d222013-03-28 13:38:25 +0900843 if (ntohs(eth->h_proto) >= ETH_P_802_3_MIN)
Jesse Grossccb13522011-10-25 19:26:31 -0700844 packet->protocol = eth->h_proto;
845 else
846 packet->protocol = htons(ETH_P_802_2);
847
848 /* Build an sw_flow for sending this packet. */
849 flow = ovs_flow_alloc();
850 err = PTR_ERR(flow);
851 if (IS_ERR(flow))
852 goto err_kfree_skb;
853
854 err = ovs_flow_extract(packet, -1, &flow->key, &key_len);
855 if (err)
856 goto err_flow_free;
857
Pravin B Shelar93d8fd12013-06-13 11:11:32 -0700858 err = ovs_flow_metadata_from_nlattrs(flow, a[OVS_PACKET_ATTR_KEY]);
Jesse Grossccb13522011-10-25 19:26:31 -0700859 if (err)
860 goto err_flow_free;
Jesse Grossccb13522011-10-25 19:26:31 -0700861 flow->hash = ovs_flow_hash(&flow->key, key_len);
Pravin B Shelar74f84a52013-06-17 17:50:12 -0700862 acts = ovs_flow_actions_alloc(nla_len(a[OVS_PACKET_ATTR_ACTIONS]));
Jesse Grossccb13522011-10-25 19:26:31 -0700863 err = PTR_ERR(acts);
864 if (IS_ERR(acts))
865 goto err_flow_free;
Pravin B Shelar74f84a52013-06-17 17:50:12 -0700866
867 err = validate_and_copy_actions(a[OVS_PACKET_ATTR_ACTIONS], &flow->key, 0, &acts);
Jesse Grossccb13522011-10-25 19:26:31 -0700868 rcu_assign_pointer(flow->sf_acts, acts);
Pravin B Shelar74f84a52013-06-17 17:50:12 -0700869 if (err)
870 goto err_flow_free;
Jesse Grossccb13522011-10-25 19:26:31 -0700871
872 OVS_CB(packet)->flow = flow;
873 packet->priority = flow->key.phy.priority;
Ansis Atteka39c7caeb2012-11-26 11:24:11 -0800874 packet->mark = flow->key.phy.skb_mark;
Jesse Grossccb13522011-10-25 19:26:31 -0700875
876 rcu_read_lock();
Pravin B Shelar46df7b82012-02-22 19:58:59 -0800877 dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex);
Jesse Grossccb13522011-10-25 19:26:31 -0700878 err = -ENODEV;
879 if (!dp)
880 goto err_unlock;
881
882 local_bh_disable();
883 err = ovs_execute_actions(dp, packet);
884 local_bh_enable();
885 rcu_read_unlock();
886
887 ovs_flow_free(flow);
888 return err;
889
890err_unlock:
891 rcu_read_unlock();
892err_flow_free:
893 ovs_flow_free(flow);
894err_kfree_skb:
895 kfree_skb(packet);
896err:
897 return err;
898}
899
900static const struct nla_policy packet_policy[OVS_PACKET_ATTR_MAX + 1] = {
Thomas Grafdded45fc2013-03-29 14:46:47 +0100901 [OVS_PACKET_ATTR_PACKET] = { .len = ETH_HLEN },
Jesse Grossccb13522011-10-25 19:26:31 -0700902 [OVS_PACKET_ATTR_KEY] = { .type = NLA_NESTED },
903 [OVS_PACKET_ATTR_ACTIONS] = { .type = NLA_NESTED },
904};
905
906static struct genl_ops dp_packet_genl_ops[] = {
907 { .cmd = OVS_PACKET_CMD_EXECUTE,
908 .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
909 .policy = packet_policy,
910 .doit = ovs_packet_cmd_execute
911 }
912};
913
914static void get_dp_stats(struct datapath *dp, struct ovs_dp_stats *stats)
915{
916 int i;
Pravin B Shelar8e4e1712013-04-15 13:23:03 -0700917 struct flow_table *table = ovsl_dereference(dp->table);
Jesse Grossccb13522011-10-25 19:26:31 -0700918
919 stats->n_flows = ovs_flow_tbl_count(table);
920
921 stats->n_hit = stats->n_missed = stats->n_lost = 0;
922 for_each_possible_cpu(i) {
923 const struct dp_stats_percpu *percpu_stats;
924 struct dp_stats_percpu local_stats;
925 unsigned int start;
926
927 percpu_stats = per_cpu_ptr(dp->stats_percpu, i);
928
929 do {
930 start = u64_stats_fetch_begin_bh(&percpu_stats->sync);
931 local_stats = *percpu_stats;
932 } while (u64_stats_fetch_retry_bh(&percpu_stats->sync, start));
933
934 stats->n_hit += local_stats.n_hit;
935 stats->n_missed += local_stats.n_missed;
936 stats->n_lost += local_stats.n_lost;
937 }
938}
939
940static const struct nla_policy flow_policy[OVS_FLOW_ATTR_MAX + 1] = {
941 [OVS_FLOW_ATTR_KEY] = { .type = NLA_NESTED },
942 [OVS_FLOW_ATTR_ACTIONS] = { .type = NLA_NESTED },
943 [OVS_FLOW_ATTR_CLEAR] = { .type = NLA_FLAG },
944};
945
946static struct genl_family dp_flow_genl_family = {
947 .id = GENL_ID_GENERATE,
948 .hdrsize = sizeof(struct ovs_header),
949 .name = OVS_FLOW_FAMILY,
950 .version = OVS_FLOW_VERSION,
Pravin B Shelar46df7b82012-02-22 19:58:59 -0800951 .maxattr = OVS_FLOW_ATTR_MAX,
Pravin B Shelar3a4e0d62013-04-23 07:48:48 +0000952 .netnsok = true,
953 .parallel_ops = true,
Jesse Grossccb13522011-10-25 19:26:31 -0700954};
955
956static struct genl_multicast_group ovs_dp_flow_multicast_group = {
957 .name = OVS_FLOW_MCGROUP
958};
959
Pravin B Shelar74f84a52013-06-17 17:50:12 -0700960static int actions_to_attr(const struct nlattr *attr, int len, struct sk_buff *skb);
961static int sample_action_to_attr(const struct nlattr *attr, struct sk_buff *skb)
962{
963 const struct nlattr *a;
964 struct nlattr *start;
965 int err = 0, rem;
966
967 start = nla_nest_start(skb, OVS_ACTION_ATTR_SAMPLE);
968 if (!start)
969 return -EMSGSIZE;
970
971 nla_for_each_nested(a, attr, rem) {
972 int type = nla_type(a);
973 struct nlattr *st_sample;
974
975 switch (type) {
976 case OVS_SAMPLE_ATTR_PROBABILITY:
977 if (nla_put(skb, OVS_SAMPLE_ATTR_PROBABILITY, sizeof(u32), nla_data(a)))
978 return -EMSGSIZE;
979 break;
980 case OVS_SAMPLE_ATTR_ACTIONS:
981 st_sample = nla_nest_start(skb, OVS_SAMPLE_ATTR_ACTIONS);
982 if (!st_sample)
983 return -EMSGSIZE;
984 err = actions_to_attr(nla_data(a), nla_len(a), skb);
985 if (err)
986 return err;
987 nla_nest_end(skb, st_sample);
988 break;
989 }
990 }
991
992 nla_nest_end(skb, start);
993 return err;
994}
995
996static int actions_to_attr(const struct nlattr *attr, int len, struct sk_buff *skb)
997{
998 const struct nlattr *a;
999 int rem, err;
1000
1001 nla_for_each_attr(a, attr, len, rem) {
1002 int type = nla_type(a);
1003
1004 switch (type) {
1005 case OVS_ACTION_ATTR_SAMPLE:
1006 err = sample_action_to_attr(a, skb);
1007 if (err)
1008 return err;
1009 break;
1010 default:
1011 if (nla_put(skb, type, nla_len(a), nla_data(a)))
1012 return -EMSGSIZE;
1013 break;
1014 }
1015 }
1016
1017 return 0;
1018}
1019
Thomas Grafc3ff8cf2013-03-29 14:46:49 +01001020static size_t ovs_flow_cmd_msg_size(const struct sw_flow_actions *acts)
1021{
1022 return NLMSG_ALIGN(sizeof(struct ovs_header))
1023 + nla_total_size(key_attr_size()) /* OVS_FLOW_ATTR_KEY */
1024 + nla_total_size(sizeof(struct ovs_flow_stats)) /* OVS_FLOW_ATTR_STATS */
1025 + nla_total_size(1) /* OVS_FLOW_ATTR_TCP_FLAGS */
1026 + nla_total_size(8) /* OVS_FLOW_ATTR_USED */
1027 + nla_total_size(acts->actions_len); /* OVS_FLOW_ATTR_ACTIONS */
1028}
1029
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001030/* Called with ovs_mutex. */
Jesse Grossccb13522011-10-25 19:26:31 -07001031static int ovs_flow_cmd_fill_info(struct sw_flow *flow, struct datapath *dp,
Eric W. Biederman15e47302012-09-07 20:12:54 +00001032 struct sk_buff *skb, u32 portid,
Jesse Grossccb13522011-10-25 19:26:31 -07001033 u32 seq, u32 flags, u8 cmd)
1034{
1035 const int skb_orig_len = skb->len;
1036 const struct sw_flow_actions *sf_acts;
Pravin B Shelar74f84a52013-06-17 17:50:12 -07001037 struct nlattr *start;
Jesse Grossccb13522011-10-25 19:26:31 -07001038 struct ovs_flow_stats stats;
1039 struct ovs_header *ovs_header;
1040 struct nlattr *nla;
1041 unsigned long used;
1042 u8 tcp_flags;
1043 int err;
1044
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001045 sf_acts = ovsl_dereference(flow->sf_acts);
Jesse Grossccb13522011-10-25 19:26:31 -07001046
Eric W. Biederman15e47302012-09-07 20:12:54 +00001047 ovs_header = genlmsg_put(skb, portid, seq, &dp_flow_genl_family, flags, cmd);
Jesse Grossccb13522011-10-25 19:26:31 -07001048 if (!ovs_header)
1049 return -EMSGSIZE;
1050
1051 ovs_header->dp_ifindex = get_dpifindex(dp);
1052
1053 nla = nla_nest_start(skb, OVS_FLOW_ATTR_KEY);
1054 if (!nla)
1055 goto nla_put_failure;
1056 err = ovs_flow_to_nlattrs(&flow->key, skb);
1057 if (err)
1058 goto error;
1059 nla_nest_end(skb, nla);
1060
1061 spin_lock_bh(&flow->lock);
1062 used = flow->used;
1063 stats.n_packets = flow->packet_count;
1064 stats.n_bytes = flow->byte_count;
1065 tcp_flags = flow->tcp_flags;
1066 spin_unlock_bh(&flow->lock);
1067
David S. Miller028d6a62012-03-29 23:20:48 -04001068 if (used &&
1069 nla_put_u64(skb, OVS_FLOW_ATTR_USED, ovs_flow_used_time(used)))
1070 goto nla_put_failure;
Jesse Grossccb13522011-10-25 19:26:31 -07001071
David S. Miller028d6a62012-03-29 23:20:48 -04001072 if (stats.n_packets &&
1073 nla_put(skb, OVS_FLOW_ATTR_STATS,
1074 sizeof(struct ovs_flow_stats), &stats))
1075 goto nla_put_failure;
Jesse Grossccb13522011-10-25 19:26:31 -07001076
David S. Miller028d6a62012-03-29 23:20:48 -04001077 if (tcp_flags &&
1078 nla_put_u8(skb, OVS_FLOW_ATTR_TCP_FLAGS, tcp_flags))
1079 goto nla_put_failure;
Jesse Grossccb13522011-10-25 19:26:31 -07001080
1081 /* If OVS_FLOW_ATTR_ACTIONS doesn't fit, skip dumping the actions if
1082 * this is the first flow to be dumped into 'skb'. This is unusual for
1083 * Netlink but individual action lists can be longer than
1084 * NLMSG_GOODSIZE and thus entirely undumpable if we didn't do this.
1085 * The userspace caller can always fetch the actions separately if it
1086 * really wants them. (Most userspace callers in fact don't care.)
1087 *
1088 * This can only fail for dump operations because the skb is always
1089 * properly sized for single flows.
1090 */
Pravin B Shelar74f84a52013-06-17 17:50:12 -07001091 start = nla_nest_start(skb, OVS_FLOW_ATTR_ACTIONS);
1092 if (start) {
1093 err = actions_to_attr(sf_acts->actions, sf_acts->actions_len, skb);
1094 if (!err)
1095 nla_nest_end(skb, start);
1096 else {
1097 if (skb_orig_len)
1098 goto error;
1099
1100 nla_nest_cancel(skb, start);
1101 }
1102 } else if (skb_orig_len)
1103 goto nla_put_failure;
Jesse Grossccb13522011-10-25 19:26:31 -07001104
1105 return genlmsg_end(skb, ovs_header);
1106
1107nla_put_failure:
1108 err = -EMSGSIZE;
1109error:
1110 genlmsg_cancel(skb, ovs_header);
1111 return err;
1112}
1113
1114static struct sk_buff *ovs_flow_cmd_alloc_info(struct sw_flow *flow)
1115{
1116 const struct sw_flow_actions *sf_acts;
Jesse Grossccb13522011-10-25 19:26:31 -07001117
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001118 sf_acts = ovsl_dereference(flow->sf_acts);
Jesse Grossccb13522011-10-25 19:26:31 -07001119
Thomas Grafc3ff8cf2013-03-29 14:46:49 +01001120 return genlmsg_new(ovs_flow_cmd_msg_size(sf_acts), GFP_KERNEL);
Jesse Grossccb13522011-10-25 19:26:31 -07001121}
1122
1123static struct sk_buff *ovs_flow_cmd_build_info(struct sw_flow *flow,
1124 struct datapath *dp,
Eric W. Biederman15e47302012-09-07 20:12:54 +00001125 u32 portid, u32 seq, u8 cmd)
Jesse Grossccb13522011-10-25 19:26:31 -07001126{
1127 struct sk_buff *skb;
1128 int retval;
1129
1130 skb = ovs_flow_cmd_alloc_info(flow);
1131 if (!skb)
1132 return ERR_PTR(-ENOMEM);
1133
Eric W. Biederman15e47302012-09-07 20:12:54 +00001134 retval = ovs_flow_cmd_fill_info(flow, dp, skb, portid, seq, 0, cmd);
Jesse Grossccb13522011-10-25 19:26:31 -07001135 BUG_ON(retval < 0);
1136 return skb;
1137}
1138
1139static int ovs_flow_cmd_new_or_set(struct sk_buff *skb, struct genl_info *info)
1140{
1141 struct nlattr **a = info->attrs;
1142 struct ovs_header *ovs_header = info->userhdr;
1143 struct sw_flow_key key;
1144 struct sw_flow *flow;
1145 struct sk_buff *reply;
1146 struct datapath *dp;
1147 struct flow_table *table;
Pravin B Shelar74f84a52013-06-17 17:50:12 -07001148 struct sw_flow_actions *acts = NULL;
Jesse Grossccb13522011-10-25 19:26:31 -07001149 int error;
1150 int key_len;
1151
1152 /* Extract key. */
1153 error = -EINVAL;
1154 if (!a[OVS_FLOW_ATTR_KEY])
1155 goto error;
1156 error = ovs_flow_from_nlattrs(&key, &key_len, a[OVS_FLOW_ATTR_KEY]);
1157 if (error)
1158 goto error;
1159
1160 /* Validate actions. */
1161 if (a[OVS_FLOW_ATTR_ACTIONS]) {
Pravin B Shelar74f84a52013-06-17 17:50:12 -07001162 acts = ovs_flow_actions_alloc(nla_len(a[OVS_FLOW_ATTR_ACTIONS]));
1163 error = PTR_ERR(acts);
1164 if (IS_ERR(acts))
Jesse Grossccb13522011-10-25 19:26:31 -07001165 goto error;
Pravin B Shelar74f84a52013-06-17 17:50:12 -07001166
1167 error = validate_and_copy_actions(a[OVS_FLOW_ATTR_ACTIONS], &key, 0, &acts);
1168 if (error)
1169 goto err_kfree;
Jesse Grossccb13522011-10-25 19:26:31 -07001170 } else if (info->genlhdr->cmd == OVS_FLOW_CMD_NEW) {
1171 error = -EINVAL;
1172 goto error;
1173 }
1174
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001175 ovs_lock();
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001176 dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex);
Jesse Grossccb13522011-10-25 19:26:31 -07001177 error = -ENODEV;
1178 if (!dp)
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001179 goto err_unlock_ovs;
Jesse Grossccb13522011-10-25 19:26:31 -07001180
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001181 table = ovsl_dereference(dp->table);
Jesse Grossccb13522011-10-25 19:26:31 -07001182 flow = ovs_flow_tbl_lookup(table, &key, key_len);
1183 if (!flow) {
Jesse Grossccb13522011-10-25 19:26:31 -07001184 /* Bail out if we're not allowed to create a new flow. */
1185 error = -ENOENT;
1186 if (info->genlhdr->cmd == OVS_FLOW_CMD_SET)
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001187 goto err_unlock_ovs;
Jesse Grossccb13522011-10-25 19:26:31 -07001188
1189 /* Expand table, if necessary, to make room. */
1190 if (ovs_flow_tbl_need_to_expand(table)) {
1191 struct flow_table *new_table;
1192
1193 new_table = ovs_flow_tbl_expand(table);
1194 if (!IS_ERR(new_table)) {
1195 rcu_assign_pointer(dp->table, new_table);
1196 ovs_flow_tbl_deferred_destroy(table);
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001197 table = ovsl_dereference(dp->table);
Jesse Grossccb13522011-10-25 19:26:31 -07001198 }
1199 }
1200
1201 /* Allocate flow. */
1202 flow = ovs_flow_alloc();
1203 if (IS_ERR(flow)) {
1204 error = PTR_ERR(flow);
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001205 goto err_unlock_ovs;
Jesse Grossccb13522011-10-25 19:26:31 -07001206 }
1207 flow->key = key;
1208 clear_stats(flow);
1209
Jesse Grossccb13522011-10-25 19:26:31 -07001210 rcu_assign_pointer(flow->sf_acts, acts);
1211
1212 /* Put flow in bucket. */
1213 flow->hash = ovs_flow_hash(&key, key_len);
1214 ovs_flow_tbl_insert(table, flow);
1215
Eric W. Biederman15e47302012-09-07 20:12:54 +00001216 reply = ovs_flow_cmd_build_info(flow, dp, info->snd_portid,
Jesse Grossccb13522011-10-25 19:26:31 -07001217 info->snd_seq,
1218 OVS_FLOW_CMD_NEW);
1219 } else {
1220 /* We found a matching flow. */
1221 struct sw_flow_actions *old_acts;
Jesse Grossccb13522011-10-25 19:26:31 -07001222
1223 /* Bail out if we're not allowed to modify an existing flow.
1224 * We accept NLM_F_CREATE in place of the intended NLM_F_EXCL
1225 * because Generic Netlink treats the latter as a dump
1226 * request. We also accept NLM_F_EXCL in case that bug ever
1227 * gets fixed.
1228 */
1229 error = -EEXIST;
1230 if (info->genlhdr->cmd == OVS_FLOW_CMD_NEW &&
1231 info->nlhdr->nlmsg_flags & (NLM_F_CREATE | NLM_F_EXCL))
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001232 goto err_unlock_ovs;
Jesse Grossccb13522011-10-25 19:26:31 -07001233
1234 /* Update actions. */
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001235 old_acts = ovsl_dereference(flow->sf_acts);
Pravin B Shelar74f84a52013-06-17 17:50:12 -07001236 rcu_assign_pointer(flow->sf_acts, acts);
1237 ovs_flow_deferred_free_acts(old_acts);
Jesse Grossccb13522011-10-25 19:26:31 -07001238
Eric W. Biederman15e47302012-09-07 20:12:54 +00001239 reply = ovs_flow_cmd_build_info(flow, dp, info->snd_portid,
Jesse Grossccb13522011-10-25 19:26:31 -07001240 info->snd_seq, OVS_FLOW_CMD_NEW);
1241
1242 /* Clear stats. */
1243 if (a[OVS_FLOW_ATTR_CLEAR]) {
1244 spin_lock_bh(&flow->lock);
1245 clear_stats(flow);
1246 spin_unlock_bh(&flow->lock);
1247 }
1248 }
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001249 ovs_unlock();
Jesse Grossccb13522011-10-25 19:26:31 -07001250
1251 if (!IS_ERR(reply))
Thomas Grafed661182013-03-29 14:46:50 +01001252 ovs_notify(reply, info, &ovs_dp_flow_multicast_group);
Jesse Grossccb13522011-10-25 19:26:31 -07001253 else
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001254 netlink_set_err(sock_net(skb->sk)->genl_sock, 0,
Jesse Grossccb13522011-10-25 19:26:31 -07001255 ovs_dp_flow_multicast_group.id, PTR_ERR(reply));
1256 return 0;
1257
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001258err_unlock_ovs:
1259 ovs_unlock();
Pravin B Shelar74f84a52013-06-17 17:50:12 -07001260err_kfree:
1261 kfree(acts);
Jesse Grossccb13522011-10-25 19:26:31 -07001262error:
1263 return error;
1264}
1265
1266static int ovs_flow_cmd_get(struct sk_buff *skb, struct genl_info *info)
1267{
1268 struct nlattr **a = info->attrs;
1269 struct ovs_header *ovs_header = info->userhdr;
1270 struct sw_flow_key key;
1271 struct sk_buff *reply;
1272 struct sw_flow *flow;
1273 struct datapath *dp;
1274 struct flow_table *table;
1275 int err;
1276 int key_len;
1277
1278 if (!a[OVS_FLOW_ATTR_KEY])
1279 return -EINVAL;
1280 err = ovs_flow_from_nlattrs(&key, &key_len, a[OVS_FLOW_ATTR_KEY]);
1281 if (err)
1282 return err;
1283
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001284 ovs_lock();
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001285 dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex);
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001286 if (!dp) {
1287 err = -ENODEV;
1288 goto unlock;
1289 }
Jesse Grossccb13522011-10-25 19:26:31 -07001290
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001291 table = ovsl_dereference(dp->table);
Jesse Grossccb13522011-10-25 19:26:31 -07001292 flow = ovs_flow_tbl_lookup(table, &key, key_len);
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001293 if (!flow) {
1294 err = -ENOENT;
1295 goto unlock;
1296 }
Jesse Grossccb13522011-10-25 19:26:31 -07001297
Eric W. Biederman15e47302012-09-07 20:12:54 +00001298 reply = ovs_flow_cmd_build_info(flow, dp, info->snd_portid,
Jesse Grossccb13522011-10-25 19:26:31 -07001299 info->snd_seq, OVS_FLOW_CMD_NEW);
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001300 if (IS_ERR(reply)) {
1301 err = PTR_ERR(reply);
1302 goto unlock;
1303 }
Jesse Grossccb13522011-10-25 19:26:31 -07001304
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001305 ovs_unlock();
Jesse Grossccb13522011-10-25 19:26:31 -07001306 return genlmsg_reply(reply, info);
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001307unlock:
1308 ovs_unlock();
1309 return err;
Jesse Grossccb13522011-10-25 19:26:31 -07001310}
1311
1312static int ovs_flow_cmd_del(struct sk_buff *skb, struct genl_info *info)
1313{
1314 struct nlattr **a = info->attrs;
1315 struct ovs_header *ovs_header = info->userhdr;
1316 struct sw_flow_key key;
1317 struct sk_buff *reply;
1318 struct sw_flow *flow;
1319 struct datapath *dp;
1320 struct flow_table *table;
1321 int err;
1322 int key_len;
1323
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001324 ovs_lock();
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001325 dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex);
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001326 if (!dp) {
1327 err = -ENODEV;
1328 goto unlock;
1329 }
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001330
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001331 if (!a[OVS_FLOW_ATTR_KEY]) {
1332 err = flush_flows(dp);
1333 goto unlock;
1334 }
Jesse Grossccb13522011-10-25 19:26:31 -07001335 err = ovs_flow_from_nlattrs(&key, &key_len, a[OVS_FLOW_ATTR_KEY]);
1336 if (err)
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001337 goto unlock;
Jesse Grossccb13522011-10-25 19:26:31 -07001338
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001339 table = ovsl_dereference(dp->table);
Jesse Grossccb13522011-10-25 19:26:31 -07001340 flow = ovs_flow_tbl_lookup(table, &key, key_len);
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001341 if (!flow) {
1342 err = -ENOENT;
1343 goto unlock;
1344 }
Jesse Grossccb13522011-10-25 19:26:31 -07001345
1346 reply = ovs_flow_cmd_alloc_info(flow);
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001347 if (!reply) {
1348 err = -ENOMEM;
1349 goto unlock;
1350 }
Jesse Grossccb13522011-10-25 19:26:31 -07001351
1352 ovs_flow_tbl_remove(table, flow);
1353
Eric W. Biederman15e47302012-09-07 20:12:54 +00001354 err = ovs_flow_cmd_fill_info(flow, dp, reply, info->snd_portid,
Jesse Grossccb13522011-10-25 19:26:31 -07001355 info->snd_seq, 0, OVS_FLOW_CMD_DEL);
1356 BUG_ON(err < 0);
1357
1358 ovs_flow_deferred_free(flow);
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001359 ovs_unlock();
Jesse Grossccb13522011-10-25 19:26:31 -07001360
Thomas Grafed661182013-03-29 14:46:50 +01001361 ovs_notify(reply, info, &ovs_dp_flow_multicast_group);
Jesse Grossccb13522011-10-25 19:26:31 -07001362 return 0;
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001363unlock:
1364 ovs_unlock();
1365 return err;
Jesse Grossccb13522011-10-25 19:26:31 -07001366}
1367
1368static int ovs_flow_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb)
1369{
1370 struct ovs_header *ovs_header = genlmsg_data(nlmsg_data(cb->nlh));
1371 struct datapath *dp;
1372 struct flow_table *table;
1373
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001374 ovs_lock();
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001375 dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex);
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001376 if (!dp) {
1377 ovs_unlock();
Jesse Grossccb13522011-10-25 19:26:31 -07001378 return -ENODEV;
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001379 }
Jesse Grossccb13522011-10-25 19:26:31 -07001380
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001381 table = ovsl_dereference(dp->table);
Jesse Grossccb13522011-10-25 19:26:31 -07001382
1383 for (;;) {
1384 struct sw_flow *flow;
1385 u32 bucket, obj;
1386
1387 bucket = cb->args[0];
1388 obj = cb->args[1];
1389 flow = ovs_flow_tbl_next(table, &bucket, &obj);
1390 if (!flow)
1391 break;
1392
1393 if (ovs_flow_cmd_fill_info(flow, dp, skb,
Eric W. Biederman15e47302012-09-07 20:12:54 +00001394 NETLINK_CB(cb->skb).portid,
Jesse Grossccb13522011-10-25 19:26:31 -07001395 cb->nlh->nlmsg_seq, NLM_F_MULTI,
1396 OVS_FLOW_CMD_NEW) < 0)
1397 break;
1398
1399 cb->args[0] = bucket;
1400 cb->args[1] = obj;
1401 }
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001402 ovs_unlock();
Jesse Grossccb13522011-10-25 19:26:31 -07001403 return skb->len;
1404}
1405
1406static struct genl_ops dp_flow_genl_ops[] = {
1407 { .cmd = OVS_FLOW_CMD_NEW,
1408 .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
1409 .policy = flow_policy,
1410 .doit = ovs_flow_cmd_new_or_set
1411 },
1412 { .cmd = OVS_FLOW_CMD_DEL,
1413 .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
1414 .policy = flow_policy,
1415 .doit = ovs_flow_cmd_del
1416 },
1417 { .cmd = OVS_FLOW_CMD_GET,
1418 .flags = 0, /* OK for unprivileged users. */
1419 .policy = flow_policy,
1420 .doit = ovs_flow_cmd_get,
1421 .dumpit = ovs_flow_cmd_dump
1422 },
1423 { .cmd = OVS_FLOW_CMD_SET,
1424 .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
1425 .policy = flow_policy,
1426 .doit = ovs_flow_cmd_new_or_set,
1427 },
1428};
1429
1430static const struct nla_policy datapath_policy[OVS_DP_ATTR_MAX + 1] = {
1431 [OVS_DP_ATTR_NAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ - 1 },
1432 [OVS_DP_ATTR_UPCALL_PID] = { .type = NLA_U32 },
1433};
1434
1435static struct genl_family dp_datapath_genl_family = {
1436 .id = GENL_ID_GENERATE,
1437 .hdrsize = sizeof(struct ovs_header),
1438 .name = OVS_DATAPATH_FAMILY,
1439 .version = OVS_DATAPATH_VERSION,
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001440 .maxattr = OVS_DP_ATTR_MAX,
Pravin B Shelar3a4e0d62013-04-23 07:48:48 +00001441 .netnsok = true,
1442 .parallel_ops = true,
Jesse Grossccb13522011-10-25 19:26:31 -07001443};
1444
1445static struct genl_multicast_group ovs_dp_datapath_multicast_group = {
1446 .name = OVS_DATAPATH_MCGROUP
1447};
1448
Thomas Grafc3ff8cf2013-03-29 14:46:49 +01001449static size_t ovs_dp_cmd_msg_size(void)
1450{
1451 size_t msgsize = NLMSG_ALIGN(sizeof(struct ovs_header));
1452
1453 msgsize += nla_total_size(IFNAMSIZ);
1454 msgsize += nla_total_size(sizeof(struct ovs_dp_stats));
1455
1456 return msgsize;
1457}
1458
Jesse Grossccb13522011-10-25 19:26:31 -07001459static int ovs_dp_cmd_fill_info(struct datapath *dp, struct sk_buff *skb,
Eric W. Biederman15e47302012-09-07 20:12:54 +00001460 u32 portid, u32 seq, u32 flags, u8 cmd)
Jesse Grossccb13522011-10-25 19:26:31 -07001461{
1462 struct ovs_header *ovs_header;
1463 struct ovs_dp_stats dp_stats;
1464 int err;
1465
Eric W. Biederman15e47302012-09-07 20:12:54 +00001466 ovs_header = genlmsg_put(skb, portid, seq, &dp_datapath_genl_family,
Jesse Grossccb13522011-10-25 19:26:31 -07001467 flags, cmd);
1468 if (!ovs_header)
1469 goto error;
1470
1471 ovs_header->dp_ifindex = get_dpifindex(dp);
1472
1473 rcu_read_lock();
1474 err = nla_put_string(skb, OVS_DP_ATTR_NAME, ovs_dp_name(dp));
1475 rcu_read_unlock();
1476 if (err)
1477 goto nla_put_failure;
1478
1479 get_dp_stats(dp, &dp_stats);
David S. Miller028d6a62012-03-29 23:20:48 -04001480 if (nla_put(skb, OVS_DP_ATTR_STATS, sizeof(struct ovs_dp_stats), &dp_stats))
1481 goto nla_put_failure;
Jesse Grossccb13522011-10-25 19:26:31 -07001482
1483 return genlmsg_end(skb, ovs_header);
1484
1485nla_put_failure:
1486 genlmsg_cancel(skb, ovs_header);
1487error:
1488 return -EMSGSIZE;
1489}
1490
Eric W. Biederman15e47302012-09-07 20:12:54 +00001491static struct sk_buff *ovs_dp_cmd_build_info(struct datapath *dp, u32 portid,
Jesse Grossccb13522011-10-25 19:26:31 -07001492 u32 seq, u8 cmd)
1493{
1494 struct sk_buff *skb;
1495 int retval;
1496
Thomas Grafc3ff8cf2013-03-29 14:46:49 +01001497 skb = genlmsg_new(ovs_dp_cmd_msg_size(), GFP_KERNEL);
Jesse Grossccb13522011-10-25 19:26:31 -07001498 if (!skb)
1499 return ERR_PTR(-ENOMEM);
1500
Eric W. Biederman15e47302012-09-07 20:12:54 +00001501 retval = ovs_dp_cmd_fill_info(dp, skb, portid, seq, 0, cmd);
Jesse Grossccb13522011-10-25 19:26:31 -07001502 if (retval < 0) {
1503 kfree_skb(skb);
1504 return ERR_PTR(retval);
1505 }
1506 return skb;
1507}
1508
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001509/* Called with ovs_mutex. */
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001510static struct datapath *lookup_datapath(struct net *net,
1511 struct ovs_header *ovs_header,
Jesse Grossccb13522011-10-25 19:26:31 -07001512 struct nlattr *a[OVS_DP_ATTR_MAX + 1])
1513{
1514 struct datapath *dp;
1515
1516 if (!a[OVS_DP_ATTR_NAME])
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001517 dp = get_dp(net, ovs_header->dp_ifindex);
Jesse Grossccb13522011-10-25 19:26:31 -07001518 else {
1519 struct vport *vport;
1520
1521 rcu_read_lock();
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001522 vport = ovs_vport_locate(net, nla_data(a[OVS_DP_ATTR_NAME]));
Jesse Grossccb13522011-10-25 19:26:31 -07001523 dp = vport && vport->port_no == OVSP_LOCAL ? vport->dp : NULL;
1524 rcu_read_unlock();
1525 }
1526 return dp ? dp : ERR_PTR(-ENODEV);
1527}
1528
1529static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info)
1530{
1531 struct nlattr **a = info->attrs;
1532 struct vport_parms parms;
1533 struct sk_buff *reply;
1534 struct datapath *dp;
1535 struct vport *vport;
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001536 struct ovs_net *ovs_net;
Pravin B Shelar15eac2a2012-08-23 12:40:54 -07001537 int err, i;
Jesse Grossccb13522011-10-25 19:26:31 -07001538
1539 err = -EINVAL;
1540 if (!a[OVS_DP_ATTR_NAME] || !a[OVS_DP_ATTR_UPCALL_PID])
1541 goto err;
1542
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001543 ovs_lock();
Jesse Grossccb13522011-10-25 19:26:31 -07001544
1545 err = -ENOMEM;
1546 dp = kzalloc(sizeof(*dp), GFP_KERNEL);
1547 if (dp == NULL)
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001548 goto err_unlock_ovs;
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001549
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001550 ovs_dp_set_net(dp, hold_net(sock_net(skb->sk)));
Jesse Grossccb13522011-10-25 19:26:31 -07001551
1552 /* Allocate table. */
1553 err = -ENOMEM;
1554 rcu_assign_pointer(dp->table, ovs_flow_tbl_alloc(TBL_MIN_BUCKETS));
1555 if (!dp->table)
1556 goto err_free_dp;
1557
1558 dp->stats_percpu = alloc_percpu(struct dp_stats_percpu);
1559 if (!dp->stats_percpu) {
1560 err = -ENOMEM;
1561 goto err_destroy_table;
1562 }
1563
Pravin B Shelar15eac2a2012-08-23 12:40:54 -07001564 dp->ports = kmalloc(DP_VPORT_HASH_BUCKETS * sizeof(struct hlist_head),
1565 GFP_KERNEL);
1566 if (!dp->ports) {
1567 err = -ENOMEM;
1568 goto err_destroy_percpu;
1569 }
1570
1571 for (i = 0; i < DP_VPORT_HASH_BUCKETS; i++)
1572 INIT_HLIST_HEAD(&dp->ports[i]);
1573
Jesse Grossccb13522011-10-25 19:26:31 -07001574 /* Set up our datapath device. */
1575 parms.name = nla_data(a[OVS_DP_ATTR_NAME]);
1576 parms.type = OVS_VPORT_TYPE_INTERNAL;
1577 parms.options = NULL;
1578 parms.dp = dp;
1579 parms.port_no = OVSP_LOCAL;
Eric W. Biederman15e47302012-09-07 20:12:54 +00001580 parms.upcall_portid = nla_get_u32(a[OVS_DP_ATTR_UPCALL_PID]);
Jesse Grossccb13522011-10-25 19:26:31 -07001581
1582 vport = new_vport(&parms);
1583 if (IS_ERR(vport)) {
1584 err = PTR_ERR(vport);
1585 if (err == -EBUSY)
1586 err = -EEXIST;
1587
Pravin B Shelar15eac2a2012-08-23 12:40:54 -07001588 goto err_destroy_ports_array;
Jesse Grossccb13522011-10-25 19:26:31 -07001589 }
1590
Eric W. Biederman15e47302012-09-07 20:12:54 +00001591 reply = ovs_dp_cmd_build_info(dp, info->snd_portid,
Jesse Grossccb13522011-10-25 19:26:31 -07001592 info->snd_seq, OVS_DP_CMD_NEW);
1593 err = PTR_ERR(reply);
1594 if (IS_ERR(reply))
1595 goto err_destroy_local_port;
1596
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001597 ovs_net = net_generic(ovs_dp_get_net(dp), ovs_net_id);
1598 list_add_tail(&dp->list_node, &ovs_net->dps);
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001599
1600 ovs_unlock();
Jesse Grossccb13522011-10-25 19:26:31 -07001601
Thomas Grafed661182013-03-29 14:46:50 +01001602 ovs_notify(reply, info, &ovs_dp_datapath_multicast_group);
Jesse Grossccb13522011-10-25 19:26:31 -07001603 return 0;
1604
1605err_destroy_local_port:
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001606 ovs_dp_detach_port(ovs_vport_ovsl(dp, OVSP_LOCAL));
Pravin B Shelar15eac2a2012-08-23 12:40:54 -07001607err_destroy_ports_array:
1608 kfree(dp->ports);
Jesse Grossccb13522011-10-25 19:26:31 -07001609err_destroy_percpu:
1610 free_percpu(dp->stats_percpu);
1611err_destroy_table:
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001612 ovs_flow_tbl_destroy(ovsl_dereference(dp->table));
Jesse Grossccb13522011-10-25 19:26:31 -07001613err_free_dp:
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001614 release_net(ovs_dp_get_net(dp));
Jesse Grossccb13522011-10-25 19:26:31 -07001615 kfree(dp);
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001616err_unlock_ovs:
1617 ovs_unlock();
Jesse Grossccb13522011-10-25 19:26:31 -07001618err:
1619 return err;
1620}
1621
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001622/* Called with ovs_mutex. */
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001623static void __dp_destroy(struct datapath *dp)
Jesse Grossccb13522011-10-25 19:26:31 -07001624{
Pravin B Shelar15eac2a2012-08-23 12:40:54 -07001625 int i;
Jesse Grossccb13522011-10-25 19:26:31 -07001626
Pravin B Shelar15eac2a2012-08-23 12:40:54 -07001627 for (i = 0; i < DP_VPORT_HASH_BUCKETS; i++) {
1628 struct vport *vport;
Sasha Levinb67bfe02013-02-27 17:06:00 -08001629 struct hlist_node *n;
Pravin B Shelar15eac2a2012-08-23 12:40:54 -07001630
Sasha Levinb67bfe02013-02-27 17:06:00 -08001631 hlist_for_each_entry_safe(vport, n, &dp->ports[i], dp_hash_node)
Pravin B Shelar15eac2a2012-08-23 12:40:54 -07001632 if (vport->port_no != OVSP_LOCAL)
1633 ovs_dp_detach_port(vport);
1634 }
Jesse Grossccb13522011-10-25 19:26:31 -07001635
1636 list_del(&dp->list_node);
Jesse Grossccb13522011-10-25 19:26:31 -07001637
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001638 /* OVSP_LOCAL is datapath internal port. We need to make sure that
1639 * all port in datapath are destroyed first before freeing datapath.
Jesse Grossccb13522011-10-25 19:26:31 -07001640 */
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001641 ovs_dp_detach_port(ovs_vport_ovsl(dp, OVSP_LOCAL));
Jesse Grossccb13522011-10-25 19:26:31 -07001642
1643 call_rcu(&dp->rcu, destroy_dp_rcu);
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001644}
1645
1646static int ovs_dp_cmd_del(struct sk_buff *skb, struct genl_info *info)
1647{
1648 struct sk_buff *reply;
1649 struct datapath *dp;
1650 int err;
1651
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001652 ovs_lock();
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001653 dp = lookup_datapath(sock_net(skb->sk), info->userhdr, info->attrs);
1654 err = PTR_ERR(dp);
1655 if (IS_ERR(dp))
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001656 goto unlock;
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001657
Eric W. Biederman15e47302012-09-07 20:12:54 +00001658 reply = ovs_dp_cmd_build_info(dp, info->snd_portid,
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001659 info->snd_seq, OVS_DP_CMD_DEL);
1660 err = PTR_ERR(reply);
1661 if (IS_ERR(reply))
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001662 goto unlock;
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001663
1664 __dp_destroy(dp);
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001665 ovs_unlock();
Jesse Grossccb13522011-10-25 19:26:31 -07001666
Thomas Grafed661182013-03-29 14:46:50 +01001667 ovs_notify(reply, info, &ovs_dp_datapath_multicast_group);
Jesse Grossccb13522011-10-25 19:26:31 -07001668
1669 return 0;
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001670unlock:
1671 ovs_unlock();
1672 return err;
Jesse Grossccb13522011-10-25 19:26:31 -07001673}
1674
1675static int ovs_dp_cmd_set(struct sk_buff *skb, struct genl_info *info)
1676{
1677 struct sk_buff *reply;
1678 struct datapath *dp;
1679 int err;
1680
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001681 ovs_lock();
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001682 dp = lookup_datapath(sock_net(skb->sk), info->userhdr, info->attrs);
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001683 err = PTR_ERR(dp);
Jesse Grossccb13522011-10-25 19:26:31 -07001684 if (IS_ERR(dp))
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001685 goto unlock;
Jesse Grossccb13522011-10-25 19:26:31 -07001686
Eric W. Biederman15e47302012-09-07 20:12:54 +00001687 reply = ovs_dp_cmd_build_info(dp, info->snd_portid,
Jesse Grossccb13522011-10-25 19:26:31 -07001688 info->snd_seq, OVS_DP_CMD_NEW);
1689 if (IS_ERR(reply)) {
1690 err = PTR_ERR(reply);
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001691 netlink_set_err(sock_net(skb->sk)->genl_sock, 0,
Jesse Grossccb13522011-10-25 19:26:31 -07001692 ovs_dp_datapath_multicast_group.id, err);
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001693 err = 0;
1694 goto unlock;
Jesse Grossccb13522011-10-25 19:26:31 -07001695 }
1696
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001697 ovs_unlock();
Thomas Grafed661182013-03-29 14:46:50 +01001698 ovs_notify(reply, info, &ovs_dp_datapath_multicast_group);
Jesse Grossccb13522011-10-25 19:26:31 -07001699
1700 return 0;
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001701unlock:
1702 ovs_unlock();
1703 return err;
Jesse Grossccb13522011-10-25 19:26:31 -07001704}
1705
1706static int ovs_dp_cmd_get(struct sk_buff *skb, struct genl_info *info)
1707{
1708 struct sk_buff *reply;
1709 struct datapath *dp;
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001710 int err;
Jesse Grossccb13522011-10-25 19:26:31 -07001711
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001712 ovs_lock();
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001713 dp = lookup_datapath(sock_net(skb->sk), info->userhdr, info->attrs);
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001714 if (IS_ERR(dp)) {
1715 err = PTR_ERR(dp);
1716 goto unlock;
1717 }
Jesse Grossccb13522011-10-25 19:26:31 -07001718
Eric W. Biederman15e47302012-09-07 20:12:54 +00001719 reply = ovs_dp_cmd_build_info(dp, info->snd_portid,
Jesse Grossccb13522011-10-25 19:26:31 -07001720 info->snd_seq, OVS_DP_CMD_NEW);
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001721 if (IS_ERR(reply)) {
1722 err = PTR_ERR(reply);
1723 goto unlock;
1724 }
Jesse Grossccb13522011-10-25 19:26:31 -07001725
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001726 ovs_unlock();
Jesse Grossccb13522011-10-25 19:26:31 -07001727 return genlmsg_reply(reply, info);
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001728
1729unlock:
1730 ovs_unlock();
1731 return err;
Jesse Grossccb13522011-10-25 19:26:31 -07001732}
1733
1734static int ovs_dp_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb)
1735{
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001736 struct ovs_net *ovs_net = net_generic(sock_net(skb->sk), ovs_net_id);
Jesse Grossccb13522011-10-25 19:26:31 -07001737 struct datapath *dp;
1738 int skip = cb->args[0];
1739 int i = 0;
1740
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001741 ovs_lock();
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001742 list_for_each_entry(dp, &ovs_net->dps, list_node) {
Ben Pfaff77676fd2012-01-17 13:33:39 +00001743 if (i >= skip &&
Eric W. Biederman15e47302012-09-07 20:12:54 +00001744 ovs_dp_cmd_fill_info(dp, skb, NETLINK_CB(cb->skb).portid,
Jesse Grossccb13522011-10-25 19:26:31 -07001745 cb->nlh->nlmsg_seq, NLM_F_MULTI,
1746 OVS_DP_CMD_NEW) < 0)
1747 break;
1748 i++;
1749 }
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001750 ovs_unlock();
Jesse Grossccb13522011-10-25 19:26:31 -07001751
1752 cb->args[0] = i;
1753
1754 return skb->len;
1755}
1756
1757static struct genl_ops dp_datapath_genl_ops[] = {
1758 { .cmd = OVS_DP_CMD_NEW,
1759 .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
1760 .policy = datapath_policy,
1761 .doit = ovs_dp_cmd_new
1762 },
1763 { .cmd = OVS_DP_CMD_DEL,
1764 .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
1765 .policy = datapath_policy,
1766 .doit = ovs_dp_cmd_del
1767 },
1768 { .cmd = OVS_DP_CMD_GET,
1769 .flags = 0, /* OK for unprivileged users. */
1770 .policy = datapath_policy,
1771 .doit = ovs_dp_cmd_get,
1772 .dumpit = ovs_dp_cmd_dump
1773 },
1774 { .cmd = OVS_DP_CMD_SET,
1775 .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
1776 .policy = datapath_policy,
1777 .doit = ovs_dp_cmd_set,
1778 },
1779};
1780
1781static const struct nla_policy vport_policy[OVS_VPORT_ATTR_MAX + 1] = {
1782 [OVS_VPORT_ATTR_NAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ - 1 },
1783 [OVS_VPORT_ATTR_STATS] = { .len = sizeof(struct ovs_vport_stats) },
1784 [OVS_VPORT_ATTR_PORT_NO] = { .type = NLA_U32 },
1785 [OVS_VPORT_ATTR_TYPE] = { .type = NLA_U32 },
1786 [OVS_VPORT_ATTR_UPCALL_PID] = { .type = NLA_U32 },
1787 [OVS_VPORT_ATTR_OPTIONS] = { .type = NLA_NESTED },
1788};
1789
1790static struct genl_family dp_vport_genl_family = {
1791 .id = GENL_ID_GENERATE,
1792 .hdrsize = sizeof(struct ovs_header),
1793 .name = OVS_VPORT_FAMILY,
1794 .version = OVS_VPORT_VERSION,
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001795 .maxattr = OVS_VPORT_ATTR_MAX,
Pravin B Shelar3a4e0d62013-04-23 07:48:48 +00001796 .netnsok = true,
1797 .parallel_ops = true,
Jesse Grossccb13522011-10-25 19:26:31 -07001798};
1799
1800struct genl_multicast_group ovs_dp_vport_multicast_group = {
1801 .name = OVS_VPORT_MCGROUP
1802};
1803
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001804/* Called with ovs_mutex or RCU read lock. */
Jesse Grossccb13522011-10-25 19:26:31 -07001805static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb,
Eric W. Biederman15e47302012-09-07 20:12:54 +00001806 u32 portid, u32 seq, u32 flags, u8 cmd)
Jesse Grossccb13522011-10-25 19:26:31 -07001807{
1808 struct ovs_header *ovs_header;
1809 struct ovs_vport_stats vport_stats;
1810 int err;
1811
Eric W. Biederman15e47302012-09-07 20:12:54 +00001812 ovs_header = genlmsg_put(skb, portid, seq, &dp_vport_genl_family,
Jesse Grossccb13522011-10-25 19:26:31 -07001813 flags, cmd);
1814 if (!ovs_header)
1815 return -EMSGSIZE;
1816
1817 ovs_header->dp_ifindex = get_dpifindex(vport->dp);
1818
David S. Miller028d6a62012-03-29 23:20:48 -04001819 if (nla_put_u32(skb, OVS_VPORT_ATTR_PORT_NO, vport->port_no) ||
1820 nla_put_u32(skb, OVS_VPORT_ATTR_TYPE, vport->ops->type) ||
1821 nla_put_string(skb, OVS_VPORT_ATTR_NAME, vport->ops->get_name(vport)) ||
Eric W. Biederman15e47302012-09-07 20:12:54 +00001822 nla_put_u32(skb, OVS_VPORT_ATTR_UPCALL_PID, vport->upcall_portid))
David S. Miller028d6a62012-03-29 23:20:48 -04001823 goto nla_put_failure;
Jesse Grossccb13522011-10-25 19:26:31 -07001824
1825 ovs_vport_get_stats(vport, &vport_stats);
David S. Miller028d6a62012-03-29 23:20:48 -04001826 if (nla_put(skb, OVS_VPORT_ATTR_STATS, sizeof(struct ovs_vport_stats),
1827 &vport_stats))
1828 goto nla_put_failure;
Jesse Grossccb13522011-10-25 19:26:31 -07001829
1830 err = ovs_vport_get_options(vport, skb);
1831 if (err == -EMSGSIZE)
1832 goto error;
1833
1834 return genlmsg_end(skb, ovs_header);
1835
1836nla_put_failure:
1837 err = -EMSGSIZE;
1838error:
1839 genlmsg_cancel(skb, ovs_header);
1840 return err;
1841}
1842
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001843/* Called with ovs_mutex or RCU read lock. */
Eric W. Biederman15e47302012-09-07 20:12:54 +00001844struct sk_buff *ovs_vport_cmd_build_info(struct vport *vport, u32 portid,
Jesse Grossccb13522011-10-25 19:26:31 -07001845 u32 seq, u8 cmd)
1846{
1847 struct sk_buff *skb;
1848 int retval;
1849
1850 skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
1851 if (!skb)
1852 return ERR_PTR(-ENOMEM);
1853
Eric W. Biederman15e47302012-09-07 20:12:54 +00001854 retval = ovs_vport_cmd_fill_info(vport, skb, portid, seq, 0, cmd);
Jesse Grossa9341512013-03-26 15:48:38 -07001855 BUG_ON(retval < 0);
1856
Jesse Grossccb13522011-10-25 19:26:31 -07001857 return skb;
1858}
1859
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001860/* Called with ovs_mutex or RCU read lock. */
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001861static struct vport *lookup_vport(struct net *net,
1862 struct ovs_header *ovs_header,
Jesse Grossccb13522011-10-25 19:26:31 -07001863 struct nlattr *a[OVS_VPORT_ATTR_MAX + 1])
1864{
1865 struct datapath *dp;
1866 struct vport *vport;
1867
1868 if (a[OVS_VPORT_ATTR_NAME]) {
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001869 vport = ovs_vport_locate(net, nla_data(a[OVS_VPORT_ATTR_NAME]));
Jesse Grossccb13522011-10-25 19:26:31 -07001870 if (!vport)
1871 return ERR_PTR(-ENODEV);
Ben Pfaff651a68e2012-03-06 15:04:04 -08001872 if (ovs_header->dp_ifindex &&
1873 ovs_header->dp_ifindex != get_dpifindex(vport->dp))
1874 return ERR_PTR(-ENODEV);
Jesse Grossccb13522011-10-25 19:26:31 -07001875 return vport;
1876 } else if (a[OVS_VPORT_ATTR_PORT_NO]) {
1877 u32 port_no = nla_get_u32(a[OVS_VPORT_ATTR_PORT_NO]);
1878
1879 if (port_no >= DP_MAX_PORTS)
1880 return ERR_PTR(-EFBIG);
1881
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001882 dp = get_dp(net, ovs_header->dp_ifindex);
Jesse Grossccb13522011-10-25 19:26:31 -07001883 if (!dp)
1884 return ERR_PTR(-ENODEV);
1885
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001886 vport = ovs_vport_ovsl_rcu(dp, port_no);
Jesse Grossccb13522011-10-25 19:26:31 -07001887 if (!vport)
Jarno Rajahalme14408db2013-01-09 14:27:35 -08001888 return ERR_PTR(-ENODEV);
Jesse Grossccb13522011-10-25 19:26:31 -07001889 return vport;
1890 } else
1891 return ERR_PTR(-EINVAL);
1892}
1893
1894static int ovs_vport_cmd_new(struct sk_buff *skb, struct genl_info *info)
1895{
1896 struct nlattr **a = info->attrs;
1897 struct ovs_header *ovs_header = info->userhdr;
1898 struct vport_parms parms;
1899 struct sk_buff *reply;
1900 struct vport *vport;
1901 struct datapath *dp;
1902 u32 port_no;
1903 int err;
1904
1905 err = -EINVAL;
1906 if (!a[OVS_VPORT_ATTR_NAME] || !a[OVS_VPORT_ATTR_TYPE] ||
1907 !a[OVS_VPORT_ATTR_UPCALL_PID])
1908 goto exit;
1909
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001910 ovs_lock();
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001911 dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex);
Jesse Grossccb13522011-10-25 19:26:31 -07001912 err = -ENODEV;
1913 if (!dp)
1914 goto exit_unlock;
1915
1916 if (a[OVS_VPORT_ATTR_PORT_NO]) {
1917 port_no = nla_get_u32(a[OVS_VPORT_ATTR_PORT_NO]);
1918
1919 err = -EFBIG;
1920 if (port_no >= DP_MAX_PORTS)
1921 goto exit_unlock;
1922
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001923 vport = ovs_vport_ovsl(dp, port_no);
Jesse Grossccb13522011-10-25 19:26:31 -07001924 err = -EBUSY;
1925 if (vport)
1926 goto exit_unlock;
1927 } else {
1928 for (port_no = 1; ; port_no++) {
1929 if (port_no >= DP_MAX_PORTS) {
1930 err = -EFBIG;
1931 goto exit_unlock;
1932 }
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001933 vport = ovs_vport_ovsl(dp, port_no);
Jesse Grossccb13522011-10-25 19:26:31 -07001934 if (!vport)
1935 break;
1936 }
1937 }
1938
1939 parms.name = nla_data(a[OVS_VPORT_ATTR_NAME]);
1940 parms.type = nla_get_u32(a[OVS_VPORT_ATTR_TYPE]);
1941 parms.options = a[OVS_VPORT_ATTR_OPTIONS];
1942 parms.dp = dp;
1943 parms.port_no = port_no;
Eric W. Biederman15e47302012-09-07 20:12:54 +00001944 parms.upcall_portid = nla_get_u32(a[OVS_VPORT_ATTR_UPCALL_PID]);
Jesse Grossccb13522011-10-25 19:26:31 -07001945
1946 vport = new_vport(&parms);
1947 err = PTR_ERR(vport);
1948 if (IS_ERR(vport))
1949 goto exit_unlock;
1950
Rich Lanecb7c5bd2013-02-08 13:18:01 -08001951 err = 0;
Eric W. Biederman15e47302012-09-07 20:12:54 +00001952 reply = ovs_vport_cmd_build_info(vport, info->snd_portid, info->snd_seq,
Jesse Grossccb13522011-10-25 19:26:31 -07001953 OVS_VPORT_CMD_NEW);
1954 if (IS_ERR(reply)) {
1955 err = PTR_ERR(reply);
1956 ovs_dp_detach_port(vport);
1957 goto exit_unlock;
1958 }
Thomas Grafed661182013-03-29 14:46:50 +01001959
1960 ovs_notify(reply, info, &ovs_dp_vport_multicast_group);
Jesse Grossccb13522011-10-25 19:26:31 -07001961
1962exit_unlock:
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001963 ovs_unlock();
Jesse Grossccb13522011-10-25 19:26:31 -07001964exit:
1965 return err;
1966}
1967
1968static int ovs_vport_cmd_set(struct sk_buff *skb, struct genl_info *info)
1969{
1970 struct nlattr **a = info->attrs;
1971 struct sk_buff *reply;
1972 struct vport *vport;
1973 int err;
1974
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001975 ovs_lock();
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001976 vport = lookup_vport(sock_net(skb->sk), info->userhdr, a);
Jesse Grossccb13522011-10-25 19:26:31 -07001977 err = PTR_ERR(vport);
1978 if (IS_ERR(vport))
1979 goto exit_unlock;
1980
Jesse Grossccb13522011-10-25 19:26:31 -07001981 if (a[OVS_VPORT_ATTR_TYPE] &&
Jesse Grossf44f3402013-05-13 08:15:26 -07001982 nla_get_u32(a[OVS_VPORT_ATTR_TYPE]) != vport->ops->type) {
Jesse Grossccb13522011-10-25 19:26:31 -07001983 err = -EINVAL;
Jesse Grossf44f3402013-05-13 08:15:26 -07001984 goto exit_unlock;
1985 }
Jesse Grossccb13522011-10-25 19:26:31 -07001986
Jesse Grossa9341512013-03-26 15:48:38 -07001987 reply = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1988 if (!reply) {
1989 err = -ENOMEM;
1990 goto exit_unlock;
1991 }
1992
Jesse Grossf44f3402013-05-13 08:15:26 -07001993 if (a[OVS_VPORT_ATTR_OPTIONS]) {
Jesse Grossccb13522011-10-25 19:26:31 -07001994 err = ovs_vport_set_options(vport, a[OVS_VPORT_ATTR_OPTIONS]);
Jesse Grossf44f3402013-05-13 08:15:26 -07001995 if (err)
1996 goto exit_free;
1997 }
Jesse Grossa9341512013-03-26 15:48:38 -07001998
Ansis Atteka03fbf8b2012-04-09 12:12:12 -07001999 if (a[OVS_VPORT_ATTR_UPCALL_PID])
Eric W. Biederman15e47302012-09-07 20:12:54 +00002000 vport->upcall_portid = nla_get_u32(a[OVS_VPORT_ATTR_UPCALL_PID]);
Jesse Grossccb13522011-10-25 19:26:31 -07002001
Jesse Grossa9341512013-03-26 15:48:38 -07002002 err = ovs_vport_cmd_fill_info(vport, reply, info->snd_portid,
2003 info->snd_seq, 0, OVS_VPORT_CMD_NEW);
2004 BUG_ON(err < 0);
Jesse Grossccb13522011-10-25 19:26:31 -07002005
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07002006 ovs_unlock();
Thomas Grafed661182013-03-29 14:46:50 +01002007 ovs_notify(reply, info, &ovs_dp_vport_multicast_group);
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07002008 return 0;
Jesse Grossccb13522011-10-25 19:26:31 -07002009
Jesse Grossa9341512013-03-26 15:48:38 -07002010 rtnl_unlock();
2011 return 0;
2012
2013exit_free:
2014 kfree_skb(reply);
Jesse Grossccb13522011-10-25 19:26:31 -07002015exit_unlock:
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07002016 ovs_unlock();
Jesse Grossccb13522011-10-25 19:26:31 -07002017 return err;
2018}
2019
2020static int ovs_vport_cmd_del(struct sk_buff *skb, struct genl_info *info)
2021{
2022 struct nlattr **a = info->attrs;
2023 struct sk_buff *reply;
2024 struct vport *vport;
2025 int err;
2026
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07002027 ovs_lock();
Pravin B Shelar46df7b82012-02-22 19:58:59 -08002028 vport = lookup_vport(sock_net(skb->sk), info->userhdr, a);
Jesse Grossccb13522011-10-25 19:26:31 -07002029 err = PTR_ERR(vport);
2030 if (IS_ERR(vport))
2031 goto exit_unlock;
2032
2033 if (vport->port_no == OVSP_LOCAL) {
2034 err = -EINVAL;
2035 goto exit_unlock;
2036 }
2037
Pravin B Shelar74f84a52013-06-17 17:50:12 -07002038 reply = ovs_vport_cmd_build_info(vport, info->snd_portid,
2039 info->snd_seq, OVS_VPORT_CMD_DEL);
Jesse Grossccb13522011-10-25 19:26:31 -07002040 err = PTR_ERR(reply);
2041 if (IS_ERR(reply))
2042 goto exit_unlock;
2043
Rich Lane734907e2013-02-08 09:30:23 -08002044 err = 0;
Jesse Grossccb13522011-10-25 19:26:31 -07002045 ovs_dp_detach_port(vport);
2046
Thomas Grafed661182013-03-29 14:46:50 +01002047 ovs_notify(reply, info, &ovs_dp_vport_multicast_group);
Jesse Grossccb13522011-10-25 19:26:31 -07002048
2049exit_unlock:
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07002050 ovs_unlock();
Jesse Grossccb13522011-10-25 19:26:31 -07002051 return err;
2052}
2053
2054static int ovs_vport_cmd_get(struct sk_buff *skb, struct genl_info *info)
2055{
2056 struct nlattr **a = info->attrs;
2057 struct ovs_header *ovs_header = info->userhdr;
2058 struct sk_buff *reply;
2059 struct vport *vport;
2060 int err;
2061
2062 rcu_read_lock();
Pravin B Shelar46df7b82012-02-22 19:58:59 -08002063 vport = lookup_vport(sock_net(skb->sk), ovs_header, a);
Jesse Grossccb13522011-10-25 19:26:31 -07002064 err = PTR_ERR(vport);
2065 if (IS_ERR(vport))
2066 goto exit_unlock;
2067
Pravin B Shelar74f84a52013-06-17 17:50:12 -07002068 reply = ovs_vport_cmd_build_info(vport, info->snd_portid,
2069 info->snd_seq, OVS_VPORT_CMD_NEW);
Jesse Grossccb13522011-10-25 19:26:31 -07002070 err = PTR_ERR(reply);
2071 if (IS_ERR(reply))
2072 goto exit_unlock;
2073
2074 rcu_read_unlock();
2075
2076 return genlmsg_reply(reply, info);
2077
2078exit_unlock:
2079 rcu_read_unlock();
2080 return err;
2081}
2082
2083static int ovs_vport_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb)
2084{
2085 struct ovs_header *ovs_header = genlmsg_data(nlmsg_data(cb->nlh));
2086 struct datapath *dp;
Pravin B Shelar15eac2a2012-08-23 12:40:54 -07002087 int bucket = cb->args[0], skip = cb->args[1];
2088 int i, j = 0;
Jesse Grossccb13522011-10-25 19:26:31 -07002089
Pravin B Shelar46df7b82012-02-22 19:58:59 -08002090 dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex);
Jesse Grossccb13522011-10-25 19:26:31 -07002091 if (!dp)
2092 return -ENODEV;
2093
2094 rcu_read_lock();
Pravin B Shelar15eac2a2012-08-23 12:40:54 -07002095 for (i = bucket; i < DP_VPORT_HASH_BUCKETS; i++) {
Jesse Grossccb13522011-10-25 19:26:31 -07002096 struct vport *vport;
2097
Pravin B Shelar15eac2a2012-08-23 12:40:54 -07002098 j = 0;
Sasha Levinb67bfe02013-02-27 17:06:00 -08002099 hlist_for_each_entry_rcu(vport, &dp->ports[i], dp_hash_node) {
Pravin B Shelar15eac2a2012-08-23 12:40:54 -07002100 if (j >= skip &&
2101 ovs_vport_cmd_fill_info(vport, skb,
Eric W. Biederman15e47302012-09-07 20:12:54 +00002102 NETLINK_CB(cb->skb).portid,
Pravin B Shelar15eac2a2012-08-23 12:40:54 -07002103 cb->nlh->nlmsg_seq,
2104 NLM_F_MULTI,
2105 OVS_VPORT_CMD_NEW) < 0)
2106 goto out;
Jesse Grossccb13522011-10-25 19:26:31 -07002107
Pravin B Shelar15eac2a2012-08-23 12:40:54 -07002108 j++;
2109 }
2110 skip = 0;
Jesse Grossccb13522011-10-25 19:26:31 -07002111 }
Pravin B Shelar15eac2a2012-08-23 12:40:54 -07002112out:
Jesse Grossccb13522011-10-25 19:26:31 -07002113 rcu_read_unlock();
2114
Pravin B Shelar15eac2a2012-08-23 12:40:54 -07002115 cb->args[0] = i;
2116 cb->args[1] = j;
Jesse Grossccb13522011-10-25 19:26:31 -07002117
Pravin B Shelar15eac2a2012-08-23 12:40:54 -07002118 return skb->len;
Jesse Grossccb13522011-10-25 19:26:31 -07002119}
2120
Jesse Grossccb13522011-10-25 19:26:31 -07002121static struct genl_ops dp_vport_genl_ops[] = {
2122 { .cmd = OVS_VPORT_CMD_NEW,
2123 .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
2124 .policy = vport_policy,
2125 .doit = ovs_vport_cmd_new
2126 },
2127 { .cmd = OVS_VPORT_CMD_DEL,
2128 .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
2129 .policy = vport_policy,
2130 .doit = ovs_vport_cmd_del
2131 },
2132 { .cmd = OVS_VPORT_CMD_GET,
2133 .flags = 0, /* OK for unprivileged users. */
2134 .policy = vport_policy,
2135 .doit = ovs_vport_cmd_get,
2136 .dumpit = ovs_vport_cmd_dump
2137 },
2138 { .cmd = OVS_VPORT_CMD_SET,
2139 .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
2140 .policy = vport_policy,
2141 .doit = ovs_vport_cmd_set,
2142 },
2143};
2144
2145struct genl_family_and_ops {
2146 struct genl_family *family;
2147 struct genl_ops *ops;
2148 int n_ops;
2149 struct genl_multicast_group *group;
2150};
2151
2152static const struct genl_family_and_ops dp_genl_families[] = {
2153 { &dp_datapath_genl_family,
2154 dp_datapath_genl_ops, ARRAY_SIZE(dp_datapath_genl_ops),
2155 &ovs_dp_datapath_multicast_group },
2156 { &dp_vport_genl_family,
2157 dp_vport_genl_ops, ARRAY_SIZE(dp_vport_genl_ops),
2158 &ovs_dp_vport_multicast_group },
2159 { &dp_flow_genl_family,
2160 dp_flow_genl_ops, ARRAY_SIZE(dp_flow_genl_ops),
2161 &ovs_dp_flow_multicast_group },
2162 { &dp_packet_genl_family,
2163 dp_packet_genl_ops, ARRAY_SIZE(dp_packet_genl_ops),
2164 NULL },
2165};
2166
2167static void dp_unregister_genl(int n_families)
2168{
2169 int i;
2170
2171 for (i = 0; i < n_families; i++)
2172 genl_unregister_family(dp_genl_families[i].family);
2173}
2174
2175static int dp_register_genl(void)
2176{
2177 int n_registered;
2178 int err;
2179 int i;
2180
2181 n_registered = 0;
2182 for (i = 0; i < ARRAY_SIZE(dp_genl_families); i++) {
2183 const struct genl_family_and_ops *f = &dp_genl_families[i];
2184
2185 err = genl_register_family_with_ops(f->family, f->ops,
2186 f->n_ops);
2187 if (err)
2188 goto error;
2189 n_registered++;
2190
2191 if (f->group) {
2192 err = genl_register_mc_group(f->family, f->group);
2193 if (err)
2194 goto error;
2195 }
2196 }
2197
2198 return 0;
2199
2200error:
2201 dp_unregister_genl(n_registered);
2202 return err;
2203}
2204
Pravin B Shelar46df7b82012-02-22 19:58:59 -08002205static void rehash_flow_table(struct work_struct *work)
2206{
2207 struct datapath *dp;
2208 struct net *net;
2209
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07002210 ovs_lock();
Pravin B Shelar46df7b82012-02-22 19:58:59 -08002211 rtnl_lock();
2212 for_each_net(net) {
2213 struct ovs_net *ovs_net = net_generic(net, ovs_net_id);
2214
2215 list_for_each_entry(dp, &ovs_net->dps, list_node) {
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07002216 struct flow_table *old_table = ovsl_dereference(dp->table);
Pravin B Shelar46df7b82012-02-22 19:58:59 -08002217 struct flow_table *new_table;
2218
2219 new_table = ovs_flow_tbl_rehash(old_table);
2220 if (!IS_ERR(new_table)) {
2221 rcu_assign_pointer(dp->table, new_table);
2222 ovs_flow_tbl_deferred_destroy(old_table);
2223 }
2224 }
2225 }
2226 rtnl_unlock();
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07002227 ovs_unlock();
Pravin B Shelar46df7b82012-02-22 19:58:59 -08002228 schedule_delayed_work(&rehash_flow_wq, REHASH_FLOW_INTERVAL);
2229}
2230
2231static int __net_init ovs_init_net(struct net *net)
2232{
2233 struct ovs_net *ovs_net = net_generic(net, ovs_net_id);
2234
2235 INIT_LIST_HEAD(&ovs_net->dps);
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07002236 INIT_WORK(&ovs_net->dp_notify_work, ovs_dp_notify_wq);
Pravin B Shelar46df7b82012-02-22 19:58:59 -08002237 return 0;
2238}
2239
2240static void __net_exit ovs_exit_net(struct net *net)
2241{
Pravin B Shelar46df7b82012-02-22 19:58:59 -08002242 struct datapath *dp, *dp_next;
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07002243 struct ovs_net *ovs_net = net_generic(net, ovs_net_id);
Pravin B Shelar46df7b82012-02-22 19:58:59 -08002244
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07002245 ovs_lock();
Pravin B Shelar46df7b82012-02-22 19:58:59 -08002246 list_for_each_entry_safe(dp, dp_next, &ovs_net->dps, list_node)
2247 __dp_destroy(dp);
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07002248 ovs_unlock();
2249
2250 cancel_work_sync(&ovs_net->dp_notify_work);
Pravin B Shelar46df7b82012-02-22 19:58:59 -08002251}
2252
2253static struct pernet_operations ovs_net_ops = {
2254 .init = ovs_init_net,
2255 .exit = ovs_exit_net,
2256 .id = &ovs_net_id,
2257 .size = sizeof(struct ovs_net),
2258};
2259
Jesse Grossccb13522011-10-25 19:26:31 -07002260static int __init dp_init(void)
2261{
Jesse Grossccb13522011-10-25 19:26:31 -07002262 int err;
2263
YOSHIFUJI Hideaki / 吉藤英明3523b292013-01-09 07:19:55 +00002264 BUILD_BUG_ON(sizeof(struct ovs_skb_cb) > FIELD_SIZEOF(struct sk_buff, cb));
Jesse Grossccb13522011-10-25 19:26:31 -07002265
2266 pr_info("Open vSwitch switching datapath\n");
2267
2268 err = ovs_flow_init();
2269 if (err)
2270 goto error;
2271
2272 err = ovs_vport_init();
2273 if (err)
2274 goto error_flow_exit;
2275
Pravin B Shelar46df7b82012-02-22 19:58:59 -08002276 err = register_pernet_device(&ovs_net_ops);
Jesse Grossccb13522011-10-25 19:26:31 -07002277 if (err)
2278 goto error_vport_exit;
2279
Pravin B Shelar46df7b82012-02-22 19:58:59 -08002280 err = register_netdevice_notifier(&ovs_dp_device_notifier);
2281 if (err)
2282 goto error_netns_exit;
2283
Jesse Grossccb13522011-10-25 19:26:31 -07002284 err = dp_register_genl();
2285 if (err < 0)
2286 goto error_unreg_notifier;
2287
2288 schedule_delayed_work(&rehash_flow_wq, REHASH_FLOW_INTERVAL);
2289
2290 return 0;
2291
2292error_unreg_notifier:
2293 unregister_netdevice_notifier(&ovs_dp_device_notifier);
Pravin B Shelar46df7b82012-02-22 19:58:59 -08002294error_netns_exit:
2295 unregister_pernet_device(&ovs_net_ops);
Jesse Grossccb13522011-10-25 19:26:31 -07002296error_vport_exit:
2297 ovs_vport_exit();
2298error_flow_exit:
2299 ovs_flow_exit();
2300error:
2301 return err;
2302}
2303
2304static void dp_cleanup(void)
2305{
2306 cancel_delayed_work_sync(&rehash_flow_wq);
Jesse Grossccb13522011-10-25 19:26:31 -07002307 dp_unregister_genl(ARRAY_SIZE(dp_genl_families));
2308 unregister_netdevice_notifier(&ovs_dp_device_notifier);
Pravin B Shelar46df7b82012-02-22 19:58:59 -08002309 unregister_pernet_device(&ovs_net_ops);
2310 rcu_barrier();
Jesse Grossccb13522011-10-25 19:26:31 -07002311 ovs_vport_exit();
2312 ovs_flow_exit();
2313}
2314
2315module_init(dp_init);
2316module_exit(dp_cleanup);
2317
2318MODULE_DESCRIPTION("Open vSwitch switching datapath");
2319MODULE_LICENSE("GPL");