bridge: Make bridge_pick_local_hw_addr() easier to reason.
[openvswitch] / lib / ofp-util.c
index d9ebcda704358d1d68965be5fcfd42912c4b0e7e..a4b1f5fc61dcb8c3e761f13c28bd795eb14df23c 100644 (file)
@@ -108,6 +108,8 @@ static const flow_wildcards_t WC_INVARIANTS = 0
 void
 ofputil_wildcard_from_openflow(uint32_t ofpfw, struct flow_wildcards *wc)
 {
+    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 1);
+
     /* Initialize most of rule->wc. */
     flow_wildcards_init_catchall(wc);
     wc->wildcards = (OVS_FORCE flow_wildcards_t) ofpfw & WC_INVARIANTS;
@@ -800,6 +802,8 @@ ofputil_min_flow_format(const struct cls_rule *rule)
 {
     const struct flow_wildcards *wc = &rule->wc;
 
+    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 1);
+
     /* Only NXM supports separately wildcards the Ethernet multicast bit. */
     if (!(wc->wildcards & FWW_DL_DST) != !(wc->wildcards & FWW_ETH_MCAST)) {
         return NXFF_NXM;
@@ -866,8 +870,8 @@ ofputil_make_flow_mod_table_id(bool flow_mod_table_id)
  *
  * Does not validate the flow_mod actions. */
 int
-ofputil_decode_flow_mod(struct flow_mod *fm, const struct ofp_header *oh,
-                        bool flow_mod_table_id)
+ofputil_decode_flow_mod(struct ofputil_flow_mod *fm,
+                        const struct ofp_header *oh, bool flow_mod_table_id)
 {
     const struct ofputil_msg_type *type;
     uint16_t command;
@@ -956,7 +960,7 @@ ofputil_decode_flow_mod(struct flow_mod *fm, const struct ofp_header *oh,
  * 'flow_mod_table_id' should be true if the NXT_FLOW_MOD_TABLE_ID extension is
  * enabled, false otherwise. */
 struct ofpbuf *
-ofputil_encode_flow_mod(const struct flow_mod *fm,
+ofputil_encode_flow_mod(const struct ofputil_flow_mod *fm,
                         enum nx_flow_format flow_format,
                         bool flow_mod_table_id)
 {
@@ -1010,7 +1014,7 @@ ofputil_encode_flow_mod(const struct flow_mod *fm,
 }
 
 static int
-ofputil_decode_ofpst_flow_request(struct flow_stats_request *fsr,
+ofputil_decode_ofpst_flow_request(struct ofputil_flow_stats_request *fsr,
                                   const struct ofp_header *oh,
                                   bool aggregate)
 {
@@ -1026,7 +1030,7 @@ ofputil_decode_ofpst_flow_request(struct flow_stats_request *fsr,
 }
 
 static int
-ofputil_decode_nxst_flow_request(struct flow_stats_request *fsr,
+ofputil_decode_nxst_flow_request(struct ofputil_flow_stats_request *fsr,
                                  const struct ofp_header *oh,
                                  bool aggregate)
 {
@@ -1056,7 +1060,7 @@ ofputil_decode_nxst_flow_request(struct flow_stats_request *fsr,
  * request 'oh', into an abstract flow_stats_request in 'fsr'.  Returns 0 if
  * successful, otherwise an OpenFlow error code. */
 int
-ofputil_decode_flow_stats_request(struct flow_stats_request *fsr,
+ofputil_decode_flow_stats_request(struct ofputil_flow_stats_request *fsr,
                                   const struct ofp_header *oh)
 {
     const struct ofputil_msg_type *type;
@@ -1090,7 +1094,7 @@ ofputil_decode_flow_stats_request(struct flow_stats_request *fsr,
  * OFPST_AGGREGATE, NXST_FLOW, or NXST_AGGREGATE request 'oh' according to
  * 'flow_format', and returns the message. */
 struct ofpbuf *
-ofputil_encode_flow_stats_request(const struct flow_stats_request *fsr,
+ofputil_encode_flow_stats_request(const struct ofputil_flow_stats_request *fsr,
                                   enum nx_flow_format flow_format)
 {
     struct ofpbuf *msg;
@@ -1879,7 +1883,7 @@ make_packet_out(const struct ofpbuf *packet, uint32_t buffer_id,
     opo->header.length = htons(size);
     opo->header.xid = htonl(0);
     opo->buffer_id = htonl(buffer_id);
-    opo->in_port = htons(in_port == ODPP_LOCAL ? OFPP_LOCAL : in_port);
+    opo->in_port = htons(in_port == OVSP_LOCAL ? OFPP_LOCAL : in_port);
     opo->actions_len = htons(actions_len);
     ofpbuf_put(out, actions, actions_len);
     if (packet) {
@@ -1966,6 +1970,31 @@ ofputil_check_output_port(uint16_t port, int max_ports)
     }
 }
 
+static int
+check_resubmit_table(const struct nx_action_resubmit *nar)
+{
+    if (nar->pad[0] || nar->pad[1] || nar->pad[2]) {
+        return ofp_mkerr(OFPET_BAD_ACTION, OFPBAC_BAD_ARGUMENT);
+    }
+    return 0;
+}
+
+static int
+check_output_reg(const struct nx_action_output_reg *naor,
+                 const struct flow *flow)
+{
+    size_t i;
+
+    for (i = 0; i < sizeof naor->zero; i++) {
+        if (naor->zero[i]) {
+            return ofp_mkerr(OFPET_BAD_ACTION, OFPBAC_BAD_ARGUMENT);
+        }
+    }
+
+    return nxm_src_check(naor->src, nxm_decode_ofs(naor->ofs_nbits),
+                         nxm_decode_n_bits(naor->ofs_nbits), flow);
+}
+
 int
 validate_actions(const union ofp_action *actions, size_t n_actions,
                  const struct flow *flow, int max_ports)
@@ -2044,6 +2073,16 @@ validate_actions(const union ofp_action *actions, size_t n_actions,
                                  max_ports, flow);
             break;
 
+        case OFPUTIL_NXAST_OUTPUT_REG:
+            error = check_output_reg((const struct nx_action_output_reg *) a,
+                                     flow);
+            break;
+
+        case OFPUTIL_NXAST_RESUBMIT_TABLE:
+            error = check_resubmit_table(
+                (const struct nx_action_resubmit *) a);
+            break;
+
         case OFPUTIL_OFPAT_STRIP_VLAN:
         case OFPUTIL_OFPAT_SET_NW_SRC:
         case OFPUTIL_OFPAT_SET_NW_DST:
@@ -2151,6 +2190,8 @@ ofputil_decode_nxast_action(const union ofp_action *a)
         NXAST_ACTION(NXAST_AUTOPATH,     struct nx_action_autopath,     false);
         NXAST_ACTION(NXAST_BUNDLE,       struct nx_action_bundle,       true);
         NXAST_ACTION(NXAST_BUNDLE_LOAD,  struct nx_action_bundle,       true);
+        NXAST_ACTION(NXAST_RESUBMIT_TABLE, struct nx_action_resubmit,   false);
+        NXAST_ACTION(NXAST_OUTPUT_REG,   struct nx_action_output_reg,   false);
 #undef NXAST_ACTION
 
     case NXAST_SNAT__OBSOLETE: