From: Ben Pfaff Date: Mon, 9 May 2011 23:21:00 +0000 (-0700) Subject: nx-match: Check prerequisites for ICMPv6 before outputting subfields. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f740239011a9650ab4d63a336a4170e8f1983a63;p=openvswitch nx-match: Check prerequisites for ICMPv6 before outputting subfields. nicira-ext.h documents that NXM_NX_ND_TARGET requires ND_NEIGHBOR_SOLICIT or ND_NEIGHBOR_ADVERT, that NXM_NX_ND_SLL requires ND_NEIGHBOR_SOLICIT, and that NXM_NX_ND_TLL requires ND_NEIGHBOR_ADVERT, but nx_put_match() would add them to the match regardless of whether these prerequisites were satisfied. On the other side, nx_pull_match() did check the prerequisites, so this was a case where OVS could output flows that it would refused to parse. This fixes the problem. Found by inspection. --- diff --git a/lib/nx-match.c b/lib/nx-match.c index f5d62de2..4a41136e 100644 --- a/lib/nx-match.c +++ b/lib/nx-match.c @@ -833,20 +833,26 @@ nx_put_match(struct ofpbuf *b, const struct cls_rule *cr) case IPPROTO_ICMPV6: if (!(wc & FWW_TP_SRC)) { nxm_put_8(b, NXM_NX_ICMPV6_TYPE, ntohs(flow->tp_src)); + + if (flow->tp_src == htons(ND_NEIGHBOR_SOLICIT) || + flow->tp_src == htons(ND_NEIGHBOR_ADVERT)) { + if (!(wc & FWW_ND_TARGET)) { + nxm_put_ipv6(b, NXM_NX_ND_TARGET, &flow->nd_target, + &in6addr_exact); + } + if (!(wc & FWW_ARP_SHA) + && flow->tp_src == htons(ND_NEIGHBOR_SOLICIT)) { + nxm_put_eth(b, NXM_NX_ND_SLL, flow->arp_sha); + } + if (!(wc & FWW_ARP_THA) + && flow->tp_src == htons(ND_NEIGHBOR_ADVERT)) { + nxm_put_eth(b, NXM_NX_ND_TLL, flow->arp_tha); + } + } } if (!(wc & FWW_TP_DST)) { nxm_put_8(b, NXM_NX_ICMPV6_CODE, ntohs(flow->tp_dst)); } - if (!(wc & FWW_ND_TARGET)) { - nxm_put_ipv6(b, NXM_NX_ND_TARGET, &flow->nd_target, - &in6addr_exact); - } - if (!(wc & FWW_ARP_SHA)) { - nxm_put_eth(b, NXM_NX_ND_SLL, flow->arp_sha); - } - if (!(wc & FWW_ARP_THA)) { - nxm_put_eth(b, NXM_NX_ND_TLL, flow->arp_tha); - } break; } }