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/memory.h"
35 #include "bgpd/bgpd.h"
36 #include "bgpd/bgp_ecommunity.h"
37 #include "bgpd/bgp_route.h"
38 #include "bgpd/bgp_debug.h"
39 #include "bgpd/bgp_advertise.h"
41 #include "bgpd/rfapi/bgp_rfapi_cfg.h"
42 #include "bgpd/rfapi/rfapi.h"
43 #include "bgpd/rfapi/rfapi_import.h"
44 #include "bgpd/rfapi/rfapi_private.h"
45 #include "bgpd/rfapi/vnc_zebra.h"
46 #include "bgpd/rfapi/rfapi_vty.h"
47 #include "bgpd/rfapi/rfapi_backend.h"
48 #include "bgpd/rfapi/vnc_debug.h"
50 static struct rfapi_descriptor vncHD1VR
; /* Single-VR export dummy nve descr */
51 static struct zclient
*zclient_vnc
= NULL
;
53 /***********************************************************************
54 * REDISTRIBUTE: Zebra sends updates/withdraws to BGPD
55 ***********************************************************************/
58 * Routes coming from zebra get added to VNC here
60 static void vnc_redistribute_add(struct prefix
*p
, u_int32_t metric
,
63 struct bgp
*bgp
= bgp_get_default();
65 struct rfapi_ip_addr vnaddr
;
68 rfp_cost_to_localpref(metric
> 255 ? 255 : metric
);
73 if (!bgp
->rfapi_cfg
) {
74 vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping",
79 afi
= family2afi(p
->family
);
81 vnc_zlog_debug_verbose("%s: unknown prefix address family %d",
86 if (!bgp
->rfapi_cfg
->redist
[afi
][type
]) {
87 vnc_zlog_debug_verbose(
88 "%s: bgp->rfapi_cfg->redist[afi=%d][type=%d] is 0, skipping",
92 if (!bgp
->rfapi_cfg
->rfg_redist
) {
93 vnc_zlog_debug_verbose("%s: no redist nve group, skipping",
99 * Assume nve group's configured VN address prefix is a host
100 * route which also happens to give the NVE VN address to use
101 * for redistributing into VNC.
103 vnaddr
.addr_family
= bgp
->rfapi_cfg
->rfg_redist
->vn_prefix
.family
;
104 switch (bgp
->rfapi_cfg
->rfg_redist
->vn_prefix
.family
) {
106 if (bgp
->rfapi_cfg
->rfg_redist
->vn_prefix
.prefixlen
!= 32) {
107 vnc_zlog_debug_verbose(
108 "%s: redist nve group VN prefix len (%d) != 32, skipping",
110 bgp
->rfapi_cfg
->rfg_redist
->vn_prefix
115 bgp
->rfapi_cfg
->rfg_redist
->vn_prefix
.u
.prefix4
;
118 if (bgp
->rfapi_cfg
->rfg_redist
->vn_prefix
.prefixlen
!= 128) {
119 vnc_zlog_debug_verbose(
120 "%s: redist nve group VN prefix len (%d) != 128, skipping",
122 bgp
->rfapi_cfg
->rfg_redist
->vn_prefix
127 bgp
->rfapi_cfg
->rfg_redist
->vn_prefix
.u
.prefix6
;
130 vnc_zlog_debug_verbose(
131 "%s: no redist nve group VN host prefix configured, skipping",
137 * Assume nve group's configured UN address prefix is a host
138 * route which also happens to give the NVE UN address to use
139 * for redistributing into VNC.
143 * Set UN address in dummy nve descriptor so add_vnc_route
144 * can use it in VNC tunnel SubTLV
147 struct rfapi_ip_prefix pfx_un
;
149 rfapiQprefix2Rprefix(&bgp
->rfapi_cfg
->rfg_redist
->un_prefix
,
152 switch (pfx_un
.prefix
.addr_family
) {
154 if (pfx_un
.length
!= 32) {
155 vnc_zlog_debug_verbose(
156 "%s: redist nve group UN prefix len (%d) != 32, skipping",
157 __func__
, pfx_un
.length
);
162 if (pfx_un
.length
!= 128) {
163 vnc_zlog_debug_verbose(
164 "%s: redist nve group UN prefix len (%d) != 128, skipping",
165 __func__
, pfx_un
.length
);
170 vnc_zlog_debug_verbose(
171 "%s: no redist nve group UN host prefix configured, skipping",
176 vncHD1VR
.un_addr
= pfx_un
.prefix
;
178 if (!vncHD1VR
.peer
) {
180 * Same setup as in rfapi_open()
182 vncHD1VR
.peer
= peer_new(bgp
);
183 vncHD1VR
.peer
->status
=
184 Established
; /* keep bgp core happy */
185 bgp_sync_delete(vncHD1VR
.peer
); /* don't need these */
186 if (vncHD1VR
.peer
->ibuf
) {
187 stream_free(vncHD1VR
.peer
188 ->ibuf
); /* don't need it */
189 vncHD1VR
.peer
->ibuf
= NULL
;
191 if (vncHD1VR
.peer
->obuf
) {
194 ->obuf
); /* don't need it */
195 vncHD1VR
.peer
->obuf
= NULL
;
197 if (vncHD1VR
.peer
->work
) {
198 stream_free(vncHD1VR
.peer
199 ->work
); /* don't need it */
200 vncHD1VR
.peer
->work
= NULL
;
202 /* base code assumes have valid host pointer */
203 vncHD1VR
.peer
->host
=
204 XSTRDUP(MTYPE_BGP_PEER_HOST
, ".zebra.");
206 /* Mark peer as belonging to HD */
207 SET_FLAG(vncHD1VR
.peer
->flags
, PEER_FLAG_IS_RFAPI_HD
);
211 memset(&prd
, 0, sizeof(prd
));
212 prd
= bgp
->rfapi_cfg
->rfg_redist
->rd
;
213 prd
.family
= AF_UNSPEC
;
216 add_vnc_route(&vncHD1VR
, /* cookie + UN addr */
217 bgp
, SAFI_MPLS_VPN
, p
, &prd
, &vnaddr
, &local_pref
,
218 &(bgp
->rfapi_cfg
->redist_lifetime
),
219 NULL
, /* RFP options */
220 NULL
, /* struct rfapi_un_option */
221 NULL
, /* struct rfapi_vn_option */
222 bgp
->rfapi_cfg
->rfg_redist
->rt_export_list
, NULL
,
223 NULL
, /* label: default */
224 type
, BGP_ROUTE_REDISTRIBUTE
, 0); /* flags */
228 * Route deletions from zebra propagate to VNC here
230 static void vnc_redistribute_delete(struct prefix
*p
, uint8_t type
)
232 struct bgp
*bgp
= bgp_get_default();
233 struct prefix_rd prd
;
239 if (!bgp
->rfapi_cfg
) {
240 vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping",
244 afi
= family2afi(p
->family
);
246 vnc_zlog_debug_verbose("%s: unknown prefix address family %d",
247 __func__
, p
->family
);
250 if (!bgp
->rfapi_cfg
->redist
[afi
][type
]) {
251 vnc_zlog_debug_verbose(
252 "%s: bgp->rfapi_cfg->redist[afi=%d][type=%d] is 0, skipping",
253 __func__
, afi
, type
);
256 if (!bgp
->rfapi_cfg
->rfg_redist
) {
257 vnc_zlog_debug_verbose("%s: no redist nve group, skipping",
262 memset(&prd
, 0, sizeof(prd
));
263 prd
= bgp
->rfapi_cfg
->rfg_redist
->rd
;
264 prd
.family
= AF_UNSPEC
;
267 del_vnc_route(&vncHD1VR
, /* use dummy ptr as cookie */
268 vncHD1VR
.peer
, bgp
, SAFI_MPLS_VPN
, p
, &prd
, type
,
269 BGP_ROUTE_REDISTRIBUTE
, NULL
, 0);
273 * Flush all redistributed routes of type <type>
275 static void vnc_redistribute_withdraw(struct bgp
*bgp
, afi_t afi
, uint8_t type
)
277 struct prefix_rd prd
;
278 struct bgp_table
*table
;
279 struct bgp_node
*prn
;
282 vnc_zlog_debug_verbose("%s: entry", __func__
);
286 if (!bgp
->rfapi_cfg
) {
287 vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping",
293 * Loop over all the RDs
295 for (prn
= bgp_table_top(bgp
->rib
[afi
][SAFI_MPLS_VPN
]); prn
;
296 prn
= bgp_route_next(prn
)) {
297 memset(&prd
, 0, sizeof(prd
));
298 prd
.family
= AF_UNSPEC
;
300 memcpy(prd
.val
, prn
->p
.u
.val
, 8);
302 /* This is the per-RD table of prefixes */
305 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
309 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
311 == type
) { /* has matching redist type */
317 &vncHD1VR
, /* use dummy ptr as cookie */
318 vncHD1VR
.peer
, bgp
, SAFI_MPLS_VPN
,
319 &(rn
->p
), &prd
, type
,
320 BGP_ROUTE_REDISTRIBUTE
, NULL
, 0);
324 vnc_zlog_debug_verbose("%s: return", __func__
);
328 * Zebra route add and delete treatment.
332 static int vnc_zebra_read_route(int command
, struct zclient
*zclient
,
333 zebra_size_t length
, vrf_id_t vrf_id
)
335 struct zapi_route api
;
338 if (zapi_route_decode(zclient
->ibuf
, &api
) < 0)
341 /* we completely ignore srcdest routes for now. */
342 if (CHECK_FLAG(api
.message
, ZAPI_MESSAGE_SRCPFX
))
345 add
= (command
== ZEBRA_REDISTRIBUTE_ROUTE_ADD
);
347 vnc_redistribute_add(&api
.prefix
, api
.metric
, api
.type
);
349 vnc_redistribute_delete(&api
.prefix
, api
.type
);
351 if (BGP_DEBUG(zebra
, ZEBRA
)) {
352 char buf
[PREFIX_STRLEN
];
354 prefix2str(&api
.prefix
, buf
, sizeof(buf
));
355 vnc_zlog_debug_verbose(
356 "%s: Zebra rcvd: route delete %s %s metric %u",
357 __func__
, zebra_route_string(api
.type
), buf
,
364 /***********************************************************************
365 * vnc_bgp_zebra_*: VNC sends updates/withdraws to Zebra
366 ***********************************************************************/
369 * low-level message builder
371 static void vnc_zebra_route_msg(struct prefix
*p
, int nhp_count
, void *nhp_ary
,
372 int add
) /* 1 = add, 0 = del */
374 struct zapi_route api
;
375 struct zapi_nexthop
*api_nh
;
379 vnc_zlog_debug_verbose("%s: empty nexthop list, skipping",
384 memset(&api
, 0, sizeof(api
));
385 api
.vrf_id
= VRF_DEFAULT
;
386 api
.type
= ZEBRA_ROUTE_VNC
;
387 api
.safi
= SAFI_UNICAST
;
391 SET_FLAG(api
.message
, ZAPI_MESSAGE_NEXTHOP
);
392 api
.nexthop_num
= nhp_count
;
393 for (i
= 0; i
< nhp_count
; i
++) {
394 struct in_addr
*nhp_ary4
;
395 struct in6_addr
*nhp_ary6
;
397 api_nh
= &api
.nexthops
[i
];
401 memcpy(&api_nh
->gate
.ipv4
, &nhp_ary4
[i
],
402 sizeof(api_nh
->gate
.ipv4
));
403 api_nh
->type
= NEXTHOP_TYPE_IPV4
;
407 memcpy(&api_nh
->gate
.ipv6
, &nhp_ary6
[i
],
408 sizeof(api_nh
->gate
.ipv6
));
409 api_nh
->type
= NEXTHOP_TYPE_IPV6
;
414 if (BGP_DEBUG(zebra
, ZEBRA
)) {
415 char buf
[PREFIX_STRLEN
];
417 prefix2str(&api
.prefix
, buf
, sizeof(buf
));
418 vnc_zlog_debug_verbose(
419 "%s: Zebra send: route %s %s, nhp_count=%d", __func__
,
420 (add
? "add" : "del"), buf
, nhp_count
);
423 zclient_route_send((add
? ZEBRA_ROUTE_ADD
: ZEBRA_ROUTE_DELETE
),
429 nve_list_to_nh_array(u_char family
, struct list
*nve_list
, int *nh_count_ret
,
430 void **nh_ary_ret
, /* returned address array */
431 void **nhp_ary_ret
) /* returned pointer array */
433 int nve_count
= listcount(nve_list
);
440 vnc_zlog_debug_verbose("%s: empty nve_list, skipping",
445 if (family
== AF_INET
) {
451 * Array of nexthop addresses
454 XCALLOC(MTYPE_TMP
, nve_count
* sizeof(struct in_addr
));
457 * Array of pointers to nexthop addresses
459 *nhp_ary_ret
= XCALLOC(MTYPE_TMP
,
460 nve_count
* sizeof(struct in_addr
*));
464 for (ln
= listhead(nve_list
); ln
; ln
= listnextnode(ln
)) {
466 struct rfapi_descriptor
*irfd
;
469 irfd
= listgetdata(ln
);
471 if (rfapiRaddr2Qprefix(&irfd
->vn_addr
, &nhp
))
474 *iap
= nhp
.u
.prefix4
;
476 vnc_zlog_debug_verbose(
477 "%s: ipadr: (%p)<-0x%x, ptr: (%p)<-%p",
478 __func__
, iap
, nhp
.u
.prefix4
.s_addr
, v
, iap
);
485 } else if (family
== AF_INET6
) {
490 XCALLOC(MTYPE_TMP
, nve_count
* sizeof(struct in6_addr
));
492 *nhp_ary_ret
= XCALLOC(MTYPE_TMP
,
493 nve_count
* sizeof(struct in6_addr
*));
495 for (ln
= listhead(nve_list
); ln
; ln
= listnextnode(ln
)) {
497 struct rfapi_descriptor
*irfd
;
498 struct in6_addr
*iap
= *nh_ary_ret
;
499 struct in6_addr
**v
= *nhp_ary_ret
;
502 irfd
= listgetdata(ln
);
504 if (rfapiRaddr2Qprefix(&irfd
->vn_addr
, &nhp
))
507 *iap
= nhp
.u
.prefix6
;
517 static void import_table_to_nve_list_zebra(struct bgp
*bgp
,
518 struct rfapi_import_table
*it
,
519 struct list
**nves
, uint8_t family
)
521 struct listnode
*node
;
522 struct rfapi_rfg_name
*rfgn
;
525 * Loop over the list of NVE-Groups configured for
526 * exporting to direct-bgp.
528 * Build a list of NVEs that use this import table
531 for (ALL_LIST_ELEMENTS_RO(bgp
->rfapi_cfg
->rfg_export_zebra_l
, node
,
535 * If this NVE-Group's import table matches the current one
537 if (rfgn
->rfg
&& rfgn
->rfg
->nves
538 && rfgn
->rfg
->rfapi_import_table
== it
) {
540 nve_group_to_nve_list(rfgn
->rfg
, nves
, family
);
545 static void vnc_zebra_add_del_prefix(struct bgp
*bgp
,
546 struct rfapi_import_table
*import_table
,
547 struct route_node
*rn
,
548 int add
) /* !0 = add, 0 = del */
552 int nexthop_count
= 0;
554 void *nhp_ary
= NULL
;
556 vnc_zlog_debug_verbose("%s: entry, add=%d", __func__
, add
);
558 if (zclient_vnc
->sock
< 0)
561 if (rn
->p
.family
!= AF_INET
&& rn
->p
.family
!= AF_INET6
) {
562 zlog_err("%s: invalid route node addr family", __func__
);
566 if (!zclient_vnc
->redist
[family2afi(rn
->p
.family
)][ZEBRA_ROUTE_VNC
])
569 if (!bgp
->rfapi_cfg
) {
570 vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping",
574 if (!listcount(bgp
->rfapi_cfg
->rfg_export_zebra_l
)) {
575 vnc_zlog_debug_verbose(
576 "%s: no zebra export nve group, skipping", __func__
);
580 import_table_to_nve_list_zebra(bgp
, import_table
, &nves
, rn
->p
.family
);
583 nve_list_to_nh_array(rn
->p
.family
, nves
, &nexthop_count
,
589 vnc_zebra_route_msg(&rn
->p
, nexthop_count
, nhp_ary
,
594 XFREE(MTYPE_TMP
, nhp_ary
);
596 XFREE(MTYPE_TMP
, nh_ary
);
599 void vnc_zebra_add_prefix(struct bgp
*bgp
,
600 struct rfapi_import_table
*import_table
,
601 struct route_node
*rn
)
603 vnc_zebra_add_del_prefix(bgp
, import_table
, rn
, 1);
606 void vnc_zebra_del_prefix(struct bgp
*bgp
,
607 struct rfapi_import_table
*import_table
,
608 struct route_node
*rn
)
610 vnc_zebra_add_del_prefix(bgp
, import_table
, rn
, 0);
614 static void vnc_zebra_add_del_nve(struct bgp
*bgp
, struct rfapi_descriptor
*rfd
,
615 int add
) /* 0 = del, !0 = add */
617 struct listnode
*node
;
618 struct rfapi_rfg_name
*rfgn
;
619 struct rfapi_nve_group_cfg
*rfg
= rfd
->rfg
;
620 afi_t afi
= family2afi(rfd
->vn_addr
.addr_family
);
622 // struct prefix *nhpp;
625 vnc_zlog_debug_verbose("%s: entry, add=%d", __func__
, add
);
627 if (zclient_vnc
->sock
< 0)
630 if (!zclient_vnc
->redist
[afi
][ZEBRA_ROUTE_VNC
])
633 if (afi
!= AFI_IP
&& afi
!= AFI_IP6
) {
634 zlog_err("%s: invalid vn addr family", __func__
);
640 if (!bgp
->rfapi_cfg
) {
641 vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping",
646 if (rfapiRaddr2Qprefix(&rfd
->vn_addr
, &nhp
)) {
647 vnc_zlog_debug_verbose("%s: can't convert vn address, skipping",
652 pAddr
= &nhp
.u
.prefix4
;
655 * Loop over the list of NVE-Groups configured for
656 * exporting to zebra and see if this new NVE's
657 * group is among them.
659 for (ALL_LIST_ELEMENTS_RO(bgp
->rfapi_cfg
->rfg_export_zebra_l
, node
,
663 * Yes, this NVE's group is configured for export to zebra
665 if (rfgn
->rfg
== rfg
) {
667 struct route_table
*rt
= NULL
;
668 struct route_node
*rn
;
669 struct rfapi_import_table
*import_table
;
670 import_table
= rfg
->rfapi_import_table
;
672 vnc_zlog_debug_verbose(
673 "%s: this nve's group is in zebra export list",
676 rt
= import_table
->imported_vpn
[afi
];
679 * Walk the NVE-Group's VNC Import table
681 for (rn
= route_top(rt
); rn
; rn
= route_next(rn
)) {
685 vnc_zlog_debug_verbose(
686 "%s: sending %s", __func__
,
687 (add
? "add" : "del"));
688 vnc_zebra_route_msg(&rn
->p
, 1, &pAddr
,
696 void vnc_zebra_add_nve(struct bgp
*bgp
, struct rfapi_descriptor
*rfd
)
698 vnc_zebra_add_del_nve(bgp
, rfd
, 1);
701 void vnc_zebra_del_nve(struct bgp
*bgp
, struct rfapi_descriptor
*rfd
)
703 vnc_zebra_add_del_nve(bgp
, rfd
, 0);
706 static void vnc_zebra_add_del_group_afi(struct bgp
*bgp
,
707 struct rfapi_nve_group_cfg
*rfg
,
710 struct route_table
*rt
= NULL
;
711 struct route_node
*rn
;
712 struct rfapi_import_table
*import_table
;
713 uint8_t family
= afi2family(afi
);
715 struct list
*nves
= NULL
;
716 int nexthop_count
= 0;
718 void *nhp_ary
= NULL
;
720 vnc_zlog_debug_verbose("%s: entry", __func__
);
721 import_table
= rfg
->rfapi_import_table
;
723 vnc_zlog_debug_verbose(
724 "%s: import table not defined, returning", __func__
);
728 if (afi
== AFI_IP
|| afi
== AFI_IP6
) {
729 rt
= import_table
->imported_vpn
[afi
];
731 zlog_err("%s: bad afi %d", __func__
, afi
);
736 zlog_err("%s: computed bad family: %d", __func__
, family
);
741 /* avoid segfault below if list doesn't exist */
742 vnc_zlog_debug_verbose("%s: no NVEs in this group", __func__
);
746 nve_group_to_nve_list(rfg
, &nves
, family
);
748 vnc_zlog_debug_verbose("%s: have nves", __func__
);
749 nve_list_to_nh_array(family
, nves
, &nexthop_count
, &nh_ary
,
752 vnc_zlog_debug_verbose("%s: family: %d, nve count: %d",
753 __func__
, family
, nexthop_count
);
759 * Walk the NVE-Group's VNC Import table
761 for (rn
= route_top(rt
); rn
; rn
= route_next(rn
)) {
763 vnc_zebra_route_msg(&rn
->p
,
770 XFREE(MTYPE_TMP
, nhp_ary
);
772 XFREE(MTYPE_TMP
, nh_ary
);
776 void vnc_zebra_add_group(struct bgp
*bgp
, struct rfapi_nve_group_cfg
*rfg
)
778 vnc_zebra_add_del_group_afi(bgp
, rfg
, AFI_IP
, 1);
779 vnc_zebra_add_del_group_afi(bgp
, rfg
, AFI_IP6
, 1);
782 void vnc_zebra_del_group(struct bgp
*bgp
, struct rfapi_nve_group_cfg
*rfg
)
784 vnc_zlog_debug_verbose("%s: entry", __func__
);
785 vnc_zebra_add_del_group_afi(bgp
, rfg
, AFI_IP
, 0);
786 vnc_zebra_add_del_group_afi(bgp
, rfg
, AFI_IP6
, 0);
789 void vnc_zebra_reexport_group_afi(struct bgp
*bgp
,
790 struct rfapi_nve_group_cfg
*rfg
, afi_t afi
)
792 struct listnode
*node
;
793 struct rfapi_rfg_name
*rfgn
;
795 for (ALL_LIST_ELEMENTS_RO(bgp
->rfapi_cfg
->rfg_export_zebra_l
, node
,
798 if (rfgn
->rfg
== rfg
) {
799 vnc_zebra_add_del_group_afi(bgp
, rfg
, afi
, 0);
800 vnc_zebra_add_del_group_afi(bgp
, rfg
, afi
, 1);
807 /***********************************************************************
809 ***********************************************************************/
812 /* Other routes redistribution into BGP. */
813 int vnc_redistribute_set(struct bgp
*bgp
, afi_t afi
, int type
)
815 if (!bgp
->rfapi_cfg
) {
816 return CMD_WARNING_CONFIG_FAILED
;
819 /* Set flag to BGP instance. */
820 bgp
->rfapi_cfg
->redist
[afi
][type
] = 1;
822 // bgp->redist[afi][type] = 1;
824 /* Return if already redistribute flag is set. */
825 if (zclient_vnc
->redist
[afi
][type
])
826 return CMD_WARNING_CONFIG_FAILED
;
828 vrf_bitmap_set(zclient_vnc
->redist
[afi
][type
], VRF_DEFAULT
);
830 // zclient_vnc->redist[afi][type] = 1;
832 /* Return if zebra connection is not established. */
833 if (zclient_vnc
->sock
< 0)
834 return CMD_WARNING_CONFIG_FAILED
;
836 if (BGP_DEBUG(zebra
, ZEBRA
))
837 vnc_zlog_debug_verbose("Zebra send: redistribute add %s",
838 zebra_route_string(type
));
840 /* Send distribute add message to zebra. */
841 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD
, zclient_vnc
, afi
, type
,
847 /* Unset redistribution. */
848 int vnc_redistribute_unset(struct bgp
*bgp
, afi_t afi
, int type
)
850 vnc_zlog_debug_verbose("%s: type=%d entry", __func__
, type
);
852 if (!bgp
->rfapi_cfg
) {
853 vnc_zlog_debug_verbose("%s: return (no rfapi_cfg)", __func__
);
854 return CMD_WARNING_CONFIG_FAILED
;
857 /* Unset flag from BGP instance. */
858 bgp
->rfapi_cfg
->redist
[afi
][type
] = 0;
860 /* Return if zebra connection is disabled. */
861 if (!zclient_vnc
->redist
[afi
][type
])
862 return CMD_WARNING_CONFIG_FAILED
;
863 zclient_vnc
->redist
[afi
][type
] = 0;
865 if (bgp
->rfapi_cfg
->redist
[AFI_IP
][type
] == 0
866 && bgp
->rfapi_cfg
->redist
[AFI_IP6
][type
] == 0
867 && zclient_vnc
->sock
>= 0) {
868 /* Send distribute delete message to zebra. */
869 if (BGP_DEBUG(zebra
, ZEBRA
))
870 vnc_zlog_debug_verbose(
871 "Zebra send: redistribute delete %s",
872 zebra_route_string(type
));
873 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE
, zclient_vnc
,
874 afi
, type
, 0, VRF_DEFAULT
);
877 /* Withdraw redistributed routes from current BGP's routing table. */
878 vnc_redistribute_withdraw(bgp
, afi
, type
);
880 vnc_zlog_debug_verbose("%s: return", __func__
);
887 * Modeled after bgp_zebra.c'bgp_zebra_init()
888 * Charriere asks, "Is it possible to carry two?"
890 void vnc_zebra_init(struct thread_master
*master
)
892 /* Set default values. */
893 zclient_vnc
= zclient_new(master
);
894 zclient_init(zclient_vnc
, ZEBRA_ROUTE_VNC
, 0);
896 zclient_vnc
->redistribute_route_add
= vnc_zebra_read_route
;
897 zclient_vnc
->redistribute_route_del
= vnc_zebra_read_route
;
900 void vnc_zebra_destroy(void)
902 if (zclient_vnc
== NULL
)
904 zclient_stop(zclient_vnc
);
905 zclient_free(zclient_vnc
);