38 u16 udp_length, ip_length;
39 bfd_udp_key_t *key = &bus->
key;
45 const size_t data_size =
sizeof (*ip4) +
sizeof (*udp);
49 memset (ip4, 0, data_size);
56 udp->
src_port = clib_host_to_net_u16 (50000);
57 udp->
dst_port = clib_host_to_net_u16 (UDP_DST_PORT_bfd4);
62 ip4->
length = clib_host_to_net_u16 (ip_length);
65 udp_length = ip_length - (
sizeof (*ip4));
66 udp->
length = clib_host_to_net_u16 (udp_length);
84 const bfd_udp_key_t *key)
96 u32 desired_min_tx_us,
u32 required_min_rx_us,
97 u8 detect_mult,
const ip46_address_t *local_addr,
98 const ip46_address_t *peer_addr)
106 t = BFD_TRANSPORT_UDP6;
110 memset (bus, 0,
sizeof (*bus));
111 bfd_udp_key_t *key = &bus->
key;
113 key->local_addr.as_u64[0] = local_addr->as_u64[0];
114 key->local_addr.as_u64[1] = local_addr->as_u64[1];
115 key->peer_addr.as_u64[0] = peer_addr->as_u64[0];
116 key->peer_addr.as_u64[1] = peer_addr->as_u64[1];
120 BFD_ERR (
"duplicate bfd-udp session, existing bs_idx=%d", tmp->
bs_idx);
122 return VNET_API_ERROR_BFD_EEXIST;
126 BFD_DBG (
"session created, bs_idx=%u, sw_if_index=%d, local=%U, peer=%U",
129 if (BFD_TRANSPORT_UDP4 == t)
132 &key->peer_addr, key->sw_if_index);
133 BFD_DBG (
"adj_nbr_add_or_lock(FIB_PROTOCOL_IP4, VNET_LINK_IP4, %U, %d) " 141 &key->peer_addr, key->sw_if_index);
142 BFD_DBG (
"adj_nbr_add_or_lock(FIB_PROTOCOL_IP6, VNET_LINK_IP6, %U, %d) " 156 const ip46_address_t *peer_addr)
160 u8 local_ip_valid = 0;
165 return VNET_API_ERROR_INVALID_SW_IF_INDEX;
171 BFD_ERR (
"IP family mismatch");
172 return VNET_API_ERROR_INVALID_ARGUMENT;
180 ip_interface_address_get_address (&im->lookup_main, ia);
181 if (x->as_u32 == local_addr->ip4.as_u32)
194 BFD_ERR (
"IP family mismatch");
195 return VNET_API_ERROR_INVALID_ARGUMENT;
202 ip_interface_address_get_address (&im->lookup_main, ia);
203 if (local_addr->ip6.as_u64[0] == x->as_u64[0] &&
204 local_addr->ip6.as_u64[1] == x->as_u64[1])
216 BFD_ERR (
"address not found on interface");
217 return VNET_API_ERROR_ADDRESS_NOT_FOUND_FOR_INTERFACE;
224 u32 required_min_rx_us,
u8 detect_mult,
225 const ip46_address_t *local_addr,
226 const ip46_address_t *peer_addr)
237 return VNET_API_ERROR_INVALID_ARGUMENT;
239 if (desired_min_tx_us < 1)
241 BFD_ERR (
"desired_min_tx_us < 1");
242 return VNET_API_ERROR_INVALID_ARGUMENT;
245 desired_min_tx_us, required_min_rx_us,
246 detect_mult, local_addr, peer_addr);
250 const ip46_address_t *local_addr,
251 const ip46_address_t *peer_addr)
263 memset (&key, 0,
sizeof (key));
265 key.local_addr.as_u64[0] = local_addr->as_u64[0];
266 key.local_addr.as_u64[1] = local_addr->as_u64[1];
267 key.peer_addr.as_u64[0] = peer_addr->as_u64[0];
268 key.peer_addr.as_u64[1] = peer_addr->as_u64[1];
280 return VNET_API_ERROR_BFD_NOENT;
292 #define foreach_bfd_udp_error(F) \ 293 F (NONE, "good bfd packets (processed)") \ 294 F (BAD, "invalid bfd packets") \ 295 F (DISABLED, "bfd packets received on disabled interfaces") 297 #define F(sym, string) static char BFD_UDP_ERR_##sym##_STR[] = string; 302 #define F(sym, string) BFD_UDP_ERR_##sym##_STR, 308 #define F(sym, str) BFD_UDP_ERROR_##sym, 319 if (start < 0 && start <
sizeof (b->
pre_data))
321 BFD_ERR (
"Start of ip header is before pre_data, ignoring");
329 BFD_ERR (
"Start of ip header is beyond current data, ignoring");
342 const bfd_udp_key_t *key = &bus->
key;
347 key->peer_addr.ip4.as_u32);
348 return BFD_UDP_ERROR_BAD;
354 key->local_addr.ip4.as_u32);
355 return BFD_UDP_ERROR_BAD;
357 const u8 expected_ttl = 255;
358 if (ip4->
ttl != expected_ttl)
360 BFD_ERR (
"IP unexpected TTL value %d, expected %d", ip4->
ttl,
362 return BFD_UDP_ERROR_BAD;
364 if (clib_net_to_host_u16 (udp->
src_port) < 49152 ||
365 clib_net_to_host_u16 (udp->
src_port) > 65535)
367 BFD_ERR (
"Invalid UDP src port %d, out of range <49152,65535>",
370 return BFD_UDP_ERROR_NONE;
404 "Payload size %d too small to hold bfd packet of minimum size %d",
406 return BFD_UDP_ERROR_BAD;
413 BFD_ERR (
"Couldn't find ip4 or udp header");
414 return BFD_UDP_ERROR_BAD;
418 return BFD_UDP_ERROR_BAD;
423 BFD_DBG (
"Looking up BFD session using discriminator %u",
430 memset (&key, 0,
sizeof (key));
434 BFD_DBG (
"Looking up BFD session using key (sw_if_index=%u, local=%U, " 442 BFD_ERR (
"BFD session lookup failed - no session matches BFD pkt");
443 return BFD_UDP_ERROR_BAD;
448 return BFD_UDP_ERROR_BAD;
457 return BFD_UDP_ERROR_NONE;
463 return BFD_UDP_ERROR_BAD;
473 u32 n_left_from, *from;
479 while (n_left_from > 0)
513 if (BFD_UDP_ERROR_NONE == error0)
556 .name =
"bfd-udp4-input",
557 .vector_size =
sizeof (
u32),
560 .n_errors = BFD_UDP_N_ERROR,
583 .name =
"bfd-udp6-input",
584 .vector_size =
sizeof (
u32),
587 .n_errors = BFD_UDP_N_ERROR,
632 sizeof (bfd_udp_key_t));
static clib_error_t * bfd_udp_init(vlib_main_t *vm)
#define foreach_ip_interface_address(lm, a, sw_if_index, loop, body)
static uword bfd_udp_input(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f, int is_ipv6)
void bfd_consume_pkt(bfd_main_t *bm, const bfd_pkt_t *pkt, u32 bs_idx)
static void vlib_set_next_frame_buffer(vlib_main_t *vm, vlib_node_runtime_t *node, u32 next_index, u32 buffer_index)
bad routing header type(not 4)") sr_error (NO_MORE_SEGMENTS
bfd_session_t * bfd_find_session_by_disc(bfd_main_t *bm, u32 disc)
Definitions for all things IP (v4|v6) unicast and multicast lookup related.
uword mhash_unset(mhash_t *h, void *key, uword *old_value)
int bfd_verify_pkt_common(const bfd_pkt_t *pkt)
verify bfd packet - common checks
static vlib_node_registration_t bfd_udp4_input_node
(constructor) VLIB_REGISTER_NODE (bfd_udp4_input_node)
struct _vlib_node_registration vlib_node_registration_t
void bfd_put_session(bfd_main_t *bm, bfd_session_t *bs)
ip_lookup_main_t lookup_main
static vnet_sw_interface_t * vnet_get_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
static vlib_node_registration_t bfd_udp6_input_node
(constructor) VLIB_REGISTER_NODE (bfd_udp6_input_node)
u32 config_desired_min_tx_us
#define foreach_bfd_udp_error(F)
#define VNET_HW_INTERFACE_FLAG_LINK_UP
static uword bfd_udp4_input(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
static uword vlib_buffer_length_in_chain(vlib_main_t *vm, vlib_buffer_t *b)
Get length in bytes of the buffer chain.
static vnet_api_error_t bfd_udp_validate_api_input(u32 sw_if_index, const ip46_address_t *local_addr, const ip46_address_t *peer_addr)
mhash_t bfd_session_idx_by_bfd_key
vnet_main_t * vnet_get_main(void)
#define VNET_BUFFER_LOCALLY_ORIGINATED
static char * bfd_udp_error_strings[]
#define VLIB_INIT_FUNCTION(x)
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
static bfd_session_t * bfd_lookup_session(bfd_udp_main_t *bum, const bfd_udp_key_t *key)
void bfd_send_final(vlib_main_t *vm, vlib_buffer_t *b, bfd_session_t *bs)
void vl_api_rpc_call_main_thread(void *fp, u8 *data, u32 data_length)
u8 pre_data[VLIB_BUFFER_PRE_DATA_SIZE]
Space for inserting data before buffer start.
static clib_error_t * bfd_hw_interface_up_down(vnet_main_t *vnm, u32 hw_if_index, u32 flags)
void adj_unlock(adj_index_t adj_index)
Release a reference counting lock on the adjacency.
static void bfd_rpc_update_session_cb(const bfd_rpc_update_t *a)
bfd_session_t * bfd_find_session_by_idx(bfd_main_t *bm, uword bs_idx)
u16 current_length
Nbytes between current data and the end of this buffer.
static clib_error_t * bfd_sw_interface_up_down(vnet_main_t *vnm, u32 sw_if_index, u32 flags)
VNET_HW_INTERFACE_LINK_UP_DOWN_FUNCTION(bfd_hw_interface_up_down)
vnet_api_error_t bfd_udp_add_session(u32 sw_if_index, u32 desired_min_tx_us, u32 required_min_rx_us, u8 detect_mult, const ip46_address_t *local_addr, const ip46_address_t *peer_addr)
static uword mhash_set(mhash_t *h, void *key, uword new_value, uword *old_value)
static bfd_udp_error_t bfd_udp4_scan(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_buffer_t *b, bfd_session_t **bs_out)
static vnet_api_error_t bfd_udp_add_session_internal(bfd_udp_main_t *bum, u32 sw_if_index, u32 desired_min_tx_us, u32 required_min_rx_us, u8 detect_mult, const ip46_address_t *local_addr, const ip46_address_t *peer_addr)
vlib_error_t error
Error code for buffers to be enqueued to error handler.
static void vlib_node_increment_counter(vlib_main_t *vm, u32 node_index, u32 counter_index, u64 increment)
void bfd_session_start(bfd_main_t *bm, bfd_session_t *bs)
#define ip46_address_is_ip4(ip46)
void mhash_init(mhash_t *h, uword n_value_bytes, uword n_key_bytes)
VNET_SW_INTERFACE_ADMIN_UP_DOWN_FUNCTION(bfd_sw_interface_up_down)
static uword bfd_udp6_input(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
#define clib_memcpy(a, b, c)
static void vlib_buffer_advance(vlib_buffer_t *b, word l)
Advance current data pointer by the supplied (signed!) amount.
u8 * bfd_input_format_trace(u8 *s, va_list *args)
#define VNET_SW_INTERFACE_FLAG_ADMIN_UP
void bfd_add_udp_transport(vlib_main_t *vm, vlib_buffer_t *b, bfd_udp_session_t *bus)
static uword * mhash_get(mhash_t *h, const void *key)
ip_lookup_main_t lookup_main
void bfd_udp_transport_to_buffer(vlib_main_t *vm, vlib_buffer_t *b, bfd_udp_session_t *bus)
static bfd_udp_error_t bfd_udp4_verify_transport(const ip4_header_t *ip4, const udp_header_t *udp, const bfd_session_t *bs)
bfd_udp_main_t bfd_udp_main
#define VLIB_BUFFER_IS_TRACED
static void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
static void bfd_udp4_find_headers(vlib_buffer_t *b, const ip4_header_t **ip4, const udp_header_t **udp)
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
vnet_api_error_t bfd_udp_del_session(u32 sw_if_index, const ip46_address_t *local_addr, const ip46_address_t *peer_addr)
u8 bfd_pkt_get_poll(const bfd_pkt_t *pkt)
#define VLIB_REGISTER_NODE(x,...)
ip4_main_t ip4_main
Global ip4 main structure.
#define STRUCT_SIZE_OF(t, f)
adj_index_t adj_nbr_add_or_lock(fib_protocol_t nh_proto, vnet_link_t link_type, const ip46_address_t *nh_addr, u32 sw_if_index)
Neighbour Adjacency sub-type.
void udp_register_dst_port(vlib_main_t *vm, udp_dst_port_t dst_port, u32 node_index, u8 is_ip4)
static void bfd_rpc_update_session(u32 bs_idx, const bfd_pkt_t *pkt)
bfd_session_t * bfd_get_session(bfd_main_t *bm, bfd_transport_t t)
u32 flags
buffer flags: VLIB_BUFFER_IS_TRACED: trace this buffer.
vlib buffer structure definition and a few select access methods.
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
int bfd_verify_pkt_session(const bfd_pkt_t *pkt, u16 pkt_size, const bfd_session_t *bs)
verify bfd packet - authentication
static u16 ip4_header_checksum(ip4_header_t *i)
static bfd_udp_error_t bfd_udp6_scan(vlib_main_t *vm, vlib_buffer_t *b)