use error checking mutexs in pltap&tunnel
[sliver-openvswitch.git] / lib / packets.c
index 9c30b95..253184f 100644 (file)
@@ -23,6 +23,7 @@
 #include <stdlib.h>
 #include "byte-order.h"
 #include "csum.h"
+#include "crc32c.h"
 #include "flow.h"
 #include "hmap.h"
 #include "dynamic-string.h"
@@ -250,7 +251,8 @@ set_ethertype(struct ofpbuf *packet, ovs_be16 eth_type)
 
     if (eh->eth_type == htons(ETH_TYPE_VLAN)) {
         ovs_be16 *p;
-        p = (ovs_be16 *)((char *)(packet->l2_5 ? packet->l2_5 : packet->l3) - 2);
+        p = ALIGNED_CAST(ovs_be16 *,
+                (char *)(packet->l2_5 ? packet->l2_5 : packet->l3) - 2);
         *p = eth_type;
     } else {
         eh->eth_type = eth_type;
@@ -670,7 +672,7 @@ packet_rh_present(struct ofpbuf *packet)
     if (remaining < sizeof *nh) {
         return false;
     }
-    nh = (struct ip6_hdr *)data;
+    nh = ALIGNED_CAST(struct ip6_hdr *, data);
     data += sizeof *nh;
     remaining -= sizeof *nh;
     nexthdr = nh->ip6_nxt;
@@ -706,7 +708,8 @@ packet_rh_present(struct ofpbuf *packet)
             nexthdr = ext_hdr->ip6e_nxt;
             len = (ext_hdr->ip6e_len + 2) * 4;
         } else if (nexthdr == IPPROTO_FRAGMENT) {
-            const struct ip6_frag *frag_hdr = (struct ip6_frag *)data;
+            const struct ip6_frag *frag_hdr = ALIGNED_CAST(struct ip6_frag *,
+                                                           data);
 
             nexthdr = frag_hdr->ip6f_nxt;
             len = sizeof *frag_hdr;
@@ -883,6 +886,27 @@ packet_set_udp_port(struct ofpbuf *packet, ovs_be16 src, ovs_be16 dst)
     }
 }
 
+/* Sets the SCTP source and destination port ('src' and 'dst' respectively) of
+ * the SCTP header contained in 'packet'.  'packet' must be a valid SCTP packet
+ * with its l4 marker properly populated. */
+void
+packet_set_sctp_port(struct ofpbuf *packet, ovs_be16 src, ovs_be16 dst)
+{
+    struct sctp_header *sh = packet->l4;
+    ovs_be32 old_csum, old_correct_csum, new_csum;
+    uint16_t tp_len = packet->size - ((uint8_t*)sh - (uint8_t*)packet->data);
+
+    old_csum = sh->sctp_csum;
+    sh->sctp_csum = 0;
+    old_correct_csum = crc32c(packet->l4, tp_len);
+
+    sh->sctp_src = src;
+    sh->sctp_dst = dst;
+
+    new_csum = crc32c(packet->l4, tp_len);
+    sh->sctp_csum = old_csum ^ old_correct_csum ^ new_csum;
+}
+
 /* If 'packet' is a TCP packet, returns the TCP flags.  Otherwise, returns 0.
  *
  * 'flow' must be the flow corresponding to 'packet' and 'packet''s header