Skip to content

Commit

Permalink
bgpd: Handle FQDN capability using dynamic capabilities
Browse files Browse the repository at this point in the history
Signed-off-by: Donatas Abraitis <[email protected]>
  • Loading branch information
ton31337 committed Oct 6, 2023
1 parent c516447 commit e253a89
Showing 1 changed file with 120 additions and 2 deletions.
122 changes: 120 additions & 2 deletions bgpd/bgp_packet.c
Original file line number Diff line number Diff line change
Expand Up @@ -1218,6 +1218,8 @@ void bgp_capability_send(struct peer *peer, afi_t afi, safi_t safi,
uint32_t gr_restart_time;
const char *capability = lookup_msg(capcode_str, capability_code,
"Unknown");
const char *hostname = cmd_hostname_get();
const char *domainname = cmd_domainname_get();

if (!peer_established(peer->connection))
return;
Expand Down Expand Up @@ -1379,13 +1381,50 @@ void bgp_capability_send(struct peer *peer, afi_t afi, safi_t safi,
capability, iana_afi2str(pkt_afi),
iana_safi2str(pkt_safi));
break;
case CAPABILITY_CODE_FQDN:
if (hostname) {
SET_FLAG(peer->cap, PEER_CAP_HOSTNAME_ADV);
stream_putc(s, action);
stream_putc(s, CAPABILITY_CODE_FQDN);
cap_len = stream_get_endp(s);
stream_putc(s, 0); /* Capability Length */

len = strlen(hostname);
if (len > BGP_MAX_HOSTNAME)
len = BGP_MAX_HOSTNAME;

stream_putc(s, len);
stream_put(s, hostname, len);

if (domainname) {
len = strlen(domainname);
if (len > BGP_MAX_HOSTNAME)
len = BGP_MAX_HOSTNAME;

stream_putc(s, len);
stream_put(s, domainname, len);
} else
stream_putc(s, 0);

len = stream_get_endp(s) - cap_len - 1;
stream_putc_at(s, cap_len, len);

if (bgp_debug_neighbor_events(peer))
zlog_debug("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s",
peer,
action == CAPABILITY_ACTION_SET
? "Advertising"
: "Removing",
capability, iana_afi2str(pkt_afi),
iana_safi2str(pkt_safi));
}
break;
case CAPABILITY_CODE_REFRESH:
case CAPABILITY_CODE_ORF:
case CAPABILITY_CODE_AS4:
case CAPABILITY_CODE_DYNAMIC:
case CAPABILITY_CODE_ADDPATH:
case CAPABILITY_CODE_ENHANCED_RR:
case CAPABILITY_CODE_FQDN:
case CAPABILITY_CODE_ENHE:
case CAPABILITY_CODE_EXT_MESSAGE:
break;
Expand Down Expand Up @@ -2878,6 +2917,83 @@ static int bgp_route_refresh_receive(struct peer_connection *connection,
return BGP_PACKET_NOOP;
}

static void bgp_dynamic_capability_fqdn(uint8_t *pnt, int action,
struct capability_header *hdr,
struct peer *peer)
{
uint8_t *data = pnt + 3;
uint8_t *end = data + hdr->length;
char str[BGP_MAX_HOSTNAME + 1] = {};
uint8_t len;

if (action == CAPABILITY_ACTION_SET) {
/* hostname */
len = *data;
if (data + len > end) {
zlog_err("%pBP: Received invalid FQDN capability length (host name) %d",
peer, hdr->length);
return;
}
data++;

if (len > BGP_MAX_HOSTNAME) {
memcpy(&str, data, BGP_MAX_HOSTNAME);
str[BGP_MAX_HOSTNAME] = '\0';
} else if (len) {
memcpy(&str, data, len);
str[len] = '\0';
}
data += len;

if (len) {
str[len] = '\0';

XFREE(MTYPE_BGP_PEER_HOST, peer->hostname);
XFREE(MTYPE_BGP_PEER_HOST, peer->domainname);

peer->hostname = XSTRDUP(MTYPE_BGP_PEER_HOST, str);
}

if (data + 1 > end) {
zlog_err("%pBP: Received invalid FQDN capability (domain name length)",
peer);
return;
}

/* domainname */
len = *data;
if (data + len > end) {
zlog_err("%pBP: Received invalid FQDN capability length (domain name) %d",
peer, len);
return;
}
data++;

if (len > BGP_MAX_HOSTNAME) {
memcpy(&str, data, BGP_MAX_HOSTNAME);
str[BGP_MAX_HOSTNAME] = '\0';
} else if (len) {
memcpy(&str, data, len);
str[len] = '\0';
}
data += len;

if (len) {
str[len] = '\0';

XFREE(MTYPE_BGP_PEER_HOST, peer->domainname);

peer->domainname = XSTRDUP(MTYPE_BGP_PEER_HOST, str);
}

SET_FLAG(peer->cap, PEER_CAP_HOSTNAME_RCV);
} else {
UNSET_FLAG(peer->cap, PEER_CAP_HOSTNAME_RCV);
XFREE(MTYPE_BGP_PEER_HOST, peer->hostname);
XFREE(MTYPE_BGP_PEER_HOST, peer->domainname);
}
}

static void bgp_dynamic_capability_llgr(uint8_t *pnt, int action,
struct capability_header *hdr,
struct peer *peer)
Expand Down Expand Up @@ -3232,13 +3348,15 @@ static int bgp_capability_msg_parse(struct peer *peer, uint8_t *pnt,
case CAPABILITY_CODE_LLGR:
bgp_dynamic_capability_llgr(pnt, action, hdr, peer);
break;
case CAPABILITY_CODE_FQDN:
bgp_dynamic_capability_fqdn(pnt, action, hdr, peer);
break;
case CAPABILITY_CODE_REFRESH:
case CAPABILITY_CODE_ORF:
case CAPABILITY_CODE_AS4:
case CAPABILITY_CODE_DYNAMIC:
case CAPABILITY_CODE_ADDPATH:
case CAPABILITY_CODE_ENHANCED_RR:
case CAPABILITY_CODE_FQDN:
case CAPABILITY_CODE_ENHE:
case CAPABILITY_CODE_EXT_MESSAGE:
break;
Expand Down

0 comments on commit e253a89

Please sign in to comment.