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 along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 * Purpose: Handle exchange of routes between VNC and Zebra
26 #include "lib/zebra.h"
27 #include "lib/prefix.h"
28 #include "lib/agg_table.h"
30 #include "lib/command.h"
31 #include "lib/zclient.h"
32 #include "lib/stream.h"
33 #include "lib/ringbuf.h"
34 #include "lib/memory.h"
35 #include "lib/lib_errors.h"
37 #include "bgpd/bgpd.h"
38 #include "bgpd/bgp_ecommunity.h"
39 #include "bgpd/bgp_route.h"
40 #include "bgpd/bgp_debug.h"
41 #include "bgpd/bgp_advertise.h"
43 #include "bgpd/rfapi/bgp_rfapi_cfg.h"
44 #include "bgpd/rfapi/rfapi.h"
45 #include "bgpd/rfapi/rfapi_import.h"
46 #include "bgpd/rfapi/rfapi_private.h"
47 #include "bgpd/rfapi/vnc_zebra.h"
48 #include "bgpd/rfapi/rfapi_vty.h"
49 #include "bgpd/rfapi/rfapi_backend.h"
50 #include "bgpd/rfapi/vnc_debug.h"
52 static struct rfapi_descriptor vncHD1VR
; /* Single-VR export dummy nve descr */
53 static struct zclient
*zclient_vnc
= NULL
;
55 /***********************************************************************
56 * REDISTRIBUTE: Zebra sends updates/withdraws to BGPD
57 ***********************************************************************/
60 * Routes coming from zebra get added to VNC here
62 static void vnc_redistribute_add(struct prefix
*p
, uint32_t metric
,
65 struct bgp
*bgp
= bgp_get_default();
67 struct rfapi_ip_addr vnaddr
;
70 rfp_cost_to_localpref(metric
> 255 ? 255 : metric
);
75 if (!bgp
->rfapi_cfg
) {
76 vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping",
81 afi
= family2afi(p
->family
);
83 vnc_zlog_debug_verbose("%s: unknown prefix address family %d",
88 if (!bgp
->rfapi_cfg
->redist
[afi
][type
]) {
89 vnc_zlog_debug_verbose(
90 "%s: bgp->rfapi_cfg->redist[afi=%d][type=%d] is 0, skipping",
94 if (!bgp
->rfapi_cfg
->rfg_redist
) {
95 vnc_zlog_debug_verbose("%s: no redist nve group, skipping",
101 * Assume nve group's configured VN address prefix is a host
102 * route which also happens to give the NVE VN address to use
103 * for redistributing into VNC.
105 vnaddr
.addr_family
= bgp
->rfapi_cfg
->rfg_redist
->vn_prefix
.family
;
106 switch (bgp
->rfapi_cfg
->rfg_redist
->vn_prefix
.family
) {
108 if (bgp
->rfapi_cfg
->rfg_redist
->vn_prefix
.prefixlen
!= 32) {
109 vnc_zlog_debug_verbose(
110 "%s: redist nve group VN prefix len (%d) != 32, skipping",
112 bgp
->rfapi_cfg
->rfg_redist
->vn_prefix
117 bgp
->rfapi_cfg
->rfg_redist
->vn_prefix
.u
.prefix4
;
120 if (bgp
->rfapi_cfg
->rfg_redist
->vn_prefix
.prefixlen
!= 128) {
121 vnc_zlog_debug_verbose(
122 "%s: redist nve group VN prefix len (%d) != 128, skipping",
124 bgp
->rfapi_cfg
->rfg_redist
->vn_prefix
129 bgp
->rfapi_cfg
->rfg_redist
->vn_prefix
.u
.prefix6
;
132 vnc_zlog_debug_verbose(
133 "%s: no redist nve group VN host prefix configured, skipping",
139 * Assume nve group's configured UN address prefix is a host
140 * route which also happens to give the NVE UN address to use
141 * for redistributing into VNC.
145 * Set UN address in dummy nve descriptor so add_vnc_route
146 * can use it in VNC tunnel SubTLV
149 struct rfapi_ip_prefix pfx_un
;
151 rfapiQprefix2Rprefix(&bgp
->rfapi_cfg
->rfg_redist
->un_prefix
,
154 switch (pfx_un
.prefix
.addr_family
) {
156 if (pfx_un
.length
!= 32) {
157 vnc_zlog_debug_verbose(
158 "%s: redist nve group UN prefix len (%d) != 32, skipping",
159 __func__
, pfx_un
.length
);
164 if (pfx_un
.length
!= 128) {
165 vnc_zlog_debug_verbose(
166 "%s: redist nve group UN prefix len (%d) != 128, skipping",
167 __func__
, pfx_un
.length
);
172 vnc_zlog_debug_verbose(
173 "%s: no redist nve group UN host prefix configured, skipping",
178 vncHD1VR
.un_addr
= pfx_un
.prefix
;
180 if (!vncHD1VR
.peer
) {
182 * Same setup as in rfapi_open()
184 vncHD1VR
.peer
= peer_new(bgp
);
185 vncHD1VR
.peer
->status
=
186 Established
; /* keep bgp core happy */
187 bgp_sync_delete(vncHD1VR
.peer
); /* don't need these */
190 * since this peer is not on the I/O thread, this lock
191 * is not strictly necessary, but serves as a reminder
192 * to those who may meddle...
194 frr_with_mutex(&vncHD1VR
.peer
->io_mtx
) {
195 // we don't need any I/O related facilities
196 if (vncHD1VR
.peer
->ibuf
)
197 stream_fifo_free(vncHD1VR
.peer
->ibuf
);
198 if (vncHD1VR
.peer
->obuf
)
199 stream_fifo_free(vncHD1VR
.peer
->obuf
);
201 if (vncHD1VR
.peer
->ibuf_work
)
202 ringbuf_del(vncHD1VR
.peer
->ibuf_work
);
203 if (vncHD1VR
.peer
->obuf_work
)
204 stream_free(vncHD1VR
.peer
->obuf_work
);
206 vncHD1VR
.peer
->ibuf
= NULL
;
207 vncHD1VR
.peer
->obuf
= NULL
;
208 vncHD1VR
.peer
->obuf_work
= NULL
;
209 vncHD1VR
.peer
->ibuf_work
= NULL
;
212 /* base code assumes have valid host pointer */
213 vncHD1VR
.peer
->host
=
214 XSTRDUP(MTYPE_BGP_PEER_HOST
, ".zebra.");
216 /* Mark peer as belonging to HD */
217 SET_FLAG(vncHD1VR
.peer
->flags
, PEER_FLAG_IS_RFAPI_HD
);
221 memset(&prd
, 0, sizeof(prd
));
222 prd
= bgp
->rfapi_cfg
->rfg_redist
->rd
;
223 prd
.family
= AF_UNSPEC
;
226 add_vnc_route(&vncHD1VR
, /* cookie + UN addr */
227 bgp
, SAFI_MPLS_VPN
, p
, &prd
, &vnaddr
, &local_pref
,
228 &(bgp
->rfapi_cfg
->redist_lifetime
),
229 NULL
, /* RFP options */
230 NULL
, /* struct rfapi_un_option */
231 NULL
, /* struct rfapi_vn_option */
232 bgp
->rfapi_cfg
->rfg_redist
->rt_export_list
, NULL
,
233 NULL
, /* label: default */
234 type
, BGP_ROUTE_REDISTRIBUTE
, 0); /* flags */
238 * Route deletions from zebra propagate to VNC here
240 static void vnc_redistribute_delete(struct prefix
*p
, uint8_t type
)
242 struct bgp
*bgp
= bgp_get_default();
243 struct prefix_rd prd
;
249 if (!bgp
->rfapi_cfg
) {
250 vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping",
254 afi
= family2afi(p
->family
);
256 vnc_zlog_debug_verbose("%s: unknown prefix address family %d",
257 __func__
, p
->family
);
260 if (!bgp
->rfapi_cfg
->redist
[afi
][type
]) {
261 vnc_zlog_debug_verbose(
262 "%s: bgp->rfapi_cfg->redist[afi=%d][type=%d] is 0, skipping",
263 __func__
, afi
, type
);
266 if (!bgp
->rfapi_cfg
->rfg_redist
) {
267 vnc_zlog_debug_verbose("%s: no redist nve group, skipping",
272 memset(&prd
, 0, sizeof(prd
));
273 prd
= bgp
->rfapi_cfg
->rfg_redist
->rd
;
274 prd
.family
= AF_UNSPEC
;
277 del_vnc_route(&vncHD1VR
, /* use dummy ptr as cookie */
278 vncHD1VR
.peer
, bgp
, SAFI_MPLS_VPN
, p
, &prd
, type
,
279 BGP_ROUTE_REDISTRIBUTE
, NULL
, 0);
283 * Flush all redistributed routes of type <type>
285 static void vnc_redistribute_withdraw(struct bgp
*bgp
, afi_t afi
, uint8_t type
)
287 struct prefix_rd prd
;
288 struct bgp_table
*table
;
289 struct bgp_node
*prn
;
292 vnc_zlog_debug_verbose("%s: entry", __func__
);
296 if (!bgp
->rfapi_cfg
) {
297 vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping",
303 * Loop over all the RDs
305 for (prn
= bgp_table_top(bgp
->rib
[afi
][SAFI_MPLS_VPN
]); prn
;
306 prn
= bgp_route_next(prn
)) {
307 const struct prefix
*prn_p
= bgp_node_get_prefix(prn
);
309 memset(&prd
, 0, sizeof(prd
));
310 prd
.family
= AF_UNSPEC
;
312 memcpy(prd
.val
, prn_p
->u
.val
, 8);
314 /* This is the per-RD table of prefixes */
315 table
= bgp_node_get_bgp_table_info(prn
);
319 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
321 struct bgp_path_info
*ri
;
323 for (ri
= bgp_node_get_bgp_path_info(rn
); ri
;
326 == type
) { /* has matching redist type */
332 &vncHD1VR
, /* use dummy ptr as cookie */
333 vncHD1VR
.peer
, bgp
, SAFI_MPLS_VPN
,
334 bgp_node_get_prefix(rn
), &prd
, type
,
335 BGP_ROUTE_REDISTRIBUTE
, NULL
, 0);
339 vnc_zlog_debug_verbose("%s: return", __func__
);
343 * Zebra route add and delete treatment.
347 static int vnc_zebra_read_route(ZAPI_CALLBACK_ARGS
)
349 struct zapi_route api
;
352 if (zapi_route_decode(zclient
->ibuf
, &api
) < 0)
355 /* we completely ignore srcdest routes for now. */
356 if (CHECK_FLAG(api
.message
, ZAPI_MESSAGE_SRCPFX
))
359 add
= (cmd
== ZEBRA_REDISTRIBUTE_ROUTE_ADD
);
361 vnc_redistribute_add(&api
.prefix
, api
.metric
, api
.type
);
363 vnc_redistribute_delete(&api
.prefix
, api
.type
);
365 if (BGP_DEBUG(zebra
, ZEBRA
)) {
366 char buf
[PREFIX_STRLEN
];
368 prefix2str(&api
.prefix
, buf
, sizeof(buf
));
369 vnc_zlog_debug_verbose(
370 "%s: Zebra rcvd: route delete %s %s metric %u",
371 __func__
, zebra_route_string(api
.type
), buf
,
378 /***********************************************************************
379 * vnc_bgp_zebra_*: VNC sends updates/withdraws to Zebra
380 ***********************************************************************/
383 * low-level message builder
385 static void vnc_zebra_route_msg(const struct prefix
*p
, unsigned int nhp_count
,
386 void *nhp_ary
, int add
) /* 1 = add, 0 = del */
388 struct zapi_route api
;
389 struct zapi_nexthop
*api_nh
;
391 struct in_addr
**nhp_ary4
= nhp_ary
;
392 struct in6_addr
**nhp_ary6
= nhp_ary
;
395 vnc_zlog_debug_verbose("%s: empty nexthop list, skipping",
400 memset(&api
, 0, sizeof(api
));
401 api
.vrf_id
= VRF_DEFAULT
;
402 api
.type
= ZEBRA_ROUTE_VNC
;
403 api
.safi
= SAFI_UNICAST
;
407 SET_FLAG(api
.message
, ZAPI_MESSAGE_NEXTHOP
);
408 api
.nexthop_num
= MIN(nhp_count
, multipath_num
);
409 for (i
= 0; i
< api
.nexthop_num
; i
++) {
411 api_nh
= &api
.nexthops
[i
];
412 api_nh
->vrf_id
= VRF_DEFAULT
;
415 memcpy(&api_nh
->gate
.ipv4
, nhp_ary4
[i
],
416 sizeof(api_nh
->gate
.ipv4
));
417 api_nh
->type
= NEXTHOP_TYPE_IPV4
;
420 memcpy(&api_nh
->gate
.ipv6
, nhp_ary6
[i
],
421 sizeof(api_nh
->gate
.ipv6
));
422 api_nh
->type
= NEXTHOP_TYPE_IPV6
;
427 if (BGP_DEBUG(zebra
, ZEBRA
)) {
428 char buf
[PREFIX_STRLEN
];
430 prefix2str(&api
.prefix
, buf
, sizeof(buf
));
431 vnc_zlog_debug_verbose(
432 "%s: Zebra send: route %s %s, nhp_count=%d", __func__
,
433 (add
? "add" : "del"), buf
, nhp_count
);
436 zclient_route_send((add
? ZEBRA_ROUTE_ADD
: ZEBRA_ROUTE_DELETE
),
442 nve_list_to_nh_array(uint8_t family
, struct list
*nve_list
,
443 unsigned int *nh_count_ret
,
444 void **nh_ary_ret
, /* returned address array */
445 void **nhp_ary_ret
) /* returned pointer array */
447 int nve_count
= listcount(nve_list
);
454 vnc_zlog_debug_verbose("%s: empty nve_list, skipping",
459 if (family
== AF_INET
) {
465 * Array of nexthop addresses
468 XCALLOC(MTYPE_TMP
, nve_count
* sizeof(struct in_addr
));
471 * Array of pointers to nexthop addresses
473 *nhp_ary_ret
= XCALLOC(MTYPE_TMP
,
474 nve_count
* sizeof(struct in_addr
*));
478 for (ln
= listhead(nve_list
); ln
; ln
= listnextnode(ln
)) {
480 struct rfapi_descriptor
*irfd
;
483 irfd
= listgetdata(ln
);
485 if (rfapiRaddr2Qprefix(&irfd
->vn_addr
, &nhp
))
488 *iap
= nhp
.u
.prefix4
;
490 vnc_zlog_debug_verbose(
491 "%s: ipadr: (%p)<-0x%x, ptr: (%p)<-%p",
492 __func__
, iap
, nhp
.u
.prefix4
.s_addr
, v
, iap
);
499 } else if (family
== AF_INET6
) {
504 XCALLOC(MTYPE_TMP
, nve_count
* sizeof(struct in6_addr
));
506 *nhp_ary_ret
= XCALLOC(MTYPE_TMP
,
507 nve_count
* sizeof(struct in6_addr
*));
509 for (ln
= listhead(nve_list
); ln
; ln
= listnextnode(ln
)) {
511 struct rfapi_descriptor
*irfd
;
512 struct in6_addr
*iap
= *nh_ary_ret
;
513 struct in6_addr
**v
= *nhp_ary_ret
;
516 irfd
= listgetdata(ln
);
518 if (rfapiRaddr2Qprefix(&irfd
->vn_addr
, &nhp
))
521 *iap
= nhp
.u
.prefix6
;
531 static void import_table_to_nve_list_zebra(struct bgp
*bgp
,
532 struct rfapi_import_table
*it
,
533 struct list
**nves
, uint8_t family
)
535 struct listnode
*node
;
536 struct rfapi_rfg_name
*rfgn
;
539 * Loop over the list of NVE-Groups configured for
540 * exporting to direct-bgp.
542 * Build a list of NVEs that use this import table
545 for (ALL_LIST_ELEMENTS_RO(bgp
->rfapi_cfg
->rfg_export_zebra_l
, node
,
549 * If this NVE-Group's import table matches the current one
551 if (rfgn
->rfg
&& rfgn
->rfg
->nves
552 && rfgn
->rfg
->rfapi_import_table
== it
) {
554 nve_group_to_nve_list(rfgn
->rfg
, nves
, family
);
559 static void vnc_zebra_add_del_prefix(struct bgp
*bgp
,
560 struct rfapi_import_table
*import_table
,
562 int add
) /* !0 = add, 0 = del */
565 const struct prefix
*p
= agg_node_get_prefix(rn
);
566 unsigned int nexthop_count
= 0;
568 void *nhp_ary
= NULL
;
570 vnc_zlog_debug_verbose("%s: entry, add=%d", __func__
, add
);
572 if (zclient_vnc
->sock
< 0)
575 if (p
->family
!= AF_INET
&& p
->family
!= AF_INET6
) {
576 flog_err(EC_LIB_DEVELOPMENT
,
577 "%s: invalid route node addr family", __func__
);
581 if (!vrf_bitmap_check(
582 zclient_vnc
->redist
[family2afi(p
->family
)][ZEBRA_ROUTE_VNC
],
586 if (!bgp
->rfapi_cfg
) {
587 vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping",
591 if (!listcount(bgp
->rfapi_cfg
->rfg_export_zebra_l
)) {
592 vnc_zlog_debug_verbose(
593 "%s: no zebra export nve group, skipping", __func__
);
597 import_table_to_nve_list_zebra(bgp
, import_table
, &nves
, p
->family
);
600 nve_list_to_nh_array(p
->family
, nves
, &nexthop_count
, &nh_ary
,
606 vnc_zebra_route_msg(p
, nexthop_count
, nhp_ary
, add
);
609 XFREE(MTYPE_TMP
, nhp_ary
);
610 XFREE(MTYPE_TMP
, nh_ary
);
613 void vnc_zebra_add_prefix(struct bgp
*bgp
,
614 struct rfapi_import_table
*import_table
,
617 vnc_zebra_add_del_prefix(bgp
, import_table
, rn
, 1);
620 void vnc_zebra_del_prefix(struct bgp
*bgp
,
621 struct rfapi_import_table
*import_table
,
624 vnc_zebra_add_del_prefix(bgp
, import_table
, rn
, 0);
628 static void vnc_zebra_add_del_nve(struct bgp
*bgp
, struct rfapi_descriptor
*rfd
,
629 int add
) /* 0 = del, !0 = add */
631 struct listnode
*node
;
632 struct rfapi_rfg_name
*rfgn
;
633 struct rfapi_nve_group_cfg
*rfg
= rfd
->rfg
;
634 afi_t afi
= family2afi(rfd
->vn_addr
.addr_family
);
636 // struct prefix *nhpp;
639 vnc_zlog_debug_verbose("%s: entry, add=%d", __func__
, add
);
641 if (zclient_vnc
->sock
< 0)
644 if (!vrf_bitmap_check(zclient_vnc
->redist
[afi
][ZEBRA_ROUTE_VNC
],
648 if (afi
!= AFI_IP
&& afi
!= AFI_IP6
) {
649 flog_err(EC_LIB_DEVELOPMENT
, "%s: invalid vn addr family",
656 if (!bgp
->rfapi_cfg
) {
657 vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping",
662 if (rfapiRaddr2Qprefix(&rfd
->vn_addr
, &nhp
)) {
663 vnc_zlog_debug_verbose("%s: can't convert vn address, skipping",
668 pAddr
= &nhp
.u
.prefix4
;
671 * Loop over the list of NVE-Groups configured for
672 * exporting to zebra and see if this new NVE's
673 * group is among them.
675 for (ALL_LIST_ELEMENTS_RO(bgp
->rfapi_cfg
->rfg_export_zebra_l
, node
,
679 * Yes, this NVE's group is configured for export to zebra
681 if (rfgn
->rfg
== rfg
) {
683 struct agg_table
*rt
= NULL
;
685 struct rfapi_import_table
*import_table
;
686 import_table
= rfg
->rfapi_import_table
;
688 vnc_zlog_debug_verbose(
689 "%s: this nve's group is in zebra export list",
692 rt
= import_table
->imported_vpn
[afi
];
695 * Walk the NVE-Group's VNC Import table
697 for (rn
= agg_route_top(rt
); rn
;
698 rn
= agg_route_next(rn
)) {
702 vnc_zlog_debug_verbose("%s: sending %s",
704 (add
? "add" : "del"));
705 vnc_zebra_route_msg(agg_node_get_prefix(rn
), 1,
712 void vnc_zebra_add_nve(struct bgp
*bgp
, struct rfapi_descriptor
*rfd
)
714 vnc_zebra_add_del_nve(bgp
, rfd
, 1);
717 void vnc_zebra_del_nve(struct bgp
*bgp
, struct rfapi_descriptor
*rfd
)
719 vnc_zebra_add_del_nve(bgp
, rfd
, 0);
722 static void vnc_zebra_add_del_group_afi(struct bgp
*bgp
,
723 struct rfapi_nve_group_cfg
*rfg
,
726 struct agg_table
*rt
= NULL
;
728 struct rfapi_import_table
*import_table
;
729 uint8_t family
= afi2family(afi
);
731 struct list
*nves
= NULL
;
732 unsigned int nexthop_count
= 0;
734 void *nhp_ary
= NULL
;
736 vnc_zlog_debug_verbose("%s: entry", __func__
);
737 import_table
= rfg
->rfapi_import_table
;
739 vnc_zlog_debug_verbose(
740 "%s: import table not defined, returning", __func__
);
744 if (afi
== AFI_IP
|| afi
== AFI_IP6
) {
745 rt
= import_table
->imported_vpn
[afi
];
747 flog_err(EC_LIB_DEVELOPMENT
, "%s: bad afi %d", __func__
, afi
);
752 flog_err(EC_LIB_DEVELOPMENT
, "%s: computed bad family: %d",
758 /* avoid segfault below if list doesn't exist */
759 vnc_zlog_debug_verbose("%s: no NVEs in this group", __func__
);
763 nve_group_to_nve_list(rfg
, &nves
, family
);
765 vnc_zlog_debug_verbose("%s: have nves", __func__
);
766 nve_list_to_nh_array(family
, nves
, &nexthop_count
, &nh_ary
,
769 vnc_zlog_debug_verbose("%s: family: %d, nve count: %d",
770 __func__
, family
, nexthop_count
);
776 * Walk the NVE-Group's VNC Import table
778 for (rn
= agg_route_top(rt
); rn
;
779 rn
= agg_route_next(rn
)) {
782 agg_node_get_prefix(rn
),
783 nexthop_count
, nhp_ary
, add
);
787 XFREE(MTYPE_TMP
, nhp_ary
);
788 XFREE(MTYPE_TMP
, nh_ary
);
792 void vnc_zebra_add_group(struct bgp
*bgp
, struct rfapi_nve_group_cfg
*rfg
)
794 vnc_zebra_add_del_group_afi(bgp
, rfg
, AFI_IP
, 1);
795 vnc_zebra_add_del_group_afi(bgp
, rfg
, AFI_IP6
, 1);
798 void vnc_zebra_del_group(struct bgp
*bgp
, struct rfapi_nve_group_cfg
*rfg
)
800 vnc_zlog_debug_verbose("%s: entry", __func__
);
801 vnc_zebra_add_del_group_afi(bgp
, rfg
, AFI_IP
, 0);
802 vnc_zebra_add_del_group_afi(bgp
, rfg
, AFI_IP6
, 0);
805 void vnc_zebra_reexport_group_afi(struct bgp
*bgp
,
806 struct rfapi_nve_group_cfg
*rfg
, afi_t afi
)
808 struct listnode
*node
;
809 struct rfapi_rfg_name
*rfgn
;
811 for (ALL_LIST_ELEMENTS_RO(bgp
->rfapi_cfg
->rfg_export_zebra_l
, node
,
814 if (rfgn
->rfg
== rfg
) {
815 vnc_zebra_add_del_group_afi(bgp
, rfg
, afi
, 0);
816 vnc_zebra_add_del_group_afi(bgp
, rfg
, afi
, 1);
823 /***********************************************************************
825 ***********************************************************************/
828 /* Other routes redistribution into BGP. */
829 int vnc_redistribute_set(struct bgp
*bgp
, afi_t afi
, int type
)
831 if (!bgp
->rfapi_cfg
) {
832 return CMD_WARNING_CONFIG_FAILED
;
835 /* Set flag to BGP instance. */
836 bgp
->rfapi_cfg
->redist
[afi
][type
] = 1;
838 // bgp->redist[afi][type] = 1;
840 /* Return if already redistribute flag is set. */
841 if (vrf_bitmap_check(zclient_vnc
->redist
[afi
][type
], VRF_DEFAULT
))
842 return CMD_WARNING_CONFIG_FAILED
;
844 vrf_bitmap_set(zclient_vnc
->redist
[afi
][type
], VRF_DEFAULT
);
846 // vrf_bitmap_set(zclient_vnc->redist[afi][type], VRF_DEFAULT);
848 /* Return if zebra connection is not established. */
849 if (zclient_vnc
->sock
< 0)
850 return CMD_WARNING_CONFIG_FAILED
;
852 if (BGP_DEBUG(zebra
, ZEBRA
))
853 vnc_zlog_debug_verbose("Zebra send: redistribute add %s",
854 zebra_route_string(type
));
856 /* Send distribute add message to zebra. */
857 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD
, zclient_vnc
, afi
, type
,
863 /* Unset redistribution. */
864 int vnc_redistribute_unset(struct bgp
*bgp
, afi_t afi
, int type
)
866 vnc_zlog_debug_verbose("%s: type=%d entry", __func__
, type
);
868 if (!bgp
->rfapi_cfg
) {
869 vnc_zlog_debug_verbose("%s: return (no rfapi_cfg)", __func__
);
870 return CMD_WARNING_CONFIG_FAILED
;
873 /* Unset flag from BGP instance. */
874 bgp
->rfapi_cfg
->redist
[afi
][type
] = 0;
876 /* Return if zebra connection is disabled. */
877 if (!vrf_bitmap_check(zclient_vnc
->redist
[afi
][type
], VRF_DEFAULT
))
878 return CMD_WARNING_CONFIG_FAILED
;
879 vrf_bitmap_unset(zclient_vnc
->redist
[afi
][type
], VRF_DEFAULT
);
881 if (bgp
->rfapi_cfg
->redist
[AFI_IP
][type
] == 0
882 && bgp
->rfapi_cfg
->redist
[AFI_IP6
][type
] == 0
883 && zclient_vnc
->sock
>= 0) {
884 /* Send distribute delete message to zebra. */
885 if (BGP_DEBUG(zebra
, ZEBRA
))
886 vnc_zlog_debug_verbose(
887 "Zebra send: redistribute delete %s",
888 zebra_route_string(type
));
889 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE
, zclient_vnc
,
890 afi
, type
, 0, VRF_DEFAULT
);
893 /* Withdraw redistributed routes from current BGP's routing table. */
894 vnc_redistribute_withdraw(bgp
, afi
, type
);
896 vnc_zlog_debug_verbose("%s: return", __func__
);
901 extern struct zebra_privs_t bgpd_privs
;
904 * Modeled after bgp_zebra.c'bgp_zebra_init()
905 * Charriere asks, "Is it possible to carry two?"
907 void vnc_zebra_init(struct thread_master
*master
)
909 /* Set default values. */
910 zclient_vnc
= zclient_new(master
, &zclient_options_default
);
911 zclient_init(zclient_vnc
, ZEBRA_ROUTE_VNC
, 0, &bgpd_privs
);
913 zclient_vnc
->redistribute_route_add
= vnc_zebra_read_route
;
914 zclient_vnc
->redistribute_route_del
= vnc_zebra_read_route
;
917 void vnc_zebra_destroy(void)
919 if (zclient_vnc
== NULL
)
921 zclient_stop(zclient_vnc
);
922 zclient_free(zclient_vnc
);