From b63f2ea79417e93390eaa86f68e546242e15a9ec Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Mon, 8 Nov 2010 10:37:35 -0800 Subject: [PATCH] flow: Better abstract flow_wildcards and use it more widely. --- lib/classifier.c | 32 +++++++++++++++++--------------- lib/classifier.h | 6 ++++-- lib/flow.c | 19 +++++++++---------- lib/flow.h | 3 ++- ofproto/ofproto.c | 7 ++++--- tests/test-classifier.c | 6 ++++-- 6 files changed, 40 insertions(+), 33 deletions(-) diff --git a/lib/classifier.c b/lib/classifier.c index e98e7fb8e..85c3c45af 100644 --- a/lib/classifier.c +++ b/lib/classifier.c @@ -99,22 +99,27 @@ cls_table_next_rule(const struct cls_table *table, const struct cls_rule *rule) &next->hmap_node))); } -static void -cls_rule_init__(struct cls_rule *rule, - const struct flow *flow, uint32_t wildcards) +/* Converts the flow in 'flow' into a cls_rule in 'rule', with the given + * 'wildcards' and 'priority'. */ +void +cls_rule_init(const struct flow *flow, const struct flow_wildcards *wildcards, + unsigned int priority, struct cls_rule *rule) { rule->flow = *flow; - flow_wildcards_init(&rule->wc, wildcards); + rule->wc = *wildcards; + rule->priority = priority; cls_rule_zero_wildcarded_fields(rule); } -/* Converts the flow in 'flow' into a cls_rule in 'rule', with the given - * 'wildcards' and 'priority'.*/ +/* Converts the flow in 'flow' into an exact-match cls_rule in 'rule', with the + * given 'priority'. (For OpenFlow 1.0, exact-match rule are always highest + * priority, so 'priority' should be at least 65535.) */ void -cls_rule_from_flow(const struct flow *flow, uint32_t wildcards, - unsigned int priority, struct cls_rule *rule) +cls_rule_init_exact(const struct flow *flow, + unsigned int priority, struct cls_rule *rule) { - cls_rule_init__(rule, flow, wildcards); + rule->flow = *flow; + flow_wildcards_init_exact(&rule->wc); rule->priority = priority; } @@ -126,12 +131,9 @@ cls_rule_from_match(const struct ofp_match *match, unsigned int priority, int flow_format, uint64_t cookie, struct cls_rule *rule) { - uint32_t wildcards; - struct flow flow; - - flow_from_match(match, flow_format, cookie, &flow, &wildcards); - cls_rule_init__(rule, &flow, wildcards); - rule->priority = rule->wc.wildcards ? priority : UINT16_MAX; + flow_from_match(match, flow_format, cookie, &rule->flow, &rule->wc); + rule->priority = !rule->wc.wildcards ? UINT16_MAX : priority; + cls_rule_zero_wildcarded_fields(rule); } /* Initializes 'rule' as a "catch-all" rule that matches every packet, with diff --git a/lib/classifier.h b/lib/classifier.h index 5de2b32d2..0d95a2ea4 100644 --- a/lib/classifier.h +++ b/lib/classifier.h @@ -73,8 +73,10 @@ enum { CLS_INC_ALL = CLS_INC_EXACT | CLS_INC_WILD }; -void cls_rule_from_flow(const struct flow *, uint32_t wildcards, - unsigned int priority, struct cls_rule *); +void cls_rule_init(const struct flow *, const struct flow_wildcards *, + unsigned int priority, struct cls_rule *); +void cls_rule_init_exact(const struct flow *, 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); diff --git a/lib/flow.c b/lib/flow.c index 678ae4309..c85219e59 100644 --- a/lib/flow.c +++ b/lib/flow.c @@ -279,18 +279,20 @@ flow_to_match(const struct flow *flow, uint32_t wildcards, void flow_from_match(const struct ofp_match *match, int flow_format, - ovs_be64 cookie, struct flow *flow, uint32_t *flow_wildcards) + ovs_be64 cookie, struct flow *flow, + struct flow_wildcards *wc) { - uint32_t wildcards = ntohl(match->wildcards); - - flow->nw_src = match->nw_src; - flow->nw_dst = match->nw_dst; - if (flow_format == NXFF_TUN_ID_FROM_COOKIE && !(wildcards & NXFW_TUN_ID)) { + flow_wildcards_init(wc, ntohl(match->wildcards)); + if (flow_format == NXFF_TUN_ID_FROM_COOKIE + && !(wc->wildcards & NXFW_TUN_ID)) { flow->tun_id = htonl(ntohll(cookie) >> 32); } else { - wildcards |= NXFW_TUN_ID; + wc->wildcards |= NXFW_TUN_ID; flow->tun_id = 0; } + + flow->nw_src = match->nw_src; + flow->nw_dst = match->nw_dst; flow->in_port = (match->in_port == htons(OFPP_LOCAL) ? ODPP_LOCAL : ntohs(match->in_port)); flow->dl_vlan = match->dl_vlan; @@ -302,9 +304,6 @@ flow_from_match(const struct ofp_match *match, int flow_format, memcpy(flow->dl_dst, match->dl_dst, ETH_ADDR_LEN); flow->nw_tos = match->nw_tos; flow->nw_proto = match->nw_proto; - if (flow_wildcards) { - *flow_wildcards = wildcards; - } } char * diff --git a/lib/flow.h b/lib/flow.h index a154df2b9..7a1084af1 100644 --- a/lib/flow.h +++ b/lib/flow.h @@ -28,6 +28,7 @@ #include "util.h" struct ds; +struct flow_wildcards; struct ofp_match; struct ofpbuf; @@ -62,7 +63,7 @@ void flow_extract_stats(const struct flow *flow, struct ofpbuf *packet, void flow_to_match(const struct flow *, uint32_t wildcards, int flow_format, struct ofp_match *); void flow_from_match(const struct ofp_match *, int flow_format, - ovs_be64 cookie, struct flow *, uint32_t *wildcards); + ovs_be64 cookie, struct flow *, struct flow_wildcards *); char *flow_to_string(const struct flow *); void flow_format(struct ds *, const struct flow *); void flow_print(FILE *, const struct flow *); diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index 9b63d0223..e53835e1a 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -2053,8 +2053,9 @@ rule_create_subrule(struct ofproto *ofproto, struct rule *rule, rule->idle_timeout, rule->hard_timeout, 0, false); COVERAGE_INC(ofproto_subrule_create); - cls_rule_from_flow(flow, 0, (rule->cr.priority <= UINT16_MAX ? UINT16_MAX - : rule->cr.priority), &subrule->cr); + cls_rule_init_exact(flow, (rule->cr.priority <= UINT16_MAX ? UINT16_MAX + : rule->cr.priority), + &subrule->cr); if (classifier_insert(&ofproto->cls, &subrule->cr)) { /* Can't happen, */ @@ -4270,7 +4271,7 @@ ofproto_update_used(struct ofproto *p) struct flow flow; odp_flow_key_to_flow(&f->key, &flow); - cls_rule_from_flow(&flow, 0, UINT16_MAX, &target); + cls_rule_init_exact(&flow, UINT16_MAX, &target); rule = rule_from_cls_rule(classifier_find_rule_exactly(&p->cls, &target)); diff --git a/tests/test-classifier.c b/tests/test-classifier.c index 70af7ed05..6c296ecce 100644 --- a/tests/test-classifier.c +++ b/tests/test-classifier.c @@ -477,6 +477,7 @@ static struct test_rule * make_rule(int wc_fields, unsigned int priority, int value_pat) { const struct cls_field *f; + struct flow_wildcards wc; struct test_rule *rule; uint32_t wildcards; struct flow flow; @@ -494,8 +495,9 @@ make_rule(int wc_fields, unsigned int priority, int value_pat) } rule = xzalloc(sizeof *rule); - cls_rule_from_flow(&flow, wildcards, !wildcards ? UINT_MAX : priority, - &rule->cls_rule); + flow_wildcards_init(&wc, wildcards); + cls_rule_init(&flow, &wc, !wildcards ? UINT_MAX : priority, + &rule->cls_rule); return rule; } -- 2.20.1