ovsdbmonitor: add .desktop file
[sliver-openvswitch.git] / ofproto / ofproto-dpif.c
index 1fe5da6..d8d1e38 100644 (file)
@@ -190,6 +190,8 @@ static struct ofbundle ofpp_none_bundle = {
 
 static void stp_run(struct ofproto_dpif *ofproto);
 static void stp_wait(struct ofproto_dpif *ofproto);
+static int set_stp_port(struct ofport *,
+                        const struct ofproto_port_stp_settings *);
 
 static bool ofbundle_includes_vlan(const struct ofbundle *, uint16_t vlan);
 
@@ -1155,6 +1157,12 @@ set_stp(struct ofproto *ofproto_, const struct ofproto_stp_settings *s)
         stp_set_max_age(ofproto->stp, s->max_age);
         stp_set_forward_delay(ofproto->stp, s->fwd_delay);
     }  else {
+        struct ofport *ofport;
+
+        HMAP_FOR_EACH (ofport, hmap_node, &ofproto->up.ports) {
+            set_stp_port(ofport, NULL);
+        }
+
         stp_destroy(ofproto->stp);
         ofproto->stp = NULL;
     }
@@ -2448,6 +2456,7 @@ send_packet_in_miss(struct ofproto_dpif *ofproto, const struct ofpbuf *packet,
     pin.packet_len = packet->size;
     pin.total_len = packet->size;
     pin.reason = OFPR_NO_MATCH;
+    pin.controller_id = 0;
 
     pin.table_id = 0;
     pin.cookie = 0;
@@ -3102,7 +3111,7 @@ rule_expire(struct rule_dpif *rule)
     if (rule->up.hard_timeout
         && now > rule->up.modified + rule->up.hard_timeout * 1000) {
         reason = OFPRR_HARD_TIMEOUT;
-    } else if (rule->up.idle_timeout && list_is_empty(&rule->facets)
+    } else if (rule->up.idle_timeout
                && now > rule->up.used + rule->up.idle_timeout * 1000) {
         reason = OFPRR_IDLE_TIMEOUT;
     } else {
@@ -4457,7 +4466,8 @@ flood_packets(struct action_xlate_ctx *ctx, bool all)
 
 static void
 execute_controller_action(struct action_xlate_ctx *ctx, int len,
-                          enum ofp_packet_in_reason reason)
+                          enum ofp_packet_in_reason reason,
+                          uint16_t controller_id)
 {
     struct ofputil_packet_in pin;
     struct ofpbuf *packet;
@@ -4503,6 +4513,7 @@ execute_controller_action(struct action_xlate_ctx *ctx, int len,
     pin.packet = packet->data;
     pin.packet_len = packet->size;
     pin.reason = reason;
+    pin.controller_id = controller_id;
     pin.table_id = ctx->table_id;
     pin.cookie = ctx->rule ? ctx->rule->up.flow_cookie : 0;
 
@@ -4527,7 +4538,7 @@ compose_dec_ttl(struct action_xlate_ctx *ctx)
         ctx->flow.nw_ttl--;
         return false;
     } else {
-        execute_controller_action(ctx, UINT16_MAX, OFPR_INVALID_TTL);
+        execute_controller_action(ctx, UINT16_MAX, OFPR_INVALID_TTL, 0);
 
         /* Stop processing for current table. */
         return true;
@@ -4559,7 +4570,7 @@ xlate_output_action__(struct action_xlate_ctx *ctx,
         flood_packets(ctx, true);
         break;
     case OFPP_CONTROLLER:
-        execute_controller_action(ctx, max_len, OFPR_ACTION);
+        execute_controller_action(ctx, max_len, OFPR_ACTION, 0);
         break;
     case OFPP_NONE:
         break;
@@ -4797,6 +4808,7 @@ do_xlate_actions(const union ofp_action *in, size_t n_in,
         const struct nx_action_autopath *naa;
         const struct nx_action_bundle *nab;
         const struct nx_action_output_reg *naor;
+        const struct nx_action_controller *nac;
         enum ofputil_action_code code;
         ovs_be64 tun_id;
 
@@ -4957,6 +4969,12 @@ do_xlate_actions(const union ofp_action *in, size_t n_in,
             ctx->has_fin_timeout = true;
             xlate_fin_timeout(ctx, (const struct nx_action_fin_timeout *) ia);
             break;
+
+        case OFPUTIL_NXAST_CONTROLLER:
+            nac = (const struct nx_action_controller *) ia;
+            execute_controller_action(ctx, ntohs(nac->max_len), nac->reason,
+                                      ntohs(nac->controller_id));
+            break;
         }
     }
 
@@ -5880,7 +5898,7 @@ ofproto_unixctl_fdb_flush(struct unixctl_conn *conn, int argc,
     if (argc > 1) {
         ofproto = ofproto_dpif_lookup(argv[1]);
         if (!ofproto) {
-            unixctl_command_reply(conn, 501, "no such bridge");
+            unixctl_command_reply_error(conn, "no such bridge");
             return;
         }
         mac_learning_flush(ofproto->ml, &ofproto->revalidate_set);
@@ -5890,7 +5908,7 @@ ofproto_unixctl_fdb_flush(struct unixctl_conn *conn, int argc,
         }
     }
 
-    unixctl_command_reply(conn, 200, "table successfully flushed");
+    unixctl_command_reply(conn, "table successfully flushed");
 }
 
 static void
@@ -5903,7 +5921,7 @@ ofproto_unixctl_fdb_show(struct unixctl_conn *conn, int argc OVS_UNUSED,
 
     ofproto = ofproto_dpif_lookup(argv[1]);
     if (!ofproto) {
-        unixctl_command_reply(conn, 501, "no such bridge");
+        unixctl_command_reply_error(conn, "no such bridge");
         return;
     }
 
@@ -5915,7 +5933,7 @@ ofproto_unixctl_fdb_show(struct unixctl_conn *conn, int argc OVS_UNUSED,
                       e->vlan, ETH_ADDR_ARGS(e->mac),
                       mac_entry_age(ofproto->ml, e));
     }
-    unixctl_command_reply(conn, 200, ds_cstr(&ds));
+    unixctl_command_reply(conn, ds_cstr(&ds));
     ds_destroy(&ds);
 }
 
@@ -5975,6 +5993,18 @@ trace_format_regs(struct ds *result, int level, const char *title,
     ds_put_char(result, '\n');
 }
 
+static void
+trace_format_odp(struct ds *result, int level, const char *title,
+                 struct ofproto_trace *trace)
+{
+    struct ofpbuf *odp_actions = trace->ctx.odp_actions;
+
+    ds_put_char_multiple(result, '\t', level);
+    ds_put_format(result, "%s: ", title);
+    format_odp_actions(result, odp_actions->data, odp_actions->size);
+    ds_put_char(result, '\n');
+}
+
 static void
 trace_resubmit(struct action_xlate_ctx *ctx, struct rule_dpif *rule)
 {
@@ -5984,6 +6014,7 @@ trace_resubmit(struct action_xlate_ctx *ctx, struct rule_dpif *rule)
     ds_put_char(result, '\n');
     trace_format_flow(result, ctx->recurse + 1, "Resubmitted flow", trace);
     trace_format_regs(result, ctx->recurse + 1, "Resubmitted regs", trace);
+    trace_format_odp(result,  ctx->recurse + 1, "Resubmitted  odp", trace);
     trace_format_rule(result, ctx->table_id, ctx->recurse + 1, rule);
 }
 
@@ -6007,8 +6038,8 @@ ofproto_unixctl_trace(struct unixctl_conn *conn, int argc, const char *argv[],
 
     ofproto = ofproto_dpif_lookup(dpname);
     if (!ofproto) {
-        unixctl_command_reply(conn, 501, "Unknown ofproto (use ofproto/list "
-                              "for help)");
+        unixctl_command_reply_error(conn, "Unknown ofproto (use ofproto/list "
+                                    "for help)");
         goto exit;
     }
     if (argc == 3 || (argc == 4 && !strcmp(argv[3], "-generate"))) {
@@ -6021,7 +6052,7 @@ ofproto_unixctl_trace(struct unixctl_conn *conn, int argc, const char *argv[],
         ofpbuf_init(&odp_key, 0);
         error = odp_flow_key_from_string(flow_s, NULL, &odp_key);
         if (error) {
-            unixctl_command_reply(conn, 501, "Bad flow syntax");
+            unixctl_command_reply_error(conn, "Bad flow syntax");
             goto exit;
         }
 
@@ -6030,7 +6061,7 @@ ofproto_unixctl_trace(struct unixctl_conn *conn, int argc, const char *argv[],
                                               odp_key.size, &flow,
                                               &initial_tci, NULL);
         if (error == ODP_FIT_ERROR) {
-            unixctl_command_reply(conn, 501, "Invalid flow");
+            unixctl_command_reply_error(conn, "Invalid flow");
             goto exit;
         }
 
@@ -6052,7 +6083,7 @@ ofproto_unixctl_trace(struct unixctl_conn *conn, int argc, const char *argv[],
 
         msg = eth_from_hex(packet_s, &packet);
         if (msg) {
-            unixctl_command_reply(conn, 501, msg);
+            unixctl_command_reply_error(conn, msg);
             goto exit;
         }
 
@@ -6064,7 +6095,7 @@ ofproto_unixctl_trace(struct unixctl_conn *conn, int argc, const char *argv[],
         flow_extract(packet, priority, tun_id, in_port, &flow);
         initial_tci = flow.vlan_tci;
     } else {
-        unixctl_command_reply(conn, 501, "Bad command syntax");
+        unixctl_command_reply_error(conn, "Bad command syntax");
         goto exit;
     }
 
@@ -6104,7 +6135,7 @@ ofproto_unixctl_trace(struct unixctl_conn *conn, int argc, const char *argv[],
         }
     }
 
-    unixctl_command_reply(conn, 200, ds_cstr(&result));
+    unixctl_command_reply(conn, ds_cstr(&result));
 
 exit:
     ds_destroy(&result);
@@ -6117,7 +6148,7 @@ ofproto_dpif_clog(struct unixctl_conn *conn OVS_UNUSED, int argc OVS_UNUSED,
                   const char *argv[] OVS_UNUSED, void *aux OVS_UNUSED)
 {
     clogged = true;
-    unixctl_command_reply(conn, 200, NULL);
+    unixctl_command_reply(conn, NULL);
 }
 
 static void
@@ -6125,7 +6156,7 @@ ofproto_dpif_unclog(struct unixctl_conn *conn OVS_UNUSED, int argc OVS_UNUSED,
                     const char *argv[] OVS_UNUSED, void *aux OVS_UNUSED)
 {
     clogged = false;
-    unixctl_command_reply(conn, 200, NULL);
+    unixctl_command_reply(conn, NULL);
 }
 
 /* Runs a self-check of flow translations in 'ofproto'.  Appends a message to
@@ -6164,8 +6195,8 @@ ofproto_dpif_self_check(struct unixctl_conn *conn,
     if (argc > 1) {
         ofproto = ofproto_dpif_lookup(argv[1]);
         if (!ofproto) {
-            unixctl_command_reply(conn, 501, "Unknown ofproto (use "
-                                  "ofproto/list for help)");
+            unixctl_command_reply_error(conn, "Unknown ofproto (use "
+                                        "ofproto/list for help)");
             return;
         }
         ofproto_dpif_self_check__(ofproto, &reply);
@@ -6175,7 +6206,7 @@ ofproto_dpif_self_check(struct unixctl_conn *conn,
         }
     }
 
-    unixctl_command_reply(conn, 200, ds_cstr(&reply));
+    unixctl_command_reply(conn, ds_cstr(&reply));
     ds_destroy(&reply);
 }