summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_evpn.c37
-rw-r--r--bgpd/bgp_evpn.h3
-rw-r--r--bgpd/bgp_evpn_private.h8
-rw-r--r--bgpd/bgp_evpn_vty.c7
-rw-r--r--bgpd/bgp_zebra.c4
5 files changed, 50 insertions, 9 deletions
diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c
index 732cc6d2bb..66b6ad37e8 100644
--- a/bgpd/bgp_evpn.c
+++ b/bgpd/bgp_evpn.c
@@ -2297,6 +2297,26 @@ static int delete_routes_for_vni(struct bgp *bgp, struct bgpevpn *vpn)
}
/*
+ * There is a flood mcast IP address change. Update the mcast-grp and
+ * remove the type-3 route if any. A new type-3 route will be generated
+ * post tunnel_ip update if the new flood mode is head-end-replication.
+ */
+static int bgp_evpn_mcast_grp_change(struct bgp *bgp, struct bgpevpn *vpn,
+ struct in_addr mcast_grp)
+{
+ struct prefix_evpn p;
+
+ vpn->mcast_grp = mcast_grp;
+
+ if (is_vni_live(vpn)) {
+ build_evpn_type3_prefix(&p, vpn->originator_ip);
+ delete_evpn_route(bgp, vpn, &p);
+ }
+
+ return 0;
+}
+
+/*
* There is a tunnel endpoint IP address change for this VNI, delete
* prior type-3 route (if needed) and update.
* Note: Route re-advertisement happens elsewhere after other processing
@@ -5138,8 +5158,9 @@ struct bgpevpn *bgp_evpn_lookup_vni(struct bgp *bgp, vni_t vni)
* Create a new vpn - invoked upon configuration or zebra notification.
*/
struct bgpevpn *bgp_evpn_new(struct bgp *bgp, vni_t vni,
- struct in_addr originator_ip,
- vrf_id_t tenant_vrf_id)
+ struct in_addr originator_ip,
+ vrf_id_t tenant_vrf_id,
+ struct in_addr mcast_grp)
{
struct bgpevpn *vpn;
@@ -5152,6 +5173,7 @@ struct bgpevpn *bgp_evpn_new(struct bgp *bgp, vni_t vni,
vpn->vni = vni;
vpn->originator_ip = originator_ip;
vpn->tenant_vrf_id = tenant_vrf_id;
+ vpn->mcast_grp = mcast_grp;
/* Initialize route-target import and export lists */
vpn->import_rtl = list_new();
@@ -5650,7 +5672,10 @@ int bgp_evpn_local_vni_del(struct bgp *bgp, vni_t vni)
* about are for the local-tunnel-ip and the (tenant) VRF.
*/
int bgp_evpn_local_vni_add(struct bgp *bgp, vni_t vni,
- struct in_addr originator_ip, vrf_id_t tenant_vrf_id)
+ struct in_addr originator_ip,
+ vrf_id_t tenant_vrf_id,
+ struct in_addr mcast_grp)
+
{
struct bgpevpn *vpn;
struct prefix_evpn p;
@@ -5661,11 +5686,14 @@ int bgp_evpn_local_vni_add(struct bgp *bgp, vni_t vni,
if (is_vni_live(vpn)
&& IPV4_ADDR_SAME(&vpn->originator_ip, &originator_ip)
+ && IPV4_ADDR_SAME(&vpn->mcast_grp, &mcast_grp)
&& vpn->tenant_vrf_id == tenant_vrf_id)
/* Probably some other param has changed that we don't
* care about. */
return 0;
+ bgp_evpn_mcast_grp_change(bgp, vpn, mcast_grp);
+
/* Update tenant_vrf_id if it has changed. */
if (vpn->tenant_vrf_id != tenant_vrf_id) {
bgpevpn_unlink_from_l3vni(vpn);
@@ -5688,7 +5716,8 @@ int bgp_evpn_local_vni_add(struct bgp *bgp, vni_t vni,
/* Create or update as appropriate. */
if (!vpn) {
- vpn = bgp_evpn_new(bgp, vni, originator_ip, tenant_vrf_id);
+ vpn = bgp_evpn_new(bgp, vni, originator_ip, tenant_vrf_id,
+ mcast_grp);
if (!vpn) {
flog_err(
EC_BGP_VNI,
diff --git a/bgpd/bgp_evpn.h b/bgpd/bgp_evpn.h
index f5802fa894..4ad8e95bee 100644
--- a/bgpd/bgp_evpn.h
+++ b/bgpd/bgp_evpn.h
@@ -180,7 +180,8 @@ extern int bgp_evpn_local_l3vni_del(vni_t vni, vrf_id_t vrf_id);
extern int bgp_evpn_local_vni_del(struct bgp *bgp, vni_t vni);
extern int bgp_evpn_local_vni_add(struct bgp *bgp, vni_t vni,
struct in_addr originator_ip,
- vrf_id_t tenant_vrf_id);
+ vrf_id_t tenant_vrf_id,
+ struct in_addr mcast_grp);
extern int bgp_evpn_local_es_add(struct bgp *bgp, esi_t *esi,
struct ipaddr *originator_ip);
extern int bgp_evpn_local_es_del(struct bgp *bgp, esi_t *esi,
diff --git a/bgpd/bgp_evpn_private.h b/bgpd/bgp_evpn_private.h
index 785139865e..88b57ff9ea 100644
--- a/bgpd/bgp_evpn_private.h
+++ b/bgpd/bgp_evpn_private.h
@@ -87,6 +87,9 @@ struct bgpevpn {
/* Route type 3 field */
struct in_addr originator_ip;
+ /* PIM-SM MDT group for BUM flooding */
+ struct in_addr mcast_grp;
+
/* Import and Export RTs. */
struct list *import_rtl;
struct list *export_rtl;
@@ -525,8 +528,9 @@ extern void bgp_evpn_derive_auto_rd(struct bgp *bgp, struct bgpevpn *vpn);
extern void bgp_evpn_derive_auto_rd_for_vrf(struct bgp *bgp);
extern struct bgpevpn *bgp_evpn_lookup_vni(struct bgp *bgp, vni_t vni);
extern struct bgpevpn *bgp_evpn_new(struct bgp *bgp, vni_t vni,
- struct in_addr originator_ip,
- vrf_id_t tenant_vrf_id);
+ struct in_addr originator_ip,
+ vrf_id_t tenant_vrf_id,
+ struct in_addr mcast_grp);
extern void bgp_evpn_free(struct bgp *bgp, struct bgpevpn *vpn);
extern struct evpnes *bgp_evpn_lookup_es(struct bgp *bgp, esi_t *esi);
extern struct evpnes *bgp_evpn_es_new(struct bgp *bgp, esi_t *esi,
diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c
index 28ccaada1c..4dccc89f52 100644
--- a/bgpd/bgp_evpn_vty.c
+++ b/bgpd/bgp_evpn_vty.c
@@ -473,6 +473,8 @@ static void display_vni(struct vty *vty, struct bgpevpn *vpn, json_object *json)
prefix_rd2str(&vpn->prd, buf1, sizeof(buf1)));
json_object_string_add(json, "originatorIp",
inet_ntoa(vpn->originator_ip));
+ json_object_string_add(json, "mcastGroup",
+ inet_ntoa(vpn->mcast_grp));
json_object_string_add(json, "advertiseGatewayMacip",
vpn->advertise_gw_macip ? "Yes" : "No");
} else {
@@ -488,6 +490,8 @@ static void display_vni(struct vty *vty, struct bgpevpn *vpn, json_object *json)
prefix_rd2str(&vpn->prd, buf1, sizeof(buf1)));
vty_out(vty, " Originator IP: %s\n",
inet_ntoa(vpn->originator_ip));
+ vty_out(vty, " Mcast group: %s\n",
+ inet_ntoa(vpn->mcast_grp));
vty_out(vty, " Advertise-gw-macip : %s\n",
vpn->advertise_gw_macip ? "Yes" : "No");
vty_out(vty, " Advertise-svi-macip : %s\n",
@@ -1897,6 +1901,7 @@ static void evpn_unconfigure_rd(struct bgp *bgp, struct bgpevpn *vpn)
static struct bgpevpn *evpn_create_update_vni(struct bgp *bgp, vni_t vni)
{
struct bgpevpn *vpn;
+ struct in_addr mcast_grp = {INADDR_ANY};
if (!bgp->vnihash)
return NULL;
@@ -1915,7 +1920,7 @@ static struct bgpevpn *evpn_create_update_vni(struct bgp *bgp, vni_t vni)
/* tenant vrf will be updated when we get local_vni_add from
* zebra
*/
- vpn = bgp_evpn_new(bgp, vni, bgp->router_id, 0);
+ vpn = bgp_evpn_new(bgp, vni, bgp->router_id, 0, mcast_grp);
if (!vpn) {
flog_err(
EC_BGP_VNI,
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index 55ecc5f16c..e42d6ee260 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -2553,12 +2553,14 @@ static int bgp_zebra_process_local_vni(int command, struct zclient *zclient,
struct bgp *bgp;
struct in_addr vtep_ip = {INADDR_ANY};
vrf_id_t tenant_vrf_id = VRF_DEFAULT;
+ struct in_addr mcast_grp = {INADDR_ANY};
s = zclient->ibuf;
vni = stream_getl(s);
if (command == ZEBRA_VNI_ADD) {
vtep_ip.s_addr = stream_get_ipv4(s);
stream_get(&tenant_vrf_id, s, sizeof(vrf_id_t));
+ mcast_grp.s_addr = stream_get_ipv4(s);
}
bgp = bgp_lookup_by_vrf_id(vrf_id);
@@ -2574,7 +2576,7 @@ static int bgp_zebra_process_local_vni(int command, struct zclient *zclient,
if (command == ZEBRA_VNI_ADD)
return bgp_evpn_local_vni_add(
bgp, vni, vtep_ip.s_addr ? vtep_ip : bgp->router_id,
- tenant_vrf_id);
+ tenant_vrf_id, mcast_grp);
else
return bgp_evpn_local_vni_del(bgp, vni);
}