From: Jarno Rajahalme Date: Mon, 2 Jun 2014 21:02:19 +0000 (-0700) Subject: lib/flow: fix minimatch_extract() ICMPv6 parsing X-Git-Tag: v2.4.0~2059 X-Git-Url: http://git.cascardo.eti.br/?a=commitdiff_plain;h=b0e2ec321f384fb2ea4300529717a5cc09e0c096;p=cascardo%2Fovs.git lib/flow: fix minimatch_extract() ICMPv6 parsing This patch addresses two bugs related to ICMPv6(NDP) packets: - In miniflow_extract() push the words in the correct order - In parse_icmpv6() use sizeof struct, not size of struct * match_wc_init() has been modified, to include the nd_target field when the transport layer protocol is ICMPv6 A testcase has been added to detect the bugs. Signed-off-by: Daniele Di Proietto Acked-by: Jarno Rajahalme --- diff --git a/lib/flow.c b/lib/flow.c index da4f79ba2..76cef6646 100644 --- a/lib/flow.c +++ b/lib/flow.c @@ -277,7 +277,7 @@ parse_icmpv6(void **datap, size_t *sizep, const struct icmp6_hdr *icmp, (icmp->icmp6_type == ND_NEIGHBOR_SOLICIT || icmp->icmp6_type == ND_NEIGHBOR_ADVERT)) { - *nd_target = data_try_pull(datap, sizep, sizeof *nd_target); + *nd_target = data_try_pull(datap, sizep, sizeof **nd_target); if (OVS_UNLIKELY(!*nd_target)) { return false; } @@ -607,12 +607,12 @@ miniflow_extract(struct ofpbuf *packet, const struct pkt_metadata *md, memset(arp_buf, 0, sizeof arp_buf); if (OVS_LIKELY(parse_icmpv6(&data, &size, icmp, &nd_target, arp_buf))) { + miniflow_push_words(mf, arp_sha, arp_buf, + ETH_ADDR_LEN * 2 / 4); if (nd_target) { miniflow_push_words(mf, nd_target, nd_target, sizeof *nd_target / 4); } - miniflow_push_words(mf, arp_sha, arp_buf, - ETH_ADDR_LEN * 2 / 4); miniflow_push_be16(mf, tp_src, htons(icmp->icmp6_type)); miniflow_push_be16(mf, tp_dst, htons(icmp->icmp6_code)); } diff --git a/lib/match.c b/lib/match.c index 308f90627..93b725a8d 100644 --- a/lib/match.c +++ b/lib/match.c @@ -136,6 +136,7 @@ match_wc_init(struct match *match, const struct flow *flow) if (flow->nw_proto == IPPROTO_ICMPV6) { memset(&wc->masks.arp_sha, 0xff, sizeof wc->masks.arp_sha); memset(&wc->masks.arp_tha, 0xff, sizeof wc->masks.arp_tha); + memset(&wc->masks.nd_target, 0xff, sizeof wc->masks.nd_target); } } diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at index c12a7ffb7..c14d671ed 100644 --- a/tests/ofproto-dpif.at +++ b/tests/ofproto-dpif.at @@ -4820,3 +4820,23 @@ AT_CHECK([ovs-ofctl -O OpenFlow13 dump-tables br0 ], [0], [expout]) OVS_VSWITCHD_STOP AT_CLEANUP + +AT_SETUP([ofproto-dpif - ICMPv6]) +OVS_VSWITCHD_START +ADD_OF_PORTS([br0], 1) + +AT_CAPTURE_FILE([ofctl_monitor.log]) + +AT_CHECK([ovs-ofctl monitor br0 65534 --detach --no-chdir --pidfile 2> ofctl_monitor.log]) + +ovs-appctl netdev-dummy/receive p1 '0060970769ea0000860580da86dd6000000000203afffe80000000000000020086fffe0580dafe80000000000000026097fffe0769ea870068bd00000000fe80000000000000026097fffe0769ea01010000860580da' + +OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit]) + +AT_CHECK([cat ofctl_monitor.log], [0], [dnl +NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=86 in_port=1 (via no_match) data_len=86 (unbuffered) +icmp6,metadata=0,in_port=0,vlan_tci=0x0000,dl_src=00:00:86:05:80:da,dl_dst=00:60:97:07:69:ea,ipv6_src=fe80::200:86ff:fe05:80da,ipv6_dst=fe80::260:97ff:fe07:69ea,ipv6_label=0x00000,nw_tos=0,nw_ecn=0,nw_ttl=255,icmp_type=135,icmp_code=0,nd_target=fe80::260:97ff:fe07:69ea,nd_sll=00:00:86:05:80:da,nd_tll=00:00:00:00:00:00 +]) + +OVS_VSWITCHD_STOP +AT_CLEANUP