From f2b788468a5133b7478924c7af3a47b2ab7f81c1 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Tue, 10 Mar 2009 10:44:23 -0700 Subject: [PATCH] secchan: Add wildcard support to ofproto_add_flow(), ofproto_delete_flow(). --- secchan/fail-open.c | 4 ++-- secchan/in-band.c | 4 ++-- secchan/ofproto.c | 40 ++++++++++++++++++++++++---------------- secchan/ofproto.h | 6 ++++-- vswitchd/bridge.c | 9 +++++---- 5 files changed, 37 insertions(+), 26 deletions(-) diff --git a/secchan/fail-open.c b/secchan/fail-open.c index 9f9718cb..f3053a8d 100644 --- a/secchan/fail-open.c +++ b/secchan/fail-open.c @@ -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. */ diff --git a/secchan/in-band.c b/secchan/in-band.c index 3f5db494..62fbef7e 100644 --- a/secchan/in-band.c +++ b/secchan/in-band.c @@ -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. */ diff --git a/secchan/ofproto.c b/secchan/ofproto.c index 019d51fb..f49ec56f 100644 --- a/secchan/ofproto.c +++ b/secchan/ofproto.c @@ -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); diff --git a/secchan/ofproto.h b/secchan/ofproto.h index 1940f389..50245a99 100644 --- a/secchan/ofproto.h +++ b/secchan/ofproto.h @@ -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 { diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index dfd9a728..2aac3126 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -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(). */ -- 2.30.2