Classifier: Staged subtable matching.
[sliver-openvswitch.git] / utilities / ovs-ofctl.c
index 630591c..f3b58dd 100644 (file)
@@ -310,6 +310,7 @@ usage(void)
            "  dump-group-features SWITCH  print group features\n"
            "  dump-groups SWITCH          print group description\n"
            "  dump-group-stats SWITCH [GROUP]  print group statistics\n"
+           "  queue-get-config SWITCH PORT  print queue information for port\n"
            "  add-meter SWITCH METER      add meter described by METER\n"
            "  mod-meter SWITCH METER      modify specific METER\n"
            "  del-meter SWITCH METER      delete METER\n"
@@ -889,7 +890,9 @@ prepare_dump_flows(int argc, char *argv[], bool aggregate,
 
     error = parse_ofp_flow_stats_request_str(&fsr, aggregate,
                                              argc > 2 ? argv[2] : "",
-                                             &usable_protocols);
+                                             &usable_protocols,
+                                             !(allowed_protocols
+                                               & OFPUTIL_P_OF10_ANY));
     if (error) {
         ovs_fatal(0, "%s", error);
     }
@@ -1046,6 +1049,26 @@ ofctl_queue_stats(int argc, char *argv[])
     vconn_close(vconn);
 }
 
+static void
+ofctl_queue_get_config(int argc OVS_UNUSED, char *argv[])
+{
+    const char *vconn_name = argv[1];
+    const char *port_name = argv[2];
+    enum ofputil_protocol protocol;
+    enum ofp_version version;
+    struct ofpbuf *request;
+    struct vconn *vconn;
+    ofp_port_t port;
+
+    port = str_to_port_no(vconn_name, port_name);
+
+    protocol = open_vconn(vconn_name, &vconn);
+    version = ofputil_protocol_to_ofp_version(protocol);
+    request = ofputil_encode_queue_get_config_request(version, port);
+    dump_transaction(vconn, request);
+    vconn_close(vconn);
+}
+
 static enum ofputil_protocol
 open_vconn_for_flow_mod(const char *remote, struct vconn **vconnp,
                         enum ofputil_protocol usable_protocols)
@@ -1111,7 +1134,8 @@ ofctl_flow_mod_file(int argc OVS_UNUSED, char *argv[], uint16_t command)
     char *error;
 
     error = parse_ofp_flow_mod_file(argv[2], command, &fms, &n_fms,
-                                    &usable_protocols);
+                                    &usable_protocols,
+                                    !(allowed_protocols & OFPUTIL_P_OF10_ANY));
     if (error) {
         ovs_fatal(0, "%s", error);
     }
@@ -1130,7 +1154,9 @@ ofctl_flow_mod(int argc, char *argv[], uint16_t command)
         enum ofputil_protocol usable_protocols;
 
         error = parse_ofp_flow_mod_str(&fm, argc > 2 ? argv[2] : "", command,
-                                       &usable_protocols);
+                                       &usable_protocols,
+                                       !(allowed_protocols
+                                         & OFPUTIL_P_OF10_ANY));
         if (error) {
             ovs_fatal(0, "%s", error);
         }
@@ -2205,7 +2231,8 @@ read_flows_from_file(const char *filename, struct classifier *cls, int index)
         char *error;
         enum ofputil_protocol usable;
 
-        error = parse_ofp_str(&fm, OFPFC_ADD, ds_cstr(&s), &usable);
+        error = parse_ofp_str(&fm, OFPFC_ADD, ds_cstr(&s), &usable,
+                              !(allowed_protocols & OFPUTIL_P_OF10_ANY));
         if (error) {
             ovs_fatal(0, "%s:%d: %s", filename, line_number, error);
         }
@@ -2371,7 +2398,7 @@ ofctl_replace_flows(int argc OVS_UNUSED, char *argv[])
     struct vconn *vconn;
     struct fte *fte;
 
-    classifier_init(&cls);
+    classifier_init(&cls, NULL);
     usable_protocols = read_flows_from_file(argv[2], &cls, FILE_IDX);
 
     protocol = open_vconn(argv[1], &vconn);
@@ -2441,7 +2468,7 @@ ofctl_diff_flows(int argc OVS_UNUSED, char *argv[])
     struct ds a_s, b_s;
     struct fte *fte;
 
-    classifier_init(&cls);
+    classifier_init(&cls, NULL);
     read_flows_from_source(argv[1], &cls, 0);
     read_flows_from_source(argv[2], &cls, 1);
 
@@ -2624,7 +2651,8 @@ ofctl_parse_flow(int argc OVS_UNUSED, char *argv[])
     struct ofputil_flow_mod fm;
     char *error;
 
-    error = parse_ofp_flow_mod_str(&fm, argv[1], OFPFC_ADD, &usable_protocols);
+    error = parse_ofp_flow_mod_str(&fm, argv[1], OFPFC_ADD, &usable_protocols,
+                                   !(allowed_protocols & OFPUTIL_P_OF10_ANY));
     if (error) {
         ovs_fatal(0, "%s", error);
     }
@@ -2642,7 +2670,8 @@ ofctl_parse_flows(int argc OVS_UNUSED, char *argv[])
     char *error;
 
     error = parse_ofp_flow_mod_file(argv[1], OFPFC_ADD, &fms, &n_fms,
-                                    &usable_protocols);
+                                    &usable_protocols,
+                                    !(allowed_protocols & OFPUTIL_P_OF10_ANY));
     if (error) {
         ovs_fatal(0, "%s", error);
     }
@@ -2784,7 +2813,8 @@ ofctl_parse_ofp10_actions(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
         /* Convert to ofpacts. */
         ofpbuf_init(&ofpacts, 0);
         size = of10_in.size;
-        error = ofpacts_pull_openflow10(&of10_in, of10_in.size, &ofpacts);
+        error = ofpacts_pull_openflow_actions(&of10_in, of10_in.size,
+                                              OFP10_VERSION, &ofpacts);
         if (error) {
             printf("bad OF1.1 actions: %s\n\n", ofperr_get_name(error));
             ofpbuf_uninit(&ofpacts);
@@ -2802,7 +2832,8 @@ ofctl_parse_ofp10_actions(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
 
         /* Convert back to ofp10 actions and print differences from input. */
         ofpbuf_init(&of10_out, 0);
-        ofpacts_put_openflow10(ofpacts.data, ofpacts.size, &of10_out);
+        ofpacts_put_openflow_actions(ofpacts.data, ofpacts.size, &of10_out,
+                                     OFP10_VERSION);
 
         print_differences("", of10_in.data, of10_in.size,
                           of10_out.data, of10_out.size);
@@ -2970,8 +3001,8 @@ ofctl_parse_ofp11_actions(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
         /* Convert to ofpacts. */
         ofpbuf_init(&ofpacts, 0);
         size = of11_in.size;
-        error = ofpacts_pull_openflow11_actions(&of11_in, OFP11_VERSION,
-                                                of11_in.size, &ofpacts);
+        error = ofpacts_pull_openflow_actions(&of11_in, of11_in.size,
+                                              OFP11_VERSION, &ofpacts);
         if (error) {
             printf("bad OF1.1 actions: %s\n\n", ofperr_get_name(error));
             ofpbuf_uninit(&ofpacts);
@@ -2989,7 +3020,8 @@ ofctl_parse_ofp11_actions(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
 
         /* Convert back to ofp11 actions and print differences from input. */
         ofpbuf_init(&of11_out, 0);
-        ofpacts_put_openflow11_actions(ofpacts.data, ofpacts.size, &of11_out);
+        ofpacts_put_openflow_actions(ofpacts.data, ofpacts.size, &of11_out,
+                                     OFP11_VERSION);
 
         print_differences("", of11_in.data, of11_in.size,
                           of11_out.data, of11_out.size);
@@ -3039,14 +3071,15 @@ ofctl_parse_ofp11_instructions(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
         /* Convert to ofpacts. */
         ofpbuf_init(&ofpacts, 0);
         size = of11_in.size;
-        error = ofpacts_pull_openflow11_instructions(&of11_in, OFP11_VERSION,
-                                                     of11_in.size, &ofpacts);
+        error = ofpacts_pull_openflow_instructions(&of11_in, of11_in.size,
+                                                   OFP11_VERSION, &ofpacts);
         if (!error) {
-            /* Verify actions. */
+            /* Verify actions, enforce consistency. */
             struct flow flow;
             memset(&flow, 0, sizeof flow);
-            error = ofpacts_check(ofpacts.data, ofpacts.size, &flow, OFPP_MAX,
-                                  table_id ? atoi(table_id) : 0);
+            error = ofpacts_check(ofpacts.data, ofpacts.size, &flow,
+                                  true, OFPP_MAX,
+                                  table_id ? atoi(table_id) : 0, 255);
         }
         if (error) {
             printf("bad OF1.1 instructions: %s\n\n", ofperr_get_name(error));
@@ -3066,8 +3099,8 @@ ofctl_parse_ofp11_instructions(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
         /* Convert back to ofp11 instructions and print differences from
          * input. */
         ofpbuf_init(&of11_out, 0);
-        ofpacts_put_openflow11_instructions(ofpacts.data, ofpacts.size,
-                                            &of11_out);
+        ofpacts_put_openflow_instructions(ofpacts.data, ofpacts.size,
+                                          &of11_out, OFP13_VERSION);
 
         print_differences("", of11_in.data, of11_in.size,
                           of11_out.data, of11_out.size);
@@ -3144,7 +3177,8 @@ ofctl_check_vlan(int argc OVS_UNUSED, char *argv[])
     string_s = match_to_string(&match, OFP_DEFAULT_PRIORITY);
     printf("%s -> ", string_s);
     fflush(stdout);
-    error_s = parse_ofp_str(&fm, -1, string_s, &usable_protocols);
+    error_s = parse_ofp_str(&fm, -1, string_s, &usable_protocols,
+                            !(allowed_protocols & OFPUTIL_P_OF10_ANY));
     if (error_s) {
         ovs_fatal(0, "%s", error_s);
     }
@@ -3317,6 +3351,7 @@ static const struct command all_commands[] = {
     { "dump-flows", 1, 2, ofctl_dump_flows },
     { "dump-aggregate", 1, 2, ofctl_dump_aggregate },
     { "queue-stats", 1, 3, ofctl_queue_stats },
+    { "queue-get-config", 2, 2, ofctl_queue_get_config },
     { "add-flow", 2, 2, ofctl_add_flow },
     { "add-flows", 2, 2, ofctl_add_flows },
     { "mod-flows", 2, 2, ofctl_mod_flows },