autopath: Create the autopath action.
[sliver-openvswitch.git] / ofproto / ofproto.c
index e6ea69d..0b85e61 100644 (file)
@@ -24,6 +24,7 @@
 #include <netinet/in.h>
 #include <stdbool.h>
 #include <stdlib.h>
+#include "autopath.h"
 #include "byte-order.h"
 #include "cfm.h"
 #include "classifier.h"
 #include "poll-loop.h"
 #include "rconn.h"
 #include "shash.h"
+#include "sset.h"
 #include "stream-ssl.h"
-#include "svec.h"
 #include "tag.h"
+#include "timer.h"
 #include "timeval.h"
 #include "unaligned.h"
 #include "unixctl.h"
@@ -296,7 +298,7 @@ struct ofproto {
 
     /* Flow table. */
     struct classifier cls;
-    long long int next_expiration;
+    struct timer next_expiration;
 
     /* Facets. */
     struct hmap facets;
@@ -404,7 +406,7 @@ ofproto_create(const char *datapath, const char *datapath_type,
 
     /* Initialize flow table. */
     classifier_init(&p->cls);
-    p->next_expiration = time_msec() + 1000;
+    timer_set_duration(&p->next_expiration, 1000);
 
     /* Initialize facet table. */
     hmap_init(&p->facets);
@@ -542,7 +544,7 @@ ofproto_set_desc(struct ofproto *p,
 }
 
 int
-ofproto_set_snoops(struct ofproto *ofproto, const struct svec *snoops)
+ofproto_set_snoops(struct ofproto *ofproto, const struct sset *snoops)
 {
     return connmgr_set_snoops(ofproto->connmgr, snoops);
 }
@@ -551,7 +553,7 @@ int
 ofproto_set_netflow(struct ofproto *ofproto,
                     const struct netflow_options *nf_options)
 {
-    if (nf_options && nf_options->collectors.n) {
+    if (nf_options && !sset_is_empty(&nf_options->collectors)) {
         if (!ofproto->netflow) {
             ofproto->netflow = netflow_create();
         }
@@ -666,8 +668,14 @@ ofproto_get_fail_mode(const struct ofproto *p)
     return connmgr_get_fail_mode(p->connmgr);
 }
 
+bool
+ofproto_has_snoops(const struct ofproto *ofproto)
+{
+    return connmgr_has_snoops(ofproto->connmgr);
+}
+
 void
-ofproto_get_snoops(const struct ofproto *ofproto, struct svec *snoops)
+ofproto_get_snoops(const struct ofproto *ofproto, struct sset *snoops)
 {
     connmgr_get_snoops(ofproto->connmgr, snoops);
 }
@@ -683,10 +691,8 @@ ofproto_destroy(struct ofproto *p)
 
     shash_find_and_delete(&all_ofprotos, dpif_name(p->dpif));
 
-    /* Destroy connmgr early, since it touches the classifier. */
-    connmgr_destroy(p->connmgr);
-
     ofproto_flush_flows(p);
+    connmgr_destroy(p->connmgr);
     classifier_destroy(&p->cls);
     hmap_destroy(&p->facets);
 
@@ -781,9 +787,9 @@ ofproto_run1(struct ofproto *p)
 
     connmgr_run(p->connmgr, handle_openflow);
 
-    if (time_msec() >= p->next_expiration) {
+    if (timer_expired(&p->next_expiration)) {
         int delay = ofproto_expire(p);
-        p->next_expiration = time_msec() + delay;
+        timer_set_duration(&p->next_expiration, delay);
         COVERAGE_INC(ofproto_expiration);
     }
 
@@ -846,8 +852,8 @@ ofproto_wait(struct ofproto *p)
         /* Shouldn't happen, but if it does just go around again. */
         VLOG_DBG_RL(&rl, "need revalidate in ofproto_wait_cb()");
         poll_immediate_wake();
-    } else if (p->next_expiration != LLONG_MAX) {
-        poll_timer_wait_until(p->next_expiration);
+    } else {
+        timer_wait(&p->next_expiration);
     }
     connmgr_wait(p->connmgr);
 }
@@ -1027,25 +1033,25 @@ static void
 reinit_ports(struct ofproto *p)
 {
     struct dpif_port_dump dump;
-    struct shash_node *node;
-    struct shash devnames;
+    struct sset devnames;
     struct ofport *ofport;
     struct dpif_port dpif_port;
+    const char *devname;
 
     COVERAGE_INC(ofproto_reinit_ports);
 
-    shash_init(&devnames);
+    sset_init(&devnames);
     HMAP_FOR_EACH (ofport, hmap_node, &p->ports) {
-        shash_add_once (&devnames, ofport->opp.name, NULL);
+        sset_add(&devnames, ofport->opp.name);
     }
     DPIF_PORT_FOR_EACH (&dpif_port, &dump, p->dpif) {
-        shash_add_once (&devnames, dpif_port.name, NULL);
+        sset_add(&devnames, dpif_port.name);
     }
 
-    SHASH_FOR_EACH (node, &devnames) {
-        update_port(p, node->name);
+    SSET_FOR_EACH (devname, &devnames) {
+        update_port(p, devname);
     }
-    shash_destroy(&devnames);
+    sset_destroy(&devnames);
 }
 
 static struct ofport *
@@ -1159,8 +1165,8 @@ ofport_run(struct ofproto *ofproto, struct ofport *ofport)
             struct ccm *ccm;
 
             ofpbuf_init(&packet, 0);
-            ccm = compose_packet(&packet, eth_addr_ccm, ofport->opp.hw_addr,
-                                 ETH_TYPE_CFM,  sizeof *ccm);
+            ccm = eth_compose(&packet, eth_addr_ccm, ofport->opp.hw_addr,
+                              ETH_TYPE_CFM,  sizeof *ccm);
             cfm_compose_ccm(ofport->cfm, ccm);
             ofproto_send_packet(ofproto, ofport->odp_port, 0, &packet);
             ofpbuf_uninit(&packet);
@@ -1616,7 +1622,6 @@ facet_put__(struct ofproto *ofproto, struct facet *facet,
 
     ofpbuf_use_stack(&key, &keybuf, sizeof keybuf);
     odp_flow_key_from_flow(&key, &facet->flow);
-    assert(key.base == &keybuf);
 
     return dpif_flow_put(ofproto->dpif, flags, key.data, key.size,
                          actions, actions_len, stats);
@@ -1666,7 +1671,6 @@ facet_uninstall(struct ofproto *p, struct facet *facet)
 
         ofpbuf_use_stack(&key, &keybuf, sizeof keybuf);
         odp_flow_key_from_flow(&key, &facet->flow);
-        assert(key.base == &keybuf);
 
         if (!dpif_flow_del(p->dpif, key.data, key.size, &stats)) {
             facet_update_stats(p, facet, &stats);
@@ -2219,8 +2223,11 @@ xlate_nicira_action(struct action_xlate_ctx *ctx,
     const struct nx_action_set_tunnel *nast;
     const struct nx_action_set_queue *nasq;
     const struct nx_action_multipath *nam;
+    const struct nx_action_autopath *naa;
     enum nx_action_subtype subtype = ntohs(nah->subtype);
+    const struct ofhooks *ofhooks = ctx->ofproto->ofhooks;
     struct xlate_reg_state state;
+    uint16_t autopath_port;
     ovs_be64 tun_id;
 
     assert(nah->vendor == htonl(NX_VENDOR_ID));
@@ -2282,6 +2289,15 @@ xlate_nicira_action(struct action_xlate_ctx *ctx,
         multipath_execute(nam, &ctx->flow);
         break;
 
+    case NXAST_AUTOPATH:
+        naa = (const struct nx_action_autopath *) nah;
+        autopath_port = (ofhooks->autopath_cb
+                         ? ofhooks->autopath_cb(&ctx->flow, ntohl(naa->id),
+                                                &ctx->tags, ctx->ofproto->aux)
+                         : OFPP_NONE);
+        autopath_execute(naa, &ctx->flow, autopath_port);
+        break;
+
     /* If you add a new action here that modifies flow data, don't forget to
      * update the flow key in ctx->flow at the same time. */
 
@@ -4412,5 +4428,6 @@ static const struct ofhooks default_ofhooks = {
     default_normal_ofhook_cb,
     NULL,
     NULL,
+    NULL,
     NULL
 };