+/*
+ * Copyright (c) 2011-2016 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
#include <vppinfra/types.h>
#include <vlibmemory/api.h>
#include <vlib/vlib.h>
bfd_udp_main_t bfd_udp_main;
+static u16
+bfd_udp_bs_idx_to_sport (u32 bs_idx)
+{
+ /* The source port MUST be in the range 49152 through 65535. The same UDP
+ * source port number MUST be used for all BFD Control packets associated
+ * with a particular session. The source port number SHOULD be unique among
+ * all BFD sessions on the system. If more than 16384 BFD sessions are
+ * simultaneously active, UDP source port numbers MAY be reused on
+ * multiple sessions, but the number of distinct uses of the same UDP
+ * source port number SHOULD be minimized.
+ */
+ return 49152 + bs_idx % (65535 - 49152 + 1);
+}
+
void
bfd_add_udp4_transport (vlib_main_t * vm, vlib_buffer_t * b,
- bfd_udp_session_t * bus)
+ const bfd_session_t * bs)
{
+ const bfd_udp_session_t *bus = &bs->udp;
const bfd_udp_key_t *key = &bus->key;
b->flags |= VNET_BUFFER_LOCALLY_ORIGINATED;
headers->ip4.src_address.as_u32 = key->local_addr.ip4.as_u32;
headers->ip4.dst_address.as_u32 = key->peer_addr.ip4.as_u32;
- headers->udp.src_port = clib_host_to_net_u16 (50000); /* FIXME */
+ headers->udp.src_port =
+ clib_host_to_net_u16 (bfd_udp_bs_idx_to_sport (bs->bs_idx));
headers->udp.dst_port = clib_host_to_net_u16 (UDP_DST_PORT_bfd4);
/* fix ip length, checksum and udp length */
void
bfd_add_udp6_transport (vlib_main_t * vm, vlib_buffer_t * b,
- bfd_udp_session_t * bus)
+ const bfd_session_t * bs)
{
+ const bfd_udp_session_t *bus = &bs->udp;
const bfd_udp_key_t *key = &bus->key;
b->flags |= VNET_BUFFER_LOCALLY_ORIGINATED;
clib_memcpy (&headers->ip6.dst_address, &key->peer_addr.ip6,
sizeof (headers->ip6.dst_address));
- headers->udp.src_port = clib_host_to_net_u16 (50000); /* FIXME */
+ headers->udp.src_port =
+ clib_host_to_net_u16 (bfd_udp_bs_idx_to_sport (bs->bs_idx));
headers->udp.dst_port = clib_host_to_net_u16 (UDP_DST_PORT_bfd6);
/* fix ip payload length and udp length */
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,
+ u32 desired_min_tx_usec,
+ u32 required_min_rx_usec, u8 detect_mult,
const ip46_address_t * local_addr,
const ip46_address_t * peer_addr,
bfd_session_t ** bs_out)
"returns %d", format_ip46_address, &key->peer_addr,
IP46_TYPE_ANY, key->sw_if_index, bus->adj_index);
}
- bs->config_desired_min_tx_us = desired_min_tx_us;
- bs->required_min_rx_us = required_min_rx_us;
- bs->required_min_echo_rx_us = required_min_rx_us; /* FIXME */
- bs->local_detect_mult = detect_mult;
*bs_out = bs;
- return 0;
+ return bfd_session_set_params (bum->bfd_main, bs, desired_min_tx_usec,
+ required_min_rx_usec, detect_mult);
}
static vnet_api_error_t
}
static vnet_api_error_t
-bfd_api_verify_common (u32 sw_if_index, u32 desired_min_tx_us,
- u32 required_min_rx_us, u8 detect_mult,
+bfd_api_verify_common (u32 sw_if_index, u32 desired_min_tx_usec,
+ u32 required_min_rx_usec, u8 detect_mult,
const ip46_address_t * local_addr,
const ip46_address_t * peer_addr)
{
clib_warning ("detect_mult < 1");
return VNET_API_ERROR_INVALID_ARGUMENT;
}
- if (desired_min_tx_us < 1)
+ if (desired_min_tx_usec < 1)
{
- clib_warning ("desired_min_tx_us < 1");
+ clib_warning ("desired_min_tx_usec < 1");
return VNET_API_ERROR_INVALID_ARGUMENT;
}
return 0;
vnet_api_error_t
bfd_udp_add_session (u32 sw_if_index, const ip46_address_t * local_addr,
- const ip46_address_t * peer_addr, u32 desired_min_tx_us,
- u32 required_min_rx_us, u8 detect_mult,
- u8 is_authenticated, u32 conf_key_id, u8 bfd_key_id)
+ const ip46_address_t * peer_addr,
+ u32 desired_min_tx_usec, u32 required_min_rx_usec,
+ u8 detect_mult, u8 is_authenticated, u32 conf_key_id,
+ u8 bfd_key_id)
{
- vnet_api_error_t rv = bfd_api_verify_common (sw_if_index, desired_min_tx_us,
- required_min_rx_us,
- detect_mult,
- local_addr, peer_addr);
+ vnet_api_error_t rv =
+ bfd_api_verify_common (sw_if_index, desired_min_tx_usec,
+ required_min_rx_usec, detect_mult,
+ local_addr, peer_addr);
bfd_session_t *bs = NULL;
if (!rv)
{
rv =
bfd_udp_add_session_internal (&bfd_udp_main, sw_if_index,
- desired_min_tx_us, required_min_rx_us,
- detect_mult, local_addr, peer_addr,
- &bs);
+ desired_min_tx_usec,
+ required_min_rx_usec, detect_mult,
+ local_addr, peer_addr, &bs);
}
if (!rv && is_authenticated)
{
return rv;
}
+vnet_api_error_t
+bfd_udp_mod_session (u32 sw_if_index,
+ const ip46_address_t * local_addr,
+ const ip46_address_t * peer_addr,
+ u32 desired_min_tx_usec,
+ u32 required_min_rx_usec, u8 detect_mult)
+{
+ bfd_session_t *bs = NULL;
+ vnet_api_error_t rv =
+ bfd_udp_find_session_by_api_input (sw_if_index, local_addr, peer_addr,
+ &bs);
+ if (rv)
+ {
+ return rv;
+ }
+
+ return bfd_session_set_params (bfd_udp_main.bfd_main, bs,
+ desired_min_tx_usec, required_min_rx_usec,
+ detect_mult);
+}
+
vnet_api_error_t
bfd_udp_del_session (u32 sw_if_index,
const ip46_address_t * local_addr,
expected_ttl);
return BFD_UDP_ERROR_BAD;
}
- if (clib_net_to_host_u16 (udp->src_port) < 49152 ||
- clib_net_to_host_u16 (udp->src_port) > 65535)
+ if (clib_net_to_host_u16 (udp->src_port) < 49152)
{
BFD_ERR ("Invalid UDP src port %u, out of range <49152,65535>",
udp->src_port);
ip6->hop_limit, expected_hop_limit);
return BFD_UDP_ERROR_BAD;
}
- if (clib_net_to_host_u16 (udp->src_port) < 49152 ||
- clib_net_to_host_u16 (udp->src_port) > 65535)
+ if (clib_net_to_host_u16 (udp->src_port) < 49152)
{
BFD_ERR ("Invalid UDP src port %u, out of range <49152,65535>",
udp->src_port);