aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-09-16 16:21:48 -0400
committerDavid S. Miller <davem@davemloft.net>2014-09-16 16:21:48 -0400
commit2d9d65fa4418b64112199449e90af226764537e4 (patch)
treeed27b33b69195f3cf86642f423070d645adcc34a
parente1f93eb06c3a13b29b1980f27dada960503cd49e (diff)
parent971427f353f3c42c8dcef62e7124440df68eb809 (diff)
Merge branch 'net_next_ovs' of git://git.kernel.org/pub/scm/linux/kernel/git/pshelar/openvswitch
Pravin B Shelar says: ==================== Open vSwitch Following patches adds recirculation and hash action to OVS. First patch removes pointer to stack object. Next three patches does code restructuring which is required for last patch. Recirculation implementation is changed, according to comments from David Miller, to avoid using recursive calls in OVS. It is using queue to record recirc action and deferred recirc is executed at the end of current actions execution. v1-v2: Changed subsystem name in subject to openvswitch v2-v3: Added patch to remove pkt_key pointer from skb->cb. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/uapi/linux/openvswitch.h26
-rw-r--r--net/openvswitch/actions.c258
-rw-r--r--net/openvswitch/datapath.c52
-rw-r--r--net/openvswitch/datapath.h23
-rw-r--r--net/openvswitch/flow.c57
-rw-r--r--net/openvswitch/flow.h10
-rw-r--r--net/openvswitch/flow_netlink.c65
-rw-r--r--net/openvswitch/flow_netlink.h4
-rw-r--r--net/openvswitch/vport-gre.c23
-rw-r--r--net/openvswitch/vport-vxlan.c21
-rw-r--r--net/openvswitch/vport.c15
11 files changed, 428 insertions, 126 deletions
diff --git a/include/uapi/linux/openvswitch.h b/include/uapi/linux/openvswitch.h
index a794d1dd7b40..f7fc507d82ab 100644
--- a/include/uapi/linux/openvswitch.h
+++ b/include/uapi/linux/openvswitch.h
@@ -289,6 +289,9 @@ enum ovs_key_attr {
289 OVS_KEY_ATTR_TUNNEL, /* Nested set of ovs_tunnel attributes */ 289 OVS_KEY_ATTR_TUNNEL, /* Nested set of ovs_tunnel attributes */
290 OVS_KEY_ATTR_SCTP, /* struct ovs_key_sctp */ 290 OVS_KEY_ATTR_SCTP, /* struct ovs_key_sctp */
291 OVS_KEY_ATTR_TCP_FLAGS, /* be16 TCP flags. */ 291 OVS_KEY_ATTR_TCP_FLAGS, /* be16 TCP flags. */
292 OVS_KEY_ATTR_DP_HASH, /* u32 hash value. Value 0 indicates the hash
293 is not computed by the datapath. */
294 OVS_KEY_ATTR_RECIRC_ID, /* u32 recirc id */
292 295
293#ifdef __KERNEL__ 296#ifdef __KERNEL__
294 OVS_KEY_ATTR_IPV4_TUNNEL, /* struct ovs_key_ipv4_tunnel */ 297 OVS_KEY_ATTR_IPV4_TUNNEL, /* struct ovs_key_ipv4_tunnel */
@@ -493,6 +496,27 @@ struct ovs_action_push_vlan {
493 __be16 vlan_tci; /* 802.1Q TCI (VLAN ID and priority). */ 496 __be16 vlan_tci; /* 802.1Q TCI (VLAN ID and priority). */
494}; 497};
495 498
499/* Data path hash algorithm for computing Datapath hash.
500 *
501 * The algorithm type only specifies the fields in a flow
502 * will be used as part of the hash. Each datapath is free
503 * to use its own hash algorithm. The hash value will be
504 * opaque to the user space daemon.
505 */
506enum ovs_hash_alg {
507 OVS_HASH_ALG_L4,
508};
509
510/*
511 * struct ovs_action_hash - %OVS_ACTION_ATTR_HASH action argument.
512 * @hash_alg: Algorithm used to compute hash prior to recirculation.
513 * @hash_basis: basis used for computing hash.
514 */
515struct ovs_action_hash {
516 uint32_t hash_alg; /* One of ovs_hash_alg. */
517 uint32_t hash_basis;
518};
519
496/** 520/**
497 * enum ovs_action_attr - Action types. 521 * enum ovs_action_attr - Action types.
498 * 522 *
@@ -521,6 +545,8 @@ enum ovs_action_attr {
521 OVS_ACTION_ATTR_PUSH_VLAN, /* struct ovs_action_push_vlan. */ 545 OVS_ACTION_ATTR_PUSH_VLAN, /* struct ovs_action_push_vlan. */
522 OVS_ACTION_ATTR_POP_VLAN, /* No argument. */ 546 OVS_ACTION_ATTR_POP_VLAN, /* No argument. */
523 OVS_ACTION_ATTR_SAMPLE, /* Nested OVS_SAMPLE_ATTR_*. */ 547 OVS_ACTION_ATTR_SAMPLE, /* Nested OVS_SAMPLE_ATTR_*. */
548 OVS_ACTION_ATTR_RECIRC, /* u32 recirc_id. */
549 OVS_ACTION_ATTR_HASH, /* struct ovs_action_hash. */
524 __OVS_ACTION_ATTR_MAX 550 __OVS_ACTION_ATTR_MAX
525}; 551};
526 552
diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c
index 5231652a95d9..6932a42e41a2 100644
--- a/net/openvswitch/actions.c
+++ b/net/openvswitch/actions.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2007-2013 Nicira, Inc. 2 * Copyright (c) 2007-2014 Nicira, Inc.
3 * 3 *
4 * This program is free software; you can redistribute it and/or 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 5 * modify it under the terms of version 2 of the GNU General Public
@@ -35,11 +35,78 @@
35#include <net/sctp/checksum.h> 35#include <net/sctp/checksum.h>
36 36
37#include "datapath.h" 37#include "datapath.h"
38#include "flow.h"
38#include "vport.h" 39#include "vport.h"
39 40
40static int do_execute_actions(struct datapath *dp, struct sk_buff *skb, 41static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
42 struct sw_flow_key *key,
41 const struct nlattr *attr, int len); 43 const struct nlattr *attr, int len);
42 44
45struct deferred_action {
46 struct sk_buff *skb;
47 const struct nlattr *actions;
48
49 /* Store pkt_key clone when creating deferred action. */
50 struct sw_flow_key pkt_key;
51};
52
53#define DEFERRED_ACTION_FIFO_SIZE 10
54struct action_fifo {
55 int head;
56 int tail;
57 /* Deferred action fifo queue storage. */
58 struct deferred_action fifo[DEFERRED_ACTION_FIFO_SIZE];
59};
60
61static struct action_fifo __percpu *action_fifos;
62static DEFINE_PER_CPU(int, exec_actions_level);
63
64static void action_fifo_init(struct action_fifo *fifo)
65{
66 fifo->head = 0;
67 fifo->tail = 0;
68}
69
70static bool action_fifo_is_empty(struct action_fifo *fifo)
71{
72 return (fifo->head == fifo->tail);
73}
74
75static struct deferred_action *action_fifo_get(struct action_fifo *fifo)
76{
77 if (action_fifo_is_empty(fifo))
78 return NULL;
79
80 return &fifo->fifo[fifo->tail++];
81}
82
83static struct deferred_action *action_fifo_put(struct action_fifo *fifo)
84{
85 if (fifo->head >= DEFERRED_ACTION_FIFO_SIZE - 1)
86 return NULL;
87
88 return &fifo->fifo[fifo->head++];
89}
90
91/* Return true if fifo is not full */
92static struct deferred_action *add_deferred_actions(struct sk_buff *skb,
93 struct sw_flow_key *key,
94 const struct nlattr *attr)
95{
96 struct action_fifo *fifo;
97 struct deferred_action *da;
98
99 fifo = this_cpu_ptr(action_fifos);
100 da = action_fifo_put(fifo);
101 if (da) {
102 da->skb = skb;
103 da->actions = attr;
104 da->pkt_key = *key;
105 }
106
107 return da;
108}
109
43static int make_writable(struct sk_buff *skb, int write_len) 110static int make_writable(struct sk_buff *skb, int write_len)
44{ 111{
45 if (!pskb_may_pull(skb, write_len)) 112 if (!pskb_may_pull(skb, write_len))
@@ -410,16 +477,14 @@ static int do_output(struct datapath *dp, struct sk_buff *skb, int out_port)
410} 477}
411 478
412static int output_userspace(struct datapath *dp, struct sk_buff *skb, 479static int output_userspace(struct datapath *dp, struct sk_buff *skb,
413 const struct nlattr *attr) 480 struct sw_flow_key *key, const struct nlattr *attr)
414{ 481{
415 struct dp_upcall_info upcall; 482 struct dp_upcall_info upcall;
416 const struct nlattr *a; 483 const struct nlattr *a;
417 int rem; 484 int rem;
418 485
419 BUG_ON(!OVS_CB(skb)->pkt_key);
420
421 upcall.cmd = OVS_PACKET_CMD_ACTION; 486 upcall.cmd = OVS_PACKET_CMD_ACTION;
422 upcall.key = OVS_CB(skb)->pkt_key; 487 upcall.key = key;
423 upcall.userdata = NULL; 488 upcall.userdata = NULL;
424 upcall.portid = 0; 489 upcall.portid = 0;
425 490
@@ -445,11 +510,10 @@ static bool last_action(const struct nlattr *a, int rem)
445} 510}
446 511
447static int sample(struct datapath *dp, struct sk_buff *skb, 512static int sample(struct datapath *dp, struct sk_buff *skb,
448 const struct nlattr *attr) 513 struct sw_flow_key *key, const struct nlattr *attr)
449{ 514{
450 const struct nlattr *acts_list = NULL; 515 const struct nlattr *acts_list = NULL;
451 const struct nlattr *a; 516 const struct nlattr *a;
452 struct sk_buff *sample_skb;
453 int rem; 517 int rem;
454 518
455 for (a = nla_data(attr), rem = nla_len(attr); rem > 0; 519 for (a = nla_data(attr), rem = nla_len(attr); rem > 0;
@@ -469,31 +533,47 @@ static int sample(struct datapath *dp, struct sk_buff *skb,
469 rem = nla_len(acts_list); 533 rem = nla_len(acts_list);
470 a = nla_data(acts_list); 534 a = nla_data(acts_list);
471 535
472 /* Actions list is either empty or only contains a single user-space 536 /* Actions list is empty, do nothing */
473 * action, the latter being a special case as it is the only known 537 if (unlikely(!rem))
474 * usage of the sample action. 538 return 0;
475 * In these special cases don't clone the skb as there are no 539
476 * side-effects in the nested actions. 540 /* The only known usage of sample action is having a single user-space
477 * Otherwise, clone in case the nested actions have side effects. 541 * action. Treat this usage as a special case.
542 * The output_userspace() should clone the skb to be sent to the
543 * user space. This skb will be consumed by its caller.
478 */ 544 */
479 if (likely(rem == 0 || (nla_type(a) == OVS_ACTION_ATTR_USERSPACE && 545 if (likely(nla_type(a) == OVS_ACTION_ATTR_USERSPACE &&
480 last_action(a, rem)))) { 546 last_action(a, rem)))
481 sample_skb = skb; 547 return output_userspace(dp, skb, key, a);
482 skb_get(skb); 548
483 } else { 549 skb = skb_clone(skb, GFP_ATOMIC);
484 sample_skb = skb_clone(skb, GFP_ATOMIC); 550 if (!skb)
485 if (!sample_skb) /* Skip sample action when out of memory. */ 551 /* Skip the sample action when out of memory. */
486 return 0; 552 return 0;
553
554 if (!add_deferred_actions(skb, key, a)) {
555 if (net_ratelimit())
556 pr_warn("%s: deferred actions limit reached, dropping sample action\n",
557 ovs_dp_name(dp));
558
559 kfree_skb(skb);
487 } 560 }
561 return 0;
562}
488 563
489 /* Note that do_execute_actions() never consumes skb. 564static void execute_hash(struct sk_buff *skb, struct sw_flow_key *key,
490 * In the case where skb has been cloned above it is the clone that 565 const struct nlattr *attr)
491 * is consumed. Otherwise the skb_get(skb) call prevents 566{
492 * consumption by do_execute_actions(). Thus, it is safe to simply 567 struct ovs_action_hash *hash_act = nla_data(attr);
493 * return the error code and let the caller (also 568 u32 hash = 0;
494 * do_execute_actions()) free skb on error. 569
495 */ 570 /* OVS_HASH_ALG_L4 is the only possible hash algorithm. */
496 return do_execute_actions(dp, sample_skb, a, rem); 571 hash = skb_get_hash(skb);
572 hash = jhash_1word(hash, hash_act->hash_basis);
573 if (!hash)
574 hash = 0x1;
575
576 key->ovs_flow_hash = hash;
497} 577}
498 578
499static int execute_set_action(struct sk_buff *skb, 579static int execute_set_action(struct sk_buff *skb,
@@ -511,7 +591,7 @@ static int execute_set_action(struct sk_buff *skb,
511 break; 591 break;
512 592
513 case OVS_KEY_ATTR_IPV4_TUNNEL: 593 case OVS_KEY_ATTR_IPV4_TUNNEL:
514 OVS_CB(skb)->tun_key = nla_data(nested_attr); 594 OVS_CB(skb)->egress_tun_key = nla_data(nested_attr);
515 break; 595 break;
516 596
517 case OVS_KEY_ATTR_ETHERNET: 597 case OVS_KEY_ATTR_ETHERNET:
@@ -542,8 +622,47 @@ static int execute_set_action(struct sk_buff *skb,
542 return err; 622 return err;
543} 623}
544 624
625static int execute_recirc(struct datapath *dp, struct sk_buff *skb,
626 struct sw_flow_key *key,
627 const struct nlattr *a, int rem)
628{
629 struct deferred_action *da;
630 int err;
631
632 err = ovs_flow_key_update(skb, key);
633 if (err)
634 return err;
635
636 if (!last_action(a, rem)) {
637 /* Recirc action is the not the last action
638 * of the action list, need to clone the skb.
639 */
640 skb = skb_clone(skb, GFP_ATOMIC);
641
642 /* Skip the recirc action when out of memory, but
643 * continue on with the rest of the action list.
644 */
645 if (!skb)
646 return 0;
647 }
648
649 da = add_deferred_actions(skb, key, NULL);
650 if (da) {
651 da->pkt_key.recirc_id = nla_get_u32(a);
652 } else {
653 kfree_skb(skb);
654
655 if (net_ratelimit())
656 pr_warn("%s: deferred action limit reached, drop recirc action\n",
657 ovs_dp_name(dp));
658 }
659
660 return 0;
661}
662
545/* Execute a list of actions against 'skb'. */ 663/* Execute a list of actions against 'skb'. */
546static int do_execute_actions(struct datapath *dp, struct sk_buff *skb, 664static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
665 struct sw_flow_key *key,
547 const struct nlattr *attr, int len) 666 const struct nlattr *attr, int len)
548{ 667{
549 /* Every output action needs a separate clone of 'skb', but the common 668 /* Every output action needs a separate clone of 'skb', but the common
@@ -569,7 +688,11 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
569 break; 688 break;
570 689
571 case OVS_ACTION_ATTR_USERSPACE: 690 case OVS_ACTION_ATTR_USERSPACE:
572 output_userspace(dp, skb, a); 691 output_userspace(dp, skb, key, a);
692 break;
693
694 case OVS_ACTION_ATTR_HASH:
695 execute_hash(skb, key, a);
573 break; 696 break;
574 697
575 case OVS_ACTION_ATTR_PUSH_VLAN: 698 case OVS_ACTION_ATTR_PUSH_VLAN:
@@ -582,12 +705,23 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
582 err = pop_vlan(skb); 705 err = pop_vlan(skb);
583 break; 706 break;
584 707
708 case OVS_ACTION_ATTR_RECIRC:
709 err = execute_recirc(dp, skb, key, a, rem);
710 if (last_action(a, rem)) {
711 /* If this is the last action, the skb has
712 * been consumed or freed.
713 * Return immediately.
714 */
715 return err;
716 }
717 break;
718
585 case OVS_ACTION_ATTR_SET: 719 case OVS_ACTION_ATTR_SET:
586 err = execute_set_action(skb, nla_data(a)); 720 err = execute_set_action(skb, nla_data(a));
587 break; 721 break;
588 722
589 case OVS_ACTION_ATTR_SAMPLE: 723 case OVS_ACTION_ATTR_SAMPLE:
590 err = sample(dp, skb, a); 724 err = sample(dp, skb, key, a);
591 if (unlikely(err)) /* skb already freed. */ 725 if (unlikely(err)) /* skb already freed. */
592 return err; 726 return err;
593 break; 727 break;
@@ -607,11 +741,63 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
607 return 0; 741 return 0;
608} 742}
609 743
744static void process_deferred_actions(struct datapath *dp)
745{
746 struct action_fifo *fifo = this_cpu_ptr(action_fifos);
747
748 /* Do not touch the FIFO in case there is no deferred actions. */
749 if (action_fifo_is_empty(fifo))
750 return;
751
752 /* Finishing executing all deferred actions. */
753 do {
754 struct deferred_action *da = action_fifo_get(fifo);
755 struct sk_buff *skb = da->skb;
756 struct sw_flow_key *key = &da->pkt_key;
757 const struct nlattr *actions = da->actions;
758
759 if (actions)
760 do_execute_actions(dp, skb, key, actions,
761 nla_len(actions));
762 else
763 ovs_dp_process_packet(skb, key);
764 } while (!action_fifo_is_empty(fifo));
765
766 /* Reset FIFO for the next packet. */
767 action_fifo_init(fifo);
768}
769
610/* Execute a list of actions against 'skb'. */ 770/* Execute a list of actions against 'skb'. */
611int ovs_execute_actions(struct datapath *dp, struct sk_buff *skb) 771int ovs_execute_actions(struct datapath *dp, struct sk_buff *skb,
772 struct sw_flow_key *key)
612{ 773{
613 struct sw_flow_actions *acts = rcu_dereference(OVS_CB(skb)->flow->sf_acts); 774 int level = this_cpu_read(exec_actions_level);
775 struct sw_flow_actions *acts;
776 int err;
777
778 acts = rcu_dereference(OVS_CB(skb)->flow->sf_acts);
779
780 this_cpu_inc(exec_actions_level);
781 err = do_execute_actions(dp, skb, key,
782 acts->actions, acts->actions_len);
614 783
615 OVS_CB(skb)->tun_key = NULL; 784 if (!level)
616 return do_execute_actions(dp, skb, acts->actions, acts->actions_len); 785 process_deferred_actions(dp);
786
787 this_cpu_dec(exec_actions_level);
788 return err;
789}
790
791int action_fifos_init(void)
792{
793 action_fifos = alloc_percpu(struct action_fifo);
794 if (!action_fifos)
795 return -ENOMEM;
796
797 return 0;
798}
799
800void action_fifos_exit(void)
801{
802 free_percpu(action_fifos);
617} 803}
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index 91d66b7e64ac..16cad14fa81e 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -156,7 +156,7 @@ static struct datapath *get_dp(struct net *net, int dp_ifindex)
156} 156}
157 157
158/* Must be called with rcu_read_lock or ovs_mutex. */ 158/* Must be called with rcu_read_lock or ovs_mutex. */
159static const char *ovs_dp_name(const struct datapath *dp) 159const char *ovs_dp_name(const struct datapath *dp)
160{ 160{
161 struct vport *vport = ovs_vport_ovsl_rcu(dp, OVSP_LOCAL); 161 struct vport *vport = ovs_vport_ovsl_rcu(dp, OVSP_LOCAL);
162 return vport->ops->get_name(vport); 162 return vport->ops->get_name(vport);
@@ -237,32 +237,25 @@ void ovs_dp_detach_port(struct vport *p)
237} 237}
238 238
239/* Must be called with rcu_read_lock. */ 239/* Must be called with rcu_read_lock. */
240void ovs_dp_process_received_packet(struct vport *p, struct sk_buff *skb) 240void ovs_dp_process_packet(struct sk_buff *skb, struct sw_flow_key *key)
241{ 241{
242 const struct vport *p = OVS_CB(skb)->input_vport;
242 struct datapath *dp = p->dp; 243 struct datapath *dp = p->dp;
243 struct sw_flow *flow; 244 struct sw_flow *flow;
244 struct dp_stats_percpu *stats; 245 struct dp_stats_percpu *stats;
245 struct sw_flow_key key;
246 u64 *stats_counter; 246 u64 *stats_counter;
247 u32 n_mask_hit; 247 u32 n_mask_hit;
248 int error;
249 248
250 stats = this_cpu_ptr(dp->stats_percpu); 249 stats = this_cpu_ptr(dp->stats_percpu);
251 250
252 /* Extract flow from 'skb' into 'key'. */
253 error = ovs_flow_extract(skb, p->port_no, &key);
254 if (unlikely(error)) {
255 kfree_skb(skb);
256 return;
257 }
258
259 /* Look up flow. */ 251 /* Look up flow. */
260 flow = ovs_flow_tbl_lookup_stats(&dp->table, &key, &n_mask_hit); 252 flow = ovs_flow_tbl_lookup_stats(&dp->table, key, &n_mask_hit);
261 if (unlikely(!flow)) { 253 if (unlikely(!flow)) {
262 struct dp_upcall_info upcall; 254 struct dp_upcall_info upcall;
255 int error;
263 256
264 upcall.cmd = OVS_PACKET_CMD_MISS; 257 upcall.cmd = OVS_PACKET_CMD_MISS;
265 upcall.key = &key; 258 upcall.key = key;
266 upcall.userdata = NULL; 259 upcall.userdata = NULL;
267 upcall.portid = ovs_vport_find_upcall_portid(p, skb); 260 upcall.portid = ovs_vport_find_upcall_portid(p, skb);
268 error = ovs_dp_upcall(dp, skb, &upcall); 261 error = ovs_dp_upcall(dp, skb, &upcall);
@@ -275,10 +268,9 @@ void ovs_dp_process_received_packet(struct vport *p, struct sk_buff *skb)
275 } 268 }
276 269
277 OVS_CB(skb)->flow = flow; 270 OVS_CB(skb)->flow = flow;
278 OVS_CB(skb)->pkt_key = &key;
279 271
280 ovs_flow_stats_update(OVS_CB(skb)->flow, key.tp.flags, skb); 272 ovs_flow_stats_update(OVS_CB(skb)->flow, key->tp.flags, skb);
281 ovs_execute_actions(dp, skb); 273 ovs_execute_actions(dp, skb, key);
282 stats_counter = &stats->n_hit; 274 stats_counter = &stats->n_hit;
283 275
284out: 276out:
@@ -515,6 +507,7 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info)
515 struct sw_flow *flow; 507 struct sw_flow *flow;
516 struct datapath *dp; 508 struct datapath *dp;
517 struct ethhdr *eth; 509 struct ethhdr *eth;
510 struct vport *input_vport;
518 int len; 511 int len;
519 int err; 512 int err;
520 513
@@ -549,13 +542,11 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info)
549 if (IS_ERR(flow)) 542 if (IS_ERR(flow))
550 goto err_kfree_skb; 543 goto err_kfree_skb;
551 544
552 err = ovs_flow_extract(packet, -1, &flow->key); 545 err = ovs_flow_key_extract_userspace(a[OVS_PACKET_ATTR_KEY], packet,
546 &flow->key);
553 if (err) 547 if (err)
554 goto err_flow_free; 548 goto err_flow_free;
555 549
556 err = ovs_nla_get_flow_metadata(flow, a[OVS_PACKET_ATTR_KEY]);
557 if (err)
558 goto err_flow_free;
559 acts = ovs_nla_alloc_flow_actions(nla_len(a[OVS_PACKET_ATTR_ACTIONS])); 550 acts = ovs_nla_alloc_flow_actions(nla_len(a[OVS_PACKET_ATTR_ACTIONS]));
560 err = PTR_ERR(acts); 551 err = PTR_ERR(acts);
561 if (IS_ERR(acts)) 552 if (IS_ERR(acts))
@@ -568,7 +559,6 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info)
568 goto err_flow_free; 559 goto err_flow_free;
569 560
570 OVS_CB(packet)->flow = flow; 561 OVS_CB(packet)->flow = flow;
571 OVS_CB(packet)->pkt_key = &flow->key;
572 packet->priority = flow->key.phy.priority; 562 packet->priority = flow->key.phy.priority;
573 packet->mark = flow->key.phy.skb_mark; 563 packet->mark = flow->key.phy.skb_mark;
574 564
@@ -578,8 +568,17 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info)
578 if (!dp) 568 if (!dp)
579 goto err_unlock; 569 goto err_unlock;
580 570
571 input_vport = ovs_vport_rcu(dp, flow->key.phy.in_port);
572 if (!input_vport)
573 input_vport = ovs_vport_rcu(dp, OVSP_LOCAL);
574
575 if (!input_vport)
576 goto err_unlock;
577
578 OVS_CB(packet)->input_vport = input_vport;
579
581 local_bh_disable(); 580 local_bh_disable();
582 err = ovs_execute_actions(dp, packet); 581 err = ovs_execute_actions(dp, packet, &flow->key);
583 local_bh_enable(); 582 local_bh_enable();
584 rcu_read_unlock(); 583 rcu_read_unlock();
585 584
@@ -2066,10 +2065,14 @@ static int __init dp_init(void)
2066 2065
2067 pr_info("Open vSwitch switching datapath\n"); 2066 pr_info("Open vSwitch switching datapath\n");
2068 2067
2069 err = ovs_internal_dev_rtnl_link_register(); 2068 err = action_fifos_init();
2070 if (err) 2069 if (err)
2071 goto error; 2070 goto error;
2072 2071
2072 err = ovs_internal_dev_rtnl_link_register();
2073 if (err)
2074 goto error_action_fifos_exit;
2075
2073 err = ovs_flow_init(); 2076 err = ovs_flow_init();
2074 if (err) 2077 if (err)
2075 goto error_unreg_rtnl_link; 2078 goto error_unreg_rtnl_link;
@@ -2102,6 +2105,8 @@ error_flow_exit:
2102 ovs_flow_exit(); 2105 ovs_flow_exit();
2103error_unreg_rtnl_link: 2106error_unreg_rtnl_link:
2104 ovs_internal_dev_rtnl_link_unregister(); 2107 ovs_internal_dev_rtnl_link_unregister();
2108error_action_fifos_exit:
2109 action_fifos_exit();
2105error: 2110error:
2106 return err; 2111 return err;
2107} 2112}
@@ -2115,6 +2120,7 @@ static void dp_cleanup(void)
2115 ovs_vport_exit(); 2120 ovs_vport_exit();
2116 ovs_flow_exit(); 2121 ovs_flow_exit();
2117 ovs_internal_dev_rtnl_link_unregister(); 2122 ovs_internal_dev_rtnl_link_unregister();
2123 action_fifos_exit();
2118} 2124}
2119 2125
2120module_init(dp_init); 2126module_init(dp_init);
diff --git a/net/openvswitch/datapath.h b/net/openvswitch/datapath.h
index 701b5738c38a..ac3f3df96961 100644
--- a/net/openvswitch/datapath.h
+++ b/net/openvswitch/datapath.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2007-2012 Nicira, Inc. 2 * Copyright (c) 2007-2014 Nicira, Inc.
3 * 3 *
4 * This program is free software; you can redistribute it and/or 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 5 * modify it under the terms of version 2 of the GNU General Public
@@ -95,14 +95,15 @@ struct datapath {
95/** 95/**
96 * struct ovs_skb_cb - OVS data in skb CB 96 * struct ovs_skb_cb - OVS data in skb CB
97 * @flow: The flow associated with this packet. May be %NULL if no flow. 97 * @flow: The flow associated with this packet. May be %NULL if no flow.
98 * @pkt_key: The flow information extracted from the packet. Must be nonnull. 98 * @egress_tun_key: Tunnel information about this packet on egress path.
99 * @tun_key: Key for the tunnel that encapsulated this packet. NULL if the 99 * NULL if the packet is not being tunneled.
100 * packet is not being tunneled. 100 * @input_vport: The original vport packet came in on. This value is cached
101 * when a packet is received by OVS.
101 */ 102 */
102struct ovs_skb_cb { 103struct ovs_skb_cb {
103 struct sw_flow *flow; 104 struct sw_flow *flow;
104 struct sw_flow_key *pkt_key; 105 struct vport *input_vport;
105 struct ovs_key_ipv4_tunnel *tun_key; 106 struct ovs_key_ipv4_tunnel *egress_tun_key;
106}; 107};
107#define OVS_CB(skb) ((struct ovs_skb_cb *)(skb)->cb) 108#define OVS_CB(skb) ((struct ovs_skb_cb *)(skb)->cb)
108 109
@@ -183,17 +184,23 @@ static inline struct vport *ovs_vport_ovsl(const struct datapath *dp, int port_n
183extern struct notifier_block ovs_dp_device_notifier; 184extern struct notifier_block ovs_dp_device_notifier;
184extern struct genl_family dp_vport_genl_family; 185extern struct genl_family dp_vport_genl_family;
185 186
186void ovs_dp_process_received_packet(struct vport *, struct sk_buff *); 187void ovs_dp_process_packet(struct sk_buff *skb, struct sw_flow_key *key);
187void ovs_dp_detach_port(struct vport *); 188void ovs_dp_detach_port(struct vport *);
188int ovs_dp_upcall(struct datapath *, struct sk_buff *, 189int ovs_dp_upcall(struct datapath *, struct sk_buff *,
189 const struct dp_upcall_info *); 190 const struct dp_upcall_info *);
190 191
192const char *ovs_dp_name(const struct datapath *dp);
191struct sk_buff *ovs_vport_cmd_build_info(struct vport *, u32 pid, u32 seq, 193struct sk_buff *ovs_vport_cmd_build_info(struct vport *, u32 pid, u32 seq,
192 u8 cmd); 194 u8 cmd);
193 195
194int ovs_execute_actions(struct datapath *dp, struct sk_buff *skb); 196int ovs_execute_actions(struct datapath *dp, struct sk_buff *skb,
197 struct sw_flow_key *);
198
195void ovs_dp_notify_wq(struct work_struct *work); 199void ovs_dp_notify_wq(struct work_struct *work);
196 200
201int action_fifos_init(void);
202void action_fifos_exit(void);
203
197#define OVS_NLERR(fmt, ...) \ 204#define OVS_NLERR(fmt, ...) \
198do { \ 205do { \
199 if (net_ratelimit()) \ 206 if (net_ratelimit()) \
diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c
index 7064da92f420..4010423f2831 100644
--- a/net/openvswitch/flow.c
+++ b/net/openvswitch/flow.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2007-2013 Nicira, Inc. 2 * Copyright (c) 2007-2014 Nicira, Inc.
3 * 3 *
4 * This program is free software; you can redistribute it and/or 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 5 * modify it under the terms of version 2 of the GNU General Public
@@ -16,8 +16,6 @@
16 * 02110-1301, USA 16 * 02110-1301, USA
17 */ 17 */
18 18
19#include "flow.h"
20#include "datapath.h"
21#include <linux/uaccess.h> 19#include <linux/uaccess.h>
22#include <linux/netdevice.h> 20#include <linux/netdevice.h>
23#include <linux/etherdevice.h> 21#include <linux/etherdevice.h>
@@ -46,6 +44,10 @@
46#include <net/ipv6.h> 44#include <net/ipv6.h>
47#include <net/ndisc.h> 45#include <net/ndisc.h>
48 46
47#include "datapath.h"
48#include "flow.h"
49#include "flow_netlink.h"
50
49u64 ovs_flow_used_time(unsigned long flow_jiffies) 51u64 ovs_flow_used_time(unsigned long flow_jiffies)
50{ 52{
51 struct timespec cur_ts; 53 struct timespec cur_ts;
@@ -420,10 +422,9 @@ invalid:
420} 422}
421 423
422/** 424/**
423 * ovs_flow_extract - extracts a flow key from an Ethernet frame. 425 * key_extract - extracts a flow key from an Ethernet frame.
424 * @skb: sk_buff that contains the frame, with skb->data pointing to the 426 * @skb: sk_buff that contains the frame, with skb->data pointing to the
425 * Ethernet header 427 * Ethernet header
426 * @in_port: port number on which @skb was received.
427 * @key: output flow key 428 * @key: output flow key
428 * 429 *
429 * The caller must ensure that skb->len >= ETH_HLEN. 430 * The caller must ensure that skb->len >= ETH_HLEN.
@@ -442,19 +443,11 @@ invalid:
442 * of a correct length, otherwise the same as skb->network_header. 443 * of a correct length, otherwise the same as skb->network_header.
443 * For other key->eth.type values it is left untouched. 444 * For other key->eth.type values it is left untouched.
444 */ 445 */
445int ovs_flow_extract(struct sk_buff *skb, u16 in_port, struct sw_flow_key *key) 446static int key_extract(struct sk_buff *skb, struct sw_flow_key *key)
446{ 447{
447 int error; 448 int error;
448 struct ethhdr *eth; 449 struct ethhdr *eth;
449 450
450 memset(key, 0, sizeof(*key));
451
452 key->phy.priority = skb->priority;
453 if (OVS_CB(skb)->tun_key)
454 memcpy(&key->tun_key, OVS_CB(skb)->tun_key, sizeof(key->tun_key));
455 key->phy.in_port = in_port;
456 key->phy.skb_mark = skb->mark;
457
458 skb_reset_mac_header(skb); 451 skb_reset_mac_header(skb);
459 452
460 /* Link layer. We are guaranteed to have at least the 14 byte Ethernet 453 /* Link layer. We are guaranteed to have at least the 14 byte Ethernet
@@ -610,6 +603,40 @@ int ovs_flow_extract(struct sk_buff *skb, u16 in_port, struct sw_flow_key *key)
610 } 603 }
611 } 604 }
612 } 605 }
613
614 return 0; 606 return 0;
615} 607}
608
609int ovs_flow_key_update(struct sk_buff *skb, struct sw_flow_key *key)
610{
611 return key_extract(skb, key);
612}
613
614int ovs_flow_key_extract(struct ovs_key_ipv4_tunnel *tun_key,
615 struct sk_buff *skb, struct sw_flow_key *key)
616{
617 /* Extract metadata from packet. */
618 memset(key, 0, sizeof(*key));
619 if (tun_key)
620 memcpy(&key->tun_key, tun_key, sizeof(key->tun_key));
621
622 key->phy.priority = skb->priority;
623 key->phy.in_port = OVS_CB(skb)->input_vport->port_no;
624 key->phy.skb_mark = skb->mark;
625
626 return key_extract(skb, key);
627}
628
629int ovs_flow_key_extract_userspace(const struct nlattr *attr,
630 struct sk_buff *skb,
631 struct sw_flow_key *key)
632{
633 int err;
634
635 memset(key, 0, sizeof(*key));
636 /* Extract metadata from netlink attributes. */
637 err = ovs_nla_get_flow_metadata(attr, key);
638 if (err)
639 return err;
640
641 return key_extract(skb, key);
642}
diff --git a/net/openvswitch/flow.h b/net/openvswitch/flow.h
index 5e5aaed3a85b..0f5db4ec565d 100644
--- a/net/openvswitch/flow.h
+++ b/net/openvswitch/flow.h
@@ -72,6 +72,8 @@ struct sw_flow_key {
72 u32 skb_mark; /* SKB mark. */ 72 u32 skb_mark; /* SKB mark. */
73 u16 in_port; /* Input switch port (or DP_MAX_PORTS). */ 73 u16 in_port; /* Input switch port (or DP_MAX_PORTS). */
74 } __packed phy; /* Safe when right after 'tun_key'. */ 74 } __packed phy; /* Safe when right after 'tun_key'. */
75 u32 ovs_flow_hash; /* Datapath computed hash value. */
76 u32 recirc_id; /* Recirculation ID. */
75 struct { 77 struct {
76 u8 src[ETH_ALEN]; /* Ethernet source address. */ 78 u8 src[ETH_ALEN]; /* Ethernet source address. */
77 u8 dst[ETH_ALEN]; /* Ethernet destination address. */ 79 u8 dst[ETH_ALEN]; /* Ethernet destination address. */
@@ -187,6 +189,12 @@ void ovs_flow_stats_get(const struct sw_flow *, struct ovs_flow_stats *,
187void ovs_flow_stats_clear(struct sw_flow *); 189void ovs_flow_stats_clear(struct sw_flow *);
188u64 ovs_flow_used_time(unsigned long flow_jiffies); 190u64 ovs_flow_used_time(unsigned long flow_jiffies);
189 191
190int ovs_flow_extract(struct sk_buff *, u16 in_port, struct sw_flow_key *); 192int ovs_flow_key_update(struct sk_buff *skb, struct sw_flow_key *key);
193int ovs_flow_key_extract(struct ovs_key_ipv4_tunnel *tun_key,
194 struct sk_buff *skb, struct sw_flow_key *key);
195/* Extract key from packet coming from userspace. */
196int ovs_flow_key_extract_userspace(const struct nlattr *attr,
197 struct sk_buff *skb,
198 struct sw_flow_key *key);
191 199
192#endif /* flow.h */ 200#endif /* flow.h */
diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c
index d757848da89c..f4c8daa73965 100644
--- a/net/openvswitch/flow_netlink.c
+++ b/net/openvswitch/flow_netlink.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2007-2013 Nicira, Inc. 2 * Copyright (c) 2007-2014 Nicira, Inc.
3 * 3 *
4 * This program is free software; you can redistribute it and/or 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 5 * modify it under the terms of version 2 of the GNU General Public
@@ -251,6 +251,8 @@ static const int ovs_key_lens[OVS_KEY_ATTR_MAX + 1] = {
251 [OVS_KEY_ATTR_ICMPV6] = sizeof(struct ovs_key_icmpv6), 251 [OVS_KEY_ATTR_ICMPV6] = sizeof(struct ovs_key_icmpv6),
252 [OVS_KEY_ATTR_ARP] = sizeof(struct ovs_key_arp), 252 [OVS_KEY_ATTR_ARP] = sizeof(struct ovs_key_arp),
253 [OVS_KEY_ATTR_ND] = sizeof(struct ovs_key_nd), 253 [OVS_KEY_ATTR_ND] = sizeof(struct ovs_key_nd),
254 [OVS_KEY_ATTR_RECIRC_ID] = sizeof(u32),
255 [OVS_KEY_ATTR_DP_HASH] = sizeof(u32),
254 [OVS_KEY_ATTR_TUNNEL] = -1, 256 [OVS_KEY_ATTR_TUNNEL] = -1,
255}; 257};
256 258
@@ -454,6 +456,20 @@ static int ipv4_tun_to_nlattr(struct sk_buff *skb,
454static int metadata_from_nlattrs(struct sw_flow_match *match, u64 *attrs, 456static int metadata_from_nlattrs(struct sw_flow_match *match, u64 *attrs,
455 const struct nlattr **a, bool is_mask) 457 const struct nlattr **a, bool is_mask)
456{ 458{
459 if (*attrs & (1 << OVS_KEY_ATTR_DP_HASH)) {
460 u32 hash_val = nla_get_u32(a[OVS_KEY_ATTR_DP_HASH]);
461
462 SW_FLOW_KEY_PUT(match, ovs_flow_hash, hash_val, is_mask);
463 *attrs &= ~(1 << OVS_KEY_ATTR_DP_HASH);
464 }
465
466 if (*attrs & (1 << OVS_KEY_ATTR_RECIRC_ID)) {
467 u32 recirc_id = nla_get_u32(a[OVS_KEY_ATTR_RECIRC_ID]);
468
469 SW_FLOW_KEY_PUT(match, recirc_id, recirc_id, is_mask);
470 *attrs &= ~(1 << OVS_KEY_ATTR_RECIRC_ID);
471 }
472
457 if (*attrs & (1 << OVS_KEY_ATTR_PRIORITY)) { 473 if (*attrs & (1 << OVS_KEY_ATTR_PRIORITY)) {
458 SW_FLOW_KEY_PUT(match, phy.priority, 474 SW_FLOW_KEY_PUT(match, phy.priority,
459 nla_get_u32(a[OVS_KEY_ATTR_PRIORITY]), is_mask); 475 nla_get_u32(a[OVS_KEY_ATTR_PRIORITY]), is_mask);
@@ -836,7 +852,7 @@ int ovs_nla_get_match(struct sw_flow_match *match,
836 852
837/** 853/**
838 * ovs_nla_get_flow_metadata - parses Netlink attributes into a flow key. 854 * ovs_nla_get_flow_metadata - parses Netlink attributes into a flow key.
839 * @flow: Receives extracted in_port, priority, tun_key and skb_mark. 855 * @key: Receives extracted in_port, priority, tun_key and skb_mark.
840 * @attr: Netlink attribute holding nested %OVS_KEY_ATTR_* Netlink attribute 856 * @attr: Netlink attribute holding nested %OVS_KEY_ATTR_* Netlink attribute
841 * sequence. 857 * sequence.
842 * 858 *
@@ -846,32 +862,24 @@ int ovs_nla_get_match(struct sw_flow_match *match,
846 * extracted from the packet itself. 862 * extracted from the packet itself.
847 */ 863 */
848 864
849int ovs_nla_get_flow_metadata(struct sw_flow *flow, 865int ovs_nla_get_flow_metadata(const struct nlattr *attr,
850 const struct nlattr *attr) 866 struct sw_flow_key *key)
851{ 867{
852 struct ovs_key_ipv4_tunnel *tun_key = &flow->key.tun_key;
853 const struct nlattr *a[OVS_KEY_ATTR_MAX + 1]; 868 const struct nlattr *a[OVS_KEY_ATTR_MAX + 1];
869 struct sw_flow_match match;
854 u64 attrs = 0; 870 u64 attrs = 0;
855 int err; 871 int err;
856 struct sw_flow_match match;
857
858 flow->key.phy.in_port = DP_MAX_PORTS;
859 flow->key.phy.priority = 0;
860 flow->key.phy.skb_mark = 0;
861 memset(tun_key, 0, sizeof(flow->key.tun_key));
862 872
863 err = parse_flow_nlattrs(attr, a, &attrs); 873 err = parse_flow_nlattrs(attr, a, &attrs);
864 if (err) 874 if (err)
865 return -EINVAL; 875 return -EINVAL;
866 876
867 memset(&match, 0, sizeof(match)); 877 memset(&match, 0, sizeof(match));
868 match.key = &flow->key; 878 match.key = key;
869 879
870 err = metadata_from_nlattrs(&match, &attrs, a, false); 880 key->phy.in_port = DP_MAX_PORTS;
871 if (err)
872 return err;
873 881
874 return 0; 882 return metadata_from_nlattrs(&match, &attrs, a, false);
875} 883}
876 884
877int ovs_nla_put_flow(const struct sw_flow_key *swkey, 885int ovs_nla_put_flow(const struct sw_flow_key *swkey,
@@ -881,6 +889,12 @@ int ovs_nla_put_flow(const struct sw_flow_key *swkey,
881 struct nlattr *nla, *encap; 889 struct nlattr *nla, *encap;
882 bool is_mask = (swkey != output); 890 bool is_mask = (swkey != output);
883 891
892 if (nla_put_u32(skb, OVS_KEY_ATTR_RECIRC_ID, output->recirc_id))
893 goto nla_put_failure;
894
895 if (nla_put_u32(skb, OVS_KEY_ATTR_DP_HASH, output->ovs_flow_hash))
896 goto nla_put_failure;
897
884 if (nla_put_u32(skb, OVS_KEY_ATTR_PRIORITY, output->phy.priority)) 898 if (nla_put_u32(skb, OVS_KEY_ATTR_PRIORITY, output->phy.priority))
885 goto nla_put_failure; 899 goto nla_put_failure;
886 900
@@ -1409,11 +1423,13 @@ int ovs_nla_copy_actions(const struct nlattr *attr,
1409 /* Expected argument lengths, (u32)-1 for variable length. */ 1423 /* Expected argument lengths, (u32)-1 for variable length. */
1410 static const u32 action_lens[OVS_ACTION_ATTR_MAX + 1] = { 1424 static const u32 action_lens[OVS_ACTION_ATTR_MAX + 1] = {
1411 [OVS_ACTION_ATTR_OUTPUT] = sizeof(u32), 1425 [OVS_ACTION_ATTR_OUTPUT] = sizeof(u32),
1426 [OVS_ACTION_ATTR_RECIRC] = sizeof(u32),
1412 [OVS_ACTION_ATTR_USERSPACE] = (u32)-1, 1427 [OVS_ACTION_ATTR_USERSPACE] = (u32)-1,
1413 [OVS_ACTION_ATTR_PUSH_VLAN] = sizeof(struct ovs_action_push_vlan), 1428 [OVS_ACTION_ATTR_PUSH_VLAN] = sizeof(struct ovs_action_push_vlan),
1414 [OVS_ACTION_ATTR_POP_VLAN] = 0, 1429 [OVS_ACTION_ATTR_POP_VLAN] = 0,
1415 [OVS_ACTION_ATTR_SET] = (u32)-1, 1430 [OVS_ACTION_ATTR_SET] = (u32)-1,
1416 [OVS_ACTION_ATTR_SAMPLE] = (u32)-1 1431 [OVS_ACTION_ATTR_SAMPLE] = (u32)-1,
1432 [OVS_ACTION_ATTR_HASH] = sizeof(struct ovs_action_hash)
1417 }; 1433 };
1418 const struct ovs_action_push_vlan *vlan; 1434 const struct ovs_action_push_vlan *vlan;
1419 int type = nla_type(a); 1435 int type = nla_type(a);
@@ -1440,6 +1456,18 @@ int ovs_nla_copy_actions(const struct nlattr *attr,
1440 return -EINVAL; 1456 return -EINVAL;
1441 break; 1457 break;
1442 1458
1459 case OVS_ACTION_ATTR_HASH: {
1460 const struct ovs_action_hash *act_hash = nla_data(a);
1461
1462 switch (act_hash->hash_alg) {
1463 case OVS_HASH_ALG_L4:
1464 break;
1465 default:
1466 return -EINVAL;
1467 }
1468
1469 break;
1470 }
1443 1471
1444 case OVS_ACTION_ATTR_POP_VLAN: 1472 case OVS_ACTION_ATTR_POP_VLAN:
1445 break; 1473 break;
@@ -1452,6 +1480,9 @@ int ovs_nla_copy_actions(const struct nlattr *attr,
1452 return -EINVAL; 1480 return -EINVAL;
1453 break; 1481 break;
1454 1482
1483 case OVS_ACTION_ATTR_RECIRC:
1484 break;
1485
1455 case OVS_ACTION_ATTR_SET: 1486 case OVS_ACTION_ATTR_SET:
1456 err = validate_set(a, key, sfa, &skip_copy); 1487 err = validate_set(a, key, sfa, &skip_copy);
1457 if (err) 1488 if (err)
diff --git a/net/openvswitch/flow_netlink.h b/net/openvswitch/flow_netlink.h
index 440151045d39..206e45add888 100644
--- a/net/openvswitch/flow_netlink.h
+++ b/net/openvswitch/flow_netlink.h
@@ -42,8 +42,8 @@ void ovs_match_init(struct sw_flow_match *match,
42 42
43int ovs_nla_put_flow(const struct sw_flow_key *, 43int ovs_nla_put_flow(const struct sw_flow_key *,
44 const struct sw_flow_key *, struct sk_buff *); 44 const struct sw_flow_key *, struct sk_buff *);
45int ovs_nla_get_flow_metadata(struct sw_flow *flow, 45int ovs_nla_get_flow_metadata(const struct nlattr *, struct sw_flow_key *);
46 const struct nlattr *attr); 46
47int ovs_nla_get_match(struct sw_flow_match *match, 47int ovs_nla_get_match(struct sw_flow_match *match,
48 const struct nlattr *, 48 const struct nlattr *,
49 const struct nlattr *); 49 const struct nlattr *);
diff --git a/net/openvswitch/vport-gre.c b/net/openvswitch/vport-gre.c
index f49148a07da2..309cca6e816f 100644
--- a/net/openvswitch/vport-gre.c
+++ b/net/openvswitch/vport-gre.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2007-2013 Nicira, Inc. 2 * Copyright (c) 2007-2014 Nicira, Inc.
3 * 3 *
4 * This program is free software; you can redistribute it and/or 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 5 * modify it under the terms of version 2 of the GNU General Public
@@ -63,7 +63,7 @@ static __be16 filter_tnl_flags(__be16 flags)
63static struct sk_buff *__build_header(struct sk_buff *skb, 63static struct sk_buff *__build_header(struct sk_buff *skb,
64 int tunnel_hlen) 64 int tunnel_hlen)
65{ 65{
66 const struct ovs_key_ipv4_tunnel *tun_key = OVS_CB(skb)->tun_key; 66 const struct ovs_key_ipv4_tunnel *tun_key = OVS_CB(skb)->egress_tun_key;
67 struct tnl_ptk_info tpi; 67 struct tnl_ptk_info tpi;
68 68
69 skb = gre_handle_offloads(skb, !!(tun_key->tun_flags & TUNNEL_CSUM)); 69 skb = gre_handle_offloads(skb, !!(tun_key->tun_flags & TUNNEL_CSUM));
@@ -129,6 +129,7 @@ static int gre_err(struct sk_buff *skb, u32 info,
129static int gre_tnl_send(struct vport *vport, struct sk_buff *skb) 129static int gre_tnl_send(struct vport *vport, struct sk_buff *skb)
130{ 130{
131 struct net *net = ovs_dp_get_net(vport->dp); 131 struct net *net = ovs_dp_get_net(vport->dp);
132 struct ovs_key_ipv4_tunnel *tun_key;
132 struct flowi4 fl; 133 struct flowi4 fl;
133 struct rtable *rt; 134 struct rtable *rt;
134 int min_headroom; 135 int min_headroom;
@@ -136,16 +137,17 @@ static int gre_tnl_send(struct vport *vport, struct sk_buff *skb)
136 __be16 df; 137 __be16 df;
137 int err; 138 int err;
138 139
139 if (unlikely(!OVS_CB(skb)->tun_key)) { 140 if (unlikely(!OVS_CB(skb)->egress_tun_key)) {
140 err = -EINVAL; 141 err = -EINVAL;
141 goto error; 142 goto error;
142 } 143 }
143 144
145 tun_key = OVS_CB(skb)->egress_tun_key;
144 /* Route lookup */ 146 /* Route lookup */
145 memset(&fl, 0, sizeof(fl)); 147 memset(&fl, 0, sizeof(fl));
146 fl.daddr = OVS_CB(skb)->tun_key->ipv4_dst; 148 fl.daddr = tun_key->ipv4_dst;
147 fl.saddr = OVS_CB(skb)->tun_key->ipv4_src; 149 fl.saddr = tun_key->ipv4_src;
148 fl.flowi4_tos = RT_TOS(OVS_CB(skb)->tun_key->ipv4_tos); 150 fl.flowi4_tos = RT_TOS(tun_key->ipv4_tos);
149 fl.flowi4_mark = skb->mark; 151 fl.flowi4_mark = skb->mark;
150 fl.flowi4_proto = IPPROTO_GRE; 152 fl.flowi4_proto = IPPROTO_GRE;
151 153
@@ -153,7 +155,7 @@ static int gre_tnl_send(struct vport *vport, struct sk_buff *skb)
153 if (IS_ERR(rt)) 155 if (IS_ERR(rt))
154 return PTR_ERR(rt); 156 return PTR_ERR(rt);
155 157
156 tunnel_hlen = ip_gre_calc_hlen(OVS_CB(skb)->tun_key->tun_flags); 158 tunnel_hlen = ip_gre_calc_hlen(tun_key->tun_flags);
157 159
158 min_headroom = LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len 160 min_headroom = LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len
159 + tunnel_hlen + sizeof(struct iphdr) 161 + tunnel_hlen + sizeof(struct iphdr)
@@ -185,15 +187,14 @@ static int gre_tnl_send(struct vport *vport, struct sk_buff *skb)
185 goto err_free_rt; 187 goto err_free_rt;
186 } 188 }
187 189
188 df = OVS_CB(skb)->tun_key->tun_flags & TUNNEL_DONT_FRAGMENT ? 190 df = tun_key->tun_flags & TUNNEL_DONT_FRAGMENT ?
189 htons(IP_DF) : 0; 191 htons(IP_DF) : 0;
190 192
191 skb->ignore_df = 1; 193 skb->ignore_df = 1;
192 194
193 return iptunnel_xmit(skb->sk, rt, skb, fl.saddr, 195 return iptunnel_xmit(skb->sk, rt, skb, fl.saddr,
194 OVS_CB(skb)->tun_key->ipv4_dst, IPPROTO_GRE, 196 tun_key->ipv4_dst, IPPROTO_GRE,
195 OVS_CB(skb)->tun_key->ipv4_tos, 197 tun_key->ipv4_tos, tun_key->ipv4_ttl, df, false);
196 OVS_CB(skb)->tun_key->ipv4_ttl, df, false);
197err_free_rt: 198err_free_rt:
198 ip_rt_put(rt); 199 ip_rt_put(rt);
199error: 200error:
diff --git a/net/openvswitch/vport-vxlan.c b/net/openvswitch/vport-vxlan.c
index d8b7e247bebf..f19539bb8adc 100644
--- a/net/openvswitch/vport-vxlan.c
+++ b/net/openvswitch/vport-vxlan.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2013 Nicira, Inc. 2 * Copyright (c) 2014 Nicira, Inc.
3 * Copyright (c) 2013 Cisco Systems, Inc. 3 * Copyright (c) 2013 Cisco Systems, Inc.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -140,22 +140,24 @@ static int vxlan_tnl_send(struct vport *vport, struct sk_buff *skb)
140 struct net *net = ovs_dp_get_net(vport->dp); 140 struct net *net = ovs_dp_get_net(vport->dp);
141 struct vxlan_port *vxlan_port = vxlan_vport(vport); 141 struct vxlan_port *vxlan_port = vxlan_vport(vport);
142 __be16 dst_port = inet_sk(vxlan_port->vs->sock->sk)->inet_sport; 142 __be16 dst_port = inet_sk(vxlan_port->vs->sock->sk)->inet_sport;
143 struct ovs_key_ipv4_tunnel *tun_key;
143 struct rtable *rt; 144 struct rtable *rt;
144 struct flowi4 fl; 145 struct flowi4 fl;
145 __be16 src_port; 146 __be16 src_port;
146 __be16 df; 147 __be16 df;
147 int err; 148 int err;
148 149
149 if (unlikely(!OVS_CB(skb)->tun_key)) { 150 if (unlikely(!OVS_CB(skb)->egress_tun_key)) {
150 err = -EINVAL; 151 err = -EINVAL;
151 goto error; 152 goto error;
152 } 153 }
153 154
155 tun_key = OVS_CB(skb)->egress_tun_key;
154 /* Route lookup */ 156 /* Route lookup */
155 memset(&fl, 0, sizeof(fl)); 157 memset(&fl, 0, sizeof(fl));
156 fl.daddr = OVS_CB(skb)->tun_key->ipv4_dst; 158 fl.daddr = tun_key->ipv4_dst;
157 fl.saddr = OVS_CB(skb)->tun_key->ipv4_src; 159 fl.saddr = tun_key->ipv4_src;
158 fl.flowi4_tos = RT_TOS(OVS_CB(skb)->tun_key->ipv4_tos); 160 fl.flowi4_tos = RT_TOS(tun_key->ipv4_tos);
159 fl.flowi4_mark = skb->mark; 161 fl.flowi4_mark = skb->mark;
160 fl.flowi4_proto = IPPROTO_UDP; 162 fl.flowi4_proto = IPPROTO_UDP;
161 163
@@ -165,7 +167,7 @@ static int vxlan_tnl_send(struct vport *vport, struct sk_buff *skb)
165 goto error; 167 goto error;
166 } 168 }
167 169
168 df = OVS_CB(skb)->tun_key->tun_flags & TUNNEL_DONT_FRAGMENT ? 170 df = tun_key->tun_flags & TUNNEL_DONT_FRAGMENT ?
169 htons(IP_DF) : 0; 171 htons(IP_DF) : 0;
170 172
171 skb->ignore_df = 1; 173 skb->ignore_df = 1;
@@ -173,11 +175,10 @@ static int vxlan_tnl_send(struct vport *vport, struct sk_buff *skb)
173 src_port = udp_flow_src_port(net, skb, 0, 0, true); 175 src_port = udp_flow_src_port(net, skb, 0, 0, true);
174 176
175 err = vxlan_xmit_skb(vxlan_port->vs, rt, skb, 177 err = vxlan_xmit_skb(vxlan_port->vs, rt, skb,
176 fl.saddr, OVS_CB(skb)->tun_key->ipv4_dst, 178 fl.saddr, tun_key->ipv4_dst,
177 OVS_CB(skb)->tun_key->ipv4_tos, 179 tun_key->ipv4_tos, tun_key->ipv4_ttl, df,
178 OVS_CB(skb)->tun_key->ipv4_ttl, df,
179 src_port, dst_port, 180 src_port, dst_port,
180 htonl(be64_to_cpu(OVS_CB(skb)->tun_key->tun_id) << 8), 181 htonl(be64_to_cpu(tun_key->tun_id) << 8),
181 false); 182 false);
182 if (err < 0) 183 if (err < 0)
183 ip_rt_put(rt); 184 ip_rt_put(rt);
diff --git a/net/openvswitch/vport.c b/net/openvswitch/vport.c
index f7e63f9df7b9..5df8377fcfb1 100644
--- a/net/openvswitch/vport.c
+++ b/net/openvswitch/vport.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2007-2012 Nicira, Inc. 2 * Copyright (c) 2007-2014 Nicira, Inc.
3 * 3 *
4 * This program is free software; you can redistribute it and/or 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 5 * modify it under the terms of version 2 of the GNU General Public
@@ -435,6 +435,8 @@ void ovs_vport_receive(struct vport *vport, struct sk_buff *skb,
435 struct ovs_key_ipv4_tunnel *tun_key) 435 struct ovs_key_ipv4_tunnel *tun_key)
436{ 436{
437 struct pcpu_sw_netstats *stats; 437 struct pcpu_sw_netstats *stats;
438 struct sw_flow_key key;
439 int error;
438 440
439 stats = this_cpu_ptr(vport->percpu_stats); 441 stats = this_cpu_ptr(vport->percpu_stats);
440 u64_stats_update_begin(&stats->syncp); 442 u64_stats_update_begin(&stats->syncp);
@@ -442,8 +444,15 @@ void ovs_vport_receive(struct vport *vport, struct sk_buff *skb,
442 stats->rx_bytes += skb->len; 444 stats->rx_bytes += skb->len;
443 u64_stats_update_end(&stats->syncp); 445 u64_stats_update_end(&stats->syncp);
444 446
445 OVS_CB(skb)->tun_key = tun_key; 447 OVS_CB(skb)->input_vport = vport;
446 ovs_dp_process_received_packet(vport, skb); 448 OVS_CB(skb)->egress_tun_key = NULL;
449 /* Extract flow from 'skb' into 'key'. */
450 error = ovs_flow_key_extract(tun_key, skb, &key);
451 if (unlikely(error)) {
452 kfree_skb(skb);
453 return;
454 }
455 ovs_dp_process_packet(skb, &key);
447} 456}
448 457
449/** 458/**