summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--conf/conf.c9
-rw-r--r--conf/conf.h1
-rw-r--r--doc/bird.sgml6
-rw-r--r--nest/cmds.c1
-rw-r--r--nest/config.Y6
-rw-r--r--proto/bgp/bgp.c4
-rw-r--r--proto/bgp/bgp.h3
-rw-r--r--proto/bgp/config.Y2
-rw-r--r--proto/bgp/packets.c41
-rw-r--r--sysdep/unix/main.c16
-rw-r--r--sysdep/unix/unix.h1
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);