aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/ip
diff options
context:
space:
mode:
authorDave Barach <dave@barachs.net>2019-01-07 09:15:47 -0500
committerFlorin Coras <florin.coras@gmail.com>2019-01-07 16:47:09 +0000
commit3a63fc5470caffda434064a439ffdbe8518963f9 (patch)
tree5413c1a884269a7c93c1ed468608222a2dbd9590 /src/vnet/ip
parent9d7570ccde4ded1c5feea097b10272870bfc81da (diff)
Handle buffer alloc failure in vlib_buffer_add_data
It's not OK to crash due to a transient buffer allocation failure. Return 1 if the requested operation failed, otherwise 0. Buffer index parameter change to a value-result, so the caller can differentiate between partial and complete allocation failure: callers which request an initial allocation (inbound bi = ~0) need to check the (out) value to decide whether or not to call vlib_buffer_free(...). Change-Id: I03029d7f2714c17dca4630dfd95a1eb578b68384 Signed-off-by: Dave Barach <dave@barachs.net>
Diffstat (limited to 'src/vnet/ip')
-rw-r--r--src/vnet/ip/icmp6.h3
-rwxr-xr-xsrc/vnet/ip/ip6_neighbor.c67
2 files changed, 47 insertions, 23 deletions
diff --git a/src/vnet/ip/icmp6.h b/src/vnet/ip/icmp6.h
index 1cac8240466..628d225eac4 100644
--- a/src/vnet/ip/icmp6.h
+++ b/src/vnet/ip/icmp6.h
@@ -46,7 +46,8 @@
_ (PACKET_TOO_BIG_SENT, "packet too big response sent") \
_ (TTL_EXPIRE_SENT, "hop limit exceeded response sent") \
_ (PARAM_PROBLEM_SENT, "parameter problem response sent") \
- _ (DROP, "error message dropped")
+ _ (DROP, "error message dropped") \
+ _ (ALLOC_FAILURE, "buffer allocation failure")
typedef enum
diff --git a/src/vnet/ip/ip6_neighbor.c b/src/vnet/ip/ip6_neighbor.c
index f9acfeff389..fde3a7e71d4 100755
--- a/src/vnet/ip/ip6_neighbor.c
+++ b/src/vnet/ip/ip6_neighbor.c
@@ -1690,11 +1690,15 @@ icmp6_router_solicitation (vlib_main_t * vm,
u16 payload_length =
sizeof (icmp6_router_advertisement_header_t);
- vlib_buffer_add_data (vm,
- vlib_buffer_get_free_list_index
- (p0), bi0, (void *) &rh,
- sizeof
- (icmp6_router_advertisement_header_t));
+ if (vlib_buffer_add_data
+ (vm, vlib_buffer_get_free_list_index
+ (p0), &bi0, (void *) &rh,
+ sizeof (icmp6_router_advertisement_header_t)))
+ {
+ /* buffer allocation failed, drop the pkt */
+ error0 = ICMP6_ERROR_ALLOC_FAILURE;
+ goto drop0;
+ }
if (radv_info->adv_link_layer_address)
{
@@ -1709,11 +1713,15 @@ icmp6_router_solicitation (vlib_main_t * vm,
clib_memcpy (&h.ethernet_address[0],
eth_if0->address, 6);
- vlib_buffer_add_data (vm,
- vlib_buffer_get_free_list_index
- (p0), bi0, (void *) &h,
- sizeof
- (icmp6_neighbor_discovery_ethernet_link_layer_address_option_t));
+ if (vlib_buffer_add_data
+ (vm, vlib_buffer_get_free_list_index
+ (p0), &bi0, (void *) &h,
+ sizeof
+ (icmp6_neighbor_discovery_ethernet_link_layer_address_option_t)))
+ {
+ error0 = ICMP6_ERROR_ALLOC_FAILURE;
+ goto drop0;
+ }
payload_length +=
sizeof
@@ -1734,11 +1742,15 @@ icmp6_router_solicitation (vlib_main_t * vm,
payload_length +=
sizeof (icmp6_neighbor_discovery_mtu_option_t);
- vlib_buffer_add_data (vm,
- vlib_buffer_get_free_list_index
- (p0), bi0, (void *) &h,
- sizeof
- (icmp6_neighbor_discovery_mtu_option_t));
+ if (vlib_buffer_add_data
+ (vm, vlib_buffer_get_free_list_index
+ (p0), &bi0, (void *) &h,
+ sizeof
+ (icmp6_neighbor_discovery_mtu_option_t)))
+ {
+ error0 = ICMP6_ERROR_ALLOC_FAILURE;
+ goto drop0;
+ }
}
/* add advertised prefix options */
@@ -1787,10 +1799,15 @@ icmp6_router_solicitation (vlib_main_t * vm,
payload_length += sizeof( icmp6_neighbor_discovery_prefix_information_option_t);
- vlib_buffer_add_data (vm,
- vlib_buffer_get_free_list_index (p0),
- bi0,
- (void *)&h, sizeof(icmp6_neighbor_discovery_prefix_information_option_t));
+ if (vlib_buffer_add_data
+ (vm, vlib_buffer_get_free_list_index (p0),
+ &bi0,
+ (void *)&h,
+ sizeof(icmp6_neighbor_discovery_prefix_information_option_t)))
+ {
+ error0 = ICMP6_ERROR_ALLOC_FAILURE;
+ goto drop0;
+ }
}
}));
@@ -1875,6 +1892,7 @@ icmp6_router_solicitation (vlib_main_t * vm,
}
}
+ drop0:
p0->error = error_node->errors[error0];
if (error0 != ICMP6_ERROR_NONE)
@@ -2761,6 +2779,7 @@ ip6_neighbor_send_mldpv2_report (u32 sw_if_index)
n_allocated = vlib_buffer_alloc (vm, &bo0, n_to_alloc);
if (PREDICT_FALSE (n_allocated == 0))
{
+ alloc_fail:
clib_warning ("buffer allocation failure");
return;
}
@@ -2827,9 +2846,13 @@ ip6_neighbor_send_mldpv2_report (u32 sw_if_index)
num_addr_records++;
- vlib_buffer_add_data
- (vm, vlib_buffer_get_free_list_index (b0), bo0,
- (void *)&rr, sizeof(icmp6_multicast_address_record_t));
+ if(vlib_buffer_add_data
+ (vm, vlib_buffer_get_free_list_index (b0), &bo0,
+ (void *)&rr, sizeof(icmp6_multicast_address_record_t)))
+ {
+ vlib_buffer_free (vm, &bo0, 1);
+ goto alloc_fail;
+ }
payload_length += sizeof( icmp6_multicast_address_record_t);
}));