0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-11-09 12:48:43 +00:00

Merge commit '26dd61ee7f91c15157601b2404de5b6500a6061c' into thread-next

This commit is contained in:
Ondrej Zajicek 2024-04-01 03:01:59 +02:00
commit f27d1bae0f
8 changed files with 168 additions and 22 deletions

View File

@ -93,6 +93,7 @@ CF_DECLS
struct lsadb_show_data *ld; struct lsadb_show_data *ld;
struct mrt_dump_data *md; struct mrt_dump_data *md;
struct mpls_show_ranges_cmd *msrc; struct mpls_show_ranges_cmd *msrc;
struct bfd_show_sessions_cmd *bssc;
struct iface *iface; struct iface *iface;
void *g; void *g;
btime time; btime time;

View File

@ -1328,8 +1328,9 @@ This argument can be omitted if there exists only a single instance.
<tag><label id="cli-show-static">show static [<m/name/]</tag> <tag><label id="cli-show-static">show static [<m/name/]</tag>
Show detailed information about static routes. Show detailed information about static routes.
<tag><label id="cli-show-bfd-sessions">show bfd sessions [<m/name/]</tag> <tag><label id="cli-show-bfd-sessions">show bfd sessions [<m/name/] [address (<m/IP/|<m/prefix/)] [(interface|dev) "<m/name/"] [ipv4|ipv6] [direct|multihop] [all]</tag>
Show information about BFD sessions. Show information about BFD sessions. Options could be used to filter
entries, or in the case of the option <cf/all/ to give verbose output.
<tag><label id="cli-show-symbols">show symbols [table|filter|function|protocol|template|roa|<m/symbol/]</tag> <tag><label id="cli-show-symbols">show symbols [table|filter|function|protocol|template|roa|<m/symbol/]</tag>
Show the list of symbols defined in the configuration (names of Show the list of symbols defined in the configuration (names of
@ -5724,6 +5725,7 @@ protocol rpki [&lt;name&gt;] {
roa6 { table &lt;tab&gt;; }; roa6 { table &lt;tab&gt;; };
remote &lt;ip&gt; | "&lt;domain&gt;" [port &lt;num&gt;]; remote &lt;ip&gt; | "&lt;domain&gt;" [port &lt;num&gt;];
port &lt;num&gt;; port &lt;num&gt;;
local address &lt;ip&gt;;
refresh [keep] &lt;num&gt;; refresh [keep] &lt;num&gt;;
retry [keep] &lt;num&gt;; retry [keep] &lt;num&gt;;
expire [keep] &lt;num&gt;; expire [keep] &lt;num&gt;;
@ -5753,6 +5755,9 @@ specify both channels.
number is 323 for transport without any encryption and 22 for transport number is 323 for transport without any encryption and 22 for transport
with SSH encryption. with SSH encryption.
<tag>local address <m/ip/</tag>
Define local address we should use as a source address for the RTR session.
<tag>refresh [keep] <m/num/</tag> Time period in seconds. Tells how <tag>refresh [keep] <m/num/</tag> Time period in seconds. Tells how
long to wait before next attempting to poll the cache using a Serial 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 Query or a Reset Query packet. Must be lower than 86400 seconds (one

View File

@ -126,6 +126,43 @@ static struct {
const char *bfd_state_names[] = { "AdminDown", "Down", "Init", "Up" }; const char *bfd_state_names[] = { "AdminDown", "Down", "Init", "Up" };
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 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); static struct bfd_iface *bfd_get_iface(struct bfd_proto *p, ip_addr local, struct iface *iface);
static void bfd_free_iface(struct bfd_iface *ifa); static void bfd_free_iface(struct bfd_iface *ifa);
@ -1179,13 +1216,84 @@ bfd_copy_config(struct proto_config *dest, struct proto_config *src UNUSED)
} }
void void
bfd_show_sessions(struct proto *P) bfd_show_session(struct bfd_session *s, int details)
{ {
/* FIXME: this is thread-unsafe, but perhaps harmless */
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;
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]; byte tbuf[TM_DATETIME_BUFFER_SIZE];
tm_format_time(tbuf, &config->tf_proto, s->last_state_change);
if (!details)
{
cli_msg(-1020, "%-25I %-10s %-10s %-12s %7t %7t",
s->addr, ifname, bfd_state_names[loc_state], tbuf, tx_int, timeout);
return;
}
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, " 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, "");
}
void
bfd_show_sessions(struct proto *P, struct bfd_show_sessions_cmd *args)
{
struct bfd_proto *p = (struct bfd_proto *) P; 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) if (p->p.proto_state != PS_UP)
{ {
@ -1194,24 +1302,25 @@ bfd_show_sessions(struct proto *P)
} }
cli_msg(-1020, "%s:", p->p.name); cli_msg(-1020, "%s:", p->p.name);
if (!args->verbose)
cli_msg(-1020, "%-25s %-10s %-10s %-12s %8s %8s", cli_msg(-1020, "%-25s %-10s %-10s %-12s %8s %8s",
"IP address", "Interface", "State", "Since", "Interval", "Timeout"); "IP address", "Interface", "State", "Since", "Interval", "Timeout");
HASH_WALK(p->session_hash_id, next_id, s) HASH_WALK(p->session_hash_id, next_id, s)
{ {
/* FIXME: this is thread-unsafe, but perhaps harmless */ if (args->address.type && !ipa_in_netX(s->addr, &args->address))
state = s->loc_state; continue;
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; if (args->iface && (s->ifa->iface != args->iface))
tm_format_time(tbuf, &config->tf_proto, s->last_state_change); continue;
cli_msg(-1020, "%-25I %-10s %-10s %-12s %7t %7t", if (ipa_is_ip4(s->addr) ? args->ipv6 : args->ipv4)
s->addr, ifname, bfd_state_names[state], tbuf, tx_int, timeout); continue;
if (s->ifa->iface ? args->multihop : args->direct)
continue;
bfd_show_session(s, args->verbose);
} }
HASH_WALK_END; HASH_WALK_END;
} }

View File

@ -172,6 +172,17 @@ struct bfd_session
u32 tx_csn_time; /* Timestamp of last tx_csn change */ u32 tx_csn_time; /* Timestamp of last tx_csn change */
}; };
struct bfd_show_sessions_cmd {
net_addr address;
struct iface *iface;
struct symbol *name;
u8 verbose;
u8 ipv4;
u8 ipv6;
u8 direct;
u8 multihop;
};
extern const char *bfd_state_names[]; extern const char *bfd_state_names[];
@ -218,7 +229,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_id(struct bfd_proto *p, u32 id);
struct bfd_session * bfd_find_session_by_addr(struct bfd_proto *p, ip_addr addr, uint ifindex); 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_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, struct bfd_show_sessions_cmd *args);
/* packets.c */ /* packets.c */
void bfd_send_ctl(struct bfd_proto *p, struct bfd_session *s, int final); void bfd_send_ctl(struct bfd_proto *p, struct bfd_session *s, int final);

View File

@ -29,6 +29,7 @@ CF_KEYWORDS(BFD, MIN, IDLE, RX, TX, INTERVAL, MULTIPLIER, PASSIVE,
%type <iface> bfd_neigh_iface %type <iface> bfd_neigh_iface
%type <a> bfd_neigh_local %type <a> bfd_neigh_local
%type <i> bfd_neigh_multihop bfd_auth_type %type <i> bfd_neigh_multihop bfd_auth_type
%type <bssc> bfd_show_sessions_args
CF_GRAMMAR CF_GRAMMAR
@ -185,8 +186,24 @@ bfd_neighbor: ipa bfd_neigh_iface bfd_neigh_local bfd_neigh_multihop
CF_CLI_HELP(SHOW BFD, ..., [[Show information about BFD protocol]]); CF_CLI_HELP(SHOW BFD, ..., [[Show information about BFD protocol]]);
CF_CLI(SHOW BFD SESSIONS, optproto, [<name>], [[Show information about BFD sessions]])
{ PROTO_WALK_CMD($4, &proto_bfd, p) bfd_show_sessions(p); }; CF_CLI_HELP(SHOW BFD SESSIONS, ..., [[Show information about BFD sessions]]);
CF_CLI(SHOW BFD SESSIONS, bfd_show_sessions_args, [<name>] [address <ip|prefix>] [(interface|dev) \"<name>\"] [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 CF_CODE

View File

@ -32,7 +32,7 @@ rpki_check_unused_transport(void)
CF_DECLS CF_DECLS
CF_KEYWORDS(RPKI, REMOTE, BIRD, PRIVATE, PUBLIC, KEY, TCP, SSH, TRANSPORT, USER, 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 <i> rpki_keep_interval %type <i> rpki_keep_interval
@ -61,6 +61,7 @@ rpki_proto_item:
| REMOTE rpki_cache_addr | REMOTE rpki_cache_addr
| REMOTE rpki_cache_addr rpki_proto_item_port | REMOTE rpki_cache_addr rpki_proto_item_port
| rpki_proto_item_port | rpki_proto_item_port
| LOCAL ADDRESS ipa { RPKI_CFG->local_ip = $3; }
| TRANSPORT rpki_transport | TRANSPORT rpki_transport
| REFRESH rpki_keep_interval expr { | REFRESH rpki_keep_interval expr {
if (rpki_check_refresh_interval($3)) if (rpki_check_refresh_interval($3))

View File

@ -118,6 +118,7 @@ struct rpki_proto {
struct rpki_config { struct rpki_config {
struct proto_config c; struct proto_config c;
const char *hostname; /* Full domain name or stringified IP address of cache server */ 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 */ ip_addr ip; /* IP address of cache server or IPA_NONE */
u16 port; /* Port number of cache server */ u16 port; /* Port number of cache server */
struct rpki_tr_config tr_config; /* Specific transport configuration structure */ struct rpki_tr_config tr_config; /* Specific transport configuration structure */

View File

@ -82,6 +82,7 @@ rpki_tr_open(struct rpki_tr_sock *tr)
sk->daddr = cf->ip; sk->daddr = cf->ip;
sk->dport = cf->port; sk->dport = cf->port;
sk->host = cf->hostname; sk->host = cf->hostname;
sk->saddr = cf->local_ip;
sk->rbsize = RPKI_RX_BUFFER_SIZE; sk->rbsize = RPKI_RX_BUFFER_SIZE;
sk->tbsize = RPKI_TX_BUFFER_SIZE; sk->tbsize = RPKI_TX_BUFFER_SIZE;
sk->tos = IP_PREC_INTERNET_CONTROL; sk->tos = IP_PREC_INTERNET_CONTROL;