forked from Mirror/frr
Merge pull request #1821 from vivek-cumulus/pmsi-parse-display
bgpd: Parse PMSI Tunnel Attribute and display
This commit is contained in:
commit
6ca96cc6ad
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
|
|
@ -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. */
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue