classifier: Rewrite.
[openvswitch] / lib / ofp-util.c
index 89f368950569d8142459a8edebc8ad7b464a0be9..933eaf430c7b45efb30c0c4419f254859a13f129 100644 (file)
 #include "ofp-print.h"
 #include <inttypes.h>
 #include <stdlib.h>
+#include "byte-order.h"
 #include "ofp-util.h"
 #include "ofpbuf.h"
 #include "packets.h"
 #include "random.h"
 #include "vlog.h"
-#include "xtoxll.h"
 
-VLOG_DEFINE_THIS_MODULE(ofp_util)
+VLOG_DEFINE_THIS_MODULE(ofp_util);
 
 /* Rate limit for OpenFlow message parse errors.  These always indicate a bug
  * in the peer and so there's not much point in showing a lot of them. */
@@ -132,7 +132,7 @@ update_openflow_length(struct ofpbuf *buffer)
 }
 
 struct ofpbuf *
-make_flow_mod(uint16_t command, const flow_t *flow, size_t actions_len)
+make_flow_mod(uint16_t command, const struct flow *flow, size_t actions_len)
 {
     struct ofp_flow_mod *ofm;
     size_t size = sizeof *ofm + actions_len;
@@ -161,7 +161,7 @@ make_flow_mod(uint16_t command, const flow_t *flow, size_t actions_len)
 }
 
 struct ofpbuf *
-make_add_flow(const flow_t *flow, uint32_t buffer_id,
+make_add_flow(const struct flow *flow, uint32_t buffer_id,
               uint16_t idle_timeout, size_t actions_len)
 {
     struct ofpbuf *out = make_flow_mod(OFPFC_ADD, flow, actions_len);
@@ -173,7 +173,7 @@ make_add_flow(const flow_t *flow, uint32_t buffer_id,
 }
 
 struct ofpbuf *
-make_del_flow(const flow_t *flow)
+make_del_flow(const struct flow *flow)
 {
     struct ofpbuf *out = make_flow_mod(OFPFC_DELETE_STRICT, flow, 0);
     struct ofp_flow_mod *ofm = out->data;
@@ -182,7 +182,7 @@ make_del_flow(const flow_t *flow)
 }
 
 struct ofpbuf *
-make_add_simple_flow(const flow_t *flow,
+make_add_simple_flow(const struct flow *flow,
                      uint32_t buffer_id, uint16_t out_port,
                      uint16_t idle_timeout)
 {
@@ -564,6 +564,9 @@ check_nicira_action(const union ofp_action *a, unsigned int len)
     switch (ntohs(nah->subtype)) {
     case NXAST_RESUBMIT:
     case NXAST_SET_TUNNEL:
+    case NXAST_DROP_SPOOFED_ARP:
+    case NXAST_SET_QUEUE:
+    case NXAST_POP_QUEUE:
         return check_action_exact_len(a, len, 16);
     default:
         return ofp_mkerr(OFPET_BAD_ACTION, OFPBAC_BAD_VENDOR_TYPE);
@@ -584,7 +587,25 @@ check_action(const union ofp_action *a, unsigned int len, int max_ports)
         return check_output_port(ntohs(a->output.port), max_ports);
 
     case OFPAT_SET_VLAN_VID:
+        error = check_action_exact_len(a, len, 8);
+        if (error) {
+            return error;
+        }
+        if (a->vlan_vid.vlan_vid & ~htons(0xfff)) {
+            return ofp_mkerr(OFPET_BAD_ACTION, OFPBAC_BAD_ARGUMENT);
+        }
+        return 0;
+
     case OFPAT_SET_VLAN_PCP:
+        error = check_action_exact_len(a, len, 8);
+        if (error) {
+            return error;
+        }
+        if (a->vlan_vid.vlan_vid & ~7) {
+            return ofp_mkerr(OFPET_BAD_ACTION, OFPBAC_BAD_ARGUMENT);
+        }
+        return 0;
+
     case OFPAT_STRIP_VLAN:
     case OFPAT_SET_NW_SRC:
     case OFPAT_SET_NW_DST:
@@ -616,9 +637,10 @@ int
 validate_actions(const union ofp_action *actions, size_t n_actions,
                  int max_ports)
 {
-    const union ofp_action *a;
+    size_t i;
 
-    for (a = actions; a < &actions[n_actions]; ) {
+    for (i = 0; i < n_actions; ) {
+        const union ofp_action *a = &actions[i];
         unsigned int len = ntohs(a->header.len);
         unsigned int n_slots = len / ACTION_ALIGNMENT;
         unsigned int slots_left = &actions[n_actions] - a;
@@ -642,7 +664,7 @@ validate_actions(const union ofp_action *actions, size_t n_actions,
         if (error) {
             return error;
         }
-        a += n_slots;
+        i += n_slots;
     }
     return 0;
 }
@@ -676,7 +698,7 @@ actions_first(struct actions_iterator *iter,
 const union ofp_action *
 actions_next(struct actions_iterator *iter)
 {
-    if (iter->pos < iter->end) {
+    if (iter->pos != iter->end) {
         const union ofp_action *a = iter->pos;
         unsigned int len = ntohs(a->header.len);
         iter->pos += len / ACTION_ALIGNMENT;
@@ -689,7 +711,8 @@ actions_next(struct actions_iterator *iter)
 void
 normalize_match(struct ofp_match *m)
 {
-    enum { OFPFW_NW = OFPFW_NW_SRC_MASK | OFPFW_NW_DST_MASK | OFPFW_NW_PROTO };
+    enum { OFPFW_NW = (OFPFW_NW_SRC_MASK | OFPFW_NW_DST_MASK | OFPFW_NW_PROTO
+                       | OFPFW_NW_TOS) };
     enum { OFPFW_TP = OFPFW_TP_SRC | OFPFW_TP_DST };
     uint32_t wc;