Add ability to direct "packet-in"s to particular controllers.
[sliver-openvswitch.git] / lib / ofp-print.c
index 8df439d..f3758ce 100644 (file)
@@ -80,24 +80,6 @@ ofp_packet_to_string(const void *data, size_t len)
     return ds_cstr(&ds);
 }
 
-static const char *
-ofp_packet_in_reason_to_string(enum ofp_packet_in_reason reason)
-{
-    static char s[32];
-
-    switch (reason) {
-    case OFPR_NO_MATCH:
-        return "no_match";
-    case OFPR_ACTION:
-        return "action";
-    case OFPR_INVALID_TTL:
-        return "invalid_ttl";
-    default:
-        sprintf(s, "%d", (int) reason);
-        return s;
-    }
-}
-
 static void
 ofp_print_packet_in(struct ds *string, const struct ofp_header *oh,
                     int verbosity)
@@ -140,7 +122,7 @@ ofp_print_packet_in(struct ds *string, const struct ofp_header *oh,
     }
 
     ds_put_format(string, " (via %s)",
-                  ofp_packet_in_reason_to_string(pin.reason));
+                  ofputil_packet_in_reason_to_string(pin.reason));
 
     ds_put_format(string, " data_len=%zu", pin.packet_len);
     if (pin.buffer_id == UINT32_MAX) {
@@ -194,6 +176,8 @@ ofp_print_action(struct ds *s, const union ofp_action *a,
     const struct nx_action_multipath *nam;
     const struct nx_action_autopath *naa;
     const struct nx_action_output_reg *naor;
+    const struct nx_action_fin_timeout *naft;
+    const struct nx_action_controller *nac;
     struct mf_subfield subfield;
     uint16_t port;
 
@@ -356,6 +340,38 @@ ofp_print_action(struct ds *s, const union ofp_action *a,
         ds_put_cstr(s, "exit");
         break;
 
+    case OFPUTIL_NXAST_FIN_TIMEOUT:
+        naft = (const struct nx_action_fin_timeout *) a;
+        ds_put_cstr(s, "fin_timeout(");
+        if (naft->fin_idle_timeout) {
+            ds_put_format(s, "idle_timeout=%"PRIu16",",
+                          ntohs(naft->fin_idle_timeout));
+        }
+        if (naft->fin_hard_timeout) {
+            ds_put_format(s, "hard_timeout=%"PRIu16",",
+                          ntohs(naft->fin_hard_timeout));
+        }
+        ds_chomp(s, ',');
+        ds_put_char(s, ')');
+        break;
+
+    case OFPUTIL_NXAST_CONTROLLER:
+        nac = (const struct nx_action_controller *) a;
+        ds_put_cstr(s, "controller(");
+        if (nac->reason != OFPR_ACTION) {
+            ds_put_format(s, "reason=%s,",
+                          ofputil_packet_in_reason_to_string(nac->reason));
+        }
+        if (nac->max_len != htons(UINT16_MAX)) {
+            ds_put_format(s, "max_len=%"PRIu16",", ntohs(nac->max_len));
+        }
+        if (nac->controller_id != htons(0)) {
+            ds_put_format(s, "id=%"PRIu16",", ntohs(nac->controller_id));
+        }
+        ds_chomp(s, ',');
+        ds_put_char(s, ')');
+        break;
+
     default:
         break;
     }
@@ -1360,7 +1376,7 @@ ofp_print_nxt_set_async_config(struct ds *string,
         for (j = 0; j < 32; j++) {
             if (nac->packet_in_mask[i] & htonl(1u << j)) {
                 ds_put_format(string, " %s",
-                              ofp_packet_in_reason_to_string(j));
+                              ofputil_packet_in_reason_to_string(j));
             }
         }
         if (!nac->packet_in_mask[i]) {
@@ -1393,6 +1409,13 @@ ofp_print_nxt_set_async_config(struct ds *string,
     }
 }
 
+static void
+ofp_print_nxt_set_controller_id(struct ds *string,
+                                const struct nx_controller_id *nci)
+{
+    ds_put_format(string, " id=%"PRIu16, ntohs(nci->controller_id));
+}
+
 static void
 ofp_to_string__(const struct ofp_header *oh,
                 const struct ofputil_msg_type *type, struct ds *string,
@@ -1552,6 +1575,10 @@ ofp_to_string__(const struct ofp_header *oh,
     case OFPUTIL_NXT_FLOW_AGE:
         break;
 
+    case OFPUTIL_NXT_SET_CONTROLLER_ID:
+        ofp_print_nxt_set_controller_id(string, msg);
+        break;
+
     case OFPUTIL_NXT_SET_ASYNC_CONFIG:
         ofp_print_nxt_set_async_config(string, msg);
         break;