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 */
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 &(rn
->p
), &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(int command
, struct zclient
*zclient
,
348 zebra_size_t length
, vrf_id_t vrf_id
)
350 struct zapi_route api
;
353 if (zapi_route_decode(zclient
->ibuf
, &api
) < 0)
356 /* we completely ignore srcdest routes for now. */
357 if (CHECK_FLAG(api
.message
, ZAPI_MESSAGE_SRCPFX
))
360 add
= (command
== ZEBRA_REDISTRIBUTE_ROUTE_ADD
);
362 vnc_redistribute_add(&api
.prefix
, api
.metric
, api
.type
);
364 vnc_redistribute_delete(&api
.prefix
, api
.type
);
366 if (BGP_DEBUG(zebra
, ZEBRA
)) {
367 char buf
[PREFIX_STRLEN
];
369 prefix2str(&api
.prefix
, buf
, sizeof(buf
));
370 vnc_zlog_debug_verbose(
371 "%s: Zebra rcvd: route delete %s %s metric %u",
372 __func__
, zebra_route_string(api
.type
), buf
,
379 /***********************************************************************
380 * vnc_bgp_zebra_*: VNC sends updates/withdraws to Zebra
381 ***********************************************************************/
384 * low-level message builder
386 static void vnc_zebra_route_msg(struct prefix
*p
, unsigned int nhp_count
,
387 void *nhp_ary
, int add
) /* 1 = add, 0 = del */
389 struct zapi_route api
;
390 struct zapi_nexthop
*api_nh
;
392 struct in_addr
**nhp_ary4
= nhp_ary
;
393 struct in6_addr
**nhp_ary6
= nhp_ary
;
396 vnc_zlog_debug_verbose("%s: empty nexthop list, skipping",
401 memset(&api
, 0, sizeof(api
));
402 api
.vrf_id
= VRF_DEFAULT
;
403 api
.type
= ZEBRA_ROUTE_VNC
;
404 api
.safi
= SAFI_UNICAST
;
408 SET_FLAG(api
.message
, ZAPI_MESSAGE_NEXTHOP
);
409 api
.nexthop_num
= MIN(nhp_count
, multipath_num
);
410 for (i
= 0; i
< api
.nexthop_num
; i
++) {
412 api_nh
= &api
.nexthops
[i
];
413 api_nh
->vrf_id
= VRF_DEFAULT
;
416 memcpy(&api_nh
->gate
.ipv4
, nhp_ary4
[i
],
417 sizeof(api_nh
->gate
.ipv4
));
418 api_nh
->type
= NEXTHOP_TYPE_IPV4
;
421 memcpy(&api_nh
->gate
.ipv6
, nhp_ary6
[i
],
422 sizeof(api_nh
->gate
.ipv6
));
423 api_nh
->type
= NEXTHOP_TYPE_IPV6
;
428 if (BGP_DEBUG(zebra
, ZEBRA
)) {
429 char buf
[PREFIX_STRLEN
];
431 prefix2str(&api
.prefix
, buf
, sizeof(buf
));
432 vnc_zlog_debug_verbose(
433 "%s: Zebra send: route %s %s, nhp_count=%d", __func__
,
434 (add
? "add" : "del"), buf
, nhp_count
);
437 zclient_route_send((add
? ZEBRA_ROUTE_ADD
: ZEBRA_ROUTE_DELETE
),
443 nve_list_to_nh_array(uint8_t family
, struct list
*nve_list
,
444 unsigned int *nh_count_ret
,
445 void **nh_ary_ret
, /* returned address array */
446 void **nhp_ary_ret
) /* returned pointer array */
448 int nve_count
= listcount(nve_list
);
455 vnc_zlog_debug_verbose("%s: empty nve_list, skipping",
460 if (family
== AF_INET
) {
466 * Array of nexthop addresses
469 XCALLOC(MTYPE_TMP
, nve_count
* sizeof(struct in_addr
));
472 * Array of pointers to nexthop addresses
474 *nhp_ary_ret
= XCALLOC(MTYPE_TMP
,
475 nve_count
* sizeof(struct in_addr
*));
479 for (ln
= listhead(nve_list
); ln
; ln
= listnextnode(ln
)) {
481 struct rfapi_descriptor
*irfd
;
484 irfd
= listgetdata(ln
);
486 if (rfapiRaddr2Qprefix(&irfd
->vn_addr
, &nhp
))
489 *iap
= nhp
.u
.prefix4
;
491 vnc_zlog_debug_verbose(
492 "%s: ipadr: (%p)<-0x%x, ptr: (%p)<-%p",
493 __func__
, iap
, nhp
.u
.prefix4
.s_addr
, v
, iap
);
500 } else if (family
== AF_INET6
) {
505 XCALLOC(MTYPE_TMP
, nve_count
* sizeof(struct in6_addr
));
507 *nhp_ary_ret
= XCALLOC(MTYPE_TMP
,
508 nve_count
* sizeof(struct in6_addr
*));
510 for (ln
= listhead(nve_list
); ln
; ln
= listnextnode(ln
)) {
512 struct rfapi_descriptor
*irfd
;
513 struct in6_addr
*iap
= *nh_ary_ret
;
514 struct in6_addr
**v
= *nhp_ary_ret
;
517 irfd
= listgetdata(ln
);
519 if (rfapiRaddr2Qprefix(&irfd
->vn_addr
, &nhp
))
522 *iap
= nhp
.u
.prefix6
;
532 static void import_table_to_nve_list_zebra(struct bgp
*bgp
,
533 struct rfapi_import_table
*it
,
534 struct list
**nves
, uint8_t family
)
536 struct listnode
*node
;
537 struct rfapi_rfg_name
*rfgn
;
540 * Loop over the list of NVE-Groups configured for
541 * exporting to direct-bgp.
543 * Build a list of NVEs that use this import table
546 for (ALL_LIST_ELEMENTS_RO(bgp
->rfapi_cfg
->rfg_export_zebra_l
, node
,
550 * If this NVE-Group's import table matches the current one
552 if (rfgn
->rfg
&& rfgn
->rfg
->nves
553 && rfgn
->rfg
->rfapi_import_table
== it
) {
555 nve_group_to_nve_list(rfgn
->rfg
, nves
, family
);
560 static void vnc_zebra_add_del_prefix(struct bgp
*bgp
,
561 struct rfapi_import_table
*import_table
,
563 int add
) /* !0 = add, 0 = del */
567 unsigned int nexthop_count
= 0;
569 void *nhp_ary
= NULL
;
571 vnc_zlog_debug_verbose("%s: entry, add=%d", __func__
, add
);
573 if (zclient_vnc
->sock
< 0)
576 if (rn
->p
.family
!= AF_INET
&& rn
->p
.family
!= AF_INET6
) {
577 flog_err(EC_LIB_DEVELOPMENT
,
578 "%s: invalid route node addr family", __func__
);
582 if (!vrf_bitmap_check(zclient_vnc
->redist
[family2afi(rn
->p
.family
)]
587 if (!bgp
->rfapi_cfg
) {
588 vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping",
592 if (!listcount(bgp
->rfapi_cfg
->rfg_export_zebra_l
)) {
593 vnc_zlog_debug_verbose(
594 "%s: no zebra export nve group, skipping", __func__
);
598 import_table_to_nve_list_zebra(bgp
, import_table
, &nves
, rn
->p
.family
);
601 nve_list_to_nh_array(rn
->p
.family
, nves
, &nexthop_count
,
607 vnc_zebra_route_msg(&rn
->p
, nexthop_count
, nhp_ary
,
612 XFREE(MTYPE_TMP
, nhp_ary
);
614 XFREE(MTYPE_TMP
, nh_ary
);
617 void vnc_zebra_add_prefix(struct bgp
*bgp
,
618 struct rfapi_import_table
*import_table
,
621 vnc_zebra_add_del_prefix(bgp
, import_table
, rn
, 1);
624 void vnc_zebra_del_prefix(struct bgp
*bgp
,
625 struct rfapi_import_table
*import_table
,
628 vnc_zebra_add_del_prefix(bgp
, import_table
, rn
, 0);
632 static void vnc_zebra_add_del_nve(struct bgp
*bgp
, struct rfapi_descriptor
*rfd
,
633 int add
) /* 0 = del, !0 = add */
635 struct listnode
*node
;
636 struct rfapi_rfg_name
*rfgn
;
637 struct rfapi_nve_group_cfg
*rfg
= rfd
->rfg
;
638 afi_t afi
= family2afi(rfd
->vn_addr
.addr_family
);
640 // struct prefix *nhpp;
643 vnc_zlog_debug_verbose("%s: entry, add=%d", __func__
, add
);
645 if (zclient_vnc
->sock
< 0)
648 if (!vrf_bitmap_check(zclient_vnc
->redist
[afi
][ZEBRA_ROUTE_VNC
],
652 if (afi
!= AFI_IP
&& afi
!= AFI_IP6
) {
653 flog_err(EC_LIB_DEVELOPMENT
, "%s: invalid vn addr family",
660 if (!bgp
->rfapi_cfg
) {
661 vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping",
666 if (rfapiRaddr2Qprefix(&rfd
->vn_addr
, &nhp
)) {
667 vnc_zlog_debug_verbose("%s: can't convert vn address, skipping",
672 pAddr
= &nhp
.u
.prefix4
;
675 * Loop over the list of NVE-Groups configured for
676 * exporting to zebra and see if this new NVE's
677 * group is among them.
679 for (ALL_LIST_ELEMENTS_RO(bgp
->rfapi_cfg
->rfg_export_zebra_l
, node
,
683 * Yes, this NVE's group is configured for export to zebra
685 if (rfgn
->rfg
== rfg
) {
687 struct agg_table
*rt
= NULL
;
689 struct rfapi_import_table
*import_table
;
690 import_table
= rfg
->rfapi_import_table
;
692 vnc_zlog_debug_verbose(
693 "%s: this nve's group is in zebra export list",
696 rt
= import_table
->imported_vpn
[afi
];
699 * Walk the NVE-Group's VNC Import table
701 for (rn
= agg_route_top(rt
); rn
;
702 rn
= agg_route_next(rn
)) {
706 vnc_zlog_debug_verbose(
707 "%s: sending %s", __func__
,
708 (add
? "add" : "del"));
709 vnc_zebra_route_msg(&rn
->p
, 1, &pAddr
,
717 void vnc_zebra_add_nve(struct bgp
*bgp
, struct rfapi_descriptor
*rfd
)
719 vnc_zebra_add_del_nve(bgp
, rfd
, 1);
722 void vnc_zebra_del_nve(struct bgp
*bgp
, struct rfapi_descriptor
*rfd
)
724 vnc_zebra_add_del_nve(bgp
, rfd
, 0);
727 static void vnc_zebra_add_del_group_afi(struct bgp
*bgp
,
728 struct rfapi_nve_group_cfg
*rfg
,
731 struct agg_table
*rt
= NULL
;
733 struct rfapi_import_table
*import_table
;
734 uint8_t family
= afi2family(afi
);
736 struct list
*nves
= NULL
;
737 unsigned int nexthop_count
= 0;
739 void *nhp_ary
= NULL
;
741 vnc_zlog_debug_verbose("%s: entry", __func__
);
742 import_table
= rfg
->rfapi_import_table
;
744 vnc_zlog_debug_verbose(
745 "%s: import table not defined, returning", __func__
);
749 if (afi
== AFI_IP
|| afi
== AFI_IP6
) {
750 rt
= import_table
->imported_vpn
[afi
];
752 flog_err(EC_LIB_DEVELOPMENT
, "%s: bad afi %d", __func__
, afi
);
757 flog_err(EC_LIB_DEVELOPMENT
, "%s: computed bad family: %d",
763 /* avoid segfault below if list doesn't exist */
764 vnc_zlog_debug_verbose("%s: no NVEs in this group", __func__
);
768 nve_group_to_nve_list(rfg
, &nves
, family
);
770 vnc_zlog_debug_verbose("%s: have nves", __func__
);
771 nve_list_to_nh_array(family
, nves
, &nexthop_count
, &nh_ary
,
774 vnc_zlog_debug_verbose("%s: family: %d, nve count: %d",
775 __func__
, family
, nexthop_count
);
781 * Walk the NVE-Group's VNC Import table
783 for (rn
= agg_route_top(rt
); rn
;
784 rn
= agg_route_next(rn
)) {
786 vnc_zebra_route_msg(&rn
->p
,
793 XFREE(MTYPE_TMP
, nhp_ary
);
795 XFREE(MTYPE_TMP
, nh_ary
);
799 void vnc_zebra_add_group(struct bgp
*bgp
, struct rfapi_nve_group_cfg
*rfg
)
801 vnc_zebra_add_del_group_afi(bgp
, rfg
, AFI_IP
, 1);
802 vnc_zebra_add_del_group_afi(bgp
, rfg
, AFI_IP6
, 1);
805 void vnc_zebra_del_group(struct bgp
*bgp
, struct rfapi_nve_group_cfg
*rfg
)
807 vnc_zlog_debug_verbose("%s: entry", __func__
);
808 vnc_zebra_add_del_group_afi(bgp
, rfg
, AFI_IP
, 0);
809 vnc_zebra_add_del_group_afi(bgp
, rfg
, AFI_IP6
, 0);
812 void vnc_zebra_reexport_group_afi(struct bgp
*bgp
,
813 struct rfapi_nve_group_cfg
*rfg
, afi_t afi
)
815 struct listnode
*node
;
816 struct rfapi_rfg_name
*rfgn
;
818 for (ALL_LIST_ELEMENTS_RO(bgp
->rfapi_cfg
->rfg_export_zebra_l
, node
,
821 if (rfgn
->rfg
== rfg
) {
822 vnc_zebra_add_del_group_afi(bgp
, rfg
, afi
, 0);
823 vnc_zebra_add_del_group_afi(bgp
, rfg
, afi
, 1);
830 /***********************************************************************
832 ***********************************************************************/
835 /* Other routes redistribution into BGP. */
836 int vnc_redistribute_set(struct bgp
*bgp
, afi_t afi
, int type
)
838 if (!bgp
->rfapi_cfg
) {
839 return CMD_WARNING_CONFIG_FAILED
;
842 /* Set flag to BGP instance. */
843 bgp
->rfapi_cfg
->redist
[afi
][type
] = 1;
845 // bgp->redist[afi][type] = 1;
847 /* Return if already redistribute flag is set. */
848 if (vrf_bitmap_check(zclient_vnc
->redist
[afi
][type
], VRF_DEFAULT
))
849 return CMD_WARNING_CONFIG_FAILED
;
851 vrf_bitmap_set(zclient_vnc
->redist
[afi
][type
], VRF_DEFAULT
);
853 // vrf_bitmap_set(zclient_vnc->redist[afi][type], VRF_DEFAULT);
855 /* Return if zebra connection is not established. */
856 if (zclient_vnc
->sock
< 0)
857 return CMD_WARNING_CONFIG_FAILED
;
859 if (BGP_DEBUG(zebra
, ZEBRA
))
860 vnc_zlog_debug_verbose("Zebra send: redistribute add %s",
861 zebra_route_string(type
));
863 /* Send distribute add message to zebra. */
864 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD
, zclient_vnc
, afi
, type
,
870 /* Unset redistribution. */
871 int vnc_redistribute_unset(struct bgp
*bgp
, afi_t afi
, int type
)
873 vnc_zlog_debug_verbose("%s: type=%d entry", __func__
, type
);
875 if (!bgp
->rfapi_cfg
) {
876 vnc_zlog_debug_verbose("%s: return (no rfapi_cfg)", __func__
);
877 return CMD_WARNING_CONFIG_FAILED
;
880 /* Unset flag from BGP instance. */
881 bgp
->rfapi_cfg
->redist
[afi
][type
] = 0;
883 /* Return if zebra connection is disabled. */
884 if (!vrf_bitmap_check(zclient_vnc
->redist
[afi
][type
], VRF_DEFAULT
))
885 return CMD_WARNING_CONFIG_FAILED
;
886 vrf_bitmap_unset(zclient_vnc
->redist
[afi
][type
], VRF_DEFAULT
);
888 if (bgp
->rfapi_cfg
->redist
[AFI_IP
][type
] == 0
889 && bgp
->rfapi_cfg
->redist
[AFI_IP6
][type
] == 0
890 && zclient_vnc
->sock
>= 0) {
891 /* Send distribute delete message to zebra. */
892 if (BGP_DEBUG(zebra
, ZEBRA
))
893 vnc_zlog_debug_verbose(
894 "Zebra send: redistribute delete %s",
895 zebra_route_string(type
));
896 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE
, zclient_vnc
,
897 afi
, type
, 0, VRF_DEFAULT
);
900 /* Withdraw redistributed routes from current BGP's routing table. */
901 vnc_redistribute_withdraw(bgp
, afi
, type
);
903 vnc_zlog_debug_verbose("%s: return", __func__
);
908 extern struct zebra_privs_t bgpd_privs
;
911 * Modeled after bgp_zebra.c'bgp_zebra_init()
912 * Charriere asks, "Is it possible to carry two?"
914 void vnc_zebra_init(struct thread_master
*master
)
916 /* Set default values. */
917 zclient_vnc
= zclient_new(master
, &zclient_options_default
);
918 zclient_init(zclient_vnc
, ZEBRA_ROUTE_VNC
, 0, &bgpd_privs
);
920 zclient_vnc
->redistribute_route_add
= vnc_zebra_read_route
;
921 zclient_vnc
->redistribute_route_del
= vnc_zebra_read_route
;
924 void vnc_zebra_destroy(void)
926 if (zclient_vnc
== NULL
)
928 zclient_stop(zclient_vnc
);
929 zclient_free(zclient_vnc
);