datapath: Use min() instead of open-coding it.
[openvswitch] / datapath / actions.c
index 51fb3105a5f96bc816da2d98a7a23d8d02a77c93..a6771b6c58c4d97c49725dde8dd2a82244259fad 100644 (file)
@@ -26,7 +26,7 @@
 
 static struct sk_buff *make_writable(struct sk_buff *skb, unsigned min_headroom, gfp_t gfp)
 {
-       if (skb_shared(skb) || skb_cloned(skb)) {
+       if (skb_cloned(skb)) {
                struct sk_buff *nskb;
                unsigned headroom = max(min_headroom, skb_headroom(skb));
 
@@ -46,12 +46,6 @@ static struct sk_buff *make_writable(struct sk_buff *skb, unsigned min_headroom,
        return NULL;
 }
 
-static void set_tunnel(struct sk_buff *skb, struct odp_flow_key *key,
-                      __be32 tun_id)
-{
-       OVS_CB(skb)->tun_id = key->tun_id = tun_id;
-}
-
 static struct sk_buff *vlan_pull_tag(struct sk_buff *skb)
 {
        struct vlan_ethhdr *vh = vlan_eth_hdr(skb);
@@ -75,21 +69,19 @@ static struct sk_buff *vlan_pull_tag(struct sk_buff *skb)
        return skb;
 }
 
-
 static struct sk_buff *modify_vlan_tci(struct datapath *dp, struct sk_buff *skb,
-                                      struct odp_flow_key *key, const union odp_action *a,
-                                      int n_actions, gfp_t gfp)
+                                      const struct odp_flow_key *key,
+                                      const union odp_action *a, int n_actions,
+                                      gfp_t gfp)
 {
        u16 tci, mask;
 
        if (a->type == ODPAT_SET_VLAN_VID) {
                tci = ntohs(a->vlan_vid.vlan_vid);
                mask = VLAN_VID_MASK;
-               key->dl_vlan = a->vlan_vid.vlan_vid;
        } else {
                tci = a->vlan_pcp.vlan_pcp << VLAN_PCP_SHIFT;
                mask = VLAN_PCP_MASK;
-               key->dl_vlan_pcp = a->vlan_pcp.vlan_pcp;
        }
 
        skb = make_writable(skb, VLAN_HLEN, gfp);
@@ -160,9 +152,8 @@ static struct sk_buff *modify_vlan_tci(struct datapath *dp, struct sk_buff *skb,
                                segs = __vlan_put_tag(segs, tci);
                                err = -ENOMEM;
                                if (segs) {
-                                       struct odp_flow_key segkey = *key;
                                        err = execute_actions(dp, segs,
-                                                             &segkey, a + 1,
+                                                             key, a + 1,
                                                              n_actions - 1,
                                                              gfp);
                                }
@@ -202,32 +193,26 @@ static struct sk_buff *modify_vlan_tci(struct datapath *dp, struct sk_buff *skb,
        return skb;
 }
 
-static struct sk_buff *strip_vlan(struct sk_buff *skb,
-                                 struct odp_flow_key *key, gfp_t gfp)
+static struct sk_buff *strip_vlan(struct sk_buff *skb, gfp_t gfp)
 {
        skb = make_writable(skb, 0, gfp);
-       if (skb) {
+       if (skb)
                vlan_pull_tag(skb);
-               key->dl_vlan = htons(ODP_VLAN_NONE);
-       }
+
        return skb;
 }
 
 static struct sk_buff *set_dl_addr(struct sk_buff *skb,
-                                  struct odp_flow_key *key,
                                   const struct odp_action_dl_addr *a,
                                   gfp_t gfp)
 {
        skb = make_writable(skb, 0, gfp);
        if (skb) {
                struct ethhdr *eh = eth_hdr(skb);
-               if (a->type == ODPAT_SET_DL_SRC) {
+               if (a->type == ODPAT_SET_DL_SRC)
                        memcpy(eh->h_source, a->dl_addr, ETH_ALEN);
-                       memcpy(key->dl_src, a->dl_addr, ETH_ALEN);
-               } else {
+               else
                        memcpy(eh->h_dest, a->dl_addr, ETH_ALEN);
-                       memcpy(key->dl_dst, a->dl_addr, ETH_ALEN);
-               }
        }
        return skb;
 }
@@ -253,7 +238,7 @@ static void update_csum(__sum16 *sum, struct sk_buff *skb,
 }
 
 static struct sk_buff *set_nw_addr(struct sk_buff *skb,
-                                  struct odp_flow_key *key,
+                                  const struct odp_flow_key *key,
                                   const struct odp_action_nw_addr *a,
                                   gfp_t gfp)
 {
@@ -276,17 +261,12 @@ static struct sk_buff *set_nw_addr(struct sk_buff *skb,
                }
                update_csum(&nh->check, skb, old, new, 0);
                *f = new;
-
-               if (a->type == ODPAT_SET_NW_SRC)
-                       key->nw_src = a->nw_addr;
-               else
-                       key->nw_dst = a->nw_addr;
        }
        return skb;
 }
 
 static struct sk_buff *set_nw_tos(struct sk_buff *skb,
-                                  struct odp_flow_key *key,
+                                  const struct odp_flow_key *key,
                                   const struct odp_action_nw_tos *a,
                                   gfp_t gfp)
 {
@@ -305,12 +285,12 @@ static struct sk_buff *set_nw_tos(struct sk_buff *skb,
                update_csum(&nh->check, skb, htons((uint16_t)old),
                                htons((uint16_t)new), 0);
                *f = new;
-               key->nw_tos = a->nw_tos;
        }
        return skb;
 }
 
-static struct sk_buff *set_tp_port(struct sk_buff *skb, struct odp_flow_key *key,
+static struct sk_buff *set_tp_port(struct sk_buff *skb,
+                                  const struct odp_flow_key *key,
                                   const struct odp_action_tp_port *a, gfp_t gfp)
 {
        int check_ofs;
@@ -334,10 +314,6 @@ static struct sk_buff *set_tp_port(struct sk_buff *skb, struct odp_flow_key *key
                update_csum((u16*)(skb_transport_header(skb) + check_ofs), 
                                skb, old, new, 0);
                *f = new;
-               if (a->type == ODPAT_SET_TP_SRC)
-                       key->tp_src = a->tp_port;
-               else
-                       key->tp_dst = a->tp_port;
        }
        return skb;
 }
@@ -419,7 +395,7 @@ static void sflow_sample(struct datapath *dp, struct sk_buff *skb,
 
 /* Execute a list of actions against 'skb'. */
 int execute_actions(struct datapath *dp, struct sk_buff *skb,
-                   struct odp_flow_key *key,
+                   const struct odp_flow_key *key,
                    const union odp_action *a, int n_actions,
                    gfp_t gfp)
 {
@@ -444,7 +420,6 @@ int execute_actions(struct datapath *dp, struct sk_buff *skb,
        OVS_CB(skb)->tun_id = 0;
 
        for (; n_actions > 0; a++, n_actions--) {
-               WARN_ON_ONCE(skb_shared(skb));
                if (prev_port != -1) {
                        do_output(dp, skb_clone(skb, gfp), prev_port);
                        prev_port = -1;
@@ -469,7 +444,7 @@ int execute_actions(struct datapath *dp, struct sk_buff *skb,
                        break;
 
                case ODPAT_SET_TUNNEL:
-                       set_tunnel(skb, key, a->tunnel.tun_id);
+                       OVS_CB(skb)->tun_id = a->tunnel.tun_id;
                        break;
 
                case ODPAT_SET_VLAN_VID:
@@ -480,12 +455,12 @@ int execute_actions(struct datapath *dp, struct sk_buff *skb,
                        break;
 
                case ODPAT_STRIP_VLAN:
-                       skb = strip_vlan(skb, key, gfp);
+                       skb = strip_vlan(skb, gfp);
                        break;
 
                case ODPAT_SET_DL_SRC:
                case ODPAT_SET_DL_DST:
-                       skb = set_dl_addr(skb, key, &a->dl_addr, gfp);
+                       skb = set_dl_addr(skb, &a->dl_addr, gfp);
                        break;
 
                case ODPAT_SET_NW_SRC: