IP4_ARP_ERROR_REQUEST_SENT,
IP4_ARP_ERROR_NON_ARP_ADJ,
IP4_ARP_ERROR_REPLICATE_DROP,
- IP4_ARP_ERROR_REPLICATE_FAIL
+ IP4_ARP_ERROR_REPLICATE_FAIL,
+ IP4_ARP_ERROR_NO_SOURCE_ADDRESS,
} ip4_arp_error_t;
typedef CLIB_PACKED (struct {
uword dest_length)
{ return 0 == ((clib_mem_unaligned (&key->data_u32, u32) ^ dest->data_u32) & im->fib_masks[dest_length]); }
-always_inline void
+always_inline int
ip4_src_address_for_packet (ip4_main_t * im, vlib_buffer_t * p, ip4_address_t * src, u32 sw_if_index)
{
ip_lookup_main_t * lm = &im->lookup_main;
ip_interface_address_t * ia = ip_interface_address_for_packet (lm, p, sw_if_index);
+ if (ia == NULL)
+ return -1;
ip4_address_t * a = ip_interface_address_get_address (lm, ia);
*src = a[0];
+ return 0;
}
/* Find interface address which matches destination. */
clib_memcpy (h0->ip4_over_ethernet[0].ethernet, hw_if0->hw_address,
sizeof (h0->ip4_over_ethernet[0].ethernet));
- ip4_src_address_for_packet (im, p0, &h0->ip4_over_ethernet[0].ip4, sw_if_index0);
+ if (ip4_src_address_for_packet (im, p0, &h0->ip4_over_ethernet[0].ip4, sw_if_index0)) {
+ //No source address available
+ p0->error = node->errors[IP4_ARP_ERROR_NO_SOURCE_ADDRESS];
+ vlib_buffer_free(vm, &bi0, 1);
+ continue;
+ }
/* Copy in destination address we are requesting. */
h0->ip4_over_ethernet[1].ip4.data_u32 = ip0->dst_address.data_u32;
[IP4_ARP_ERROR_NON_ARP_ADJ] = "ARPs to non-ARP adjacencies",
[IP4_ARP_ERROR_REPLICATE_DROP] = "ARP replication completed",
[IP4_ARP_ERROR_REPLICATE_FAIL] = "ARP replication failed",
+ [IP4_ARP_ERROR_NO_SOURCE_ADDRESS] = "no source address for ARP request",
};
VLIB_REGISTER_NODE (ip4_arp_node) = {
return 1;
}
-always_inline void
+always_inline int
ip6_src_address_for_packet (ip6_main_t * im, vlib_buffer_t * p, ip6_address_t * src, u32 sw_if_index)
{
ip_lookup_main_t * lm = &im->lookup_main;
ip_interface_address_t * ia = ip_interface_address_for_packet (lm, p, sw_if_index);
+ if (ia == NULL)
+ return -1;
ip6_address_t * a = ip_interface_address_get_address (lm, ia);
*src = a[0];
+ return 0;
}
always_inline u32
typedef enum {
IP6_DISCOVER_NEIGHBOR_ERROR_DROP,
IP6_DISCOVER_NEIGHBOR_ERROR_REQUEST_SENT,
+ IP6_DISCOVER_NEIGHBOR_ERROR_NO_SOURCE_ADDRESS,
} ip6_discover_neighbor_error_t;
static uword
* Choose source address based on destination lookup
* adjacency.
*/
- ip6_src_address_for_packet (im, p0, &h0->ip.src_address,
- sw_if_index0);
+ if (ip6_src_address_for_packet (im, p0, &h0->ip.src_address,
+ sw_if_index0)) {
+ //There is no address on the interface
+ p0->error = node->errors[IP6_DISCOVER_NEIGHBOR_ERROR_NO_SOURCE_ADDRESS];
+ vlib_buffer_free(vm, &bi0, 1);
+ continue;
+ }
/*
* Destination address is a solicited node multicast address.
[IP6_DISCOVER_NEIGHBOR_ERROR_DROP] = "address overflow drops",
[IP6_DISCOVER_NEIGHBOR_ERROR_REQUEST_SENT]
= "neighbor solicitations sent",
+ [IP6_DISCOVER_NEIGHBOR_ERROR_NO_SOURCE_ADDRESS]
+ = "no source address for ND solicitation",
};
VLIB_REGISTER_NODE (ip6_discover_neighbor_node) = {
vec_elt (lm->if_address_pool_index_by_sw_if_index, sw_if_index)
: if_address_index);
- return pool_elt_at_index (lm->if_address_pool, if_address_index);
+ return (if_address_index != ~0)?pool_elt_at_index (lm->if_address_pool, if_address_index):NULL;
}
#define foreach_ip_interface_address(lm,a,sw_if_index,loop,body) \