Signed-off-by: Jarno Rajahalme <jrajaha...@nicira.com>
---
 datapath/datapath.c |   60 +++++++++++++++++++++++++++------------------------
 1 file changed, 32 insertions(+), 28 deletions(-)

diff --git a/datapath/datapath.c b/datapath/datapath.c
index a46ceb0..90fdc60 100644
--- a/datapath/datapath.c
+++ b/datapath/datapath.c
@@ -492,14 +492,24 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, 
struct genl_info *info)
 {
        struct ovs_header *ovs_header = info->userhdr;
        struct nlattr **a = info->attrs;
-       struct sw_flow_actions *acts;
        struct sk_buff *packet;
-       struct sw_flow *flow;
        struct datapath *dp;
        struct ethhdr *eth;
+       struct sw_flow flow;
+       struct {
+               struct sw_flow_actions acts;
+               u64 buf[512 / sizeof (u64)];
+       } sw_acts;
+       struct sw_flow_actions *acts;
        int len;
        int err;
 
+       /* Start with actions in the stack with enough space for most cases. */
+       acts = &sw_acts.acts;
+       acts->actions_len = 0;
+       acts->alloc_size = sizeof(sw_acts);
+       acts->alloced = false;
+
        err = -EINVAL;
        if (!a[OVS_PACKET_ATTR_PACKET] || !a[OVS_PACKET_ATTR_KEY] ||
            !a[OVS_PACKET_ATTR_ACTIONS])
@@ -525,54 +535,48 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, 
struct genl_info *info)
        else
                packet->protocol = htons(ETH_P_802_2);
 
-       /* Build an sw_flow for sending this packet. */
-       flow = ovs_flow_alloc();
-       err = PTR_ERR(flow);
-       if (IS_ERR(flow))
-               goto err_kfree_skb;
-
-       err = ovs_flow_extract(packet, -1, &flow->key);
+       /* Build an sw_flow for sending this packet.
+        * We do not initialize mask, nor stats as they are not used
+        * by a flow that is not in the flow table. */
+       err = ovs_flow_extract(packet, -1, &flow.key);
        if (err)
-               goto err_flow_free;
+               goto err_free;
 
-       err = ovs_nla_get_flow_metadata(flow, a[OVS_PACKET_ATTR_KEY]);
+       err = ovs_nla_get_flow_metadata(&flow, a[OVS_PACKET_ATTR_KEY]);
        if (err)
-               goto err_flow_free;
-       acts = ovs_nla_alloc_flow_actions(nla_len(a[OVS_PACKET_ATTR_ACTIONS]));
-       err = PTR_ERR(acts);
-       if (IS_ERR(acts))
-               goto err_flow_free;
+               goto err_free;
 
        err = ovs_nla_copy_actions(a[OVS_PACKET_ATTR_ACTIONS],
-                                  &flow->key, 0, &acts);
-       rcu_assign_pointer(flow->sf_acts, acts);
+                                  &flow.key, 0, &acts);
+       rcu_assign_pointer(flow.sf_acts, acts);
        if (err)
-               goto err_flow_free;
+               goto err_free_acts;
 
-       OVS_CB(packet)->flow = flow;
-       OVS_CB(packet)->pkt_key = &flow->key;
-       packet->priority = flow->key.phy.priority;
-       packet->mark = flow->key.phy.skb_mark;
+       OVS_CB(packet)->flow = &flow;
+       OVS_CB(packet)->pkt_key = &flow.key;
+       packet->priority = flow.key.phy.priority;
+       packet->mark = flow.key.phy.skb_mark;
 
        rcu_read_lock();
        dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex);
        err = -ENODEV;
        if (!dp)
                goto err_unlock;
-
        local_bh_disable();
        err = ovs_execute_actions(dp, packet);
        local_bh_enable();
        rcu_read_unlock();
 
-       ovs_flow_free(flow, false);
+       /* Will free if actions were realloced. */
+       ovs_nla_free_flow_actions(acts, false);
+
        return err;
 
 err_unlock:
        rcu_read_unlock();
-err_flow_free:
-       ovs_flow_free(flow, false);
-err_kfree_skb:
+err_free_acts:
+       ovs_nla_free_flow_actions(acts, false);
+err_free:
        kfree_skb(packet);
 err:
        return err;
-- 
1.7.10.4

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to