From e2728c8078161d9811d6c24a11e4c95efd1c9313 Mon Sep 17 00:00:00 2001 From: Job Snijders Date: Thu, 22 Feb 2024 14:58:29 +0100 Subject: [PATCH 1/5] RPKI: Add 'local address' configuration option Allow to explicitly configure the source IP address for RPKI-To-Router sessions. Predictable source addresses are useful for minimizing the holes to be poked in ACLs. Changed from 'source address' to 'local address' by committer. --- doc/bird.sgml | 4 ++++ proto/rpki/config.Y | 3 ++- proto/rpki/rpki.h | 1 + proto/rpki/transport.c | 1 + 4 files changed, 8 insertions(+), 1 deletion(-) diff --git a/doc/bird.sgml b/doc/bird.sgml index 76ca7f75..aeecb1dc 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -5697,6 +5697,7 @@ protocol rpki [<name>] { roa6 { table <tab>; }; remote <ip> | "<domain>" [port <num>]; port <num>; + local address <ip>; refresh [keep] <num>; retry [keep] <num>; expire [keep] <num>; @@ -5726,6 +5727,9 @@ specify both channels. number is 323 for transport without any encryption and 22 for transport with SSH encryption. + local address + Define local address we should use as a source address for the RTR session. + refresh [keep] Time period in seconds. Tells how long to wait before next attempting to poll the cache using a Serial Query or a Reset Query packet. Must be lower than 86400 seconds (one diff --git a/proto/rpki/config.Y b/proto/rpki/config.Y index c28cab7a..769ebb2c 100644 --- a/proto/rpki/config.Y +++ b/proto/rpki/config.Y @@ -32,7 +32,7 @@ rpki_check_unused_transport(void) CF_DECLS CF_KEYWORDS(RPKI, REMOTE, BIRD, PRIVATE, PUBLIC, KEY, TCP, SSH, TRANSPORT, USER, - RETRY, REFRESH, EXPIRE, KEEP, IGNORE, MAX, LENGTH) + RETRY, REFRESH, EXPIRE, KEEP, IGNORE, MAX, LENGTH, LOCAL, ADDRESS) %type rpki_keep_interval @@ -60,6 +60,7 @@ rpki_proto_item: | REMOTE rpki_cache_addr | REMOTE rpki_cache_addr rpki_proto_item_port | rpki_proto_item_port + | LOCAL ADDRESS ipa { RPKI_CFG->local_ip = $3; } | TRANSPORT rpki_transport | REFRESH rpki_keep_interval expr { if (rpki_check_refresh_interval($3)) diff --git a/proto/rpki/rpki.h b/proto/rpki/rpki.h index 8a5c38fd..e67eb0e3 100644 --- a/proto/rpki/rpki.h +++ b/proto/rpki/rpki.h @@ -116,6 +116,7 @@ struct rpki_proto { struct rpki_config { struct proto_config c; const char *hostname; /* Full domain name or stringified IP address of cache server */ + ip_addr local_ip; /* Source address to use */ ip_addr ip; /* IP address of cache server or IPA_NONE */ u16 port; /* Port number of cache server */ struct rpki_tr_config tr_config; /* Specific transport configuration structure */ diff --git a/proto/rpki/transport.c b/proto/rpki/transport.c index 81bd6dd8..26571977 100644 --- a/proto/rpki/transport.c +++ b/proto/rpki/transport.c @@ -82,6 +82,7 @@ rpki_tr_open(struct rpki_tr_sock *tr) sk->daddr = cf->ip; sk->dport = cf->port; sk->host = cf->hostname; + sk->saddr = cf->local_ip; sk->rbsize = RPKI_RX_BUFFER_SIZE; sk->tbsize = RPKI_TX_BUFFER_SIZE; sk->tos = IP_PREC_INTERNET_CONTROL; From 37bf2078434b5de5662d28345bce788624d50ac7 Mon Sep 17 00:00:00 2001 From: Katerina Kubecova Date: Tue, 16 Jan 2024 11:02:22 +0100 Subject: [PATCH 2/5] BFD: show bfd sessions all --- proto/bfd/bfd.c | 76 ++++++++++++++++++++++++++++++++++++++++------ proto/bfd/bfd.h | 2 +- proto/bfd/config.Y | 5 ++- 3 files changed, 71 insertions(+), 12 deletions(-) diff --git a/proto/bfd/bfd.c b/proto/bfd/bfd.c index adeb729c..080ce909 100644 --- a/proto/bfd/bfd.c +++ b/proto/bfd/bfd.c @@ -117,6 +117,7 @@ static list STATIC_LIST_INIT(bfd_proto_list); static list STATIC_LIST_INIT(bfd_wait_list); const char *bfd_state_names[] = { "AdminDown", "Down", "Init", "Up" }; +const char *bfd_diag_names[] = { "Nothing", "Timeout", "Echo failed", "Neighbor down", "Fwd reset", "Path down", "C path down", "Admin down", "RC path down" }; static void bfd_session_set_min_tx(struct bfd_session *s, u32 val); static struct bfd_iface *bfd_get_iface(struct bfd_proto *p, ip_addr local, struct iface *iface); @@ -1143,8 +1144,55 @@ bfd_copy_config(struct proto_config *dest, struct proto_config *src UNUSED) init_list(&d->neigh_list); } +void bfd_show_details(struct bfd_session *s) +{ + cli_msg(-1020, " IP address: %I", s->addr); + cli_msg(-1020, " Interface: %s", (s->ifa && s->ifa->iface) ? s->ifa->iface->name : "---"); + cli_msg(-1020, " Role: %s", (s->passive) ? "Passive" : "Active"); + cli_msg(-1020, " Local session:"); + cli_msg(-1020, " State: %s", bfd_state_names[s->loc_state]); + cli_msg(-1020, " Session ID: %u", s->loc_id); + if (s->loc_diag || s->rem_diag) + cli_msg(-1020, " Issue: %s", bfd_diag_names[s->loc_diag]); + + cli_msg(-1020, " Remote session:"); + cli_msg(-1020, " State: %s", bfd_state_names[s->rem_state]); + cli_msg(-1020, " Session ID: %u", s->loc_id, s->rem_id); + if (s->loc_diag || s->rem_diag) + cli_msg(-1020, " Issue: %s", bfd_diag_names[s->rem_diag]); + + cli_msg(-1020, " Session mode: %s", (s->rem_demand_mode) ? "Demand" : "Asynchronous"); + if (!s->rem_demand_mode) + { + cli_msg(-1020, " Local intervals:"); + cli_msg(-1020, " Desired min tx: %t", s->des_min_tx_int); + cli_msg(-1020, " Required min rx: %t", s->req_min_rx_int); + cli_msg(-1020, " Remote intervals:"); + cli_msg(-1020, " Desired min tx: %t", s->rem_min_tx_int); + cli_msg(-1020, " Required min rx: %t", s->rem_min_rx_int); + cli_msg(-1020, " Timers:"); + cli_msg(-1020, " Hold timer remains %t/%t", tm_remains(s->hold_timer), MAX(s->req_min_rx_int, s->rem_min_tx_int) * s->rem_detect_mult); // The total time is just copied from timers setings. I hope it is not (and will not) be problem. + cli_msg(-1020, " TX timer remains %t", tm_remains(s->tx_timer)); + } + else if (tm_remains(s->hold_timer) > 0) + { + cli_msg(-1020, " Hold timer remains %t", tm_remains(s->hold_timer)); + } + cli_msg(-1020, " Latest actions:"); + cli_msg(-1020, " Last received valid control packet before %t", current_time() - s->last_rx); + cli_msg(-1020, " Last sent periodic control packet before %t", current_time() - s->last_tx); + btime tim = (btime)(((u64) s->tx_csn_time) << 20); + if (tim > 0) + cli_msg(-1020, " Last csn change before %t", current_time() - tim); + if (s->poll_active || s->poll_scheduled) + cli_msg(-1020, " Poll %s%s", (s->poll_active) ? ", poll active" : "", (s->poll_scheduled) ? ", poll scheduled" : ""); + else + cli_msg(-1020, " Poll inactive"); + cli_msg(-1020, ""); +} + void -bfd_show_sessions(struct proto *P) +bfd_show_sessions(struct proto *P, int details) { byte tbuf[TM_DATETIME_BUFFER_SIZE]; struct bfd_proto *p = (struct bfd_proto *) P; @@ -1159,24 +1207,32 @@ bfd_show_sessions(struct proto *P) } cli_msg(-1020, "%s:", p->p.name); - cli_msg(-1020, "%-25s %-10s %-10s %-12s %8s %8s", + if (!details) + cli_msg(-1020, "%-25s %-10s %-10s %-12s %8s %8s", "IP address", "Interface", "State", "Since", "Interval", "Timeout"); HASH_WALK(p->session_hash_id, next_id, s) { /* FIXME: this is thread-unsafe, but perhaps harmless */ - state = s->loc_state; - diag = s->loc_diag; - ifname = (s->ifa && s->ifa->iface) ? s->ifa->iface->name : "---"; - tx_int = s->last_tx ? MAX(s->des_min_tx_int, s->rem_min_rx_int) : 0; - timeout = (btime) MAX(s->req_min_rx_int, s->rem_min_tx_int) * s->rem_detect_mult; + if (!details) + { + state = s->loc_state; + diag = s->loc_diag; + ifname = (s->ifa && s->ifa->iface) ? s->ifa->iface->name : "---"; + tx_int = s->last_tx ? MAX(s->des_min_tx_int, s->rem_min_rx_int) : 0; + timeout = (btime) MAX(s->req_min_rx_int, s->rem_min_tx_int) * s->rem_detect_mult; - state = (state < 4) ? state : 0; - tm_format_time(tbuf, &config->tf_proto, s->last_state_change); + state = (state < 4) ? state : 0; + tm_format_time(tbuf, &config->tf_proto, s->last_state_change); - cli_msg(-1020, "%-25I %-10s %-10s %-12s %7t %7t", + cli_msg(-1020, "%-25I %-10s %-10s %-12s %7t %7t", s->addr, ifname, bfd_state_names[state], tbuf, tx_int, timeout); + } + else + { + bfd_show_details(s); + } } HASH_WALK_END; } diff --git a/proto/bfd/bfd.h b/proto/bfd/bfd.h index 7caf9f66..a68a45ad 100644 --- a/proto/bfd/bfd.h +++ b/proto/bfd/bfd.h @@ -218,7 +218,7 @@ static inline void bfd_unlock_sessions(struct bfd_proto *p) { pthread_spin_unloc struct bfd_session * bfd_find_session_by_id(struct bfd_proto *p, u32 id); struct bfd_session * bfd_find_session_by_addr(struct bfd_proto *p, ip_addr addr, uint ifindex); void bfd_session_process_ctl(struct bfd_session *s, u8 flags, u32 old_tx_int, u32 old_rx_int); -void bfd_show_sessions(struct proto *P); +void bfd_show_sessions(struct proto *P, int details); /* packets.c */ void bfd_send_ctl(struct bfd_proto *p, struct bfd_session *s, int final); diff --git a/proto/bfd/config.Y b/proto/bfd/config.Y index d9a154b2..41f8cbdf 100644 --- a/proto/bfd/config.Y +++ b/proto/bfd/config.Y @@ -184,7 +184,10 @@ bfd_neighbor: ipa bfd_neigh_iface bfd_neigh_local bfd_neigh_multihop CF_CLI_HELP(SHOW BFD, ..., [[Show information about BFD protocol]]); CF_CLI(SHOW BFD SESSIONS, optproto, [], [[Show information about BFD sessions]]) -{ PROTO_WALK_CMD($4, &proto_bfd, p) bfd_show_sessions(p); }; +{ PROTO_WALK_CMD($4, &proto_bfd, p) bfd_show_sessions(p, 0); }; + +CF_CLI(SHOW BFD SESSIONS ALL, optproto, [], [[Show information about BFD sessions]]) +{ PROTO_WALK_CMD($5, &proto_bfd, p) bfd_show_sessions(p, 1); }; CF_CODE From a48dc5efe05f4e985b648f19679865153d0398bd Mon Sep 17 00:00:00 2001 From: Katerina Kubecova Date: Thu, 18 Jan 2024 12:36:48 +0100 Subject: [PATCH 3/5] BFD: Show session for ip / ip prefix --- proto/bfd/bfd.c | 5 ++++- proto/bfd/bfd.h | 2 +- proto/bfd/config.Y | 20 ++++++++++++++++---- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/proto/bfd/bfd.c b/proto/bfd/bfd.c index 080ce909..61ceea50 100644 --- a/proto/bfd/bfd.c +++ b/proto/bfd/bfd.c @@ -1192,7 +1192,7 @@ void bfd_show_details(struct bfd_session *s) } void -bfd_show_sessions(struct proto *P, int details) +bfd_show_sessions(struct proto *P, int details, net_addr addr) { byte tbuf[TM_DATETIME_BUFFER_SIZE]; struct bfd_proto *p = (struct bfd_proto *) P; @@ -1215,6 +1215,9 @@ bfd_show_sessions(struct proto *P, int details) HASH_WALK(p->session_hash_id, next_id, s) { /* FIXME: this is thread-unsafe, but perhaps harmless */ + + if (addr.type != 0 && !ipa_in_netX(s->addr, &addr)) + continue; if (!details) { state = s->loc_state; diff --git a/proto/bfd/bfd.h b/proto/bfd/bfd.h index a68a45ad..83c1c884 100644 --- a/proto/bfd/bfd.h +++ b/proto/bfd/bfd.h @@ -218,7 +218,7 @@ static inline void bfd_unlock_sessions(struct bfd_proto *p) { pthread_spin_unloc struct bfd_session * bfd_find_session_by_id(struct bfd_proto *p, u32 id); struct bfd_session * bfd_find_session_by_addr(struct bfd_proto *p, ip_addr addr, uint ifindex); void bfd_session_process_ctl(struct bfd_session *s, u8 flags, u32 old_tx_int, u32 old_rx_int); -void bfd_show_sessions(struct proto *P, int details); +void bfd_show_sessions(struct proto *P, int details, net_addr addr); /* packets.c */ void bfd_send_ctl(struct bfd_proto *p, struct bfd_session *s, int final); diff --git a/proto/bfd/config.Y b/proto/bfd/config.Y index 41f8cbdf..da687b5f 100644 --- a/proto/bfd/config.Y +++ b/proto/bfd/config.Y @@ -29,6 +29,7 @@ CF_KEYWORDS(BFD, MIN, IDLE, RX, TX, INTERVAL, MULTIPLIER, PASSIVE, %type bfd_neigh_iface %type bfd_neigh_local %type bfd_neigh_multihop bfd_auth_type +%type opt_addr CF_GRAMMAR @@ -181,13 +182,24 @@ bfd_neighbor: ipa bfd_neigh_iface bfd_neigh_local bfd_neigh_multihop cf_error("Multihop neighbor requires specified local address"); }; +opt_addr: + /* empty */ { + net_addr addr; + addr.type = 0; + $$ = addr; } + | net_ip4_ + | net_ip6_ + | IP4 { net_fill_ip4(&($$), $1, IP4_MAX_PREFIX_LENGTH); } + | IP6 { net_fill_ip6(&($$), $1, IP6_MAX_PREFIX_LENGTH); } + + CF_CLI_HELP(SHOW BFD, ..., [[Show information about BFD protocol]]); -CF_CLI(SHOW BFD SESSIONS, optproto, [], [[Show information about BFD sessions]]) -{ PROTO_WALK_CMD($4, &proto_bfd, p) bfd_show_sessions(p, 0); }; +CF_CLI(SHOW BFD SESSIONS, optproto opt_addr, [] [], [[Show information about BFD sessions]]) +{ PROTO_WALK_CMD($4, &proto_bfd, p) bfd_show_sessions(p, 0, $5); }; -CF_CLI(SHOW BFD SESSIONS ALL, optproto, [], [[Show information about BFD sessions]]) -{ PROTO_WALK_CMD($5, &proto_bfd, p) bfd_show_sessions(p, 1); }; +CF_CLI(SHOW BFD SESSIONS ALL, optproto opt_addr, [] [], [[Show information about BFD sessions]]) +{ PROTO_WALK_CMD($5, &proto_bfd, p) bfd_show_sessions(p, 1, $6); }; CF_CODE From 4737937375c657794d608ea02cefa289531d763a Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Fri, 1 Mar 2024 18:39:09 +0100 Subject: [PATCH 4/5] BFD: Improve 'show bfd sessions all' command --- proto/bfd/bfd.c | 165 ++++++++++++++++++++++++++++++------------------ 1 file changed, 103 insertions(+), 62 deletions(-) diff --git a/proto/bfd/bfd.c b/proto/bfd/bfd.c index 61ceea50..b9461085 100644 --- a/proto/bfd/bfd.c +++ b/proto/bfd/bfd.c @@ -117,7 +117,43 @@ static list STATIC_LIST_INIT(bfd_proto_list); static list STATIC_LIST_INIT(bfd_wait_list); const char *bfd_state_names[] = { "AdminDown", "Down", "Init", "Up" }; -const char *bfd_diag_names[] = { "Nothing", "Timeout", "Echo failed", "Neighbor down", "Fwd reset", "Path down", "C path down", "Admin down", "RC path down" }; + +const char *bfd_diag_names[] = { + [BFD_DIAG_NOTHING] = "None", + [BFD_DIAG_TIMEOUT] = "Time expired", + [BFD_DIAG_ECHO_FAILED] = "Echo failed", + [BFD_DIAG_NEIGHBOR_DOWN] = "Neighbor down", + [BFD_DIAG_FWD_RESET] = "Fwd plane reset", + [BFD_DIAG_PATH_DOWN] = "Path down", + [BFD_DIAG_C_PATH_DOWN] = "Concat path down", + [BFD_DIAG_ADMIN_DOWN] = "Admin down", + [BFD_DIAG_RC_PATH_DOWN] = "Rev concat path down", +}; + +const char *bfd_auth_names[] = { + [BFD_AUTH_NONE] = "None", + [BFD_AUTH_SIMPLE] = "Simple", + [BFD_AUTH_KEYED_MD5] = "Keyed MD5", + [BFD_AUTH_METICULOUS_KEYED_MD5] = "Meticulous keyed MD5", + [BFD_AUTH_KEYED_SHA1] = "Keyed SHA1", + [BFD_AUTH_METICULOUS_KEYED_SHA1] = "Meticulous keyed SHA1", +}; + +#define BFD_DIAG_BUFFER_SIZE 16 + +static inline const char * +bfd_diag_name(u8 id, char buf[BFD_DIAG_BUFFER_SIZE]) +{ + return (id < ARRAY_SIZE(bfd_diag_names)) ? + bfd_diag_names[id] : + (bsprintf(buf, "Error #%u", (uint) id), buf); +} + +static inline const char * +bfd_auth_name(u8 id) +{ + return (id < ARRAY_SIZE(bfd_auth_names)) ? bfd_auth_names[id] : "?"; +} static void bfd_session_set_min_tx(struct bfd_session *s, u32 val); static struct bfd_iface *bfd_get_iface(struct bfd_proto *p, ip_addr local, struct iface *iface); @@ -1144,61 +1180,85 @@ bfd_copy_config(struct proto_config *dest, struct proto_config *src UNUSED) init_list(&d->neigh_list); } -void bfd_show_details(struct bfd_session *s) +void +bfd_show_session(struct bfd_session *s, int details) { - cli_msg(-1020, " IP address: %I", s->addr); - cli_msg(-1020, " Interface: %s", (s->ifa && s->ifa->iface) ? s->ifa->iface->name : "---"); - cli_msg(-1020, " Role: %s", (s->passive) ? "Passive" : "Active"); - cli_msg(-1020, " Local session:"); - cli_msg(-1020, " State: %s", bfd_state_names[s->loc_state]); - cli_msg(-1020, " Session ID: %u", s->loc_id); - if (s->loc_diag || s->rem_diag) - cli_msg(-1020, " Issue: %s", bfd_diag_names[s->loc_diag]); + /* FIXME: this is thread-unsafe, but perhaps harmless */ - cli_msg(-1020, " Remote session:"); - cli_msg(-1020, " State: %s", bfd_state_names[s->rem_state]); - cli_msg(-1020, " Session ID: %u", s->loc_id, s->rem_id); - if (s->loc_diag || s->rem_diag) - cli_msg(-1020, " Issue: %s", bfd_diag_names[s->rem_diag]); + u8 loc_state = s->loc_state; + u8 rem_state = s->rem_state; + u8 loc_diag = s->loc_diag; + u8 rem_diag = s->rem_diag; + uint loc_id = s->loc_id; + uint rem_id = s->rem_id; - cli_msg(-1020, " Session mode: %s", (s->rem_demand_mode) ? "Demand" : "Asynchronous"); - if (!s->rem_demand_mode) + const char *ifname = (s->ifa && s->ifa->iface) ? s->ifa->iface->name : "---"; + btime tx_int = s->last_tx ? MAX(s->des_min_tx_int, s->rem_min_rx_int) : 0; + btime timeout = (btime) MAX(s->req_min_rx_int, s->rem_min_tx_int) * s->rem_detect_mult; + u8 auth_type = s->ifa->cf->auth_type; + + loc_state = (loc_state < 4) ? loc_state : 0; + rem_state = (rem_state < 4) ? rem_state : 0; + + byte dbuf[BFD_DIAG_BUFFER_SIZE]; + byte tbuf[TM_DATETIME_BUFFER_SIZE]; + tm_format_time(tbuf, &config->tf_proto, s->last_state_change); + + if (!details) { - cli_msg(-1020, " Local intervals:"); - cli_msg(-1020, " Desired min tx: %t", s->des_min_tx_int); - cli_msg(-1020, " Required min rx: %t", s->req_min_rx_int); - cli_msg(-1020, " Remote intervals:"); - cli_msg(-1020, " Desired min tx: %t", s->rem_min_tx_int); - cli_msg(-1020, " Required min rx: %t", s->rem_min_rx_int); - cli_msg(-1020, " Timers:"); - cli_msg(-1020, " Hold timer remains %t/%t", tm_remains(s->hold_timer), MAX(s->req_min_rx_int, s->rem_min_tx_int) * s->rem_detect_mult); // The total time is just copied from timers setings. I hope it is not (and will not) be problem. - cli_msg(-1020, " TX timer remains %t", tm_remains(s->tx_timer)); + cli_msg(-1020, "%-25I %-10s %-10s %-12s %7t %7t", + s->addr, ifname, bfd_state_names[loc_state], tbuf, tx_int, timeout); + + return; } - else if (tm_remains(s->hold_timer) > 0) + + cli_msg(-1020, " %-21s %I", "Address:", s->addr); + cli_msg(-1020, " %-21s %s", "Interface:", ifname); + cli_msg(-1020, " %-21s %s", "Session type:", s->ifa->iface ? "Direct" : "Multihop"); + cli_msg(-1020, " %-21s %s", "Session state:", bfd_state_names[loc_state]); + cli_msg(-1020, " %-21s %s", "Remote state:", bfd_state_names[rem_state]); + cli_msg(-1020, " %-21s %s", "Last state change:", tbuf); + cli_msg(-1020, " %-21s %s", "Local diagnostic:", bfd_diag_name(loc_diag, dbuf)); + cli_msg(-1020, " %-21s %s", "Remote diagnostic:", bfd_diag_name(rem_diag, dbuf)); + cli_msg(-1020, " %-21s %u", "Local discriminator:", loc_id); + cli_msg(-1020, " %-21s %u", "Remote discriminator:", rem_id); + + if (tm_active(s->tx_timer)) + cli_msg(-1020, " %-21s %t / %t", "Transmit timer:", tm_remains(s->tx_timer), tx_int); + + if (tm_active(s->hold_timer)) + cli_msg(-1020, " %-21s %t / %t", "Detect timer:", tm_remains(s->hold_timer), timeout); + + cli_msg(-1020, " Local parameters:"); + cli_msg(-1020, " %-19s %t", "Min TX interval:", (btime) s->des_min_tx_int); + cli_msg(-1020, " %-19s %t", "Min RX interval:", (btime) s->req_min_rx_int); + cli_msg(-1020, " %-19s %s", "Demand mode:", s->demand_mode ? "Yes" : "No"); + cli_msg(-1020, " %-19s %i", "Multiplier:", s->detect_mult); + cli_msg(-1020, " Remote parameters:"); + cli_msg(-1020, " %-19s %t", "Min TX interval:", (btime) s->rem_min_tx_int); + cli_msg(-1020, " %-19s %t", "Min RX interval:", (btime) s->rem_min_rx_int); + cli_msg(-1020, " %-19s %s", "Demand mode:", s->rem_demand_mode ? "Yes" : "No"); + cli_msg(-1020, " %-19s %i", "Multiplier:", s->rem_detect_mult); + + if (auth_type) { - cli_msg(-1020, " Hold timer remains %t", tm_remains(s->hold_timer)); + cli_msg(-1020, " Authentication:"); + cli_msg(-1020, " %-19s %s", "Type:", bfd_auth_name(auth_type)); + + if (s->rx_csn_known) + cli_msg(-1020, " %-19s %u", "RX CSN:", s->rx_csn); + + if (auth_type > BFD_AUTH_SIMPLE) + cli_msg(-1020, " %-19s %u", "TX CSN:", s->tx_csn); } - cli_msg(-1020, " Latest actions:"); - cli_msg(-1020, " Last received valid control packet before %t", current_time() - s->last_rx); - cli_msg(-1020, " Last sent periodic control packet before %t", current_time() - s->last_tx); - btime tim = (btime)(((u64) s->tx_csn_time) << 20); - if (tim > 0) - cli_msg(-1020, " Last csn change before %t", current_time() - tim); - if (s->poll_active || s->poll_scheduled) - cli_msg(-1020, " Poll %s%s", (s->poll_active) ? ", poll active" : "", (s->poll_scheduled) ? ", poll scheduled" : ""); - else - cli_msg(-1020, " Poll inactive"); + cli_msg(-1020, ""); } void bfd_show_sessions(struct proto *P, int details, net_addr addr) { - byte tbuf[TM_DATETIME_BUFFER_SIZE]; struct bfd_proto *p = (struct bfd_proto *) P; - uint state, diag UNUSED; - btime tx_int, timeout; - const char *ifname; if (p->p.proto_state != PS_UP) { @@ -1211,31 +1271,12 @@ bfd_show_sessions(struct proto *P, int details, net_addr addr) cli_msg(-1020, "%-25s %-10s %-10s %-12s %8s %8s", "IP address", "Interface", "State", "Since", "Interval", "Timeout"); - HASH_WALK(p->session_hash_id, next_id, s) { - /* FIXME: this is thread-unsafe, but perhaps harmless */ - if (addr.type != 0 && !ipa_in_netX(s->addr, &addr)) continue; - if (!details) - { - state = s->loc_state; - diag = s->loc_diag; - ifname = (s->ifa && s->ifa->iface) ? s->ifa->iface->name : "---"; - tx_int = s->last_tx ? MAX(s->des_min_tx_int, s->rem_min_rx_int) : 0; - timeout = (btime) MAX(s->req_min_rx_int, s->rem_min_tx_int) * s->rem_detect_mult; - state = (state < 4) ? state : 0; - tm_format_time(tbuf, &config->tf_proto, s->last_state_change); - - cli_msg(-1020, "%-25I %-10s %-10s %-12s %7t %7t", - s->addr, ifname, bfd_state_names[state], tbuf, tx_int, timeout); - } - else - { - bfd_show_details(s); - } + bfd_show_session(s, details); } HASH_WALK_END; } From 26dd61ee7f91c15157601b2404de5b6500a6061c Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Mon, 4 Mar 2024 23:20:53 +0100 Subject: [PATCH 5/5] BFD: Add arguments to 'show bfd sessions' command Add several arguments to 'show bfd sessions' command to filter the list of sessions. --- conf/confbase.Y | 1 + doc/bird.sgml | 5 +++-- proto/bfd/bfd.c | 17 +++++++++++++---- proto/bfd/bfd.h | 13 ++++++++++++- proto/bfd/config.Y | 34 ++++++++++++++++++---------------- 5 files changed, 47 insertions(+), 23 deletions(-) diff --git a/conf/confbase.Y b/conf/confbase.Y index b2471198..ed3c1e6e 100644 --- a/conf/confbase.Y +++ b/conf/confbase.Y @@ -89,6 +89,7 @@ CF_DECLS struct lsadb_show_data *ld; struct mrt_dump_data *md; struct mpls_show_ranges_cmd *msrc; + struct bfd_show_sessions_cmd *bssc; struct iface *iface; void *g; btime time; diff --git a/doc/bird.sgml b/doc/bird.sgml index aeecb1dc..ced927d4 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -1288,8 +1288,9 @@ This argument can be omitted if there exists only a single instance. bfd_neigh_local %type bfd_neigh_multihop bfd_auth_type -%type opt_addr +%type bfd_show_sessions_args CF_GRAMMAR @@ -182,24 +182,26 @@ bfd_neighbor: ipa bfd_neigh_iface bfd_neigh_local bfd_neigh_multihop cf_error("Multihop neighbor requires specified local address"); }; -opt_addr: - /* empty */ { - net_addr addr; - addr.type = 0; - $$ = addr; } - | net_ip4_ - | net_ip6_ - | IP4 { net_fill_ip4(&($$), $1, IP4_MAX_PREFIX_LENGTH); } - | IP6 { net_fill_ip6(&($$), $1, IP6_MAX_PREFIX_LENGTH); } - - CF_CLI_HELP(SHOW BFD, ..., [[Show information about BFD protocol]]); -CF_CLI(SHOW BFD SESSIONS, optproto opt_addr, [] [], [[Show information about BFD sessions]]) -{ PROTO_WALK_CMD($4, &proto_bfd, p) bfd_show_sessions(p, 0, $5); }; -CF_CLI(SHOW BFD SESSIONS ALL, optproto opt_addr, [] [], [[Show information about BFD sessions]]) -{ PROTO_WALK_CMD($5, &proto_bfd, p) bfd_show_sessions(p, 1, $6); }; +CF_CLI_HELP(SHOW BFD SESSIONS, ..., [[Show information about BFD sessions]]); +CF_CLI(SHOW BFD SESSIONS, bfd_show_sessions_args, [] [address ] [(interface|dev) \"\"] [ipv4|ipv6] [direct|multihop] [all], [[Show information about BFD sessions]]) +{ PROTO_WALK_CMD($4->name, &proto_bfd, p) bfd_show_sessions(p, $4); }; + +bfd_show_sessions_args: + /* empty */ { $$ = cfg_allocz(sizeof(struct bfd_show_sessions_cmd)); } + | bfd_show_sessions_args CF_SYM_KNOWN { cf_assert_symbol($2, SYM_PROTO); $$->name = $2; } + | bfd_show_sessions_args ADDRESS net_or_ipa { net_copy(&($$->address), &($3)); } + | bfd_show_sessions_args INTERFACE text { $$->iface = if_get_by_name($3); } + | bfd_show_sessions_args DEV text { $$->iface = if_get_by_name($3); } + | bfd_show_sessions_args ALL { $$->verbose = 1; } + | bfd_show_sessions_args IPV4 { $$->ipv4 = 1; if ($$->ipv6) cf_error("Options 'ipv4' and 'ipv6' are mutually exclusive"); } + | bfd_show_sessions_args IPV6 { $$->ipv6 = 1; if ($$->ipv4) cf_error("Options 'ipv4' and 'ipv6' are mutually exclusive"); } + | bfd_show_sessions_args DIRECT { $$->direct = 1; if ($$->multihop) cf_error("Options 'direct' and 'multihop' are mutually exclusive"); } + | bfd_show_sessions_args MULTIHOP { $$->multihop = 1; if ($$->direct) cf_error("Options 'direct' and 'multihop' are mutually exclusive"); } + ; + CF_CODE