secchan: Add wildcard support to ofproto_add_flow(), ofproto_delete_flow().
authorBen Pfaff <blp@nicira.com>
Tue, 10 Mar 2009 17:44:23 +0000 (10:44 -0700)
committerBen Pfaff <blp@nicira.com>
Tue, 10 Mar 2009 21:00:34 +0000 (14:00 -0700)
secchan/fail-open.c
secchan/in-band.c
secchan/ofproto.c
secchan/ofproto.h
vswitchd/bridge.c

index 9f9718cb162ce982a07df06e50c694f4bebbb7fd..f3053a8d2d6893667e2d6d8f2d6ee6cc48a82d02 100644 (file)
@@ -116,11 +116,11 @@ fail_open_handle_flow_miss(struct fail_open *fo, struct ofproto *ofproto,
     action.output.len = htons(sizeof action);
     if (in_port == out_port || out_port == DROP) {
         /* Set up a flow to drop packets. */
-        ofproto_add_flow(ofproto, flow, NULL, 0, NULL, 0);
+        ofproto_add_flow(ofproto, flow, 0, UINT16_MAX, NULL, 0, NULL, 0);
     } else if (out_port != FLOOD) {
         /* The output port is known, so add a new flow. */
         action.output.port = htons(out_port);
-        ofproto_add_flow(ofproto, flow, &action, 1, payload, 0);
+        ofproto_add_flow(ofproto, flow, 0, UINT16_MAX, &action, 1, payload, 0);
     } else {
         /* We don't know that MAC.  Send along the packet without setting up a
          * flow. */
index 3f5db494fc9eaaecea55cfb2edc1b69cd9ddc080..62fbef7e34798eec0e99ae7d4fda064fe0e8ec9d 100644 (file)
@@ -189,11 +189,11 @@ in_band_handle_flow_miss(struct in_band *in_band, struct ofproto *ofproto,
     action.output.len = htons(sizeof action);
     if (in_port == out_port || out_port == DROP) {
         /* Set up a flow to drop packets. */
-        ofproto_add_flow(ofproto, flow, NULL, 0, NULL, 0);
+        ofproto_add_flow(ofproto, flow, 0, UINT16_MAX, NULL, 0, NULL, 0);
     } else if (out_port != FLOOD) {
         /* The output port is known, so add a new flow. */
         action.output.port = htons(out_port);
-        ofproto_add_flow(ofproto, flow, &action, 1, payload, 0);
+        ofproto_add_flow(ofproto, flow, 0, UINT16_MAX, &action, 1, payload, 0);
     } else {
         /* We don't know that MAC.  Send along the packet without setting up a
          * flow. */
index 019d51fb8fec0d573466f42d680fc7555ca8be4d..f49ec56fcad16789404c6bc4084a6390977f3123 100644 (file)
@@ -768,7 +768,8 @@ ofproto_send_packet(struct ofproto *p, const flow_t *flow,
 }
 
 void
-ofproto_add_flow(struct ofproto *p, const flow_t *flow,
+ofproto_add_flow(struct ofproto *p,
+                 const flow_t *flow, uint32_t wildcards, uint16_t priority,
                  const union ofp_action *actions, size_t n_actions,
                  const struct ofpbuf *packet, int idle_timeout)
 {
@@ -777,7 +778,7 @@ ofproto_add_flow(struct ofproto *p, const flow_t *flow,
     struct odp_flow odp_flow;
 
     rule = xmalloc(sizeof *rule);
-    cls_rule_from_flow(&rule->cr, flow, 0, UINT16_MAX);
+    cls_rule_from_flow(&rule->cr, flow, wildcards, priority);
     rule->idle_timeout = idle_timeout ? idle_timeout : 5; /* XXX */
     rule->hard_timeout = 0;     /* XXX */
     rule->used = rule->created = time_msec();
@@ -796,20 +797,24 @@ ofproto_add_flow(struct ofproto *p, const flow_t *flow,
         rule_destroy(displaced_rule);
     }
 
-    rule_make_actions(p, rule, &odp_actions);
-    if (packet) {
-        if (!ofproto_send_packet(p, flow, actions, n_actions, packet)) {
-            rule->byte_count = packet->size;
-            rule->packet_count++;
+    if (!wildcards) {
+        rule_make_actions(p, rule, &odp_actions);
+        if (packet) {
+            if (!ofproto_send_packet(p, flow, actions, n_actions, packet)) {
+                rule->byte_count = packet->size;
+                rule->packet_count++;
+            }
         }
-    }
 
-    memset(&odp_flow.stats, 0, sizeof odp_flow.stats);
-    odp_flow.key = *flow;
-    odp_flow.actions = odp_actions.actions;
-    odp_flow.n_actions = odp_actions.n_actions;
-    dpif_flow_add(&p->dpif, &odp_flow);
-    odp_actions_free(&odp_actions);
+        memset(&odp_flow.stats, 0, sizeof odp_flow.stats);
+        odp_flow.key = *flow;
+        odp_flow.actions = odp_actions.actions;
+        odp_flow.n_actions = odp_actions.n_actions;
+        dpif_flow_add(&p->dpif, &odp_flow);
+        odp_actions_free(&odp_actions);
+    } else {
+        assert(!packet);
+    }
 }
 
 void
@@ -835,11 +840,14 @@ ofproto_set_actions(struct ofproto *ofproto, const flow_t *flow,
 }
 
 void
-ofproto_delete_flow(struct ofproto *ofproto, const flow_t *flow)
+ofproto_delete_flow(struct ofproto *ofproto, const flow_t *flow,
+                    uint32_t wildcards, uint16_t priority)
 {
     struct rule *rule;
 
-    rule = rule_from_cls_rule(classifier_lookup_exact(&ofproto->cls, flow));
+    rule = rule_from_cls_rule(classifier_find_rule_exactly(&ofproto->cls,
+                                                           flow, wildcards,
+                                                           priority));
     if (rule) {
         classifier_remove(&ofproto->cls, &rule->cr);
         rule_destroy(rule);
index 1940f389f9bc01c86a5597d00c30865d34ae6e8b..50245a992a922bb317517eac4b8d31f54d612ed2 100644 (file)
@@ -94,12 +94,14 @@ void ofproto_get_listeners(const struct ofproto *, struct svec *);
 int ofproto_send_packet(struct ofproto *, const flow_t *,
                         const union ofp_action *, size_t n_actions,
                         const struct ofpbuf *);
-void ofproto_add_flow(struct ofproto *, const flow_t *,
+void ofproto_add_flow(struct ofproto *,
+                      const flow_t *, uint32_t wildcards, uint16_t priority,
                       const union ofp_action *, size_t n_actions,
                       const struct ofpbuf *, int idle_timeout);
 void ofproto_set_actions(struct ofproto *, const flow_t *,
                          const union ofp_action *, size_t n_actions);
-void ofproto_delete_flow(struct ofproto *, const flow_t *);
+void ofproto_delete_flow(struct ofproto *, const flow_t *, uint32_t wildcards,
+                         uint16_t priority);
 
 /* Hooks for vswitchd. */
 struct ofhooks {
index dfd9a7281f90c86acbe3ee41636c407bbaaf4101..2aac3126dec829bf8c696591d0bffe92dc638b56 100644 (file)
@@ -1448,7 +1448,8 @@ send_packets(struct bridge *br, const flow_t *flow,
             n_actions = abuf.size / sizeof(union ofp_action);
 
             if (command == ADD_FLOW) {
-                ofproto_add_flow(br->ofproto, &odp_flow, abuf.data, n_actions,
+                ofproto_add_flow(br->ofproto, &odp_flow, 0, UINT16_MAX,
+                                 abuf.data, n_actions,
                                  pkt, bridge_idle_time(br));
                 pkt = NULL;     /* Already sent. */
 
@@ -1527,8 +1528,8 @@ process_flow(struct bridge *br, const flow_t *flow, const struct ofpbuf *pkt)
              * awkward copy). */
             odp_flow = *flow;
             odp_flow.in_port = ofp_port_to_odp_port(odp_flow.in_port);
-            ofproto_add_flow(br->ofproto, &odp_flow, NULL, 0, NULL,
-                             bridge_idle_time(br));
+            ofproto_add_flow(br->ofproto, &odp_flow, 0, UINT16_MAX,
+                             NULL, 0, NULL, bridge_idle_time(br));
             if (f) {
                 ftf_set_dsts(f, NULL, 0);
                 f->tags = tags;
@@ -1554,7 +1555,7 @@ process_flow(struct bridge *br, const flow_t *flow, const struct ofpbuf *pkt)
              * awkward copy). */
             odp_flow = *flow;
             odp_flow.in_port = ofp_port_to_odp_port(odp_flow.in_port);
-            ofproto_delete_flow(br->ofproto, &odp_flow);
+            ofproto_delete_flow(br->ofproto, &odp_flow, 0, UINT16_MAX);
 
             /* ofproto_delete_flow() better not call back to
              * bridge_flow_expired_ofhook_cb(). */