From 0c1519b5e7953d093d5532d6caf87ae7ac9333d8 Mon Sep 17 00:00:00 2001 From: Klement Sekera Date: Thu, 8 Dec 2016 05:03:32 +0100 Subject: BFD: improve ip header handling, fix assert Instead of storing a pointer, store an offset within vlib_buffer marking the start of the ip header (similar to storing start of ethernet header). Handle negative timeout in the bfd process main loop. Change-Id: I05a1ff3ac41da5bdc3b2ac6f9e03b3241994688b Signed-off-by: Klement Sekera --- vnet/vnet/bfd/bfd_main.c | 14 +++++++++++--- vnet/vnet/bfd/bfd_udp.c | 26 +++++++++++++++++++++----- vnet/vnet/buffer.h | 4 ++-- vnet/vnet/ip/ip4_forward.c | 6 +++--- 4 files changed, 37 insertions(+), 13 deletions(-) (limited to 'vnet') diff --git a/vnet/vnet/bfd/bfd_main.c b/vnet/vnet/bfd/bfd_main.c index a72d6fed9bb..26b9fe31f09 100644 --- a/vnet/vnet/bfd/bfd_main.c +++ b/vnet/vnet/bfd/bfd_main.c @@ -570,15 +570,23 @@ bfd_process (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f) { BFD_DBG ("wait for event without timeout"); (void) vlib_process_wait_for_event (vm); + event_type = vlib_process_get_events (vm, &event_data); } else { f64 timeout = ((i64) next_expire - (i64) now) / bm->cpu_cps; BFD_DBG ("wait for event with timeout %.02f", timeout); - ASSERT (timeout > 0); - (void) vlib_process_wait_for_event_or_clock (vm, timeout); + if (timeout < 0) + { + BFD_DBG ("negative timeout, already expired, skipping wait"); + event_type = ~0; + } + else + { + (void) vlib_process_wait_for_event_or_clock (vm, timeout); + event_type = vlib_process_get_events (vm, &event_data); + } } - event_type = vlib_process_get_events (vm, &event_data); now = clib_cpu_time_now (); switch (event_type) { diff --git a/vnet/vnet/bfd/bfd_udp.c b/vnet/vnet/bfd/bfd_udp.c index ded3342559c..44a4a18dbeb 100644 --- a/vnet/vnet/bfd/bfd_udp.c +++ b/vnet/vnet/bfd/bfd_udp.c @@ -311,7 +311,23 @@ typedef enum { static void bfd_udp4_find_headers (vlib_buffer_t *b, const ip4_header_t **ip4, const udp_header_t **udp) { - *ip4 = vnet_buffer (b)->ip.header; + /* sanity check first */ + const i32 start = vnet_buffer (b)->ip.start_of_ip_header; + if (start < 0 && start < sizeof (b->pre_data)) + { + BFD_ERR ("Start of ip header is before pre_data, ignoring"); + *ip4 = NULL; + *udp = NULL; + return; + } + *ip4 = (ip4_header_t *)(b->data + start); + if ((u8 *)*ip4 > (u8 *)vlib_buffer_get_current (b)) + { + BFD_ERR ("Start of ip header is beyond current data, ignoring"); + *ip4 = NULL; + *udp = NULL; + return; + } *udp = (udp_header_t *)((*ip4) + 1); } @@ -493,14 +509,14 @@ static uword bfd_udp_input (vlib_main_t *vm, vlib_node_runtime_t *rt, next0 = BFD_UDP_INPUT_NEXT_NORMAL; if (BFD_UDP_ERROR_NONE == error0) { - /* if everything went fine, check for poll bit, if present, re-use - the buffer and based on (now update) session parameters, send the - final packet back */ + /* if everything went fine, check for poll bit, if present, re-use + the buffer and based on (now update) session parameters, send the + final packet back */ const bfd_pkt_t *pkt = vlib_buffer_get_current (b0); if (bfd_pkt_get_poll (pkt)) { bfd_send_final (vm, b0, bs); - next0 = BFD_UDP_INPUT_NEXT_REPLY; + next0 = BFD_UDP_INPUT_NEXT_REPLY; } } vlib_set_next_frame_buffer (vm, rt, next0, bi0); diff --git a/vnet/vnet/buffer.h b/vnet/vnet/buffer.h index 82806bba986..7935027f9ec 100644 --- a/vnet/vnet/buffer.h +++ b/vnet/vnet/buffer.h @@ -144,8 +144,8 @@ typedef struct u32 data; } icmp; - /* IP header - saved by ip*_local nodes */ - void *header; + /* IP header offset from vlib_buffer.data - saved by ip*_local nodes */ + i32 start_of_ip_header; }; } ip; diff --git a/vnet/vnet/ip/ip4_forward.c b/vnet/vnet/ip/ip4_forward.c index 38729c8ecfb..43a894075dd 100644 --- a/vnet/vnet/ip/ip4_forward.c +++ b/vnet/vnet/ip/ip4_forward.c @@ -1472,8 +1472,8 @@ ip4_local (vlib_main_t * vm, ip0 = vlib_buffer_get_current (p0); ip1 = vlib_buffer_get_current (p1); - vnet_buffer (p0)->ip.header = ip0; - vnet_buffer (p1)->ip.header = ip1; + vnet_buffer (p0)->ip.start_of_ip_header = p0->current_data; + vnet_buffer (p1)->ip.start_of_ip_header = p1->current_data; fib_index0 = vec_elt (im->fib_index_by_sw_if_index, vnet_buffer (p0)->sw_if_index[VLIB_RX]); @@ -1682,7 +1682,7 @@ ip4_local (vlib_main_t * vm, ip0 = vlib_buffer_get_current (p0); - vnet_buffer (p0)->ip.header = ip0; + vnet_buffer (p0)->ip.start_of_ip_header = p0->current_data; fib_index0 = vec_elt (im->fib_index_by_sw_if_index, vnet_buffer(p0)->sw_if_index[VLIB_RX]); -- cgit 1.2.3-korg