summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_open.c
diff options
context:
space:
mode:
authorDaniel Walton <dwalton@cumulusnetworks.com>2015-09-11 05:10:16 +0200
committerDaniel Walton <dwalton@cumulusnetworks.com>2015-09-11 05:10:16 +0200
commit04b6bdc0ee6275442464edec1d14b3f4d3eaa246 (patch)
tree402996c2ef60c5a4ed2f03a0a8e63d3ec7c8c154 /bgpd/bgp_open.c
parentFix arm compilation failures of sockunion_hash issues (diff)
downloadfrr-04b6bdc0ee6275442464edec1d14b3f4d3eaa246.tar.xz
frr-04b6bdc0ee6275442464edec1d14b3f4d3eaa246.zip
bgpd: Exchange hostname capability and display hostnames in output
This patch adds a hostname capability. The node's hostname and domainname are exchanged in the new capability and used in show command outputs based on a knob enabled by the user. The hostname and domainname can be a maximum of 64 chars long, each. Signed-off-by: Dinesh G Dutt <ddutt@cumulusnetworks.com> Reviewed-by: Daniel Walton <dwalton@cumulusnetworks.com> Reviewed-by: Vivek Venkataraman <vivek@cumulusnetworks.com> Ticket: CM-5660 Reviewed By: CCR-2563 Testing Done:
Diffstat (limited to 'bgpd/bgp_open.c')
-rw-r--r--bgpd/bgp_open.c131
1 files changed, 131 insertions, 0 deletions
diff --git a/bgpd/bgp_open.c b/bgpd/bgp_open.c
index a530542a4..3ab782b02 100644
--- a/bgpd/bgp_open.c
+++ b/bgpd/bgp_open.c
@@ -588,6 +588,85 @@ bgp_capability_enhe (struct peer *peer, struct capability_header *hdr)
return 0;
}
+static int
+bgp_capability_hostname (struct peer *peer, struct capability_header *hdr)
+{
+ struct stream *s = BGP_INPUT (peer);
+ char str[BGP_MAX_HOSTNAME+1];
+ size_t end = stream_get_getp (s) + hdr->length;
+ u_char len;
+
+ SET_FLAG(peer->cap, PEER_CAP_HOSTNAME_RCV);
+
+ len = stream_getc(s);
+ if (stream_get_getp(s) + len > end)
+ {
+ zlog_warn("%s: Received malformed hostname capability from peer %s",
+ __FUNCTION__, peer->host);
+ return -1;
+ }
+
+ if (len > BGP_MAX_HOSTNAME)
+ {
+ stream_get(str, s, BGP_MAX_HOSTNAME);
+ stream_forward_getp(s, len-BGP_MAX_HOSTNAME);
+ len = BGP_MAX_HOSTNAME; /* to set the '\0' below */
+ }
+ else if (len)
+ stream_get(str, s, len);
+
+ if (len)
+ {
+ str[len] = '\0';
+
+ if (peer->hostname != NULL)
+ XFREE(MTYPE_HOST, peer->hostname);
+
+ if (peer->domainname != NULL)
+ XFREE(MTYPE_HOST, peer->domainname);
+
+ peer->hostname = XSTRDUP(MTYPE_HOST, str);
+ }
+
+ if (stream_get_getp(s) +1 > end)
+ {
+ zlog_warn("%s: Received invalid domain name len (hostname capability) from peer %s",
+ __FUNCTION__, peer->host);
+ return -1;
+ }
+
+ len = stream_getc(s);
+ if (stream_get_getp(s) + len > end)
+ {
+ zlog_warn("%s: Received runt domain name (hostname capability) from peer %s",
+ __FUNCTION__, peer->host);
+ return -1;
+ }
+
+ if (len > BGP_MAX_HOSTNAME)
+ {
+ stream_get(str, s, BGP_MAX_HOSTNAME);
+ stream_forward_getp(s, len-BGP_MAX_HOSTNAME);
+ len = BGP_MAX_HOSTNAME; /* to set the '\0' below */
+ }
+ else if (len)
+ stream_get(str, s, len);
+
+ if (len)
+ {
+ str[len] = '\0';
+ peer->domainname = XSTRDUP(MTYPE_HOST, str);
+ }
+
+ if (bgp_debug_neighbor_events(peer))
+ {
+ zlog_debug("%s received hostname %s, domainname %s",
+ peer->host, peer->hostname, peer->domainname);
+ }
+
+ return 0;
+}
+
static const struct message capcode_str[] =
{
{ CAPABILITY_CODE_MP, "MultiProtocol Extensions" },
@@ -601,6 +680,7 @@ bgp_capability_enhe (struct peer *peer, struct capability_header *hdr)
{ CAPABILITY_CODE_DYNAMIC_OLD, "Dynamic (Old)" },
{ CAPABILITY_CODE_REFRESH_OLD, "Route Refresh (Old)" },
{ CAPABILITY_CODE_ORF_OLD, "ORF (Old)" },
+ { CAPABILITY_CODE_FQDN, "FQDN" },
};
static const int capcode_str_max = array_size(capcode_str);
@@ -618,6 +698,7 @@ static const size_t cap_minsizes[] =
[CAPABILITY_CODE_ENHE] = CAPABILITY_CODE_ENHE_LEN,
[CAPABILITY_CODE_REFRESH_OLD] = CAPABILITY_CODE_REFRESH_LEN,
[CAPABILITY_CODE_ORF_OLD] = sizeof (struct capability_orf_entry),
+ [CAPABILITY_CODE_FQDN] = CAPABILITY_CODE_MIN_FQDN_LEN,
};
/**
@@ -684,6 +765,7 @@ bgp_capability_parse (struct peer *peer, size_t length, int *mp_capability,
case CAPABILITY_CODE_DYNAMIC:
case CAPABILITY_CODE_DYNAMIC_OLD:
case CAPABILITY_CODE_ENHE:
+ case CAPABILITY_CODE_FQDN:
/* Check length. */
if (caphdr.length < cap_minsizes[caphdr.code])
{
@@ -759,6 +841,9 @@ bgp_capability_parse (struct peer *peer, size_t length, int *mp_capability,
case CAPABILITY_CODE_ENHE:
ret = bgp_capability_enhe (peer, &caphdr);
break;
+ case CAPABILITY_CODE_FQDN:
+ ret = bgp_capability_hostname (peer, &caphdr);
+ break;
default:
if (caphdr.code > 128)
{
@@ -1099,6 +1184,7 @@ bgp_open_capability (struct stream *s, struct peer *peer)
as_t local_as;
u_int32_t restart_time;
u_char afi_safi_count = 0;
+ struct utsname names;
/* Remember current pointer for Opt Parm Len. */
cp = stream_get_endp (s);
@@ -1265,6 +1351,51 @@ bgp_open_capability (struct stream *s, struct peer *peer)
stream_putc (s, CAPABILITY_CODE_DYNAMIC_LEN);
}
+ /* Hostname capability */
+ uname(&names);
+ if (names.nodename[0] != '\0')
+ {
+ SET_FLAG(peer->cap, PEER_CAP_HOSTNAME_ADV);
+ stream_putc (s, BGP_OPEN_OPT_CAP);
+ rcapp = stream_get_endp(s); /* Ptr to length placeholder */
+ stream_putc(s, 0); /* dummy len for now */
+ stream_putc (s, CAPABILITY_CODE_FQDN);
+ capp = stream_get_endp(s);
+ stream_putc(s, 0); /* dummy len for now */
+ len = strlen(names.nodename);
+ if (len > BGP_MAX_HOSTNAME)
+ len = BGP_MAX_HOSTNAME;
+
+ stream_putc(s, len);
+ stream_put(s, names.nodename, len);
+#ifdef _GNU_SOURCE
+ if ((names.domainname[0] != '\0') &&
+ (strcmp(names.domainname, "(none)") != 0))
+ {
+ len = strlen(names.domainname);
+ if (len > BGP_MAX_HOSTNAME)
+ len = BGP_MAX_HOSTNAME;
+
+ stream_putc(s, len);
+ stream_put(s, names.domainname, len);
+ }
+ else
+#endif
+ {
+ stream_putc(s, 0); /* 0 length */
+ }
+
+ /* Set the lengths straight */
+ len = stream_get_endp(s) - rcapp - 1;
+ stream_putc_at(s, rcapp, len);
+ len = stream_get_endp(s) - capp - 1;
+ stream_putc_at(s, capp, len);
+
+ if (bgp_debug_neighbor_events(peer))
+ zlog_debug("%s Sending hostname cap with hn = %s, dn = %s",
+ peer->host, names.nodename, names.domainname);
+ }
+
/* Sending base graceful-restart capability irrespective of the config */
SET_FLAG (peer->cap, PEER_CAP_RESTART_ADV);
stream_putc (s, BGP_OPEN_OPT_CAP);