From: Ben Pfaff Date: Mon, 2 Mar 2009 19:12:33 +0000 (-0800) Subject: vconn: New function normalize_match(). X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=30320797d3daba80570ac91fe22d09a35aa5a958;p=openvswitch vconn: New function normalize_match(). --- diff --git a/lib/vconn.c b/lib/vconn.c index cf527ddf..f43b35f1 100644 --- a/lib/vconn.c +++ b/lib/vconn.c @@ -1346,6 +1346,67 @@ actions_next(struct actions_iterator *iter) } } +void +normalize_match(struct ofp_match *m) +{ + enum { OFPFW_NW = OFPFW_NW_SRC_MASK | OFPFW_NW_DST_MASK | OFPFW_NW_PROTO }; + enum { OFPFW_TP = OFPFW_TP_SRC | OFPFW_TP_DST }; + uint32_t wc; + + wc = ntohl(m->wildcards) & OFPFW_ALL; + if (wc & OFPFW_DL_TYPE) { + m->dl_type = 0; + + /* Can't sensibly m on network or transport headers if the + * data link type is unknown. */ + wc |= OFPFW_NW | OFPFW_TP; + m->nw_src = m->nw_dst = m->nw_proto = 0; + m->tp_src = m->tp_dst = 0; + } else if (m->dl_type == htons(ETH_TYPE_IP)) { + if (wc & OFPFW_NW_PROTO) { + m->nw_proto = 0; + + /* Can't sensibly m on transport headers if the network + * protocol is unknown. */ + wc |= OFPFW_TP; + m->tp_src = m->tp_dst = 0; + } else if (m->nw_proto == IPPROTO_TCP || + m->nw_proto == IPPROTO_UDP || + m->nw_proto == IPPROTO_ICMP) { + if (wc & OFPFW_TP_SRC) { + m->tp_src = 0; + } + if (wc & OFPFW_TP_DST) { + m->tp_dst = 0; + } + } else { + /* Transport layer fields will always be extracted as zeros, so we + * can do an exact-m on those values. */ + wc &= ~OFPFW_TP; + m->tp_src = m->tp_dst = 0; + } + if (wc & OFPFW_NW_SRC_MASK) { + m->nw_src &= flow_nw_bits_to_mask(wc, OFPFW_NW_SRC_SHIFT); + } + if (wc & OFPFW_NW_DST_MASK) { + m->nw_dst &= flow_nw_bits_to_mask(wc, OFPFW_NW_DST_SHIFT); + } + } else { + /* Network and transport layer fields will always be extracted as + * zeros, so we can do an exact-m on those values. */ + wc &= ~(OFPFW_NW | OFPFW_TP); + m->nw_proto = m->nw_src = m->nw_dst = 0; + m->tp_src = m->tp_dst = 0; + } + if (wc & OFPFW_DL_SRC) { + memset(m->dl_src, 0, sizeof m->dl_src); + } + if (wc & OFPFW_DL_DST) { + memset(m->dl_dst, 0, sizeof m->dl_dst); + } + m->wildcards = htonl(wc); +} + void vconn_init(struct vconn *vconn, struct vconn_class *class, int connect_status, uint32_t ip, const char *name, bool reconnectable) diff --git a/lib/vconn.h b/lib/vconn.h index 3c7a9a4a..41d60c69 100644 --- a/lib/vconn.h +++ b/lib/vconn.h @@ -43,6 +43,7 @@ struct ofpbuf; struct flow; struct ofp_action_header; struct ofp_header; +struct ofp_match; struct ofp_stats_reply; struct pvconn; struct vconn; @@ -130,6 +131,8 @@ const union ofp_action *actions_first(struct actions_iterator *, const union ofp_action *actions_next(struct actions_iterator *); int validate_actions(const union ofp_action *, size_t n_actions); +void normalize_match(struct ofp_match *); + static inline int ofp_mkerr(uint16_t type, uint16_t code) {