Skip to content

Commit

Permalink
Merge pull request #14290 from opensourcerouting/fix/bgpd_encap_tunne…
Browse files Browse the repository at this point in the history
…l_handling

bgpd: Use treat-as-withdraw for tunnel encapsulation attribute
  • Loading branch information
chiragshah6 authored Aug 29, 2023
2 parents dccd9ab + bcb6b58 commit f80262b
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 f80262b

Please sign in to comment.