aboutsummaryrefslogtreecommitdiffstats
path: root/net/openvswitch/actions.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/openvswitch/actions.c')
-rw-r--r--net/openvswitch/actions.c55
1 files changed, 44 insertions, 11 deletions
diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c
index e70d8b18e962..5231652a95d9 100644
--- a/net/openvswitch/actions.c
+++ b/net/openvswitch/actions.c
@@ -38,10 +38,13 @@
38#include "vport.h" 38#include "vport.h"
39 39
40static int do_execute_actions(struct datapath *dp, struct sk_buff *skb, 40static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
41 const struct nlattr *attr, int len, bool keep_skb); 41 const struct nlattr *attr, int len);
42 42
43static int make_writable(struct sk_buff *skb, int write_len) 43static int make_writable(struct sk_buff *skb, int write_len)
44{ 44{
45 if (!pskb_may_pull(skb, write_len))
46 return -ENOMEM;
47
45 if (!skb_cloned(skb) || skb_clone_writable(skb, write_len)) 48 if (!skb_cloned(skb) || skb_clone_writable(skb, write_len))
46 return 0; 49 return 0;
47 50
@@ -70,6 +73,8 @@ static int __pop_vlan_tci(struct sk_buff *skb, __be16 *current_tci)
70 73
71 vlan_set_encap_proto(skb, vhdr); 74 vlan_set_encap_proto(skb, vhdr);
72 skb->mac_header += VLAN_HLEN; 75 skb->mac_header += VLAN_HLEN;
76 if (skb_network_offset(skb) < ETH_HLEN)
77 skb_set_network_header(skb, ETH_HLEN);
73 skb_reset_mac_len(skb); 78 skb_reset_mac_len(skb);
74 79
75 return 0; 80 return 0;
@@ -434,11 +439,17 @@ static int output_userspace(struct datapath *dp, struct sk_buff *skb,
434 return ovs_dp_upcall(dp, skb, &upcall); 439 return ovs_dp_upcall(dp, skb, &upcall);
435} 440}
436 441
442static bool last_action(const struct nlattr *a, int rem)
443{
444 return a->nla_len == rem;
445}
446
437static int sample(struct datapath *dp, struct sk_buff *skb, 447static int sample(struct datapath *dp, struct sk_buff *skb,
438 const struct nlattr *attr) 448 const struct nlattr *attr)
439{ 449{
440 const struct nlattr *acts_list = NULL; 450 const struct nlattr *acts_list = NULL;
441 const struct nlattr *a; 451 const struct nlattr *a;
452 struct sk_buff *sample_skb;
442 int rem; 453 int rem;
443 454
444 for (a = nla_data(attr), rem = nla_len(attr); rem > 0; 455 for (a = nla_data(attr), rem = nla_len(attr); rem > 0;
@@ -455,8 +466,34 @@ static int sample(struct datapath *dp, struct sk_buff *skb,
455 } 466 }
456 } 467 }
457 468
458 return do_execute_actions(dp, skb, nla_data(acts_list), 469 rem = nla_len(acts_list);
459 nla_len(acts_list), true); 470 a = nla_data(acts_list);
471
472 /* Actions list is either empty or only contains a single user-space
473 * action, the latter being a special case as it is the only known
474 * usage of the sample action.
475 * In these special cases don't clone the skb as there are no
476 * side-effects in the nested actions.
477 * Otherwise, clone in case the nested actions have side effects.
478 */
479 if (likely(rem == 0 || (nla_type(a) == OVS_ACTION_ATTR_USERSPACE &&
480 last_action(a, rem)))) {
481 sample_skb = skb;
482 skb_get(skb);
483 } else {
484 sample_skb = skb_clone(skb, GFP_ATOMIC);
485 if (!sample_skb) /* Skip sample action when out of memory. */
486 return 0;
487 }
488
489 /* Note that do_execute_actions() never consumes skb.
490 * In the case where skb has been cloned above it is the clone that
491 * is consumed. Otherwise the skb_get(skb) call prevents
492 * consumption by do_execute_actions(). Thus, it is safe to simply
493 * return the error code and let the caller (also
494 * do_execute_actions()) free skb on error.
495 */
496 return do_execute_actions(dp, sample_skb, a, rem);
460} 497}
461 498
462static int execute_set_action(struct sk_buff *skb, 499static int execute_set_action(struct sk_buff *skb,
@@ -507,7 +544,7 @@ static int execute_set_action(struct sk_buff *skb,
507 544
508/* Execute a list of actions against 'skb'. */ 545/* Execute a list of actions against 'skb'. */
509static int do_execute_actions(struct datapath *dp, struct sk_buff *skb, 546static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
510 const struct nlattr *attr, int len, bool keep_skb) 547 const struct nlattr *attr, int len)
511{ 548{
512 /* Every output action needs a separate clone of 'skb', but the common 549 /* Every output action needs a separate clone of 'skb', but the common
513 * case is just a single output action, so that doing a clone and 550 * case is just a single output action, so that doing a clone and
@@ -562,12 +599,9 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
562 } 599 }
563 } 600 }
564 601
565 if (prev_port != -1) { 602 if (prev_port != -1)
566 if (keep_skb)
567 skb = skb_clone(skb, GFP_ATOMIC);
568
569 do_output(dp, skb, prev_port); 603 do_output(dp, skb, prev_port);
570 } else if (!keep_skb) 604 else
571 consume_skb(skb); 605 consume_skb(skb);
572 606
573 return 0; 607 return 0;
@@ -579,6 +613,5 @@ int ovs_execute_actions(struct datapath *dp, struct sk_buff *skb)
579 struct sw_flow_actions *acts = rcu_dereference(OVS_CB(skb)->flow->sf_acts); 613 struct sw_flow_actions *acts = rcu_dereference(OVS_CB(skb)->flow->sf_acts);
580 614
581 OVS_CB(skb)->tun_key = NULL; 615 OVS_CB(skb)->tun_key = NULL;
582 return do_execute_actions(dp, skb, acts->actions, 616 return do_execute_actions(dp, skb, acts->actions, acts->actions_len);
583 acts->actions_len, false);
584} 617}