Skip to content

Commit

Permalink
bgpd: Use treat-as-withdraw for tunnel encapsulation attribute
Browse files Browse the repository at this point in the history
Before this path we used session reset method, which is discouraged by rfc7606.

Handle this as rfc requires.

Signed-off-by: Donatas Abraitis <[email protected]>
  • Loading branch information
ton31337 committed Aug 29, 2023
1 parent dccd9ab commit bcb6b58
Showing 1 changed file with 25 additions and 36 deletions.
61 changes: 25 additions & 36 deletions bgpd/bgp_attr.c
Original file line number Diff line number Diff line change
Expand Up @@ -1405,6 +1405,7 @@ bgp_attr_malformed(struct bgp_attr_parser_args *args, uint8_t subcode,
case BGP_ATTR_LARGE_COMMUNITIES:
case BGP_ATTR_ORIGINATOR_ID:
case BGP_ATTR_CLUSTER_LIST:
case BGP_ATTR_ENCAP:
case BGP_ATTR_OTC:
return BGP_ATTR_PARSE_WITHDRAW;
case BGP_ATTR_MP_REACH_NLRI:
Expand Down Expand Up @@ -2635,39 +2636,33 @@ bgp_attr_ipv6_ext_communities(struct bgp_attr_parser_args *args)
}

/* Parse Tunnel Encap attribute in an UPDATE */
static int bgp_attr_encap(uint8_t type, struct peer *peer, /* IN */
bgp_size_t length, /* IN: attr's length field */
struct attr *attr, /* IN: caller already allocated */
uint8_t flag, /* IN: attr's flags field */
uint8_t *startp)
static int bgp_attr_encap(struct bgp_attr_parser_args *args)
{
bgp_size_t total;
uint16_t tunneltype = 0;

total = length + (CHECK_FLAG(flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3);
struct peer *const peer = args->peer;
struct attr *const attr = args->attr;
bgp_size_t length = args->length;
uint8_t type = args->type;
uint8_t flag = args->flags;

if (!CHECK_FLAG(flag, BGP_ATTR_FLAG_TRANS)
|| !CHECK_FLAG(flag, BGP_ATTR_FLAG_OPTIONAL)) {
zlog_info(
"Tunnel Encap attribute flag isn't optional and transitive %d",
flag);
bgp_notify_send_with_data(peer, BGP_NOTIFY_UPDATE_ERR,
BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR,
startp, total);
return -1;
zlog_err("Tunnel Encap attribute flag isn't optional and transitive %d",
flag);
return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
args->total);
}

if (BGP_ATTR_ENCAP == type) {
/* read outer TLV type and length */
uint16_t tlv_length;

if (length < 4) {
zlog_info(
zlog_err(
"Tunnel Encap attribute not long enough to contain outer T,L");
bgp_notify_send_with_data(
peer, BGP_NOTIFY_UPDATE_ERR,
BGP_NOTIFY_UPDATE_OPT_ATTR_ERR, startp, total);
return -1;
return bgp_attr_malformed(args,
BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
args->total);
}
tunneltype = stream_getw(BGP_INPUT(peer));
tlv_length = stream_getw(BGP_INPUT(peer));
Expand Down Expand Up @@ -2699,13 +2694,11 @@ static int bgp_attr_encap(uint8_t type, struct peer *peer, /* IN */
}

if (sublength > length) {
zlog_info(
"Tunnel Encap attribute sub-tlv length %d exceeds remaining length %d",
sublength, length);
bgp_notify_send_with_data(
peer, BGP_NOTIFY_UPDATE_ERR,
BGP_NOTIFY_UPDATE_OPT_ATTR_ERR, startp, total);
return -1;
zlog_err("Tunnel Encap attribute sub-tlv length %d exceeds remaining length %d",
sublength, length);
return bgp_attr_malformed(args,
BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
args->total);
}

/* alloc and copy sub-tlv */
Expand Down Expand Up @@ -2753,13 +2746,10 @@ static int bgp_attr_encap(uint8_t type, struct peer *peer, /* IN */

if (length) {
/* spurious leftover data */
zlog_info(
"Tunnel Encap attribute length is bad: %d leftover octets",
length);
bgp_notify_send_with_data(peer, BGP_NOTIFY_UPDATE_ERR,
BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
startp, total);
return -1;
zlog_err("Tunnel Encap attribute length is bad: %d leftover octets",
length);
return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
args->total);
}

return 0;
Expand Down Expand Up @@ -3732,8 +3722,7 @@ enum bgp_attr_parse_ret bgp_attr_parse(struct peer *peer, struct attr *attr,
case BGP_ATTR_VNC:
#endif
case BGP_ATTR_ENCAP:
ret = bgp_attr_encap(type, peer, length, attr, flag,
startp);
ret = bgp_attr_encap(&attr_args);
break;
case BGP_ATTR_PREFIX_SID:
ret = bgp_attr_prefix_sid(&attr_args);
Expand Down

0 comments on commit bcb6b58

Please sign in to comment.