summaryrefslogtreecommitdiff
path: root/bgpd
diff options
context:
space:
mode:
authorpaulzlabn <paulz@labn.net>2018-03-14 13:31:58 -0700
committerGitHub <noreply@github.com>2018-03-14 13:31:58 -0700
commit3f1224cd1a9408bdad6aca8c0c205211cb548d5c (patch)
tree87e6a52a3e7ad7b09caa3207f081fd92bc8fd018 /bgpd
parentfd9b55a2b77c187730600d429b3f290ab58fa035 (diff)
parent6ca96cc6ada990d052fcfc48cffeef454ae64a10 (diff)
Merge branch 'master' into working/master/bgp-vpn-vrf-leaking
Diffstat (limited to 'bgpd')
-rw-r--r--bgpd/.gitignore1
-rw-r--r--bgpd/bgp_attr.c50
-rw-r--r--bgpd/bgp_attr.h17
-rw-r--r--bgpd/bgp_debug.c5
-rw-r--r--bgpd/bgp_debug.h1
-rw-r--r--bgpd/bgp_evpn.c206
-rw-r--r--bgpd/bgp_evpn.h19
-rw-r--r--bgpd/bgp_evpn_private.h26
-rw-r--r--bgpd/bgp_evpn_vty.c142
-rw-r--r--bgpd/bgp_route.c47
-rw-r--r--bgpd/bgp_routemap.c44
-rw-r--r--bgpd/bgpd.c6
-rw-r--r--bgpd/bgpd.h18
13 files changed, 428 insertions, 154 deletions
diff --git a/bgpd/.gitignore b/bgpd/.gitignore
index a97bdb83d3..105be22995 100644
--- a/bgpd/.gitignore
+++ b/bgpd/.gitignore
@@ -16,4 +16,3 @@ TAGS
.arch-ids
*~
*.loT
-*clippy.c
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index c23950799f..c3a1105995 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -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);
diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h
index 1a49e4ecf2..5403f32543 100644
--- a/bgpd/bgp_attr.h
+++ b/bgpd/bgp_attr.h
@@ -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;
diff --git a/bgpd/bgp_debug.c b/bgpd/bgp_debug.c
index 691cdd19d7..f867266956 100644
--- a/bgpd/bgp_debug.c
+++ b/bgpd/bgp_debug.c
@@ -162,7 +162,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)
{
@@ -417,6 +416,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));
diff --git a/bgpd/bgp_debug.h b/bgpd/bgp_debug.h
index 57f8fef5f2..fe7ca8c46a 100644
--- a/bgpd/bgp_debug.h
+++ b/bgpd/bgp_debug.h
@@ -142,6 +142,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);
diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c
index fc7549671e..94d9cb465b 100644
--- a/bgpd/bgp_evpn.c
+++ b/bgpd/bgp_evpn.c
@@ -475,6 +475,17 @@ static void derive_rd_rt_for_vni(struct bgp *bgp, struct bgpevpn *vpn)
}
/*
+ * Convert nexthop (remote VTEP IP) into an IPv6 address.
+ */
+static void evpn_convert_nexthop_to_ipv6(struct attr *attr)
+{
+ if (BGP_ATTR_NEXTHOP_AFI_IP6(attr))
+ return;
+ ipv4_to_ipv4_mapped_ipv6(&attr->mp_nexthop_global, attr->nexthop);
+ attr->mp_nexthop_len = IPV6_MAX_BYTELEN;
+}
+
+/*
* Add (update) or delete MACIP from zebra.
*/
static int bgp_zebra_send_remote_macip(struct bgp *bgp, struct bgpevpn *vpn,
@@ -622,17 +633,17 @@ static void build_evpn_type5_route_extcomm(struct bgp *bgp_vrf,
}
/*
- * Build extended communities for EVPN route. RT and ENCAP are
- * applicable to all routes.
- * TODO: currently kernel doesnt support ipv6 routes with ipv4 nexthops.
- * This means that we can't do symmetric routing for ipv6 hosts routes
- * in the same way as ipv4 host routes.
- * We wont attach l3-vni related RTs for ipv6 routes.
- * For now, We will only adevrtise ipv4 host routes
- * with L3-VNI related ext-comm.
+ * Build extended communities for EVPN route.
+ * This function is applicable for type-2 and type-3 routes. The layer-2 RT
+ * and ENCAP extended communities are applicable for all routes.
+ * The default gateway extended community and MAC mobility (sticky) extended
+ * community are added as needed based on passed settings - only for type-2
+ * routes. Likewise, the layer-3 RT and Router MAC extended communities are
+ * added, if present, based on passed settings - only for non-link-local
+ * type-2 routes.
*/
static void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr,
- afi_t afi)
+ int add_l3_ecomm)
{
struct ecommunity ecom_encap;
struct ecommunity ecom_sticky;
@@ -662,11 +673,10 @@ static void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr,
for (ALL_LIST_ELEMENTS(vpn->export_rtl, node, nnode, ecom))
attr->ecommunity = ecommunity_merge(attr->ecommunity, ecom);
- /*
- * only attach l3-vni export rts for ipv4 address family and if we are
- * advertising both the labels in type-2 routes
+ /* Add the export RTs for L3VNI if told to - caller determines
+ * when this should be done.
*/
- if (afi == AFI_IP && CHECK_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS)) {
+ if (add_l3_ecomm) {
vrf_export_rtl = bgpevpn_get_vrf_export_rtl(vpn);
if (vrf_export_rtl && !list_isempty(vrf_export_rtl)) {
for (ALL_LIST_ELEMENTS(vrf_export_rtl, node, nnode,
@@ -676,6 +686,7 @@ static void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr,
}
}
+ /* Add MAC mobility (sticky) if needed. */
if (attr->sticky) {
seqnum = 0;
memset(&ecom_sticky, 0, sizeof(ecom_sticky));
@@ -686,12 +697,8 @@ static void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr,
ecommunity_merge(attr->ecommunity, &ecom_sticky);
}
- /*
- * only attach l3-vni rmac for ipv4 address family and if we are
- * advertising both the labels in type-2 routes
- */
- if (afi == AFI_IP && !is_zero_mac(&attr->rmac)
- && CHECK_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS)) {
+ /* Add RMAC, if told to. */
+ if (add_l3_ecomm) {
memset(&ecom_rmac, 0, sizeof(ecom_rmac));
encode_rmac_extcomm(&eval_rmac, &attr->rmac);
ecom_rmac.size = 1;
@@ -700,6 +707,7 @@ static void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr,
ecommunity_merge(attr->ecommunity, &ecom_rmac);
}
+ /* Add default gateway, if needed. */
if (attr->default_gw) {
memset(&ecom_default_gw, 0, sizeof(ecom_default_gw));
encode_default_gw_extcomm(&eval_default_gw);
@@ -1260,6 +1268,7 @@ static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn,
struct bgp_node *rn;
struct attr attr;
struct attr *attr_new;
+ int add_l3_ecomm = 0;
struct bgp_info *ri;
afi_t afi = AFI_L2VPN;
safi_t safi = SAFI_EVPN;
@@ -1279,14 +1288,23 @@ static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn,
if (p->prefix.route_type == BGP_EVPN_IMET_ROUTE)
attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL);
- /* router mac is only needed for type-2 and type-5 routes */
+ /* router mac is only needed for type-2 routes here. */
if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE)
bgpevpn_get_rmac(vpn, &attr.rmac);
vni2label(vpn->vni, &(attr.label));
- /* Set up RT and ENCAP extended community. */
- build_evpn_route_extcomm(
- vpn, &attr, IS_EVPN_PREFIX_IPADDR_V4(p) ? AFI_IP : AFI_IP6);
+ /* Include L3 VNI related RTs and RMAC for type-2 routes, if they're
+ * IPv4 or IPv6 global addresses and we're advertising L3VNI with
+ * these routes.
+ */
+ if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE &&
+ (IS_EVPN_PREFIX_IPADDR_V4(p) ||
+ !IN6_IS_ADDR_LINKLOCAL(&p->prefix.ip.ipaddr_v6)) &&
+ CHECK_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS))
+ add_l3_ecomm = 1;
+
+ /* Set up extended community. */
+ build_evpn_route_extcomm(vpn, &attr, add_l3_ecomm);
/* First, create (or fetch) route node within the VNI. */
/* NOTE: There is no RD here. */
@@ -1466,22 +1484,20 @@ static int update_all_type2_routes(struct bgp *bgp, struct bgpevpn *vpn)
struct attr attr;
struct attr attr_sticky;
struct attr attr_def_gw;
- struct attr attr_ip6;
- struct attr attr_sticky_ip6;
- struct attr attr_def_gw_ip6;
+ struct attr attr_ip6_ll;
struct attr *attr_new;
+ int add_l3_ecomm = 0;
afi = AFI_L2VPN;
safi = SAFI_EVPN;
memset(&attr, 0, sizeof(struct attr));
memset(&attr_sticky, 0, sizeof(struct attr));
memset(&attr_def_gw, 0, sizeof(struct attr));
- memset(&attr_ip6, 0, sizeof(struct attr));
- memset(&attr_sticky_ip6, 0, sizeof(struct attr));
- memset(&attr_def_gw_ip6, 0, sizeof(struct attr));
+ memset(&attr_ip6_ll, 0, sizeof(struct attr));
- /* Build path-attribute - all type-2 routes for this VNI will share the
- * same path attribute.
+ /* Build path-attribute - multiple type-2 routes for this VNI will share
+ * the same path attribute, but we need separate structures for sticky
+ * MACs, default gateway and IPv6 link-local addresses (no L3 RT/RMAC).
*/
bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
bgp_attr_default_set(&attr_sticky, BGP_ORIGIN_IGP);
@@ -1500,31 +1516,21 @@ static int update_all_type2_routes(struct bgp *bgp, struct bgpevpn *vpn)
attr_def_gw.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
attr_def_gw.default_gw = 1;
bgpevpn_get_rmac(vpn, &attr_def_gw.rmac);
- bgp_attr_default_set(&attr_ip6, BGP_ORIGIN_IGP);
- bgp_attr_default_set(&attr_sticky_ip6, BGP_ORIGIN_IGP);
- bgp_attr_default_set(&attr_def_gw_ip6, BGP_ORIGIN_IGP);
- attr_ip6.nexthop = vpn->originator_ip;
- attr_ip6.mp_nexthop_global_in = vpn->originator_ip;
- attr_ip6.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
- bgpevpn_get_rmac(vpn, &attr_ip6.rmac);
- attr_sticky_ip6.nexthop = vpn->originator_ip;
- attr_sticky_ip6.mp_nexthop_global_in = vpn->originator_ip;
- attr_sticky_ip6.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
- attr_sticky_ip6.sticky = 1;
- bgpevpn_get_rmac(vpn, &attr_sticky_ip6.rmac);
- attr_def_gw_ip6.nexthop = vpn->originator_ip;
- attr_def_gw_ip6.mp_nexthop_global_in = vpn->originator_ip;
- attr_def_gw_ip6.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
- attr_def_gw_ip6.default_gw = 1;
- bgpevpn_get_rmac(vpn, &attr_def_gw_ip6.rmac);
-
- /* Set up RT, ENCAP and sticky MAC extended community. */
- build_evpn_route_extcomm(vpn, &attr, AFI_IP);
- build_evpn_route_extcomm(vpn, &attr_sticky, AFI_IP);
- build_evpn_route_extcomm(vpn, &attr_def_gw, AFI_IP);
- build_evpn_route_extcomm(vpn, &attr_ip6, AFI_IP6);
- build_evpn_route_extcomm(vpn, &attr_sticky_ip6, AFI_IP6);
- build_evpn_route_extcomm(vpn, &attr_def_gw_ip6, AFI_IP);
+ bgp_attr_default_set(&attr_ip6_ll, BGP_ORIGIN_IGP);
+ attr_ip6_ll.nexthop = vpn->originator_ip;
+ attr_ip6_ll.mp_nexthop_global_in = vpn->originator_ip;
+ attr_ip6_ll.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
+
+ /* Add L3 VNI RTs and RMAC for non IPv6 link-local attributes if
+ * using L3 VNI for type-2 routes also.
+ */
+ if (CHECK_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS))
+ add_l3_ecomm = 1;
+
+ build_evpn_route_extcomm(vpn, &attr, add_l3_ecomm);
+ build_evpn_route_extcomm(vpn, &attr_sticky, add_l3_ecomm);
+ build_evpn_route_extcomm(vpn, &attr_def_gw, add_l3_ecomm);
+ build_evpn_route_extcomm(vpn, &attr_ip6_ll, 0);
/* Walk this VNI's route table and update local type-2 routes. For any
* routes updated, update corresponding entry in the global table too.
@@ -1538,7 +1544,11 @@ static int update_all_type2_routes(struct bgp *bgp, struct bgpevpn *vpn)
if (evp->prefix.route_type != BGP_EVPN_MAC_IP_ROUTE)
continue;
- if (IS_EVPN_PREFIX_IPADDR_V4(evp)) {
+ if (IS_EVPN_PREFIX_IPADDR_V6(evp) &&
+ IN6_IS_ADDR_LINKLOCAL(&evp->prefix.ip.ipaddr_v6))
+ update_evpn_route_entry(bgp, vpn, afi, safi, rn,
+ &attr_ip6_ll, 0, 1, &ri, 0);
+ else {
if (evpn_route_is_sticky(bgp, rn))
update_evpn_route_entry(bgp, vpn, afi, safi, rn,
&attr_sticky, 0, 1, &ri,
@@ -1550,19 +1560,6 @@ static int update_all_type2_routes(struct bgp *bgp, struct bgpevpn *vpn)
else
update_evpn_route_entry(bgp, vpn, afi, safi, rn,
&attr, 0, 1, &ri, 0);
- } else {
- if (evpn_route_is_sticky(bgp, rn))
- update_evpn_route_entry(bgp, vpn, afi, safi, rn,
- &attr_sticky_ip6, 0, 1,
- &ri, 0);
- else if (evpn_route_is_def_gw(bgp, rn))
- update_evpn_route_entry(bgp, vpn, afi, safi, rn,
- &attr_def_gw_ip6, 0, 1,
- &ri, 0);
- else
- update_evpn_route_entry(bgp, vpn, afi, safi, rn,
- &attr_ip6, 0, 1, &ri,
- 0);
}
/* If a local route exists for this prefix, we need to update
@@ -1593,11 +1590,9 @@ static int update_all_type2_routes(struct bgp *bgp, struct bgpevpn *vpn)
/* Unintern temporary. */
aspath_unintern(&attr.aspath);
- aspath_unintern(&attr_ip6.aspath);
aspath_unintern(&attr_sticky.aspath);
- aspath_unintern(&attr_sticky_ip6.aspath);
aspath_unintern(&attr_def_gw.aspath);
- aspath_unintern(&attr_def_gw_ip6.aspath);
+ aspath_unintern(&attr_ip6_ll.aspath);
return 0;
}
@@ -1791,6 +1786,7 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
{
struct bgp_node *rn;
struct bgp_info *ri;
+ struct attr attr;
struct attr *attr_new;
int ret = 0;
struct prefix p;
@@ -1827,6 +1823,15 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
} else
return 0;
+ /* EVPN routes currently only support a IPv4 next hop which corresponds
+ * to the remote VTEP. When importing into a VRF, if it is IPv6 host
+ * route, we have to convert the next hop to an IPv4-mapped address
+ * for the rest of the code to flow through.
+ */
+ bgp_attr_dup(&attr, parent_ri->attr);
+ if (afi == AFI_IP6)
+ evpn_convert_nexthop_to_ipv6(&attr);
+
/* Check if route entry is already present. */
for (ri = rn->info; ri; ri = ri->next)
if (ri->extra
@@ -1835,7 +1840,7 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
if (!ri) {
/* Add (or update) attribute to hash. */
- attr_new = bgp_attr_intern(parent_ri->attr);
+ attr_new = bgp_attr_intern(&attr);
/* Create new route with its attribute. */
ri = info_make(parent_ri->type, parent_ri->sub_type, 0,
@@ -1850,21 +1855,25 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
}
bgp_info_add(rn, ri);
} else {
- if (attrhash_cmp(ri->attr, parent_ri->attr)
+ if (attrhash_cmp(ri->attr, &attr)
&& !CHECK_FLAG(ri->flags, BGP_INFO_REMOVED)) {
bgp_unlock_node(rn);
return 0;
}
/* The attribute has changed. */
/* Add (or update) attribute to hash. */
- attr_new = bgp_attr_intern(parent_ri->attr);
+ attr_new = bgp_attr_intern(&attr);
/* Restore route, if needed. */
if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
bgp_info_restore(rn, ri);
/* Mark if nexthop has changed. */
- if (!IPV4_ADDR_SAME(&ri->attr->nexthop, &attr_new->nexthop))
+ if ((afi == AFI_IP &&
+ !IPV4_ADDR_SAME(&ri->attr->nexthop, &attr_new->nexthop)) ||
+ (afi == AFI_IP6 &&
+ !IPV6_ADDR_SAME(&ri->attr->mp_nexthop_global,
+ &attr_new->mp_nexthop_global)))
SET_FLAG(ri->flags, BGP_INFO_IGP_CHANGED);
/* Unintern existing, set to new. */
@@ -2577,10 +2586,12 @@ static int install_uninstall_evpn_route(struct bgp *bgp, afi_t afi, safi_t safi,
static void delete_withdraw_vrf_routes(struct bgp *bgp_vrf)
{
/* delete all ipv4 routes and withdraw from peers */
- bgp_evpn_withdraw_type5_routes(bgp_vrf, AFI_IP, SAFI_UNICAST);
+ if (advertise_type5_routes(bgp_vrf, AFI_IP))
+ bgp_evpn_withdraw_type5_routes(bgp_vrf, AFI_IP, SAFI_UNICAST);
/* delete all ipv6 routes and withdraw from peers */
- bgp_evpn_withdraw_type5_routes(bgp_vrf, AFI_IP6, SAFI_UNICAST);
+ if (advertise_type5_routes(bgp_vrf, AFI_IP6))
+ bgp_evpn_withdraw_type5_routes(bgp_vrf, AFI_IP6, SAFI_UNICAST);
}
/* update and advertise all ipv4 and ipv6 routes in thr vrf table as type-5
@@ -2588,10 +2599,12 @@ static void delete_withdraw_vrf_routes(struct bgp *bgp_vrf)
static void update_advertise_vrf_routes(struct bgp *bgp_vrf)
{
/* update all ipv4 routes */
- bgp_evpn_advertise_type5_routes(bgp_vrf, AFI_IP, SAFI_UNICAST);
+ if (advertise_type5_routes(bgp_vrf, AFI_IP))
+ bgp_evpn_advertise_type5_routes(bgp_vrf, AFI_IP, SAFI_UNICAST);
/* update all ipv6 routes */
- bgp_evpn_advertise_type5_routes(bgp_vrf, AFI_IP6, SAFI_UNICAST);
+ if (advertise_type5_routes(bgp_vrf, AFI_IP6))
+ bgp_evpn_advertise_type5_routes(bgp_vrf, AFI_IP6, SAFI_UNICAST);
}
/*
@@ -2922,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;
@@ -3214,10 +3240,6 @@ void bgp_evpn_withdraw_type5_route(struct bgp *bgp_vrf, struct prefix *p,
struct prefix_evpn evp;
char buf[PREFIX_STRLEN];
- /* NOTE: Check needed as this is called per-route also. */
- if (!advertise_type5_routes(bgp_vrf, afi))
- return;
-
build_type5_prefix_from_ip_prefix(&evp, p);
ret = delete_evpn_type5_route(bgp_vrf, &evp);
if (ret) {
@@ -3235,10 +3257,6 @@ void bgp_evpn_withdraw_type5_routes(struct bgp *bgp_vrf, afi_t afi, safi_t safi)
struct bgp_node *rn = NULL;
struct bgp_info *ri;
- /* Bail out early if we don't have to advertise type-5 routes. */
- if (!advertise_type5_routes(bgp_vrf, afi))
- return;
-
table = bgp_vrf->rib[afi][safi];
for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
/* Only care about "selected" routes - non-imported. */
@@ -3267,11 +3285,7 @@ void bgp_evpn_advertise_type5_route(struct bgp *bgp_vrf, struct prefix *p,
int ret = 0;
struct prefix_evpn evp;
char buf[PREFIX_STRLEN];
-
- /* NOTE: Check needed as this is called per-route also. */
- if (!advertise_type5_routes(bgp_vrf, afi))
- return;
-
+
build_type5_prefix_from_ip_prefix(&evp, p);
ret = update_evpn_type5_route(bgp_vrf, &evp, src_attr);
if (ret)
@@ -3290,10 +3304,6 @@ void bgp_evpn_advertise_type5_routes(struct bgp *bgp_vrf, afi_t afi,
struct bgp_node *rn = NULL;
struct bgp_info *ri;
- /* Bail out early if we don't have to advertise type-5 routes. */
- if (!advertise_type5_routes(bgp_vrf, afi))
- return;
-
table = bgp_vrf->rib[afi][safi];
for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
/* Need to identify the "selected" route entry to use its
diff --git a/bgpd/bgp_evpn.h b/bgpd/bgp_evpn.h
index bf6150e648..7c0d638327 100644
--- a/bgpd/bgp_evpn.h
+++ b/bgpd/bgp_evpn.h
@@ -55,6 +55,25 @@ static inline vni_t label2vni(mpls_label_t *label)
return vni;
}
+static inline int advertise_type5_routes(struct bgp *bgp_vrf,
+ afi_t afi)
+{
+ if (!bgp_vrf->l3vni)
+ return 0;
+
+ if (afi == AFI_IP &&
+ CHECK_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
+ BGP_L2VPN_EVPN_ADVERTISE_IPV4_UNICAST))
+ return 1;
+
+ if (afi == AFI_IP6 &&
+ CHECK_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
+ BGP_L2VPN_EVPN_ADVERTISE_IPV6_UNICAST))
+ return 1;
+
+ return 0;
+}
+
extern void bgp_evpn_advertise_type5_route(struct bgp *bgp_vrf,
struct prefix *p,
struct attr *src_attr, afi_t afi,
diff --git a/bgpd/bgp_evpn_private.h b/bgpd/bgp_evpn_private.h
index 63dd581845..ce279005dc 100644
--- a/bgpd/bgp_evpn_private.h
+++ b/bgpd/bgp_evpn_private.h
@@ -285,6 +285,14 @@ static inline void ip_prefix_from_type5_prefix(struct prefix_evpn *evp,
}
}
+static inline int is_evpn_prefix_default(struct prefix *evp)
+{
+ if (evp->family != AF_EVPN)
+ return 0;
+
+ return ((evp->u.prefix_evpn.ip_prefix_length == 0) ? 1 : 0);
+}
+
static inline void ip_prefix_from_type2_prefix(struct prefix_evpn *evp,
struct prefix *ip)
{
@@ -352,19 +360,17 @@ static inline void build_evpn_type3_prefix(struct prefix_evpn *p,
p->prefix.ip.ipaddr_v4 = originator_ip;
}
-static inline int advertise_type5_routes(struct bgp *bgp_vrf, afi_t afi)
+static inline int evpn_default_originate_set(struct bgp *bgp, afi_t afi,
+ safi_t safi)
{
- if (!bgp_vrf->l3vni)
- return 0;
-
- if (afi == AFI_IP
- && CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_ADVERTISE_IPV4_IN_EVPN))
+ if (afi == AFI_IP &&
+ CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN],
+ BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV4))
return 1;
-
- if (afi == AFI_IP6
- && CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_ADVERTISE_IPV6_IN_EVPN))
+ else if (afi == AFI_IP6 &&
+ CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN],
+ BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV6))
return 1;
-
return 0;
}
diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c
index d42da23f52..58487a682c 100644
--- a/bgpd/bgp_evpn_vty.c
+++ b/bgpd/bgp_evpn_vty.c
@@ -2419,7 +2419,50 @@ static void evpn_unset_advertise_default_gw(struct bgp *bgp,
/*
* evpn - enable advertisement of default g/w
*/
-static void evpn_set_advertise_subnet(struct bgp *bgp, struct bgpevpn *vpn)
+static void evpn_process_default_originate_cmd(struct bgp *bgp_vrf,
+ afi_t afi, int add)
+{
+ struct prefix ip_prefix;
+ safi_t safi = SAFI_UNICAST; /* ipv4/ipv6 unicast */
+
+ /* form the default prefix 0.0.0.0/0 */
+ memset(&ip_prefix, 0, sizeof(struct prefix));
+ ip_prefix.family = afi2family(afi);
+ ip_prefix.prefixlen = 0;
+
+ if (add) {
+ /* bail if we are already advertising default route */
+ if (evpn_default_originate_set(bgp_vrf, afi, safi))
+ return;
+
+ if (afi == AFI_IP)
+ SET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
+ BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV4);
+ else if (afi == AFI_IP6)
+ SET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
+ BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV6);
+ bgp_evpn_advertise_type5_route(bgp_vrf, &ip_prefix,
+ NULL, afi, safi);
+ } else {
+ /* bail out if we havent advertised the default route */
+ if (!evpn_default_originate_set(bgp_vrf, afi, safi))
+ return;
+ if (afi == AFI_IP)
+ UNSET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
+ BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV4);
+ else if (afi == AFI_IP6)
+ UNSET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
+ BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV6);
+ bgp_evpn_withdraw_type5_route(bgp_vrf, &ip_prefix,
+ afi, safi);
+ }
+}
+
+/*
+ * evpn - enable advertisement of default g/w
+ */
+static void evpn_set_advertise_subnet(struct bgp *bgp,
+ struct bgpevpn *vpn)
{
if (vpn->advertise_subnet)
return;
@@ -2612,6 +2655,43 @@ DEFUN (no_bgp_evpn_advertise_all_vni,
return CMD_SUCCESS;
}
+DEFUN (bgp_evpn_default_originate,
+ bgp_evpn_default_originate_cmd,
+ "default-originate <ipv4 | ipv6>",
+ "originate a default route\n"
+ "ipv4 address family\n"
+ "ipv6 address family\n")
+{
+ afi_t afi = 0;
+ int idx_afi = 0;
+ struct bgp *bgp_vrf = VTY_GET_CONTEXT(bgp);
+
+ if (!bgp_vrf)
+ return CMD_WARNING;
+ argv_find_and_parse_afi(argv, argc, &idx_afi, &afi);
+ evpn_process_default_originate_cmd(bgp_vrf, afi, 1);
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_bgp_evpn_default_originate,
+ no_bgp_evpn_default_originate_cmd,
+ "no default-originate <ipv4 | ipv6>",
+ NO_STR
+ "withdraw a default route\n"
+ "ipv4 address family\n"
+ "ipv6 address family\n")
+{
+ afi_t afi = 0;
+ int idx_afi = 0;
+ struct bgp *bgp_vrf = VTY_GET_CONTEXT(bgp);
+
+ if (!bgp_vrf)
+ return CMD_WARNING;
+ argv_find_and_parse_afi(argv, argc, &idx_afi, &afi);
+ evpn_process_default_originate_cmd(bgp_vrf, afi, 0);
+ return CMD_SUCCESS;
+}
+
DEFUN (bgp_evpn_advertise_vni_subnet,
bgp_evpn_advertise_vni_subnet_cmd,
"advertise-subnet",
@@ -2631,14 +2711,6 @@ DEFUN (bgp_evpn_advertise_vni_subnet,
if (!bgp_vrf)
return CMD_WARNING;
- if (!(advertise_type5_routes(bgp_vrf, AFI_IP)
- || advertise_type5_routes(bgp_vrf, AFI_IP6))) {
- vty_out(vty,
- "%%Please enable ip prefix advertisement under l2vpn evpn in %s",
- vrf_id_to_name(bgp_vrf->vrf_id));
- return CMD_WARNING;
- }
-
evpn_set_advertise_subnet(bgp, vpn);
return CMD_SUCCESS;
}
@@ -2711,19 +2783,23 @@ DEFUN (bgp_evpn_advertise_type5,
/* if we are already advertising ipv4 prefix as type-5
* nothing to do
*/
- if (!rmap_changed && CHECK_FLAG(bgp_vrf->vrf_flags,
- BGP_VRF_ADVERTISE_IPV4_IN_EVPN))
+ if (!rmap_changed &&
+ CHECK_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
+ BGP_L2VPN_EVPN_ADVERTISE_IPV4_UNICAST))
return CMD_WARNING;
- SET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_ADVERTISE_IPV4_IN_EVPN);
+ SET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
+ BGP_L2VPN_EVPN_ADVERTISE_IPV4_UNICAST);
} else {
/* if we are already advertising ipv6 prefix as type-5
* nothing to do
*/
- if (!rmap_changed && CHECK_FLAG(bgp_vrf->vrf_flags,
- BGP_VRF_ADVERTISE_IPV6_IN_EVPN))
+ if (!rmap_changed &&
+ CHECK_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
+ BGP_L2VPN_EVPN_ADVERTISE_IPV6_UNICAST))
return CMD_WARNING;
- SET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_ADVERTISE_IPV6_IN_EVPN);
+ SET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
+ BGP_L2VPN_EVPN_ADVERTISE_IPV6_UNICAST);
}
if (rmap_changed) {
@@ -2766,7 +2842,7 @@ DEFUN (no_bgp_evpn_advertise_type5,
argv_find_and_parse_afi(argv, argc, &idx_afi, &afi);
argv_find_and_parse_safi(argv, argc, &idx_safi, &safi);
- if (!(afi == AFI_IP) || (afi == AFI_IP6)) {
+ if (!(afi == AFI_IP || afi == AFI_IP6)) {
vty_out(vty,
"%%only ipv4 or ipv6 address families are supported");
return CMD_WARNING;
@@ -2780,25 +2856,25 @@ DEFUN (no_bgp_evpn_advertise_type5,
if (afi == AFI_IP) {
- /* if we are already advertising ipv4 prefix as type-5
+ /* if we are not advertising ipv4 prefix as type-5
* nothing to do
*/
- if (CHECK_FLAG(bgp_vrf->vrf_flags,
- BGP_VRF_ADVERTISE_IPV4_IN_EVPN)) {
+ if (CHECK_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
+ BGP_L2VPN_EVPN_ADVERTISE_IPV4_UNICAST)) {
bgp_evpn_withdraw_type5_routes(bgp_vrf, afi, safi);
- UNSET_FLAG(bgp_vrf->vrf_flags,
- BGP_VRF_ADVERTISE_IPV4_IN_EVPN);
+ UNSET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
+ BGP_L2VPN_EVPN_ADVERTISE_IPV4_UNICAST);
}
} else {
- /* if we are already advertising ipv6 prefix as type-5
+ /* if we are not advertising ipv6 prefix as type-5
* nothing to do
*/
- if (CHECK_FLAG(bgp_vrf->vrf_flags,
- BGP_VRF_ADVERTISE_IPV6_IN_EVPN)) {
+ if (CHECK_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
+ BGP_L2VPN_EVPN_ADVERTISE_IPV6_UNICAST)) {
bgp_evpn_withdraw_type5_routes(bgp_vrf, afi, safi);
UNSET_FLAG(bgp_vrf->vrf_flags,
- BGP_VRF_ADVERTISE_IPV6_IN_EVPN);
+ BGP_L2VPN_EVPN_ADVERTISE_IPV6_UNICAST);
}
}
@@ -4305,12 +4381,22 @@ void bgp_config_write_evpn_info(struct vty *vty, struct bgp *bgp, afi_t afi,
if (bgp->advertise_gw_macip)
vty_out(vty, " advertise-default-gw\n");
- if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_ADVERTISE_IPV4_IN_EVPN))
+ if (CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN],
+ BGP_L2VPN_EVPN_ADVERTISE_IPV4_UNICAST))
vty_out(vty, " advertise ipv4 unicast\n");
- if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_ADVERTISE_IPV6_IN_EVPN))
+ if (CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN],
+ BGP_L2VPN_EVPN_ADVERTISE_IPV6_UNICAST))
vty_out(vty, " advertise ipv6 unicast\n");
+ if (CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN],
+ BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV4))
+ vty_out(vty, " default-originate ipv4\n");
+
+ if (CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN],
+ BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV6))
+ vty_out(vty, " default-originate ipv6\n");
+
if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_RD_CFGD))
vty_out(vty, " rd %s\n",
prefix_rd2str(&bgp->vrf_prd, buf1, sizeof(buf1)));
@@ -4373,6 +4459,8 @@ void bgp_ethernetvpn_init(void)
install_element(BGP_EVPN_NODE, &no_bgp_evpn_advertise_default_gw_cmd);
install_element(BGP_EVPN_NODE, &bgp_evpn_advertise_type5_cmd);
install_element(BGP_EVPN_NODE, &no_bgp_evpn_advertise_type5_cmd);
+ install_element(BGP_EVPN_NODE, &bgp_evpn_default_originate_cmd);
+ install_element(BGP_EVPN_NODE, &no_bgp_evpn_default_originate_cmd);
/* "show bgp l2vpn evpn" commands. */
install_element(VIEW_NODE, &show_bgp_l2vpn_evpn_vni_cmd);
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 26f96d684a..032b33229c 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -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)
@@ -2285,12 +2300,13 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_node *rn,
/* advertise/withdraw type-5 routes */
if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
- if (new_select
- && (!new_select->extra || !new_select->extra->parent))
- bgp_evpn_advertise_type5_route(
- bgp, &rn->p, new_select->attr, afi, safi);
- else if (old_select
- && (!old_select->extra || !old_select->extra->parent))
+ if (advertise_type5_routes(bgp, afi) && new_select &&
+ (!new_select->extra || !new_select->extra->parent))
+ bgp_evpn_advertise_type5_route(bgp, &rn->p,
+ new_select->attr,
+ afi, safi);
+ else if (advertise_type5_routes(bgp, afi) && old_select &&
+ (!old_select->extra || !old_select->extra->parent))
bgp_evpn_withdraw_type5_route(bgp, &rn->p, afi, safi);
}
@@ -7197,6 +7213,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;
@@ -7949,6 +7966,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
diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c
index b79c6a7c3a..5a265b6c9c 100644
--- a/bgpd/bgp_routemap.c
+++ b/bgpd/bgp_routemap.c
@@ -595,6 +595,24 @@ struct route_map_rule_cmd route_match_ip_route_source_prefix_list_cmd = {
route_match_ip_route_source_prefix_list_compile,
route_match_ip_route_source_prefix_list_free};
+/* `match evpn default-route' */
+
+/* Match function should return 1 if match is success else 0 */
+static route_map_result_t route_match_evpn_default_route(void *rule,
+ struct prefix *p,
+ route_map_object_t
+ type, void *object)
+{
+ if (type == RMAP_BGP && is_evpn_prefix_default(p))
+ return RMAP_MATCH;
+
+ return RMAP_NOMATCH;
+}
+
+/* Route map commands for default-route matching. */
+struct route_map_rule_cmd route_match_evpn_default_route_cmd = {
+ "evpn default-route", route_match_evpn_default_route, NULL, NULL};
+
/* `match mac address MAC_ACCESS_LIST' */
/* Match function should return 1 if match is success else return
@@ -3254,6 +3272,29 @@ DEFUN (no_match_evpn_vni,
RMAP_EVENT_MATCH_DELETED);
}
+DEFUN (match_evpn_default_route,
+ match_evpn_default_route_cmd,
+ "match evpn default-route",
+ MATCH_STR
+ EVPN_HELP_STR
+ "default EVPN type-5 route\n")
+{
+ return bgp_route_match_add(vty, "evpn default-route", NULL,
+ RMAP_EVENT_MATCH_ADDED);
+}
+
+DEFUN (no_match_evpn_default_route,
+ no_match_evpn_default_route_cmd,
+ "no match evpn default-route",
+ NO_STR
+ MATCH_STR
+ EVPN_HELP_STR
+ "default EVPN type-5 route\n")
+{
+ return bgp_route_match_delete(vty, "evpn default-route", NULL,
+ RMAP_EVENT_MATCH_DELETED);
+}
+
DEFUN (match_peer,
match_peer_cmd,
"match peer <A.B.C.D|X:X::X:X|WORD>",
@@ -4633,6 +4674,7 @@ void bgp_route_map_init(void)
route_map_install_match(&route_match_mac_address_cmd);
route_map_install_match(&route_match_evpn_vni_cmd);
route_map_install_match(&route_match_evpn_route_type_cmd);
+ route_map_install_match(&route_match_evpn_default_route_cmd);
route_map_install_set(&route_set_ip_nexthop_cmd);
route_map_install_set(&route_set_local_pref_cmd);
@@ -4669,6 +4711,8 @@ void bgp_route_map_init(void)
install_element(RMAP_NODE, &no_match_evpn_vni_cmd);
install_element(RMAP_NODE, &match_evpn_route_type_cmd);
install_element(RMAP_NODE, &no_match_evpn_route_type_cmd);
+ install_element(RMAP_NODE, &match_evpn_default_route_cmd);
+ install_element(RMAP_NODE, &no_match_evpn_default_route_cmd);
install_element(RMAP_NODE, &match_aspath_cmd);
install_element(RMAP_NODE, &no_match_aspath_cmd);
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index e7d58a021b..2eae2e5e9e 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -7534,16 +7534,14 @@ static void bgp_pthreads_init()
.id = PTHREAD_IO,
.start = frr_pthread_attr_default.start,
.stop = frr_pthread_attr_default.stop,
- .name = "BGP I/O thread",
};
struct frr_pthread_attr ka = {
.id = PTHREAD_KEEPALIVES,
.start = bgp_keepalives_start,
.stop = bgp_keepalives_stop,
- .name = "BGP Keepalives thread",
};
- frr_pthread_new(&io);
- frr_pthread_new(&ka);
+ frr_pthread_new(&io, "BGP I/O thread");
+ frr_pthread_new(&ka, "BGP Keepalives thread");
}
void bgp_pthreads_run()
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index 41ae8e916f..664f8c9da4 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -319,6 +319,13 @@ struct bgp {
#define BGP_CONFIG_DAMPENING (1 << 0)
#define BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT (1 << 1)
+/* l2vpn evpn flags - 1 << 0 is used for DAMPENNG */
+#define BGP_L2VPN_EVPN_ADVERTISE_IPV4_UNICAST (1 << 1)
+#define BGP_L2VPN_EVPN_ADVERTISE_IPV6_UNICAST (1 << 2)
+#define BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV4 (1 << 3)
+#define BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV6 (1 << 4)
+
+
/* Route table for next-hop lookup cache. */
struct bgp_table *nexthop_cache_table[AFI_MAX];
@@ -430,12 +437,11 @@ struct bgp {
/* vrf flags */
uint32_t vrf_flags;
#define BGP_VRF_AUTO (1 << 0)
-#define BGP_VRF_ADVERTISE_IPV4_IN_EVPN (1 << 1)
-#define BGP_VRF_ADVERTISE_IPV6_IN_EVPN (1 << 2)
-#define BGP_VRF_IMPORT_RT_CFGD (1 << 3)
-#define BGP_VRF_EXPORT_RT_CFGD (1 << 4)
-#define BGP_VRF_RD_CFGD (1 << 5)
-#define BGP_VRF_L3VNI_PREFIX_ROUTES_ONLY (1 << 6)
+#define BGP_VRF_IMPORT_RT_CFGD (1 << 1)
+#define BGP_VRF_EXPORT_RT_CFGD (1 << 2)
+#define BGP_VRF_RD_CFGD (1 << 3)
+#define BGP_VRF_L3VNI_PREFIX_ROUTES_ONLY (1 << 4)
+
/* unique ID for auto derivation of RD for this vrf */
uint16_t vrf_rd_id;