[ovs-dev] [PATCH 2/2] OVN: add buffering support for ipv6 packets
Lorenzo Bianconi
lorenzo.bianconi at redhat.com
Fri Sep 14 15:19:25 UTC 2018
Add buffering support for IPv6 packets that will be processed by
nd_ns {} action when L2 address is not discovered yet since
otherwise the packet will be substituted with a Neighbor Solicitation
frame and this will result in the lost of the first packet of the
connection
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi at redhat.com>
---
ovn/controller/pinctrl.c | 35 ++++++++++++++++++++++++++++++-----
1 file changed, 30 insertions(+), 5 deletions(-)
diff --git a/ovn/controller/pinctrl.c b/ovn/controller/pinctrl.c
index 3f8c0ac4e..6436be428 100644
--- a/ovn/controller/pinctrl.c
+++ b/ovn/controller/pinctrl.c
@@ -99,6 +99,7 @@ static void pinctrl_handle_put_nd_ra_opts(
struct ofputil_packet_in *pin, struct ofpbuf *userdata,
struct ofpbuf *continuation);
static void pinctrl_handle_nd_ns(const struct flow *ip_flow,
+ struct dp_packet *pkt_in,
const struct match *md,
struct ofpbuf *userdata);
static void init_ipv6_ras(void);
@@ -1358,7 +1359,8 @@ process_packet_in(const struct ofp_header *msg,
break;
case ACTION_OPCODE_ND_NS:
- pinctrl_handle_nd_ns(&headers, &pin.flow_metadata, &userdata);
+ pinctrl_handle_nd_ns(&headers, &packet, &pin.flow_metadata,
+ &userdata);
break;
case ACTION_OPCODE_ICMP:
@@ -2569,9 +2571,13 @@ pinctrl_handle_nd_na(const struct flow *ip_flow, const struct match *md,
}
static void
-pinctrl_handle_nd_ns(const struct flow *ip_flow, const struct match *md,
- struct ofpbuf *userdata)
+pinctrl_handle_nd_ns(const struct flow *ip_flow, struct dp_packet *pkt_in,
+ const struct match *md, struct ofpbuf *userdata)
{
+ struct dp_packet *clone, packet;
+ uint64_t packet_stub[128 / 8];
+ char ip[INET6_ADDRSTRLEN];
+
/* This action only works for IPv6 packets. */
if (get_dl_type(ip_flow) != htons(ETH_TYPE_IPV6)) {
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
@@ -2579,8 +2585,27 @@ pinctrl_handle_nd_ns(const struct flow *ip_flow, const struct match *md,
return;
}
- uint64_t packet_stub[128 / 8];
- struct dp_packet packet;
+ inet_ntop(AF_INET6, &ip_flow->ipv6_dst, ip, sizeof(ip));
+ uint32_t hash = hash_string(ip, 0);
+ struct buffered_packets *bp = pinctrl_find_buffered_packets(ip, hash);
+ if (!bp) {
+ if (hmap_count(&buffered_packets_map) >= 1000) {
+ COVERAGE_INC(pinctrl_drop_buffered_packets_map);
+ goto send_ns;
+ }
+
+ bp = xmalloc(sizeof *bp);
+ hmap_insert(&buffered_packets_map, &bp->hmap_node, hash);
+ ovs_strlcpy_arrays(bp->ip, ip);
+ bp->head = bp->tail = 0;
+ }
+ bp->timestamp = time_msec();
+ /* clone the packet to send it later with correct L2 address */
+ clone = dp_packet_clone_data(dp_packet_data(pkt_in),
+ dp_packet_size(pkt_in));
+ buffered_push_packet(bp, clone, md);
+
+send_ns:
dp_packet_use_stub(&packet, packet_stub, sizeof packet_stub);
compose_nd_ns(&packet, ip_flow->dl_src, &ip_flow->ipv6_src,
--
2.17.1
More information about the dev
mailing list