Skip to content

Commit

Permalink
Merge pull request #1821 from vivek-cumulus/pmsi-parse-display
Browse files Browse the repository at this point in the history
bgpd: Parse PMSI Tunnel Attribute and display
  • Loading branch information
pguibert6WIND authored Mar 14, 2018
2 parents 73394c7 + 88fbc36 commit 6ca96cc
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 2 deletions.
50 changes: 49 additions & 1 deletion bgpd/bgp_attr.c
Original file line number Diff line number Diff line change
Expand Up @@ -2107,6 +2107,51 @@ bgp_attr_prefix_sid(struct bgp_attr_parser_args *args,
return BGP_ATTR_PARSE_PROCEED;
}

/* PMSI tunnel attribute (RFC 6514)
* Basic validation checks done here.
*/
static bgp_attr_parse_ret_t
bgp_attr_pmsi_tunnel(struct bgp_attr_parser_args *args)
{
struct peer *const peer = args->peer;
struct attr *const attr = args->attr;
const bgp_size_t length = args->length;
u_int8_t tnl_type;

/* Verify that the receiver is expecting "ingress replication" as we
* can only support that.
*/
if (length < 2) {
zlog_err("Bad PMSI tunnel attribute length %d", length);
return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
args->total);
}
stream_getc(peer->curr); /* Flags */
tnl_type = stream_getc(peer->curr);
if (tnl_type > PMSI_TNLTYPE_MAX) {
zlog_err("Invalid PMSI tunnel attribute type %d", tnl_type);
return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
args->total);
}
if (tnl_type == PMSI_TNLTYPE_INGR_REPL) {
if (length != 9) {
zlog_err("Bad PMSI tunnel attribute length %d for IR",
length);
return bgp_attr_malformed(
args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
args->total);
}
}

attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL);
attr->pmsi_tnl_type = tnl_type;

/* Forward read pointer of input stream. */
stream_forward_getp(peer->curr, length - 2);

return BGP_ATTR_PARSE_PROCEED;
}

/* BGP unknown attribute treatment. */
static bgp_attr_parse_ret_t bgp_attr_unknown(struct bgp_attr_parser_args *args)
{
Expand Down Expand Up @@ -2440,6 +2485,9 @@ bgp_attr_parse_ret_t bgp_attr_parse(struct peer *peer, struct attr *attr,
case BGP_ATTR_PREFIX_SID:
ret = bgp_attr_prefix_sid(&attr_args, mp_update);
break;
case BGP_ATTR_PMSI_TUNNEL:
ret = bgp_attr_pmsi_tunnel(&attr_args);
break;
default:
ret = bgp_attr_unknown(&attr_args);
break;
Expand Down Expand Up @@ -3263,7 +3311,7 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer,
stream_putc(s, BGP_ATTR_PMSI_TUNNEL);
stream_putc(s, 9); // Length
stream_putc(s, 0); // Flags
stream_putc(s, 6); // Tunnel type: Ingress Replication (6)
stream_putc(s, PMSI_TNLTYPE_INGR_REPL); // IR (6)
stream_put(s, &(attr->label),
BGP_LABEL_BYTES); // MPLS Label / VXLAN VNI
stream_put_ipv4(s, attr->nexthop.s_addr);
Expand Down
17 changes: 17 additions & 0 deletions bgpd/bgp_attr.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@
#define BGP_PREFIX_SID_IPV6_LENGTH 19
#define BGP_PREFIX_SID_ORIGINATOR_SRGB_LENGTH 6

/* PMSI tunnel types (RFC 6514) */

struct bgp_attr_encap_subtlv {
struct bgp_attr_encap_subtlv *next; /* for chaining */
/* Reference count of this attribute. */
Expand Down Expand Up @@ -96,6 +98,18 @@ struct overlay_index {
union gw_addr gw_ip;
};

enum pta_type {
PMSI_TNLTYPE_NO_INFO = 0,
PMSI_TNLTYPE_RSVP_TE_P2MP,
PMSI_TNLTYPE_MLDP_P2MP,
PMSI_TNLTYPE_PIM_SSM,
PMSI_TNLTYPE_PIM_SM,
PMSI_TNLTYPE_PIM_BIDIR,
PMSI_TNLTYPE_INGR_REPL,
PMSI_TNLTYPE_MLDP_MP2MP,
PMSI_TNLTYPE_MAX = PMSI_TNLTYPE_MLDP_MP2MP
};

/* BGP core attribute structure. */
struct attr {
/* AS Path structure */
Expand All @@ -119,6 +133,9 @@ struct attr {
/* Path origin attribute */
u_char origin;

/* PMSI tunnel type (RFC 6514). */
enum pta_type pmsi_tnl_type;

/* has the route-map changed any attribute?
Used on the peer outbound side. */
u_int32_t rmap_change_flags;
Expand Down
5 changes: 4 additions & 1 deletion bgpd/bgp_debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,6 @@ static const struct message bgp_notify_capability_msg[] = {
const char *bgp_origin_str[] = {"i", "e", "?"};
const char *bgp_origin_long_str[] = {"IGP", "EGP", "incomplete"};


/* Given a string return a pointer the corresponding peer structure */
static struct peer *bgp_find_peer(struct vty *vty, const char *peer_str)
{
Expand Down Expand Up @@ -415,6 +414,10 @@ int bgp_dump_attr(struct attr *attr, char *buf, size_t size)
inet_ntoa(attr->cluster->list[i]));
}

if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)))
snprintf(buf + strlen(buf), size - strlen(buf),
", pmsi tnltype %u", attr->pmsi_tnl_type);

if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AS_PATH)))
snprintf(buf + strlen(buf), size - strlen(buf), ", path %s",
aspath_print(attr->aspath));
Expand Down
1 change: 1 addition & 0 deletions bgpd/bgp_debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ struct bgp_debug_filter {
#define CONF_BGP_DEBUG(a, b) (conf_bgp_debug_ ## a & BGP_DEBUG_ ## b)

extern const char *bgp_type_str[];
extern const char *pmsi_tnltype_str[];

extern int bgp_dump_attr(struct attr *, char *, size_t);
extern int bgp_debug_peer_updout_enabled(char *host);
Expand Down
13 changes: 13 additions & 0 deletions bgpd/bgp_evpn.c
Original file line number Diff line number Diff line change
Expand Up @@ -2935,6 +2935,19 @@ static int process_type3_route(struct peer *peer, afi_t afi, safi_t safi,
return -1;
}

/* If PMSI is present, log if it is anything other than IR.
* Note: We just simply ignore the values as it is not clear if
* doing anything else is better.
*/
if (attr &&
(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL))) {
if (attr->pmsi_tnl_type != PMSI_TNLTYPE_INGR_REPL) {
zlog_warn("%u:%s - Rx EVPN Type-3 NLRI with unsupported PTA %d",
peer->bgp->vrf_id, peer->host,
attr->pmsi_tnl_type);
}
}

/* Make prefix_rd */
prd.family = AF_UNSPEC;
prd.prefixlen = 64;
Expand Down
34 changes: 34 additions & 0 deletions bgpd/bgp_route.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,21 @@
extern const char *bgp_origin_str[];
extern const char *bgp_origin_long_str[];

/* PMSI strings. */
#define PMSI_TNLTYPE_STR_NO_INFO "No info"
#define PMSI_TNLTYPE_STR_DEFAULT PMSI_TNLTYPE_STR_NO_INFO
static const struct message bgp_pmsi_tnltype_str[] = {
{PMSI_TNLTYPE_NO_INFO, PMSI_TNLTYPE_STR_NO_INFO},
{PMSI_TNLTYPE_RSVP_TE_P2MP, "RSVP-TE P2MP"},
{PMSI_TNLTYPE_MLDP_P2MP, "mLDP P2MP"},
{PMSI_TNLTYPE_PIM_SSM, "PIM-SSM"},
{PMSI_TNLTYPE_PIM_SM, "PIM-SM"},
{PMSI_TNLTYPE_PIM_BIDIR, "PIM-BIDIR"},
{PMSI_TNLTYPE_INGR_REPL, "Ingress Replication"},
{PMSI_TNLTYPE_MLDP_MP2MP, "mLDP MP2MP"},
{0}
};

struct bgp_node *bgp_afi_node_get(struct bgp_table *table, afi_t afi,
safi_t safi, struct prefix *p,
struct prefix_rd *prd)
Expand Down Expand Up @@ -7035,6 +7050,7 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct prefix *p,
json_object *json_ext_community = NULL;
json_object *json_lcommunity = NULL;
json_object *json_last_update = NULL;
json_object *json_pmsi = NULL;
json_object *json_nexthop_global = NULL;
json_object *json_nexthop_ll = NULL;
json_object *json_nexthops = NULL;
Expand Down Expand Up @@ -7787,6 +7803,24 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct prefix *p,
json_last_update);
} else
vty_out(vty, " Last update: %s", ctime(&tbuf));

/* Line 10 display PMSI tunnel attribute, if present */
if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) {
const char *str = lookup_msg(bgp_pmsi_tnltype_str,
attr->pmsi_tnl_type,
PMSI_TNLTYPE_STR_DEFAULT);

if (json_paths) {
json_pmsi = json_object_new_object();
json_object_string_add(json_pmsi,
"tunnelType", str);
json_object_object_add(json_path, "pmsi",
json_pmsi);
} else
vty_out(vty, " PMSI Tunnel Type: %s\n",
str);
}

}

/* We've constructed the json object for this path, add it to the json
Expand Down

0 comments on commit 6ca96cc

Please sign in to comment.