BGP: Add support for BGP hostname capability
This is an implementation of draft-walton-bgp-hostname-capability-02. It is implemented since quite some time for FRR and in datacenter, this gives a nice output to avoid using IP addresses. It is disabled by default. The hostname is retrieved from uname(2) and can be overriden with "hostname" option. The domain name is never set nor displayed. Minor changes by committer.
This commit is contained in:
parent
00b85905b9
commit
714238716e
11 changed files with 89 additions and 1 deletions
|
@ -55,6 +55,7 @@
|
||||||
#include "lib/timer.h"
|
#include "lib/timer.h"
|
||||||
#include "conf/conf.h"
|
#include "conf/conf.h"
|
||||||
#include "filter/filter.h"
|
#include "filter/filter.h"
|
||||||
|
#include "sysdep/unix/unix.h"
|
||||||
|
|
||||||
|
|
||||||
static jmp_buf conf_jmpbuf;
|
static jmp_buf conf_jmpbuf;
|
||||||
|
@ -217,6 +218,14 @@ config_del_obstacle(struct config *c)
|
||||||
static int
|
static int
|
||||||
global_commit(struct config *new, struct config *old)
|
global_commit(struct config *new, struct config *old)
|
||||||
{
|
{
|
||||||
|
if (!new->hostname)
|
||||||
|
{
|
||||||
|
new->hostname = get_hostname(new->mem);
|
||||||
|
|
||||||
|
if (!new->hostname)
|
||||||
|
log(L_WARN "Cannot determine hostname");
|
||||||
|
}
|
||||||
|
|
||||||
if (!old)
|
if (!old)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,7 @@ struct config {
|
||||||
struct timeformat tf_log; /* Time format for the logfile */
|
struct timeformat tf_log; /* Time format for the logfile */
|
||||||
struct timeformat tf_base; /* Time format for other purposes */
|
struct timeformat tf_base; /* Time format for other purposes */
|
||||||
u32 gr_wait; /* Graceful restart wait timeout (sec) */
|
u32 gr_wait; /* Graceful restart wait timeout (sec) */
|
||||||
|
const char *hostname; /* Hostname */
|
||||||
|
|
||||||
int cli_debug; /* Tracing of CLI connections and commands */
|
int cli_debug; /* Tracing of CLI connections and commands */
|
||||||
int latency_debug; /* I/O loop tracks duration of each event */
|
int latency_debug; /* I/O loop tracks duration of each event */
|
||||||
|
|
|
@ -585,6 +585,9 @@ include "tablename.conf";;
|
||||||
See <ref id="proto-iface" name="interface"> section for detailed
|
See <ref id="proto-iface" name="interface"> section for detailed
|
||||||
description of interface patterns with extended clauses.
|
description of interface patterns with extended clauses.
|
||||||
|
|
||||||
|
<tag><label id="opt-hostname">hostname "<m/name/"</tag>
|
||||||
|
Set hostname. Default: node name as returned by `uname -n'.
|
||||||
|
|
||||||
<tag><label id="opt-graceful-restart">graceful restart wait <m/number/</tag>
|
<tag><label id="opt-graceful-restart">graceful restart wait <m/number/</tag>
|
||||||
During graceful restart recovery, BIRD waits for convergence of routing
|
During graceful restart recovery, BIRD waits for convergence of routing
|
||||||
protocols. This option allows to specify a timeout for the recovery to
|
protocols. This option allows to specify a timeout for the recovery to
|
||||||
|
@ -2536,6 +2539,9 @@ using the following configuration parameters:
|
||||||
This option is relevant to IPv4 mode with enabled capability
|
This option is relevant to IPv4 mode with enabled capability
|
||||||
advertisement only. Default: on.
|
advertisement only. Default: on.
|
||||||
|
|
||||||
|
<tag><label id="bgp-advertise-hostname">advertise hostname <m/switch/</tag>
|
||||||
|
Advertise hostname capability along with the hostname. Default: off.
|
||||||
|
|
||||||
<tag><label id="bgp-disable-after-error">disable after error <m/switch/</tag>
|
<tag><label id="bgp-disable-after-error">disable after error <m/switch/</tag>
|
||||||
When an error is encountered (either locally or by the other side),
|
When an error is encountered (either locally or by the other side),
|
||||||
disable the instance automatically and wait for an administrator to fix
|
disable the instance automatically and wait for an administrator to fix
|
||||||
|
|
|
@ -27,6 +27,7 @@ cmd_show_status(void)
|
||||||
cli_msg(-1000, "BIRD " BIRD_VERSION);
|
cli_msg(-1000, "BIRD " BIRD_VERSION);
|
||||||
tm_format_time(tim, &config->tf_base, current_time());
|
tm_format_time(tim, &config->tf_base, current_time());
|
||||||
cli_msg(-1011, "Router ID is %R", config->router_id);
|
cli_msg(-1011, "Router ID is %R", config->router_id);
|
||||||
|
cli_msg(-1011, "Hostname is %s", config->hostname);
|
||||||
cli_msg(-1011, "Current server time is %s", tim);
|
cli_msg(-1011, "Current server time is %s", tim);
|
||||||
tm_format_time(tim, &config->tf_base, boot_time);
|
tm_format_time(tim, &config->tf_base, boot_time);
|
||||||
cli_msg(-1011, "Last reboot on %s", tim);
|
cli_msg(-1011, "Last reboot on %s", tim);
|
||||||
|
|
|
@ -87,7 +87,7 @@ proto_postconfig(void)
|
||||||
|
|
||||||
CF_DECLS
|
CF_DECLS
|
||||||
|
|
||||||
CF_KEYWORDS(ROUTER, ID, PROTOCOL, TEMPLATE, PREFERENCE, DISABLED, DEBUG, ALL, OFF, DIRECT)
|
CF_KEYWORDS(ROUTER, ID, HOSTNAME, PROTOCOL, TEMPLATE, PREFERENCE, DISABLED, DEBUG, ALL, OFF, DIRECT)
|
||||||
CF_KEYWORDS(INTERFACE, IMPORT, EXPORT, FILTER, NONE, VRF, DEFAULT, TABLE, STATES, ROUTES, FILTERS)
|
CF_KEYWORDS(INTERFACE, IMPORT, EXPORT, FILTER, NONE, VRF, DEFAULT, TABLE, STATES, ROUTES, FILTERS)
|
||||||
CF_KEYWORDS(IPV4, IPV6, VPN4, VPN6, ROA4, ROA6, FLOW4, FLOW6, SADR, MPLS)
|
CF_KEYWORDS(IPV4, IPV6, VPN4, VPN6, ROA4, ROA6, FLOW4, FLOW6, SADR, MPLS)
|
||||||
CF_KEYWORDS(RECEIVE, LIMIT, ACTION, WARN, BLOCK, RESTART, DISABLE, KEEP, FILTERED)
|
CF_KEYWORDS(RECEIVE, LIMIT, ACTION, WARN, BLOCK, RESTART, DISABLE, KEEP, FILTERED)
|
||||||
|
@ -151,6 +151,10 @@ idval:
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
conf: hostname_override ;
|
||||||
|
|
||||||
|
hostname_override: HOSTNAME text ';' { new_config->hostname = $2; } ;
|
||||||
|
|
||||||
conf: gr_opts ;
|
conf: gr_opts ;
|
||||||
|
|
||||||
gr_opts: GRACEFUL RESTART WAIT expr ';' { new_config->gr_wait = $4; } ;
|
gr_opts: GRACEFUL RESTART WAIT expr ';' { new_config->gr_wait = $4; } ;
|
||||||
|
|
|
@ -103,6 +103,7 @@
|
||||||
* RFC 8654 - Extended Message Support for BGP
|
* RFC 8654 - Extended Message Support for BGP
|
||||||
* draft-ietf-idr-ext-opt-param-07
|
* draft-ietf-idr-ext-opt-param-07
|
||||||
* draft-uttaro-idr-bgp-persistence-04
|
* draft-uttaro-idr-bgp-persistence-04
|
||||||
|
* draft-walton-bgp-hostname-capability-02
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#undef LOCAL_DEBUG
|
#undef LOCAL_DEBUG
|
||||||
|
@ -2415,6 +2416,9 @@ bgp_show_capabilities(struct bgp_proto *p UNUSED, struct bgp_caps *caps)
|
||||||
bgp_show_afis(-1006, " AF supported:", afl1, afn1);
|
bgp_show_afis(-1006, " AF supported:", afl1, afn1);
|
||||||
bgp_show_afis(-1006, " AF preserved:", afl2, afn2);
|
bgp_show_afis(-1006, " AF preserved:", afl2, afn2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (caps->hostname)
|
||||||
|
cli_msg(-1006, " Hostname: %s", caps->hostname);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -98,6 +98,7 @@ struct bgp_config {
|
||||||
int enable_refresh; /* Enable local support for route refresh [RFC 2918] */
|
int enable_refresh; /* Enable local support for route refresh [RFC 2918] */
|
||||||
int enable_as4; /* Enable local support for 4B AS numbers [RFC 6793] */
|
int enable_as4; /* Enable local support for 4B AS numbers [RFC 6793] */
|
||||||
int enable_extended_messages; /* Enable local support for extended messages [draft] */
|
int enable_extended_messages; /* Enable local support for extended messages [draft] */
|
||||||
|
int enable_hostname; /* Enable local support for hostname [draft] */
|
||||||
u32 rr_cluster_id; /* Route reflector cluster ID, if different from local ID */
|
u32 rr_cluster_id; /* Route reflector cluster ID, if different from local ID */
|
||||||
int rr_client; /* Whether neighbor is RR client of me */
|
int rr_client; /* Whether neighbor is RR client of me */
|
||||||
int rs_client; /* Whether neighbor is RS client of me */
|
int rs_client; /* Whether neighbor is RS client of me */
|
||||||
|
@ -228,6 +229,8 @@ struct bgp_caps {
|
||||||
u8 any_ext_next_hop; /* Bitwise OR of per-AF ext_next_hop */
|
u8 any_ext_next_hop; /* Bitwise OR of per-AF ext_next_hop */
|
||||||
u8 any_add_path; /* Bitwise OR of per-AF add_path */
|
u8 any_add_path; /* Bitwise OR of per-AF add_path */
|
||||||
|
|
||||||
|
const char *hostname; /* Hostname, RFC draft */
|
||||||
|
|
||||||
u16 af_count; /* Number of af_data items */
|
u16 af_count; /* Number of af_data items */
|
||||||
u16 length; /* Length of capabilities in OPEN msg */
|
u16 length; /* Length of capabilities in OPEN msg */
|
||||||
|
|
||||||
|
|
|
@ -62,6 +62,7 @@ bgp_proto_start: proto_start BGP {
|
||||||
BGP_CFG->error_delay_time_max = 300;
|
BGP_CFG->error_delay_time_max = 300;
|
||||||
BGP_CFG->enable_refresh = 1;
|
BGP_CFG->enable_refresh = 1;
|
||||||
BGP_CFG->enable_as4 = 1;
|
BGP_CFG->enable_as4 = 1;
|
||||||
|
BGP_CFG->enable_hostname = 0;
|
||||||
BGP_CFG->capabilities = 2;
|
BGP_CFG->capabilities = 2;
|
||||||
BGP_CFG->interpret_communities = 1;
|
BGP_CFG->interpret_communities = 1;
|
||||||
BGP_CFG->allow_as_sets = 1;
|
BGP_CFG->allow_as_sets = 1;
|
||||||
|
@ -173,6 +174,7 @@ bgp_proto:
|
||||||
| bgp_proto ENABLE ROUTE REFRESH bool ';' { BGP_CFG->enable_refresh = $5; }
|
| bgp_proto ENABLE ROUTE REFRESH bool ';' { BGP_CFG->enable_refresh = $5; }
|
||||||
| bgp_proto ENABLE AS4 bool ';' { BGP_CFG->enable_as4 = $4; }
|
| bgp_proto ENABLE AS4 bool ';' { BGP_CFG->enable_as4 = $4; }
|
||||||
| bgp_proto ENABLE EXTENDED MESSAGES bool ';' { BGP_CFG->enable_extended_messages = $5; }
|
| bgp_proto ENABLE EXTENDED MESSAGES bool ';' { BGP_CFG->enable_extended_messages = $5; }
|
||||||
|
| bgp_proto ADVERTISE HOSTNAME bool ';' { BGP_CFG->enable_hostname = $4; }
|
||||||
| bgp_proto CAPABILITIES bool ';' { BGP_CFG->capabilities = $3; }
|
| bgp_proto CAPABILITIES bool ';' { BGP_CFG->capabilities = $3; }
|
||||||
| bgp_proto PASSWORD text ';' { BGP_CFG->password = $3; }
|
| bgp_proto PASSWORD text ';' { BGP_CFG->password = $3; }
|
||||||
| bgp_proto SETKEY bool ';' { BGP_CFG->setkey = $3; }
|
| bgp_proto SETKEY bool ';' { BGP_CFG->setkey = $3; }
|
||||||
|
|
|
@ -252,6 +252,14 @@ bgp_prepare_capabilities(struct bgp_conn *conn)
|
||||||
if (p->cf->llgr_mode)
|
if (p->cf->llgr_mode)
|
||||||
caps->llgr_aware = 1;
|
caps->llgr_aware = 1;
|
||||||
|
|
||||||
|
if (p->cf->enable_hostname && config->hostname)
|
||||||
|
{
|
||||||
|
size_t length = strlen(config->hostname);
|
||||||
|
char *hostname = mb_allocz(p->p.pool, length+1);
|
||||||
|
memcpy(hostname, config->hostname, length+1);
|
||||||
|
caps->hostname = hostname;
|
||||||
|
}
|
||||||
|
|
||||||
/* Allocate and fill per-AF fields */
|
/* Allocate and fill per-AF fields */
|
||||||
WALK_LIST(c, p->p.channels)
|
WALK_LIST(c, p->p.channels)
|
||||||
{
|
{
|
||||||
|
@ -412,6 +420,24 @@ bgp_write_capabilities(struct bgp_conn *conn, byte *buf)
|
||||||
data[-1] = buf - data;
|
data[-1] = buf - data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (caps->hostname)
|
||||||
|
{
|
||||||
|
*buf++ = 73; /* Capability 73: Hostname */
|
||||||
|
*buf++ = 0; /* Capability data length */
|
||||||
|
data = buf;
|
||||||
|
|
||||||
|
/* Hostname */
|
||||||
|
size_t length = strlen(caps->hostname);
|
||||||
|
*buf++ = length;
|
||||||
|
memcpy(buf, caps->hostname, length);
|
||||||
|
buf += length;
|
||||||
|
|
||||||
|
/* Domain, not implemented */
|
||||||
|
*buf++ = 0;
|
||||||
|
|
||||||
|
data[-1] = buf - data;
|
||||||
|
}
|
||||||
|
|
||||||
caps->length = buf - buf_head;
|
caps->length = buf - buf_head;
|
||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
|
@ -573,6 +599,21 @@ bgp_read_capabilities(struct bgp_conn *conn, byte *pos, int len)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 73: /* Hostname, RFC draft */
|
||||||
|
if ((cl < 2) || (cl < 2 + pos[2]))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
int length = pos[2];
|
||||||
|
char *hostname = mb_allocz(p->p.pool, length+1);
|
||||||
|
memcpy(hostname, pos + 3, length);
|
||||||
|
hostname[length] = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < length; i++)
|
||||||
|
if (hostname[i] < ' ')
|
||||||
|
hostname[i] = ' ';
|
||||||
|
|
||||||
|
caps->hostname = hostname;
|
||||||
|
|
||||||
/* We can safely ignore all other capabilities */
|
/* We can safely ignore all other capabilities */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <grp.h>
|
#include <grp.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <sys/utsname.h>
|
||||||
#include <libgen.h>
|
#include <libgen.h>
|
||||||
|
|
||||||
#include "nest/bird.h"
|
#include "nest/bird.h"
|
||||||
|
@ -88,6 +89,21 @@ drop_gid(gid_t gid)
|
||||||
die("setgroups: %m");
|
die("setgroups: %m");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Hostname
|
||||||
|
*/
|
||||||
|
|
||||||
|
char *
|
||||||
|
get_hostname(linpool *lp)
|
||||||
|
{
|
||||||
|
struct utsname uts = {};
|
||||||
|
|
||||||
|
if (uname(&uts) < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return lp_strdup(lp, uts.nodename);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reading the Configuration
|
* Reading the Configuration
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -24,6 +24,7 @@ extern int parse_and_exit;
|
||||||
void async_config(void);
|
void async_config(void);
|
||||||
void async_dump(void);
|
void async_dump(void);
|
||||||
void async_shutdown(void);
|
void async_shutdown(void);
|
||||||
|
char *get_hostname(linpool *lp);
|
||||||
void cmd_check_config(const char *name);
|
void cmd_check_config(const char *name);
|
||||||
void cmd_reconfig(const char *name, int type, uint timeout);
|
void cmd_reconfig(const char *name, int type, uint timeout);
|
||||||
void cmd_reconfig_confirm(void);
|
void cmd_reconfig_confirm(void);
|
||||||
|
|
Loading…
Reference in a new issue