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/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"
36 #include "bgpd/bgpd.h"
37 #include "bgpd/bgp_ecommunity.h"
38 #include "bgpd/bgp_route.h"
39 #include "bgpd/bgp_debug.h"
40 #include "bgpd/bgp_advertise.h"
42 #include "bgpd/rfapi/bgp_rfapi_cfg.h"
43 #include "bgpd/rfapi/rfapi.h"
44 #include "bgpd/rfapi/rfapi_import.h"
45 #include "bgpd/rfapi/rfapi_private.h"
46 #include "bgpd/rfapi/vnc_zebra.h"
47 #include "bgpd/rfapi/rfapi_vty.h"
48 #include "bgpd/rfapi/rfapi_backend.h"
49 #include "bgpd/rfapi/vnc_debug.h"
51 static struct rfapi_descriptor vncHD1VR
; /* Single-VR export dummy nve descr */
52 static struct zclient
*zclient_vnc
= NULL
;
54 /***********************************************************************
55 * REDISTRIBUTE: Zebra sends updates/withdraws to BGPD
56 ***********************************************************************/
59 * Routes coming from zebra get added to VNC here
61 static void vnc_redistribute_add(struct prefix
*p
, uint32_t metric
,
64 struct bgp
*bgp
= bgp_get_default();
66 struct rfapi_ip_addr vnaddr
;
69 rfp_cost_to_localpref(metric
> 255 ? 255 : metric
);
74 if (!bgp
->rfapi_cfg
) {
75 vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping",
80 afi
= family2afi(p
->family
);
82 vnc_zlog_debug_verbose("%s: unknown prefix address family %d",
87 if (!bgp
->rfapi_cfg
->redist
[afi
][type
]) {
88 vnc_zlog_debug_verbose(
89 "%s: bgp->rfapi_cfg->redist[afi=%d][type=%d] is 0, skipping",
93 if (!bgp
->rfapi_cfg
->rfg_redist
) {
94 vnc_zlog_debug_verbose("%s: no redist nve group, skipping",
100 * Assume nve group's configured VN address prefix is a host
101 * route which also happens to give the NVE VN address to use
102 * for redistributing into VNC.
104 vnaddr
.addr_family
= bgp
->rfapi_cfg
->rfg_redist
->vn_prefix
.family
;
105 switch (bgp
->rfapi_cfg
->rfg_redist
->vn_prefix
.family
) {
107 if (bgp
->rfapi_cfg
->rfg_redist
->vn_prefix
.prefixlen
!= 32) {
108 vnc_zlog_debug_verbose(
109 "%s: redist nve group VN prefix len (%d) != 32, skipping",
111 bgp
->rfapi_cfg
->rfg_redist
->vn_prefix
116 bgp
->rfapi_cfg
->rfg_redist
->vn_prefix
.u
.prefix4
;
119 if (bgp
->rfapi_cfg
->rfg_redist
->vn_prefix
.prefixlen
!= 128) {
120 vnc_zlog_debug_verbose(
121 "%s: redist nve group VN prefix len (%d) != 128, skipping",
123 bgp
->rfapi_cfg
->rfg_redist
->vn_prefix
128 bgp
->rfapi_cfg
->rfg_redist
->vn_prefix
.u
.prefix6
;
131 vnc_zlog_debug_verbose(
132 "%s: no redist nve group VN host prefix configured, skipping",
138 * Assume nve group's configured UN address prefix is a host
139 * route which also happens to give the NVE UN address to use
140 * for redistributing into VNC.
144 * Set UN address in dummy nve descriptor so add_vnc_route
145 * can use it in VNC tunnel SubTLV
148 struct rfapi_ip_prefix pfx_un
;
150 rfapiQprefix2Rprefix(&bgp
->rfapi_cfg
->rfg_redist
->un_prefix
,
153 switch (pfx_un
.prefix
.addr_family
) {
155 if (pfx_un
.length
!= 32) {
156 vnc_zlog_debug_verbose(
157 "%s: redist nve group UN prefix len (%d) != 32, skipping",
158 __func__
, pfx_un
.length
);
163 if (pfx_un
.length
!= 128) {
164 vnc_zlog_debug_verbose(
165 "%s: redist nve group UN prefix len (%d) != 128, skipping",
166 __func__
, pfx_un
.length
);
171 vnc_zlog_debug_verbose(
172 "%s: no redist nve group UN host prefix configured, skipping",
177 vncHD1VR
.un_addr
= pfx_un
.prefix
;
179 if (!vncHD1VR
.peer
) {
181 * Same setup as in rfapi_open()
183 vncHD1VR
.peer
= peer_new(bgp
);
184 vncHD1VR
.peer
->status
=
185 Established
; /* keep bgp core happy */
186 bgp_sync_delete(vncHD1VR
.peer
); /* don't need these */
189 * since this peer is not on the I/O thread, this lock
190 * is not strictly necessary, but serves as a reminder
191 * to those who may meddle...
193 pthread_mutex_lock(&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
;
211 pthread_mutex_unlock(&vncHD1VR
.peer
->io_mtx
);
213 /* base code assumes have valid host pointer */
214 vncHD1VR
.peer
->host
=
215 XSTRDUP(MTYPE_BGP_PEER_HOST
, ".zebra.");
217 /* Mark peer as belonging to HD */
218 SET_FLAG(vncHD1VR
.peer
->flags
, PEER_FLAG_IS_RFAPI_HD
);
222 memset(&prd
, 0, sizeof(prd
));
223 prd
= bgp
->rfapi_cfg
->rfg_redist
->rd
;
224 prd
.family
= AF_UNSPEC
;
227 add_vnc_route(&vncHD1VR
, /* cookie + UN addr */
228 bgp
, SAFI_MPLS_VPN
, p
, &prd
, &vnaddr
, &local_pref
,
229 &(bgp
->rfapi_cfg
->redist_lifetime
),
230 NULL
, /* RFP options */
231 NULL
, /* struct rfapi_un_option */
232 NULL
, /* struct rfapi_vn_option */
233 bgp
->rfapi_cfg
->rfg_redist
->rt_export_list
, NULL
,
234 NULL
, /* label: default */
235 type
, BGP_ROUTE_REDISTRIBUTE
, 0); /* flags */
239 * Route deletions from zebra propagate to VNC here
241 static void vnc_redistribute_delete(struct prefix
*p
, uint8_t type
)
243 struct bgp
*bgp
= bgp_get_default();
244 struct prefix_rd prd
;
250 if (!bgp
->rfapi_cfg
) {
251 vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping",
255 afi
= family2afi(p
->family
);
257 vnc_zlog_debug_verbose("%s: unknown prefix address family %d",
258 __func__
, p
->family
);
261 if (!bgp
->rfapi_cfg
->redist
[afi
][type
]) {
262 vnc_zlog_debug_verbose(
263 "%s: bgp->rfapi_cfg->redist[afi=%d][type=%d] is 0, skipping",
264 __func__
, afi
, type
);
267 if (!bgp
->rfapi_cfg
->rfg_redist
) {
268 vnc_zlog_debug_verbose("%s: no redist nve group, skipping",
273 memset(&prd
, 0, sizeof(prd
));
274 prd
= bgp
->rfapi_cfg
->rfg_redist
->rd
;
275 prd
.family
= AF_UNSPEC
;
278 del_vnc_route(&vncHD1VR
, /* use dummy ptr as cookie */
279 vncHD1VR
.peer
, bgp
, SAFI_MPLS_VPN
, p
, &prd
, type
,
280 BGP_ROUTE_REDISTRIBUTE
, NULL
, 0);
284 * Flush all redistributed routes of type <type>
286 static void vnc_redistribute_withdraw(struct bgp
*bgp
, afi_t afi
, uint8_t type
)
288 struct prefix_rd prd
;
289 struct bgp_table
*table
;
290 struct bgp_node
*prn
;
293 vnc_zlog_debug_verbose("%s: entry", __func__
);
297 if (!bgp
->rfapi_cfg
) {
298 vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping",
304 * Loop over all the RDs
306 for (prn
= bgp_table_top(bgp
->rib
[afi
][SAFI_MPLS_VPN
]); prn
;
307 prn
= bgp_route_next(prn
)) {
308 memset(&prd
, 0, sizeof(prd
));
309 prd
.family
= AF_UNSPEC
;
311 memcpy(prd
.val
, prn
->p
.u
.val
, 8);
313 /* This is the per-RD table of prefixes */
316 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
320 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
322 == type
) { /* has matching redist type */
328 &vncHD1VR
, /* use dummy ptr as cookie */
329 vncHD1VR
.peer
, bgp
, SAFI_MPLS_VPN
,
330 &(rn
->p
), &prd
, type
,
331 BGP_ROUTE_REDISTRIBUTE
, NULL
, 0);
335 vnc_zlog_debug_verbose("%s: return", __func__
);
339 * Zebra route add and delete treatment.
343 static int vnc_zebra_read_route(int command
, struct zclient
*zclient
,
344 zebra_size_t length
, vrf_id_t vrf_id
)
346 struct zapi_route api
;
349 if (zapi_route_decode(zclient
->ibuf
, &api
) < 0)
352 /* we completely ignore srcdest routes for now. */
353 if (CHECK_FLAG(api
.message
, ZAPI_MESSAGE_SRCPFX
))
356 add
= (command
== ZEBRA_REDISTRIBUTE_ROUTE_ADD
);
358 vnc_redistribute_add(&api
.prefix
, api
.metric
, api
.type
);
360 vnc_redistribute_delete(&api
.prefix
, api
.type
);
362 if (BGP_DEBUG(zebra
, ZEBRA
)) {
363 char buf
[PREFIX_STRLEN
];
365 prefix2str(&api
.prefix
, buf
, sizeof(buf
));
366 vnc_zlog_debug_verbose(
367 "%s: Zebra rcvd: route delete %s %s metric %u",
368 __func__
, zebra_route_string(api
.type
), buf
,
375 /***********************************************************************
376 * vnc_bgp_zebra_*: VNC sends updates/withdraws to Zebra
377 ***********************************************************************/
380 * low-level message builder
382 static void vnc_zebra_route_msg(struct prefix
*p
, unsigned int nhp_count
,
383 void *nhp_ary
, int add
) /* 1 = add, 0 = del */
385 struct zapi_route api
;
386 struct zapi_nexthop
*api_nh
;
388 struct in_addr
**nhp_ary4
= nhp_ary
;
389 struct in6_addr
**nhp_ary6
= nhp_ary
;
392 vnc_zlog_debug_verbose("%s: empty nexthop list, skipping",
397 memset(&api
, 0, sizeof(api
));
398 api
.vrf_id
= VRF_DEFAULT
;
399 api
.type
= ZEBRA_ROUTE_VNC
;
400 api
.safi
= SAFI_UNICAST
;
404 SET_FLAG(api
.message
, ZAPI_MESSAGE_NEXTHOP
);
405 api
.nexthop_num
= MIN(nhp_count
, multipath_num
);
406 for (i
= 0; i
< api
.nexthop_num
; i
++) {
408 api_nh
= &api
.nexthops
[i
];
409 api_nh
->vrf_id
= VRF_DEFAULT
;
412 memcpy(&api_nh
->gate
.ipv4
, nhp_ary4
[i
],
413 sizeof(api_nh
->gate
.ipv4
));
414 api_nh
->type
= NEXTHOP_TYPE_IPV4
;
417 memcpy(&api_nh
->gate
.ipv6
, nhp_ary6
[i
],
418 sizeof(api_nh
->gate
.ipv6
));
419 api_nh
->type
= NEXTHOP_TYPE_IPV6
;
424 if (BGP_DEBUG(zebra
, ZEBRA
)) {
425 char buf
[PREFIX_STRLEN
];
427 prefix2str(&api
.prefix
, buf
, sizeof(buf
));
428 vnc_zlog_debug_verbose(
429 "%s: Zebra send: route %s %s, nhp_count=%d", __func__
,
430 (add
? "add" : "del"), buf
, nhp_count
);
433 zclient_route_send((add
? ZEBRA_ROUTE_ADD
: ZEBRA_ROUTE_DELETE
),
439 nve_list_to_nh_array(uint8_t family
, struct list
*nve_list
,
440 unsigned int *nh_count_ret
,
441 void **nh_ary_ret
, /* returned address array */
442 void **nhp_ary_ret
) /* returned pointer array */
444 int nve_count
= listcount(nve_list
);
451 vnc_zlog_debug_verbose("%s: empty nve_list, skipping",
456 if (family
== AF_INET
) {
462 * Array of nexthop addresses
465 XCALLOC(MTYPE_TMP
, nve_count
* sizeof(struct in_addr
));
468 * Array of pointers to nexthop addresses
470 *nhp_ary_ret
= XCALLOC(MTYPE_TMP
,
471 nve_count
* sizeof(struct in_addr
*));
475 for (ln
= listhead(nve_list
); ln
; ln
= listnextnode(ln
)) {
477 struct rfapi_descriptor
*irfd
;
480 irfd
= listgetdata(ln
);
482 if (rfapiRaddr2Qprefix(&irfd
->vn_addr
, &nhp
))
485 *iap
= nhp
.u
.prefix4
;
487 vnc_zlog_debug_verbose(
488 "%s: ipadr: (%p)<-0x%x, ptr: (%p)<-%p",
489 __func__
, iap
, nhp
.u
.prefix4
.s_addr
, v
, iap
);
496 } else if (family
== AF_INET6
) {
501 XCALLOC(MTYPE_TMP
, nve_count
* sizeof(struct in6_addr
));
503 *nhp_ary_ret
= XCALLOC(MTYPE_TMP
,
504 nve_count
* sizeof(struct in6_addr
*));
506 for (ln
= listhead(nve_list
); ln
; ln
= listnextnode(ln
)) {
508 struct rfapi_descriptor
*irfd
;
509 struct in6_addr
*iap
= *nh_ary_ret
;
510 struct in6_addr
**v
= *nhp_ary_ret
;
513 irfd
= listgetdata(ln
);
515 if (rfapiRaddr2Qprefix(&irfd
->vn_addr
, &nhp
))
518 *iap
= nhp
.u
.prefix6
;
528 static void import_table_to_nve_list_zebra(struct bgp
*bgp
,
529 struct rfapi_import_table
*it
,
530 struct list
**nves
, uint8_t family
)
532 struct listnode
*node
;
533 struct rfapi_rfg_name
*rfgn
;
536 * Loop over the list of NVE-Groups configured for
537 * exporting to direct-bgp.
539 * Build a list of NVEs that use this import table
542 for (ALL_LIST_ELEMENTS_RO(bgp
->rfapi_cfg
->rfg_export_zebra_l
, node
,
546 * If this NVE-Group's import table matches the current one
548 if (rfgn
->rfg
&& rfgn
->rfg
->nves
549 && rfgn
->rfg
->rfapi_import_table
== it
) {
551 nve_group_to_nve_list(rfgn
->rfg
, nves
, family
);
556 static void vnc_zebra_add_del_prefix(struct bgp
*bgp
,
557 struct rfapi_import_table
*import_table
,
558 struct route_node
*rn
,
559 int add
) /* !0 = add, 0 = del */
563 unsigned int nexthop_count
= 0;
565 void *nhp_ary
= NULL
;
567 vnc_zlog_debug_verbose("%s: entry, add=%d", __func__
, add
);
569 if (zclient_vnc
->sock
< 0)
572 if (rn
->p
.family
!= AF_INET
&& rn
->p
.family
!= AF_INET6
) {
573 zlog_err("%s: invalid route node addr family", __func__
);
577 if (!zclient_vnc
->redist
[family2afi(rn
->p
.family
)][ZEBRA_ROUTE_VNC
])
580 if (!bgp
->rfapi_cfg
) {
581 vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping",
585 if (!listcount(bgp
->rfapi_cfg
->rfg_export_zebra_l
)) {
586 vnc_zlog_debug_verbose(
587 "%s: no zebra export nve group, skipping", __func__
);
591 import_table_to_nve_list_zebra(bgp
, import_table
, &nves
, rn
->p
.family
);
594 nve_list_to_nh_array(rn
->p
.family
, nves
, &nexthop_count
,
597 list_delete_and_null(&nves
);
600 vnc_zebra_route_msg(&rn
->p
, nexthop_count
, nhp_ary
,
605 XFREE(MTYPE_TMP
, nhp_ary
);
607 XFREE(MTYPE_TMP
, nh_ary
);
610 void vnc_zebra_add_prefix(struct bgp
*bgp
,
611 struct rfapi_import_table
*import_table
,
612 struct route_node
*rn
)
614 vnc_zebra_add_del_prefix(bgp
, import_table
, rn
, 1);
617 void vnc_zebra_del_prefix(struct bgp
*bgp
,
618 struct rfapi_import_table
*import_table
,
619 struct route_node
*rn
)
621 vnc_zebra_add_del_prefix(bgp
, import_table
, rn
, 0);
625 static void vnc_zebra_add_del_nve(struct bgp
*bgp
, struct rfapi_descriptor
*rfd
,
626 int add
) /* 0 = del, !0 = add */
628 struct listnode
*node
;
629 struct rfapi_rfg_name
*rfgn
;
630 struct rfapi_nve_group_cfg
*rfg
= rfd
->rfg
;
631 afi_t afi
= family2afi(rfd
->vn_addr
.addr_family
);
633 // struct prefix *nhpp;
636 vnc_zlog_debug_verbose("%s: entry, add=%d", __func__
, add
);
638 if (zclient_vnc
->sock
< 0)
641 if (!zclient_vnc
->redist
[afi
][ZEBRA_ROUTE_VNC
])
644 if (afi
!= AFI_IP
&& afi
!= AFI_IP6
) {
645 zlog_err("%s: invalid vn addr family", __func__
);
651 if (!bgp
->rfapi_cfg
) {
652 vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping",
657 if (rfapiRaddr2Qprefix(&rfd
->vn_addr
, &nhp
)) {
658 vnc_zlog_debug_verbose("%s: can't convert vn address, skipping",
663 pAddr
= &nhp
.u
.prefix4
;
666 * Loop over the list of NVE-Groups configured for
667 * exporting to zebra and see if this new NVE's
668 * group is among them.
670 for (ALL_LIST_ELEMENTS_RO(bgp
->rfapi_cfg
->rfg_export_zebra_l
, node
,
674 * Yes, this NVE's group is configured for export to zebra
676 if (rfgn
->rfg
== rfg
) {
678 struct route_table
*rt
= NULL
;
679 struct route_node
*rn
;
680 struct rfapi_import_table
*import_table
;
681 import_table
= rfg
->rfapi_import_table
;
683 vnc_zlog_debug_verbose(
684 "%s: this nve's group is in zebra export list",
687 rt
= import_table
->imported_vpn
[afi
];
690 * Walk the NVE-Group's VNC Import table
692 for (rn
= route_top(rt
); rn
; rn
= route_next(rn
)) {
696 vnc_zlog_debug_verbose(
697 "%s: sending %s", __func__
,
698 (add
? "add" : "del"));
699 vnc_zebra_route_msg(&rn
->p
, 1, &pAddr
,
707 void vnc_zebra_add_nve(struct bgp
*bgp
, struct rfapi_descriptor
*rfd
)
709 vnc_zebra_add_del_nve(bgp
, rfd
, 1);
712 void vnc_zebra_del_nve(struct bgp
*bgp
, struct rfapi_descriptor
*rfd
)
714 vnc_zebra_add_del_nve(bgp
, rfd
, 0);
717 static void vnc_zebra_add_del_group_afi(struct bgp
*bgp
,
718 struct rfapi_nve_group_cfg
*rfg
,
721 struct route_table
*rt
= NULL
;
722 struct route_node
*rn
;
723 struct rfapi_import_table
*import_table
;
724 uint8_t family
= afi2family(afi
);
726 struct list
*nves
= NULL
;
727 unsigned int nexthop_count
= 0;
729 void *nhp_ary
= NULL
;
731 vnc_zlog_debug_verbose("%s: entry", __func__
);
732 import_table
= rfg
->rfapi_import_table
;
734 vnc_zlog_debug_verbose(
735 "%s: import table not defined, returning", __func__
);
739 if (afi
== AFI_IP
|| afi
== AFI_IP6
) {
740 rt
= import_table
->imported_vpn
[afi
];
742 zlog_err("%s: bad afi %d", __func__
, afi
);
747 zlog_err("%s: computed bad family: %d", __func__
, family
);
752 /* avoid segfault below if list doesn't exist */
753 vnc_zlog_debug_verbose("%s: no NVEs in this group", __func__
);
757 nve_group_to_nve_list(rfg
, &nves
, family
);
759 vnc_zlog_debug_verbose("%s: have nves", __func__
);
760 nve_list_to_nh_array(family
, nves
, &nexthop_count
, &nh_ary
,
763 vnc_zlog_debug_verbose("%s: family: %d, nve count: %d",
764 __func__
, family
, nexthop_count
);
766 list_delete_and_null(&nves
);
770 * Walk the NVE-Group's VNC Import table
772 for (rn
= route_top(rt
); rn
; rn
= route_next(rn
)) {
774 vnc_zebra_route_msg(&rn
->p
,
781 XFREE(MTYPE_TMP
, nhp_ary
);
783 XFREE(MTYPE_TMP
, nh_ary
);
787 void vnc_zebra_add_group(struct bgp
*bgp
, struct rfapi_nve_group_cfg
*rfg
)
789 vnc_zebra_add_del_group_afi(bgp
, rfg
, AFI_IP
, 1);
790 vnc_zebra_add_del_group_afi(bgp
, rfg
, AFI_IP6
, 1);
793 void vnc_zebra_del_group(struct bgp
*bgp
, struct rfapi_nve_group_cfg
*rfg
)
795 vnc_zlog_debug_verbose("%s: entry", __func__
);
796 vnc_zebra_add_del_group_afi(bgp
, rfg
, AFI_IP
, 0);
797 vnc_zebra_add_del_group_afi(bgp
, rfg
, AFI_IP6
, 0);
800 void vnc_zebra_reexport_group_afi(struct bgp
*bgp
,
801 struct rfapi_nve_group_cfg
*rfg
, afi_t afi
)
803 struct listnode
*node
;
804 struct rfapi_rfg_name
*rfgn
;
806 for (ALL_LIST_ELEMENTS_RO(bgp
->rfapi_cfg
->rfg_export_zebra_l
, node
,
809 if (rfgn
->rfg
== rfg
) {
810 vnc_zebra_add_del_group_afi(bgp
, rfg
, afi
, 0);
811 vnc_zebra_add_del_group_afi(bgp
, rfg
, afi
, 1);
818 /***********************************************************************
820 ***********************************************************************/
823 /* Other routes redistribution into BGP. */
824 int vnc_redistribute_set(struct bgp
*bgp
, afi_t afi
, int type
)
826 if (!bgp
->rfapi_cfg
) {
827 return CMD_WARNING_CONFIG_FAILED
;
830 /* Set flag to BGP instance. */
831 bgp
->rfapi_cfg
->redist
[afi
][type
] = 1;
833 // bgp->redist[afi][type] = 1;
835 /* Return if already redistribute flag is set. */
836 if (zclient_vnc
->redist
[afi
][type
])
837 return CMD_WARNING_CONFIG_FAILED
;
839 vrf_bitmap_set(zclient_vnc
->redist
[afi
][type
], VRF_DEFAULT
);
841 // zclient_vnc->redist[afi][type] = 1;
843 /* Return if zebra connection is not established. */
844 if (zclient_vnc
->sock
< 0)
845 return CMD_WARNING_CONFIG_FAILED
;
847 if (BGP_DEBUG(zebra
, ZEBRA
))
848 vnc_zlog_debug_verbose("Zebra send: redistribute add %s",
849 zebra_route_string(type
));
851 /* Send distribute add message to zebra. */
852 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD
, zclient_vnc
, afi
, type
,
858 /* Unset redistribution. */
859 int vnc_redistribute_unset(struct bgp
*bgp
, afi_t afi
, int type
)
861 vnc_zlog_debug_verbose("%s: type=%d entry", __func__
, type
);
863 if (!bgp
->rfapi_cfg
) {
864 vnc_zlog_debug_verbose("%s: return (no rfapi_cfg)", __func__
);
865 return CMD_WARNING_CONFIG_FAILED
;
868 /* Unset flag from BGP instance. */
869 bgp
->rfapi_cfg
->redist
[afi
][type
] = 0;
871 /* Return if zebra connection is disabled. */
872 if (!zclient_vnc
->redist
[afi
][type
])
873 return CMD_WARNING_CONFIG_FAILED
;
874 zclient_vnc
->redist
[afi
][type
] = 0;
876 if (bgp
->rfapi_cfg
->redist
[AFI_IP
][type
] == 0
877 && bgp
->rfapi_cfg
->redist
[AFI_IP6
][type
] == 0
878 && zclient_vnc
->sock
>= 0) {
879 /* Send distribute delete message to zebra. */
880 if (BGP_DEBUG(zebra
, ZEBRA
))
881 vnc_zlog_debug_verbose(
882 "Zebra send: redistribute delete %s",
883 zebra_route_string(type
));
884 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE
, zclient_vnc
,
885 afi
, type
, 0, VRF_DEFAULT
);
888 /* Withdraw redistributed routes from current BGP's routing table. */
889 vnc_redistribute_withdraw(bgp
, afi
, type
);
891 vnc_zlog_debug_verbose("%s: return", __func__
);
896 extern struct zebra_privs_t bgpd_privs
;
899 * Modeled after bgp_zebra.c'bgp_zebra_init()
900 * Charriere asks, "Is it possible to carry two?"
902 void vnc_zebra_init(struct thread_master
*master
)
904 /* Set default values. */
905 zclient_vnc
= zclient_new_notify(master
, &zclient_options_default
);
906 zclient_init(zclient_vnc
, ZEBRA_ROUTE_VNC
, 0, &bgpd_privs
);
908 zclient_vnc
->redistribute_route_add
= vnc_zebra_read_route
;
909 zclient_vnc
->redistribute_route_del
= vnc_zebra_read_route
;
912 void vnc_zebra_destroy(void)
914 if (zclient_vnc
== NULL
)
916 zclient_stop(zclient_vnc
);
917 zclient_free(zclient_vnc
);