From: Justin Pettit Date: Fri, 9 May 2008 18:22:45 +0000 (-0700) Subject: Zero-out invalid fields when extracting a "match" and transforming it into a "flow". X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3cf996b4cd967386960fbde9ad50e43a71a37cd9;p=openvswitch Zero-out invalid fields when extracting a "match" and transforming it into a "flow". When the controller wishes to add a flow entry to the switch, it sends a request with a description of matching flows in a "match". The switch was adding these exactly as described into the flow tables. However, when packets arrived, all invalid fields (e.g., the TCP/UDP ports in a non-TCP/UDP packet) are set to zero. If the rule being added by the controller had not set these invalid fields to zero, the packets would never match. We now zero out these fields when extracing a "match". -- Reported by Brandon H. -- --- diff --git a/datapath/flow.c b/datapath/flow.c index a755947b..d207bfa3 100644 --- a/datapath/flow.c +++ b/datapath/flow.c @@ -67,17 +67,38 @@ int flow_del_matches(const struct sw_flow_key *t, const struct sw_flow_key *d, i void flow_extract_match(struct sw_flow_key* to, const struct ofp_match* from) { to->wildcards = ntohs(from->wildcards) & OFPFW_ALL; - to->in_port = from->in_port; - to->dl_vlan = from->dl_vlan; + memset(to->pad, '\0', sizeof(to->pad)); + to->in_port = from->in_port; + to->dl_vlan = from->dl_vlan; memcpy(to->dl_src, from->dl_src, ETH_ALEN); memcpy(to->dl_dst, from->dl_dst, ETH_ALEN); - to->dl_type = from->dl_type; - to->nw_src = from->nw_src; - to->nw_dst = from->nw_dst; - to->nw_proto = from->nw_proto; - to->tp_src = from->tp_src; - to->tp_dst = from->tp_dst; - memset(to->pad, '\0', sizeof(to->pad)); + to->dl_type = from->dl_type; + + if (likely(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; + } + to->tp_src = from->tp_src; + to->tp_dst = from->tp_dst; + return; + } else if (from->dl_type == htons(ETH_P_ARP)) { + to->nw_src = from->nw_src; + to->nw_dst = from->nw_dst; + to->nw_proto = 0; + goto no_th; + } + + 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 e146dbbb..5a353351 100644 --- a/switch/switch-flow.c +++ b/switch/switch-flow.c @@ -81,17 +81,39 @@ int flow_del_matches(const struct sw_flow_key *t, const struct sw_flow_key *d, i void flow_extract_match(struct sw_flow_key* to, const struct ofp_match* from) { to->wildcards = ntohs(from->wildcards) & OFPFW_ALL; - to->flow.in_port = from->in_port; - to->flow.dl_vlan = from->dl_vlan; + to->flow.reserved = 0; + to->flow.in_port = from->in_port; + to->flow.dl_vlan = from->dl_vlan; memcpy(to->flow.dl_src, from->dl_src, ETH_ADDR_LEN); memcpy(to->flow.dl_dst, from->dl_dst, ETH_ADDR_LEN); - to->flow.dl_type = from->dl_type; - to->flow.nw_src = from->nw_src; - to->flow.nw_dst = from->nw_dst; - to->flow.nw_proto = from->nw_proto; - to->flow.tp_src = from->tp_src; - to->flow.tp_dst = from->tp_dst; - to->flow.reserved = 0; + to->flow.dl_type = from->dl_type; + + + if (from->dl_type == htons(ETH_TYPE_IP)) { + to->flow.nw_src = from->nw_src; + to->flow.nw_dst = from->nw_dst; + to->flow.nw_proto = from->nw_proto; + + if ((from->nw_proto != IPPROTO_TCP && from->nw_proto != IPPROTO_UDP)) { + goto no_th; + } + to->flow.tp_src = from->tp_src; + to->flow.tp_dst = from->tp_dst; + return; + } else if (from->dl_type == htons(ETH_TYPE_ARP)) { + to->flow.nw_src = from->nw_src; + to->flow.nw_dst = from->nw_dst; + to->flow.nw_proto = 0; + goto no_th; + } + + to->flow.nw_src = 0; + to->flow.nw_dst = 0; + to->flow.nw_proto = 0; + +no_th: + to->flow.tp_src = 0; + to->flow.tp_dst = 0; } void flow_fill_match(struct ofp_match* to, const struct sw_flow_key* from)