mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-03 06:59:21 +00:00
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:
parent
39c46ff136
commit
76d07c7aa1
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user