bgpd: maintain flood mcast group per-l2-vni

If PIM-SM if used for BUM flooding the multicast group address can be
configured per-vxlan-device. BGP receives this config from zebra via
the L2 VNI add/update.

Sample output -
root@TORS1:~# vtysh -c "show bgp l2vpn evpn vni 1000" |grep Mcast
  Mcast group: 239.1.1.100
root@TORS1:~#

Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
This commit is contained in:
Anuradha Karuppiah 2019-03-19 11:08:24 -07:00
parent 39c46ff136
commit 76d07c7aa1
5 changed files with 50 additions and 9 deletions

View File

@ -2296,6 +2296,26 @@ static int delete_routes_for_vni(struct bgp *bgp, struct bgpevpn *vpn)
return delete_all_vni_routes(bgp, 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.
@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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);
}