summaryrefslogtreecommitdiffstats
path: root/bfdd
diff options
context:
space:
mode:
authorRafael Zalamena <rzalamena@opensourcerouting.org>2020-08-11 19:43:56 +0200
committerRafael Zalamena <rzalamena@opensourcerouting.org>2020-08-12 02:22:39 +0200
commit262e1d2528e866d5608a3cf337c7761e35160926 (patch)
treeba8a99ce918626978c4c99d7ffe8ecaf7f58dd0b /bfdd
parentdoc: add BFD passive mode documentation (diff)
downloadfrr-262e1d2528e866d5608a3cf337c7761e35160926.tar.xz
frr-262e1d2528e866d5608a3cf337c7761e35160926.zip
bfdd: implement minimum TTL
Initial BFD protocol implementation had a hard coded value of maximum 5 hops, now we have a configurable hop amount with a safe default of 1 hop. Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
Diffstat (limited to 'bfdd')
-rw-r--r--bfdd/bfd.c12
-rw-r--r--bfdd/bfd.h5
-rw-r--r--bfdd/bfd_packet.c6
-rw-r--r--bfdd/bfdctl.h3
-rw-r--r--bfdd/bfdd_cli.c51
-rw-r--r--bfdd/bfdd_nb.c16
-rw-r--r--bfdd/bfdd_nb.h8
-rw-r--r--bfdd/bfdd_nb_config.c87
-rw-r--r--bfdd/bfdd_vty.c4
-rw-r--r--bfdd/ptm_adapter.c14
10 files changed, 200 insertions, 6 deletions
diff --git a/bfdd/bfd.c b/bfdd/bfd.c
index 1fc922475..2b3caa6fe 100644
--- a/bfdd/bfd.c
+++ b/bfdd/bfd.c
@@ -89,6 +89,7 @@ static void bfd_profile_set_default(struct bfd_profile *bp)
bp->detection_multiplier = BFD_DEFDETECTMULT;
bp->echo_mode = false;
bp->passive = false;
+ bp->minimum_ttl = BFD_DEF_MHOP_TTL;
bp->min_echo_rx = BFD_DEF_REQ_MIN_ECHO;
bp->min_rx = BFD_DEFREQUIREDMINRX;
bp->min_tx = BFD_DEFDESIREDMINTX;
@@ -190,6 +191,12 @@ void bfd_session_apply(struct bfd_session *bs)
bfd_set_echo(bs, bp->echo_mode);
else
bfd_set_echo(bs, bs->peer_profile.echo_mode);
+ } else {
+ /* Configure the TTL packet filter. */
+ if (bs->peer_profile.minimum_ttl == BFD_DEF_MHOP_TTL)
+ bs->mh_ttl = bp->minimum_ttl;
+ else
+ bs->mh_ttl = bs->peer_profile.minimum_ttl;
}
/* Toggle 'passive-mode' if default value. */
@@ -752,6 +759,11 @@ static void _bfd_session_update(struct bfd_session *bs,
else
UNSET_FLAG(bs->flags, BFD_SESS_FLAG_CBIT);
+ if (bpc->bpc_has_minimum_ttl) {
+ bs->mh_ttl = bpc->bpc_minimum_ttl;
+ bs->peer_profile.minimum_ttl = bpc->bpc_minimum_ttl;
+ }
+
bs->peer_profile.echo_mode = bpc->bpc_echo;
bfd_set_echo(bs, bpc->bpc_echo);
diff --git a/bfdd/bfd.h b/bfdd/bfd.h
index 4f88e6b2e..af3f92d6a 100644
--- a/bfdd/bfd.h
+++ b/bfdd/bfd.h
@@ -210,6 +210,8 @@ struct bfd_profile {
bool admin_shutdown;
/** Passive mode. */
bool passive;
+ /** Minimum expected TTL value. */
+ uint8_t minimum_ttl;
/** Echo mode (only applies to single hop). */
bool echo_mode;
@@ -331,7 +333,8 @@ TAILQ_HEAD(obslist, bfd_session_observer);
#define BFD_DEFREQUIREDMINRX (300 * 1000) /* microseconds. */
#define BFD_DEF_REQ_MIN_ECHO (50 * 1000) /* microseconds. */
#define BFD_DEF_SLOWTX (1000 * 1000) /* microseconds. */
-#define BFD_DEF_MHOP_TTL 5
+/** Minimum multi hop TTL. */
+#define BFD_DEF_MHOP_TTL 254
#define BFD_PKT_LEN 24 /* Length of control packet */
#define BFD_TTL_VAL 255
#define BFD_RCV_TTL_VAL 1
diff --git a/bfdd/bfd_packet.c b/bfdd/bfd_packet.c
index 68bdd89bb..38855acff 100644
--- a/bfdd/bfd_packet.c
+++ b/bfdd/bfd_packet.c
@@ -577,7 +577,7 @@ int bfd_recv_cb(struct thread *t)
return 0;
}
- /* Validate packet TTL. */
+ /* Validate single hop packet TTL. */
if ((!is_mhop) && (ttl != BFD_TTL_VAL)) {
cp_debug(is_mhop, &peer, &local, ifindex, vrfid,
"invalid TTL: %d expected %d", ttl, BFD_TTL_VAL);
@@ -630,10 +630,10 @@ int bfd_recv_cb(struct thread *t)
* Single hop: set local address that received the packet.
*/
if (is_mhop) {
- if ((BFD_TTL_VAL - bfd->mh_ttl) > BFD_TTL_VAL) {
+ if (ttl < bfd->mh_ttl) {
cp_debug(is_mhop, &peer, &local, ifindex, vrfid,
"exceeded max hop count (expected %d, got %d)",
- bfd->mh_ttl, BFD_TTL_VAL);
+ bfd->mh_ttl, ttl);
return 0;
}
} else if (bfd->local_address.sa_sin.sin_family == AF_UNSPEC) {
diff --git a/bfdd/bfdctl.h b/bfdd/bfdctl.h
index 3cb2fba49..e1cff9a31 100644
--- a/bfdd/bfdctl.h
+++ b/bfdd/bfdctl.h
@@ -84,6 +84,9 @@ struct bfd_peer_cfg {
bool bpc_has_echointerval;
uint64_t bpc_echointerval;
+ bool bpc_has_minimum_ttl;
+ uint8_t bpc_minimum_ttl;
+
bool bpc_echo;
bool bpc_createonly;
bool bpc_shutdown;
diff --git a/bfdd/bfdd_cli.c b/bfdd/bfdd_cli.c
index e70354de0..058ce7d1f 100644
--- a/bfdd/bfdd_cli.c
+++ b/bfdd/bfdd_cli.c
@@ -287,6 +287,42 @@ void bfd_cli_show_passive(struct vty *vty, struct lyd_node *dnode,
}
DEFPY_YANG(
+ bfd_peer_minimum_ttl, bfd_peer_minimum_ttl_cmd,
+ "[no] minimum-ttl (1-254)$ttl",
+ NO_STR
+ "Expect packets with at least this TTL\n"
+ "Minimum TTL expected\n")
+{
+ if (no)
+ nb_cli_enqueue_change(vty, "./minimum-ttl", NB_OP_DESTROY,
+ NULL);
+ else
+ nb_cli_enqueue_change(vty, "./minimum-ttl", NB_OP_MODIFY,
+ ttl_str);
+ return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY_YANG(
+ no_bfd_peer_minimum_ttl, no_bfd_peer_minimum_ttl_cmd,
+ "no minimum-ttl",
+ NO_STR
+ "Expect packets with at least this TTL\n")
+{
+ nb_cli_enqueue_change(vty, "./minimum-ttl", NB_OP_DESTROY, NULL);
+ return nb_cli_apply_changes(vty, NULL);
+}
+
+void bfd_cli_show_minimum_ttl(struct vty *vty, struct lyd_node *dnode,
+ bool show_defaults)
+{
+ if (show_defaults)
+ vty_out(vty, " minimum-ttl 254\n");
+ else
+ vty_out(vty, " minimum-ttl %s\n",
+ yang_dnode_get_string(dnode, NULL));
+}
+
+DEFPY_YANG(
bfd_peer_mult, bfd_peer_mult_cmd,
"detect-multiplier (2-255)$multiplier",
"Configure peer detection multiplier\n"
@@ -488,6 +524,17 @@ ALIAS_YANG(bfd_peer_passive, bfd_profile_passive_cmd,
NO_STR
"Don't attempt to start sessions\n")
+ALIAS_YANG(bfd_peer_minimum_ttl, bfd_profile_minimum_ttl_cmd,
+ "[no] minimum-ttl (1-254)$ttl",
+ NO_STR
+ "Expect packets with at least this TTL\n"
+ "Minimum TTL expected\n")
+
+ALIAS_YANG(no_bfd_peer_minimum_ttl, no_bfd_profile_minimum_ttl_cmd,
+ "no minimum-ttl",
+ NO_STR
+ "Expect packets with at least this TTL\n")
+
ALIAS_YANG(bfd_peer_echo, bfd_profile_echo_cmd,
"[no] echo-mode",
NO_STR
@@ -557,6 +604,8 @@ bfdd_cli_init(void)
install_element(BFD_PEER_NODE, &bfd_peer_echo_interval_cmd);
install_element(BFD_PEER_NODE, &bfd_peer_profile_cmd);
install_element(BFD_PEER_NODE, &bfd_peer_passive_cmd);
+ install_element(BFD_PEER_NODE, &bfd_peer_minimum_ttl_cmd);
+ install_element(BFD_PEER_NODE, &no_bfd_peer_minimum_ttl_cmd);
/* Profile commands. */
cmd_variable_handler_register(bfd_vars);
@@ -574,4 +623,6 @@ bfdd_cli_init(void)
install_element(BFD_PROFILE_NODE, &bfd_profile_echo_cmd);
install_element(BFD_PROFILE_NODE, &bfd_profile_echo_interval_cmd);
install_element(BFD_PROFILE_NODE, &bfd_profile_passive_cmd);
+ install_element(BFD_PROFILE_NODE, &bfd_profile_minimum_ttl_cmd);
+ install_element(BFD_PROFILE_NODE, &no_bfd_profile_minimum_ttl_cmd);
}
diff --git a/bfdd/bfdd_nb.c b/bfdd/bfdd_nb.c
index cf063f82f..64ba3cf81 100644
--- a/bfdd/bfdd_nb.c
+++ b/bfdd/bfdd_nb.c
@@ -84,6 +84,14 @@ const struct frr_yang_module_info frr_bfdd_info = {
.cli_show = bfd_cli_show_passive,
}
},
+ {
+ .xpath = "/frr-bfdd:bfdd/bfd/profile/minimum-ttl",
+ .cbs = {
+ .modify = bfdd_bfd_profile_minimum_ttl_modify,
+ .destroy = bfdd_bfd_profile_minimum_ttl_destroy,
+ .cli_show = bfd_cli_show_minimum_ttl,
+ }
+ },
{
.xpath = "/frr-bfdd:bfdd/bfd/profile/echo-mode",
.cbs = {
@@ -350,6 +358,14 @@ const struct frr_yang_module_info frr_bfdd_info = {
}
},
{
+ .xpath = "/frr-bfdd:bfdd/bfd/sessions/multi-hop/minimum-ttl",
+ .cbs = {
+ .modify = bfdd_bfd_sessions_multi_hop_minimum_ttl_modify,
+ .destroy = bfdd_bfd_sessions_multi_hop_minimum_ttl_destroy,
+ .cli_show = bfd_cli_show_minimum_ttl,
+ }
+ },
+ {
.xpath = "/frr-bfdd:bfdd/bfd/sessions/multi-hop/stats/local-discriminator",
.cbs = {
.get_elem = bfdd_bfd_sessions_single_hop_stats_local_discriminator_get_elem,
diff --git a/bfdd/bfdd_nb.h b/bfdd/bfdd_nb.h
index ec467f357..fbd557b6b 100644
--- a/bfdd/bfdd_nb.h
+++ b/bfdd/bfdd_nb.h
@@ -38,6 +38,8 @@ int bfdd_bfd_profile_required_receive_interval_modify(
struct nb_cb_modify_args *args);
int bfdd_bfd_profile_administrative_down_modify(struct nb_cb_modify_args *args);
int bfdd_bfd_profile_passive_mode_modify(struct nb_cb_modify_args *args);
+int bfdd_bfd_profile_minimum_ttl_modify(struct nb_cb_modify_args *args);
+int bfdd_bfd_profile_minimum_ttl_destroy(struct nb_cb_destroy_args *args);
int bfdd_bfd_profile_echo_mode_modify(struct nb_cb_modify_args *args);
int bfdd_bfd_profile_desired_echo_transmission_interval_modify(
struct nb_cb_modify_args *args);
@@ -134,6 +136,10 @@ int bfdd_bfd_sessions_multi_hop_required_receive_interval_modify(
struct nb_cb_modify_args *args);
int bfdd_bfd_sessions_multi_hop_administrative_down_modify(
struct nb_cb_modify_args *args);
+int bfdd_bfd_sessions_multi_hop_minimum_ttl_modify(
+ struct nb_cb_modify_args *args);
+int bfdd_bfd_sessions_multi_hop_minimum_ttl_destroy(
+ struct nb_cb_destroy_args *args);
struct yang_data *
bfdd_bfd_sessions_multi_hop_stats_local_discriminator_get_elem(
struct nb_cb_get_elem_args *args);
@@ -211,5 +217,7 @@ void bfd_cli_peer_profile_show(struct vty *vty, struct lyd_node *dnode,
bool show_defaults);
void bfd_cli_show_passive(struct vty *vty, struct lyd_node *dnode,
bool show_defaults);
+void bfd_cli_show_minimum_ttl(struct vty *vty, struct lyd_node *dnode,
+ bool show_defaults);
#endif /* _FRR_BFDD_NB_H_ */
diff --git a/bfdd/bfdd_nb_config.c b/bfdd/bfdd_nb_config.c
index 527c6d83a..0046bc625 100644
--- a/bfdd/bfdd_nb_config.c
+++ b/bfdd/bfdd_nb_config.c
@@ -382,6 +382,42 @@ int bfdd_bfd_profile_passive_mode_modify(struct nb_cb_modify_args *args)
}
/*
+ * XPath: /frr-bfdd:bfdd/bfd/profile/minimum-ttl
+ */
+int bfdd_bfd_profile_minimum_ttl_modify(struct nb_cb_modify_args *args)
+{
+ struct bfd_profile *bp;
+ uint8_t minimum_ttl;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ minimum_ttl = yang_dnode_get_uint8(args->dnode, NULL);
+ bp = nb_running_get_entry(args->dnode, NULL, true);
+ if (bp->minimum_ttl == minimum_ttl)
+ return NB_OK;
+
+ bp->minimum_ttl = minimum_ttl;
+ bfd_profile_update(bp);
+
+ return NB_OK;
+}
+
+int bfdd_bfd_profile_minimum_ttl_destroy(struct nb_cb_destroy_args *args)
+{
+ struct bfd_profile *bp;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ bp = nb_running_get_entry(args->dnode, NULL, true);
+ bp->minimum_ttl = BFD_DEF_MHOP_TTL;
+ bfd_profile_update(bp);
+
+ return NB_OK;
+}
+
+/*
* XPath: /frr-bfdd:bfdd/bfd/profile/echo-mode
*/
int bfdd_bfd_profile_echo_mode_modify(struct nb_cb_modify_args *args)
@@ -739,3 +775,54 @@ int bfdd_bfd_sessions_multi_hop_destroy(struct nb_cb_destroy_args *args)
{
return bfd_session_destroy(args->event, args->dnode, true);
}
+
+/*
+ * XPath: /frr-bfdd:bfdd/bfd/sessions/multi-hop/minimum-ttl
+ */
+int bfdd_bfd_sessions_multi_hop_minimum_ttl_modify(
+ struct nb_cb_modify_args *args)
+{
+ struct bfd_session *bs;
+
+ switch (args->event) {
+ case NB_EV_VALIDATE:
+ case NB_EV_PREPARE:
+ return NB_OK;
+
+ case NB_EV_APPLY:
+ break;
+
+ case NB_EV_ABORT:
+ return NB_OK;
+ }
+
+ bs = nb_running_get_entry(args->dnode, NULL, true);
+ bs->peer_profile.minimum_ttl = yang_dnode_get_uint8(args->dnode, NULL);
+ bfd_session_apply(bs);
+
+ return NB_OK;
+}
+
+int bfdd_bfd_sessions_multi_hop_minimum_ttl_destroy(
+ struct nb_cb_destroy_args *args)
+{
+ struct bfd_session *bs;
+
+ switch (args->event) {
+ case NB_EV_VALIDATE:
+ case NB_EV_PREPARE:
+ return NB_OK;
+
+ case NB_EV_APPLY:
+ break;
+
+ case NB_EV_ABORT:
+ return NB_OK;
+ }
+
+ bs = nb_running_get_entry(args->dnode, NULL, true);
+ bs->peer_profile.minimum_ttl = BFD_DEF_MHOP_TTL;
+ bfd_session_apply(bs);
+
+ return NB_OK;
+}
diff --git a/bfdd/bfdd_vty.c b/bfdd/bfdd_vty.c
index a532b76f0..a3f1638e5 100644
--- a/bfdd/bfdd_vty.c
+++ b/bfdd/bfdd_vty.c
@@ -115,6 +115,8 @@ static void _display_peer(struct vty *vty, struct bfd_session *bs)
vty_out(vty, "\t\tPassive mode\n");
else
vty_out(vty, "\t\tActive mode\n");
+ if (CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH))
+ vty_out(vty, "\t\tMinimum TTL: %d\n", bs->mh_ttl);
vty_out(vty, "\t\tStatus: ");
switch (bs->ses_state) {
@@ -209,6 +211,8 @@ static struct json_object *__display_peer_json(struct bfd_session *bs)
json_object_int_add(jo, "remote-id", bs->discrs.remote_discr);
json_object_boolean_add(jo, "passive-mode",
CHECK_FLAG(bs->flags, BFD_SESS_FLAG_PASSIVE));
+ if (CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH))
+ json_object_int_add(jo, "minimum-ttl", bs->mh_ttl);
switch (bs->ses_state) {
case PTM_BFD_ADM_DOWN:
diff --git a/bfdd/ptm_adapter.c b/bfdd/ptm_adapter.c
index 8134807a1..48e55bce3 100644
--- a/bfdd/ptm_adapter.c
+++ b/bfdd/ptm_adapter.c
@@ -303,7 +303,6 @@ static int _ptm_msg_read(struct stream *msg, int command, vrf_id_t vrf_id,
struct bfd_peer_cfg *bpc, struct ptm_client **pc)
{
uint32_t pid;
- uint8_t ttl __attribute__((unused));
size_t ifnamelen;
/*
@@ -375,7 +374,18 @@ static int _ptm_msg_read(struct stream *msg, int command, vrf_id_t vrf_id,
if (bpc->bpc_mhop) {
/* Read multihop source address and TTL. */
_ptm_msg_read_address(msg, &bpc->bpc_local);
- STREAM_GETC(msg, ttl);
+ STREAM_GETC(msg, bpc->bpc_minimum_ttl);
+ if (bpc->bpc_minimum_ttl >= BFD_TTL_VAL
+ || bpc->bpc_minimum_ttl == 0) {
+ zlog_warn("%s: received invalid TTL configuration %d",
+ __func__, bpc->bpc_has_minimum_ttl);
+ bpc->bpc_minimum_ttl = BFD_DEF_MHOP_TTL;
+ bpc->bpc_has_minimum_ttl = false;
+ } else {
+ bpc->bpc_minimum_ttl =
+ (BFD_TTL_VAL + 1) - bpc->bpc_minimum_ttl;
+ bpc->bpc_has_minimum_ttl = true;
+ }
} else {
/* If target is IPv6, then we must obtain local address. */
if (bpc->bpc_ipv4 == false)