summaryrefslogtreecommitdiffstats
path: root/vnet
diff options
context:
space:
mode:
Diffstat (limited to 'vnet')
-rw-r--r--vnet/vnet/bfd/bfd_main.c14
-rw-r--r--vnet/vnet/bfd/bfd_udp.c26
-rw-r--r--vnet/vnet/buffer.h4
-rw-r--r--vnet/vnet/ip/ip4_forward.c6
4 files changed, 37 insertions, 13 deletions
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]);