[ovs-dev] [PATCH] datapath: Update flow key before recirc

Andy Zhou azhou at nicira.com
Mon Aug 11 21:22:30 UTC 2014


When flow key becomes invalid due to push or pop actions, current
implementation leaves it as invalid, only rebuild the flow key used
for recirculation.

This works, but is less efficient in case of multiple recirc
actions. Each recirc action will have to re-extract
its own flow keys.

This patch update the original flow key as soon as the first recirc
action is encountered, avoiding expensive flow extract call for any
future recirc actions as long as the flow key remains valid.

Signed-off-by: Andy Zhou <azhou at nicira.com>
---
 datapath/actions.c | 16 +++++++---------
 datapath/flow.c    |  5 +++++
 datapath/flow.h    |  2 ++
 3 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/datapath/actions.c b/datapath/actions.c
index 25c5d77..ae1978d 100644
--- a/datapath/actions.c
+++ b/datapath/actions.c
@@ -806,20 +806,18 @@ static int execute_recirc(struct datapath *dp, struct sk_buff *skb,
 	}
 
 	if (is_skb_flow_key_valid(skb)) {
-		if (!last_action(a, rem))
-			flow_key_clone_recirc(skb, nla_get_u32(a), &recirc_key);
-		else
-			flow_key_set_recirc_id(skb, nla_get_u32(a));
-	} else {
-		struct sw_flow_key *pkt_key = OVS_CB(skb)->pkt_key;
-
-		err = ovs_flow_key_extract_recirc(nla_get_u32(a), pkt_key,
-						  skb, &recirc_key);
+		err = ovs_flow_key_update(skb, OVS_CB(skb)->pkt_key);
 		if (err) {
 			kfree_skb(skb);
 			return err;
 		}
 	}
+	BUG_ON(!is_skb_flow_key_valid(skb));
+
+	if (last_action(a, rem))
+		flow_key_set_recirc_id(skb, nla_get_u32(a));
+	else
+		flow_key_clone_recirc(skb, nla_get_u32(a), &recirc_key);
 
 	ovs_dp_process_packet(skb, true);
 	return 0;
diff --git a/datapath/flow.c b/datapath/flow.c
index d56812a..ae64813 100644
--- a/datapath/flow.c
+++ b/datapath/flow.c
@@ -673,6 +673,11 @@ static int key_extract(struct sk_buff *skb, struct sw_flow_key *key)
 	return 0;
 }
 
+int ovs_flow_key_update(struct sk_buff *skb, struct sw_flow_key *key)
+{
+	return key_extract(skb, key);
+}
+
 int ovs_flow_key_extract(const struct ovs_tunnel_info *tun_info,
 			 struct sk_buff *skb,
 			 struct sw_flow_key *key)
diff --git a/datapath/flow.h b/datapath/flow.h
index 106feb8..bc38eba 100644
--- a/datapath/flow.h
+++ b/datapath/flow.h
@@ -232,5 +232,7 @@ int ovs_flow_key_extract_recirc(u32 recirc_id,
 				const struct sw_flow_key *key,
 				struct sk_buff *skb,
 				struct sw_flow_key *new_key);
+/* Update the non-metadata part of the flow key using skb. */
+int ovs_flow_key_update(struct sk_buff *skb, struct sw_flow_key *key);
 
 #endif /* flow.h */
-- 
1.9.1




More information about the dev mailing list