use error checking mutexs in pltap&tunnel
[sliver-openvswitch.git] / lib / ofp-util.c
index d1bcf9c..62cfd2e 100644 (file)
@@ -420,6 +420,7 @@ ofputil_match_from_ofp11_match(const struct ofp11_match *ofmatch,
 
         case IPPROTO_TCP:
         case IPPROTO_UDP:
+        case IPPROTO_SCTP:
             if (!(wc & (OFPFW11_TP_SRC))) {
                 match_set_tp_src(match, ofmatch->tp_src);
             }
@@ -428,11 +429,6 @@ ofputil_match_from_ofp11_match(const struct ofp11_match *ofmatch,
             }
             break;
 
-        case IPPROTO_SCTP:
-            /* We don't support SCTP and it seems that we should tell the
-             * controller, since OF1.1 implementations are supposed to. */
-            return OFPERR_OFPBMC_BAD_FIELD;
-
         default:
             /* OF1.1 says explicitly to ignore this. */
             break;
@@ -1134,11 +1130,17 @@ ofputil_usable_protocols(const struct match *match)
         return OFPUTIL_P_NONE;
     }
 
-    /* skb_mark and skb_priority can't be sent in a flow_mod */
-    if (wc->masks.skb_mark || wc->masks.skb_priority) {
+    /* skb_priority can't be sent in a flow_mod */
+    if (wc->masks.skb_priority) {
         return OFPUTIL_P_NONE;
     }
 
+    /* NXM and OXM support pkt_mark */
+    if (wc->masks.pkt_mark) {
+        return OFPUTIL_P_OF10_NXM_ANY | OFPUTIL_P_OF12_OXM
+            | OFPUTIL_P_OF13_OXM;
+    }
+
     /* NXM, OXM, and OF1.1 support bitwise matching on ethernet addresses. */
     if (!eth_mask_is_exact(wc->masks.dl_src)
         && !eth_addr_is_zero(wc->masks.dl_src)) {
@@ -2917,6 +2919,7 @@ ofputil_decode_packet_in_finish(struct ofputil_packet_in *pin,
     pin->fmd.tun_dst = match->flow.tunnel.ip_dst;
     pin->fmd.metadata = match->flow.metadata;
     memcpy(pin->fmd.regs, match->flow.regs, sizeof pin->fmd.regs);
+    pin->fmd.pkt_mark = match->flow.pkt_mark;
 }
 
 enum ofperr
@@ -3031,6 +3034,10 @@ ofputil_packet_in_to_match(const struct ofputil_packet_in *pin,
         }
     }
 
+    if (pin->fmd.pkt_mark != 0) {
+        match_set_pkt_mark(match, pin->fmd.pkt_mark);
+    }
+
     match_set_in_port(match, pin->fmd.in_port);
 }
 
@@ -4824,13 +4831,15 @@ ofputil_normalize_match__(struct match *match, bool may_log)
         may_match = MAY_NW_PROTO | MAY_IPVx | MAY_NW_ADDR;
         if (match->flow.nw_proto == IPPROTO_TCP ||
             match->flow.nw_proto == IPPROTO_UDP ||
+            match->flow.nw_proto == IPPROTO_SCTP ||
             match->flow.nw_proto == IPPROTO_ICMP) {
             may_match |= MAY_TP_ADDR;
         }
     } else if (match->flow.dl_type == htons(ETH_TYPE_IPV6)) {
         may_match = MAY_NW_PROTO | MAY_IPVx | MAY_IPV6;
         if (match->flow.nw_proto == IPPROTO_TCP ||
-            match->flow.nw_proto == IPPROTO_UDP) {
+            match->flow.nw_proto == IPPROTO_UDP ||
+            match->flow.nw_proto == IPPROTO_SCTP) {
             may_match |= MAY_TP_ADDR;
         } else if (match->flow.nw_proto == IPPROTO_ICMPV6) {
             may_match |= MAY_TP_ADDR;