ofp-actions: Give ovs_instruction funcs names that start with that prefix.
[sliver-openvswitch.git] / lib / ofp-actions.c
index 5339811..b934be1 100644 (file)
@@ -914,13 +914,13 @@ OVS_INSTRUCTIONS
 };
 
 const char *
-ofpact_instruction_name_from_type(enum ovs_instruction_type type)
+ovs_instruction_name_from_type(enum ovs_instruction_type type)
 {
     return inst_info[type].name;
 }
 
 int
-ofpact_instruction_type_from_name(const char *name)
+ovs_instruction_type_from_name(const char *name)
 {
     const struct instruction_type_info *p;
     for (p = inst_info; p < &inst_info[ARRAY_SIZE(inst_info)]; p++) {
@@ -1003,9 +1003,7 @@ decode_openflow11_instructions(const struct ofp11_instruction insts[],
         }
 
         if (out[type]) {
-            return OFPERR_OFPBAC_UNSUPPORTED_ORDER; /* No specific code for
-                                                     * a duplicate instruction
-                                                     * exist */
+            return OFPERR_ONFBIC_DUP_INSTRUCTION;
         }
         out[type] = inst;
     }
@@ -1087,6 +1085,16 @@ ofpacts_pull_openflow11_instructions(struct ofpbuf *openflow,
         goto exit;
     }
 
+    if (insts[OVSINST_OFPIT13_METER]) {
+        const struct ofp13_instruction_meter *oim;
+        struct ofpact_meter *om;
+
+        oim = (const struct ofp13_instruction_meter *)
+            insts[OVSINST_OFPIT13_METER];
+
+        om = ofpact_put_METER(ofpacts);
+        om->meter_id = ntohl(oim->meter_id);
+    }
     if (insts[OVSINST_OFPIT11_APPLY_ACTIONS]) {
         const union ofp_action *actions;
         size_t n_actions;
@@ -1229,6 +1237,7 @@ ofpact_check__(const struct ofpact *a, struct flow *flow, ofp_port_t max_ports)
 
     case OFPACT_CLEAR_ACTIONS:
     case OFPACT_WRITE_METADATA:
+    case OFPACT_METER:
     case OFPACT_GOTO_TABLE:
         return 0;
 
@@ -1272,7 +1281,9 @@ ofpacts_verify(const struct ofpact ofpacts[], size_t ofpacts_len)
     OFPACT_FOR_EACH (a, ofpacts, ofpacts_len) {
         enum ovs_instruction_type next;
 
-        if (a->type == OFPACT_CLEAR_ACTIONS) {
+        if (a->type == OFPACT_METER) {
+            next = OVSINST_OFPIT13_METER;
+        } else if (a->type == OFPACT_CLEAR_ACTIONS) {
             next = OVSINST_OFPIT11_CLEAR_ACTIONS;
         } else if (a->type == OFPACT_WRITE_METADATA) {
             next = OVSINST_OFPIT11_WRITE_METADATA;
@@ -1283,8 +1294,8 @@ ofpacts_verify(const struct ofpact ofpacts[], size_t ofpacts_len)
         }
 
         if (inst != OVSINST_OFPIT11_APPLY_ACTIONS && next <= inst) {
-            const char *name = ofpact_instruction_name_from_type(inst);
-            const char *next_name = ofpact_instruction_name_from_type(next);
+            const char *name = ovs_instruction_name_from_type(inst);
+            const char *next_name = ovs_instruction_name_from_type(next);
 
             if (next == inst) {
                 VLOG_WARN("duplicate %s instruction not allowed, for OpenFlow "
@@ -1552,6 +1563,7 @@ ofpact_to_nxast(const struct ofpact *a, struct ofpbuf *out)
     case OFPACT_SET_L4_DST_PORT:
     case OFPACT_CLEAR_ACTIONS:
     case OFPACT_GOTO_TABLE:
+    case OFPACT_METER:
         NOT_REACHED();
     }
 }
@@ -1644,6 +1656,7 @@ ofpact_to_openflow10(const struct ofpact *a, struct ofpbuf *out)
     case OFPACT_PUSH_VLAN:
     case OFPACT_CLEAR_ACTIONS:
     case OFPACT_GOTO_TABLE:
+    case OFPACT_METER:
         /* XXX */
         break;
 
@@ -1816,6 +1829,7 @@ ofpact_to_openflow11(const struct ofpact *a, struct ofpbuf *out)
 
     case OFPACT_CLEAR_ACTIONS:
     case OFPACT_GOTO_TABLE:
+    case OFPACT_METER:
         NOT_REACHED();
 
     case OFPACT_CONTROLLER:
@@ -1896,6 +1910,13 @@ ofpacts_put_openflow11_instructions(const struct ofpact ofpacts[],
             oiwm = instruction_put_OFPIT11_WRITE_METADATA(openflow);
             oiwm->metadata = om->metadata;
             oiwm->metadata_mask = om->mask;
+        } else if (a->type == OFPACT_METER) {
+            const struct ofpact_meter *om;
+            struct ofp13_instruction_meter *oim;
+
+            om = ofpact_get_METER(a);
+            oim = instruction_put_OFPIT13_METER(openflow);
+            oim->meter_id = htonl(om->meter_id);
         } else if (!ofpact_is_instruction(a)) {
             /* Apply-actions */
             const size_t ofs = openflow->size;
@@ -1965,6 +1986,7 @@ ofpact_outputs_to_port(const struct ofpact *ofpact, ofp_port_t port)
     case OFPACT_SAMPLE:
     case OFPACT_CLEAR_ACTIONS:
     case OFPACT_GOTO_TABLE:
+    case OFPACT_METER:
     default:
         return false;
     }
@@ -2270,14 +2292,14 @@ ofpact_format(const struct ofpact *a, struct ds *s)
 
     case OFPACT_CLEAR_ACTIONS:
         ds_put_format(s, "%s",
-                      ofpact_instruction_name_from_type(
+                      ovs_instruction_name_from_type(
                           OVSINST_OFPIT11_CLEAR_ACTIONS));
         break;
 
     case OFPACT_WRITE_METADATA:
         metadata = ofpact_get_WRITE_METADATA(a);
         ds_put_format(s, "%s:%#"PRIx64,
-                      ofpact_instruction_name_from_type(
+                      ovs_instruction_name_from_type(
                           OVSINST_OFPIT11_WRITE_METADATA),
                       ntohll(metadata->metadata));
         if (metadata->mask != htonll(UINT64_MAX)) {
@@ -2287,10 +2309,16 @@ ofpact_format(const struct ofpact *a, struct ds *s)
 
     case OFPACT_GOTO_TABLE:
         ds_put_format(s, "%s:%"PRIu8,
-                      ofpact_instruction_name_from_type(
+                      ovs_instruction_name_from_type(
                           OVSINST_OFPIT11_GOTO_TABLE),
                       ofpact_get_GOTO_TABLE(a)->table_id);
         break;
+
+    case OFPACT_METER:
+        ds_put_format(s, "%s:%"PRIu32,
+                      ovs_instruction_name_from_type(OVSINST_OFPIT13_METER),
+                      ofpact_get_METER(a)->meter_id);
+        break;
     }
 }