datapath: Check vswitch_skb_checksum_setup() return code.
[sliver-openvswitch.git] / datapath / actions.c
index 4020411..f7e51d9 100644 (file)
@@ -33,19 +33,7 @@ make_writable(struct sk_buff *skb, unsigned min_headroom, gfp_t gfp)
 
                nskb = skb_copy_expand(skb, headroom, skb_tailroom(skb), gfp);
                if (nskb) {
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
-                       /* Before 2.6.24 these fields were not copied when
-                        * doing an skb_copy_expand. */
-                       nskb->ip_summed = skb->ip_summed;
-                       nskb->csum = skb->csum;
-#endif
-#if defined(CONFIG_XEN) && defined(HAVE_PROTO_DATA_VALID)
-                       /* These fields are copied in skb_clone but not in
-                        * skb_copy or related functions.  We need to manually
-                        * copy them over here. */
-                       nskb->proto_data_valid = skb->proto_data_valid;
-                       nskb->proto_csum_blank = skb->proto_csum_blank;
-#endif
+                       set_skb_csum_bits(skb, nskb);
                        kfree_skb(skb);
                        return nskb;
                }
@@ -125,6 +113,8 @@ modify_vlan_tci(struct datapath *dp, struct sk_buff *skb,
                                                ~skb->csum);
                }
        } else {
+               int err;
+
                /* Add vlan header */
 
                /* Set up checksumming pointers for checksum-deferred packets
@@ -132,7 +122,11 @@ modify_vlan_tci(struct datapath *dp, struct sk_buff *skb,
                 * when we send the packet out on the wire, and it will fail at
                 * that point because skb_checksum_setup() will not look inside
                 * an 802.1Q header. */
-               vswitch_skb_checksum_setup(skb);
+               err = vswitch_skb_checksum_setup(skb);
+               if (unlikely(err)) {
+                       kfree_skb(skb);
+                       return ERR_PTR(err);
+               }       
 
                /* GSO is not implemented for packets with an 802.1Q header, so
                 * we have to do segmentation before we add that header.
@@ -456,6 +450,7 @@ int execute_actions(struct datapath *dp, struct sk_buff *skb,
         * then freeing the original skbuff is wasteful.  So the following code
         * is slightly obscure just to avoid that. */
        int prev_port = -1;
+       u32 priority = skb->priority;
        int err;
 
        if (dp->sflow_probability) {
@@ -528,6 +523,14 @@ int execute_actions(struct datapath *dp, struct sk_buff *skb,
                case ODPAT_SET_TP_DST:
                        skb = set_tp_port(skb, key, &a->tp_port, gfp);
                        break;
+
+               case ODPAT_SET_PRIORITY:
+                       skb->priority = a->priority.priority;
+                       break;
+
+               case ODPAT_POP_PRIORITY:
+                       skb->priority = priority;
+                       break;
                }
                if (!skb)
                        return -ENOMEM;