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 pthread_mutex_lock(&vncHD1VR
.peer
->io_mtx
);
196 // we don't need any I/O related facilities
197 if (vncHD1VR
.peer
->ibuf
)
198 stream_fifo_free(vncHD1VR
.peer
->ibuf
);
199 if (vncHD1VR
.peer
->obuf
)
200 stream_fifo_free(vncHD1VR
.peer
->obuf
);
202 if (vncHD1VR
.peer
->ibuf_work
)
203 ringbuf_del(vncHD1VR
.peer
->ibuf_work
);
204 if (vncHD1VR
.peer
->obuf_work
)
205 stream_free(vncHD1VR
.peer
->obuf_work
);
207 vncHD1VR
.peer
->ibuf
= NULL
;
208 vncHD1VR
.peer
->obuf
= NULL
;
209 vncHD1VR
.peer
->obuf_work
= NULL
;
210 vncHD1VR
.peer
->ibuf_work
= NULL
;
212 pthread_mutex_unlock(&vncHD1VR
.peer
->io_mtx
);
214 /* base code assumes have valid host pointer */
215 vncHD1VR
.peer
->host
=
216 XSTRDUP(MTYPE_BGP_PEER_HOST
, ".zebra.");
218 /* Mark peer as belonging to HD */
219 SET_FLAG(vncHD1VR
.peer
->flags
, PEER_FLAG_IS_RFAPI_HD
);
223 memset(&prd
, 0, sizeof(prd
));
224 prd
= bgp
->rfapi_cfg
->rfg_redist
->rd
;
225 prd
.family
= AF_UNSPEC
;
228 add_vnc_route(&vncHD1VR
, /* cookie + UN addr */
229 bgp
, SAFI_MPLS_VPN
, p
, &prd
, &vnaddr
, &local_pref
,
230 &(bgp
->rfapi_cfg
->redist_lifetime
),
231 NULL
, /* RFP options */
232 NULL
, /* struct rfapi_un_option */
233 NULL
, /* struct rfapi_vn_option */
234 bgp
->rfapi_cfg
->rfg_redist
->rt_export_list
, NULL
,
235 NULL
, /* label: default */
236 type
, BGP_ROUTE_REDISTRIBUTE
, 0); /* flags */
240 * Route deletions from zebra propagate to VNC here
242 static void vnc_redistribute_delete(struct prefix
*p
, uint8_t type
)
244 struct bgp
*bgp
= bgp_get_default();
245 struct prefix_rd prd
;
251 if (!bgp
->rfapi_cfg
) {
252 vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping",
256 afi
= family2afi(p
->family
);
258 vnc_zlog_debug_verbose("%s: unknown prefix address family %d",
259 __func__
, p
->family
);
262 if (!bgp
->rfapi_cfg
->redist
[afi
][type
]) {
263 vnc_zlog_debug_verbose(
264 "%s: bgp->rfapi_cfg->redist[afi=%d][type=%d] is 0, skipping",
265 __func__
, afi
, type
);
268 if (!bgp
->rfapi_cfg
->rfg_redist
) {
269 vnc_zlog_debug_verbose("%s: no redist nve group, skipping",
274 memset(&prd
, 0, sizeof(prd
));
275 prd
= bgp
->rfapi_cfg
->rfg_redist
->rd
;
276 prd
.family
= AF_UNSPEC
;
279 del_vnc_route(&vncHD1VR
, /* use dummy ptr as cookie */
280 vncHD1VR
.peer
, bgp
, SAFI_MPLS_VPN
, p
, &prd
, type
,
281 BGP_ROUTE_REDISTRIBUTE
, NULL
, 0);
285 * Flush all redistributed routes of type <type>
287 static void vnc_redistribute_withdraw(struct bgp
*bgp
, afi_t afi
, uint8_t type
)
289 struct prefix_rd prd
;
290 struct bgp_table
*table
;
291 struct bgp_node
*prn
;
294 vnc_zlog_debug_verbose("%s: entry", __func__
);
298 if (!bgp
->rfapi_cfg
) {
299 vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping",
305 * Loop over all the RDs
307 for (prn
= bgp_table_top(bgp
->rib
[afi
][SAFI_MPLS_VPN
]); prn
;
308 prn
= bgp_route_next(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 */
317 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
321 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
323 == type
) { /* has matching redist type */
329 &vncHD1VR
, /* use dummy ptr as cookie */
330 vncHD1VR
.peer
, bgp
, SAFI_MPLS_VPN
,
331 &(rn
->p
), &prd
, type
,
332 BGP_ROUTE_REDISTRIBUTE
, NULL
, 0);
336 vnc_zlog_debug_verbose("%s: return", __func__
);
340 * Zebra route add and delete treatment.
344 static int vnc_zebra_read_route(int command
, struct zclient
*zclient
,
345 zebra_size_t length
, vrf_id_t vrf_id
)
347 struct zapi_route api
;
350 if (zapi_route_decode(zclient
->ibuf
, &api
) < 0)
353 /* we completely ignore srcdest routes for now. */
354 if (CHECK_FLAG(api
.message
, ZAPI_MESSAGE_SRCPFX
))
357 add
= (command
== ZEBRA_REDISTRIBUTE_ROUTE_ADD
);
359 vnc_redistribute_add(&api
.prefix
, api
.metric
, api
.type
);
361 vnc_redistribute_delete(&api
.prefix
, api
.type
);
363 if (BGP_DEBUG(zebra
, ZEBRA
)) {
364 char buf
[PREFIX_STRLEN
];
366 prefix2str(&api
.prefix
, buf
, sizeof(buf
));
367 vnc_zlog_debug_verbose(
368 "%s: Zebra rcvd: route delete %s %s metric %u",
369 __func__
, zebra_route_string(api
.type
), buf
,
376 /***********************************************************************
377 * vnc_bgp_zebra_*: VNC sends updates/withdraws to Zebra
378 ***********************************************************************/
381 * low-level message builder
383 static void vnc_zebra_route_msg(struct prefix
*p
, unsigned int nhp_count
,
384 void *nhp_ary
, int add
) /* 1 = add, 0 = del */
386 struct zapi_route api
;
387 struct zapi_nexthop
*api_nh
;
389 struct in_addr
**nhp_ary4
= nhp_ary
;
390 struct in6_addr
**nhp_ary6
= nhp_ary
;
393 vnc_zlog_debug_verbose("%s: empty nexthop list, skipping",
398 memset(&api
, 0, sizeof(api
));
399 api
.vrf_id
= VRF_DEFAULT
;
400 api
.type
= ZEBRA_ROUTE_VNC
;
401 api
.safi
= SAFI_UNICAST
;
405 SET_FLAG(api
.message
, ZAPI_MESSAGE_NEXTHOP
);
406 api
.nexthop_num
= MIN(nhp_count
, multipath_num
);
407 for (i
= 0; i
< api
.nexthop_num
; i
++) {
409 api_nh
= &api
.nexthops
[i
];
410 api_nh
->vrf_id
= VRF_DEFAULT
;
413 memcpy(&api_nh
->gate
.ipv4
, nhp_ary4
[i
],
414 sizeof(api_nh
->gate
.ipv4
));
415 api_nh
->type
= NEXTHOP_TYPE_IPV4
;
418 memcpy(&api_nh
->gate
.ipv6
, nhp_ary6
[i
],
419 sizeof(api_nh
->gate
.ipv6
));
420 api_nh
->type
= NEXTHOP_TYPE_IPV6
;
425 if (BGP_DEBUG(zebra
, ZEBRA
)) {
426 char buf
[PREFIX_STRLEN
];
428 prefix2str(&api
.prefix
, buf
, sizeof(buf
));
429 vnc_zlog_debug_verbose(
430 "%s: Zebra send: route %s %s, nhp_count=%d", __func__
,
431 (add
? "add" : "del"), buf
, nhp_count
);
434 zclient_route_send((add
? ZEBRA_ROUTE_ADD
: ZEBRA_ROUTE_DELETE
),
440 nve_list_to_nh_array(uint8_t family
, struct list
*nve_list
,
441 unsigned int *nh_count_ret
,
442 void **nh_ary_ret
, /* returned address array */
443 void **nhp_ary_ret
) /* returned pointer array */
445 int nve_count
= listcount(nve_list
);
452 vnc_zlog_debug_verbose("%s: empty nve_list, skipping",
457 if (family
== AF_INET
) {
463 * Array of nexthop addresses
466 XCALLOC(MTYPE_TMP
, nve_count
* sizeof(struct in_addr
));
469 * Array of pointers to nexthop addresses
471 *nhp_ary_ret
= XCALLOC(MTYPE_TMP
,
472 nve_count
* sizeof(struct in_addr
*));
476 for (ln
= listhead(nve_list
); ln
; ln
= listnextnode(ln
)) {
478 struct rfapi_descriptor
*irfd
;
481 irfd
= listgetdata(ln
);
483 if (rfapiRaddr2Qprefix(&irfd
->vn_addr
, &nhp
))
486 *iap
= nhp
.u
.prefix4
;
488 vnc_zlog_debug_verbose(
489 "%s: ipadr: (%p)<-0x%x, ptr: (%p)<-%p",
490 __func__
, iap
, nhp
.u
.prefix4
.s_addr
, v
, iap
);
497 } else if (family
== AF_INET6
) {
502 XCALLOC(MTYPE_TMP
, nve_count
* sizeof(struct in6_addr
));
504 *nhp_ary_ret
= XCALLOC(MTYPE_TMP
,
505 nve_count
* sizeof(struct in6_addr
*));
507 for (ln
= listhead(nve_list
); ln
; ln
= listnextnode(ln
)) {
509 struct rfapi_descriptor
*irfd
;
510 struct in6_addr
*iap
= *nh_ary_ret
;
511 struct in6_addr
**v
= *nhp_ary_ret
;
514 irfd
= listgetdata(ln
);
516 if (rfapiRaddr2Qprefix(&irfd
->vn_addr
, &nhp
))
519 *iap
= nhp
.u
.prefix6
;
529 static void import_table_to_nve_list_zebra(struct bgp
*bgp
,
530 struct rfapi_import_table
*it
,
531 struct list
**nves
, uint8_t family
)
533 struct listnode
*node
;
534 struct rfapi_rfg_name
*rfgn
;
537 * Loop over the list of NVE-Groups configured for
538 * exporting to direct-bgp.
540 * Build a list of NVEs that use this import table
543 for (ALL_LIST_ELEMENTS_RO(bgp
->rfapi_cfg
->rfg_export_zebra_l
, node
,
547 * If this NVE-Group's import table matches the current one
549 if (rfgn
->rfg
&& rfgn
->rfg
->nves
550 && rfgn
->rfg
->rfapi_import_table
== it
) {
552 nve_group_to_nve_list(rfgn
->rfg
, nves
, family
);
557 static void vnc_zebra_add_del_prefix(struct bgp
*bgp
,
558 struct rfapi_import_table
*import_table
,
560 int add
) /* !0 = add, 0 = del */
564 unsigned int nexthop_count
= 0;
566 void *nhp_ary
= NULL
;
568 vnc_zlog_debug_verbose("%s: entry, add=%d", __func__
, add
);
570 if (zclient_vnc
->sock
< 0)
573 if (rn
->p
.family
!= AF_INET
&& rn
->p
.family
!= AF_INET6
) {
574 flog_err(EC_LIB_DEVELOPMENT
,
575 "%s: invalid route node addr family", __func__
);
579 if (!zclient_vnc
->redist
[family2afi(rn
->p
.family
)][ZEBRA_ROUTE_VNC
])
582 if (!bgp
->rfapi_cfg
) {
583 vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping",
587 if (!listcount(bgp
->rfapi_cfg
->rfg_export_zebra_l
)) {
588 vnc_zlog_debug_verbose(
589 "%s: no zebra export nve group, skipping", __func__
);
593 import_table_to_nve_list_zebra(bgp
, import_table
, &nves
, rn
->p
.family
);
596 nve_list_to_nh_array(rn
->p
.family
, nves
, &nexthop_count
,
599 list_delete_and_null(&nves
);
602 vnc_zebra_route_msg(&rn
->p
, nexthop_count
, nhp_ary
,
607 XFREE(MTYPE_TMP
, nhp_ary
);
609 XFREE(MTYPE_TMP
, nh_ary
);
612 void vnc_zebra_add_prefix(struct bgp
*bgp
,
613 struct rfapi_import_table
*import_table
,
616 vnc_zebra_add_del_prefix(bgp
, import_table
, rn
, 1);
619 void vnc_zebra_del_prefix(struct bgp
*bgp
,
620 struct rfapi_import_table
*import_table
,
623 vnc_zebra_add_del_prefix(bgp
, import_table
, rn
, 0);
627 static void vnc_zebra_add_del_nve(struct bgp
*bgp
, struct rfapi_descriptor
*rfd
,
628 int add
) /* 0 = del, !0 = add */
630 struct listnode
*node
;
631 struct rfapi_rfg_name
*rfgn
;
632 struct rfapi_nve_group_cfg
*rfg
= rfd
->rfg
;
633 afi_t afi
= family2afi(rfd
->vn_addr
.addr_family
);
635 // struct prefix *nhpp;
638 vnc_zlog_debug_verbose("%s: entry, add=%d", __func__
, add
);
640 if (zclient_vnc
->sock
< 0)
643 if (!zclient_vnc
->redist
[afi
][ZEBRA_ROUTE_VNC
])
646 if (afi
!= AFI_IP
&& afi
!= AFI_IP6
) {
647 flog_err(EC_LIB_DEVELOPMENT
, "%s: invalid vn addr family",
654 if (!bgp
->rfapi_cfg
) {
655 vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping",
660 if (rfapiRaddr2Qprefix(&rfd
->vn_addr
, &nhp
)) {
661 vnc_zlog_debug_verbose("%s: can't convert vn address, skipping",
666 pAddr
= &nhp
.u
.prefix4
;
669 * Loop over the list of NVE-Groups configured for
670 * exporting to zebra and see if this new NVE's
671 * group is among them.
673 for (ALL_LIST_ELEMENTS_RO(bgp
->rfapi_cfg
->rfg_export_zebra_l
, node
,
677 * Yes, this NVE's group is configured for export to zebra
679 if (rfgn
->rfg
== rfg
) {
681 struct agg_table
*rt
= NULL
;
683 struct rfapi_import_table
*import_table
;
684 import_table
= rfg
->rfapi_import_table
;
686 vnc_zlog_debug_verbose(
687 "%s: this nve's group is in zebra export list",
690 rt
= import_table
->imported_vpn
[afi
];
693 * Walk the NVE-Group's VNC Import table
695 for (rn
= agg_route_top(rt
); rn
;
696 rn
= agg_route_next(rn
)) {
700 vnc_zlog_debug_verbose(
701 "%s: sending %s", __func__
,
702 (add
? "add" : "del"));
703 vnc_zebra_route_msg(&rn
->p
, 1, &pAddr
,
711 void vnc_zebra_add_nve(struct bgp
*bgp
, struct rfapi_descriptor
*rfd
)
713 vnc_zebra_add_del_nve(bgp
, rfd
, 1);
716 void vnc_zebra_del_nve(struct bgp
*bgp
, struct rfapi_descriptor
*rfd
)
718 vnc_zebra_add_del_nve(bgp
, rfd
, 0);
721 static void vnc_zebra_add_del_group_afi(struct bgp
*bgp
,
722 struct rfapi_nve_group_cfg
*rfg
,
725 struct agg_table
*rt
= NULL
;
727 struct rfapi_import_table
*import_table
;
728 uint8_t family
= afi2family(afi
);
730 struct list
*nves
= NULL
;
731 unsigned int nexthop_count
= 0;
733 void *nhp_ary
= NULL
;
735 vnc_zlog_debug_verbose("%s: entry", __func__
);
736 import_table
= rfg
->rfapi_import_table
;
738 vnc_zlog_debug_verbose(
739 "%s: import table not defined, returning", __func__
);
743 if (afi
== AFI_IP
|| afi
== AFI_IP6
) {
744 rt
= import_table
->imported_vpn
[afi
];
746 flog_err(EC_LIB_DEVELOPMENT
, "%s: bad afi %d", __func__
, afi
);
751 flog_err(EC_LIB_DEVELOPMENT
, "%s: computed bad family: %d",
757 /* avoid segfault below if list doesn't exist */
758 vnc_zlog_debug_verbose("%s: no NVEs in this group", __func__
);
762 nve_group_to_nve_list(rfg
, &nves
, family
);
764 vnc_zlog_debug_verbose("%s: have nves", __func__
);
765 nve_list_to_nh_array(family
, nves
, &nexthop_count
, &nh_ary
,
768 vnc_zlog_debug_verbose("%s: family: %d, nve count: %d",
769 __func__
, family
, nexthop_count
);
771 list_delete_and_null(&nves
);
775 * Walk the NVE-Group's VNC Import table
777 for (rn
= agg_route_top(rt
); rn
;
778 rn
= agg_route_next(rn
)) {
780 vnc_zebra_route_msg(&rn
->p
,
787 XFREE(MTYPE_TMP
, nhp_ary
);
789 XFREE(MTYPE_TMP
, nh_ary
);
793 void vnc_zebra_add_group(struct bgp
*bgp
, struct rfapi_nve_group_cfg
*rfg
)
795 vnc_zebra_add_del_group_afi(bgp
, rfg
, AFI_IP
, 1);
796 vnc_zebra_add_del_group_afi(bgp
, rfg
, AFI_IP6
, 1);
799 void vnc_zebra_del_group(struct bgp
*bgp
, struct rfapi_nve_group_cfg
*rfg
)
801 vnc_zlog_debug_verbose("%s: entry", __func__
);
802 vnc_zebra_add_del_group_afi(bgp
, rfg
, AFI_IP
, 0);
803 vnc_zebra_add_del_group_afi(bgp
, rfg
, AFI_IP6
, 0);
806 void vnc_zebra_reexport_group_afi(struct bgp
*bgp
,
807 struct rfapi_nve_group_cfg
*rfg
, afi_t afi
)
809 struct listnode
*node
;
810 struct rfapi_rfg_name
*rfgn
;
812 for (ALL_LIST_ELEMENTS_RO(bgp
->rfapi_cfg
->rfg_export_zebra_l
, node
,
815 if (rfgn
->rfg
== rfg
) {
816 vnc_zebra_add_del_group_afi(bgp
, rfg
, afi
, 0);
817 vnc_zebra_add_del_group_afi(bgp
, rfg
, afi
, 1);
824 /***********************************************************************
826 ***********************************************************************/
829 /* Other routes redistribution into BGP. */
830 int vnc_redistribute_set(struct bgp
*bgp
, afi_t afi
, int type
)
832 if (!bgp
->rfapi_cfg
) {
833 return CMD_WARNING_CONFIG_FAILED
;
836 /* Set flag to BGP instance. */
837 bgp
->rfapi_cfg
->redist
[afi
][type
] = 1;
839 // bgp->redist[afi][type] = 1;
841 /* Return if already redistribute flag is set. */
842 if (zclient_vnc
->redist
[afi
][type
])
843 return CMD_WARNING_CONFIG_FAILED
;
845 vrf_bitmap_set(zclient_vnc
->redist
[afi
][type
], VRF_DEFAULT
);
847 // zclient_vnc->redist[afi][type] = 1;
849 /* Return if zebra connection is not established. */
850 if (zclient_vnc
->sock
< 0)
851 return CMD_WARNING_CONFIG_FAILED
;
853 if (BGP_DEBUG(zebra
, ZEBRA
))
854 vnc_zlog_debug_verbose("Zebra send: redistribute add %s",
855 zebra_route_string(type
));
857 /* Send distribute add message to zebra. */
858 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD
, zclient_vnc
, afi
, type
,
864 /* Unset redistribution. */
865 int vnc_redistribute_unset(struct bgp
*bgp
, afi_t afi
, int type
)
867 vnc_zlog_debug_verbose("%s: type=%d entry", __func__
, type
);
869 if (!bgp
->rfapi_cfg
) {
870 vnc_zlog_debug_verbose("%s: return (no rfapi_cfg)", __func__
);
871 return CMD_WARNING_CONFIG_FAILED
;
874 /* Unset flag from BGP instance. */
875 bgp
->rfapi_cfg
->redist
[afi
][type
] = 0;
877 /* Return if zebra connection is disabled. */
878 if (!zclient_vnc
->redist
[afi
][type
])
879 return CMD_WARNING_CONFIG_FAILED
;
880 zclient_vnc
->redist
[afi
][type
] = 0;
882 if (bgp
->rfapi_cfg
->redist
[AFI_IP
][type
] == 0
883 && bgp
->rfapi_cfg
->redist
[AFI_IP6
][type
] == 0
884 && zclient_vnc
->sock
>= 0) {
885 /* Send distribute delete message to zebra. */
886 if (BGP_DEBUG(zebra
, ZEBRA
))
887 vnc_zlog_debug_verbose(
888 "Zebra send: redistribute delete %s",
889 zebra_route_string(type
));
890 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE
, zclient_vnc
,
891 afi
, type
, 0, VRF_DEFAULT
);
894 /* Withdraw redistributed routes from current BGP's routing table. */
895 vnc_redistribute_withdraw(bgp
, afi
, type
);
897 vnc_zlog_debug_verbose("%s: return", __func__
);
902 extern struct zebra_privs_t bgpd_privs
;
905 * Modeled after bgp_zebra.c'bgp_zebra_init()
906 * Charriere asks, "Is it possible to carry two?"
908 void vnc_zebra_init(struct thread_master
*master
)
910 /* Set default values. */
911 zclient_vnc
= zclient_new_notify(master
, &zclient_options_default
);
912 zclient_init(zclient_vnc
, ZEBRA_ROUTE_VNC
, 0, &bgpd_privs
);
914 zclient_vnc
->redistribute_route_add
= vnc_zebra_read_route
;
915 zclient_vnc
->redistribute_route_del
= vnc_zebra_read_route
;
918 void vnc_zebra_destroy(void)
920 if (zclient_vnc
== NULL
)
922 zclient_stop(zclient_vnc
);
923 zclient_free(zclient_vnc
);