diff options
-rw-r--r-- | conf/conf.c | 9 | ||||
-rw-r--r-- | conf/conf.h | 1 | ||||
-rw-r--r-- | doc/bird.sgml | 6 | ||||
-rw-r--r-- | nest/cmds.c | 1 | ||||
-rw-r--r-- | nest/config.Y | 6 | ||||
-rw-r--r-- | proto/bgp/bgp.c | 4 | ||||
-rw-r--r-- | proto/bgp/bgp.h | 3 | ||||
-rw-r--r-- | proto/bgp/config.Y | 2 | ||||
-rw-r--r-- | proto/bgp/packets.c | 41 | ||||
-rw-r--r-- | sysdep/unix/main.c | 16 | ||||
-rw-r--r-- | sysdep/unix/unix.h | 1 |
11 files changed, 89 insertions, 1 deletions
diff --git a/conf/conf.c b/conf/conf.c index 6f64b541..58abcde1 100644 --- a/conf/conf.c +++ b/conf/conf.c @@ -55,6 +55,7 @@ #include "lib/timer.h" #include "conf/conf.h" #include "filter/filter.h" +#include "sysdep/unix/unix.h" static jmp_buf conf_jmpbuf; @@ -217,6 +218,14 @@ config_del_obstacle(struct config *c) static int 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) return 0; diff --git a/conf/conf.h b/conf/conf.h index 3e47c918..860d267a 100644 --- a/conf/conf.h +++ b/conf/conf.h @@ -40,6 +40,7 @@ struct config { struct timeformat tf_log; /* Time format for the logfile */ struct timeformat tf_base; /* Time format for other purposes */ u32 gr_wait; /* Graceful restart wait timeout (sec) */ + const char *hostname; /* Hostname */ int cli_debug; /* Tracing of CLI connections and commands */ int latency_debug; /* I/O loop tracks duration of each event */ diff --git a/doc/bird.sgml b/doc/bird.sgml index 28b0e400..5d1df5bc 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -585,6 +585,9 @@ include "tablename.conf";; See <ref id="proto-iface" name="interface"> section for detailed 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> During graceful restart recovery, BIRD waits for convergence of routing 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 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> When an error is encountered (either locally or by the other side), disable the instance automatically and wait for an administrator to fix diff --git a/nest/cmds.c b/nest/cmds.c index da4015cf..18f39eb5 100644 --- a/nest/cmds.c +++ b/nest/cmds.c @@ -27,6 +27,7 @@ cmd_show_status(void) cli_msg(-1000, "BIRD " BIRD_VERSION); tm_format_time(tim, &config->tf_base, current_time()); 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); tm_format_time(tim, &config->tf_base, boot_time); cli_msg(-1011, "Last reboot on %s", tim); diff --git a/nest/config.Y b/nest/config.Y index 0bb8ca51..39bf6149 100644 --- a/nest/config.Y +++ b/nest/config.Y @@ -87,7 +87,7 @@ proto_postconfig(void) 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(IPV4, IPV6, VPN4, VPN6, ROA4, ROA6, FLOW4, FLOW6, SADR, MPLS) 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 ; gr_opts: GRACEFUL RESTART WAIT expr ';' { new_config->gr_wait = $4; } ; diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c index 302d026c..c54afe06 100644 --- a/proto/bgp/bgp.c +++ b/proto/bgp/bgp.c @@ -103,6 +103,7 @@ * RFC 8654 - Extended Message Support for BGP * draft-ietf-idr-ext-opt-param-07 * draft-uttaro-idr-bgp-persistence-04 + * draft-walton-bgp-hostname-capability-02 */ #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 preserved:", afl2, afn2); } + + if (caps->hostname) + cli_msg(-1006, " Hostname: %s", caps->hostname); } static void diff --git a/proto/bgp/bgp.h b/proto/bgp/bgp.h index dd7dc28f..cca4b448 100644 --- a/proto/bgp/bgp.h +++ b/proto/bgp/bgp.h @@ -98,6 +98,7 @@ struct bgp_config { 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_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 */ int rr_client; /* Whether neighbor is RR 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_add_path; /* Bitwise OR of per-AF add_path */ + const char *hostname; /* Hostname, RFC draft */ + u16 af_count; /* Number of af_data items */ u16 length; /* Length of capabilities in OPEN msg */ diff --git a/proto/bgp/config.Y b/proto/bgp/config.Y index 18c3560d..2dfbdca9 100644 --- a/proto/bgp/config.Y +++ b/proto/bgp/config.Y @@ -62,6 +62,7 @@ bgp_proto_start: proto_start BGP { BGP_CFG->error_delay_time_max = 300; BGP_CFG->enable_refresh = 1; BGP_CFG->enable_as4 = 1; + BGP_CFG->enable_hostname = 0; BGP_CFG->capabilities = 2; BGP_CFG->interpret_communities = 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 AS4 bool ';' { BGP_CFG->enable_as4 = $4; } | 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 PASSWORD text ';' { BGP_CFG->password = $3; } | bgp_proto SETKEY bool ';' { BGP_CFG->setkey = $3; } diff --git a/proto/bgp/packets.c b/proto/bgp/packets.c index 78fdd1e0..b16ee242 100644 --- a/proto/bgp/packets.c +++ b/proto/bgp/packets.c @@ -252,6 +252,14 @@ bgp_prepare_capabilities(struct bgp_conn *conn) if (p->cf->llgr_mode) 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 */ WALK_LIST(c, p->p.channels) { @@ -412,6 +420,24 @@ bgp_write_capabilities(struct bgp_conn *conn, byte *buf) 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; return buf; @@ -573,6 +599,21 @@ bgp_read_capabilities(struct bgp_conn *conn, byte *pos, int len) } 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 */ } diff --git a/sysdep/unix/main.c b/sysdep/unix/main.c index 2c7e3cef..67e76655 100644 --- a/sysdep/unix/main.c +++ b/sysdep/unix/main.c @@ -20,6 +20,7 @@ #include <pwd.h> #include <grp.h> #include <sys/stat.h> +#include <sys/utsname.h> #include <libgen.h> #include "nest/bird.h" @@ -89,6 +90,21 @@ drop_gid(gid_t gid) } /* + * Hostname + */ + +char * +get_hostname(linpool *lp) +{ + struct utsname uts = {}; + + if (uname(&uts) < 0) + return NULL; + + return lp_strdup(lp, uts.nodename); +} + +/* * Reading the Configuration */ diff --git a/sysdep/unix/unix.h b/sysdep/unix/unix.h index 0f2973f0..ad85d1ea 100644 --- a/sysdep/unix/unix.h +++ b/sysdep/unix/unix.h @@ -24,6 +24,7 @@ extern int parse_and_exit; void async_config(void); void async_dump(void); void async_shutdown(void); +char *get_hostname(linpool *lp); void cmd_check_config(const char *name); void cmd_reconfig(const char *name, int type, uint timeout); void cmd_reconfig_confirm(void); |