Global replace of Nicira Networks.
[sliver-openvswitch.git] / lib / bundle.c
index 86762f9..a205974 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011 Nicira Networks.
+/* Copyright (c) 2011, 2012 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 
 #include "dynamic-string.h"
 #include "multipath.h"
+#include "meta-flow.h"
 #include "nx-match.h"
 #include "ofpbuf.h"
+#include "ofp-errors.h"
 #include "ofp-util.h"
 #include "openflow/nicira-ext.h"
 #include "vlog.h"
@@ -93,15 +95,18 @@ bundle_execute_load(const struct nx_action_bundle *nab, struct flow *flow,
                     bool (*slave_enabled)(uint16_t ofp_port, void *aux),
                     void *aux)
 {
-    nxm_reg_load(nab->dst, nab->ofs_nbits,
-                 bundle_execute(nab, flow, slave_enabled, aux), flow);
+    struct mf_subfield dst;
+
+    nxm_decode(&dst, nab->dst, nab->ofs_nbits);
+    mf_set_subfield_value(&dst, bundle_execute(nab, flow, slave_enabled, aux),
+                          flow);
 }
 
 /* Checks that 'nab' specifies a bundle action which is supported by this
  * bundle module.  Uses the 'max_ports' parameter to validate each port using
  * ofputil_check_output_port().  Returns 0 if 'nab' is supported, otherwise an
- * OpenFlow error code (as returned by ofp_mkerr()). */
-int
+ * OFPERR_* error code. */
+enum ofperr
 bundle_check(const struct nx_action_bundle *nab, int max_ports,
              const struct flow *flow)
 {
@@ -109,7 +114,7 @@ bundle_check(const struct nx_action_bundle *nab, int max_ports,
     uint16_t n_slaves, fields, algorithm, subtype;
     uint32_t slave_type;
     size_t slaves_size, i;
-    int error;
+    enum ofperr error;
 
     subtype = ntohs(nab->subtype);
     n_slaves = ntohs(nab->n_slaves);
@@ -118,7 +123,7 @@ bundle_check(const struct nx_action_bundle *nab, int max_ports,
     slave_type = ntohl(nab->slave_type);
     slaves_size = ntohs(nab->len) - sizeof *nab;
 
-    error = ofp_mkerr(OFPET_BAD_ACTION, OFPBAC_BAD_ARGUMENT);
+    error = OFPERR_OFPBAC_BAD_ARGUMENT;
     if (!flow_hash_fields_valid(fields)) {
         VLOG_WARN_RL(&rl, "unsupported fields %"PRIu16, fields);
     } else if (n_slaves > BUNDLE_MAX_SLAVES) {
@@ -135,25 +140,25 @@ bundle_check(const struct nx_action_bundle *nab, int max_ports,
     for (i = 0; i < sizeof(nab->zero); i++) {
         if (nab->zero[i]) {
             VLOG_WARN_RL(&rl, "reserved field is nonzero");
-            error = ofp_mkerr(OFPET_BAD_ACTION, OFPBAC_BAD_ARGUMENT);
+            error = OFPERR_OFPBAC_BAD_ARGUMENT;
         }
     }
 
     if (subtype == NXAST_BUNDLE && (nab->ofs_nbits || nab->dst)) {
         VLOG_WARN_RL(&rl, "bundle action has nonzero reserved fields");
-        error = ofp_mkerr(OFPET_BAD_ACTION, OFPBAC_BAD_ARGUMENT);
+        error = OFPERR_OFPBAC_BAD_ARGUMENT;
     }
 
     if (subtype == NXAST_BUNDLE_LOAD) {
-        int ofs = nxm_decode_ofs(nab->ofs_nbits);
-        int n_bits = nxm_decode_n_bits(nab->ofs_nbits);
+        struct mf_subfield dst;
 
-        if (n_bits < 16) {
+        nxm_decode(&dst, nab->dst, nab->ofs_nbits);
+        if (dst.n_bits < 16) {
             VLOG_WARN_RL(&rl, "bundle_load action requires at least 16 bit "
                          "destination.");
-            error = ofp_mkerr(OFPET_BAD_ACTION, OFPBAC_BAD_ARGUMENT);
-        } else {
-            error = nxm_dst_check(nab->dst, ofs, n_bits, flow) || error;
+            error = OFPERR_OFPBAC_BAD_ARGUMENT;
+        } else if (!error) {
+            error = mf_check_dst(&dst, flow);
         }
     }
 
@@ -162,13 +167,14 @@ bundle_check(const struct nx_action_bundle *nab, int max_ports,
                      "allocated for slaves.  %zu bytes are required for "
                      "%"PRIu16" slaves.", subtype, slaves_size,
                      n_slaves * sizeof(ovs_be16), n_slaves);
-        error = ofp_mkerr(OFPET_BAD_ACTION, OFPBAC_BAD_LEN);
+        error = OFPERR_OFPBAC_BAD_LEN;
     }
 
     for (i = 0; i < n_slaves; i++) {
         uint16_t ofp_port = bundle_get_slave(nab, i);
-        int ofputil_error = ofputil_check_output_port(ofp_port, max_ports);
+        enum ofperr ofputil_error;
 
+        ofputil_error = ofputil_check_output_port(ofp_port, max_ports);
         if (ofputil_error) {
             VLOG_WARN_RL(&rl, "invalid slave %"PRIu16, ofp_port);
             error = ofputil_error;
@@ -179,7 +185,7 @@ bundle_check(const struct nx_action_bundle *nab, int max_ports,
          * seem to be a real-world use-case for supporting it. */
         if (ofp_port == OFPP_CONTROLLER) {
             VLOG_WARN_RL(&rl, "unsupported controller slave");
-            error = ofp_mkerr(OFPET_BAD_ACTION, OFPBAC_BAD_OUT_PORT);
+            error = OFPERR_OFPBAC_BAD_OUT_PORT;
         }
     }
 
@@ -190,9 +196,10 @@ bundle_check(const struct nx_action_bundle *nab, int max_ports,
 static void
 bundle_parse__(struct ofpbuf *b, const char *s, char **save_ptr,
                const char *fields, const char *basis, const char *algorithm,
-               const char *slave_type, const char *dst,
+               const char *slave_type, const char *dst_s,
                const char *slave_delim)
 {
+    enum ofputil_action_code code;
     struct nx_action_bundle *nab;
     uint16_t n_slaves;
 
@@ -205,14 +212,15 @@ bundle_parse__(struct ofpbuf *b, const char *s, char **save_ptr,
                    s, slave_delim);
     }
 
-    b->l2 = ofpbuf_put_zeros(b, sizeof *nab);
+    code = dst_s ? OFPUTIL_NXAST_BUNDLE_LOAD : OFPUTIL_NXAST_BUNDLE;
+    b->l2 = ofputil_put_action(code, b);
 
     n_slaves = 0;
     for (;;) {
         ovs_be16 slave_be;
         char *slave;
 
-        slave = strtok_r(NULL, ", ", save_ptr);
+        slave = strtok_r(NULL, ", [", save_ptr);
         if (!slave || n_slaves >= BUNDLE_MAX_SLAVES) {
             break;
         }
@@ -229,10 +237,7 @@ bundle_parse__(struct ofpbuf *b, const char *s, char **save_ptr,
     }
 
     nab = b->l2;
-    nab->type = htons(OFPAT_VENDOR);
     nab->len = htons(b->size - ((char *) b->l2 - (char *) b->data));
-    nab->vendor = htonl(NX_VENDOR_ID);
-    nab->subtype = htons(dst ? NXAST_BUNDLE_LOAD: NXAST_BUNDLE);
     nab->n_slaves = htons(n_slaves);
     nab->basis = htons(atoi(basis));
 
@@ -258,14 +263,12 @@ bundle_parse__(struct ofpbuf *b, const char *s, char **save_ptr,
         ovs_fatal(0, "%s: unknown slave_type `%s'", s, slave_type);
     }
 
-    if (dst) {
-        uint32_t reg;
-        int ofs, n_bits;
-
-        nxm_parse_field_bits(dst, &reg, &ofs, &n_bits);
+    if (dst_s) {
+        struct mf_subfield dst;
 
-        nab->dst = htonl(reg);
-        nab->ofs_nbits = nxm_encode_ofs_nbits(ofs, n_bits);
+        mf_parse_subfield(&dst, dst_s);
+        nab->dst = htonl(dst.field->nxm_header);
+        nab->ofs_nbits = nxm_encode_ofs_nbits(dst.ofs, dst.n_bits);
     }
 
     b->l2 = NULL;
@@ -358,9 +361,10 @@ bundle_format(const struct nx_action_bundle *nab, struct ds *s)
                   ntohs(nab->basis), algorithm, slave_type);
 
     if (nab->subtype == htons(NXAST_BUNDLE_LOAD)) {
-        nxm_format_field_bits(s, ntohl(nab->dst),
-                              nxm_decode_ofs(nab->ofs_nbits),
-                              nxm_decode_n_bits(nab->ofs_nbits));
+        struct mf_subfield dst;
+
+        nxm_decode(&dst, nab->dst, nab->ofs_nbits);
+        mf_format_subfield(&dst, s);
         ds_put_cstr(s, ",");
     }