ofp-print-ofctl: Free group buckets.
[cascardo/ovs.git] / lib / ofp-print.c
index 02f3db0..e3a4172 100644 (file)
@@ -418,28 +418,33 @@ static void
 ofp_print_phy_ports(struct ds *string, uint8_t ofp_version,
                     struct ofpbuf *b)
 {
-    size_t n_ports;
     struct ofputil_phy_port *ports;
-    enum ofperr error;
+    size_t allocated_ports, n_ports;
+    int retval;
     size_t i;
 
-    n_ports = ofputil_count_phy_ports(ofp_version, b);
+    ports = NULL;
+    allocated_ports = 0;
+    for (n_ports = 0; ; n_ports++) {
+        if (n_ports >= allocated_ports) {
+            ports = x2nrealloc(ports, &allocated_ports, sizeof *ports);
+        }
 
-    ports = xmalloc(n_ports * sizeof *ports);
-    for (i = 0; i < n_ports; i++) {
-        error = ofputil_pull_phy_port(ofp_version, b, &ports[i]);
-        if (error) {
-            ofp_print_error(string, error);
-            goto exit;
+        retval = ofputil_pull_phy_port(ofp_version, b, &ports[n_ports]);
+        if (retval) {
+            break;
         }
     }
+
     qsort(ports, n_ports, sizeof *ports, compare_ports);
     for (i = 0; i < n_ports; i++) {
         ofp_print_phy_port(string, &ports[i]);
     }
-
-exit:
     free(ports);
+
+    if (retval != EOF) {
+        ofp_print_error(string, retval);
+    }
 }
 
 static const char *
@@ -540,6 +545,7 @@ ofp_print_switch_features(struct ds *string, const struct ofp_header *oh)
         break;
     case OFP13_VERSION:
     case OFP14_VERSION:
+    case OFP15_VERSION:
         return; /* no ports in ofp13_switch_features */
     default:
         OVS_NOT_REACHED();
@@ -743,6 +749,12 @@ ofp_print_flow_flags(struct ds *s, enum ofputil_flow_mod_flags flags)
     if (flags & OFPUTIL_FF_NO_BYT_COUNTS) {
         ds_put_cstr(s, "no_byte_counts ");
     }
+    if (flags & OFPUTIL_FF_HIDDEN_FIELDS) {
+        ds_put_cstr(s, "allow_hidden_fields ");
+    }
+    if (flags & OFPUTIL_FF_NO_READONLY) {
+        ds_put_cstr(s, "no_readonly_table ");
+    }
 }
 
 static void
@@ -959,7 +971,7 @@ ofp_print_port_mod(struct ds *string, const struct ofp_header *oh)
     struct ofputil_port_mod pm;
     enum ofperr error;
 
-    error = ofputil_decode_port_mod(oh, &pm);
+    error = ofputil_decode_port_mod(oh, &pm, true);
     if (error) {
         ofp_print_error(string, error);
         return;
@@ -1791,6 +1803,7 @@ ofp_print_ofpst_table_reply(struct ds *string, const struct ofp_header *oh,
                             int verbosity)
 {
     switch ((enum ofp_version)oh->version) {
+    case OFP15_VERSION:
     case OFP14_VERSION:
     case OFP13_VERSION:
         ofp_print_ofpst_table_reply13(string, oh, verbosity);
@@ -1886,6 +1899,23 @@ ofp_print_ofpst_queue_reply(struct ds *string, const struct ofp_header *oh,
     }
 }
 
+static void
+ofp_print_ofpst_port_desc_request(struct ds *string,
+                                  const struct ofp_header *oh)
+{
+    enum ofperr error;
+    ofp_port_t port;
+
+    error = ofputil_decode_port_desc_stats_request(oh, &port);
+    if (error) {
+        ofp_print_error(string, error);
+        return;
+    }
+
+    ds_put_cstr(string, " port=");
+    ofputil_format_port(port, string);
+}
+
 static void
 ofp_print_ofpst_port_desc_reply(struct ds *string,
                                 const struct ofp_header *oh)
@@ -2289,6 +2319,12 @@ ofp_print_version(const struct ofp_header *oh,
     case OFP13_VERSION:
         ds_put_cstr(string, " (OF1.3)");
         break;
+    case OFP14_VERSION:
+        ds_put_cstr(string, " (OF1.4)");
+        break;
+    case OFP15_VERSION:
+        ds_put_cstr(string, " (OF1.5)");
+        break;
     default:
         ds_put_format(string, " (OF 0x%02"PRIx8")", oh->version);
         break;
@@ -2336,6 +2372,15 @@ ofp_print_group(struct ds *s, uint32_t group_id, uint8_t type,
     }
 }
 
+static void
+ofp_print_ofpst_group_desc_request(struct ds *string,
+                                   const struct ofp_header *oh)
+{
+    uint32_t group_id = ofputil_decode_group_desc_request(oh);
+    ds_put_cstr(string, " group_id=");
+    ofputil_format_group(group_id, string);
+}
+
 static void
 ofp_print_group_desc(struct ds *s, const struct ofp_header *oh)
 {
@@ -2357,6 +2402,7 @@ ofp_print_group_desc(struct ds *s, const struct ofp_header *oh)
         ds_put_char(s, '\n');
         ds_put_char(s, ' ');
         ofp_print_group(s, gd.group_id, gd.type, &gd.buckets);
+        ofputil_bucket_list_destroy(&gd.buckets);
      }
 }
 
@@ -2497,6 +2543,7 @@ ofp_print_group_mod(struct ds *s, const struct ofp_header *oh)
     ds_put_char(s, ' ');
 
     ofp_print_group(s, gm.group_id, gm.type, &gm.buckets);
+    ofputil_bucket_list_destroy(&gm.buckets);
 }
 
 static const char *
@@ -2659,6 +2706,90 @@ ofp_print_table_features(struct ds *s, const struct ofp_header *oh)
     }
 }
 
+static const char *
+bundle_flags_to_name(uint32_t bit)
+{
+    switch (bit) {
+    case OFPBF_ATOMIC:
+        return "atomic";
+    case OFPBF_ORDERED:
+        return "ordered";
+    default:
+        return NULL;
+    }
+}
+
+static void
+ofp_print_bundle_ctrl(struct ds *s, const struct ofp_header *oh)
+{
+    int error;
+    struct ofputil_bundle_ctrl_msg bctrl;
+
+    error = ofputil_decode_bundle_ctrl(oh, &bctrl);
+    if (error) {
+        ofp_print_error(s, error);
+        return;
+    }
+
+    ds_put_char(s, '\n');
+
+    ds_put_format(s, " bundle_id=%#"PRIx32" type=",  bctrl.bundle_id);
+    switch (bctrl.type) {
+    case OFPBCT_OPEN_REQUEST:
+        ds_put_cstr(s, "OPEN_REQUEST");
+        break;
+    case OFPBCT_OPEN_REPLY:
+        ds_put_cstr(s, "OPEN_REPLY");
+        break;
+    case OFPBCT_CLOSE_REQUEST:
+        ds_put_cstr(s, "CLOSE_REQUEST");
+        break;
+    case OFPBCT_CLOSE_REPLY:
+        ds_put_cstr(s, "CLOSE_REPLY");
+        break;
+    case OFPBCT_COMMIT_REQUEST:
+        ds_put_cstr(s, "COMMIT_REQUEST");
+        break;
+    case OFPBCT_COMMIT_REPLY:
+        ds_put_cstr(s, "COMMIT_REPLY");
+        break;
+    case OFPBCT_DISCARD_REQUEST:
+        ds_put_cstr(s, "DISCARD_REQUEST");
+        break;
+    case OFPBCT_DISCARD_REPLY:
+        ds_put_cstr(s, "DISCARD_REPLY");
+        break;
+    }
+
+    ds_put_cstr(s, " flags=");
+    ofp_print_bit_names(s, bctrl.flags, bundle_flags_to_name, ' ');
+}
+
+static void
+ofp_print_bundle_add(struct ds *s, const struct ofp_header *oh, int verbosity)
+{
+    int error;
+    struct ofputil_bundle_add_msg badd;
+    char *msg;
+
+    error = ofputil_decode_bundle_add(oh, &badd);
+    if (error) {
+        ofp_print_error(s, error);
+        return;
+    }
+
+    ds_put_char(s, '\n');
+    ds_put_format(s, " bundle_id=%#"PRIx32,  badd.bundle_id);
+    ds_put_cstr(s, " flags=");
+    ofp_print_bit_names(s, badd.flags, bundle_flags_to_name, ' ');
+
+    ds_put_char(s, '\n');
+    msg = ofp_to_string(badd.msg, ntohs(badd.msg->length), verbosity);
+    if (msg) {
+        ds_put_cstr(s, msg);
+    }
+}
+
 static void
 ofp_to_string__(const struct ofp_header *oh, enum ofpraw raw,
                 struct ds *string, int verbosity)
@@ -2679,6 +2810,7 @@ ofp_to_string__(const struct ofp_header *oh, enum ofpraw raw,
 
     case OFPTYPE_GROUP_DESC_STATS_REQUEST:
         ofp_print_stats_request(string, oh);
+        ofp_print_ofpst_group_desc_request(string, oh);
         break;
 
     case OFPTYPE_GROUP_DESC_STATS_REPLY:
@@ -2804,7 +2936,6 @@ ofp_to_string__(const struct ofp_header *oh, enum ofpraw raw,
         break;
 
     case OFPTYPE_DESC_STATS_REQUEST:
-    case OFPTYPE_PORT_DESC_STATS_REQUEST:
     case OFPTYPE_METER_FEATURES_STATS_REQUEST:
         ofp_print_stats_request(string, oh);
         break;
@@ -2859,6 +2990,11 @@ ofp_to_string__(const struct ofp_header *oh, enum ofpraw raw,
         ofp_print_aggregate_stats_reply(string, oh);
         break;
 
+    case OFPTYPE_PORT_DESC_STATS_REQUEST:
+        ofp_print_stats_request(string, oh);
+        ofp_print_ofpst_port_desc_request(string, oh);
+        break;
+
     case OFPTYPE_PORT_DESC_STATS_REPLY:
         ofp_print_stats_reply(string, oh);
         ofp_print_ofpst_port_desc_reply(string, oh);
@@ -2904,6 +3040,14 @@ ofp_to_string__(const struct ofp_header *oh, enum ofpraw raw,
     case OFPTYPE_FLOW_MONITOR_STATS_REPLY:
         ofp_print_nxst_flow_monitor_reply(string, msg);
         break;
+
+    case OFPTYPE_BUNDLE_CONTROL:
+        ofp_print_bundle_ctrl(string, msg);
+        break;
+
+    case OFPTYPE_BUNDLE_ADD_MESSAGE:
+        ofp_print_bundle_add(string, msg, verbosity);
+        break;
     }
 }