datapath: refactor ovs flow extract API.
[cascardo/ovs.git] / datapath / actions.c
index caf432e..5a0bfa9 100644 (file)
@@ -486,21 +486,14 @@ static int set_sctp(struct sk_buff *skb,
        return 0;
 }
 
-static int do_output(struct datapath *dp, struct sk_buff *skb, int out_port)
+static void do_output(struct datapath *dp, struct sk_buff *skb, int out_port)
 {
-       struct vport *vport;
+       struct vport *vport = ovs_vport_rcu(dp, out_port);
 
-       if (unlikely(!skb))
-               return -ENOMEM;
-
-       vport = ovs_vport_rcu(dp, out_port);
-       if (unlikely(!vport)) {
+       if (likely(vport))
+               ovs_vport_send(vport, skb);
+       else
                kfree_skb(skb);
-               return -ENODEV;
-       }
-
-       ovs_vport_send(vport, skb);
-       return 0;
 }
 
 static int output_userspace(struct datapath *dp, struct sk_buff *skb,
@@ -510,10 +503,7 @@ static int output_userspace(struct datapath *dp, struct sk_buff *skb,
        const struct nlattr *a;
        int rem;
 
-       BUG_ON(!OVS_CB(skb)->pkt_key);
-
        upcall.cmd = OVS_PACKET_CMD_ACTION;
-       upcall.key = OVS_CB(skb)->pkt_key;
        upcall.userdata = NULL;
        upcall.portid = 0;
 
@@ -576,6 +566,9 @@ static int sample(struct datapath *dp, struct sk_buff *skb,
                skb_get(skb);
        } else {
                sample_skb = skb_clone(skb, GFP_ATOMIC);
+               if (!sample_skb)
+                       /* Skip the sample action when out of memory. */
+                       return 0;
        }
 
        /* Note that do_execute_actions() never consumes skb.
@@ -656,11 +649,10 @@ static int execute_recirc(struct datapath *dp, struct sk_buff *skb,
                                 const struct nlattr *a)
 {
        struct sw_flow_key recirc_key;
-       const struct vport *p = OVS_CB(skb)->input_vport;
        uint32_t hash = OVS_CB(skb)->pkt_key->ovs_flow_hash;
        int err;
 
-       err = ovs_flow_extract(skb, p->port_no, &recirc_key);
+       err = ovs_flow_key_extract(skb, &recirc_key);
        if (err) {
                kfree_skb(skb);
                return err;
@@ -690,8 +682,12 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
             a = nla_next(a, &rem)) {
                int err = 0;
 
-               if (prev_port != -1) {
-                       do_output(dp, skb_clone(skb, GFP_ATOMIC), prev_port);
+               if (unlikely(prev_port != -1)) {
+                       struct sk_buff *out_skb = skb_clone(skb, GFP_ATOMIC);
+
+                       if (out_skb)
+                               do_output(dp, out_skb, prev_port);
+
                        prev_port = -1;
                }