tnl_neigh_snoop() is part of the translation. During translation we have to unwildcard all the fields we examine to make a decision.
tnl_arp_snoop() and tnl_nd_snoop() failed to unwildcard fileds in case of failure. The solution is to do unwildcarding before the field is inspected. Signed-off-by: Daniele Di Proietto <diproiet...@vmware.com> --- lib/flow.h | 7 +++++++ lib/tnl-neigh-cache.c | 22 ++++++++-------------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/lib/flow.h b/lib/flow.h index 5b83695..ea24e28 100644 --- a/lib/flow.h +++ b/lib/flow.h @@ -854,6 +854,13 @@ pkt_metadata_from_flow(struct pkt_metadata *md, const struct flow *flow) md->ct_label = flow->ct_label; } +/* Often, during translation we need to read a value from a flow('FLOW') and + * unwildcard the corresponding bits in the wildcards('WC'). This macro makes + * it easier to do that. */ + +#define FLOW_WC_GET_AND_MASK_WC(FLOW, WC, FIELD) \ + (((WC) ? WC_MASK_FIELD(WC, FIELD) : NULL), ((FLOW)->FIELD)) + static inline bool is_vlan(const struct flow *flow, struct flow_wildcards *wc) { diff --git a/lib/tnl-neigh-cache.c b/lib/tnl-neigh-cache.c index f7d29f6..499efff 100644 --- a/lib/tnl-neigh-cache.c +++ b/lib/tnl-neigh-cache.c @@ -115,7 +115,7 @@ tnl_neigh_delete(struct tnl_neigh_entry *neigh) static void tnl_neigh_set__(const char name[IFNAMSIZ], const struct in6_addr *dst, - const struct eth_addr mac) + const struct eth_addr mac) { ovs_mutex_lock(&mutex); struct tnl_neigh_entry *neigh = tnl_neigh_lookup__(name, dst); @@ -151,26 +151,21 @@ static int tnl_arp_snoop(const struct flow *flow, struct flow_wildcards *wc, const char name[IFNAMSIZ]) { - if (flow->dl_type != htons(ETH_TYPE_ARP) || - flow->nw_proto != ARP_OP_REPLY || - eth_addr_is_zero(flow->arp_sha)) { + if (flow->dl_type != htons(ETH_TYPE_ARP) + || FLOW_WC_GET_AND_MASK_WC(flow, wc, nw_proto) != ARP_OP_REPLY + || eth_addr_is_zero(FLOW_WC_GET_AND_MASK_WC(flow, wc, arp_sha))) { return EINVAL; } - /* Exact Match on all ARP flows. */ - memset(&wc->masks.nw_proto, 0xff, sizeof wc->masks.nw_proto); - memset(&wc->masks.nw_src, 0xff, sizeof wc->masks.nw_src); - memset(&wc->masks.arp_sha, 0xff, sizeof wc->masks.arp_sha); - - tnl_arp_set(name, flow->nw_src, flow->arp_sha); + tnl_arp_set(name, FLOW_WC_GET_AND_MASK_WC(flow, wc, nw_src), flow->arp_sha); return 0; } static int tnl_nd_snoop(const struct flow *flow, struct flow_wildcards *wc, - const char name[IFNAMSIZ]) + const char name[IFNAMSIZ]) { - if (!is_nd(flow, NULL) || flow->tp_src != htons(ND_NEIGHBOR_ADVERT)) { + if (!is_nd(flow, wc) || flow->tp_src != htons(ND_NEIGHBOR_ADVERT)) { return EINVAL; } /* - RFC4861 says Neighbor Advertisements sent in response to unicast Neighbor @@ -179,14 +174,13 @@ tnl_nd_snoop(const struct flow *flow, struct flow_wildcards *wc, * TLL address and other Advertisements not including it can be ignored. * - OVS flow extract can set this field to zero in case of packet parsing errors. * For details refer miniflow_extract()*/ - if (eth_addr_is_zero(flow->arp_tha)) { + if (eth_addr_is_zero(FLOW_WC_GET_AND_MASK_WC(flow, wc, arp_tha))) { return EINVAL; } memset(&wc->masks.ipv6_src, 0xff, sizeof wc->masks.ipv6_src); memset(&wc->masks.ipv6_dst, 0xff, sizeof wc->masks.ipv6_dst); memset(&wc->masks.nd_target, 0xff, sizeof wc->masks.nd_target); - memset(&wc->masks.arp_tha, 0xff, sizeof wc->masks.arp_tha); tnl_neigh_set__(name, &flow->nd_target, flow->arp_tha); return 0; -- 2.9.3 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev