From: Ben Pfaff Date: Sat, 17 May 2008 00:00:36 +0000 (-0700) Subject: Always do exact-match on undefined flow fields, so that such flows can be in table... X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=253d1704aa0f9db3bc0bb1d7a7cbecb5bd526228;p=openvswitch Always do exact-match on undefined flow fields, so that such flows can be in table-hash. --- diff --git a/datapath/flow.c b/datapath/flow.c index cdda24ba..8cf09a1b 100644 --- a/datapath/flow.c +++ b/datapath/flow.c @@ -73,26 +73,40 @@ void flow_extract_match(struct sw_flow_key* to, const struct ofp_match* from) memcpy(to->dl_dst, from->dl_dst, ETH_ALEN); to->dl_type = from->dl_type; - if (likely(from->dl_type == htons(ETH_P_IP))) { + to->nw_src = to->nw_dst = to->nw_proto = 0; + to->tp_src = to->tp_dst = 0; + +#define OFPFW_TP (OFPFW_TP_SRC | OFPFW_TP_DST) +#define OFPFW_NW (OFPFW_NW_SRC | OFPFW_NW_DST | OFPFW_NW_PROTO) + if (to->wildcards & OFPFW_DL_TYPE) { + /* Can't sensibly match on network or transport headers if the + * data link type is unknown. */ + to->wildcards |= OFPFW_NW | OFPFW_TP; + } else if (from->dl_type == htons(ETH_P_IP)) { to->nw_src = from->nw_src; to->nw_dst = from->nw_dst; to->nw_proto = from->nw_proto; - if ((from->nw_proto != IPPROTO_TCP && from->nw_proto != IPPROTO_UDP)) { - goto no_th; + if (to->wildcards & OFPFW_NW_PROTO) { + /* Can't sensibly match on transport headers if the + * network protocol is unknown. */ + to->wildcards |= OFPFW_TP; + } else if (from->nw_proto == IPPROTO_TCP + || from->nw_proto == IPPROTO_UDP) { + to->tp_src = from->tp_src; + to->tp_dst = from->tp_dst; + } else { + /* Transport layer fields are undefined. Mark them as + * exact-match to allow such flows to reside in + * table-hash, instead of falling into table-linear. */ + to->wildcards &= ~OFPFW_TP; } - to->tp_src = from->tp_src; - to->tp_dst = from->tp_dst; - return; + } else { + /* Network and transport layer fields are undefined. Mark them + * as exact-match to allow such flows to reside in table-hash, + * instead of falling into table-linear. */ + to->wildcards &= ~(OFPFW_NW | OFPFW_TP); } - - to->nw_src = 0; - to->nw_dst = 0; - to->nw_proto = 0; - -no_th: - to->tp_src = 0; - to->tp_dst = 0; } void flow_fill_match(struct ofp_match* to, const struct sw_flow_key* from) diff --git a/switch/switch-flow.c b/switch/switch-flow.c index 39df8622..4e5d2578 100644 --- a/switch/switch-flow.c +++ b/switch/switch-flow.c @@ -102,11 +102,19 @@ void flow_extract_match(struct sw_flow_key* to, const struct ofp_match* from) return; } + /* dl_type is not IPv4, so the network layer fields are undefined. We set + * them to zero and mark them as exact-match to allow such flows to reside + * in table-hash, instead of falling into table-linear. */ + to->wildcards &= ~(OFPFW_NW_SRC | OFPFW_NW_DST | OFPFW_NW_PROTO); to->flow.nw_src = 0; to->flow.nw_dst = 0; to->flow.nw_proto = 0; no_th: + /* nw_proto is not TCP or UDP, so the transport layer fields are undefined. + * We set them to zero and mark them as exact-match to allow such flows to + * reside in table-hash, instead of falling into table-linear. */ + to->wildcards &= ~(OFPFW_TP_SRC | OFPFW_TP_DST); to->flow.tp_src = 0; to->flow.tp_dst = 0; }