diff options
Diffstat (limited to 'proto')
-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 |
4 files changed, 50 insertions, 0 deletions
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 */ } |