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.c50
1 files changed, 39 insertions, 11 deletions
diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c
index e70d8b18e962..fe5cda0deb39 100644
--- a/net/openvswitch/actions.c
+++ b/net/openvswitch/actions.c
@@ -38,7 +38,7 @@
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{
@@ -434,11 +434,17 @@ static int output_userspace(struct datapath *dp, struct sk_buff *skb,
434 return ovs_dp_upcall(dp, skb, &upcall); 434 return ovs_dp_upcall(dp, skb, &upcall);
435} 435}
436 436
437static bool last_action(const struct nlattr *a, int rem)
438{
439 return a->nla_len == rem;
440}
441
437static int sample(struct datapath *dp, struct sk_buff *skb, 442static int sample(struct datapath *dp, struct sk_buff *skb,
438 const struct nlattr *attr) 443 const struct nlattr *attr)
439{ 444{
440 const struct nlattr *acts_list = NULL; 445 const struct nlattr *acts_list = NULL;
441 const struct nlattr *a; 446 const struct nlattr *a;
447 struct sk_buff *sample_skb;
442 int rem; 448 int rem;
443 449
444 for (a = nla_data(attr), rem = nla_len(attr); rem > 0; 450 for (a = nla_data(attr), rem = nla_len(attr); rem > 0;
@@ -455,8 +461,34 @@ static int sample(struct datapath *dp, struct sk_buff *skb,
455 } 461 }
456 } 462 }
457 463
458 return do_execute_actions(dp, skb, nla_data(acts_list), 464 rem = nla_len(acts_list);
459 nla_len(acts_list), true); 465 a = nla_data(acts_list);
466
467 /* Actions list is either empty or only contains a single user-space
468 * action, the latter being a special case as it is the only known
469 * usage of the sample action.
470 * In these special cases don't clone the skb as there are no
471 * side-effects in the nested actions.
472 * Otherwise, clone in case the nested actions have side effects.
473 */
474 if (likely(rem == 0 || (nla_type(a) == OVS_ACTION_ATTR_USERSPACE &&
475 last_action(a, rem)))) {
476 sample_skb = skb;
477 skb_get(skb);
478 } else {
479 sample_skb = skb_clone(skb, GFP_ATOMIC);
480 if (!sample_skb) /* Skip sample action when out of memory. */
481 return 0;
482 }
483
484 /* Note that do_execute_actions() never consumes skb.
485 * In the case where skb has been cloned above it is the clone that
486 * is consumed. Otherwise the skb_get(skb) call prevents
487 * consumption by do_execute_actions(). Thus, it is safe to simply
488 * return the error code and let the caller (also
489 * do_execute_actions()) free skb on error.
490 */
491 return do_execute_actions(dp, sample_skb, a, rem);
460} 492}
461 493
462static int execute_set_action(struct sk_buff *skb, 494static int execute_set_action(struct sk_buff *skb,
@@ -507,7 +539,7 @@ static int execute_set_action(struct sk_buff *skb,
507 539
508/* Execute a list of actions against 'skb'. */ 540/* Execute a list of actions against 'skb'. */
509static int do_execute_actions(struct datapath *dp, struct sk_buff *skb, 541static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
510 const struct nlattr *attr, int len, bool keep_skb) 542 const struct nlattr *attr, int len)
511{ 543{
512 /* Every output action needs a separate clone of 'skb', but the common 544 /* 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 545 * case is just a single output action, so that doing a clone and
@@ -562,12 +594,9 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
562 } 594 }
563 } 595 }
564 596
565 if (prev_port != -1) { 597 if (prev_port != -1)
566 if (keep_skb)
567 skb = skb_clone(skb, GFP_ATOMIC);
568
569 do_output(dp, skb, prev_port); 598 do_output(dp, skb, prev_port);
570 } else if (!keep_skb) 599 else
571 consume_skb(skb); 600 consume_skb(skb);
572 601
573 return 0; 602 return 0;
@@ -579,6 +608,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); 608 struct sw_flow_actions *acts = rcu_dereference(OVS_CB(skb)->flow->sf_acts);
580 609
581 OVS_CB(skb)->tun_key = NULL; 610 OVS_CB(skb)->tun_key = NULL;
582 return do_execute_actions(dp, skb, acts->actions, 611 return do_execute_actions(dp, skb, acts->actions, acts->actions_len);
583 acts->actions_len, false);
584} 612}