Move tunnel neigh snooping from do_xlate_actions() to terminate_native_tunnel() in order to keep ARP neighbor cache clean. Furthermore filter ARP reply and Neighbor Advertisement messages addressing tunnel endpoint.
Signed-off-by: Zoltan Balogh <[email protected]> --- include/sparse/netinet/in.h | 10 +++ lib/tnl-neigh-cache.c | 1 + ofproto/ofproto-dpif-xlate.c | 143 +++++++++++++++++++++++++++++++++++++++--- tests/tunnel-push-pop-ipv6.at | 68 +++++++++++++++++++- tests/tunnel-push-pop.at | 67 +++++++++++++++++++- 5 files changed, 279 insertions(+), 10 deletions(-) diff --git a/include/sparse/netinet/in.h b/include/sparse/netinet/in.h index c28158ca0..c90a9dcef 100644 --- a/include/sparse/netinet/in.h +++ b/include/sparse/netinet/in.h @@ -117,6 +117,16 @@ struct sockaddr_in6 { (X)->s6_addr[10] == 0xff && \ (X)->s6_addr[11] == 0xff) +#define IN6_IS_ADDR_MC_LINKLOCAL(a) \ + (((const uint8_t *) (a))[0] == 0xff && \ + (((const uint8_t *) (a))[1] & 0xf) == 0x2) + +# define IN6_ARE_ADDR_EQUAL(a,b) \ + ((((const uint32_t *) (a))[0] == ((const uint32_t *) (b))[0]) && \ + (((const uint32_t *) (a))[1] == ((const uint32_t *) (b))[1]) && \ + (((const uint32_t *) (a))[2] == ((const uint32_t *) (b))[2]) && \ + (((const uint32_t *) (a))[3] == ((const uint32_t *) (b))[3])) + #define INET_ADDRSTRLEN 16 #define INET6_ADDRSTRLEN 46 diff --git a/lib/tnl-neigh-cache.c b/lib/tnl-neigh-cache.c index 5ddd53976..5b32efb6b 100644 --- a/lib/tnl-neigh-cache.c +++ b/lib/tnl-neigh-cache.c @@ -42,6 +42,7 @@ #include "unixctl.h" #include "util.h" #include "openvswitch/vlog.h" +#include "odp-util.h" /* In seconds */ diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c index 9be0bbd84..ed741815f 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -89,6 +89,12 @@ VLOG_DEFINE_THIS_MODULE(ofproto_dpif_xlate); * recursive or not. */ #define MAX_RESUBMITS (MAX_DEPTH * MAX_DEPTH) +struct xbridge_addr { + struct in6_addr *addr; /* Array of IP addresses of xbridge. */ + int n_addr; /* Number of IP addresses. */ + struct ovs_refcount ref_cnt; +}; + struct xbridge { struct hmap_node hmap_node; /* Node in global 'xbridges' map. */ struct ofproto_dpif *ofproto; /* Key in global 'xbridges' map. */ @@ -112,6 +118,8 @@ struct xbridge { /* Datapath feature support. */ struct dpif_backer_support support; + + struct xbridge_addr *addr; }; struct xbundle { @@ -575,7 +583,8 @@ static void xlate_xbridge_set(struct xbridge *, struct dpif *, const struct dpif_ipfix *, const struct netflow *, bool forward_bpdu, bool has_in_band, - const struct dpif_backer_support *); + const struct dpif_backer_support *, + const struct xbridge_addr *); static void xlate_xbundle_set(struct xbundle *xbundle, enum port_vlan_mode vlan_mode, uint16_t qinq_ethtype, int vlan, @@ -825,6 +834,56 @@ xlate_xport_init(struct xlate_cfg *xcfg, struct xport *xport) hash_ofp_port(xport->ofp_port)); } +static struct xbridge_addr * +xbridge_addr_create(struct xbridge *xbridge) +{ + struct xbridge_addr *xbridge_addr = xbridge->addr; + struct in6_addr *addr = NULL, *mask = NULL; + struct netdev *dev; + int err, n_addr = 0; + + err = netdev_open(xbridge->name, NULL, &dev); + if (!err) { + err = netdev_get_addr_list(dev, &addr, &mask, &n_addr); + if (!err) { + if (!xbridge->addr || + n_addr != xbridge->addr->n_addr || + (xbridge->addr->addr && memcmp(addr, xbridge->addr->addr, + sizeof(*addr) * n_addr))) { + xbridge_addr = xzalloc(sizeof *xbridge_addr); + xbridge_addr->addr = addr; + xbridge_addr->n_addr = n_addr; + ovs_refcount_init(&xbridge_addr->ref_cnt); + } else { + free(addr); + } + free(mask); + } + netdev_close(dev); + } + + return xbridge_addr; +} + +static struct xbridge_addr * +xbridge_addr_ref(const struct xbridge_addr *addr_) +{ + struct xbridge_addr *addr = CONST_CAST(struct xbridge_addr *, addr_); + if (addr) { + ovs_refcount_ref(&addr->ref_cnt); + } + return addr; +} + +static void +xbridge_addr_unref(struct xbridge_addr *addr) +{ + if (addr && ovs_refcount_unref_relaxed(&addr->ref_cnt) == 1) { + free(addr->addr); + free(addr); + } +} + static void xlate_xbridge_set(struct xbridge *xbridge, struct dpif *dpif, @@ -835,7 +894,8 @@ xlate_xbridge_set(struct xbridge *xbridge, const struct dpif_ipfix *ipfix, const struct netflow *netflow, bool forward_bpdu, bool has_in_band, - const struct dpif_backer_support *support) + const struct dpif_backer_support *support, + const struct xbridge_addr *addr) { if (xbridge->ml != ml) { mac_learning_unref(xbridge->ml); @@ -877,6 +937,11 @@ xlate_xbridge_set(struct xbridge *xbridge, xbridge->netflow = netflow_ref(netflow); } + if (xbridge->addr != addr) { + xbridge_addr_unref(xbridge->addr); + xbridge->addr = xbridge_addr_ref(addr); + } + xbridge->dpif = dpif; xbridge->forward_bpdu = forward_bpdu; xbridge->has_in_band = has_in_band; @@ -970,7 +1035,7 @@ xlate_xbridge_copy(struct xbridge *xbridge) xbridge->rstp, xbridge->ms, xbridge->mbridge, xbridge->sflow, xbridge->ipfix, xbridge->netflow, xbridge->forward_bpdu, xbridge->has_in_band, - &xbridge->support); + &xbridge->support, xbridge->addr); LIST_FOR_EACH (xbundle, list_node, &xbridge->xbundles) { xlate_xbundle_copy(new_xbridge, xbundle); } @@ -1125,6 +1190,7 @@ xlate_ofproto_set(struct ofproto_dpif *ofproto, const char *name, const struct dpif_backer_support *support) { struct xbridge *xbridge; + struct xbridge_addr *xbridge_addr, *old_addr; ovs_assert(new_xcfg); @@ -1139,8 +1205,16 @@ xlate_ofproto_set(struct ofproto_dpif *ofproto, const char *name, free(xbridge->name); xbridge->name = xstrdup(name); + xbridge_addr = xbridge_addr_create(xbridge); + old_addr = xbridge->addr; + xlate_xbridge_set(xbridge, dpif, ml, stp, rstp, ms, mbridge, sflow, ipfix, - netflow, forward_bpdu, has_in_band, support); + netflow, forward_bpdu, has_in_band, support, + xbridge_addr); + + if (xbridge_addr != old_addr) { + xbridge_addr_unref(xbridge_addr); + } } static void @@ -1170,6 +1244,7 @@ xlate_xbridge_remove(struct xlate_cfg *xcfg, struct xbridge *xbridge) netflow_unref(xbridge->netflow); stp_unref(xbridge->stp); rstp_unref(xbridge->rstp); + xbridge_addr_unref(xbridge->addr); hmap_destroy(&xbridge->xports); free(xbridge->name); free(xbridge); @@ -3654,6 +3729,54 @@ check_output_prerequisites(struct xlate_ctx *ctx, return true; } +/* Function verifies if destination address of received Neighbor Advertisement + * message stored in 'flow' is correct. It should be either FF02::1:FFXX:XXXX + * where XX:XXXX stands for the last 24 bits of 'ipv6_addr' or it should match + * 'ipv6_addr'. */ +static bool +is_nd_dst_correct(const struct flow *flow, const struct in6_addr *ipv6_addr) +{ + const uint8_t *flow_ipv6_addr = (uint8_t *) & flow->ipv6_dst; + const uint8_t *addr = (uint8_t *) ipv6_addr; + + return (IN6_IS_ADDR_MC_LINKLOCAL(flow_ipv6_addr) && + flow_ipv6_addr[11] == 0x01 && + flow_ipv6_addr[12] == 0xff && + flow_ipv6_addr[13] == addr[13] && + flow_ipv6_addr[14] == addr[14] && + flow_ipv6_addr[15] == addr[15]) || + IN6_ARE_ADDR_EQUAL(flow_ipv6_addr, addr); +} + +/* Function verifies if the ARP reply or Neighbor Advertisement represented by + * 'flow' addresses the 'xbridge' of 'ctx'. Returns true if the ARP TA or + * neighbor discovery destination is in the list of configured IP addresses of + * the bridge. Otherwise, it returns false. */ +static bool +is_neighbor_reply_correct(const struct xlate_ctx *ctx, const struct flow *flow) +{ + bool ret = false; + int i; + struct xbridge_addr *xbridge_addr = xbridge_addr_ref(ctx->xbridge->addr); + + /* Verify if 'nw_dst' of ARP or 'ipv6_dst' of ICMPV6 is in the list. */ + for (i = 0; xbridge_addr && i < xbridge_addr->n_addr; i++) { + struct in6_addr *ip_addr = &xbridge_addr->addr[i]; + if ((IN6_IS_ADDR_V4MAPPED(ip_addr) && + flow->dl_type == htons(ETH_TYPE_ARP) && + in6_addr_get_mapped_ipv4(ip_addr) == flow->nw_dst) || + (!IN6_IS_ADDR_V4MAPPED(ip_addr) && + is_nd_dst_correct(flow, ip_addr))) { + /* Found a match. */ + ret = true; + break; + } + } + + xbridge_addr_unref(xbridge_addr); + return ret; +} + static bool terminate_native_tunnel(struct xlate_ctx *ctx, ofp_port_t ofp_port, struct flow *flow, struct flow_wildcards *wc, @@ -3666,6 +3789,15 @@ terminate_native_tunnel(struct xlate_ctx *ctx, ofp_port_t ofp_port, if (ofp_port == OFPP_LOCAL && ovs_native_tunneling_is_on(ctx->xbridge->ofproto)) { *tnl_port = tnl_port_map_lookup(flow, wc); + + /* If no tunnel port was found and it's about an ARP or ICMPv6 packet, + * do tunnel neighbor snooping. */ + if (*tnl_port == ODPP_NONE && + (flow->dl_type == htons(ETH_TYPE_ARP) || + flow->nw_proto == IPPROTO_ICMPV6) && + is_neighbor_reply_correct(ctx, flow)) { + tnl_neigh_snoop(flow, wc, ctx->xbridge->name); + } } return *tnl_port != ODPP_NONE; @@ -6182,9 +6314,6 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, struct flow *flow = &ctx->xin->flow; const struct ofpact *a; - if (ovs_native_tunneling_is_on(ctx->xbridge->ofproto)) { - tnl_neigh_snoop(flow, wc, ctx->xbridge->name); - } /* dl_type already in the mask, not set below. */ if (!ofpacts_len) { diff --git a/tests/tunnel-push-pop-ipv6.at b/tests/tunnel-push-pop-ipv6.at index 0b9d436db..b0f4a7e91 100644 --- a/tests/tunnel-push-pop-ipv6.at +++ b/tests/tunnel-push-pop-ipv6.at @@ -55,9 +55,73 @@ AT_CHECK([cat p0.pcap.txt | grep 93aa55aa55000086dd6000000000203aff2001cafe | un ]) dnl Check ARP Snoop -AT_CHECK([ovs-appctl netdev-dummy/receive p0 'in_port(1),eth(src=f8:bc:12:44:34:b6,dst=aa:55:aa:55:00:00),eth_type(0x86dd),ipv6(src=2001:cafe::92,dst=2001:cafe::94,label=0,proto=58,tclass=0,hlimit=255,frag=no),icmpv6(type=136,code=0),nd(target=2001:cafe::92,sll=00:00:00:00:00:00,tll=f8:bc:12:44:34:b6)']) +AT_CHECK([ovs-appctl netdev-dummy/receive p0 'in_port(1),eth(src=f8:bc:12:44:34:c8,dst=aa:55:aa:55:00:00),eth_type(0x86dd),ipv6(src=2001:cafe::92,dst=2001:cafe::88,label=0,proto=58,tclass=0,hlimit=255,frag=no),icmpv6(type=136,code=0),nd(target=2001:cafe::92,sll=00:00:00:00:00:00,tll=f8:bc:12:44:34:c8)']) -AT_CHECK([ovs-appctl netdev-dummy/receive p0 'in_port(1),eth(src=f8:bc:12:44:34:b7,dst=aa:55:aa:55:00:00),eth_type(0x86dd),ipv6(src=2001:cafe::93,dst=2001:cafe::94,label=0,proto=58,tclass=0,hlimit=255,frag=no),icmpv6(type=136,code=0),nd(target=2001:cafe::93,sll=00:00:00:00:00:00,tll=f8:bc:12:44:34:b7)']) +ovs-appctl time/warp 1000 +ovs-appctl time/warp 1000 + +AT_CHECK([ovs-appctl tnl/arp/show | tail -n+3 | sort], [0], [dnl +2001:cafe::92 f8:bc:12:44:34:c8 br0 +]) + +dnl Receiving Neighbor Advertisement with incorrect 'nw_dst' should not alter tunnel neighbor cache +AT_CHECK([ovs-appctl netdev-dummy/receive p0 'in_port(1),eth(src=f8:bc:12:44:34:b6,dst=aa:55:aa:55:00:00),eth_type(0x86dd),ipv6(src=2001:cafe::92,dst=2001:cafe::99,label=0,proto=58,tclass=0,hlimit=255,frag=no),icmpv6(type=136,code=0),nd(target=2001:cafe::92,sll=00:00:00:00:00:00,tll=f8:bc:12:44:34:b6)']) + +ovs-appctl time/warp 1000 +ovs-appctl time/warp 1000 + +AT_CHECK([ovs-appctl tnl/arp/show | tail -n+3 | sort], [0], [dnl +2001:cafe::92 f8:bc:12:44:34:c8 br0 +]) + +dnl Receiving Neighbot Advertisement with incorrect VLAN id should not alter tunnel neighbor cache +AT_CHECK([ovs-vsctl set port br0 tag=10]) +AT_CHECK([ovs-appctl netdev-dummy/receive p0 'in_port(1),eth(src=f8:bc:12:44:34:b6,dst=aa:55:aa:55:00:00),eth_type(0x8100),vlan(vid=99,pcp=7),encap(eth_type(0x86dd),ipv6(src=2001:cafe::92,dst=2001:cafe::88,label=0,proto=58,tclass=0,hlimit=255,frag=no),icmpv6(type=136,code=0),nd(target=2001:cafe::92,sll=00:00:00:00:00:00,tll=f8:bc:12:44:34:b6))']) + +ovs-appctl time/warp 1000 +ovs-appctl time/warp 1000 + +AT_CHECK([ovs-appctl tnl/arp/show | tail -n+3 | sort], [0], [dnl +2001:cafe::92 f8:bc:12:44:34:c8 br0 +]) + +dnl Receiving Neighbor Advertisement with correct VLAN id should alter tunnel neighbor cache +AT_CHECK([ovs-vsctl set port br0 tag=10]) +AT_CHECK([ovs-appctl netdev-dummy/receive p0 'in_port(1),eth(src=f8:bc:12:44:34:b6,dst=aa:55:aa:55:00:00),eth_type(0x8100),vlan(vid=10,pcp=7),encap(eth_type(0x86dd),ipv6(src=2001:cafe::92,dst=2001:cafe::88,label=0,proto=58,tclass=0,hlimit=255,frag=no),icmpv6(type=136,code=0),nd(target=2001:cafe::92,sll=00:00:00:00:00:00,tll=f8:bc:12:44:34:b6))']) + +ovs-appctl time/warp 1000 +ovs-appctl time/warp 1000 + +AT_CHECK([ovs-appctl tnl/arp/show | tail -n+3 | sort], [0], [dnl +2001:cafe::92 f8:bc:12:44:34:b6 br0 +]) + +dnl Receiving Neighbor Advertisement in overlay bridge should not alter tunnel neighbor cache +AT_CHECK([ovs-vsctl add-port int-br p1 -- set interface p1 type=dummy ofport_request=200 other-config:hwaddr=aa:55:aa:55:00:99]) +AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(200),eth(src=f8:bc:12:44:34:c8,dst=aa:55:aa:55:00:00),eth_type(0x86dd),ipv6(src=2001:cafe::92,dst=2001:cafe::99,label=0,proto=58,tclass=0,hlimit=255,frag=no),icmpv6(type=136,code=0),nd(target=2001:cafe::92,sll=00:00:00:00:00:00,tll=f8:bc:12:44:34:c8)']) + +ovs-appctl time/warp 1000 +ovs-appctl time/warp 1000 + +AT_CHECK([ovs-appctl tnl/neigh/show | grep br | sort], [0], [dnl +2001:cafe::92 f8:bc:12:44:34:b6 br0 +]) + +dnl Receive Neighbor Advertisement without VLAN header +AT_CHECK([ovs-vsctl set port br0 tag=0]) +AT_CHECK([ovs-appctl tnl/neigh/flush], [0], [OK +]) + +ovs-appctl time/warp 1000 +ovs-appctl time/warp 1000 + + +AT_CHECK([ovs-appctl netdev-dummy/receive p0 'in_port(1),eth(src=f8:bc:12:44:34:b6,dst=aa:55:aa:55:00:00),eth_type(0x86dd),ipv6(src=2001:cafe::92,dst=2001:cafe::88,label=0,proto=58,tclass=0,hlimit=255,frag=no),icmpv6(type=136,code=0),nd(target=2001:cafe::92,sll=00:00:00:00:00:00,tll=f8:bc:12:44:34:b6)']) + +AT_CHECK([ovs-appctl netdev-dummy/receive p0 'in_port(1),eth(src=f8:bc:12:44:34:b7,dst=aa:55:aa:55:00:00),eth_type(0x86dd),ipv6(src=2001:cafe::93,dst=ff02::1:ff00:0088,label=0,proto=58,tclass=0,hlimit=255,frag=no),icmpv6(type=136,code=0),nd(target=2001:cafe::93,sll=00:00:00:00:00:00,tll=f8:bc:12:44:34:b7)']) + +ovs-appctl time/warp 1000 +ovs-appctl time/warp 1000 AT_CHECK([ovs-appctl tnl/arp/show | tail -n+3 | sort], [0], [dnl 2001:cafe::92 f8:bc:12:44:34:b6 br0 diff --git a/tests/tunnel-push-pop.at b/tests/tunnel-push-pop.at index b168f5f2f..4e259730c 100644 --- a/tests/tunnel-push-pop.at +++ b/tests/tunnel-push-pop.at @@ -70,9 +70,71 @@ ffffffffffffaa55aa55000008060001080006040001aa55aa550000010102580000000000000101 ]) dnl Check ARP Snoop +AT_CHECK([ovs-appctl netdev-dummy/receive p0 'recirc_id(0),in_port(1),eth(src=f8:bc:12:44:34:c8,dst=ff:ff:ff:ff:ff:ff),eth_type(0x0806),arp(sip=1.1.2.92,tip=1.1.2.88,op=2,sha=f8:bc:12:44:34:c8,tha=00:00:00:00:00:00)']) + +ovs-appctl time/warp 1000 +ovs-appctl time/warp 1000 + +AT_CHECK([ovs-appctl tnl/neigh/show | grep br0 | sort], [0], [dnl +1.1.2.92 f8:bc:12:44:34:c8 br0 +]) + +dnl Receiving ARP reply with incorrect 'tip' should not alter tunnel neighbor cache +AT_CHECK([ovs-appctl netdev-dummy/receive p0 'recirc_id(0),in_port(1),eth(src=f8:bc:12:44:34:b8,dst=ff:ff:ff:ff:ff:ff),eth_type(0x0806),arp(sip=1.1.2.92,tip=1.1.2.90,op=2,sha=f8:bc:12:44:34:b8,tha=00:00:00:00:00:00)']) + +ovs-appctl time/warp 1000 +ovs-appctl time/warp 1000 + +AT_CHECK([ovs-appctl tnl/neigh/show | grep br0 | sort], [0], [dnl +1.1.2.92 f8:bc:12:44:34:c8 br0 +]) + +dnl Receiving ARP reply with incorrect VLAN id should not alter tunnel neighbor cache +AT_CHECK([ovs-vsctl set port br0 tag=10]) +AT_CHECK([ovs-appctl netdev-dummy/receive p0 'recirc_id(0),in_port(1),eth(src=f8:bc:12:44:34:b6,dst=ff:ff:ff:ff:ff:ff),eth_type(0x8100),vlan(vid=99,pcp=7),encap(eth_type(0x0806),arp(sip=1.1.2.92,tip=1.1.2.88,op=2,sha=f8:bc:12:44:34:b6,tha=00:00:00:00:00:00))']) + +ovs-appctl time/warp 1000 +ovs-appctl time/warp 1000 + +AT_CHECK([ovs-appctl tnl/neigh/show | grep br0 | sort], [0], [dnl +1.1.2.92 f8:bc:12:44:34:c8 br0 +]) + +dnl Receiving ARP reply with correct VLAN id should alter tunnel neighbor cache +AT_CHECK([ovs-appctl netdev-dummy/receive p0 'recirc_id(0),in_port(1),eth(src=f8:bc:12:44:34:b6,dst=ff:ff:ff:ff:ff:ff),eth_type(0x8100),vlan(vid=10,pcp=7),encap(eth_type(0x0806),arp(sip=1.1.2.92,tip=1.1.2.88,op=2,sha=f8:bc:12:44:34:b6,tha=00:00:00:00:00:00))']) + +ovs-appctl time/warp 1000 +ovs-appctl time/warp 1000 + +AT_CHECK([ovs-appctl tnl/neigh/show | grep br0 | sort], [0], [dnl +1.1.2.92 f8:bc:12:44:34:b6 br0 +]) + +dnl Receiving ARP reply in overlay bridge should not alter tunnel neighbor cache +AT_CHECK([ovs-vsctl add-port int-br p1 -- set interface p1 type=dummy ofport_request=200 other-config:hwaddr=aa:55:aa:55:00:99]) +AT_CHECK([ovs-appctl netdev-dummy/receive p1 'recirc_id(0),in_port(200),eth(src=f8:bc:12:44:34:c8,dst=ff:ff:ff:ff:ff:ff),eth_type(0x0806),arp(sip=1.1.2.92,tip=1.1.2.88,op=2,sha=f8:bc:12:44:34:c8,tha=00:00:00:00:00:00)']) + +ovs-appctl time/warp 1000 +ovs-appctl time/warp 1000 + +AT_CHECK([ovs-appctl tnl/neigh/show | grep br | sort], [0], [dnl +1.1.2.92 f8:bc:12:44:34:b6 br0 +]) + +dnl Receive ARP reply without VLAN header +AT_CHECK([ovs-vsctl set port br0 tag=0]) +AT_CHECK([ovs-appctl tnl/neigh/flush], [0], [OK +]) + +ovs-appctl time/warp 1000 +ovs-appctl time/warp 1000 + AT_CHECK([ovs-appctl netdev-dummy/receive p0 'recirc_id(0),in_port(1),eth(src=f8:bc:12:44:34:b6,dst=ff:ff:ff:ff:ff:ff),eth_type(0x0806),arp(sip=1.1.2.92,tip=1.1.2.88,op=2,sha=f8:bc:12:44:34:b6,tha=00:00:00:00:00:00)']) AT_CHECK([ovs-appctl netdev-dummy/receive p0 'recirc_id(0),in_port(1),eth(src=f8:bc:12:44:34:b7,dst=ff:ff:ff:ff:ff:ff),eth_type(0x0806),arp(sip=1.1.2.93,tip=1.1.2.88,op=2,sha=f8:bc:12:44:34:b7,tha=00:00:00:00:00:00)']) +ovs-appctl time/warp 1000 +ovs-appctl time/warp 1000 + AT_CHECK([ovs-appctl tnl/neigh/show | tail -n+3 | sort], [0], [dnl 1.1.2.92 f8:bc:12:44:34:b6 br0 1.1.2.93 f8:bc:12:44:34:b7 br0 @@ -190,9 +252,12 @@ AT_CHECK([ovs-ofctl dump-ports int-br | grep 'port 7'], [0], [dnl dnl Check GREL3 only accepts non-fragmented packets? AT_CHECK([ovs-appctl netdev-dummy/receive p0 'aa55aa550000001b213cab6408004500007e79464000402fba550101025c0101025820000800000001c8fe71d883724fbeb6f4e1494a080045000054ba200000400184861e0000011e00000200004227e75400030af3195500000000f265010000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637']) +ovs-appctl time/warp 1000 +ovs-appctl time/warp 1000 + AT_CHECK([ovs-ofctl dump-ports int-br | grep 'port [[37]]' | sort], [0], [dnl port 3: rx pkts=3, bytes=294, drop=?, errs=?, frame=?, over=?, crc=? - port 7: rx pkts=3, bytes=252, drop=?, errs=?, frame=?, over=?, crc=? + port 7: rx pkts=4, bytes=350, drop=?, errs=?, frame=?, over=?, crc=? ]) dnl Check decapsulation of Geneve packet with options -- 2.14.1 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
