From cf3fad8a1b633c7c4231edda04b0e56e67df0d91 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Wed, 20 Oct 2010 16:46:48 -0700 Subject: [PATCH] ofproto: Change ofproto_add_flow(), ofproto_delete_flow() to take cls_rule. This is a small cleanup that will make later changes to wildcards easier. --- lib/classifier.c | 10 ++++++ lib/classifier.h | 1 + ofproto/fail-open.c | 15 ++++---- ofproto/in-band.c | 85 ++++++++++++++++++--------------------------- ofproto/ofproto.c | 12 +++---- ofproto/ofproto.h | 7 ++-- vswitchd/bridge.c | 7 ++-- 7 files changed, 64 insertions(+), 73 deletions(-) diff --git a/lib/classifier.c b/lib/classifier.c index 3e0e2150d..f3e34f2b7 100644 --- a/lib/classifier.c +++ b/lib/classifier.c @@ -134,6 +134,16 @@ cls_rule_from_match(const struct ofp_match *match, unsigned int priority, rule->priority = rule->wc.wildcards ? priority : UINT16_MAX; } +/* Initializes 'rule' as a "catch-all" rule that matches every packet, with + * priority 'priority'. */ +void +cls_rule_init_catchall(struct cls_rule *rule, unsigned int priority) +{ + memset(&rule->flow, 0, sizeof rule->flow); + flow_wildcards_init(&rule->wc, OVSFW_ALL); + rule->priority = priority; +} + /* For each bit or field wildcarded in 'rule', sets the corresponding bit or * field in 'flow' to all-0-bits. It is important to maintain this invariant * in a clr_rule that might be inserted into a classifier. diff --git a/lib/classifier.h b/lib/classifier.h index 64f5e31b8..f626970c7 100644 --- a/lib/classifier.h +++ b/lib/classifier.h @@ -77,6 +77,7 @@ void cls_rule_from_flow(const struct flow *, uint32_t wildcards, unsigned int priority, struct cls_rule *); void cls_rule_from_match(const struct ofp_match *, unsigned int priority, int flow_format, uint64_t cookie, struct cls_rule *); +void cls_rule_init_catchall(struct cls_rule *, unsigned int priority); void cls_rule_zero_wildcarded_fields(struct cls_rule *); diff --git a/ofproto/fail-open.c b/ofproto/fail-open.c index 95af14232..ba6dbcfa8 100644 --- a/ofproto/fail-open.c +++ b/ofproto/fail-open.c @@ -18,6 +18,7 @@ #include "fail-open.h" #include #include +#include "classifier.h" #include "flow.h" #include "mac-learning.h" #include "odp-util.h" @@ -257,14 +258,14 @@ static void fail_open_recover(struct fail_open *fo) { if (fail_open_is_active(fo)) { - struct flow flow; + struct cls_rule rule; VLOG_WARN("No longer in fail-open mode"); fo->last_disconn_secs = 0; fo->next_bogus_packet_in = LLONG_MAX; - memset(&flow, 0, sizeof flow); - ofproto_delete_flow(fo->ofproto, &flow, OVSFW_ALL, FAIL_OPEN_PRIORITY); + cls_rule_init_catchall(&rule, FAIL_OPEN_PRIORITY); + ofproto_delete_flow(fo->ofproto, &rule); } } @@ -283,7 +284,7 @@ fail_open_flushed(struct fail_open *fo) bool open = disconn_secs >= trigger_duration(fo); if (open) { union ofp_action action; - struct flow flow; + struct cls_rule rule; /* Set up a flow that matches every packet and directs them to * OFPP_NORMAL. */ @@ -291,9 +292,9 @@ fail_open_flushed(struct fail_open *fo) action.type = htons(OFPAT_OUTPUT); action.output.len = htons(sizeof action); action.output.port = htons(OFPP_NORMAL); - memset(&flow, 0, sizeof flow); - ofproto_add_flow(fo->ofproto, &flow, OVSFW_ALL, FAIL_OPEN_PRIORITY, - &action, 1, 0); + + cls_rule_init_catchall(&rule, FAIL_OPEN_PRIORITY); + ofproto_add_flow(fo->ofproto, &rule, &action, 1, 0); } } diff --git a/ofproto/in-band.c b/ofproto/in-band.c index efc9c8acc..8968cff59 100644 --- a/ofproto/in-band.c +++ b/ofproto/in-band.c @@ -23,6 +23,7 @@ #include #include #include +#include "classifier.h" #include "dhcp.h" #include "dpif.h" #include "flow.h" @@ -223,12 +224,6 @@ enum { IBR_FROM_REMOTE_TCP /* (i) From remote IP, TCP port. */ }; -struct in_band_rule { - struct flow flow; - uint32_t wildcards; - unsigned int priority; -}; - /* Track one remote IP and next hop information. */ struct in_band_remote { struct sockaddr_in remote_addr; /* IP address, in network byte order. */ @@ -459,88 +454,78 @@ in_band_rule_check(struct in_band *in_band, const struct flow *flow, } static void -init_rule(struct in_band_rule *rule, unsigned int priority) -{ - rule->wildcards = OVSFW_ALL; - rule->priority = priority; - - /* Not strictly necessary but seems cleaner. */ - memset(&rule->flow, 0, sizeof rule->flow); -} - -static void -set_in_port(struct in_band_rule *rule, uint16_t odp_port) +set_in_port(struct cls_rule *rule, uint16_t odp_port) { - rule->wildcards &= ~OFPFW_IN_PORT; + rule->wc.wildcards &= ~OFPFW_IN_PORT; rule->flow.in_port = odp_port; } static void -set_dl_type(struct in_band_rule *rule, uint16_t dl_type) +set_dl_type(struct cls_rule *rule, uint16_t dl_type) { - rule->wildcards &= ~OFPFW_DL_TYPE; + rule->wc.wildcards &= ~OFPFW_DL_TYPE; rule->flow.dl_type = dl_type; } static void -set_dl_src(struct in_band_rule *rule, const uint8_t dl_src[ETH_ADDR_LEN]) +set_dl_src(struct cls_rule *rule, const uint8_t dl_src[ETH_ADDR_LEN]) { - rule->wildcards &= ~OFPFW_DL_SRC; + rule->wc.wildcards &= ~OFPFW_DL_SRC; memcpy(rule->flow.dl_src, dl_src, ETH_ADDR_LEN); } static void -set_dl_dst(struct in_band_rule *rule, const uint8_t dl_dst[ETH_ADDR_LEN]) +set_dl_dst(struct cls_rule *rule, const uint8_t dl_dst[ETH_ADDR_LEN]) { - rule->wildcards &= ~OFPFW_DL_DST; + rule->wc.wildcards &= ~OFPFW_DL_DST; memcpy(rule->flow.dl_dst, dl_dst, ETH_ADDR_LEN); } static void -set_tp_src(struct in_band_rule *rule, uint16_t tp_src) +set_tp_src(struct cls_rule *rule, uint16_t tp_src) { - rule->wildcards &= ~OFPFW_TP_SRC; + rule->wc.wildcards &= ~OFPFW_TP_SRC; rule->flow.tp_src = tp_src; } static void -set_tp_dst(struct in_band_rule *rule, uint16_t tp_dst) +set_tp_dst(struct cls_rule *rule, uint16_t tp_dst) { - rule->wildcards &= ~OFPFW_TP_DST; + rule->wc.wildcards &= ~OFPFW_TP_DST; rule->flow.tp_dst = tp_dst; } static void -set_nw_proto(struct in_band_rule *rule, uint8_t nw_proto) +set_nw_proto(struct cls_rule *rule, uint8_t nw_proto) { - rule->wildcards &= ~OFPFW_NW_PROTO; + rule->wc.wildcards &= ~OFPFW_NW_PROTO; rule->flow.nw_proto = nw_proto; } static void -set_nw_src(struct in_band_rule *rule, const struct in_addr nw_src) +set_nw_src(struct cls_rule *rule, const struct in_addr nw_src) { - rule->wildcards &= ~OFPFW_NW_SRC_MASK; + rule->wc.wildcards &= ~OFPFW_NW_SRC_MASK; rule->flow.nw_src = nw_src.s_addr; } static void -set_nw_dst(struct in_band_rule *rule, const struct in_addr nw_dst) +set_nw_dst(struct cls_rule *rule, const struct in_addr nw_dst) { - rule->wildcards &= ~OFPFW_NW_DST_MASK; + rule->wc.wildcards &= ~OFPFW_NW_DST_MASK; rule->flow.nw_dst = nw_dst.s_addr; } static void make_rules(struct in_band *ib, - void (*cb)(struct in_band *, const struct in_band_rule *)) + void (*cb)(struct in_band *, const struct cls_rule *)) { - struct in_band_rule rule; + struct cls_rule rule; size_t i; if (!eth_addr_is_zero(ib->installed_local_mac)) { /* (a) Allow DHCP requests sent from the local port. */ - init_rule(&rule, IBR_FROM_LOCAL_DHCP); + cls_rule_init_catchall(&rule, IBR_FROM_LOCAL_DHCP); set_in_port(&rule, ODPP_LOCAL); set_dl_type(&rule, htons(ETH_TYPE_IP)); set_dl_src(&rule, ib->installed_local_mac); @@ -550,14 +535,14 @@ make_rules(struct in_band *ib, cb(ib, &rule); /* (b) Allow ARP replies to the local port's MAC address. */ - init_rule(&rule, IBR_TO_LOCAL_ARP); + cls_rule_init_catchall(&rule, IBR_TO_LOCAL_ARP); set_dl_type(&rule, htons(ETH_TYPE_ARP)); set_dl_dst(&rule, ib->installed_local_mac); set_nw_proto(&rule, ARP_OP_REPLY); cb(ib, &rule); /* (c) Allow ARP requests from the local port's MAC address. */ - init_rule(&rule, IBR_FROM_LOCAL_ARP); + cls_rule_init_catchall(&rule, IBR_FROM_LOCAL_ARP); set_dl_type(&rule, htons(ETH_TYPE_ARP)); set_dl_src(&rule, ib->installed_local_mac); set_nw_proto(&rule, ARP_OP_REQUEST); @@ -576,14 +561,14 @@ make_rules(struct in_band *ib, } /* (d) Allow ARP replies to the next hop's MAC address. */ - init_rule(&rule, IBR_TO_NEXT_HOP_ARP); + cls_rule_init_catchall(&rule, IBR_TO_NEXT_HOP_ARP); set_dl_type(&rule, htons(ETH_TYPE_ARP)); set_dl_dst(&rule, remote_mac); set_nw_proto(&rule, ARP_OP_REPLY); cb(ib, &rule); /* (e) Allow ARP requests from the next hop's MAC address. */ - init_rule(&rule, IBR_FROM_NEXT_HOP_ARP); + cls_rule_init_catchall(&rule, IBR_FROM_NEXT_HOP_ARP); set_dl_type(&rule, htons(ETH_TYPE_ARP)); set_dl_src(&rule, remote_mac); set_nw_proto(&rule, ARP_OP_REQUEST); @@ -596,7 +581,7 @@ make_rules(struct in_band *ib, if (!i || a->sin_addr.s_addr != a[-1].sin_addr.s_addr) { /* (f) Allow ARP replies containing the remote's IP address as a * target. */ - init_rule(&rule, IBR_TO_REMOTE_ARP); + cls_rule_init_catchall(&rule, IBR_TO_REMOTE_ARP); set_dl_type(&rule, htons(ETH_TYPE_ARP)); set_nw_proto(&rule, ARP_OP_REPLY); set_nw_dst(&rule, a->sin_addr); @@ -604,7 +589,7 @@ make_rules(struct in_band *ib, /* (g) Allow ARP requests containing the remote's IP address as a * source. */ - init_rule(&rule, IBR_FROM_REMOTE_ARP); + cls_rule_init_catchall(&rule, IBR_FROM_REMOTE_ARP); set_dl_type(&rule, htons(ETH_TYPE_ARP)); set_nw_proto(&rule, ARP_OP_REQUEST); set_nw_src(&rule, a->sin_addr); @@ -615,7 +600,7 @@ make_rules(struct in_band *ib, || a->sin_addr.s_addr != a[-1].sin_addr.s_addr || a->sin_port != a[-1].sin_port) { /* (h) Allow TCP traffic to the remote's IP and port. */ - init_rule(&rule, IBR_TO_REMOTE_TCP); + cls_rule_init_catchall(&rule, IBR_TO_REMOTE_TCP); set_dl_type(&rule, htons(ETH_TYPE_IP)); set_nw_proto(&rule, IP_TYPE_TCP); set_nw_dst(&rule, a->sin_addr); @@ -623,7 +608,7 @@ make_rules(struct in_band *ib, cb(ib, &rule); /* (i) Allow TCP traffic from the remote's IP and port. */ - init_rule(&rule, IBR_FROM_REMOTE_TCP); + cls_rule_init_catchall(&rule, IBR_FROM_REMOTE_TCP); set_dl_type(&rule, htons(ETH_TYPE_IP)); set_nw_proto(&rule, IP_TYPE_TCP); set_nw_src(&rule, a->sin_addr); @@ -634,10 +619,9 @@ make_rules(struct in_band *ib, } static void -drop_rule(struct in_band *ib, const struct in_band_rule *rule) +drop_rule(struct in_band *ib, const struct cls_rule *rule) { - ofproto_delete_flow(ib->ofproto, &rule->flow, - rule->wildcards, rule->priority); + ofproto_delete_flow(ib->ofproto, rule); } /* Drops from the flow table all of the flows set up by 'ib', then clears out @@ -662,7 +646,7 @@ drop_rules(struct in_band *ib) } static void -add_rule(struct in_band *ib, const struct in_band_rule *rule) +add_rule(struct in_band *ib, const struct cls_rule *rule) { union ofp_action action; @@ -670,8 +654,7 @@ add_rule(struct in_band *ib, const struct in_band_rule *rule) action.output.len = htons(sizeof action); action.output.port = htons(OFPP_NORMAL); action.output.max_len = htons(0); - ofproto_add_flow(ib->ofproto, &rule->flow, rule->wildcards, - rule->priority, &action, 1, 0); + ofproto_add_flow(ib->ofproto, rule, &action, 1, 0); } /* Inserts flows into the flow table for the current state of 'ib'. */ diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index 92c2e9ddf..9b63d0223 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -1298,8 +1298,7 @@ ofproto_send_packet(struct ofproto *p, const struct flow *flow, } void -ofproto_add_flow(struct ofproto *p, const struct flow *flow, - uint32_t wildcards, unsigned int priority, +ofproto_add_flow(struct ofproto *p, const struct cls_rule *cls_rule, const union ofp_action *actions, size_t n_actions, int idle_timeout) { @@ -1307,20 +1306,17 @@ ofproto_add_flow(struct ofproto *p, const struct flow *flow, rule = rule_create(p, NULL, actions, n_actions, idle_timeout >= 0 ? idle_timeout : 5 /* XXX */, 0, 0, false); - cls_rule_from_flow(flow, wildcards, priority, &rule->cr); + rule->cr = *cls_rule; rule_insert(p, rule, NULL, 0); } void -ofproto_delete_flow(struct ofproto *ofproto, const struct flow *flow, - uint32_t wildcards, unsigned int priority) +ofproto_delete_flow(struct ofproto *ofproto, const struct cls_rule *target) { - struct cls_rule target; struct rule *rule; - cls_rule_from_flow(flow, wildcards, priority, &target); rule = rule_from_cls_rule(classifier_find_rule_exactly(&ofproto->cls, - &target)); + target)); if (rule) { rule_remove(ofproto, rule); } diff --git a/ofproto/ofproto.h b/ofproto/ofproto.h index 362ea264b..a0a00f809 100644 --- a/ofproto/ofproto.h +++ b/ofproto/ofproto.h @@ -30,6 +30,7 @@ extern "C" { #endif +struct cls_rule; struct odp_actions; struct ofhooks; struct ofproto; @@ -126,12 +127,10 @@ void ofproto_get_all_flows(struct ofproto *p, struct ds *); int ofproto_send_packet(struct ofproto *, const struct flow *, const union ofp_action *, size_t n_actions, const struct ofpbuf *); -void ofproto_add_flow(struct ofproto *, const struct flow *, - uint32_t wildcards, unsigned int priority, +void ofproto_add_flow(struct ofproto *, const struct cls_rule *, const union ofp_action *, size_t n_actions, int idle_timeout); -void ofproto_delete_flow(struct ofproto *, const struct flow *, - uint32_t wildcards, unsigned int priority); +void ofproto_delete_flow(struct ofproto *, const struct cls_rule *); void ofproto_flush_flows(struct ofproto *); /* Hooks for ovs-vswitchd. */ diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index 5085703a3..808fc5867 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -32,6 +32,7 @@ #include #include #include "bitmap.h" +#include "classifier.h" #include "coverage.h" #include "dirs.h" #include "dpif.h" @@ -1792,14 +1793,14 @@ bridge_reconfigure_remotes(struct bridge *br, if (!n_controllers && ofproto_get_fail_mode(br->ofproto) == OFPROTO_FAIL_STANDALONE) { union ofp_action action; - struct flow flow; + struct cls_rule rule; memset(&action, 0, sizeof action); action.type = htons(OFPAT_OUTPUT); action.output.len = htons(sizeof action); action.output.port = htons(OFPP_NORMAL); - memset(&flow, 0, sizeof flow); - ofproto_add_flow(br->ofproto, &flow, OVSFW_ALL, 0, &action, 1, 0); + cls_rule_init_catchall(&rule, 0); + ofproto_add_flow(br->ofproto, &rule, &action, 1, 0); } } -- 2.43.0