blob: 4fd8a45e5d56828cef84743b743c7fbef1ccffa3 [file] [log] [blame]
Jesse Grossccb13522011-10-25 19:26:31 -07001/*
Ben Pfaffad552002014-05-06 16:48:38 -07002 * Copyright (c) 2007-2014 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>
47#include <linux/openvswitch.h>
48#include <linux/rculist.h>
49#include <linux/dmi.h>
Jesse Grossccb13522011-10-25 19:26:31 -070050#include <net/genetlink.h>
Pravin B Shelar46df7b82012-02-22 19:58:59 -080051#include <net/net_namespace.h>
52#include <net/netns/generic.h>
Jesse Grossccb13522011-10-25 19:26:31 -070053
54#include "datapath.h"
55#include "flow.h"
Andy Zhoue80857c2014-01-21 09:31:04 -080056#include "flow_table.h"
Pravin B Shelare6445712013-10-03 18:16:47 -070057#include "flow_netlink.h"
Jesse Grossccb13522011-10-25 19:26:31 -070058#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 Shelar8e4e1712013-04-15 13:23:03 -070061int ovs_net_id __read_mostly;
Thomas Graf62b9c8d2014-10-22 17:29:06 +020062EXPORT_SYMBOL(ovs_net_id);
Pravin B Shelar8e4e1712013-04-15 13:23:03 -070063
Pravin B Shelar0c200ef2014-05-06 16:44:50 -070064static struct genl_family dp_packet_genl_family;
65static struct genl_family dp_flow_genl_family;
66static struct genl_family dp_datapath_genl_family;
67
stephen hemminger48e48a72014-07-16 11:25:52 -070068static const struct genl_multicast_group ovs_dp_flow_multicast_group = {
69 .name = OVS_FLOW_MCGROUP,
Pravin B Shelar0c200ef2014-05-06 16:44:50 -070070};
71
stephen hemminger48e48a72014-07-16 11:25:52 -070072static const struct genl_multicast_group ovs_dp_datapath_multicast_group = {
73 .name = OVS_DATAPATH_MCGROUP,
Pravin B Shelar0c200ef2014-05-06 16:44:50 -070074};
75
stephen hemminger48e48a72014-07-16 11:25:52 -070076static const struct genl_multicast_group ovs_dp_vport_multicast_group = {
77 .name = OVS_VPORT_MCGROUP,
Pravin B Shelar0c200ef2014-05-06 16:44:50 -070078};
79
Jarno Rajahalmefb5d1e92014-05-05 13:13:14 -070080/* Check if need to build a reply message.
81 * OVS userspace sets the NLM_F_ECHO flag if it needs the reply. */
Samuel Gauthier9b67aa42014-09-18 10:31:04 +020082static bool ovs_must_notify(struct genl_family *family, struct genl_info *info,
83 unsigned int group)
Jarno Rajahalmefb5d1e92014-05-05 13:13:14 -070084{
85 return info->nlhdr->nlmsg_flags & NLM_F_ECHO ||
Samuel Gauthier9b67aa42014-09-18 10:31:04 +020086 genl_has_listeners(family, genl_info_net(info)->genl_sock,
87 group);
Jarno Rajahalmefb5d1e92014-05-05 13:13:14 -070088}
89
Johannes Berg68eb5502013-11-19 15:19:38 +010090static void ovs_notify(struct genl_family *family,
Johannes Berg2a94fe42013-11-19 15:19:39 +010091 struct sk_buff *skb, struct genl_info *info)
Thomas Grafed6611852013-03-29 14:46:50 +010092{
Johannes Berg68eb5502013-11-19 15:19:38 +010093 genl_notify(family, skb, genl_info_net(info), info->snd_portid,
Johannes Berg2a94fe42013-11-19 15:19:39 +010094 0, info->nlhdr, GFP_KERNEL);
Thomas Grafed6611852013-03-29 14:46:50 +010095}
96
Pravin B Shelar46df7b82012-02-22 19:58:59 -080097/**
Jesse Grossccb13522011-10-25 19:26:31 -070098 * DOC: Locking:
99 *
Pravin B Shelar8e4e1712013-04-15 13:23:03 -0700100 * All writes e.g. Writes to device state (add/remove datapath, port, set
101 * operations on vports, etc.), Writes to other state (flow table
102 * modifications, set miscellaneous datapath parameters, etc.) are protected
103 * by ovs_lock.
Jesse Grossccb13522011-10-25 19:26:31 -0700104 *
105 * Reads are protected by RCU.
106 *
107 * There are a few special cases (mostly stats) that have their own
108 * synchronization but they nest under all of above and don't interact with
109 * each other.
Pravin B Shelar8e4e1712013-04-15 13:23:03 -0700110 *
111 * The RTNL lock nests inside ovs_mutex.
Jesse Grossccb13522011-10-25 19:26:31 -0700112 */
113
Pravin B Shelar8e4e1712013-04-15 13:23:03 -0700114static DEFINE_MUTEX(ovs_mutex);
115
116void ovs_lock(void)
117{
118 mutex_lock(&ovs_mutex);
119}
120
121void ovs_unlock(void)
122{
123 mutex_unlock(&ovs_mutex);
124}
125
126#ifdef CONFIG_LOCKDEP
127int lockdep_ovsl_is_held(void)
128{
129 if (debug_locks)
130 return lockdep_is_held(&ovs_mutex);
131 else
132 return 1;
133}
David S. Miller2c6c49d2014-10-28 17:27:23 -0400134EXPORT_SYMBOL(lockdep_ovsl_is_held);
Pravin B Shelar8e4e1712013-04-15 13:23:03 -0700135#endif
136
Jesse Grossccb13522011-10-25 19:26:31 -0700137static struct vport *new_vport(const struct vport_parms *);
Thomas Graf8055a892013-12-13 15:22:20 +0100138static int queue_gso_packets(struct datapath *dp, struct sk_buff *,
Jesse Grossccb13522011-10-25 19:26:31 -0700139 const struct dp_upcall_info *);
Thomas Graf8055a892013-12-13 15:22:20 +0100140static int queue_userspace_packet(struct datapath *dp, struct sk_buff *,
Jesse Grossccb13522011-10-25 19:26:31 -0700141 const struct dp_upcall_info *);
142
Andy Zhoucc3a5ae2014-09-08 13:14:22 -0700143/* Must be called with rcu_read_lock. */
144static struct datapath *get_dp_rcu(struct net *net, int dp_ifindex)
Jesse Grossccb13522011-10-25 19:26:31 -0700145{
Andy Zhoucc3a5ae2014-09-08 13:14:22 -0700146 struct net_device *dev = dev_get_by_index_rcu(net, dp_ifindex);
Jesse Grossccb13522011-10-25 19:26:31 -0700147
Jesse Grossccb13522011-10-25 19:26:31 -0700148 if (dev) {
149 struct vport *vport = ovs_internal_dev_get_vport(dev);
150 if (vport)
Andy Zhoucc3a5ae2014-09-08 13:14:22 -0700151 return vport->dp;
Jesse Grossccb13522011-10-25 19:26:31 -0700152 }
Andy Zhoucc3a5ae2014-09-08 13:14:22 -0700153
154 return NULL;
155}
156
157/* The caller must hold either ovs_mutex or rcu_read_lock to keep the
158 * returned dp pointer valid.
159 */
160static inline struct datapath *get_dp(struct net *net, int dp_ifindex)
161{
162 struct datapath *dp;
163
164 WARN_ON_ONCE(!rcu_read_lock_held() && !lockdep_ovsl_is_held());
165 rcu_read_lock();
166 dp = get_dp_rcu(net, dp_ifindex);
Jesse Grossccb13522011-10-25 19:26:31 -0700167 rcu_read_unlock();
168
169 return dp;
170}
171
Pravin B Shelar8e4e1712013-04-15 13:23:03 -0700172/* Must be called with rcu_read_lock or ovs_mutex. */
Andy Zhou971427f32014-09-15 19:37:25 -0700173const char *ovs_dp_name(const struct datapath *dp)
Jesse Grossccb13522011-10-25 19:26:31 -0700174{
Pravin B Shelar8e4e1712013-04-15 13:23:03 -0700175 struct vport *vport = ovs_vport_ovsl_rcu(dp, OVSP_LOCAL);
Jesse Grossccb13522011-10-25 19:26:31 -0700176 return vport->ops->get_name(vport);
177}
178
179static int get_dpifindex(struct datapath *dp)
180{
181 struct vport *local;
182 int ifindex;
183
184 rcu_read_lock();
185
Pravin B Shelar15eac2a2012-08-23 12:40:54 -0700186 local = ovs_vport_rcu(dp, OVSP_LOCAL);
Jesse Grossccb13522011-10-25 19:26:31 -0700187 if (local)
Thomas Grafcff63a52013-04-29 13:06:41 +0000188 ifindex = netdev_vport_priv(local)->dev->ifindex;
Jesse Grossccb13522011-10-25 19:26:31 -0700189 else
190 ifindex = 0;
191
192 rcu_read_unlock();
193
194 return ifindex;
195}
196
197static void destroy_dp_rcu(struct rcu_head *rcu)
198{
199 struct datapath *dp = container_of(rcu, struct datapath, rcu);
200
Pravin B Shelar9b996e52014-05-06 18:41:20 -0700201 ovs_flow_tbl_destroy(&dp->table);
Jesse Grossccb13522011-10-25 19:26:31 -0700202 free_percpu(dp->stats_percpu);
Pravin B Shelar46df7b82012-02-22 19:58:59 -0800203 release_net(ovs_dp_get_net(dp));
Pravin B Shelar15eac2a2012-08-23 12:40:54 -0700204 kfree(dp->ports);
Jesse Grossccb13522011-10-25 19:26:31 -0700205 kfree(dp);
206}
207
Pravin B Shelar15eac2a2012-08-23 12:40:54 -0700208static struct hlist_head *vport_hash_bucket(const struct datapath *dp,
209 u16 port_no)
210{
211 return &dp->ports[port_no & (DP_VPORT_HASH_BUCKETS - 1)];
212}
213
Jarno Rajahalmebb6f9a72014-05-05 11:32:17 -0700214/* Called with ovs_mutex or RCU read lock. */
Pravin B Shelar15eac2a2012-08-23 12:40:54 -0700215struct vport *ovs_lookup_vport(const struct datapath *dp, u16 port_no)
216{
217 struct vport *vport;
Pravin B Shelar15eac2a2012-08-23 12:40:54 -0700218 struct hlist_head *head;
219
220 head = vport_hash_bucket(dp, port_no);
Sasha Levinb67bfe02013-02-27 17:06:00 -0800221 hlist_for_each_entry_rcu(vport, head, dp_hash_node) {
Pravin B Shelar15eac2a2012-08-23 12:40:54 -0700222 if (vport->port_no == port_no)
223 return vport;
224 }
225 return NULL;
226}
227
Pravin B Shelar8e4e1712013-04-15 13:23:03 -0700228/* Called with ovs_mutex. */
Jesse Grossccb13522011-10-25 19:26:31 -0700229static struct vport *new_vport(const struct vport_parms *parms)
230{
231 struct vport *vport;
232
233 vport = ovs_vport_add(parms);
234 if (!IS_ERR(vport)) {
235 struct datapath *dp = parms->dp;
Pravin B Shelar15eac2a2012-08-23 12:40:54 -0700236 struct hlist_head *head = vport_hash_bucket(dp, vport->port_no);
Jesse Grossccb13522011-10-25 19:26:31 -0700237
Pravin B Shelar15eac2a2012-08-23 12:40:54 -0700238 hlist_add_head_rcu(&vport->dp_hash_node, head);
Jesse Grossccb13522011-10-25 19:26:31 -0700239 }
Jesse Grossccb13522011-10-25 19:26:31 -0700240 return vport;
241}
242
Jesse Grossccb13522011-10-25 19:26:31 -0700243void ovs_dp_detach_port(struct vport *p)
244{
Pravin B Shelar8e4e1712013-04-15 13:23:03 -0700245 ASSERT_OVSL();
Jesse Grossccb13522011-10-25 19:26:31 -0700246
247 /* First drop references to device. */
Pravin B Shelar15eac2a2012-08-23 12:40:54 -0700248 hlist_del_rcu(&p->dp_hash_node);
Jesse Grossccb13522011-10-25 19:26:31 -0700249
250 /* Then destroy it. */
251 ovs_vport_del(p);
252}
253
254/* Must be called with rcu_read_lock. */
Pravin B Shelar8c8b1b82014-09-15 19:28:44 -0700255void ovs_dp_process_packet(struct sk_buff *skb, struct sw_flow_key *key)
Jesse Grossccb13522011-10-25 19:26:31 -0700256{
Pravin B Shelar83c8df22014-09-15 19:20:31 -0700257 const struct vport *p = OVS_CB(skb)->input_vport;
Jesse Grossccb13522011-10-25 19:26:31 -0700258 struct datapath *dp = p->dp;
259 struct sw_flow *flow;
Lorand Jakabd98612b2014-10-06 05:45:32 -0700260 struct sw_flow_actions *sf_acts;
Jesse Grossccb13522011-10-25 19:26:31 -0700261 struct dp_stats_percpu *stats;
Jesse Grossccb13522011-10-25 19:26:31 -0700262 u64 *stats_counter;
Andy Zhou1bd71162013-10-22 10:42:46 -0700263 u32 n_mask_hit;
Jesse Grossccb13522011-10-25 19:26:31 -0700264
Shan Wei404f2f12012-11-13 09:52:25 +0800265 stats = this_cpu_ptr(dp->stats_percpu);
Jesse Grossccb13522011-10-25 19:26:31 -0700266
Jesse Grossccb13522011-10-25 19:26:31 -0700267 /* Look up flow. */
Pravin B Shelar8c8b1b82014-09-15 19:28:44 -0700268 flow = ovs_flow_tbl_lookup_stats(&dp->table, key, &n_mask_hit);
Jesse Grossccb13522011-10-25 19:26:31 -0700269 if (unlikely(!flow)) {
270 struct dp_upcall_info upcall;
Pravin B Shelar8c8b1b82014-09-15 19:28:44 -0700271 int error;
Jesse Grossccb13522011-10-25 19:26:31 -0700272
273 upcall.cmd = OVS_PACKET_CMD_MISS;
Pravin B Shelar8c8b1b82014-09-15 19:28:44 -0700274 upcall.key = key;
Jesse Grossccb13522011-10-25 19:26:31 -0700275 upcall.userdata = NULL;
Alex Wang5cd667b2014-07-17 15:14:13 -0700276 upcall.portid = ovs_vport_find_upcall_portid(p, skb);
Li RongQingc5eba0b2014-09-03 17:43:45 +0800277 error = ovs_dp_upcall(dp, skb, &upcall);
278 if (unlikely(error))
279 kfree_skb(skb);
280 else
281 consume_skb(skb);
Jesse Grossccb13522011-10-25 19:26:31 -0700282 stats_counter = &stats->n_missed;
283 goto out;
284 }
285
Lorand Jakabd98612b2014-10-06 05:45:32 -0700286 ovs_flow_stats_update(flow, key->tp.flags, skb);
287 sf_acts = rcu_dereference(flow->sf_acts);
288 ovs_execute_actions(dp, skb, sf_acts, key);
Jesse Grossccb13522011-10-25 19:26:31 -0700289
Pravin B Shelare298e502013-10-29 17:22:21 -0700290 stats_counter = &stats->n_hit;
Jesse Grossccb13522011-10-25 19:26:31 -0700291
292out:
293 /* Update datapath statistics. */
WANG Congdf9d9fd2014-02-14 15:10:46 -0800294 u64_stats_update_begin(&stats->syncp);
Jesse Grossccb13522011-10-25 19:26:31 -0700295 (*stats_counter)++;
Andy Zhou1bd71162013-10-22 10:42:46 -0700296 stats->n_mask_hit += n_mask_hit;
WANG Congdf9d9fd2014-02-14 15:10:46 -0800297 u64_stats_update_end(&stats->syncp);
Jesse Grossccb13522011-10-25 19:26:31 -0700298}
299
Jesse Grossccb13522011-10-25 19:26:31 -0700300int ovs_dp_upcall(struct datapath *dp, struct sk_buff *skb,
Pravin B Shelar46df7b82012-02-22 19:58:59 -0800301 const struct dp_upcall_info *upcall_info)
Jesse Grossccb13522011-10-25 19:26:31 -0700302{
303 struct dp_stats_percpu *stats;
Jesse Grossccb13522011-10-25 19:26:31 -0700304 int err;
305
Eric W. Biederman15e47302012-09-07 20:12:54 +0000306 if (upcall_info->portid == 0) {
Jesse Grossccb13522011-10-25 19:26:31 -0700307 err = -ENOTCONN;
308 goto err;
309 }
310
Jesse Grossccb13522011-10-25 19:26:31 -0700311 if (!skb_is_gso(skb))
Thomas Graf8055a892013-12-13 15:22:20 +0100312 err = queue_userspace_packet(dp, skb, upcall_info);
Jesse Grossccb13522011-10-25 19:26:31 -0700313 else
Thomas Graf8055a892013-12-13 15:22:20 +0100314 err = queue_gso_packets(dp, skb, upcall_info);
Jesse Grossccb13522011-10-25 19:26:31 -0700315 if (err)
316 goto err;
317
318 return 0;
319
320err:
Shan Wei404f2f12012-11-13 09:52:25 +0800321 stats = this_cpu_ptr(dp->stats_percpu);
Jesse Grossccb13522011-10-25 19:26:31 -0700322
WANG Congdf9d9fd2014-02-14 15:10:46 -0800323 u64_stats_update_begin(&stats->syncp);
Jesse Grossccb13522011-10-25 19:26:31 -0700324 stats->n_lost++;
WANG Congdf9d9fd2014-02-14 15:10:46 -0800325 u64_stats_update_end(&stats->syncp);
Jesse Grossccb13522011-10-25 19:26:31 -0700326
327 return err;
328}
329
Thomas Graf8055a892013-12-13 15:22:20 +0100330static int queue_gso_packets(struct datapath *dp, struct sk_buff *skb,
Jesse Grossccb13522011-10-25 19:26:31 -0700331 const struct dp_upcall_info *upcall_info)
332{
Ben Pfaffa1b5d0d2012-07-20 14:47:54 -0700333 unsigned short gso_type = skb_shinfo(skb)->gso_type;
Jesse Grossccb13522011-10-25 19:26:31 -0700334 struct dp_upcall_info later_info;
335 struct sw_flow_key later_key;
336 struct sk_buff *segs, *nskb;
337 int err;
338
Thomas Graf09c5e602013-12-13 15:22:22 +0100339 segs = __skb_gso_segment(skb, NETIF_F_SG, false);
Pravin B Shelar92e5dfc2012-07-20 14:46:29 -0700340 if (IS_ERR(segs))
341 return PTR_ERR(segs);
Florian Westphal330966e2014-10-20 13:49:17 +0200342 if (segs == NULL)
343 return -EINVAL;
Jesse Grossccb13522011-10-25 19:26:31 -0700344
345 /* Queue all of the segments. */
346 skb = segs;
347 do {
Thomas Graf8055a892013-12-13 15:22:20 +0100348 err = queue_userspace_packet(dp, skb, upcall_info);
Jesse Grossccb13522011-10-25 19:26:31 -0700349 if (err)
350 break;
351
Ben Pfaffa1b5d0d2012-07-20 14:47:54 -0700352 if (skb == segs && gso_type & SKB_GSO_UDP) {
Jesse Grossccb13522011-10-25 19:26:31 -0700353 /* The initial flow key extracted by ovs_flow_extract()
354 * in this case is for a first fragment, so we need to
355 * properly mark later fragments.
356 */
357 later_key = *upcall_info->key;
358 later_key.ip.frag = OVS_FRAG_TYPE_LATER;
359
360 later_info = *upcall_info;
361 later_info.key = &later_key;
362 upcall_info = &later_info;
363 }
364 } while ((skb = skb->next));
365
366 /* Free all of the segments. */
367 skb = segs;
368 do {
369 nskb = skb->next;
370 if (err)
371 kfree_skb(skb);
372 else
373 consume_skb(skb);
374 } while ((skb = nskb));
375 return err;
376}
377
Thomas Grafc3ff8cf2013-03-29 14:46:49 +0100378static size_t key_attr_size(void)
379{
380 return nla_total_size(4) /* OVS_KEY_ATTR_PRIORITY */
Pravin B Shelar7d5437c2013-06-17 17:50:18 -0700381 + nla_total_size(0) /* OVS_KEY_ATTR_TUNNEL */
382 + nla_total_size(8) /* OVS_TUNNEL_KEY_ATTR_ID */
383 + nla_total_size(4) /* OVS_TUNNEL_KEY_ATTR_IPV4_SRC */
384 + nla_total_size(4) /* OVS_TUNNEL_KEY_ATTR_IPV4_DST */
385 + nla_total_size(1) /* OVS_TUNNEL_KEY_ATTR_TOS */
386 + nla_total_size(1) /* OVS_TUNNEL_KEY_ATTR_TTL */
387 + nla_total_size(0) /* OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT */
388 + nla_total_size(0) /* OVS_TUNNEL_KEY_ATTR_CSUM */
Jesse Gross67fa0342014-10-03 15:35:30 -0700389 + nla_total_size(0) /* OVS_TUNNEL_KEY_ATTR_OAM */
Jesse Grossf5796682014-10-03 15:35:33 -0700390 + nla_total_size(256) /* OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS */
Thomas Grafc3ff8cf2013-03-29 14:46:49 +0100391 + nla_total_size(4) /* OVS_KEY_ATTR_IN_PORT */
392 + nla_total_size(4) /* OVS_KEY_ATTR_SKB_MARK */
393 + nla_total_size(12) /* OVS_KEY_ATTR_ETHERNET */
394 + nla_total_size(2) /* OVS_KEY_ATTR_ETHERTYPE */
395 + nla_total_size(4) /* OVS_KEY_ATTR_8021Q */
396 + nla_total_size(0) /* OVS_KEY_ATTR_ENCAP */
397 + nla_total_size(2) /* OVS_KEY_ATTR_ETHERTYPE */
398 + nla_total_size(40) /* OVS_KEY_ATTR_IPV6 */
399 + nla_total_size(2) /* OVS_KEY_ATTR_ICMPV6 */
400 + nla_total_size(28); /* OVS_KEY_ATTR_ND */
401}
402
Thomas Grafbda56f12013-12-13 15:22:21 +0100403static size_t upcall_msg_size(const struct nlattr *userdata,
404 unsigned int hdrlen)
Thomas Grafc3ff8cf2013-03-29 14:46:49 +0100405{
406 size_t size = NLMSG_ALIGN(sizeof(struct ovs_header))
Thomas Grafbda56f12013-12-13 15:22:21 +0100407 + nla_total_size(hdrlen) /* OVS_PACKET_ATTR_PACKET */
Thomas Grafc3ff8cf2013-03-29 14:46:49 +0100408 + nla_total_size(key_attr_size()); /* OVS_PACKET_ATTR_KEY */
409
410 /* OVS_PACKET_ATTR_USERDATA */
411 if (userdata)
412 size += NLA_ALIGN(userdata->nla_len);
413
414 return size;
415}
416
Thomas Graf8055a892013-12-13 15:22:20 +0100417static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb,
Jesse Grossccb13522011-10-25 19:26:31 -0700418 const struct dp_upcall_info *upcall_info)
419{
420 struct ovs_header *upcall;
421 struct sk_buff *nskb = NULL;
Li RongQing4ee45ea2014-09-02 20:52:28 +0800422 struct sk_buff *user_skb = NULL; /* to be queued to userspace */
Jesse Grossccb13522011-10-25 19:26:31 -0700423 struct nlattr *nla;
Thomas Graf795449d2013-11-30 13:21:32 +0100424 struct genl_info info = {
Thomas Graf8055a892013-12-13 15:22:20 +0100425 .dst_sk = ovs_dp_get_net(dp)->genl_sock,
Thomas Graf795449d2013-11-30 13:21:32 +0100426 .snd_portid = upcall_info->portid,
427 };
428 size_t len;
Thomas Grafbda56f12013-12-13 15:22:21 +0100429 unsigned int hlen;
Thomas Graf8055a892013-12-13 15:22:20 +0100430 int err, dp_ifindex;
431
432 dp_ifindex = get_dpifindex(dp);
433 if (!dp_ifindex)
434 return -ENODEV;
Jesse Grossccb13522011-10-25 19:26:31 -0700435
436 if (vlan_tx_tag_present(skb)) {
437 nskb = skb_clone(skb, GFP_ATOMIC);
438 if (!nskb)
439 return -ENOMEM;
440
Patrick McHardy86a9bad2013-04-19 02:04:30 +0000441 nskb = __vlan_put_tag(nskb, nskb->vlan_proto, vlan_tx_tag_get(nskb));
Dan Carpenter8aa51d62012-05-13 08:44:18 +0000442 if (!nskb)
Jesse Grossccb13522011-10-25 19:26:31 -0700443 return -ENOMEM;
444
445 nskb->vlan_tci = 0;
446 skb = nskb;
447 }
448
449 if (nla_attr_size(skb->len) > USHRT_MAX) {
450 err = -EFBIG;
451 goto out;
452 }
453
Thomas Grafbda56f12013-12-13 15:22:21 +0100454 /* Complete checksum if needed */
455 if (skb->ip_summed == CHECKSUM_PARTIAL &&
456 (err = skb_checksum_help(skb)))
457 goto out;
458
459 /* Older versions of OVS user space enforce alignment of the last
460 * Netlink attribute to NLA_ALIGNTO which would require extensive
461 * padding logic. Only perform zerocopy if padding is not required.
462 */
463 if (dp->user_features & OVS_DP_F_UNALIGNED)
464 hlen = skb_zerocopy_headlen(skb);
465 else
466 hlen = skb->len;
467
468 len = upcall_msg_size(upcall_info->userdata, hlen);
Thomas Graf795449d2013-11-30 13:21:32 +0100469 user_skb = genlmsg_new_unicast(len, &info, GFP_ATOMIC);
Jesse Grossccb13522011-10-25 19:26:31 -0700470 if (!user_skb) {
471 err = -ENOMEM;
472 goto out;
473 }
474
475 upcall = genlmsg_put(user_skb, 0, 0, &dp_packet_genl_family,
476 0, upcall_info->cmd);
477 upcall->dp_ifindex = dp_ifindex;
478
479 nla = nla_nest_start(user_skb, OVS_PACKET_ATTR_KEY);
Andy Zhouf53e3832014-07-17 15:17:44 -0700480 err = ovs_nla_put_flow(upcall_info->key, upcall_info->key, user_skb);
481 BUG_ON(err);
Jesse Grossccb13522011-10-25 19:26:31 -0700482 nla_nest_end(user_skb, nla);
483
484 if (upcall_info->userdata)
Ben Pfaff44901082013-02-15 17:29:22 -0800485 __nla_put(user_skb, OVS_PACKET_ATTR_USERDATA,
486 nla_len(upcall_info->userdata),
487 nla_data(upcall_info->userdata));
Jesse Grossccb13522011-10-25 19:26:31 -0700488
Thomas Grafbda56f12013-12-13 15:22:21 +0100489 /* Only reserve room for attribute header, packet data is added
490 * in skb_zerocopy() */
491 if (!(nla = nla_reserve(user_skb, OVS_PACKET_ATTR_PACKET, 0))) {
492 err = -ENOBUFS;
493 goto out;
494 }
495 nla->nla_len = nla_attr_size(skb->len);
Jesse Grossccb13522011-10-25 19:26:31 -0700496
Zoltan Kiss36d5fe62014-03-26 22:37:45 +0000497 err = skb_zerocopy(user_skb, skb, skb->len, hlen);
498 if (err)
499 goto out;
Jesse Grossccb13522011-10-25 19:26:31 -0700500
Thomas Grafaea0bb42014-01-14 16:27:49 +0000501 /* Pad OVS_PACKET_ATTR_PACKET if linear copy was performed */
502 if (!(dp->user_features & OVS_DP_F_UNALIGNED)) {
503 size_t plen = NLA_ALIGN(user_skb->len) - user_skb->len;
504
505 if (plen > 0)
506 memset(skb_put(user_skb, plen), 0, plen);
507 }
508
Thomas Grafbda56f12013-12-13 15:22:21 +0100509 ((struct nlmsghdr *) user_skb->data)->nlmsg_len = user_skb->len;
510
Thomas Graf8055a892013-12-13 15:22:20 +0100511 err = genlmsg_unicast(ovs_dp_get_net(dp), user_skb, upcall_info->portid);
Li RongQing4ee45ea2014-09-02 20:52:28 +0800512 user_skb = NULL;
Jesse Grossccb13522011-10-25 19:26:31 -0700513out:
Zoltan Kiss36d5fe62014-03-26 22:37:45 +0000514 if (err)
515 skb_tx_error(skb);
Li RongQing4ee45ea2014-09-02 20:52:28 +0800516 kfree_skb(user_skb);
Jesse Grossccb13522011-10-25 19:26:31 -0700517 kfree_skb(nskb);
518 return err;
519}
520
Jesse Grossccb13522011-10-25 19:26:31 -0700521static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info)
522{
523 struct ovs_header *ovs_header = info->userhdr;
524 struct nlattr **a = info->attrs;
525 struct sw_flow_actions *acts;
526 struct sk_buff *packet;
527 struct sw_flow *flow;
Lorand Jakabd98612b2014-10-06 05:45:32 -0700528 struct sw_flow_actions *sf_acts;
Jesse Grossccb13522011-10-25 19:26:31 -0700529 struct datapath *dp;
530 struct ethhdr *eth;
Pravin B Shelar83c8df22014-09-15 19:20:31 -0700531 struct vport *input_vport;
Jesse Grossccb13522011-10-25 19:26:31 -0700532 int len;
533 int err;
Jesse Grossccb13522011-10-25 19:26:31 -0700534
535 err = -EINVAL;
536 if (!a[OVS_PACKET_ATTR_PACKET] || !a[OVS_PACKET_ATTR_KEY] ||
Thomas Grafdded45fc2013-03-29 14:46:47 +0100537 !a[OVS_PACKET_ATTR_ACTIONS])
Jesse Grossccb13522011-10-25 19:26:31 -0700538 goto err;
539
540 len = nla_len(a[OVS_PACKET_ATTR_PACKET]);
541 packet = __dev_alloc_skb(NET_IP_ALIGN + len, GFP_KERNEL);
542 err = -ENOMEM;
543 if (!packet)
544 goto err;
545 skb_reserve(packet, NET_IP_ALIGN);
546
Thomas Graf32686a92013-03-29 14:46:48 +0100547 nla_memcpy(__skb_put(packet, len), a[OVS_PACKET_ATTR_PACKET], len);
Jesse Grossccb13522011-10-25 19:26:31 -0700548
549 skb_reset_mac_header(packet);
550 eth = eth_hdr(packet);
551
552 /* Normally, setting the skb 'protocol' field would be handled by a
553 * call to eth_type_trans(), but it assumes there's a sending
554 * device, which we may not have. */
Simon Hormane5c5d222013-03-28 13:38:25 +0900555 if (ntohs(eth->h_proto) >= ETH_P_802_3_MIN)
Jesse Grossccb13522011-10-25 19:26:31 -0700556 packet->protocol = eth->h_proto;
557 else
558 packet->protocol = htons(ETH_P_802_2);
559
560 /* Build an sw_flow for sending this packet. */
Jarno Rajahalme23dabf82014-03-27 12:35:23 -0700561 flow = ovs_flow_alloc();
Jesse Grossccb13522011-10-25 19:26:31 -0700562 err = PTR_ERR(flow);
563 if (IS_ERR(flow))
564 goto err_kfree_skb;
565
Pravin B Shelar83c8df22014-09-15 19:20:31 -0700566 err = ovs_flow_key_extract_userspace(a[OVS_PACKET_ATTR_KEY], packet,
567 &flow->key);
Jesse Grossccb13522011-10-25 19:26:31 -0700568 if (err)
569 goto err_flow_free;
570
Pravin B Shelare6445712013-10-03 18:16:47 -0700571 acts = ovs_nla_alloc_flow_actions(nla_len(a[OVS_PACKET_ATTR_ACTIONS]));
Jesse Grossccb13522011-10-25 19:26:31 -0700572 err = PTR_ERR(acts);
573 if (IS_ERR(acts))
574 goto err_flow_free;
Pravin B Shelar74f84a52013-06-17 17:50:12 -0700575
Pravin B Shelare6445712013-10-03 18:16:47 -0700576 err = ovs_nla_copy_actions(a[OVS_PACKET_ATTR_ACTIONS],
Simon Horman25cd9ba2014-10-06 05:05:13 -0700577 &flow->key, &acts);
Pravin B Shelar74f84a52013-06-17 17:50:12 -0700578 if (err)
579 goto err_flow_free;
Jesse Grossccb13522011-10-25 19:26:31 -0700580
Jesse Grossf5796682014-10-03 15:35:33 -0700581 rcu_assign_pointer(flow->sf_acts, acts);
582
583 OVS_CB(packet)->egress_tun_info = NULL;
Jesse Grossccb13522011-10-25 19:26:31 -0700584 packet->priority = flow->key.phy.priority;
Ansis Atteka39c7caeb2012-11-26 11:24:11 -0800585 packet->mark = flow->key.phy.skb_mark;
Jesse Grossccb13522011-10-25 19:26:31 -0700586
587 rcu_read_lock();
Andy Zhoucc3a5ae2014-09-08 13:14:22 -0700588 dp = get_dp_rcu(sock_net(skb->sk), ovs_header->dp_ifindex);
Jesse Grossccb13522011-10-25 19:26:31 -0700589 err = -ENODEV;
590 if (!dp)
591 goto err_unlock;
592
Pravin B Shelar83c8df22014-09-15 19:20:31 -0700593 input_vport = ovs_vport_rcu(dp, flow->key.phy.in_port);
594 if (!input_vport)
595 input_vport = ovs_vport_rcu(dp, OVSP_LOCAL);
596
597 if (!input_vport)
598 goto err_unlock;
599
600 OVS_CB(packet)->input_vport = input_vport;
Lorand Jakabd98612b2014-10-06 05:45:32 -0700601 sf_acts = rcu_dereference(flow->sf_acts);
Pravin B Shelar83c8df22014-09-15 19:20:31 -0700602
Jesse Grossccb13522011-10-25 19:26:31 -0700603 local_bh_disable();
Lorand Jakabd98612b2014-10-06 05:45:32 -0700604 err = ovs_execute_actions(dp, packet, sf_acts, &flow->key);
Jesse Grossccb13522011-10-25 19:26:31 -0700605 local_bh_enable();
606 rcu_read_unlock();
607
Andy Zhou03f0d912013-08-07 20:01:00 -0700608 ovs_flow_free(flow, false);
Jesse Grossccb13522011-10-25 19:26:31 -0700609 return err;
610
611err_unlock:
612 rcu_read_unlock();
613err_flow_free:
Andy Zhou03f0d912013-08-07 20:01:00 -0700614 ovs_flow_free(flow, false);
Jesse Grossccb13522011-10-25 19:26:31 -0700615err_kfree_skb:
616 kfree_skb(packet);
617err:
618 return err;
619}
620
621static const struct nla_policy packet_policy[OVS_PACKET_ATTR_MAX + 1] = {
Thomas Grafdded45fc2013-03-29 14:46:47 +0100622 [OVS_PACKET_ATTR_PACKET] = { .len = ETH_HLEN },
Jesse Grossccb13522011-10-25 19:26:31 -0700623 [OVS_PACKET_ATTR_KEY] = { .type = NLA_NESTED },
624 [OVS_PACKET_ATTR_ACTIONS] = { .type = NLA_NESTED },
625};
626
Johannes Berg4534de82013-11-14 17:14:46 +0100627static const struct genl_ops dp_packet_genl_ops[] = {
Jesse Grossccb13522011-10-25 19:26:31 -0700628 { .cmd = OVS_PACKET_CMD_EXECUTE,
629 .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
630 .policy = packet_policy,
631 .doit = ovs_packet_cmd_execute
632 }
633};
634
Pravin B Shelar0c200ef2014-05-06 16:44:50 -0700635static struct genl_family dp_packet_genl_family = {
636 .id = GENL_ID_GENERATE,
637 .hdrsize = sizeof(struct ovs_header),
638 .name = OVS_PACKET_FAMILY,
639 .version = OVS_PACKET_VERSION,
640 .maxattr = OVS_PACKET_ATTR_MAX,
641 .netnsok = true,
642 .parallel_ops = true,
643 .ops = dp_packet_genl_ops,
644 .n_ops = ARRAY_SIZE(dp_packet_genl_ops),
645};
646
Andy Zhou1bd71162013-10-22 10:42:46 -0700647static void get_dp_stats(struct datapath *dp, struct ovs_dp_stats *stats,
648 struct ovs_dp_megaflow_stats *mega_stats)
Jesse Grossccb13522011-10-25 19:26:31 -0700649{
650 int i;
Jesse Grossccb13522011-10-25 19:26:31 -0700651
Andy Zhou1bd71162013-10-22 10:42:46 -0700652 memset(mega_stats, 0, sizeof(*mega_stats));
653
Pravin B Shelarb637e492013-10-04 00:14:23 -0700654 stats->n_flows = ovs_flow_tbl_count(&dp->table);
Andy Zhou1bd71162013-10-22 10:42:46 -0700655 mega_stats->n_masks = ovs_flow_tbl_num_masks(&dp->table);
Jesse Grossccb13522011-10-25 19:26:31 -0700656
657 stats->n_hit = stats->n_missed = stats->n_lost = 0;
Andy Zhou1bd71162013-10-22 10:42:46 -0700658
Jesse Grossccb13522011-10-25 19:26:31 -0700659 for_each_possible_cpu(i) {
660 const struct dp_stats_percpu *percpu_stats;
661 struct dp_stats_percpu local_stats;
662 unsigned int start;
663
664 percpu_stats = per_cpu_ptr(dp->stats_percpu, i);
665
666 do {
Eric W. Biederman57a77442014-03-13 21:26:42 -0700667 start = u64_stats_fetch_begin_irq(&percpu_stats->syncp);
Jesse Grossccb13522011-10-25 19:26:31 -0700668 local_stats = *percpu_stats;
Eric W. Biederman57a77442014-03-13 21:26:42 -0700669 } while (u64_stats_fetch_retry_irq(&percpu_stats->syncp, start));
Jesse Grossccb13522011-10-25 19:26:31 -0700670
671 stats->n_hit += local_stats.n_hit;
672 stats->n_missed += local_stats.n_missed;
673 stats->n_lost += local_stats.n_lost;
Andy Zhou1bd71162013-10-22 10:42:46 -0700674 mega_stats->n_mask_hit += local_stats.n_mask_hit;
Jesse Grossccb13522011-10-25 19:26:31 -0700675 }
676}
677
Thomas Grafc3ff8cf2013-03-29 14:46:49 +0100678static size_t ovs_flow_cmd_msg_size(const struct sw_flow_actions *acts)
679{
680 return NLMSG_ALIGN(sizeof(struct ovs_header))
681 + nla_total_size(key_attr_size()) /* OVS_FLOW_ATTR_KEY */
Andy Zhou03f0d912013-08-07 20:01:00 -0700682 + nla_total_size(key_attr_size()) /* OVS_FLOW_ATTR_MASK */
Thomas Grafc3ff8cf2013-03-29 14:46:49 +0100683 + nla_total_size(sizeof(struct ovs_flow_stats)) /* OVS_FLOW_ATTR_STATS */
684 + nla_total_size(1) /* OVS_FLOW_ATTR_TCP_FLAGS */
685 + nla_total_size(8) /* OVS_FLOW_ATTR_USED */
686 + nla_total_size(acts->actions_len); /* OVS_FLOW_ATTR_ACTIONS */
687}
688
Jarno Rajahalmebb6f9a72014-05-05 11:32:17 -0700689/* Called with ovs_mutex or RCU read lock. */
Joe Stringerca7105f2014-09-08 13:09:37 -0700690static int ovs_flow_cmd_fill_match(const struct sw_flow *flow,
691 struct sk_buff *skb)
Jesse Grossccb13522011-10-25 19:26:31 -0700692{
Jesse Grossccb13522011-10-25 19:26:31 -0700693 struct nlattr *nla;
Jesse Grossccb13522011-10-25 19:26:31 -0700694 int err;
695
Andy Zhou03f0d912013-08-07 20:01:00 -0700696 /* Fill flow key. */
Jesse Grossccb13522011-10-25 19:26:31 -0700697 nla = nla_nest_start(skb, OVS_FLOW_ATTR_KEY);
698 if (!nla)
Joe Stringerca7105f2014-09-08 13:09:37 -0700699 return -EMSGSIZE;
Andy Zhou03f0d912013-08-07 20:01:00 -0700700
Pravin B Shelare6445712013-10-03 18:16:47 -0700701 err = ovs_nla_put_flow(&flow->unmasked_key, &flow->unmasked_key, skb);
Jesse Grossccb13522011-10-25 19:26:31 -0700702 if (err)
Joe Stringerca7105f2014-09-08 13:09:37 -0700703 return err;
704
Jesse Grossccb13522011-10-25 19:26:31 -0700705 nla_nest_end(skb, nla);
706
Joe Stringerca7105f2014-09-08 13:09:37 -0700707 /* Fill flow mask. */
Andy Zhou03f0d912013-08-07 20:01:00 -0700708 nla = nla_nest_start(skb, OVS_FLOW_ATTR_MASK);
709 if (!nla)
Joe Stringerca7105f2014-09-08 13:09:37 -0700710 return -EMSGSIZE;
Andy Zhou03f0d912013-08-07 20:01:00 -0700711
Pravin B Shelare6445712013-10-03 18:16:47 -0700712 err = ovs_nla_put_flow(&flow->key, &flow->mask->key, skb);
Andy Zhou03f0d912013-08-07 20:01:00 -0700713 if (err)
Joe Stringerca7105f2014-09-08 13:09:37 -0700714 return err;
Andy Zhou03f0d912013-08-07 20:01:00 -0700715
716 nla_nest_end(skb, nla);
Joe Stringerca7105f2014-09-08 13:09:37 -0700717 return 0;
718}
719
720/* Called with ovs_mutex or RCU read lock. */
721static int ovs_flow_cmd_fill_stats(const struct sw_flow *flow,
722 struct sk_buff *skb)
723{
724 struct ovs_flow_stats stats;
725 __be16 tcp_flags;
726 unsigned long used;
Andy Zhou03f0d912013-08-07 20:01:00 -0700727
Pravin B Shelare298e502013-10-29 17:22:21 -0700728 ovs_flow_stats_get(flow, &stats, &used, &tcp_flags);
Jarno Rajahalme0e9796b2014-05-05 14:28:07 -0700729
David S. Miller028d6a62012-03-29 23:20:48 -0400730 if (used &&
731 nla_put_u64(skb, OVS_FLOW_ATTR_USED, ovs_flow_used_time(used)))
Joe Stringerca7105f2014-09-08 13:09:37 -0700732 return -EMSGSIZE;
Jesse Grossccb13522011-10-25 19:26:31 -0700733
David S. Miller028d6a62012-03-29 23:20:48 -0400734 if (stats.n_packets &&
Pravin B Shelare298e502013-10-29 17:22:21 -0700735 nla_put(skb, OVS_FLOW_ATTR_STATS, sizeof(struct ovs_flow_stats), &stats))
Joe Stringerca7105f2014-09-08 13:09:37 -0700736 return -EMSGSIZE;
Jesse Grossccb13522011-10-25 19:26:31 -0700737
Pravin B Shelare298e502013-10-29 17:22:21 -0700738 if ((u8)ntohs(tcp_flags) &&
739 nla_put_u8(skb, OVS_FLOW_ATTR_TCP_FLAGS, (u8)ntohs(tcp_flags)))
Joe Stringerca7105f2014-09-08 13:09:37 -0700740 return -EMSGSIZE;
741
742 return 0;
743}
744
745/* Called with ovs_mutex or RCU read lock. */
746static int ovs_flow_cmd_fill_actions(const struct sw_flow *flow,
747 struct sk_buff *skb, int skb_orig_len)
748{
749 struct nlattr *start;
750 int err;
Jesse Grossccb13522011-10-25 19:26:31 -0700751
752 /* If OVS_FLOW_ATTR_ACTIONS doesn't fit, skip dumping the actions if
753 * this is the first flow to be dumped into 'skb'. This is unusual for
754 * Netlink but individual action lists can be longer than
755 * NLMSG_GOODSIZE and thus entirely undumpable if we didn't do this.
756 * The userspace caller can always fetch the actions separately if it
757 * really wants them. (Most userspace callers in fact don't care.)
758 *
759 * This can only fail for dump operations because the skb is always
760 * properly sized for single flows.
761 */
Pravin B Shelar74f84a52013-06-17 17:50:12 -0700762 start = nla_nest_start(skb, OVS_FLOW_ATTR_ACTIONS);
763 if (start) {
Pravin B Shelard57170b2013-07-30 15:39:39 -0700764 const struct sw_flow_actions *sf_acts;
765
Jesse Gross663efa32013-12-03 10:58:53 -0800766 sf_acts = rcu_dereference_ovsl(flow->sf_acts);
Pravin B Shelare6445712013-10-03 18:16:47 -0700767 err = ovs_nla_put_actions(sf_acts->actions,
768 sf_acts->actions_len, skb);
Jarno Rajahalme0e9796b2014-05-05 14:28:07 -0700769
Pravin B Shelar74f84a52013-06-17 17:50:12 -0700770 if (!err)
771 nla_nest_end(skb, start);
772 else {
773 if (skb_orig_len)
Joe Stringerca7105f2014-09-08 13:09:37 -0700774 return err;
Pravin B Shelar74f84a52013-06-17 17:50:12 -0700775
776 nla_nest_cancel(skb, start);
777 }
Joe Stringerca7105f2014-09-08 13:09:37 -0700778 } else if (skb_orig_len) {
779 return -EMSGSIZE;
780 }
781
782 return 0;
783}
784
785/* Called with ovs_mutex or RCU read lock. */
786static int ovs_flow_cmd_fill_info(const struct sw_flow *flow, int dp_ifindex,
787 struct sk_buff *skb, u32 portid,
788 u32 seq, u32 flags, u8 cmd)
789{
790 const int skb_orig_len = skb->len;
791 struct ovs_header *ovs_header;
792 int err;
793
794 ovs_header = genlmsg_put(skb, portid, seq, &dp_flow_genl_family,
795 flags, cmd);
796 if (!ovs_header)
797 return -EMSGSIZE;
798
799 ovs_header->dp_ifindex = dp_ifindex;
800
801 err = ovs_flow_cmd_fill_match(flow, skb);
802 if (err)
803 goto error;
804
805 err = ovs_flow_cmd_fill_stats(flow, skb);
806 if (err)
807 goto error;
808
809 err = ovs_flow_cmd_fill_actions(flow, skb, skb_orig_len);
810 if (err)
811 goto error;
Jesse Grossccb13522011-10-25 19:26:31 -0700812
813 return genlmsg_end(skb, ovs_header);
814
Jesse Grossccb13522011-10-25 19:26:31 -0700815error:
816 genlmsg_cancel(skb, ovs_header);
817 return err;
818}
819
Jarno Rajahalme0e9796b2014-05-05 14:28:07 -0700820/* May not be called with RCU read lock. */
821static struct sk_buff *ovs_flow_cmd_alloc_info(const struct sw_flow_actions *acts,
Jarno Rajahalmefb5d1e92014-05-05 13:13:14 -0700822 struct genl_info *info,
823 bool always)
Jesse Grossccb13522011-10-25 19:26:31 -0700824{
Jarno Rajahalmefb5d1e92014-05-05 13:13:14 -0700825 struct sk_buff *skb;
Jesse Grossccb13522011-10-25 19:26:31 -0700826
Samuel Gauthier9b67aa42014-09-18 10:31:04 +0200827 if (!always && !ovs_must_notify(&dp_flow_genl_family, info, 0))
Jarno Rajahalmefb5d1e92014-05-05 13:13:14 -0700828 return NULL;
829
Jarno Rajahalme0e9796b2014-05-05 14:28:07 -0700830 skb = genlmsg_new_unicast(ovs_flow_cmd_msg_size(acts), info, GFP_KERNEL);
Jarno Rajahalmefb5d1e92014-05-05 13:13:14 -0700831 if (!skb)
832 return ERR_PTR(-ENOMEM);
833
834 return skb;
Jesse Grossccb13522011-10-25 19:26:31 -0700835}
836
Jarno Rajahalme0e9796b2014-05-05 14:28:07 -0700837/* Called with ovs_mutex. */
838static struct sk_buff *ovs_flow_cmd_build_info(const struct sw_flow *flow,
839 int dp_ifindex,
840 struct genl_info *info, u8 cmd,
841 bool always)
Jesse Grossccb13522011-10-25 19:26:31 -0700842{
843 struct sk_buff *skb;
844 int retval;
845
Jarno Rajahalme0e9796b2014-05-05 14:28:07 -0700846 skb = ovs_flow_cmd_alloc_info(ovsl_dereference(flow->sf_acts), info,
847 always);
Himangi Saraogid0e992a2014-07-27 12:37:46 +0530848 if (IS_ERR_OR_NULL(skb))
Jarno Rajahalmefb5d1e92014-05-05 13:13:14 -0700849 return skb;
Jesse Grossccb13522011-10-25 19:26:31 -0700850
Jarno Rajahalme0e9796b2014-05-05 14:28:07 -0700851 retval = ovs_flow_cmd_fill_info(flow, dp_ifindex, skb,
852 info->snd_portid, info->snd_seq, 0,
853 cmd);
Jesse Grossccb13522011-10-25 19:26:31 -0700854 BUG_ON(retval < 0);
855 return skb;
856}
857
Jarno Rajahalme37bdc872014-05-05 14:53:51 -0700858static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info)
Jesse Grossccb13522011-10-25 19:26:31 -0700859{
860 struct nlattr **a = info->attrs;
861 struct ovs_header *ovs_header = info->userhdr;
Jarno Rajahalme893f1392014-05-05 15:22:25 -0700862 struct sw_flow *flow, *new_flow;
Andy Zhou03f0d912013-08-07 20:01:00 -0700863 struct sw_flow_mask mask;
Jesse Grossccb13522011-10-25 19:26:31 -0700864 struct sk_buff *reply;
865 struct datapath *dp;
Jarno Rajahalme37bdc872014-05-05 14:53:51 -0700866 struct sw_flow_actions *acts;
867 struct sw_flow_match match;
868 int error;
869
Jarno Rajahalme893f1392014-05-05 15:22:25 -0700870 /* Must have key and actions. */
Jarno Rajahalme37bdc872014-05-05 14:53:51 -0700871 error = -EINVAL;
Jesse Gross426cda52014-10-06 05:08:38 -0700872 if (!a[OVS_FLOW_ATTR_KEY]) {
873 OVS_NLERR("Flow key attribute not present in new flow.\n");
Jarno Rajahalme37bdc872014-05-05 14:53:51 -0700874 goto error;
Jesse Gross426cda52014-10-06 05:08:38 -0700875 }
876 if (!a[OVS_FLOW_ATTR_ACTIONS]) {
877 OVS_NLERR("Flow actions attribute not present in new flow.\n");
Jarno Rajahalme37bdc872014-05-05 14:53:51 -0700878 goto error;
Jesse Gross426cda52014-10-06 05:08:38 -0700879 }
Jarno Rajahalme37bdc872014-05-05 14:53:51 -0700880
Jarno Rajahalme893f1392014-05-05 15:22:25 -0700881 /* Most of the time we need to allocate a new flow, do it before
882 * locking.
883 */
884 new_flow = ovs_flow_alloc();
885 if (IS_ERR(new_flow)) {
886 error = PTR_ERR(new_flow);
887 goto error;
888 }
889
890 /* Extract key. */
891 ovs_match_init(&match, &new_flow->unmasked_key, &mask);
892 error = ovs_nla_get_match(&match,
893 a[OVS_FLOW_ATTR_KEY], a[OVS_FLOW_ATTR_MASK]);
894 if (error)
895 goto err_kfree_flow;
896
897 ovs_flow_mask_key(&new_flow->key, &new_flow->unmasked_key, &mask);
898
899 /* Validate actions. */
Jarno Rajahalme37bdc872014-05-05 14:53:51 -0700900 acts = ovs_nla_alloc_flow_actions(nla_len(a[OVS_FLOW_ATTR_ACTIONS]));
901 error = PTR_ERR(acts);
902 if (IS_ERR(acts))
Jarno Rajahalme893f1392014-05-05 15:22:25 -0700903 goto err_kfree_flow;
Jarno Rajahalme37bdc872014-05-05 14:53:51 -0700904
Jarno Rajahalme893f1392014-05-05 15:22:25 -0700905 error = ovs_nla_copy_actions(a[OVS_FLOW_ATTR_ACTIONS], &new_flow->key,
Simon Horman25cd9ba2014-10-06 05:05:13 -0700906 &acts);
Jarno Rajahalme37bdc872014-05-05 14:53:51 -0700907 if (error) {
908 OVS_NLERR("Flow actions may not be safe on all matching packets.\n");
Jarno Rajahalme893f1392014-05-05 15:22:25 -0700909 goto err_kfree_acts;
910 }
911
912 reply = ovs_flow_cmd_alloc_info(acts, info, false);
913 if (IS_ERR(reply)) {
914 error = PTR_ERR(reply);
915 goto err_kfree_acts;
Jarno Rajahalme37bdc872014-05-05 14:53:51 -0700916 }
917
918 ovs_lock();
919 dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex);
Jarno Rajahalme893f1392014-05-05 15:22:25 -0700920 if (unlikely(!dp)) {
921 error = -ENODEV;
Jarno Rajahalme37bdc872014-05-05 14:53:51 -0700922 goto err_unlock_ovs;
Jarno Rajahalme893f1392014-05-05 15:22:25 -0700923 }
Jarno Rajahalme37bdc872014-05-05 14:53:51 -0700924 /* Check if this is a duplicate flow */
Jarno Rajahalme893f1392014-05-05 15:22:25 -0700925 flow = ovs_flow_tbl_lookup(&dp->table, &new_flow->unmasked_key);
926 if (likely(!flow)) {
927 rcu_assign_pointer(new_flow->sf_acts, acts);
928
929 /* Put flow in bucket. */
930 error = ovs_flow_tbl_insert(&dp->table, new_flow, &mask);
931 if (unlikely(error)) {
932 acts = NULL;
Jarno Rajahalme37bdc872014-05-05 14:53:51 -0700933 goto err_unlock_ovs;
934 }
935
Jarno Rajahalme893f1392014-05-05 15:22:25 -0700936 if (unlikely(reply)) {
937 error = ovs_flow_cmd_fill_info(new_flow,
938 ovs_header->dp_ifindex,
939 reply, info->snd_portid,
940 info->snd_seq, 0,
941 OVS_FLOW_CMD_NEW);
942 BUG_ON(error < 0);
Jarno Rajahalme37bdc872014-05-05 14:53:51 -0700943 }
Jarno Rajahalme893f1392014-05-05 15:22:25 -0700944 ovs_unlock();
Jarno Rajahalme37bdc872014-05-05 14:53:51 -0700945 } else {
946 struct sw_flow_actions *old_acts;
947
948 /* Bail out if we're not allowed to modify an existing flow.
949 * We accept NLM_F_CREATE in place of the intended NLM_F_EXCL
950 * because Generic Netlink treats the latter as a dump
951 * request. We also accept NLM_F_EXCL in case that bug ever
952 * gets fixed.
953 */
Jarno Rajahalme893f1392014-05-05 15:22:25 -0700954 if (unlikely(info->nlhdr->nlmsg_flags & (NLM_F_CREATE
955 | NLM_F_EXCL))) {
956 error = -EEXIST;
Jarno Rajahalme37bdc872014-05-05 14:53:51 -0700957 goto err_unlock_ovs;
Jarno Rajahalme893f1392014-05-05 15:22:25 -0700958 }
Jarno Rajahalme37bdc872014-05-05 14:53:51 -0700959 /* The unmasked key has to be the same for flow updates. */
Jarno Rajahalme893f1392014-05-05 15:22:25 -0700960 if (unlikely(!ovs_flow_cmp_unmasked_key(flow, &match))) {
Alex Wang4a46b242014-06-30 20:30:29 -0700961 flow = ovs_flow_tbl_lookup_exact(&dp->table, &match);
962 if (!flow) {
963 error = -ENOENT;
964 goto err_unlock_ovs;
965 }
Jarno Rajahalme893f1392014-05-05 15:22:25 -0700966 }
Jarno Rajahalme37bdc872014-05-05 14:53:51 -0700967 /* Update actions. */
968 old_acts = ovsl_dereference(flow->sf_acts);
969 rcu_assign_pointer(flow->sf_acts, acts);
Jarno Rajahalme893f1392014-05-05 15:22:25 -0700970
971 if (unlikely(reply)) {
972 error = ovs_flow_cmd_fill_info(flow,
973 ovs_header->dp_ifindex,
974 reply, info->snd_portid,
975 info->snd_seq, 0,
976 OVS_FLOW_CMD_NEW);
977 BUG_ON(error < 0);
978 }
979 ovs_unlock();
980
Jarno Rajahalme37bdc872014-05-05 14:53:51 -0700981 ovs_nla_free_flow_actions(old_acts);
Jarno Rajahalme893f1392014-05-05 15:22:25 -0700982 ovs_flow_free(new_flow, false);
Jarno Rajahalme37bdc872014-05-05 14:53:51 -0700983 }
984
Jarno Rajahalme893f1392014-05-05 15:22:25 -0700985 if (reply)
986 ovs_notify(&dp_flow_genl_family, reply, info);
Jarno Rajahalme37bdc872014-05-05 14:53:51 -0700987 return 0;
988
Jarno Rajahalme37bdc872014-05-05 14:53:51 -0700989err_unlock_ovs:
990 ovs_unlock();
Jarno Rajahalme893f1392014-05-05 15:22:25 -0700991 kfree_skb(reply);
992err_kfree_acts:
Jarno Rajahalme37bdc872014-05-05 14:53:51 -0700993 kfree(acts);
Jarno Rajahalme893f1392014-05-05 15:22:25 -0700994err_kfree_flow:
995 ovs_flow_free(new_flow, false);
Jarno Rajahalme37bdc872014-05-05 14:53:51 -0700996error:
997 return error;
998}
999
Jesse Gross6b205b22014-10-03 15:35:32 -07001000static struct sw_flow_actions *get_flow_actions(const struct nlattr *a,
1001 const struct sw_flow_key *key,
1002 const struct sw_flow_mask *mask)
1003{
1004 struct sw_flow_actions *acts;
1005 struct sw_flow_key masked_key;
1006 int error;
1007
1008 acts = ovs_nla_alloc_flow_actions(nla_len(a));
1009 if (IS_ERR(acts))
1010 return acts;
1011
1012 ovs_flow_mask_key(&masked_key, key, mask);
Simon Horman25cd9ba2014-10-06 05:05:13 -07001013 error = ovs_nla_copy_actions(a, &masked_key, &acts);
Jesse Gross6b205b22014-10-03 15:35:32 -07001014 if (error) {
1015 OVS_NLERR("Flow actions may not be safe on all matching packets.\n");
1016 kfree(acts);
1017 return ERR_PTR(error);
1018 }
1019
1020 return acts;
1021}
1022
Jarno Rajahalme37bdc872014-05-05 14:53:51 -07001023static int ovs_flow_cmd_set(struct sk_buff *skb, struct genl_info *info)
1024{
1025 struct nlattr **a = info->attrs;
1026 struct ovs_header *ovs_header = info->userhdr;
Jesse Gross6b205b22014-10-03 15:35:32 -07001027 struct sw_flow_key key;
Jarno Rajahalme37bdc872014-05-05 14:53:51 -07001028 struct sw_flow *flow;
1029 struct sw_flow_mask mask;
1030 struct sk_buff *reply = NULL;
1031 struct datapath *dp;
Jarno Rajahalme893f1392014-05-05 15:22:25 -07001032 struct sw_flow_actions *old_acts = NULL, *acts = NULL;
Andy Zhou03f0d912013-08-07 20:01:00 -07001033 struct sw_flow_match match;
Jesse Grossccb13522011-10-25 19:26:31 -07001034 int error;
Jesse Grossccb13522011-10-25 19:26:31 -07001035
1036 /* Extract key. */
1037 error = -EINVAL;
Jesse Gross426cda52014-10-06 05:08:38 -07001038 if (!a[OVS_FLOW_ATTR_KEY]) {
1039 OVS_NLERR("Flow key attribute not present in set flow.\n");
Jesse Grossccb13522011-10-25 19:26:31 -07001040 goto error;
Jesse Gross426cda52014-10-06 05:08:38 -07001041 }
Andy Zhou03f0d912013-08-07 20:01:00 -07001042
1043 ovs_match_init(&match, &key, &mask);
Jarno Rajahalme23dabf82014-03-27 12:35:23 -07001044 error = ovs_nla_get_match(&match,
Pravin B Shelare6445712013-10-03 18:16:47 -07001045 a[OVS_FLOW_ATTR_KEY], a[OVS_FLOW_ATTR_MASK]);
Jesse Grossccb13522011-10-25 19:26:31 -07001046 if (error)
1047 goto error;
1048
1049 /* Validate actions. */
1050 if (a[OVS_FLOW_ATTR_ACTIONS]) {
Jesse Gross6b205b22014-10-03 15:35:32 -07001051 acts = get_flow_actions(a[OVS_FLOW_ATTR_ACTIONS], &key, &mask);
1052 if (IS_ERR(acts)) {
1053 error = PTR_ERR(acts);
Jesse Grossccb13522011-10-25 19:26:31 -07001054 goto error;
Jarno Rajahalme893f1392014-05-05 15:22:25 -07001055 }
1056 }
1057
1058 /* Can allocate before locking if have acts. */
1059 if (acts) {
1060 reply = ovs_flow_cmd_alloc_info(acts, info, false);
1061 if (IS_ERR(reply)) {
1062 error = PTR_ERR(reply);
1063 goto err_kfree_acts;
Andy Zhou03f0d912013-08-07 20:01:00 -07001064 }
Jesse Grossccb13522011-10-25 19:26:31 -07001065 }
1066
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001067 ovs_lock();
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001068 dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex);
Jarno Rajahalme893f1392014-05-05 15:22:25 -07001069 if (unlikely(!dp)) {
1070 error = -ENODEV;
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001071 goto err_unlock_ovs;
Jarno Rajahalme893f1392014-05-05 15:22:25 -07001072 }
Jarno Rajahalme37bdc872014-05-05 14:53:51 -07001073 /* Check that the flow exists. */
Alex Wang4a46b242014-06-30 20:30:29 -07001074 flow = ovs_flow_tbl_lookup_exact(&dp->table, &match);
Jarno Rajahalme893f1392014-05-05 15:22:25 -07001075 if (unlikely(!flow)) {
1076 error = -ENOENT;
Jarno Rajahalme37bdc872014-05-05 14:53:51 -07001077 goto err_unlock_ovs;
Jarno Rajahalme893f1392014-05-05 15:22:25 -07001078 }
Alex Wang4a46b242014-06-30 20:30:29 -07001079
Jarno Rajahalme37bdc872014-05-05 14:53:51 -07001080 /* Update actions, if present. */
Jarno Rajahalme893f1392014-05-05 15:22:25 -07001081 if (likely(acts)) {
Jarno Rajahalme37bdc872014-05-05 14:53:51 -07001082 old_acts = ovsl_dereference(flow->sf_acts);
Jesse Grossccb13522011-10-25 19:26:31 -07001083 rcu_assign_pointer(flow->sf_acts, acts);
Jarno Rajahalme893f1392014-05-05 15:22:25 -07001084
1085 if (unlikely(reply)) {
1086 error = ovs_flow_cmd_fill_info(flow,
1087 ovs_header->dp_ifindex,
1088 reply, info->snd_portid,
1089 info->snd_seq, 0,
1090 OVS_FLOW_CMD_NEW);
1091 BUG_ON(error < 0);
1092 }
1093 } else {
1094 /* Could not alloc without acts before locking. */
1095 reply = ovs_flow_cmd_build_info(flow, ovs_header->dp_ifindex,
1096 info, OVS_FLOW_CMD_NEW, false);
1097 if (unlikely(IS_ERR(reply))) {
1098 error = PTR_ERR(reply);
1099 goto err_unlock_ovs;
1100 }
Jesse Grossccb13522011-10-25 19:26:31 -07001101 }
Jarno Rajahalme37bdc872014-05-05 14:53:51 -07001102
Jarno Rajahalme37bdc872014-05-05 14:53:51 -07001103 /* Clear stats. */
1104 if (a[OVS_FLOW_ATTR_CLEAR])
1105 ovs_flow_stats_clear(flow);
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001106 ovs_unlock();
Jesse Grossccb13522011-10-25 19:26:31 -07001107
Jarno Rajahalme893f1392014-05-05 15:22:25 -07001108 if (reply)
1109 ovs_notify(&dp_flow_genl_family, reply, info);
1110 if (old_acts)
1111 ovs_nla_free_flow_actions(old_acts);
Jarno Rajahalmefb5d1e92014-05-05 13:13:14 -07001112
Jesse Grossccb13522011-10-25 19:26:31 -07001113 return 0;
1114
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001115err_unlock_ovs:
1116 ovs_unlock();
Jarno Rajahalme893f1392014-05-05 15:22:25 -07001117 kfree_skb(reply);
1118err_kfree_acts:
Pravin B Shelar74f84a52013-06-17 17:50:12 -07001119 kfree(acts);
Jesse Grossccb13522011-10-25 19:26:31 -07001120error:
1121 return error;
1122}
1123
1124static int ovs_flow_cmd_get(struct sk_buff *skb, struct genl_info *info)
1125{
1126 struct nlattr **a = info->attrs;
1127 struct ovs_header *ovs_header = info->userhdr;
1128 struct sw_flow_key key;
1129 struct sk_buff *reply;
1130 struct sw_flow *flow;
1131 struct datapath *dp;
Andy Zhou03f0d912013-08-07 20:01:00 -07001132 struct sw_flow_match match;
Jesse Grossccb13522011-10-25 19:26:31 -07001133 int err;
Jesse Grossccb13522011-10-25 19:26:31 -07001134
Andy Zhou03f0d912013-08-07 20:01:00 -07001135 if (!a[OVS_FLOW_ATTR_KEY]) {
1136 OVS_NLERR("Flow get message rejected, Key attribute missing.\n");
Jesse Grossccb13522011-10-25 19:26:31 -07001137 return -EINVAL;
Andy Zhou03f0d912013-08-07 20:01:00 -07001138 }
1139
1140 ovs_match_init(&match, &key, NULL);
Jarno Rajahalme23dabf82014-03-27 12:35:23 -07001141 err = ovs_nla_get_match(&match, a[OVS_FLOW_ATTR_KEY], NULL);
Jesse Grossccb13522011-10-25 19:26:31 -07001142 if (err)
1143 return err;
1144
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001145 ovs_lock();
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001146 dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex);
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001147 if (!dp) {
1148 err = -ENODEV;
1149 goto unlock;
1150 }
Jesse Grossccb13522011-10-25 19:26:31 -07001151
Alex Wang4a46b242014-06-30 20:30:29 -07001152 flow = ovs_flow_tbl_lookup_exact(&dp->table, &match);
1153 if (!flow) {
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001154 err = -ENOENT;
1155 goto unlock;
1156 }
Jesse Grossccb13522011-10-25 19:26:31 -07001157
Jarno Rajahalme0e9796b2014-05-05 14:28:07 -07001158 reply = ovs_flow_cmd_build_info(flow, ovs_header->dp_ifindex, info,
1159 OVS_FLOW_CMD_NEW, true);
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001160 if (IS_ERR(reply)) {
1161 err = PTR_ERR(reply);
1162 goto unlock;
1163 }
Jesse Grossccb13522011-10-25 19:26:31 -07001164
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001165 ovs_unlock();
Jesse Grossccb13522011-10-25 19:26:31 -07001166 return genlmsg_reply(reply, info);
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001167unlock:
1168 ovs_unlock();
1169 return err;
Jesse Grossccb13522011-10-25 19:26:31 -07001170}
1171
1172static int ovs_flow_cmd_del(struct sk_buff *skb, struct genl_info *info)
1173{
1174 struct nlattr **a = info->attrs;
1175 struct ovs_header *ovs_header = info->userhdr;
1176 struct sw_flow_key key;
1177 struct sk_buff *reply;
1178 struct sw_flow *flow;
1179 struct datapath *dp;
Andy Zhou03f0d912013-08-07 20:01:00 -07001180 struct sw_flow_match match;
Jesse Grossccb13522011-10-25 19:26:31 -07001181 int err;
Jesse Grossccb13522011-10-25 19:26:31 -07001182
Jarno Rajahalmeaed06772014-05-05 14:40:13 -07001183 if (likely(a[OVS_FLOW_ATTR_KEY])) {
1184 ovs_match_init(&match, &key, NULL);
1185 err = ovs_nla_get_match(&match, a[OVS_FLOW_ATTR_KEY], NULL);
1186 if (unlikely(err))
1187 return err;
1188 }
1189
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001190 ovs_lock();
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001191 dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex);
Jarno Rajahalmeaed06772014-05-05 14:40:13 -07001192 if (unlikely(!dp)) {
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001193 err = -ENODEV;
1194 goto unlock;
1195 }
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001196
Jarno Rajahalmeaed06772014-05-05 14:40:13 -07001197 if (unlikely(!a[OVS_FLOW_ATTR_KEY])) {
Pravin B Shelarb637e492013-10-04 00:14:23 -07001198 err = ovs_flow_tbl_flush(&dp->table);
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001199 goto unlock;
1200 }
Andy Zhou03f0d912013-08-07 20:01:00 -07001201
Alex Wang4a46b242014-06-30 20:30:29 -07001202 flow = ovs_flow_tbl_lookup_exact(&dp->table, &match);
1203 if (unlikely(!flow)) {
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001204 err = -ENOENT;
1205 goto unlock;
1206 }
Jesse Grossccb13522011-10-25 19:26:31 -07001207
Pravin B Shelarb637e492013-10-04 00:14:23 -07001208 ovs_flow_tbl_remove(&dp->table, flow);
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001209 ovs_unlock();
Jesse Grossccb13522011-10-25 19:26:31 -07001210
Jarno Rajahalmeaed06772014-05-05 14:40:13 -07001211 reply = ovs_flow_cmd_alloc_info((const struct sw_flow_actions __force *) flow->sf_acts,
1212 info, false);
1213 if (likely(reply)) {
1214 if (likely(!IS_ERR(reply))) {
1215 rcu_read_lock(); /*To keep RCU checker happy. */
1216 err = ovs_flow_cmd_fill_info(flow, ovs_header->dp_ifindex,
1217 reply, info->snd_portid,
1218 info->snd_seq, 0,
1219 OVS_FLOW_CMD_DEL);
1220 rcu_read_unlock();
1221 BUG_ON(err < 0);
1222
1223 ovs_notify(&dp_flow_genl_family, reply, info);
1224 } else {
1225 netlink_set_err(sock_net(skb->sk)->genl_sock, 0, 0, PTR_ERR(reply));
1226 }
1227 }
1228
1229 ovs_flow_free(flow, true);
Jesse Grossccb13522011-10-25 19:26:31 -07001230 return 0;
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001231unlock:
1232 ovs_unlock();
1233 return err;
Jesse Grossccb13522011-10-25 19:26:31 -07001234}
1235
1236static int ovs_flow_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb)
1237{
1238 struct ovs_header *ovs_header = genlmsg_data(nlmsg_data(cb->nlh));
Pravin B Shelarb637e492013-10-04 00:14:23 -07001239 struct table_instance *ti;
Jesse Grossccb13522011-10-25 19:26:31 -07001240 struct datapath *dp;
Jesse Grossccb13522011-10-25 19:26:31 -07001241
Pravin B Shelard57170b2013-07-30 15:39:39 -07001242 rcu_read_lock();
Andy Zhoucc3a5ae2014-09-08 13:14:22 -07001243 dp = get_dp_rcu(sock_net(skb->sk), ovs_header->dp_ifindex);
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001244 if (!dp) {
Pravin B Shelard57170b2013-07-30 15:39:39 -07001245 rcu_read_unlock();
Jesse Grossccb13522011-10-25 19:26:31 -07001246 return -ENODEV;
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001247 }
Jesse Grossccb13522011-10-25 19:26:31 -07001248
Pravin B Shelarb637e492013-10-04 00:14:23 -07001249 ti = rcu_dereference(dp->table.ti);
Jesse Grossccb13522011-10-25 19:26:31 -07001250 for (;;) {
1251 struct sw_flow *flow;
1252 u32 bucket, obj;
1253
1254 bucket = cb->args[0];
1255 obj = cb->args[1];
Pravin B Shelarb637e492013-10-04 00:14:23 -07001256 flow = ovs_flow_tbl_dump_next(ti, &bucket, &obj);
Jesse Grossccb13522011-10-25 19:26:31 -07001257 if (!flow)
1258 break;
1259
Jarno Rajahalme0e9796b2014-05-05 14:28:07 -07001260 if (ovs_flow_cmd_fill_info(flow, ovs_header->dp_ifindex, skb,
Eric W. Biederman15e47302012-09-07 20:12:54 +00001261 NETLINK_CB(cb->skb).portid,
Jesse Grossccb13522011-10-25 19:26:31 -07001262 cb->nlh->nlmsg_seq, NLM_F_MULTI,
1263 OVS_FLOW_CMD_NEW) < 0)
1264 break;
1265
1266 cb->args[0] = bucket;
1267 cb->args[1] = obj;
1268 }
Pravin B Shelard57170b2013-07-30 15:39:39 -07001269 rcu_read_unlock();
Jesse Grossccb13522011-10-25 19:26:31 -07001270 return skb->len;
1271}
1272
Pravin B Shelar0c200ef2014-05-06 16:44:50 -07001273static const struct nla_policy flow_policy[OVS_FLOW_ATTR_MAX + 1] = {
1274 [OVS_FLOW_ATTR_KEY] = { .type = NLA_NESTED },
1275 [OVS_FLOW_ATTR_ACTIONS] = { .type = NLA_NESTED },
1276 [OVS_FLOW_ATTR_CLEAR] = { .type = NLA_FLAG },
1277};
1278
stephen hemminger48e48a72014-07-16 11:25:52 -07001279static const struct genl_ops dp_flow_genl_ops[] = {
Jesse Grossccb13522011-10-25 19:26:31 -07001280 { .cmd = OVS_FLOW_CMD_NEW,
1281 .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
1282 .policy = flow_policy,
Jarno Rajahalme37bdc872014-05-05 14:53:51 -07001283 .doit = ovs_flow_cmd_new
Jesse Grossccb13522011-10-25 19:26:31 -07001284 },
1285 { .cmd = OVS_FLOW_CMD_DEL,
1286 .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
1287 .policy = flow_policy,
1288 .doit = ovs_flow_cmd_del
1289 },
1290 { .cmd = OVS_FLOW_CMD_GET,
1291 .flags = 0, /* OK for unprivileged users. */
1292 .policy = flow_policy,
1293 .doit = ovs_flow_cmd_get,
1294 .dumpit = ovs_flow_cmd_dump
1295 },
1296 { .cmd = OVS_FLOW_CMD_SET,
1297 .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
1298 .policy = flow_policy,
Jarno Rajahalme37bdc872014-05-05 14:53:51 -07001299 .doit = ovs_flow_cmd_set,
Jesse Grossccb13522011-10-25 19:26:31 -07001300 },
1301};
1302
Pravin B Shelar0c200ef2014-05-06 16:44:50 -07001303static struct genl_family dp_flow_genl_family = {
Jesse Grossccb13522011-10-25 19:26:31 -07001304 .id = GENL_ID_GENERATE,
1305 .hdrsize = sizeof(struct ovs_header),
Pravin B Shelar0c200ef2014-05-06 16:44:50 -07001306 .name = OVS_FLOW_FAMILY,
1307 .version = OVS_FLOW_VERSION,
1308 .maxattr = OVS_FLOW_ATTR_MAX,
Pravin B Shelar3a4e0d62013-04-23 07:48:48 +00001309 .netnsok = true,
1310 .parallel_ops = true,
Pravin B Shelar0c200ef2014-05-06 16:44:50 -07001311 .ops = dp_flow_genl_ops,
1312 .n_ops = ARRAY_SIZE(dp_flow_genl_ops),
1313 .mcgrps = &ovs_dp_flow_multicast_group,
1314 .n_mcgrps = 1,
Jesse Grossccb13522011-10-25 19:26:31 -07001315};
1316
Thomas Grafc3ff8cf2013-03-29 14:46:49 +01001317static size_t ovs_dp_cmd_msg_size(void)
1318{
1319 size_t msgsize = NLMSG_ALIGN(sizeof(struct ovs_header));
1320
1321 msgsize += nla_total_size(IFNAMSIZ);
1322 msgsize += nla_total_size(sizeof(struct ovs_dp_stats));
Andy Zhou1bd71162013-10-22 10:42:46 -07001323 msgsize += nla_total_size(sizeof(struct ovs_dp_megaflow_stats));
Daniele Di Proietto45fb9c32014-01-23 10:47:35 -08001324 msgsize += nla_total_size(sizeof(u32)); /* OVS_DP_ATTR_USER_FEATURES */
Thomas Grafc3ff8cf2013-03-29 14:46:49 +01001325
1326 return msgsize;
1327}
1328
Jarno Rajahalmebb6f9a72014-05-05 11:32:17 -07001329/* Called with ovs_mutex or RCU read lock. */
Jesse Grossccb13522011-10-25 19:26:31 -07001330static int ovs_dp_cmd_fill_info(struct datapath *dp, struct sk_buff *skb,
Eric W. Biederman15e47302012-09-07 20:12:54 +00001331 u32 portid, u32 seq, u32 flags, u8 cmd)
Jesse Grossccb13522011-10-25 19:26:31 -07001332{
1333 struct ovs_header *ovs_header;
1334 struct ovs_dp_stats dp_stats;
Andy Zhou1bd71162013-10-22 10:42:46 -07001335 struct ovs_dp_megaflow_stats dp_megaflow_stats;
Jesse Grossccb13522011-10-25 19:26:31 -07001336 int err;
1337
Eric W. Biederman15e47302012-09-07 20:12:54 +00001338 ovs_header = genlmsg_put(skb, portid, seq, &dp_datapath_genl_family,
Jesse Grossccb13522011-10-25 19:26:31 -07001339 flags, cmd);
1340 if (!ovs_header)
1341 goto error;
1342
1343 ovs_header->dp_ifindex = get_dpifindex(dp);
1344
Jesse Grossccb13522011-10-25 19:26:31 -07001345 err = nla_put_string(skb, OVS_DP_ATTR_NAME, ovs_dp_name(dp));
Jesse Grossccb13522011-10-25 19:26:31 -07001346 if (err)
1347 goto nla_put_failure;
1348
Andy Zhou1bd71162013-10-22 10:42:46 -07001349 get_dp_stats(dp, &dp_stats, &dp_megaflow_stats);
1350 if (nla_put(skb, OVS_DP_ATTR_STATS, sizeof(struct ovs_dp_stats),
1351 &dp_stats))
1352 goto nla_put_failure;
1353
1354 if (nla_put(skb, OVS_DP_ATTR_MEGAFLOW_STATS,
1355 sizeof(struct ovs_dp_megaflow_stats),
1356 &dp_megaflow_stats))
David S. Miller028d6a62012-03-29 23:20:48 -04001357 goto nla_put_failure;
Jesse Grossccb13522011-10-25 19:26:31 -07001358
Thomas Graf43d4be92013-12-13 15:22:18 +01001359 if (nla_put_u32(skb, OVS_DP_ATTR_USER_FEATURES, dp->user_features))
1360 goto nla_put_failure;
1361
Jesse Grossccb13522011-10-25 19:26:31 -07001362 return genlmsg_end(skb, ovs_header);
1363
1364nla_put_failure:
1365 genlmsg_cancel(skb, ovs_header);
1366error:
1367 return -EMSGSIZE;
1368}
1369
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001370static struct sk_buff *ovs_dp_cmd_alloc_info(struct genl_info *info)
Jesse Grossccb13522011-10-25 19:26:31 -07001371{
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001372 return genlmsg_new_unicast(ovs_dp_cmd_msg_size(), info, GFP_KERNEL);
Jesse Grossccb13522011-10-25 19:26:31 -07001373}
1374
Jarno Rajahalmebb6f9a72014-05-05 11:32:17 -07001375/* Called with rcu_read_lock or ovs_mutex. */
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001376static struct datapath *lookup_datapath(struct net *net,
1377 struct ovs_header *ovs_header,
Jesse Grossccb13522011-10-25 19:26:31 -07001378 struct nlattr *a[OVS_DP_ATTR_MAX + 1])
1379{
1380 struct datapath *dp;
1381
1382 if (!a[OVS_DP_ATTR_NAME])
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001383 dp = get_dp(net, ovs_header->dp_ifindex);
Jesse Grossccb13522011-10-25 19:26:31 -07001384 else {
1385 struct vport *vport;
1386
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001387 vport = ovs_vport_locate(net, nla_data(a[OVS_DP_ATTR_NAME]));
Jesse Grossccb13522011-10-25 19:26:31 -07001388 dp = vport && vport->port_no == OVSP_LOCAL ? vport->dp : NULL;
Jesse Grossccb13522011-10-25 19:26:31 -07001389 }
1390 return dp ? dp : ERR_PTR(-ENODEV);
1391}
1392
Thomas Graf44da5ae2013-12-13 15:22:19 +01001393static void ovs_dp_reset_user_features(struct sk_buff *skb, struct genl_info *info)
1394{
1395 struct datapath *dp;
1396
1397 dp = lookup_datapath(sock_net(skb->sk), info->userhdr, info->attrs);
Jiri Pirko3c7eacf2014-02-14 11:42:36 +01001398 if (IS_ERR(dp))
Thomas Graf44da5ae2013-12-13 15:22:19 +01001399 return;
1400
1401 WARN(dp->user_features, "Dropping previously announced user features\n");
1402 dp->user_features = 0;
1403}
1404
Thomas Graf43d4be92013-12-13 15:22:18 +01001405static void ovs_dp_change(struct datapath *dp, struct nlattr **a)
1406{
1407 if (a[OVS_DP_ATTR_USER_FEATURES])
1408 dp->user_features = nla_get_u32(a[OVS_DP_ATTR_USER_FEATURES]);
1409}
1410
Jesse Grossccb13522011-10-25 19:26:31 -07001411static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info)
1412{
1413 struct nlattr **a = info->attrs;
1414 struct vport_parms parms;
1415 struct sk_buff *reply;
1416 struct datapath *dp;
1417 struct vport *vport;
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001418 struct ovs_net *ovs_net;
Pravin B Shelar15eac2a2012-08-23 12:40:54 -07001419 int err, i;
Jesse Grossccb13522011-10-25 19:26:31 -07001420
1421 err = -EINVAL;
1422 if (!a[OVS_DP_ATTR_NAME] || !a[OVS_DP_ATTR_UPCALL_PID])
1423 goto err;
1424
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001425 reply = ovs_dp_cmd_alloc_info(info);
1426 if (!reply)
1427 return -ENOMEM;
Jesse Grossccb13522011-10-25 19:26:31 -07001428
1429 err = -ENOMEM;
1430 dp = kzalloc(sizeof(*dp), GFP_KERNEL);
1431 if (dp == NULL)
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001432 goto err_free_reply;
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001433
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001434 ovs_dp_set_net(dp, hold_net(sock_net(skb->sk)));
Jesse Grossccb13522011-10-25 19:26:31 -07001435
1436 /* Allocate table. */
Pravin B Shelarb637e492013-10-04 00:14:23 -07001437 err = ovs_flow_tbl_init(&dp->table);
1438 if (err)
Jesse Grossccb13522011-10-25 19:26:31 -07001439 goto err_free_dp;
1440
WANG Cong1c213bd2014-02-13 11:46:28 -08001441 dp->stats_percpu = netdev_alloc_pcpu_stats(struct dp_stats_percpu);
Jesse Grossccb13522011-10-25 19:26:31 -07001442 if (!dp->stats_percpu) {
1443 err = -ENOMEM;
1444 goto err_destroy_table;
1445 }
1446
Pravin B Shelar15eac2a2012-08-23 12:40:54 -07001447 dp->ports = kmalloc(DP_VPORT_HASH_BUCKETS * sizeof(struct hlist_head),
Pravin B Shelare6445712013-10-03 18:16:47 -07001448 GFP_KERNEL);
Pravin B Shelar15eac2a2012-08-23 12:40:54 -07001449 if (!dp->ports) {
1450 err = -ENOMEM;
1451 goto err_destroy_percpu;
1452 }
1453
1454 for (i = 0; i < DP_VPORT_HASH_BUCKETS; i++)
1455 INIT_HLIST_HEAD(&dp->ports[i]);
1456
Jesse Grossccb13522011-10-25 19:26:31 -07001457 /* Set up our datapath device. */
1458 parms.name = nla_data(a[OVS_DP_ATTR_NAME]);
1459 parms.type = OVS_VPORT_TYPE_INTERNAL;
1460 parms.options = NULL;
1461 parms.dp = dp;
1462 parms.port_no = OVSP_LOCAL;
Alex Wang5cd667b2014-07-17 15:14:13 -07001463 parms.upcall_portids = a[OVS_DP_ATTR_UPCALL_PID];
Jesse Grossccb13522011-10-25 19:26:31 -07001464
Thomas Graf43d4be92013-12-13 15:22:18 +01001465 ovs_dp_change(dp, a);
1466
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001467 /* So far only local changes have been made, now need the lock. */
1468 ovs_lock();
1469
Jesse Grossccb13522011-10-25 19:26:31 -07001470 vport = new_vport(&parms);
1471 if (IS_ERR(vport)) {
1472 err = PTR_ERR(vport);
1473 if (err == -EBUSY)
1474 err = -EEXIST;
1475
Thomas Graf44da5ae2013-12-13 15:22:19 +01001476 if (err == -EEXIST) {
1477 /* An outdated user space instance that does not understand
1478 * the concept of user_features has attempted to create a new
1479 * datapath and is likely to reuse it. Drop all user features.
1480 */
1481 if (info->genlhdr->version < OVS_DP_VER_FEATURES)
1482 ovs_dp_reset_user_features(skb, info);
1483 }
1484
Pravin B Shelar15eac2a2012-08-23 12:40:54 -07001485 goto err_destroy_ports_array;
Jesse Grossccb13522011-10-25 19:26:31 -07001486 }
1487
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001488 err = ovs_dp_cmd_fill_info(dp, reply, info->snd_portid,
1489 info->snd_seq, 0, OVS_DP_CMD_NEW);
1490 BUG_ON(err < 0);
Jesse Grossccb13522011-10-25 19:26:31 -07001491
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001492 ovs_net = net_generic(ovs_dp_get_net(dp), ovs_net_id);
Pravin B Shelar59a35d62013-07-30 15:42:19 -07001493 list_add_tail_rcu(&dp->list_node, &ovs_net->dps);
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001494
1495 ovs_unlock();
Jesse Grossccb13522011-10-25 19:26:31 -07001496
Johannes Berg2a94fe42013-11-19 15:19:39 +01001497 ovs_notify(&dp_datapath_genl_family, reply, info);
Jesse Grossccb13522011-10-25 19:26:31 -07001498 return 0;
1499
Pravin B Shelar15eac2a2012-08-23 12:40:54 -07001500err_destroy_ports_array:
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001501 ovs_unlock();
Pravin B Shelar15eac2a2012-08-23 12:40:54 -07001502 kfree(dp->ports);
Jesse Grossccb13522011-10-25 19:26:31 -07001503err_destroy_percpu:
1504 free_percpu(dp->stats_percpu);
1505err_destroy_table:
Pravin B Shelar9b996e52014-05-06 18:41:20 -07001506 ovs_flow_tbl_destroy(&dp->table);
Jesse Grossccb13522011-10-25 19:26:31 -07001507err_free_dp:
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001508 release_net(ovs_dp_get_net(dp));
Jesse Grossccb13522011-10-25 19:26:31 -07001509 kfree(dp);
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001510err_free_reply:
1511 kfree_skb(reply);
Jesse Grossccb13522011-10-25 19:26:31 -07001512err:
1513 return err;
1514}
1515
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001516/* Called with ovs_mutex. */
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001517static void __dp_destroy(struct datapath *dp)
Jesse Grossccb13522011-10-25 19:26:31 -07001518{
Pravin B Shelar15eac2a2012-08-23 12:40:54 -07001519 int i;
Jesse Grossccb13522011-10-25 19:26:31 -07001520
Pravin B Shelar15eac2a2012-08-23 12:40:54 -07001521 for (i = 0; i < DP_VPORT_HASH_BUCKETS; i++) {
1522 struct vport *vport;
Sasha Levinb67bfe02013-02-27 17:06:00 -08001523 struct hlist_node *n;
Pravin B Shelar15eac2a2012-08-23 12:40:54 -07001524
Sasha Levinb67bfe02013-02-27 17:06:00 -08001525 hlist_for_each_entry_safe(vport, n, &dp->ports[i], dp_hash_node)
Pravin B Shelar15eac2a2012-08-23 12:40:54 -07001526 if (vport->port_no != OVSP_LOCAL)
1527 ovs_dp_detach_port(vport);
1528 }
Jesse Grossccb13522011-10-25 19:26:31 -07001529
Pravin B Shelar59a35d62013-07-30 15:42:19 -07001530 list_del_rcu(&dp->list_node);
Jesse Grossccb13522011-10-25 19:26:31 -07001531
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001532 /* OVSP_LOCAL is datapath internal port. We need to make sure that
Andy Zhoue80857c2014-01-21 09:31:04 -08001533 * all ports in datapath are destroyed first before freeing datapath.
Jesse Grossccb13522011-10-25 19:26:31 -07001534 */
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001535 ovs_dp_detach_port(ovs_vport_ovsl(dp, OVSP_LOCAL));
Jesse Grossccb13522011-10-25 19:26:31 -07001536
Andy Zhoue80857c2014-01-21 09:31:04 -08001537 /* RCU destroy the flow table */
Jesse Grossccb13522011-10-25 19:26:31 -07001538 call_rcu(&dp->rcu, destroy_dp_rcu);
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001539}
1540
1541static int ovs_dp_cmd_del(struct sk_buff *skb, struct genl_info *info)
1542{
1543 struct sk_buff *reply;
1544 struct datapath *dp;
1545 int err;
1546
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001547 reply = ovs_dp_cmd_alloc_info(info);
1548 if (!reply)
1549 return -ENOMEM;
1550
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001551 ovs_lock();
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001552 dp = lookup_datapath(sock_net(skb->sk), info->userhdr, info->attrs);
1553 err = PTR_ERR(dp);
1554 if (IS_ERR(dp))
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001555 goto err_unlock_free;
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001556
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001557 err = ovs_dp_cmd_fill_info(dp, reply, info->snd_portid,
1558 info->snd_seq, 0, OVS_DP_CMD_DEL);
1559 BUG_ON(err < 0);
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001560
1561 __dp_destroy(dp);
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001562 ovs_unlock();
Jesse Grossccb13522011-10-25 19:26:31 -07001563
Johannes Berg2a94fe42013-11-19 15:19:39 +01001564 ovs_notify(&dp_datapath_genl_family, reply, info);
Jesse Grossccb13522011-10-25 19:26:31 -07001565
1566 return 0;
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001567
1568err_unlock_free:
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001569 ovs_unlock();
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001570 kfree_skb(reply);
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001571 return err;
Jesse Grossccb13522011-10-25 19:26:31 -07001572}
1573
1574static int ovs_dp_cmd_set(struct sk_buff *skb, struct genl_info *info)
1575{
1576 struct sk_buff *reply;
1577 struct datapath *dp;
1578 int err;
1579
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001580 reply = ovs_dp_cmd_alloc_info(info);
1581 if (!reply)
1582 return -ENOMEM;
1583
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001584 ovs_lock();
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001585 dp = lookup_datapath(sock_net(skb->sk), info->userhdr, info->attrs);
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001586 err = PTR_ERR(dp);
Jesse Grossccb13522011-10-25 19:26:31 -07001587 if (IS_ERR(dp))
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001588 goto err_unlock_free;
Jesse Grossccb13522011-10-25 19:26:31 -07001589
Thomas Graf43d4be92013-12-13 15:22:18 +01001590 ovs_dp_change(dp, info->attrs);
1591
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001592 err = ovs_dp_cmd_fill_info(dp, reply, info->snd_portid,
1593 info->snd_seq, 0, OVS_DP_CMD_NEW);
1594 BUG_ON(err < 0);
Jesse Grossccb13522011-10-25 19:26:31 -07001595
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001596 ovs_unlock();
Johannes Berg2a94fe42013-11-19 15:19:39 +01001597 ovs_notify(&dp_datapath_genl_family, reply, info);
Jesse Grossccb13522011-10-25 19:26:31 -07001598
1599 return 0;
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001600
1601err_unlock_free:
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001602 ovs_unlock();
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001603 kfree_skb(reply);
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001604 return err;
Jesse Grossccb13522011-10-25 19:26:31 -07001605}
1606
1607static int ovs_dp_cmd_get(struct sk_buff *skb, struct genl_info *info)
1608{
1609 struct sk_buff *reply;
1610 struct datapath *dp;
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001611 int err;
Jesse Grossccb13522011-10-25 19:26:31 -07001612
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001613 reply = ovs_dp_cmd_alloc_info(info);
1614 if (!reply)
1615 return -ENOMEM;
1616
1617 rcu_read_lock();
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001618 dp = lookup_datapath(sock_net(skb->sk), info->userhdr, info->attrs);
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001619 if (IS_ERR(dp)) {
1620 err = PTR_ERR(dp);
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001621 goto err_unlock_free;
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001622 }
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001623 err = ovs_dp_cmd_fill_info(dp, reply, info->snd_portid,
1624 info->snd_seq, 0, OVS_DP_CMD_NEW);
1625 BUG_ON(err < 0);
1626 rcu_read_unlock();
Jesse Grossccb13522011-10-25 19:26:31 -07001627
Jesse Grossccb13522011-10-25 19:26:31 -07001628 return genlmsg_reply(reply, info);
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001629
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001630err_unlock_free:
1631 rcu_read_unlock();
1632 kfree_skb(reply);
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001633 return err;
Jesse Grossccb13522011-10-25 19:26:31 -07001634}
1635
1636static int ovs_dp_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb)
1637{
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001638 struct ovs_net *ovs_net = net_generic(sock_net(skb->sk), ovs_net_id);
Jesse Grossccb13522011-10-25 19:26:31 -07001639 struct datapath *dp;
1640 int skip = cb->args[0];
1641 int i = 0;
1642
Pravin B Shelar59a35d62013-07-30 15:42:19 -07001643 rcu_read_lock();
1644 list_for_each_entry_rcu(dp, &ovs_net->dps, list_node) {
Ben Pfaff77676fd2012-01-17 13:33:39 +00001645 if (i >= skip &&
Eric W. Biederman15e47302012-09-07 20:12:54 +00001646 ovs_dp_cmd_fill_info(dp, skb, NETLINK_CB(cb->skb).portid,
Jesse Grossccb13522011-10-25 19:26:31 -07001647 cb->nlh->nlmsg_seq, NLM_F_MULTI,
1648 OVS_DP_CMD_NEW) < 0)
1649 break;
1650 i++;
1651 }
Pravin B Shelar59a35d62013-07-30 15:42:19 -07001652 rcu_read_unlock();
Jesse Grossccb13522011-10-25 19:26:31 -07001653
1654 cb->args[0] = i;
1655
1656 return skb->len;
1657}
1658
Pravin B Shelar0c200ef2014-05-06 16:44:50 -07001659static const struct nla_policy datapath_policy[OVS_DP_ATTR_MAX + 1] = {
1660 [OVS_DP_ATTR_NAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ - 1 },
1661 [OVS_DP_ATTR_UPCALL_PID] = { .type = NLA_U32 },
1662 [OVS_DP_ATTR_USER_FEATURES] = { .type = NLA_U32 },
1663};
1664
stephen hemminger48e48a72014-07-16 11:25:52 -07001665static const struct genl_ops dp_datapath_genl_ops[] = {
Jesse Grossccb13522011-10-25 19:26:31 -07001666 { .cmd = OVS_DP_CMD_NEW,
1667 .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
1668 .policy = datapath_policy,
1669 .doit = ovs_dp_cmd_new
1670 },
1671 { .cmd = OVS_DP_CMD_DEL,
1672 .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
1673 .policy = datapath_policy,
1674 .doit = ovs_dp_cmd_del
1675 },
1676 { .cmd = OVS_DP_CMD_GET,
1677 .flags = 0, /* OK for unprivileged users. */
1678 .policy = datapath_policy,
1679 .doit = ovs_dp_cmd_get,
1680 .dumpit = ovs_dp_cmd_dump
1681 },
1682 { .cmd = OVS_DP_CMD_SET,
1683 .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
1684 .policy = datapath_policy,
1685 .doit = ovs_dp_cmd_set,
1686 },
1687};
1688
Pravin B Shelar0c200ef2014-05-06 16:44:50 -07001689static struct genl_family dp_datapath_genl_family = {
Jesse Grossccb13522011-10-25 19:26:31 -07001690 .id = GENL_ID_GENERATE,
1691 .hdrsize = sizeof(struct ovs_header),
Pravin B Shelar0c200ef2014-05-06 16:44:50 -07001692 .name = OVS_DATAPATH_FAMILY,
1693 .version = OVS_DATAPATH_VERSION,
1694 .maxattr = OVS_DP_ATTR_MAX,
Pravin B Shelar3a4e0d62013-04-23 07:48:48 +00001695 .netnsok = true,
1696 .parallel_ops = true,
Pravin B Shelar0c200ef2014-05-06 16:44:50 -07001697 .ops = dp_datapath_genl_ops,
1698 .n_ops = ARRAY_SIZE(dp_datapath_genl_ops),
1699 .mcgrps = &ovs_dp_datapath_multicast_group,
1700 .n_mcgrps = 1,
Jesse Grossccb13522011-10-25 19:26:31 -07001701};
1702
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001703/* Called with ovs_mutex or RCU read lock. */
Jesse Grossccb13522011-10-25 19:26:31 -07001704static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb,
Eric W. Biederman15e47302012-09-07 20:12:54 +00001705 u32 portid, u32 seq, u32 flags, u8 cmd)
Jesse Grossccb13522011-10-25 19:26:31 -07001706{
1707 struct ovs_header *ovs_header;
1708 struct ovs_vport_stats vport_stats;
1709 int err;
1710
Eric W. Biederman15e47302012-09-07 20:12:54 +00001711 ovs_header = genlmsg_put(skb, portid, seq, &dp_vport_genl_family,
Jesse Grossccb13522011-10-25 19:26:31 -07001712 flags, cmd);
1713 if (!ovs_header)
1714 return -EMSGSIZE;
1715
1716 ovs_header->dp_ifindex = get_dpifindex(vport->dp);
1717
David S. Miller028d6a62012-03-29 23:20:48 -04001718 if (nla_put_u32(skb, OVS_VPORT_ATTR_PORT_NO, vport->port_no) ||
1719 nla_put_u32(skb, OVS_VPORT_ATTR_TYPE, vport->ops->type) ||
Alex Wang5cd667b2014-07-17 15:14:13 -07001720 nla_put_string(skb, OVS_VPORT_ATTR_NAME,
1721 vport->ops->get_name(vport)))
David S. Miller028d6a62012-03-29 23:20:48 -04001722 goto nla_put_failure;
Jesse Grossccb13522011-10-25 19:26:31 -07001723
1724 ovs_vport_get_stats(vport, &vport_stats);
David S. Miller028d6a62012-03-29 23:20:48 -04001725 if (nla_put(skb, OVS_VPORT_ATTR_STATS, sizeof(struct ovs_vport_stats),
1726 &vport_stats))
1727 goto nla_put_failure;
Jesse Grossccb13522011-10-25 19:26:31 -07001728
Alex Wang5cd667b2014-07-17 15:14:13 -07001729 if (ovs_vport_get_upcall_portids(vport, skb))
1730 goto nla_put_failure;
1731
Jesse Grossccb13522011-10-25 19:26:31 -07001732 err = ovs_vport_get_options(vport, skb);
1733 if (err == -EMSGSIZE)
1734 goto error;
1735
1736 return genlmsg_end(skb, ovs_header);
1737
1738nla_put_failure:
1739 err = -EMSGSIZE;
1740error:
1741 genlmsg_cancel(skb, ovs_header);
1742 return err;
1743}
1744
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001745static struct sk_buff *ovs_vport_cmd_alloc_info(void)
1746{
1747 return nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1748}
1749
1750/* Called with ovs_mutex, only via ovs_dp_notify_wq(). */
Eric W. Biederman15e47302012-09-07 20:12:54 +00001751struct sk_buff *ovs_vport_cmd_build_info(struct vport *vport, u32 portid,
Jesse Grossccb13522011-10-25 19:26:31 -07001752 u32 seq, u8 cmd)
1753{
1754 struct sk_buff *skb;
1755 int retval;
1756
1757 skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
1758 if (!skb)
1759 return ERR_PTR(-ENOMEM);
1760
Eric W. Biederman15e47302012-09-07 20:12:54 +00001761 retval = ovs_vport_cmd_fill_info(vport, skb, portid, seq, 0, cmd);
Jesse Grossa9341512013-03-26 15:48:38 -07001762 BUG_ON(retval < 0);
1763
Jesse Grossccb13522011-10-25 19:26:31 -07001764 return skb;
1765}
1766
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001767/* Called with ovs_mutex or RCU read lock. */
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001768static struct vport *lookup_vport(struct net *net,
1769 struct ovs_header *ovs_header,
Jesse Grossccb13522011-10-25 19:26:31 -07001770 struct nlattr *a[OVS_VPORT_ATTR_MAX + 1])
1771{
1772 struct datapath *dp;
1773 struct vport *vport;
1774
1775 if (a[OVS_VPORT_ATTR_NAME]) {
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001776 vport = ovs_vport_locate(net, nla_data(a[OVS_VPORT_ATTR_NAME]));
Jesse Grossccb13522011-10-25 19:26:31 -07001777 if (!vport)
1778 return ERR_PTR(-ENODEV);
Ben Pfaff651a68e2012-03-06 15:04:04 -08001779 if (ovs_header->dp_ifindex &&
1780 ovs_header->dp_ifindex != get_dpifindex(vport->dp))
1781 return ERR_PTR(-ENODEV);
Jesse Grossccb13522011-10-25 19:26:31 -07001782 return vport;
1783 } else if (a[OVS_VPORT_ATTR_PORT_NO]) {
1784 u32 port_no = nla_get_u32(a[OVS_VPORT_ATTR_PORT_NO]);
1785
1786 if (port_no >= DP_MAX_PORTS)
1787 return ERR_PTR(-EFBIG);
1788
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001789 dp = get_dp(net, ovs_header->dp_ifindex);
Jesse Grossccb13522011-10-25 19:26:31 -07001790 if (!dp)
1791 return ERR_PTR(-ENODEV);
1792
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001793 vport = ovs_vport_ovsl_rcu(dp, port_no);
Jesse Grossccb13522011-10-25 19:26:31 -07001794 if (!vport)
Jarno Rajahalme14408db2013-01-09 14:27:35 -08001795 return ERR_PTR(-ENODEV);
Jesse Grossccb13522011-10-25 19:26:31 -07001796 return vport;
1797 } else
1798 return ERR_PTR(-EINVAL);
1799}
1800
1801static int ovs_vport_cmd_new(struct sk_buff *skb, struct genl_info *info)
1802{
1803 struct nlattr **a = info->attrs;
1804 struct ovs_header *ovs_header = info->userhdr;
1805 struct vport_parms parms;
1806 struct sk_buff *reply;
1807 struct vport *vport;
1808 struct datapath *dp;
1809 u32 port_no;
1810 int err;
1811
Jesse Grossccb13522011-10-25 19:26:31 -07001812 if (!a[OVS_VPORT_ATTR_NAME] || !a[OVS_VPORT_ATTR_TYPE] ||
1813 !a[OVS_VPORT_ATTR_UPCALL_PID])
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001814 return -EINVAL;
1815
1816 port_no = a[OVS_VPORT_ATTR_PORT_NO]
1817 ? nla_get_u32(a[OVS_VPORT_ATTR_PORT_NO]) : 0;
1818 if (port_no >= DP_MAX_PORTS)
1819 return -EFBIG;
1820
1821 reply = ovs_vport_cmd_alloc_info();
1822 if (!reply)
1823 return -ENOMEM;
Jesse Grossccb13522011-10-25 19:26:31 -07001824
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001825 ovs_lock();
Thomas Graf62b9c8d2014-10-22 17:29:06 +02001826restart:
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001827 dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex);
Jesse Grossccb13522011-10-25 19:26:31 -07001828 err = -ENODEV;
1829 if (!dp)
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001830 goto exit_unlock_free;
Jesse Grossccb13522011-10-25 19:26:31 -07001831
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001832 if (port_no) {
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001833 vport = ovs_vport_ovsl(dp, port_no);
Jesse Grossccb13522011-10-25 19:26:31 -07001834 err = -EBUSY;
1835 if (vport)
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001836 goto exit_unlock_free;
Jesse Grossccb13522011-10-25 19:26:31 -07001837 } else {
1838 for (port_no = 1; ; port_no++) {
1839 if (port_no >= DP_MAX_PORTS) {
1840 err = -EFBIG;
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001841 goto exit_unlock_free;
Jesse Grossccb13522011-10-25 19:26:31 -07001842 }
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001843 vport = ovs_vport_ovsl(dp, port_no);
Jesse Grossccb13522011-10-25 19:26:31 -07001844 if (!vport)
1845 break;
1846 }
1847 }
1848
1849 parms.name = nla_data(a[OVS_VPORT_ATTR_NAME]);
1850 parms.type = nla_get_u32(a[OVS_VPORT_ATTR_TYPE]);
1851 parms.options = a[OVS_VPORT_ATTR_OPTIONS];
1852 parms.dp = dp;
1853 parms.port_no = port_no;
Alex Wang5cd667b2014-07-17 15:14:13 -07001854 parms.upcall_portids = a[OVS_VPORT_ATTR_UPCALL_PID];
Jesse Grossccb13522011-10-25 19:26:31 -07001855
1856 vport = new_vport(&parms);
1857 err = PTR_ERR(vport);
Thomas Graf62b9c8d2014-10-22 17:29:06 +02001858 if (IS_ERR(vport)) {
1859 if (err == -EAGAIN)
1860 goto restart;
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001861 goto exit_unlock_free;
Thomas Graf62b9c8d2014-10-22 17:29:06 +02001862 }
Jesse Grossccb13522011-10-25 19:26:31 -07001863
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001864 err = ovs_vport_cmd_fill_info(vport, reply, info->snd_portid,
1865 info->snd_seq, 0, OVS_VPORT_CMD_NEW);
1866 BUG_ON(err < 0);
1867 ovs_unlock();
Thomas Grafed6611852013-03-29 14:46:50 +01001868
Johannes Berg2a94fe42013-11-19 15:19:39 +01001869 ovs_notify(&dp_vport_genl_family, reply, info);
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001870 return 0;
Jesse Grossccb13522011-10-25 19:26:31 -07001871
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001872exit_unlock_free:
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001873 ovs_unlock();
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001874 kfree_skb(reply);
Jesse Grossccb13522011-10-25 19:26:31 -07001875 return err;
1876}
1877
1878static int ovs_vport_cmd_set(struct sk_buff *skb, struct genl_info *info)
1879{
1880 struct nlattr **a = info->attrs;
1881 struct sk_buff *reply;
1882 struct vport *vport;
1883 int err;
1884
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001885 reply = ovs_vport_cmd_alloc_info();
1886 if (!reply)
1887 return -ENOMEM;
1888
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001889 ovs_lock();
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001890 vport = lookup_vport(sock_net(skb->sk), info->userhdr, a);
Jesse Grossccb13522011-10-25 19:26:31 -07001891 err = PTR_ERR(vport);
1892 if (IS_ERR(vport))
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001893 goto exit_unlock_free;
Jesse Grossccb13522011-10-25 19:26:31 -07001894
Jesse Grossccb13522011-10-25 19:26:31 -07001895 if (a[OVS_VPORT_ATTR_TYPE] &&
Jesse Grossf44f3402013-05-13 08:15:26 -07001896 nla_get_u32(a[OVS_VPORT_ATTR_TYPE]) != vport->ops->type) {
Jesse Grossccb13522011-10-25 19:26:31 -07001897 err = -EINVAL;
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001898 goto exit_unlock_free;
Jesse Grossa9341512013-03-26 15:48:38 -07001899 }
1900
Jesse Grossf44f3402013-05-13 08:15:26 -07001901 if (a[OVS_VPORT_ATTR_OPTIONS]) {
Jesse Grossccb13522011-10-25 19:26:31 -07001902 err = ovs_vport_set_options(vport, a[OVS_VPORT_ATTR_OPTIONS]);
Jesse Grossf44f3402013-05-13 08:15:26 -07001903 if (err)
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001904 goto exit_unlock_free;
Jesse Grossf44f3402013-05-13 08:15:26 -07001905 }
Jesse Grossa9341512013-03-26 15:48:38 -07001906
Alex Wang5cd667b2014-07-17 15:14:13 -07001907
1908 if (a[OVS_VPORT_ATTR_UPCALL_PID]) {
1909 struct nlattr *ids = a[OVS_VPORT_ATTR_UPCALL_PID];
1910
1911 err = ovs_vport_set_upcall_portids(vport, ids);
1912 if (err)
1913 goto exit_unlock_free;
1914 }
Jesse Grossccb13522011-10-25 19:26:31 -07001915
Jesse Grossa9341512013-03-26 15:48:38 -07001916 err = ovs_vport_cmd_fill_info(vport, reply, info->snd_portid,
1917 info->snd_seq, 0, OVS_VPORT_CMD_NEW);
1918 BUG_ON(err < 0);
Jesse Grossccb13522011-10-25 19:26:31 -07001919
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001920 ovs_unlock();
Johannes Berg2a94fe42013-11-19 15:19:39 +01001921 ovs_notify(&dp_vport_genl_family, reply, info);
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001922 return 0;
Jesse Grossccb13522011-10-25 19:26:31 -07001923
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001924exit_unlock_free:
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001925 ovs_unlock();
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001926 kfree_skb(reply);
Jesse Grossccb13522011-10-25 19:26:31 -07001927 return err;
1928}
1929
1930static int ovs_vport_cmd_del(struct sk_buff *skb, struct genl_info *info)
1931{
1932 struct nlattr **a = info->attrs;
1933 struct sk_buff *reply;
1934 struct vport *vport;
1935 int err;
1936
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001937 reply = ovs_vport_cmd_alloc_info();
1938 if (!reply)
1939 return -ENOMEM;
1940
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001941 ovs_lock();
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001942 vport = lookup_vport(sock_net(skb->sk), info->userhdr, a);
Jesse Grossccb13522011-10-25 19:26:31 -07001943 err = PTR_ERR(vport);
1944 if (IS_ERR(vport))
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001945 goto exit_unlock_free;
Jesse Grossccb13522011-10-25 19:26:31 -07001946
1947 if (vport->port_no == OVSP_LOCAL) {
1948 err = -EINVAL;
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001949 goto exit_unlock_free;
Jesse Grossccb13522011-10-25 19:26:31 -07001950 }
1951
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001952 err = ovs_vport_cmd_fill_info(vport, reply, info->snd_portid,
1953 info->snd_seq, 0, OVS_VPORT_CMD_DEL);
1954 BUG_ON(err < 0);
Jesse Grossccb13522011-10-25 19:26:31 -07001955 ovs_dp_detach_port(vport);
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001956 ovs_unlock();
Jesse Grossccb13522011-10-25 19:26:31 -07001957
Johannes Berg2a94fe42013-11-19 15:19:39 +01001958 ovs_notify(&dp_vport_genl_family, reply, info);
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001959 return 0;
Jesse Grossccb13522011-10-25 19:26:31 -07001960
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001961exit_unlock_free:
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07001962 ovs_unlock();
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001963 kfree_skb(reply);
Jesse Grossccb13522011-10-25 19:26:31 -07001964 return err;
1965}
1966
1967static int ovs_vport_cmd_get(struct sk_buff *skb, struct genl_info *info)
1968{
1969 struct nlattr **a = info->attrs;
1970 struct ovs_header *ovs_header = info->userhdr;
1971 struct sk_buff *reply;
1972 struct vport *vport;
1973 int err;
1974
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001975 reply = ovs_vport_cmd_alloc_info();
1976 if (!reply)
1977 return -ENOMEM;
1978
Jesse Grossccb13522011-10-25 19:26:31 -07001979 rcu_read_lock();
Pravin B Shelar46df7b82012-02-22 19:58:59 -08001980 vport = lookup_vport(sock_net(skb->sk), ovs_header, a);
Jesse Grossccb13522011-10-25 19:26:31 -07001981 err = PTR_ERR(vport);
1982 if (IS_ERR(vport))
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001983 goto exit_unlock_free;
1984 err = ovs_vport_cmd_fill_info(vport, reply, info->snd_portid,
1985 info->snd_seq, 0, OVS_VPORT_CMD_NEW);
1986 BUG_ON(err < 0);
Jesse Grossccb13522011-10-25 19:26:31 -07001987 rcu_read_unlock();
1988
1989 return genlmsg_reply(reply, info);
1990
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001991exit_unlock_free:
Jesse Grossccb13522011-10-25 19:26:31 -07001992 rcu_read_unlock();
Jarno Rajahalme6093ae92014-05-05 14:13:32 -07001993 kfree_skb(reply);
Jesse Grossccb13522011-10-25 19:26:31 -07001994 return err;
1995}
1996
1997static int ovs_vport_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb)
1998{
1999 struct ovs_header *ovs_header = genlmsg_data(nlmsg_data(cb->nlh));
2000 struct datapath *dp;
Pravin B Shelar15eac2a2012-08-23 12:40:54 -07002001 int bucket = cb->args[0], skip = cb->args[1];
2002 int i, j = 0;
Jesse Grossccb13522011-10-25 19:26:31 -07002003
Jesse Grossccb13522011-10-25 19:26:31 -07002004 rcu_read_lock();
Andy Zhoucc3a5ae2014-09-08 13:14:22 -07002005 dp = get_dp_rcu(sock_net(skb->sk), ovs_header->dp_ifindex);
Jarno Rajahalme42ee19e2014-02-15 17:42:29 -08002006 if (!dp) {
2007 rcu_read_unlock();
2008 return -ENODEV;
2009 }
Pravin B Shelar15eac2a2012-08-23 12:40:54 -07002010 for (i = bucket; i < DP_VPORT_HASH_BUCKETS; i++) {
Jesse Grossccb13522011-10-25 19:26:31 -07002011 struct vport *vport;
2012
Pravin B Shelar15eac2a2012-08-23 12:40:54 -07002013 j = 0;
Sasha Levinb67bfe02013-02-27 17:06:00 -08002014 hlist_for_each_entry_rcu(vport, &dp->ports[i], dp_hash_node) {
Pravin B Shelar15eac2a2012-08-23 12:40:54 -07002015 if (j >= skip &&
2016 ovs_vport_cmd_fill_info(vport, skb,
Eric W. Biederman15e47302012-09-07 20:12:54 +00002017 NETLINK_CB(cb->skb).portid,
Pravin B Shelar15eac2a2012-08-23 12:40:54 -07002018 cb->nlh->nlmsg_seq,
2019 NLM_F_MULTI,
2020 OVS_VPORT_CMD_NEW) < 0)
2021 goto out;
Jesse Grossccb13522011-10-25 19:26:31 -07002022
Pravin B Shelar15eac2a2012-08-23 12:40:54 -07002023 j++;
2024 }
2025 skip = 0;
Jesse Grossccb13522011-10-25 19:26:31 -07002026 }
Pravin B Shelar15eac2a2012-08-23 12:40:54 -07002027out:
Jesse Grossccb13522011-10-25 19:26:31 -07002028 rcu_read_unlock();
2029
Pravin B Shelar15eac2a2012-08-23 12:40:54 -07002030 cb->args[0] = i;
2031 cb->args[1] = j;
Jesse Grossccb13522011-10-25 19:26:31 -07002032
Pravin B Shelar15eac2a2012-08-23 12:40:54 -07002033 return skb->len;
Jesse Grossccb13522011-10-25 19:26:31 -07002034}
2035
Pravin B Shelar0c200ef2014-05-06 16:44:50 -07002036static const struct nla_policy vport_policy[OVS_VPORT_ATTR_MAX + 1] = {
2037 [OVS_VPORT_ATTR_NAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ - 1 },
2038 [OVS_VPORT_ATTR_STATS] = { .len = sizeof(struct ovs_vport_stats) },
2039 [OVS_VPORT_ATTR_PORT_NO] = { .type = NLA_U32 },
2040 [OVS_VPORT_ATTR_TYPE] = { .type = NLA_U32 },
2041 [OVS_VPORT_ATTR_UPCALL_PID] = { .type = NLA_U32 },
2042 [OVS_VPORT_ATTR_OPTIONS] = { .type = NLA_NESTED },
2043};
2044
stephen hemminger48e48a72014-07-16 11:25:52 -07002045static const struct genl_ops dp_vport_genl_ops[] = {
Jesse Grossccb13522011-10-25 19:26:31 -07002046 { .cmd = OVS_VPORT_CMD_NEW,
2047 .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
2048 .policy = vport_policy,
2049 .doit = ovs_vport_cmd_new
2050 },
2051 { .cmd = OVS_VPORT_CMD_DEL,
2052 .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
2053 .policy = vport_policy,
2054 .doit = ovs_vport_cmd_del
2055 },
2056 { .cmd = OVS_VPORT_CMD_GET,
2057 .flags = 0, /* OK for unprivileged users. */
2058 .policy = vport_policy,
2059 .doit = ovs_vport_cmd_get,
2060 .dumpit = ovs_vport_cmd_dump
2061 },
2062 { .cmd = OVS_VPORT_CMD_SET,
2063 .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
2064 .policy = vport_policy,
2065 .doit = ovs_vport_cmd_set,
2066 },
2067};
2068
Pravin B Shelar0c200ef2014-05-06 16:44:50 -07002069struct genl_family dp_vport_genl_family = {
2070 .id = GENL_ID_GENERATE,
2071 .hdrsize = sizeof(struct ovs_header),
2072 .name = OVS_VPORT_FAMILY,
2073 .version = OVS_VPORT_VERSION,
2074 .maxattr = OVS_VPORT_ATTR_MAX,
2075 .netnsok = true,
2076 .parallel_ops = true,
2077 .ops = dp_vport_genl_ops,
2078 .n_ops = ARRAY_SIZE(dp_vport_genl_ops),
2079 .mcgrps = &ovs_dp_vport_multicast_group,
2080 .n_mcgrps = 1,
Jesse Grossccb13522011-10-25 19:26:31 -07002081};
2082
Pravin B Shelar0c200ef2014-05-06 16:44:50 -07002083static struct genl_family * const dp_genl_families[] = {
2084 &dp_datapath_genl_family,
2085 &dp_vport_genl_family,
2086 &dp_flow_genl_family,
2087 &dp_packet_genl_family,
Jesse Grossccb13522011-10-25 19:26:31 -07002088};
2089
2090static void dp_unregister_genl(int n_families)
2091{
2092 int i;
2093
2094 for (i = 0; i < n_families; i++)
Pravin B Shelar0c200ef2014-05-06 16:44:50 -07002095 genl_unregister_family(dp_genl_families[i]);
Jesse Grossccb13522011-10-25 19:26:31 -07002096}
2097
2098static int dp_register_genl(void)
2099{
Jesse Grossccb13522011-10-25 19:26:31 -07002100 int err;
2101 int i;
2102
Jesse Grossccb13522011-10-25 19:26:31 -07002103 for (i = 0; i < ARRAY_SIZE(dp_genl_families); i++) {
Jesse Grossccb13522011-10-25 19:26:31 -07002104
Pravin B Shelar0c200ef2014-05-06 16:44:50 -07002105 err = genl_register_family(dp_genl_families[i]);
Jesse Grossccb13522011-10-25 19:26:31 -07002106 if (err)
2107 goto error;
Jesse Grossccb13522011-10-25 19:26:31 -07002108 }
2109
2110 return 0;
2111
2112error:
Pravin B Shelar0c200ef2014-05-06 16:44:50 -07002113 dp_unregister_genl(i);
Jesse Grossccb13522011-10-25 19:26:31 -07002114 return err;
2115}
2116
Pravin B Shelar46df7b82012-02-22 19:58:59 -08002117static int __net_init ovs_init_net(struct net *net)
2118{
2119 struct ovs_net *ovs_net = net_generic(net, ovs_net_id);
2120
2121 INIT_LIST_HEAD(&ovs_net->dps);
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07002122 INIT_WORK(&ovs_net->dp_notify_work, ovs_dp_notify_wq);
Pravin B Shelar46df7b82012-02-22 19:58:59 -08002123 return 0;
2124}
2125
2126static void __net_exit ovs_exit_net(struct net *net)
2127{
Pravin B Shelar46df7b82012-02-22 19:58:59 -08002128 struct datapath *dp, *dp_next;
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07002129 struct ovs_net *ovs_net = net_generic(net, ovs_net_id);
Pravin B Shelar46df7b82012-02-22 19:58:59 -08002130
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07002131 ovs_lock();
Pravin B Shelar46df7b82012-02-22 19:58:59 -08002132 list_for_each_entry_safe(dp, dp_next, &ovs_net->dps, list_node)
2133 __dp_destroy(dp);
Pravin B Shelar8e4e1712013-04-15 13:23:03 -07002134 ovs_unlock();
2135
2136 cancel_work_sync(&ovs_net->dp_notify_work);
Pravin B Shelar46df7b82012-02-22 19:58:59 -08002137}
2138
2139static struct pernet_operations ovs_net_ops = {
2140 .init = ovs_init_net,
2141 .exit = ovs_exit_net,
2142 .id = &ovs_net_id,
2143 .size = sizeof(struct ovs_net),
2144};
2145
Jesse Grossccb13522011-10-25 19:26:31 -07002146static int __init dp_init(void)
2147{
Jesse Grossccb13522011-10-25 19:26:31 -07002148 int err;
2149
YOSHIFUJI Hideaki / 吉藤英明3523b292013-01-09 07:19:55 +00002150 BUILD_BUG_ON(sizeof(struct ovs_skb_cb) > FIELD_SIZEOF(struct sk_buff, cb));
Jesse Grossccb13522011-10-25 19:26:31 -07002151
2152 pr_info("Open vSwitch switching datapath\n");
2153
Andy Zhou971427f32014-09-15 19:37:25 -07002154 err = action_fifos_init();
Jesse Grossccb13522011-10-25 19:26:31 -07002155 if (err)
2156 goto error;
2157
Andy Zhou971427f32014-09-15 19:37:25 -07002158 err = ovs_internal_dev_rtnl_link_register();
2159 if (err)
2160 goto error_action_fifos_exit;
2161
Jiri Pirko5b9e7e12014-06-26 09:58:26 +02002162 err = ovs_flow_init();
2163 if (err)
2164 goto error_unreg_rtnl_link;
2165
Jesse Grossccb13522011-10-25 19:26:31 -07002166 err = ovs_vport_init();
2167 if (err)
2168 goto error_flow_exit;
2169
Pravin B Shelar46df7b82012-02-22 19:58:59 -08002170 err = register_pernet_device(&ovs_net_ops);
Jesse Grossccb13522011-10-25 19:26:31 -07002171 if (err)
2172 goto error_vport_exit;
2173
Pravin B Shelar46df7b82012-02-22 19:58:59 -08002174 err = register_netdevice_notifier(&ovs_dp_device_notifier);
2175 if (err)
2176 goto error_netns_exit;
2177
Thomas Graf62b9c8d2014-10-22 17:29:06 +02002178 err = ovs_netdev_init();
2179 if (err)
2180 goto error_unreg_notifier;
2181
Jesse Grossccb13522011-10-25 19:26:31 -07002182 err = dp_register_genl();
2183 if (err < 0)
Thomas Graf62b9c8d2014-10-22 17:29:06 +02002184 goto error_unreg_netdev;
Jesse Grossccb13522011-10-25 19:26:31 -07002185
Jesse Grossccb13522011-10-25 19:26:31 -07002186 return 0;
2187
Thomas Graf62b9c8d2014-10-22 17:29:06 +02002188error_unreg_netdev:
2189 ovs_netdev_exit();
Jesse Grossccb13522011-10-25 19:26:31 -07002190error_unreg_notifier:
2191 unregister_netdevice_notifier(&ovs_dp_device_notifier);
Pravin B Shelar46df7b82012-02-22 19:58:59 -08002192error_netns_exit:
2193 unregister_pernet_device(&ovs_net_ops);
Jesse Grossccb13522011-10-25 19:26:31 -07002194error_vport_exit:
2195 ovs_vport_exit();
2196error_flow_exit:
2197 ovs_flow_exit();
Jiri Pirko5b9e7e12014-06-26 09:58:26 +02002198error_unreg_rtnl_link:
2199 ovs_internal_dev_rtnl_link_unregister();
Andy Zhou971427f32014-09-15 19:37:25 -07002200error_action_fifos_exit:
2201 action_fifos_exit();
Jesse Grossccb13522011-10-25 19:26:31 -07002202error:
2203 return err;
2204}
2205
2206static void dp_cleanup(void)
2207{
Jesse Grossccb13522011-10-25 19:26:31 -07002208 dp_unregister_genl(ARRAY_SIZE(dp_genl_families));
Thomas Graf62b9c8d2014-10-22 17:29:06 +02002209 ovs_netdev_exit();
Jesse Grossccb13522011-10-25 19:26:31 -07002210 unregister_netdevice_notifier(&ovs_dp_device_notifier);
Pravin B Shelar46df7b82012-02-22 19:58:59 -08002211 unregister_pernet_device(&ovs_net_ops);
2212 rcu_barrier();
Jesse Grossccb13522011-10-25 19:26:31 -07002213 ovs_vport_exit();
2214 ovs_flow_exit();
Jiri Pirko5b9e7e12014-06-26 09:58:26 +02002215 ovs_internal_dev_rtnl_link_unregister();
Andy Zhou971427f32014-09-15 19:37:25 -07002216 action_fifos_exit();
Jesse Grossccb13522011-10-25 19:26:31 -07002217}
2218
2219module_init(dp_init);
2220module_exit(dp_cleanup);
2221
2222MODULE_DESCRIPTION("Open vSwitch switching datapath");
2223MODULE_LICENSE("GPL");