On Tue, Jan 09, 2018 at 07:54:33PM +0100, Zoltan Balogh wrote:
> Currenlty, OVS snoops any ARP or ND packets in any bridge and populates
> the tunnel neighbor cache with the retreived data. For instance, when
> ARP reply originated by a tenant is received in an overlay bridge, the
> ARP message is snooped and tunnel neighbor cache is filled with tenant
> data, however only tunnel neighbor data should be stored there.
>
> This patch moves tunnel neighbor snooping from do_xlate_actions() to
> terminate_native_tunnel() where native tunnel is terminated, in order to
> keep ARP neighbor cache clean, i.e. only packets comming from a native
> tunnel are snooped.
>
> By applying the patch, only ARP and Neighbor Advertisement messages
> addressing a tunnel endpoint (LOCAL port of underlay bridge) are
> snooped. In order to achieve this, IP addresses of the bridge are
> retrieved and then stored in xbridge by calling xlate_xbridge_set().
> These data is then matched against the data extracted from an ARP or
> Neighbor Advertisement message in is_neighbor_reply_correct() which is
> invoked from terminate_native_tunnel().
>
> Signed-off-by: Zoltan Balogh <[email protected]>
Thanks a lot!
It appears to me that this patch makes the following test consistently
fail. When I revert the test, it passes for me again. Can you take a
look?
Thanks,
Ben.
# -*- compilation -*-
2370. ovn.at:8136: testing ovn -- /32 router IP address ...
creating ovn-sb database
creating ovn-nb database
starting ovn-northd
starting backup ovn-northd
adding simulator 'main'
adding simulator 'hv1'
adding simulator 'hv2'
../../tests/ovn.at:8198: ovn_populate_arp__
stdout:
OK
OK
checking packets in hv2/vif1-tx.pcap against expected:
expected 1 packets, only received 0
../../tests/ovn.at:8230: sort $rcv_text
--- expout 2018-01-23 10:59:47.231797273 -0800
+++ /home/blp/nicira/ovs/_build/tests/testsuite.dir/at-groups/2370/stdout
2018-01-23 10:59:47.231797273 -0800
@@ -1 +0,0 @@
-f0000001020400000001020408004500001c000000003f110100c0a801020a0000020035111100080000
2370. ovn.at:8136: 2370. ovn -- /32 router IP address (ovn.at:8136): FAILED
(ovn.at:8230)
> ---
> include/sparse/netinet/in.h | 10 +++
> ofproto/ofproto-dpif-xlate.c | 147
> ++++++++++++++++++++++++++++++++++++++++--
> tests/tunnel-push-pop-ipv6.at | 68 ++++++++++++++++++-
> tests/tunnel-push-pop.at | 67 ++++++++++++++++++-
> 4 files changed, 282 insertions(+), 10 deletions(-)
>
> diff --git a/include/sparse/netinet/in.h b/include/sparse/netinet/in.h
> index 6abdb2331..eea41bd7f 100644
> --- a/include/sparse/netinet/in.h
> +++ b/include/sparse/netinet/in.h
> @@ -123,6 +123,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/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
> index 2328ec1da..16bc0cd96 100644
> --- a/ofproto/ofproto-dpif-xlate.c
> +++ b/ofproto/ofproto-dpif-xlate.c
> @@ -90,6 +90,16 @@ VLOG_DEFINE_THIS_MODULE(ofproto_dpif_xlate);
> * recursive or not. */
> #define MAX_RESUBMITS (MAX_DEPTH * MAX_DEPTH)
>
> +/* The structure holds an array of IP addresses assigned to a bridge and the
> + * number of elements in the array. These data are mutable and are evaluated
> + * when ARP or Neighbor Advertisement packets received on a native tunnel
> + * port are xlated. So 'ref_cnt' and RCU are used for synchronization. */
> +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. */
> @@ -113,6 +123,8 @@ struct xbridge {
>
> /* Datapath feature support. */
> struct dpif_backer_support support;
> +
> + struct xbridge_addr *addr;
> };
>
> struct xbundle {
> @@ -576,7 +588,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,
> @@ -826,6 +839,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,
> @@ -836,7 +899,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);
> @@ -878,6 +942,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;
> @@ -971,7 +1040,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);
> }
> @@ -1126,6 +1195,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);
>
> @@ -1140,8 +1210,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
> @@ -1171,6 +1249,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);
> @@ -3655,6 +3734,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_dst, ipv6_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,
> @@ -3667,6 +3794,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;
> @@ -6183,9 +6319,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
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev