diff options
-rw-r--r-- | lib/tnl-neigh-cache.c | 12 | ||||
-rw-r--r-- | lib/tnl-neigh-cache.h | 2 | ||||
-rw-r--r-- | ofproto/ofproto-dpif-xlate.c | 13 | ||||
-rw-r--r-- | tests/tunnel-push-pop-ipv6.at | 36 | ||||
-rw-r--r-- | tests/tunnel-push-pop.at | 35 |
5 files changed, 92 insertions, 6 deletions
diff --git a/lib/tnl-neigh-cache.c b/lib/tnl-neigh-cache.c index eb3bdbc8e..bdff1debc 100644 --- a/lib/tnl-neigh-cache.c +++ b/lib/tnl-neigh-cache.c @@ -136,9 +136,9 @@ tnl_neigh_delete(struct tnl_neigh_entry *neigh) ovsrcu_postpone(neigh_entry_free, neigh); } -static void -tnl_neigh_set__(const char name[IFNAMSIZ], const struct in6_addr *dst, - const struct eth_addr mac) +void +tnl_neigh_set(const char name[IFNAMSIZ], const struct in6_addr *dst, + const struct eth_addr mac) { ovs_mutex_lock(&mutex); struct tnl_neigh_entry *neigh = tnl_neigh_lookup__(name, dst); @@ -169,7 +169,7 @@ tnl_arp_set(const char name[IFNAMSIZ], ovs_be32 dst, const struct eth_addr mac) { struct in6_addr dst6 = in6_addr_mapped_ipv4(dst); - tnl_neigh_set__(name, &dst6, mac); + tnl_neigh_set(name, &dst6, mac); } static int @@ -214,7 +214,7 @@ tnl_nd_snoop(const struct flow *flow, struct flow_wildcards *wc, memset(&wc->masks.nd_target, 0xff, sizeof wc->masks.nd_target); if (allow_update) { - tnl_neigh_set__(name, &flow->nd_target, flow->arp_tha); + tnl_neigh_set(name, &flow->nd_target, flow->arp_tha); } return 0; } @@ -364,7 +364,7 @@ tnl_neigh_cache_add(struct unixctl_conn *conn, int argc OVS_UNUSED, return; } - tnl_neigh_set__(br_name, &ip6, mac); + tnl_neigh_set(br_name, &ip6, mac); unixctl_command_reply(conn, "OK"); } diff --git a/lib/tnl-neigh-cache.h b/lib/tnl-neigh-cache.h index 59804ea3e..877bca312 100644 --- a/lib/tnl-neigh-cache.h +++ b/lib/tnl-neigh-cache.h @@ -33,6 +33,8 @@ int tnl_neigh_snoop(const struct flow *flow, struct flow_wildcards *wc, const char dev_name[IFNAMSIZ], bool allow_update); +void tnl_neigh_set(const char name[IFNAMSIZ], const struct in6_addr *dst, + const struct eth_addr mac); int tnl_neigh_lookup(const char dev_name[IFNAMSIZ], const struct in6_addr *dst, struct eth_addr *mac); void tnl_neigh_cache_init(void); diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c index 248aacd6a..cafcd014a 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -4121,6 +4121,19 @@ terminate_native_tunnel(struct xlate_ctx *ctx, const struct xport *xport, is_neighbor_reply_correct(ctx, flow)) { tnl_neigh_snoop(flow, wc, ctx->xbridge->name, ctx->xin->allow_side_effects); + } else if (*tnl_port != ODPP_NONE && + ctx->xin->allow_side_effects && + dl_type_is_ip_any(flow->dl_type)) { + struct eth_addr mac = flow->dl_src; + struct in6_addr s_ip6; + + if (flow->dl_type == htons(ETH_TYPE_IP)) { + in6_addr_set_mapped_ipv4(&s_ip6, flow->nw_src); + } else { + s_ip6 = flow->ipv6_src; + } + + tnl_neigh_set(ctx->xbridge->name, &s_ip6, mac); } } diff --git a/tests/tunnel-push-pop-ipv6.at b/tests/tunnel-push-pop-ipv6.at index 327c0e61e..3f58e3e8f 100644 --- a/tests/tunnel-push-pop-ipv6.at +++ b/tests/tunnel-push-pop-ipv6.at @@ -462,6 +462,42 @@ AT_CHECK([ovs-appctl dpif/dump-flows int-br | grep 'in_port(6081)'], [0], [dnl tunnel(tun_id=0x7b,ipv6_src=2001:cafe::92,ipv6_dst=2001:cafe::88,geneve({class=0xffff,type=0x80,len=4,0xa/0xf}{class=0xffff,type=0,len=4}),flags(-df-csum+key)),recirc_id(0),in_port(6081),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(frag=no), packets:0, bytes:0, used:never, actions:userspace(pid=0,controller(reason=1,dont_send=0,continuation=0,recirc_id=3,rule_cookie=0,controller_id=0,max_len=65535)) ]) +dnl Receive VXLAN with different MAC and verify that the neigh cache gets updated +AT_CHECK([ovs-appctl netdev-dummy/receive p0 'aa55aa550000f8bc1244cafe86dd60000000003a11402001cafe0000000000000000000000922001cafe000000000000000000000088c85312b5003abc700c00000300007b00ffffffffffff00000000000008004500001c0001000040117cce7f0000017f0000010035003500080172']) + +ovs-appctl time/warp 1000 +ovs-appctl time/warp 1000 + +dnl Check VXLAN tunnel push +AT_CHECK([ovs-ofctl add-flow int-br action=2]) +AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(2),eth(src=36:b1:ee:7c:01:01,dst=36:b1:ee:7c:01:02),eth_type(0x0800),ipv4(src=1.1.3.88,dst=1.1.3.112,proto=47,tos=0,ttl=64,frag=no)'], [0], [stdout]) +AT_CHECK([tail -1 stdout], [0], + [Datapath actions: clone(tnl_push(tnl_port(4789),header(size=70,type=4,eth(dst=f8:bc:12:44:ca:fe,src=aa:55:aa:55:00:00,dl_type=0x86dd),ipv6(src=2001:cafe::88,dst=2001:cafe::92,label=0,proto=17,tclass=0x0,hlimit=64),udp(src=0,dst=4789,csum=0xffff),vxlan(flags=0x8000000,vni=0x7b)),out_port(100)),1) +]) + +AT_CHECK([ovs-appctl tnl/arp/show | tail -n+3 | sort], [0], [dnl +2001:cafe::92 f8:bc:12:44:ca:fe br0 +2001:cafe::93 f8:bc:12:44:34:b7 br0 +]) + +dnl Restore and check the cache entries +AT_CHECK([ovs-appctl netdev-dummy/receive p0 'aa55aa550000f8bc124434b686dd60000000003a11402001cafe0000000000000000000000922001cafe000000000000000000000088c85312b5003abc700c00000300007b00ffffffffffff00000000000008004500001c0001000040117cce7f0000017f0000010035003500080172']) + +ovs-appctl time/warp 1000 +ovs-appctl time/warp 1000 + +dnl Check VXLAN tunnel push +AT_CHECK([ovs-ofctl add-flow int-br action=2]) +AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(2),eth(src=36:b1:ee:7c:01:01,dst=36:b1:ee:7c:01:02),eth_type(0x0800),ipv4(src=1.1.3.88,dst=1.1.3.112,proto=47,tos=0,ttl=64,frag=no)'], [0], [stdout]) +AT_CHECK([tail -1 stdout], [0], + [Datapath actions: clone(tnl_push(tnl_port(4789),header(size=70,type=4,eth(dst=f8:bc:12:44:34:b6,src=aa:55:aa:55:00:00,dl_type=0x86dd),ipv6(src=2001:cafe::88,dst=2001:cafe::92,label=0,proto=17,tclass=0x0,hlimit=64),udp(src=0,dst=4789,csum=0xffff),vxlan(flags=0x8000000,vni=0x7b)),out_port(100)),1) +]) + +AT_CHECK([ovs-appctl tnl/arp/show | tail -n+3 | sort], [0], [dnl +2001:cafe::92 f8:bc:12:44:34:b6 br0 +2001:cafe::93 f8:bc:12:44:34:b7 br0 +]) + ovs-appctl time/warp 10000 AT_CHECK([ovs-vsctl del-port int-br t3 \ diff --git a/tests/tunnel-push-pop.at b/tests/tunnel-push-pop.at index ab1f836b8..57589758f 100644 --- a/tests/tunnel-push-pop.at +++ b/tests/tunnel-push-pop.at @@ -569,6 +569,41 @@ AT_CHECK([ovs-appctl dpif/dump-flows int-br | grep 'in_port(6081)'], [0], [dnl tunnel(tun_id=0x7b,src=1.1.2.92,dst=1.1.2.88,geneve({class=0xffff,type=0x80,len=4,0xa/0xf}{class=0xffff,type=0,len=4}),flags(-df-csum+key)),recirc_id(0),in_port(6081),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(frag=no), packets:0, bytes:0, used:never, actions:userspace(pid=0,controller(reason=1,dont_send=0,continuation=0,recirc_id=2,rule_cookie=0,controller_id=0,max_len=65535)) ]) +dnl Receive VXLAN with different MAC and verify that the neigh cache gets updated +AT_CHECK([ovs-appctl netdev-dummy/receive p0 'aa55aa550000f8bc1244cafe08004500004e00010000401173e90101025c01010258c85312b5003a8cd40c00000300007b00ffffffffffff00000000000008004500001c0001000040117cce7f0000017f0000010035003500080172']) + +ovs-appctl time/warp 1000 +ovs-appctl time/warp 1000 + +dnl Check VXLAN tunnel push +AT_CHECK([ovs-ofctl add-flow int-br action=2]) +AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(2),eth(src=36:b1:ee:7c:01:01,dst=36:b1:ee:7c:01:02),eth_type(0x0800),ipv4(src=1.1.3.88,dst=1.1.3.112,proto=47,tos=0,ttl=64,frag=no)'], [0], [stdout]) +AT_CHECK([tail -1 stdout], [0], + [Datapath actions: clone(tnl_push(tnl_port(4789),header(size=50,type=4,eth(dst=f8:bc:12:44:ca:fe,src=aa:55:aa:55:00:00,dl_type=0x0800),ipv4(src=1.1.2.88,dst=1.1.2.92,proto=17,tos=0,ttl=64,frag=0x4000),udp(src=0,dst=4789,csum=0x0),vxlan(flags=0x8000000,vni=0x7b)),out_port(100)),1) +]) + +AT_CHECK([ovs-appctl tnl/neigh/show | tail -n+3 | sort], [0], [dnl +1.1.2.92 f8:bc:12:44:ca:fe br0 +1.1.2.93 f8:bc:12:44:34:b7 br0 +]) + +dnl Restore and check the cache entries +AT_CHECK([ovs-appctl netdev-dummy/receive p0 'aa55aa550000f8bc124434b608004500004e00010000401173e90101025c01010258c85312b5003a8cd40c00000300007b00ffffffffffff00000000000008004500001c0001000040117cce7f0000017f0000010035003500080172']) + +ovs-appctl time/warp 1000 +ovs-appctl time/warp 1000 + +dnl Check VXLAN tunnel push +AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(2),eth(src=36:b1:ee:7c:01:01,dst=36:b1:ee:7c:01:02),eth_type(0x0800),ipv4(src=1.1.3.88,dst=1.1.3.112,proto=47,tos=0,ttl=64,frag=no)'], [0], [stdout]) +AT_CHECK([tail -1 stdout], [0], + [Datapath actions: clone(tnl_push(tnl_port(4789),header(size=50,type=4,eth(dst=f8:bc:12:44:34:b6,src=aa:55:aa:55:00:00,dl_type=0x0800),ipv4(src=1.1.2.88,dst=1.1.2.92,proto=17,tos=0,ttl=64,frag=0x4000),udp(src=0,dst=4789,csum=0x0),vxlan(flags=0x8000000,vni=0x7b)),out_port(100)),1) +]) + +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 +]) + ovs-appctl time/warp 10000 AT_CHECK([ovs-vsctl del-port int-br t3 \ |