3 * Copyright 2009-2016, LabN Consulting, L.L.C.
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 * File: vnc_export_bgp.c
24 * Purpose: Export routes to BGP directly (not via zebra)
27 #include "lib/zebra.h"
28 #include "lib/prefix.h"
29 #include "lib/table.h"
32 #include "lib/stream.h"
33 #include "lib/memory.h"
34 #include "lib/linklist.h"
35 #include "lib/plist.h"
36 #include "lib/routemap.h"
38 #include "bgpd/bgpd.h"
39 #include "bgpd/bgp_ecommunity.h"
40 #include "bgpd/bgp_attr.h"
41 #include "bgpd/bgp_aspath.h"
43 #include "bgpd/rfapi/vnc_export_bgp.h"
44 #include "bgpd/rfapi/vnc_export_bgp_p.h"
45 #include "bgpd/rfapi/vnc_export_table.h"
46 #include "bgpd/rfapi/bgp_rfapi_cfg.h"
47 #include "bgpd/rfapi/rfapi.h"
48 #include "bgpd/rfapi/rfapi_import.h"
49 #include "bgpd/rfapi/rfapi_private.h"
50 #include "bgpd/rfapi/rfapi_backend.h"
51 #include "bgpd/rfapi/rfapi_vty.h"
52 #include "bgpd/rfapi/vnc_debug.h"
54 /***********************************************************************
55 * Export methods that set nexthop to CE (from 5226 roo EC) BEGIN
56 ***********************************************************************/
59 * Memory allocation approach: make a ghost attr that
60 * has non-interned parts for the modifications. ghost attr
61 * memory is allocated by caller.
63 * - extract ce (=5226) EC and use as new nexthop
64 * - strip Tunnel Encap attr
68 encap_attr_export_ce (
71 struct prefix
*use_nexthop
)
74 * Make "new" a ghost attr copy of "orig"
76 memset (new, 0, sizeof (struct attr
));
77 bgp_attr_dup (new, orig
);
78 bgp_attr_extra_get (new);
83 switch (use_nexthop
->family
)
86 new->nexthop
= use_nexthop
->u
.prefix4
;
87 new->extra
->mp_nexthop_len
= 4; /* bytes */
88 new->flag
|= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP
);
94 new->extra
= XCALLOC (MTYPE_ATTR_EXTRA
, sizeof (struct attr_extra
));
96 new->extra
->mp_nexthop_global
= use_nexthop
->u
.prefix6
;
97 new->extra
->mp_nexthop_len
= 16; /* bytes */
108 * Note that it will be deleted when BGP sends to any eBGP
109 * peer unless PEER_FLAG_MED_UNCHANGED is set:
111 * neighbor NEIGHBOR attribute-unchanged med
113 if (!CHECK_FLAG (new->flag
, BGP_ATTR_MULTI_EXIT_DISC
))
115 if (CHECK_FLAG (new->flag
, BGP_ATTR_LOCAL_PREF
))
117 if (new->local_pref
> 255)
120 new->med
= 255 - new->local_pref
;
124 new->med
= 255; /* shouldn't happen */
126 new->flag
|= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
);
130 * "new" is now a ghost attr:
131 * - it owns an "extra" struct
132 * - it owns any non-interned parts
133 * - any references to interned parts are not counted
135 * Caller should, after using the attr, call:
136 * - bgp_attr_flush() to free non-interned parts
137 * - call bgp_attr_extra_free() to free extra
142 getce (struct bgp
*bgp
, struct attr
*attr
, struct prefix
*pfx_ce
)
146 uint16_t localadmin
= bgp
->rfapi_cfg
->resolve_nve_roo_local_admin
;
148 for (ecp
= attr
->extra
->ecommunity
->val
, i
= 0;
149 i
< attr
->extra
->ecommunity
->size
; ++i
, ecp
+= ECOMMUNITY_SIZE
)
152 if (VNC_DEBUG(EXPORT_BGP_GETCE
))
154 vnc_zlog_debug_any ("%s: %02x %02x %02x %02x %02x %02x %02x %02x",
156 ecp
[0], ecp
[1], ecp
[2], ecp
[3], ecp
[4], ecp
[5], ecp
[6],
163 if (ecp
[0] != 1 || ecp
[1] != 3)
169 * Match local admin value?
171 if (ecp
[6] != ((localadmin
& 0xff00) >> 8) ||
172 ecp
[7] != (localadmin
& 0xff))
175 memset ((uint8_t *) pfx_ce
, 0, sizeof (*pfx_ce
));
176 memcpy (&pfx_ce
->u
.prefix4
, ecp
+ 2, 4);
177 pfx_ce
->family
= AF_INET
;
178 pfx_ce
->prefixlen
= 32;
187 vnc_direct_bgp_add_route_ce (
189 struct route_node
*rn
,
192 struct attr
*attr
= bi
->attr
;
193 struct peer
*peer
= bi
->peer
;
194 struct prefix
*prefix
= &rn
->p
;
195 afi_t afi
= family2afi (prefix
->family
);
196 struct bgp_node
*urn
;
197 struct bgp_info
*ubi
;
200 struct prefix ce_nexthop
;
201 struct prefix post_routemap_nexthop
;
206 zlog_err ("%s: can't get afi of route node", __func__
);
210 if ((bi
->type
!= ZEBRA_ROUTE_BGP
) ||
211 (bi
->sub_type
!= BGP_ROUTE_NORMAL
&&
212 bi
->sub_type
!= BGP_ROUTE_RFP
&& bi
->sub_type
!= BGP_ROUTE_STATIC
))
215 vnc_zlog_debug_verbose ("%s: wrong route type/sub_type for export, skipping",
220 /* check bgp redist flag for vnc direct ("vpn") routes */
221 if (!bgp
->redist
[afi
][ZEBRA_ROUTE_VNC_DIRECT
])
223 vnc_zlog_debug_verbose ("%s: bgp redistribution of VNC direct routes is off",
230 vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__
);
234 if (!VNC_EXPORT_BGP_CE_ENABLED (bgp
->rfapi_cfg
))
236 vnc_zlog_debug_verbose ("%s: export-to-bgp ce mode not enabled, skipping",
244 if (bgp
->rfapi_cfg
->plist_export_bgp
[afi
])
246 if (prefix_list_apply (bgp
->rfapi_cfg
->plist_export_bgp
[afi
], prefix
) ==
249 vnc_zlog_debug_verbose ("%s: prefix list denied, skipping", __func__
);
257 * This works only for IPv4 because IPv6 addresses are too big
258 * to fit in an extended community
260 if (getce (bgp
, attr
, &ce_nexthop
))
262 vnc_zlog_debug_verbose ("%s: EC has no encoded CE, skipping", __func__
);
267 * Is this route already represented in the unicast RIB?
268 * (look up prefix; compare route type, sub_type, peer, nexthop)
271 bgp_afi_node_get (bgp
->rib
[afi
][SAFI_UNICAST
], afi
, SAFI_UNICAST
, prefix
,
273 for (ubi
= urn
->info
; ubi
; ubi
= ubi
->next
)
275 struct prefix unicast_nexthop
;
277 if (CHECK_FLAG (ubi
->flags
, BGP_INFO_REMOVED
))
280 rfapiUnicastNexthop2Prefix (afi
, ubi
->attr
, &unicast_nexthop
);
282 if (ubi
->type
== ZEBRA_ROUTE_VNC_DIRECT
&&
283 ubi
->sub_type
== BGP_ROUTE_REDISTRIBUTE
&&
284 ubi
->peer
== peer
&& prefix_same (&unicast_nexthop
, &ce_nexthop
))
287 vnc_zlog_debug_verbose
288 ("%s: already have matching exported unicast route, skipping",
295 * Construct new attribute set with CE addr as
296 * nexthop and without Tunnel Encap attr
298 encap_attr_export_ce (&hattr
, attr
, &ce_nexthop
);
299 if (bgp
->rfapi_cfg
->routemap_export_bgp
)
301 struct bgp_info info
;
302 route_map_result_t ret
;
304 memset (&info
, 0, sizeof (info
));
308 route_map_apply (bgp
->rfapi_cfg
->routemap_export_bgp
, prefix
,
310 if (ret
== RMAP_DENYMATCH
)
312 bgp_attr_flush (&hattr
);
313 bgp_attr_extra_free (&hattr
);
318 iattr
= bgp_attr_intern (&hattr
);
319 bgp_attr_flush (&hattr
);
320 bgp_attr_extra_free (&hattr
);
323 * Rule: disallow route-map alteration of next-hop, because it
324 * would make it too difficult to keep track of the correspondence
325 * between VPN routes and unicast routes.
327 rfapiUnicastNexthop2Prefix (afi
, iattr
, &post_routemap_nexthop
);
329 if (!prefix_same (&ce_nexthop
, &post_routemap_nexthop
))
331 vnc_zlog_debug_verbose
332 ("%s: route-map modification of nexthop not allowed, skipping",
334 bgp_attr_unintern (&iattr
);
338 bgp_update (peer
, prefix
,
340 iattr
, /* bgp_update copies this attr */
341 afi
, SAFI_UNICAST
, ZEBRA_ROUTE_VNC_DIRECT
, BGP_ROUTE_REDISTRIBUTE
, NULL
, /* RD not used for unicast */
342 NULL
, /* tag not used for unicast */
343 0, NULL
); /* EVPN not used */
344 bgp_attr_unintern (&iattr
);
349 * "Withdrawing a Route" export process
352 vnc_direct_bgp_del_route_ce (
354 struct route_node
*rn
,
357 afi_t afi
= family2afi (rn
->p
.family
);
358 struct bgp_info
*vbi
;
359 struct prefix ce_nexthop
;
363 zlog_err ("%s: bad afi", __func__
);
367 /* check bgp redist flag for vnc direct ("vpn") routes */
368 if (!bgp
->redist
[afi
][ZEBRA_ROUTE_VNC_DIRECT
])
370 vnc_zlog_debug_verbose ("%s: bgp redistribution of VNC direct routes is off",
377 vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__
);
380 if (!VNC_EXPORT_BGP_CE_ENABLED (bgp
->rfapi_cfg
))
382 vnc_zlog_debug_verbose ("%s: export-to-bgp ce mode not enabled, skipping",
389 * This works only for IPv4 because IPv6 addresses are too big
390 * to fit in an extended community
392 if (getce (bgp
, bi
->attr
, &ce_nexthop
))
394 vnc_zlog_debug_verbose ("%s: EC has no encoded CE, skipping", __func__
);
399 * Look for other VPN routes with same prefix, same 5226 CE,
400 * same peer. If at least one is present, don't remove the
401 * route from the unicast RIB
404 for (vbi
= rn
->info
; vbi
; vbi
= vbi
->next
)
409 if (bi
->peer
!= vbi
->peer
)
411 if (getce (bgp
, vbi
->attr
, &ce
))
413 if (prefix_same (&ce
, &ce_nexthop
))
415 vnc_zlog_debug_verbose ("%s: still have a route via CE, not deleting unicast",
424 bgp_withdraw (bi
->peer
, &rn
->p
,
426 NULL
, /* attr, ignored */
427 afi
, SAFI_UNICAST
, ZEBRA_ROUTE_VNC_DIRECT
, BGP_ROUTE_REDISTRIBUTE
, NULL
, /* RD not used for unicast */
428 NULL
, NULL
); /* tag not used for unicast */
433 vnc_direct_bgp_vpn_enable_ce (struct bgp
*bgp
, afi_t afi
)
435 struct rfapi_cfg
*hc
;
436 struct route_node
*rn
;
439 vnc_zlog_debug_verbose ("%s: entry, afi=%d", __func__
, afi
);
444 if (!(hc
= bgp
->rfapi_cfg
))
447 if (!VNC_EXPORT_BGP_CE_ENABLED (bgp
->rfapi_cfg
))
449 vnc_zlog_debug_verbose ("%s: export of CE routes not enabled, skipping", __func__
);
456 vnc_zlog_debug_verbose ("%s: bad afi: %d", __func__
, afi
);
461 * Go through entire ce import table and export to BGP unicast.
463 for (rn
= route_top (bgp
->rfapi
->it_ce
->imported_vpn
[afi
]); rn
;
464 rn
= route_next (rn
))
471 char prefixstr
[BUFSIZ
];
474 inet_ntop (rn
->p
.family
, &rn
->p
.u
.prefix
, prefixstr
, BUFSIZ
);
475 vnc_zlog_debug_verbose ("%s: checking prefix %s/%d", __func__
, prefixstr
,
479 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
482 vnc_zlog_debug_verbose ("%s: ri->sub_type: %d", __func__
, ri
->sub_type
);
484 if (ri
->sub_type
== BGP_ROUTE_NORMAL
||
485 ri
->sub_type
== BGP_ROUTE_RFP
||
486 ri
->sub_type
== BGP_ROUTE_STATIC
)
489 vnc_direct_bgp_add_route_ce (bgp
, rn
, ri
);
497 vnc_direct_bgp_vpn_disable_ce (struct bgp
*bgp
, afi_t afi
)
501 vnc_zlog_debug_verbose ("%s: entry, afi=%d", __func__
, afi
);
509 vnc_zlog_debug_verbose ("%s: bad afi: %d", __func__
, afi
);
514 * Go through the entire BGP unicast table and remove routes that
517 for (rn
= bgp_table_top (bgp
->rib
[afi
][SAFI_UNICAST
]); rn
;
518 rn
= bgp_route_next (rn
))
522 struct bgp_info
*next
;
524 for (ri
= rn
->info
, next
= NULL
; ri
; ri
= next
)
529 if (ri
->type
== ZEBRA_ROUTE_VNC_DIRECT
&&
530 ri
->sub_type
== BGP_ROUTE_REDISTRIBUTE
)
533 bgp_withdraw (ri
->peer
, &rn
->p
, /* prefix */
536 AFI_IP
, SAFI_UNICAST
, ZEBRA_ROUTE_VNC_DIRECT
, BGP_ROUTE_REDISTRIBUTE
, NULL
, /* RD not used for unicast */
537 NULL
, NULL
); /* tag not used for unicast */
543 /***********************************************************************
544 * Export methods that set nexthop to CE (from 5226 roo EC) END
545 ***********************************************************************/
547 /***********************************************************************
548 * Export methods that proxy nexthop BEGIN
549 ***********************************************************************/
551 static struct ecommunity
*
552 vnc_route_origin_ecom (struct route_node
*rn
)
554 struct ecommunity
*new;
560 new = ecommunity_new ();
562 for (bi
= rn
->info
; bi
; bi
= bi
->next
)
565 struct ecommunity_val roec
;
567 switch (BGP_MP_NEXTHOP_FAMILY (bi
->attr
->extra
->mp_nexthop_len
))
570 memset (&roec
, 0, sizeof (roec
));
573 memcpy (roec
.val
+ 2,
574 &bi
->attr
->extra
->mp_nexthop_global_in
.s_addr
, 4);
577 ecommunity_add_val (new, &roec
);
580 /* No support for IPv6 addresses in extended communities */
587 ecommunity_free (&new);
594 static struct ecommunity
*
595 vnc_route_origin_ecom_single (struct in_addr
*origin
)
597 struct ecommunity
*new;
598 struct ecommunity_val roec
;
600 memset (&roec
, 0, sizeof (roec
));
603 memcpy (roec
.val
+ 2, &origin
->s_addr
, 4);
607 new = ecommunity_new ();
609 ecommunity_add_val (new, &roec
);
613 ecommunity_free (&new);
622 * New memory allocation approach: make a ghost attr that
623 * has non-interned parts for the modifications. ghost attr
624 * memory is allocated by caller.
630 struct prefix
*new_nexthop
,
631 struct route_node
*rn
) /* for VN addrs for ecom list */
632 /* if rn is 0, use route's nexthop */
634 struct prefix orig_nexthop
;
635 struct prefix
*use_nexthop
;
636 static struct ecommunity
*ecom_ro
;
640 use_nexthop
= new_nexthop
;
644 use_nexthop
= &orig_nexthop
;
645 orig_nexthop
.family
=
646 BGP_MP_NEXTHOP_FAMILY (orig
->extra
->mp_nexthop_len
);
647 if (orig_nexthop
.family
== AF_INET
)
649 orig_nexthop
.prefixlen
= 32;
650 orig_nexthop
.u
.prefix4
= orig
->extra
->mp_nexthop_global_in
;
652 else if (orig_nexthop
.family
== AF_INET6
)
654 orig_nexthop
.prefixlen
= 128;
655 orig_nexthop
.u
.prefix6
= orig
->extra
->mp_nexthop_global
;
659 return -1; /* FAIL - can't compute nexthop */
665 * Make "new" a ghost attr copy of "orig"
667 memset (new, 0, sizeof (struct attr
));
668 bgp_attr_dup (new, orig
);
673 switch (use_nexthop
->family
)
676 new->nexthop
= use_nexthop
->u
.prefix4
;
677 new->extra
->mp_nexthop_len
= 4; /* bytes */
678 new->flag
|= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP
);
684 new->extra
= XCALLOC (MTYPE_ATTR_EXTRA
, sizeof (struct attr_extra
));
686 new->extra
->mp_nexthop_global
= use_nexthop
->u
.prefix6
;
687 new->extra
->mp_nexthop_len
= 16; /* bytes */
695 bgp_attr_extra_get (new);
698 ecom_ro
= vnc_route_origin_ecom (rn
);
702 /* TBD test/assert for IPv6 */
703 ecom_ro
= vnc_route_origin_ecom_single (&use_nexthop
->u
.prefix4
);
705 if (new->extra
->ecommunity
)
709 new->extra
->ecommunity
=
710 ecommunity_merge (ecom_ro
, new->extra
->ecommunity
);
715 new->extra
->ecommunity
= ecom_ro
;
719 new->flag
|= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES
);
725 * Note that it will be deleted when BGP sends to any eBGP
726 * peer unless PEER_FLAG_MED_UNCHANGED is set:
728 * neighbor NEIGHBOR attribute-unchanged med
730 if (!CHECK_FLAG (new->flag
, BGP_ATTR_MULTI_EXIT_DISC
))
732 if (CHECK_FLAG (new->flag
, BGP_ATTR_LOCAL_PREF
))
734 if (new->local_pref
> 255)
737 new->med
= 255 - new->local_pref
;
741 new->med
= 255; /* shouldn't happen */
743 new->flag
|= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
);
747 * "new" is now a ghost attr:
748 * - it owns an "extra" struct
749 * - it owns any non-interned parts
750 * - any references to interned parts are not counted
752 * Caller should, after using the attr, call:
753 * - bgp_attr_flush() to free non-interned parts
754 * - call bgp_attr_extra_free() to free extra
761 * "Adding a Route" export process
764 vnc_direct_bgp_add_prefix (
766 struct rfapi_import_table
*import_table
,
767 struct route_node
*rn
)
769 struct attr attr
= { 0 };
770 struct listnode
*node
, *nnode
;
771 struct rfapi_rfg_name
*rfgn
;
772 afi_t afi
= family2afi (rn
->p
.family
);
776 zlog_err ("%s: can't get afi of route node", __func__
);
780 /* check bgp redist flag for vnc direct ("vpn") routes */
781 if (!bgp
->redist
[afi
][ZEBRA_ROUTE_VNC_DIRECT
])
783 vnc_zlog_debug_verbose ("%s: bgp redistribution of VNC direct routes is off",
790 vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__
);
794 if (!VNC_EXPORT_BGP_GRP_ENABLED (bgp
->rfapi_cfg
))
796 vnc_zlog_debug_verbose ("%s: export-to-bgp group mode not enabled, skipping",
801 if (!listcount (bgp
->rfapi_cfg
->rfg_export_direct_bgp_l
))
803 vnc_zlog_debug_verbose ("%s: no bgp-direct export nve group, skipping", __func__
);
807 bgp_attr_default_set (&attr
, BGP_ORIGIN_INCOMPLETE
);
808 /* TBD set some configured med, see add_vnc_route() */
810 vnc_zlog_debug_verbose ("%s: looping over nve-groups in direct-bgp export list",
813 for (ALL_LIST_ELEMENTS (bgp
->rfapi_cfg
->rfg_export_direct_bgp_l
,
820 * If nve group is not defined yet, skip it
826 * If the nve group uses a different import table, skip it
828 if (import_table
!= rfgn
->rfg
->rfapi_import_table
)
832 * if no NVEs currently associated with this group, skip it
834 if (!rfgn
->rfg
->nves
)
838 * per-nve-group prefix list check
840 if (rfgn
->rfg
->plist_export_bgp
[afi
])
842 if (prefix_list_apply (rfgn
->rfg
->plist_export_bgp
[afi
], &rn
->p
) ==
849 * For each NVE that is assigned to the export nve group, generate
850 * a route with that NVE as its next hop
852 for (ln
= listhead (rfgn
->rfg
->nves
); ln
; ln
= listnextnode (ln
))
856 struct rfapi_descriptor
*irfd
;
857 struct bgp_info info
;
861 irfd
= listgetdata (ln
);
863 if (rfapiRaddr2Qprefix (&irfd
->vn_addr
, &nhp
))
867 * Construct new attribute set with NVE's VN addr as
868 * nexthop and without Tunnel Encap attr
870 if (encap_attr_export (&hattr
, &attr
, &nhp
, rn
))
873 if (VNC_DEBUG(EXPORT_BGP_DIRECT_ADD
))
875 vnc_zlog_debug_any ("%s: attr follows", __func__
);
876 rfapiPrintAttrPtrs (NULL
, &attr
);
877 vnc_zlog_debug_any ("%s: hattr follows", __func__
);
878 rfapiPrintAttrPtrs (NULL
, &hattr
);
881 if (rfgn
->rfg
->routemap_export_bgp
)
883 route_map_result_t ret
;
884 info
.peer
= irfd
->peer
;
886 ret
= route_map_apply (rfgn
->rfg
->routemap_export_bgp
, &rn
->p
,
888 if (ret
== RMAP_DENYMATCH
)
890 bgp_attr_flush (&hattr
);
891 bgp_attr_extra_free (&hattr
);
892 vnc_zlog_debug_verbose
893 ("%s: route map says DENY, so not calling bgp_update",
899 if (VNC_DEBUG(EXPORT_BGP_DIRECT_ADD
))
901 vnc_zlog_debug_any ("%s: hattr after route_map_apply:", __func__
);
902 rfapiPrintAttrPtrs (NULL
, &hattr
);
905 iattr
= bgp_attr_intern (&hattr
);
906 bgp_attr_flush (&hattr
);
907 bgp_attr_extra_free (&hattr
);
909 bgp_update (irfd
->peer
, &rn
->p
, /* prefix */
911 iattr
, /* bgp_update copies it */
912 afi
, SAFI_UNICAST
, ZEBRA_ROUTE_VNC_DIRECT
, BGP_ROUTE_REDISTRIBUTE
, NULL
, /* RD not used for unicast */
913 NULL
, /* tag not used for unicast */
914 0, NULL
); /* EVPN not used */
916 bgp_attr_unintern (&iattr
);
920 aspath_unintern (&attr
.aspath
);
921 bgp_attr_extra_free (&attr
);
925 * "Withdrawing a Route" export process
928 vnc_direct_bgp_del_prefix (
930 struct rfapi_import_table
*import_table
,
931 struct route_node
*rn
)
933 struct listnode
*node
, *nnode
;
934 struct rfapi_rfg_name
*rfgn
;
935 afi_t afi
= family2afi (rn
->p
.family
);
939 zlog_err ("%s: can't get afi route node", __func__
);
943 /* check bgp redist flag for vnc direct ("vpn") routes */
944 if (!bgp
->redist
[afi
][ZEBRA_ROUTE_VNC_DIRECT
])
946 vnc_zlog_debug_verbose ("%s: bgp redistribution of VNC direct routes is off",
953 vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__
);
957 if (!VNC_EXPORT_BGP_GRP_ENABLED (bgp
->rfapi_cfg
))
959 vnc_zlog_debug_verbose ("%s: export-to-bgp group mode not enabled, skipping",
964 if (!listcount (bgp
->rfapi_cfg
->rfg_export_direct_bgp_l
))
966 vnc_zlog_debug_verbose ("%s: no bgp-direct export nve group, skipping", __func__
);
970 for (ALL_LIST_ELEMENTS (bgp
->rfapi_cfg
->rfg_export_direct_bgp_l
,
977 * If nve group is not defined yet, skip it
983 * if no NVEs currently associated with this group, skip it
985 if (!rfgn
->rfg
->nves
)
989 * If the nve group uses a different import table,
992 if (import_table
!= rfgn
->rfg
->rfapi_import_table
)
996 * For each NVE that is assigned to the export nve group, generate
997 * a route with that NVE as its next hop
999 for (ln
= listhead (rfgn
->rfg
->nves
); ln
; ln
= listnextnode (ln
))
1003 struct rfapi_descriptor
*irfd
;
1005 irfd
= listgetdata (ln
);
1007 if (rfapiRaddr2Qprefix (&irfd
->vn_addr
, &nhp
))
1010 bgp_withdraw (irfd
->peer
, &rn
->p
, /* prefix */
1012 NULL
, /* attr, ignored */
1013 afi
, SAFI_UNICAST
, ZEBRA_ROUTE_VNC_DIRECT
, BGP_ROUTE_REDISTRIBUTE
, NULL
, /* RD not used for unicast */
1014 NULL
, NULL
); /* tag not used for unicast */
1020 vnc_direct_bgp_add_nve (struct bgp
*bgp
, struct rfapi_descriptor
*rfd
)
1022 struct listnode
*node
, *nnode
;
1023 struct rfapi_rfg_name
*rfgn
;
1024 struct rfapi_nve_group_cfg
*rfg
= rfd
->rfg
;
1025 afi_t afi
= family2afi (rfd
->vn_addr
.addr_family
);
1029 zlog_err ("%s: can't get afi of nve vn addr", __func__
);
1035 if (!bgp
->rfapi_cfg
)
1037 vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__
);
1040 if (!VNC_EXPORT_BGP_GRP_ENABLED (bgp
->rfapi_cfg
))
1042 vnc_zlog_debug_verbose ("%s: export-to-bgp group mode not enabled, skipping",
1047 if (!bgp
->redist
[afi
][ZEBRA_ROUTE_VNC_DIRECT
])
1049 vnc_zlog_debug_verbose ("%s: bgp redistribution of VNC direct routes is off",
1055 * Loop over the list of NVE-Groups configured for
1056 * exporting to direct-bgp and see if this new NVE's
1057 * group is among them.
1059 for (ALL_LIST_ELEMENTS (bgp
->rfapi_cfg
->rfg_export_direct_bgp_l
,
1064 * Yes, this NVE's group is configured for export to direct-bgp
1066 if (rfgn
->rfg
== rfg
)
1069 struct route_table
*rt
= NULL
;
1070 struct route_node
*rn
;
1071 struct attr attr
= { 0 };
1072 struct rfapi_import_table
*import_table
;
1075 import_table
= rfg
->rfapi_import_table
;
1077 bgp_attr_default_set (&attr
, BGP_ORIGIN_INCOMPLETE
);
1078 /* TBD set some configured med, see add_vnc_route() */
1083 rt
= import_table
->imported_vpn
[afi
];
1087 zlog_err ("%s: bad afi %d", __func__
, afi
);
1092 * Walk the NVE-Group's VNC Import table
1094 for (rn
= route_top (rt
); rn
; rn
= route_next (rn
))
1101 struct rfapi_descriptor
*irfd
= rfd
;
1104 struct bgp_info info
;
1106 if (rfapiRaddr2Qprefix (&irfd
->vn_addr
, &nhp
))
1110 * per-nve-group prefix list check
1112 if (rfgn
->rfg
->plist_export_bgp
[afi
])
1114 if (prefix_list_apply (rfgn
->rfg
->plist_export_bgp
[afi
],
1115 &rn
->p
) == PREFIX_DENY
)
1122 * Construct new attribute set with NVE's VN addr as
1123 * nexthop and without Tunnel Encap attr
1125 if (encap_attr_export (&hattr
, &attr
, &nhp
, rn
))
1128 if (rfgn
->rfg
->routemap_export_bgp
)
1130 route_map_result_t ret
;
1131 info
.peer
= irfd
->peer
;
1133 ret
= route_map_apply (rfgn
->rfg
->routemap_export_bgp
,
1134 &rn
->p
, RMAP_BGP
, &info
);
1135 if (ret
== RMAP_DENYMATCH
)
1137 bgp_attr_flush (&hattr
);
1138 bgp_attr_extra_free (&hattr
);
1144 iattr
= bgp_attr_intern (&hattr
);
1145 bgp_attr_flush (&hattr
);
1146 bgp_attr_extra_free (&hattr
);
1148 bgp_update (irfd
->peer
, &rn
->p
, /* prefix */
1150 iattr
, /* bgp_update copies it */
1151 afi
, SAFI_UNICAST
, ZEBRA_ROUTE_VNC_DIRECT
, BGP_ROUTE_REDISTRIBUTE
, NULL
, /* RD not used for unicast */
1152 NULL
, /* tag not used for unicast */
1153 0, NULL
); /* EVPN not used */
1155 bgp_attr_unintern (&iattr
);
1160 aspath_unintern (&attr
.aspath
);
1161 bgp_attr_extra_free (&attr
);
1168 vnc_direct_bgp_del_nve (struct bgp
*bgp
, struct rfapi_descriptor
*rfd
)
1170 struct listnode
*node
, *nnode
;
1171 struct rfapi_rfg_name
*rfgn
;
1172 struct rfapi_nve_group_cfg
*rfg
= rfd
->rfg
;
1173 afi_t afi
= family2afi (rfd
->vn_addr
.addr_family
);
1177 zlog_err ("%s: can't get afi of nve vn addr", __func__
);
1183 if (!bgp
->rfapi_cfg
)
1185 vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__
);
1188 if (!VNC_EXPORT_BGP_GRP_ENABLED (bgp
->rfapi_cfg
))
1190 vnc_zlog_debug_verbose ("%s: export-to-bgp group mode not enabled, skipping",
1195 if (!bgp
->redist
[afi
][ZEBRA_ROUTE_VNC_DIRECT
])
1197 vnc_zlog_debug_verbose ("%s: bgp redistribution of VNC direct routes is off",
1203 * Loop over the list of NVE-Groups configured for
1204 * exporting to direct-bgp and see if this new NVE's
1205 * group is among them.
1207 for (ALL_LIST_ELEMENTS (bgp
->rfapi_cfg
->rfg_export_direct_bgp_l
,
1212 * Yes, this NVE's group is configured for export to direct-bgp
1214 if (rfg
&& rfgn
->rfg
== rfg
)
1217 struct route_table
*rt
= NULL
;
1218 struct route_node
*rn
;
1219 struct rfapi_import_table
*import_table
;
1221 import_table
= rfg
->rfapi_import_table
;
1226 rt
= import_table
->imported_vpn
[afi
];
1230 zlog_err ("%s: bad afi %d", __func__
, afi
);
1235 * Walk the NVE-Group's VNC Import table
1237 for (rn
= route_top (rt
); rn
; rn
= route_next (rn
))
1244 struct rfapi_descriptor
*irfd
= rfd
;
1246 if (rfapiRaddr2Qprefix (&irfd
->vn_addr
, &nhp
))
1249 bgp_withdraw (irfd
->peer
, &rn
->p
, /* prefix */
1251 NULL
, /* attr, ignored */
1252 afi
, SAFI_UNICAST
, ZEBRA_ROUTE_VNC_DIRECT
, BGP_ROUTE_REDISTRIBUTE
, NULL
, /* RD not used for unicast */
1253 NULL
, NULL
); /* tag not used for unicast */
1264 * Caller is responsible for ensuring that the specified nve-group
1265 * is actually part of the list of exported nve groups.
1268 vnc_direct_bgp_add_group_afi (
1270 struct rfapi_nve_group_cfg
*rfg
,
1273 struct route_table
*rt
= NULL
;
1274 struct route_node
*rn
;
1275 struct attr attr
= { 0 };
1276 struct rfapi_import_table
*import_table
;
1278 vnc_zlog_debug_verbose ("%s: entry", __func__
);
1280 import_table
= rfg
->rfapi_import_table
;
1283 vnc_zlog_debug_verbose ("%s: import table not defined, returning", __func__
);
1290 rt
= import_table
->imported_vpn
[afi
];
1294 zlog_err ("%s: bad afi %d", __func__
, afi
);
1300 /* avoid segfault below if list doesn't exist */
1301 vnc_zlog_debug_verbose ("%s: no NVEs in this group", __func__
);
1305 bgp_attr_default_set (&attr
, BGP_ORIGIN_INCOMPLETE
);
1306 /* TBD set some configured med, see add_vnc_route() */
1309 * Walk the NVE-Group's VNC Import table
1311 for (rn
= route_top (rt
); rn
; rn
= route_next (rn
))
1317 struct listnode
*ln
;
1320 * per-nve-group prefix list check
1322 if (rfg
->plist_export_bgp
[afi
])
1324 if (prefix_list_apply (rfg
->plist_export_bgp
[afi
], &rn
->p
) ==
1331 * For each NVE that is assigned to the export nve group, generate
1332 * a route with that NVE as its next hop
1334 for (ln
= listhead (rfg
->nves
); ln
; ln
= listnextnode (ln
))
1338 struct rfapi_descriptor
*irfd
;
1339 struct bgp_info info
;
1343 irfd
= listgetdata (ln
);
1345 if (rfapiRaddr2Qprefix (&irfd
->vn_addr
, &nhp
))
1349 * Construct new attribute set with NVE's VN addr as
1350 * nexthop and without Tunnel Encap attr
1352 if (encap_attr_export (&hattr
, &attr
, &nhp
, rn
))
1355 if (rfg
->routemap_export_bgp
)
1357 route_map_result_t ret
;
1358 info
.peer
= irfd
->peer
;
1360 ret
= route_map_apply (rfg
->routemap_export_bgp
,
1361 &rn
->p
, RMAP_BGP
, &info
);
1362 if (ret
== RMAP_DENYMATCH
)
1364 bgp_attr_flush (&hattr
);
1365 bgp_attr_extra_free (&hattr
);
1371 iattr
= bgp_attr_intern (&hattr
);
1372 bgp_attr_flush (&hattr
);
1373 bgp_attr_extra_free (&hattr
);
1375 bgp_update (irfd
->peer
, &rn
->p
, /* prefix */
1377 iattr
, /* bgp_update copies it */
1378 afi
, SAFI_UNICAST
, ZEBRA_ROUTE_VNC_DIRECT
, BGP_ROUTE_REDISTRIBUTE
, NULL
, /* RD not used for unicast */
1379 NULL
, /* tag not used for unicast */
1380 0, NULL
); /* EVPN not used */
1382 bgp_attr_unintern (&iattr
);
1387 aspath_unintern (&attr
.aspath
);
1388 bgp_attr_extra_free (&attr
);
1393 * Caller is responsible for ensuring that the specified nve-group
1394 * is actually part of the list of exported nve groups.
1397 vnc_direct_bgp_add_group (struct bgp
*bgp
, struct rfapi_nve_group_cfg
*rfg
)
1399 vnc_direct_bgp_add_group_afi (bgp
, rfg
, AFI_IP
);
1400 vnc_direct_bgp_add_group_afi (bgp
, rfg
, AFI_IP6
);
1406 * Caller is responsible for ensuring that the specified nve-group
1407 * was actually part of the list of exported nve groups.
1410 vnc_direct_bgp_del_group_afi (
1412 struct rfapi_nve_group_cfg
*rfg
,
1415 struct route_table
*rt
= NULL
;
1416 struct route_node
*rn
;
1417 struct rfapi_import_table
*import_table
;
1419 vnc_zlog_debug_verbose ("%s: entry", __func__
);
1421 import_table
= rfg
->rfapi_import_table
;
1424 vnc_zlog_debug_verbose ("%s: import table not defined, returning", __func__
);
1428 assert (afi
== AFI_IP
1430 rt
= import_table
->imported_vpn
[afi
];
1434 /* avoid segfault below if list does not exist */
1435 vnc_zlog_debug_verbose ("%s: no NVEs in this group", __func__
);
1440 * Walk the NVE-Group's VNC Import table
1442 for (rn
= route_top (rt
); rn
; rn
= route_next (rn
))
1448 struct listnode
*ln
;
1451 * For each NVE that is assigned to the export nve group, generate
1452 * a route with that NVE as its next hop
1454 for (ln
= listhead (rfg
->nves
); ln
; ln
= listnextnode (ln
))
1457 struct rfapi_descriptor
*irfd
;
1459 irfd
= listgetdata (ln
);
1461 bgp_withdraw (irfd
->peer
, &rn
->p
, /* prefix */
1463 NULL
, /* attr, ignored */
1464 afi
, SAFI_UNICAST
, ZEBRA_ROUTE_VNC_DIRECT
, BGP_ROUTE_REDISTRIBUTE
, NULL
, /* RD not used for unicast */
1465 NULL
, NULL
); /* tag not used for unicast */
1474 * Caller is responsible for ensuring that the specified nve-group
1475 * was actually part of the list of exported nve groups.
1478 vnc_direct_bgp_del_group (struct bgp
*bgp
, struct rfapi_nve_group_cfg
*rfg
)
1480 vnc_direct_bgp_del_group_afi (bgp
, rfg
, AFI_IP
);
1481 vnc_direct_bgp_del_group_afi (bgp
, rfg
, AFI_IP6
);
1485 vnc_direct_bgp_reexport_group_afi (
1487 struct rfapi_nve_group_cfg
*rfg
,
1490 struct listnode
*node
;
1491 struct rfapi_rfg_name
*rfgn
;
1493 if (VNC_EXPORT_BGP_GRP_ENABLED (bgp
->rfapi_cfg
))
1496 * look in the list of currently-exported groups
1498 for (ALL_LIST_ELEMENTS_RO (bgp
->rfapi_cfg
->rfg_export_direct_bgp_l
,
1502 if (rfgn
->rfg
== rfg
)
1505 * If it matches, reexport it
1507 vnc_direct_bgp_del_group_afi (bgp
, rfg
, afi
);
1508 vnc_direct_bgp_add_group_afi (bgp
, rfg
, afi
);
1517 vnc_direct_bgp_unexport_table (
1519 struct route_table
*rt
,
1520 struct list
*nve_list
)
1525 struct route_node
*rn
;
1527 for (rn
= route_top (rt
); rn
; rn
= route_next (rn
))
1533 struct listnode
*hln
;
1534 struct rfapi_descriptor
*irfd
;
1536 for (ALL_LIST_ELEMENTS_RO (nve_list
, hln
, irfd
))
1539 bgp_withdraw (irfd
->peer
, &rn
->p
, /* prefix */
1541 NULL
, /* attr, ignored */
1542 afi
, SAFI_UNICAST
, ZEBRA_ROUTE_VNC_DIRECT
, BGP_ROUTE_REDISTRIBUTE
, NULL
, /* RD not used for unicast */
1543 NULL
, NULL
); /* tag not used for unicast, EVPN neither */
1552 import_table_to_nve_list_direct_bgp (
1554 struct rfapi_import_table
*it
,
1558 struct listnode
*node
;
1559 struct rfapi_rfg_name
*rfgn
;
1562 * Loop over the list of NVE-Groups configured for
1563 * exporting to direct-bgp.
1565 * Build a list of NVEs that use this import table
1568 for (ALL_LIST_ELEMENTS_RO (bgp
->rfapi_cfg
->rfg_export_direct_bgp_l
,
1573 * If this NVE-Group's import table matches the current one
1575 if (rfgn
->rfg
&& rfgn
->rfg
->nves
&& rfgn
->rfg
->rfapi_import_table
== it
)
1578 nve_group_to_nve_list (rfgn
->rfg
, nves
, family
);
1584 vnc_direct_bgp_vpn_enable (struct bgp
*bgp
, afi_t afi
)
1586 struct listnode
*rfgn
;
1587 struct rfapi_nve_group_cfg
*rfg
;
1592 if (!VNC_EXPORT_BGP_GRP_ENABLED (bgp
->rfapi_cfg
))
1594 vnc_zlog_debug_verbose ("%s: export-to-bgp group mode not enabled, skipping",
1602 vnc_zlog_debug_verbose ("%s: bad afi: %d", __func__
, afi
);
1607 * Policy is applied per-nve-group, so we need to iterate
1608 * over the groups to add everything.
1610 for (ALL_LIST_ELEMENTS_RO (bgp
->rfapi_cfg
->nve_groups_sequential
,
1615 * contains policy management
1617 vnc_direct_bgp_add_group_afi (bgp
, rfg
, afi
);
1623 vnc_direct_bgp_vpn_disable (struct bgp
*bgp
, afi_t afi
)
1625 struct rfapi_import_table
*it
;
1626 uint8_t family
= afi2family (afi
);
1628 vnc_zlog_debug_verbose ("%s: entry, afi=%d", __func__
, afi
);
1635 vnc_zlog_debug_verbose ("%s: rfapi not initialized", __func__
);
1639 if (!family
|| (afi
!= AFI_IP
1642 vnc_zlog_debug_verbose ("%s: bad afi: %d", __func__
, afi
);
1646 for (it
= bgp
->rfapi
->imports
; it
; it
= it
->next
)
1649 struct list
*nve_list
= NULL
;
1651 import_table_to_nve_list_direct_bgp (bgp
, it
, &nve_list
, family
);
1655 vnc_direct_bgp_unexport_table (afi
, it
->imported_vpn
[afi
],
1657 list_free (nve_list
);
1663 /***********************************************************************
1664 * Export methods that proxy nexthop END
1665 ***********************************************************************/
1668 /***********************************************************************
1669 * Export methods that preserve original nexthop BEGIN
1670 * rh = "registering nve"
1671 ***********************************************************************/
1675 * "Adding a Route" export process
1676 * TBD do we need to check bi->type and bi->sub_type here, or does
1680 vnc_direct_bgp_rh_add_route (
1683 struct prefix
*prefix
,
1687 struct vnc_export_info
*eti
;
1689 struct rfapi_cfg
*hc
;
1694 zlog_err ("%s: can't get afi of route node", __func__
);
1698 /* check bgp redist flag for vnc direct ("vpn") routes */
1699 if (!bgp
->redist
[afi
][ZEBRA_ROUTE_VNC_DIRECT
])
1701 vnc_zlog_debug_verbose ("%s: bgp redistribution of VNC direct routes is off",
1706 if (!(hc
= bgp
->rfapi_cfg
))
1708 vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__
);
1712 if (!VNC_EXPORT_BGP_RH_ENABLED (bgp
->rfapi_cfg
))
1714 vnc_zlog_debug_verbose ("%s: export-to-bgp RH mode not enabled, skipping",
1722 if (hc
->plist_export_bgp
[afi
])
1724 if (prefix_list_apply (hc
->plist_export_bgp
[afi
], prefix
) ==
1730 * Construct new attribute set with NVE's VN addr as
1731 * nexthop and without Tunnel Encap attr
1733 if (encap_attr_export (&hattr
, attr
, NULL
, NULL
))
1735 if (hc
->routemap_export_bgp
)
1737 struct bgp_info info
;
1738 route_map_result_t ret
;
1740 memset (&info
, 0, sizeof (info
));
1744 route_map_apply (hc
->routemap_export_bgp
, prefix
, RMAP_BGP
, &info
);
1745 if (ret
== RMAP_DENYMATCH
)
1747 bgp_attr_flush (&hattr
);
1748 bgp_attr_extra_free (&hattr
);
1753 iattr
= bgp_attr_intern (&hattr
);
1754 bgp_attr_flush (&hattr
);
1755 bgp_attr_extra_free (&hattr
);
1758 * record route information that we will need to expire
1761 eti
= vnc_eti_get (bgp
, EXPORT_TYPE_BGP
, prefix
, peer
,
1762 ZEBRA_ROUTE_VNC_DIRECT_RH
, BGP_ROUTE_REDISTRIBUTE
);
1763 rfapiGetVncLifetime (attr
, &eti
->lifetime
);
1764 eti
->lifetime
= rfapiGetHolddownFromLifetime (eti
->lifetime
);
1769 * export expiration timer is already running on
1770 * this route: cancel it
1772 thread_cancel (eti
->timer
);
1776 bgp_update (peer
, prefix
, /* prefix */
1778 iattr
, /* bgp_update copies this attr */
1779 afi
, SAFI_UNICAST
, ZEBRA_ROUTE_VNC_DIRECT_RH
, BGP_ROUTE_REDISTRIBUTE
, NULL
, /* RD not used for unicast */
1780 NULL
, /* tag not used for unicast, EVPN neither */
1781 0, NULL
); /* EVPN not used */
1782 bgp_attr_unintern (&iattr
);
1787 vncExportWithdrawTimer (struct thread
*t
)
1789 struct vnc_export_info
*eti
= t
->arg
;
1792 * withdraw the route
1798 NULL
, /* attr, ignored */
1799 family2afi (eti
->node
->p
.family
),
1803 NULL
, /* RD not used for unicast */
1804 NULL
, NULL
); /* tag not used for unicast, EVPN neither */
1809 vnc_eti_delete (eti
);
1815 * "Withdrawing a Route" export process
1816 * TBD do we need to check bi->type and bi->sub_type here, or does
1820 vnc_direct_bgp_rh_del_route (
1823 struct prefix
*prefix
,
1826 struct vnc_export_info
*eti
;
1830 zlog_err ("%s: can't get afi route node", __func__
);
1834 /* check bgp redist flag for vnc direct ("vpn") routes */
1835 if (!bgp
->redist
[afi
][ZEBRA_ROUTE_VNC_DIRECT
])
1837 vnc_zlog_debug_verbose ("%s: bgp redistribution of VNC direct routes is off",
1842 if (!bgp
->rfapi_cfg
)
1844 vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__
);
1847 if (!VNC_EXPORT_BGP_RH_ENABLED (bgp
->rfapi_cfg
))
1849 vnc_zlog_debug_verbose ("%s: export-to-bgp group mode not enabled, skipping",
1854 eti
= vnc_eti_get (bgp
, EXPORT_TYPE_BGP
, prefix
, peer
,
1855 ZEBRA_ROUTE_VNC_DIRECT_RH
, BGP_ROUTE_REDISTRIBUTE
);
1857 if (!eti
->timer
&& eti
->lifetime
<= INT32_MAX
)
1860 thread_add_timer(bm
->master
, vncExportWithdrawTimer
, eti
, eti
->lifetime
,
1862 vnc_zlog_debug_verbose ("%s: set expiration timer for %u seconds",
1863 __func__
, eti
->lifetime
);
1869 vnc_direct_bgp_rh_vpn_enable (struct bgp
*bgp
, afi_t afi
)
1871 struct prefix_rd prd
;
1872 struct bgp_node
*prn
;
1873 struct rfapi_cfg
*hc
;
1875 vnc_zlog_debug_verbose ("%s: entry, afi=%d", __func__
, afi
);
1880 if (!(hc
= bgp
->rfapi_cfg
))
1883 if (!VNC_EXPORT_BGP_RH_ENABLED (bgp
->rfapi_cfg
))
1885 vnc_zlog_debug_verbose ("%s: export of RH routes not enabled, skipping", __func__
);
1892 vnc_zlog_debug_verbose ("%s: bad afi: %d", __func__
, afi
);
1897 * Go through the entire BGP VPN table and export to BGP unicast.
1900 vnc_zlog_debug_verbose ("%s: starting RD loop", __func__
);
1902 /* Loop over all the RDs */
1903 for (prn
= bgp_table_top (bgp
->rib
[afi
][SAFI_MPLS_VPN
]); prn
;
1904 prn
= bgp_route_next (prn
))
1907 struct bgp_table
*table
;
1908 struct bgp_node
*rn
;
1909 struct bgp_info
*ri
;
1911 memset (&prd
, 0, sizeof (prd
));
1912 prd
.family
= AF_UNSPEC
;
1914 memcpy (prd
.val
, prn
->p
.u
.val
, 8);
1916 /* This is the per-RD table of prefixes */
1919 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
1923 * skip prefix list check if no routes here
1929 char prefixstr
[BUFSIZ
];
1932 inet_ntop (rn
->p
.family
, &rn
->p
.u
.prefix
, prefixstr
, BUFSIZ
);
1933 vnc_zlog_debug_verbose ("%s: checking prefix %s/%d", __func__
, prefixstr
,
1940 if (hc
->plist_export_bgp
[afi
])
1942 if (prefix_list_apply (hc
->plist_export_bgp
[afi
], &rn
->p
) ==
1946 vnc_zlog_debug_verbose ("%s: prefix list says DENY", __func__
);
1951 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
1954 vnc_zlog_debug_verbose ("%s: ri->sub_type: %d", __func__
, ri
->sub_type
);
1956 if (ri
->sub_type
== BGP_ROUTE_NORMAL
||
1957 ri
->sub_type
== BGP_ROUTE_RFP
)
1960 struct vnc_export_info
*eti
;
1965 * Construct new attribute set with NVE's VN addr as
1966 * nexthop and without Tunnel Encap attr
1968 if (encap_attr_export (&hattr
, ri
->attr
, NULL
, NULL
))
1970 vnc_zlog_debug_verbose ("%s: encap_attr_export failed", __func__
);
1974 if (hc
->routemap_export_bgp
)
1976 struct bgp_info info
;
1977 route_map_result_t ret
;
1979 memset (&info
, 0, sizeof (info
));
1980 info
.peer
= ri
->peer
;
1982 ret
= route_map_apply (hc
->routemap_export_bgp
,
1983 &rn
->p
, RMAP_BGP
, &info
);
1984 if (ret
== RMAP_DENYMATCH
)
1986 bgp_attr_flush (&hattr
);
1987 bgp_attr_extra_free (&hattr
);
1988 vnc_zlog_debug_verbose ("%s: route map says DENY", __func__
);
1993 iattr
= bgp_attr_intern (&hattr
);
1994 bgp_attr_flush (&hattr
);
1995 bgp_attr_extra_free (&hattr
);
1998 * record route information that we will need to expire
2001 eti
= vnc_eti_get (bgp
, EXPORT_TYPE_BGP
, &rn
->p
, ri
->peer
,
2002 ZEBRA_ROUTE_VNC_DIRECT_RH
,
2003 BGP_ROUTE_REDISTRIBUTE
);
2004 rfapiGetVncLifetime (ri
->attr
, &eti
->lifetime
);
2009 * export expiration timer is already running on
2010 * this route: cancel it
2012 thread_cancel (eti
->timer
);
2016 vnc_zlog_debug_verbose ("%s: calling bgp_update", __func__
);
2018 bgp_update (ri
->peer
, &rn
->p
, /* prefix */
2020 iattr
, /* bgp_update copies it */
2021 AFI_IP
, SAFI_UNICAST
, ZEBRA_ROUTE_VNC_DIRECT_RH
, BGP_ROUTE_REDISTRIBUTE
, NULL
, /* RD not used for unicast */
2022 NULL
, /* tag not used for unicast, EVPN neither */
2023 0, NULL
); /* EVPN not used */
2024 bgp_attr_unintern (&iattr
);
2032 vnc_direct_bgp_rh_vpn_disable (struct bgp
*bgp
, afi_t afi
)
2034 struct bgp_node
*rn
;
2036 vnc_zlog_debug_verbose ("%s: entry, afi=%d", __func__
, afi
);
2044 vnc_zlog_debug_verbose ("%s: bad afi: %d", __func__
, afi
);
2049 * Go through the entire BGP unicast table and remove routes that
2050 * originated from us
2052 for (rn
= bgp_table_top (bgp
->rib
[afi
][SAFI_UNICAST
]); rn
;
2053 rn
= bgp_route_next (rn
))
2056 struct bgp_info
*ri
;
2057 struct bgp_info
*next
;
2059 for (ri
= rn
->info
, next
= NULL
; ri
; ri
= next
)
2064 if (ri
->type
== ZEBRA_ROUTE_VNC_DIRECT_RH
&&
2065 ri
->sub_type
== BGP_ROUTE_REDISTRIBUTE
)
2068 struct vnc_export_info
*eti
;
2071 * Delete routes immediately (no timer)
2074 vnc_eti_checktimer (bgp
, EXPORT_TYPE_BGP
, &rn
->p
, ri
->peer
,
2075 ZEBRA_ROUTE_VNC_DIRECT_RH
,
2076 BGP_ROUTE_REDISTRIBUTE
);
2080 thread_cancel (eti
->timer
);
2081 vnc_eti_delete (eti
);
2084 bgp_withdraw (ri
->peer
, &rn
->p
, /* prefix */
2087 AFI_IP
, SAFI_UNICAST
, ZEBRA_ROUTE_VNC_DIRECT_RH
, BGP_ROUTE_REDISTRIBUTE
, NULL
, /* RD not used for unicast */
2088 NULL
, NULL
); /* tag not used for unicast, EVPN neither */
2095 vnc_direct_bgp_rh_reexport (struct bgp
*bgp
, afi_t afi
)
2097 if (VNC_EXPORT_BGP_RH_ENABLED (bgp
->rfapi_cfg
))
2099 vnc_direct_bgp_rh_vpn_disable (bgp
, afi
);
2100 vnc_direct_bgp_rh_vpn_enable (bgp
, afi
);
2104 /***********************************************************************
2105 * Generic Export methods
2106 ***********************************************************************/
2109 * Assumes the correct mode bits are already turned on. Thus it
2110 * is OK to call this function from, e.g., bgp_redistribute_set()
2111 * without caring if export is enabled or not
2114 vnc_export_bgp_enable (struct bgp
*bgp
, afi_t afi
)
2116 switch (bgp
->rfapi_cfg
->flags
& BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS
)
2118 case BGP_VNC_CONFIG_EXPORT_BGP_MODE_NONE
:
2121 case BGP_VNC_CONFIG_EXPORT_BGP_MODE_GRP
:
2122 vnc_direct_bgp_vpn_enable (bgp
, afi
);
2125 case BGP_VNC_CONFIG_EXPORT_BGP_MODE_RH
:
2126 vnc_direct_bgp_rh_vpn_enable (bgp
, afi
);
2129 case BGP_VNC_CONFIG_EXPORT_BGP_MODE_CE
:
2130 vnc_direct_bgp_vpn_enable_ce (bgp
, afi
);
2136 vnc_export_bgp_disable (struct bgp
*bgp
, afi_t afi
)
2138 switch (bgp
->rfapi_cfg
->flags
& BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS
)
2140 case BGP_VNC_CONFIG_EXPORT_BGP_MODE_NONE
:
2143 case BGP_VNC_CONFIG_EXPORT_BGP_MODE_GRP
:
2144 vnc_direct_bgp_vpn_disable (bgp
, afi
);
2147 case BGP_VNC_CONFIG_EXPORT_BGP_MODE_RH
:
2148 vnc_direct_bgp_rh_vpn_disable (bgp
, afi
);
2151 case BGP_VNC_CONFIG_EXPORT_BGP_MODE_CE
:
2152 vnc_direct_bgp_vpn_disable_ce (bgp
, afi
);
2158 vnc_export_bgp_prechange (struct bgp
*bgp
)
2160 vnc_export_bgp_disable (bgp
, AFI_IP
);
2161 vnc_export_bgp_disable (bgp
, AFI_IP6
);
2165 vnc_export_bgp_postchange (struct bgp
*bgp
)
2167 vnc_export_bgp_enable (bgp
, AFI_IP
);
2168 vnc_export_bgp_enable (bgp
, AFI_IP6
);
2172 vnc_direct_bgp_reexport (struct bgp
*bgp
, afi_t afi
)
2174 vnc_export_bgp_disable (bgp
, afi
);
2175 vnc_export_bgp_enable (bgp
, afi
);