Line data Source code
1 : /* zebra client
2 : * Copyright (C) 1997, 98, 99 Kunihiro Ishiguro
3 : *
4 : * This file is part of GNU Zebra.
5 : *
6 : * GNU Zebra is free software; you can redistribute it and/or modify it
7 : * under the terms of the GNU General Public License as published by the
8 : * Free Software Foundation; either version 2, or (at your option) any
9 : * later version.
10 : *
11 : * GNU Zebra is distributed in the hope that it will be useful, but
12 : * WITHOUT ANY WARRANTY; without even the implied warranty of
13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : * General Public License for more details.
15 : *
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
19 : */
20 :
21 : #include <zebra.h>
22 :
23 : #include "command.h"
24 : #include "stream.h"
25 : #include "network.h"
26 : #include "prefix.h"
27 : #include "log.h"
28 : #include "sockunion.h"
29 : #include "zclient.h"
30 : #include "routemap.h"
31 : #include "thread.h"
32 : #include "queue.h"
33 : #include "memory.h"
34 : #include "lib/json.h"
35 : #include "lib/bfd.h"
36 : #include "lib/route_opaque.h"
37 : #include "filter.h"
38 : #include "mpls.h"
39 : #include "vxlan.h"
40 : #include "pbr.h"
41 :
42 : #include "bgpd/bgpd.h"
43 : #include "bgpd/bgp_route.h"
44 : #include "bgpd/bgp_attr.h"
45 : #include "bgpd/bgp_aspath.h"
46 : #include "bgpd/bgp_nexthop.h"
47 : #include "bgpd/bgp_zebra.h"
48 : #include "bgpd/bgp_fsm.h"
49 : #include "bgpd/bgp_debug.h"
50 : #include "bgpd/bgp_errors.h"
51 : #include "bgpd/bgp_mpath.h"
52 : #include "bgpd/bgp_nexthop.h"
53 : #include "bgpd/bgp_nht.h"
54 : #include "bgpd/bgp_bfd.h"
55 : #include "bgpd/bgp_label.h"
56 : #ifdef ENABLE_BGP_VNC
57 : #include "bgpd/rfapi/rfapi_backend.h"
58 : #include "bgpd/rfapi/vnc_export_bgp.h"
59 : #endif
60 : #include "bgpd/bgp_evpn.h"
61 : #include "bgpd/bgp_mplsvpn.h"
62 : #include "bgpd/bgp_labelpool.h"
63 : #include "bgpd/bgp_pbr.h"
64 : #include "bgpd/bgp_evpn_private.h"
65 : #include "bgpd/bgp_evpn_mh.h"
66 : #include "bgpd/bgp_mac.h"
67 : #include "bgpd/bgp_trace.h"
68 : #include "bgpd/bgp_community.h"
69 : #include "bgpd/bgp_lcommunity.h"
70 :
71 : /* All information about zebra. */
72 : struct zclient *zclient = NULL;
73 :
74 : /* hook to indicate vrf status change for SNMP */
75 471 : DEFINE_HOOK(bgp_vrf_status_changed, (struct bgp *bgp, struct interface *ifp),
76 : (bgp, ifp));
77 :
78 144 : DEFINE_MTYPE_STATIC(BGPD, BGP_IF_INFO, "BGP interface context");
79 :
80 : /* Can we install into zebra? */
81 153 : static inline bool bgp_install_info_to_zebra(struct bgp *bgp)
82 : {
83 153 : if (zclient->sock <= 0)
84 : return false;
85 :
86 153 : if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) {
87 0 : zlog_debug(
88 : "%s: No zebra instance to talk to, not installing information",
89 : __func__);
90 0 : return false;
91 : }
92 :
93 : return true;
94 : }
95 :
96 : int zclient_num_connects;
97 :
98 : /* Router-id update message from zebra. */
99 45 : static int bgp_router_id_update(ZAPI_CALLBACK_ARGS)
100 : {
101 45 : struct prefix router_id;
102 :
103 45 : zebra_router_id_update_read(zclient->ibuf, &router_id);
104 :
105 45 : if (BGP_DEBUG(zebra, ZEBRA))
106 0 : zlog_debug("Rx Router Id update VRF %u Id %pFX", vrf_id,
107 : &router_id);
108 :
109 45 : bgp_router_id_zebra_bump(vrf_id, &router_id);
110 45 : return 0;
111 : }
112 :
113 : /* Nexthop update message from zebra. */
114 60 : static int bgp_read_nexthop_update(ZAPI_CALLBACK_ARGS)
115 : {
116 60 : bgp_parse_nexthop_update(cmd, vrf_id);
117 60 : return 0;
118 : }
119 :
120 : /* Set or clear interface on which unnumbered neighbor is configured. This
121 : * would in turn cause BGP to initiate or turn off IPv6 RAs on this
122 : * interface.
123 : */
124 297 : static void bgp_update_interface_nbrs(struct bgp *bgp, struct interface *ifp,
125 : struct interface *upd_ifp)
126 : {
127 297 : struct listnode *node, *nnode;
128 297 : struct peer *peer;
129 :
130 951 : for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
131 357 : if (peer->conf_if && (strcmp(peer->conf_if, ifp->name) == 0)) {
132 0 : if (upd_ifp) {
133 0 : peer->ifp = upd_ifp;
134 0 : bgp_zebra_initiate_radv(bgp, peer);
135 : } else {
136 0 : bgp_zebra_terminate_radv(bgp, peer);
137 0 : peer->ifp = upd_ifp;
138 : }
139 : }
140 : }
141 297 : }
142 :
143 0 : static int bgp_read_fec_update(ZAPI_CALLBACK_ARGS)
144 : {
145 0 : bgp_parse_fec_update();
146 0 : return 0;
147 : }
148 :
149 0 : static void bgp_start_interface_nbrs(struct bgp *bgp, struct interface *ifp)
150 : {
151 0 : struct listnode *node, *nnode;
152 0 : struct peer *peer;
153 :
154 0 : for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
155 0 : if (peer->conf_if && (strcmp(peer->conf_if, ifp->name) == 0)
156 0 : && !peer_established(peer)) {
157 0 : if (peer_active(peer))
158 0 : BGP_EVENT_ADD(peer, BGP_Stop);
159 0 : BGP_EVENT_ADD(peer, BGP_Start);
160 : }
161 : }
162 0 : }
163 :
164 0 : static void bgp_nbr_connected_add(struct bgp *bgp, struct nbr_connected *ifc)
165 : {
166 0 : struct listnode *node;
167 0 : struct connected *connected;
168 0 : struct interface *ifp;
169 0 : struct prefix *p;
170 :
171 : /* Kick-off the FSM for any relevant peers only if there is a
172 : * valid local address on the interface.
173 : */
174 0 : ifp = ifc->ifp;
175 0 : for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected)) {
176 0 : p = connected->address;
177 0 : if (p->family == AF_INET6
178 0 : && IN6_IS_ADDR_LINKLOCAL(&p->u.prefix6))
179 : break;
180 : }
181 0 : if (!connected)
182 : return;
183 :
184 0 : bgp_start_interface_nbrs(bgp, ifp);
185 : }
186 :
187 0 : static void bgp_nbr_connected_delete(struct bgp *bgp, struct nbr_connected *ifc,
188 : int del)
189 : {
190 0 : struct listnode *node, *nnode;
191 0 : struct peer *peer;
192 0 : struct interface *ifp;
193 :
194 0 : for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
195 0 : if (peer->conf_if
196 0 : && (strcmp(peer->conf_if, ifc->ifp->name) == 0)) {
197 0 : peer->last_reset = PEER_DOWN_NBR_ADDR_DEL;
198 0 : BGP_EVENT_ADD(peer, BGP_Stop);
199 : }
200 : }
201 : /* Free neighbor also, if we're asked to. */
202 0 : if (del) {
203 0 : ifp = ifc->ifp;
204 0 : listnode_delete(ifp->nbr_connected, ifc);
205 0 : nbr_connected_free(ifc);
206 : }
207 0 : }
208 :
209 2 : static int bgp_ifp_destroy(struct interface *ifp)
210 : {
211 2 : struct bgp *bgp;
212 :
213 2 : bgp = ifp->vrf->info;
214 :
215 2 : if (BGP_DEBUG(zebra, ZEBRA))
216 0 : zlog_debug("Rx Intf del VRF %u IF %s", ifp->vrf->vrf_id,
217 : ifp->name);
218 :
219 2 : if (bgp) {
220 2 : bgp_update_interface_nbrs(bgp, ifp, NULL);
221 2 : hook_call(bgp_vrf_status_changed, bgp, ifp);
222 : }
223 :
224 2 : bgp_mac_del_mac_entry(ifp);
225 :
226 2 : return 0;
227 : }
228 :
229 114 : static int bgp_ifp_up(struct interface *ifp)
230 : {
231 114 : struct connected *c;
232 114 : struct nbr_connected *nc;
233 114 : struct listnode *node, *nnode;
234 114 : struct bgp *bgp;
235 :
236 114 : bgp = ifp->vrf->info;
237 :
238 114 : bgp_mac_add_mac_entry(ifp);
239 :
240 114 : if (BGP_DEBUG(zebra, ZEBRA))
241 0 : zlog_debug("Rx Intf up VRF %u IF %s", ifp->vrf->vrf_id,
242 : ifp->name);
243 :
244 114 : if (!bgp)
245 : return 0;
246 :
247 304 : for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, c))
248 88 : bgp_connected_add(bgp, c);
249 :
250 216 : for (ALL_LIST_ELEMENTS(ifp->nbr_connected, node, nnode, nc))
251 0 : bgp_nbr_connected_add(bgp, nc);
252 :
253 108 : hook_call(bgp_vrf_status_changed, bgp, ifp);
254 108 : bgp_nht_ifp_up(ifp);
255 :
256 108 : return 0;
257 : }
258 :
259 70 : static int bgp_ifp_down(struct interface *ifp)
260 : {
261 70 : struct connected *c;
262 70 : struct nbr_connected *nc;
263 70 : struct listnode *node, *nnode;
264 70 : struct bgp *bgp;
265 70 : struct peer *peer;
266 :
267 70 : bgp = ifp->vrf->info;
268 :
269 70 : bgp_mac_del_mac_entry(ifp);
270 :
271 70 : if (BGP_DEBUG(zebra, ZEBRA))
272 0 : zlog_debug("Rx Intf down VRF %u IF %s", ifp->vrf->vrf_id,
273 : ifp->name);
274 :
275 70 : if (!bgp)
276 : return 0;
277 :
278 249 : for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, c))
279 117 : bgp_connected_delete(bgp, c);
280 :
281 132 : for (ALL_LIST_ELEMENTS(ifp->nbr_connected, node, nnode, nc))
282 0 : bgp_nbr_connected_delete(bgp, nc, 1);
283 :
284 : /* Fast external-failover */
285 66 : if (!CHECK_FLAG(bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER)) {
286 :
287 208 : for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
288 : /* Take down directly connected peers. */
289 76 : if ((peer->ttl != BGP_DEFAULT_TTL)
290 2 : && (peer->gtsm_hops != BGP_GTSM_HOPS_CONNECTED))
291 2 : continue;
292 :
293 74 : if (ifp == peer->nexthop.ifp) {
294 0 : BGP_EVENT_ADD(peer, BGP_Stop);
295 0 : peer->last_reset = PEER_DOWN_IF_DOWN;
296 : }
297 : }
298 : }
299 :
300 66 : hook_call(bgp_vrf_status_changed, bgp, ifp);
301 66 : bgp_nht_ifp_down(ifp);
302 :
303 66 : return 0;
304 : }
305 :
306 549 : static int bgp_interface_address_add(ZAPI_CALLBACK_ARGS)
307 : {
308 549 : struct connected *ifc;
309 549 : struct bgp *bgp;
310 549 : struct peer *peer;
311 549 : struct prefix *addr;
312 549 : struct listnode *node, *nnode;
313 549 : afi_t afi;
314 549 : safi_t safi;
315 :
316 549 : bgp = bgp_lookup_by_vrf_id(vrf_id);
317 :
318 549 : ifc = zebra_interface_address_read(cmd, zclient->ibuf, vrf_id);
319 :
320 549 : if (ifc == NULL)
321 : return 0;
322 :
323 549 : if (bgp_debug_zebra(ifc->address))
324 0 : zlog_debug("Rx Intf address add VRF %u IF %s addr %pFX", vrf_id,
325 : ifc->ifp->name, ifc->address);
326 :
327 549 : if (!bgp)
328 : return 0;
329 :
330 530 : if (if_is_operative(ifc->ifp)) {
331 498 : bgp_connected_add(bgp, ifc);
332 :
333 : /* If we have learnt of any neighbors on this interface,
334 : * check to kick off any BGP interface-based neighbors,
335 : * but only if this is a link-local address.
336 : */
337 498 : if (IN6_IS_ADDR_LINKLOCAL(&ifc->address->u.prefix6)
338 52 : && !list_isempty(ifc->ifp->nbr_connected))
339 0 : bgp_start_interface_nbrs(bgp, ifc->ifp);
340 : else {
341 498 : addr = ifc->address;
342 :
343 1584 : for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
344 588 : if (addr->family == AF_INET)
345 258 : continue;
346 :
347 : /*
348 : * If the Peer's interface name matches the
349 : * interface name for which BGP received the
350 : * update and if the received interface address
351 : * is a globalV6 and if the peer is currently
352 : * using a v4-mapped-v6 addr or a link local
353 : * address, then copy the Rxed global v6 addr
354 : * into peer's v6_global and send updates out
355 : * with new nexthop addr.
356 : */
357 330 : if ((peer->conf_if &&
358 0 : (strcmp(peer->conf_if, ifc->ifp->name) ==
359 0 : 0)) &&
360 0 : !IN6_IS_ADDR_LINKLOCAL(&addr->u.prefix6) &&
361 0 : ((IS_MAPPED_IPV6(
362 0 : &peer->nexthop.v6_global)) ||
363 0 : IN6_IS_ADDR_LINKLOCAL(
364 : &peer->nexthop.v6_global))) {
365 :
366 0 : if (bgp_debug_zebra(ifc->address)) {
367 0 : zlog_debug(
368 : "Update peer %pBP's current intf addr %pI6 and send updates",
369 : peer,
370 : &peer->nexthop
371 : .v6_global);
372 : }
373 0 : memcpy(&peer->nexthop.v6_global,
374 : &addr->u.prefix6,
375 : IPV6_MAX_BYTELEN);
376 0 : FOREACH_AFI_SAFI (afi, safi)
377 0 : bgp_announce_route(peer, afi,
378 : safi, true);
379 : }
380 : }
381 : }
382 : }
383 :
384 : return 0;
385 : }
386 :
387 66 : static int bgp_interface_address_delete(ZAPI_CALLBACK_ARGS)
388 : {
389 66 : struct listnode *node, *nnode;
390 66 : struct connected *ifc;
391 66 : struct peer *peer;
392 66 : struct bgp *bgp;
393 66 : struct prefix *addr;
394 :
395 66 : bgp = bgp_lookup_by_vrf_id(vrf_id);
396 :
397 66 : ifc = zebra_interface_address_read(cmd, zclient->ibuf, vrf_id);
398 :
399 66 : if (ifc == NULL)
400 : return 0;
401 :
402 66 : if (bgp_debug_zebra(ifc->address))
403 0 : zlog_debug("Rx Intf address del VRF %u IF %s addr %pFX", vrf_id,
404 : ifc->ifp->name, ifc->address);
405 :
406 66 : if (bgp && if_is_operative(ifc->ifp)) {
407 0 : bgp_connected_delete(bgp, ifc);
408 : }
409 :
410 66 : addr = ifc->address;
411 :
412 66 : if (bgp) {
413 : /*
414 : * When we are using the v6 global as part of the peering
415 : * nexthops and we are removing it, then we need to
416 : * clear the peer data saved for that nexthop and
417 : * cause a re-announcement of the route. Since
418 : * we do not want the peering to bounce.
419 : */
420 196 : for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
421 72 : afi_t afi;
422 72 : safi_t safi;
423 :
424 72 : if (addr->family == AF_INET)
425 36 : continue;
426 :
427 36 : if (!IN6_IS_ADDR_LINKLOCAL(&addr->u.prefix6)
428 36 : && memcmp(&peer->nexthop.v6_global,
429 36 : &addr->u.prefix6, 16)
430 : == 0) {
431 0 : memset(&peer->nexthop.v6_global, 0, 16);
432 0 : FOREACH_AFI_SAFI (afi, safi)
433 0 : bgp_announce_route(peer, afi, safi,
434 : true);
435 : }
436 : }
437 : }
438 :
439 66 : connected_free(&ifc);
440 :
441 66 : return 0;
442 : }
443 :
444 0 : static int bgp_interface_nbr_address_add(ZAPI_CALLBACK_ARGS)
445 : {
446 0 : struct nbr_connected *ifc = NULL;
447 0 : struct bgp *bgp;
448 :
449 0 : ifc = zebra_interface_nbr_address_read(cmd, zclient->ibuf, vrf_id);
450 :
451 0 : if (ifc == NULL)
452 : return 0;
453 :
454 0 : if (bgp_debug_zebra(ifc->address))
455 0 : zlog_debug("Rx Intf neighbor add VRF %u IF %s addr %pFX",
456 : vrf_id, ifc->ifp->name, ifc->address);
457 :
458 0 : if (if_is_operative(ifc->ifp)) {
459 0 : bgp = bgp_lookup_by_vrf_id(vrf_id);
460 0 : if (bgp)
461 0 : bgp_nbr_connected_add(bgp, ifc);
462 : }
463 :
464 : return 0;
465 : }
466 :
467 0 : static int bgp_interface_nbr_address_delete(ZAPI_CALLBACK_ARGS)
468 : {
469 0 : struct nbr_connected *ifc = NULL;
470 0 : struct bgp *bgp;
471 :
472 0 : ifc = zebra_interface_nbr_address_read(cmd, zclient->ibuf, vrf_id);
473 :
474 0 : if (ifc == NULL)
475 : return 0;
476 :
477 0 : if (bgp_debug_zebra(ifc->address))
478 0 : zlog_debug("Rx Intf neighbor del VRF %u IF %s addr %pFX",
479 : vrf_id, ifc->ifp->name, ifc->address);
480 :
481 0 : if (if_is_operative(ifc->ifp)) {
482 0 : bgp = bgp_lookup_by_vrf_id(vrf_id);
483 0 : if (bgp)
484 0 : bgp_nbr_connected_delete(bgp, ifc, 0);
485 : }
486 :
487 0 : nbr_connected_free(ifc);
488 :
489 0 : return 0;
490 : }
491 :
492 : /* VRF update for an interface. */
493 0 : static int bgp_interface_vrf_update(ZAPI_CALLBACK_ARGS)
494 : {
495 0 : struct interface *ifp;
496 0 : vrf_id_t new_vrf_id;
497 0 : struct connected *c;
498 0 : struct nbr_connected *nc;
499 0 : struct listnode *node, *nnode;
500 0 : struct bgp *bgp;
501 0 : struct peer *peer;
502 :
503 0 : ifp = zebra_interface_vrf_update_read(zclient->ibuf, vrf_id,
504 : &new_vrf_id);
505 0 : if (!ifp)
506 : return 0;
507 :
508 0 : if (BGP_DEBUG(zebra, ZEBRA))
509 0 : zlog_debug("Rx Intf VRF change VRF %u IF %s NewVRF %u", vrf_id,
510 : ifp->name, new_vrf_id);
511 :
512 0 : bgp = bgp_lookup_by_vrf_id(vrf_id);
513 :
514 0 : if (bgp) {
515 0 : for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, c))
516 0 : bgp_connected_delete(bgp, c);
517 :
518 0 : for (ALL_LIST_ELEMENTS(ifp->nbr_connected, node, nnode, nc))
519 0 : bgp_nbr_connected_delete(bgp, nc, 1);
520 :
521 : /* Fast external-failover */
522 0 : if (!CHECK_FLAG(bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER)) {
523 0 : for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
524 0 : if ((peer->ttl != BGP_DEFAULT_TTL)
525 0 : && (peer->gtsm_hops
526 : != BGP_GTSM_HOPS_CONNECTED))
527 0 : continue;
528 :
529 0 : if (ifp == peer->nexthop.ifp)
530 0 : BGP_EVENT_ADD(peer, BGP_Stop);
531 : }
532 : }
533 : }
534 :
535 0 : if_update_to_new_vrf(ifp, new_vrf_id);
536 :
537 0 : bgp = bgp_lookup_by_vrf_id(new_vrf_id);
538 0 : if (!bgp)
539 : return 0;
540 :
541 0 : for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, c))
542 0 : bgp_connected_add(bgp, c);
543 :
544 0 : for (ALL_LIST_ELEMENTS(ifp->nbr_connected, node, nnode, nc))
545 0 : bgp_nbr_connected_add(bgp, nc);
546 :
547 0 : hook_call(bgp_vrf_status_changed, bgp, ifp);
548 0 : return 0;
549 : }
550 :
551 : /* Zebra route add and delete treatment. */
552 93 : static int zebra_read_route(ZAPI_CALLBACK_ARGS)
553 : {
554 93 : enum nexthop_types_t nhtype;
555 93 : enum blackhole_type bhtype = BLACKHOLE_UNSPEC;
556 93 : struct zapi_route api;
557 93 : union g_addr nexthop = {};
558 93 : ifindex_t ifindex;
559 93 : int add, i;
560 93 : struct bgp *bgp;
561 :
562 93 : bgp = bgp_lookup_by_vrf_id(vrf_id);
563 93 : if (!bgp)
564 : return 0;
565 :
566 93 : if (zapi_route_decode(zclient->ibuf, &api) < 0)
567 : return -1;
568 :
569 : /* we completely ignore srcdest routes for now. */
570 93 : if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX))
571 : return 0;
572 :
573 : /* ignore link-local address. */
574 93 : if (api.prefix.family == AF_INET6
575 10 : && IN6_IS_ADDR_LINKLOCAL(&api.prefix.u.prefix6))
576 : return 0;
577 :
578 93 : ifindex = api.nexthops[0].ifindex;
579 93 : nhtype = api.nexthops[0].type;
580 :
581 : /* api_nh structure has union of gate and bh_type */
582 93 : if (nhtype == NEXTHOP_TYPE_BLACKHOLE) {
583 : /* bh_type is only applicable if NEXTHOP_TYPE_BLACKHOLE*/
584 0 : bhtype = api.nexthops[0].bh_type;
585 : } else
586 93 : nexthop = api.nexthops[0].gate;
587 :
588 93 : add = (cmd == ZEBRA_REDISTRIBUTE_ROUTE_ADD);
589 93 : if (add) {
590 : /*
591 : * The ADD message is actually an UPDATE and there is no
592 : * explicit DEL
593 : * for a prior redistributed route, if any. So, perform an
594 : * implicit
595 : * DEL processing for the same redistributed route from any
596 : * other
597 : * source type.
598 : */
599 2144 : for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
600 2077 : if (i != api.type)
601 2010 : bgp_redistribute_delete(bgp, &api.prefix, i,
602 2010 : api.instance);
603 : }
604 :
605 : /* Now perform the add/update. */
606 67 : bgp_redistribute_add(bgp, &api.prefix, &nexthop, ifindex,
607 67 : nhtype, bhtype, api.distance, api.metric,
608 67 : api.type, api.instance, api.tag);
609 : } else {
610 26 : bgp_redistribute_delete(bgp, &api.prefix, api.type,
611 26 : api.instance);
612 : }
613 :
614 93 : if (bgp_debug_zebra(&api.prefix)) {
615 0 : char buf[PREFIX_STRLEN];
616 :
617 0 : if (add) {
618 0 : inet_ntop(api.prefix.family, &nexthop, buf,
619 : sizeof(buf));
620 0 : zlog_debug(
621 : "Rx route ADD VRF %u %s[%d] %pFX nexthop %s (type %d if %u) metric %u distance %u tag %" ROUTE_TAG_PRI,
622 : vrf_id, zebra_route_string(api.type),
623 : api.instance, &api.prefix, buf, nhtype, ifindex,
624 : api.metric, api.distance, api.tag);
625 : } else {
626 0 : zlog_debug("Rx route DEL VRF %u %s[%d] %pFX", vrf_id,
627 : zebra_route_string(api.type), api.instance,
628 : &api.prefix);
629 : }
630 : }
631 :
632 : return 0;
633 : }
634 :
635 136 : struct interface *if_lookup_by_ipv4(struct in_addr *addr, vrf_id_t vrf_id)
636 : {
637 136 : struct vrf *vrf;
638 136 : struct listnode *cnode;
639 136 : struct interface *ifp;
640 136 : struct connected *connected;
641 136 : struct prefix_ipv4 p;
642 136 : struct prefix *cp;
643 :
644 136 : vrf = vrf_lookup_by_id(vrf_id);
645 136 : if (!vrf)
646 : return NULL;
647 :
648 136 : p.family = AF_INET;
649 136 : p.prefix = *addr;
650 136 : p.prefixlen = IPV4_MAX_BITLEN;
651 :
652 426 : FOR_ALL_INTERFACES (vrf, ifp) {
653 887 : for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, connected)) {
654 443 : cp = connected->address;
655 :
656 443 : if (cp->family == AF_INET)
657 285 : if (prefix_match(cp, (struct prefix *)&p))
658 136 : return ifp;
659 : }
660 : }
661 : return NULL;
662 : }
663 :
664 187 : struct interface *if_lookup_by_ipv4_exact(struct in_addr *addr, vrf_id_t vrf_id)
665 : {
666 187 : struct vrf *vrf;
667 187 : struct listnode *cnode;
668 187 : struct interface *ifp;
669 187 : struct connected *connected;
670 187 : struct prefix *cp;
671 :
672 187 : vrf = vrf_lookup_by_id(vrf_id);
673 187 : if (!vrf)
674 : return NULL;
675 :
676 528 : FOR_ALL_INTERFACES (vrf, ifp) {
677 887 : for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, connected)) {
678 443 : cp = connected->address;
679 :
680 443 : if (cp->family == AF_INET)
681 285 : if (IPV4_ADDR_SAME(&cp->u.prefix4, addr))
682 136 : return ifp;
683 : }
684 : }
685 : return NULL;
686 : }
687 :
688 10 : struct interface *if_lookup_by_ipv6(struct in6_addr *addr, ifindex_t ifindex,
689 : vrf_id_t vrf_id)
690 : {
691 10 : struct vrf *vrf;
692 10 : struct listnode *cnode;
693 10 : struct interface *ifp;
694 10 : struct connected *connected;
695 10 : struct prefix_ipv6 p;
696 10 : struct prefix *cp;
697 :
698 10 : vrf = vrf_lookup_by_id(vrf_id);
699 10 : if (!vrf)
700 : return NULL;
701 :
702 10 : p.family = AF_INET6;
703 10 : p.prefix = *addr;
704 10 : p.prefixlen = IPV6_MAX_BITLEN;
705 :
706 30 : FOR_ALL_INTERFACES (vrf, ifp) {
707 100 : for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, connected)) {
708 70 : cp = connected->address;
709 :
710 70 : if (cp->family == AF_INET6)
711 50 : if (prefix_match(cp, (struct prefix *)&p)) {
712 10 : if (IN6_IS_ADDR_LINKLOCAL(
713 : &cp->u.prefix6)) {
714 0 : if (ifindex == ifp->ifindex)
715 0 : return ifp;
716 : } else
717 10 : return ifp;
718 : }
719 : }
720 : }
721 : return NULL;
722 : }
723 :
724 7 : struct interface *if_lookup_by_ipv6_exact(struct in6_addr *addr,
725 : ifindex_t ifindex, vrf_id_t vrf_id)
726 : {
727 7 : struct vrf *vrf;
728 7 : struct listnode *cnode;
729 7 : struct interface *ifp;
730 7 : struct connected *connected;
731 7 : struct prefix *cp;
732 :
733 7 : vrf = vrf_lookup_by_id(vrf_id);
734 7 : if (!vrf)
735 : return NULL;
736 :
737 19 : FOR_ALL_INTERFACES (vrf, ifp) {
738 50 : for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, connected)) {
739 35 : cp = connected->address;
740 :
741 35 : if (cp->family == AF_INET6)
742 25 : if (IPV6_ADDR_SAME(&cp->u.prefix6, addr)) {
743 5 : if (IN6_IS_ADDR_LINKLOCAL(
744 : &cp->u.prefix6)) {
745 0 : if (ifindex == ifp->ifindex)
746 0 : return ifp;
747 : } else
748 5 : return ifp;
749 : }
750 : }
751 : }
752 : return NULL;
753 : }
754 :
755 136 : static int if_get_ipv6_global(struct interface *ifp, struct in6_addr *addr)
756 : {
757 136 : struct listnode *cnode;
758 136 : struct connected *connected;
759 136 : struct prefix *cp;
760 :
761 408 : for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, connected)) {
762 272 : cp = connected->address;
763 :
764 272 : if (cp->family == AF_INET6)
765 136 : if (!IN6_IS_ADDR_LINKLOCAL(&cp->u.prefix6)) {
766 136 : memcpy(addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);
767 136 : return 1;
768 : }
769 : }
770 : return 0;
771 : }
772 :
773 141 : static bool if_get_ipv6_local(struct interface *ifp, struct in6_addr *addr)
774 : {
775 141 : struct listnode *cnode;
776 141 : struct connected *connected;
777 141 : struct prefix *cp;
778 :
779 564 : for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, connected)) {
780 423 : cp = connected->address;
781 :
782 423 : if (cp->family == AF_INET6)
783 282 : if (IN6_IS_ADDR_LINKLOCAL(&cp->u.prefix6)) {
784 141 : memcpy(addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);
785 141 : return true;
786 : }
787 : }
788 : return false;
789 : }
790 :
791 5 : static int if_get_ipv4_address(struct interface *ifp, struct in_addr *addr)
792 : {
793 5 : struct listnode *cnode;
794 5 : struct connected *connected;
795 5 : struct prefix *cp;
796 :
797 10 : for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, connected)) {
798 5 : cp = connected->address;
799 5 : if ((cp->family == AF_INET)
800 5 : && !ipv4_martian(&(cp->u.prefix4))) {
801 5 : *addr = cp->u.prefix4;
802 5 : return 1;
803 : }
804 : }
805 : return 0;
806 : }
807 :
808 :
809 141 : bool bgp_zebra_nexthop_set(union sockunion *local, union sockunion *remote,
810 : struct bgp_nexthop *nexthop, struct peer *peer)
811 : {
812 141 : int ret = 0;
813 141 : struct interface *ifp = NULL;
814 141 : bool v6_ll_avail = true;
815 :
816 141 : memset(nexthop, 0, sizeof(struct bgp_nexthop));
817 :
818 141 : if (!local)
819 : return false;
820 141 : if (!remote)
821 : return false;
822 :
823 141 : if (local->sa.sa_family == AF_INET) {
824 136 : nexthop->v4 = local->sin.sin_addr;
825 136 : if (peer->update_if)
826 0 : ifp = if_lookup_by_name(peer->update_if,
827 0 : peer->bgp->vrf_id);
828 : else
829 136 : ifp = if_lookup_by_ipv4_exact(&local->sin.sin_addr,
830 136 : peer->bgp->vrf_id);
831 : }
832 141 : if (local->sa.sa_family == AF_INET6) {
833 5 : memcpy(&nexthop->v6_global, &local->sin6.sin6_addr, IPV6_MAX_BYTELEN);
834 5 : if (IN6_IS_ADDR_LINKLOCAL(&local->sin6.sin6_addr)) {
835 0 : if (peer->conf_if || peer->ifname)
836 0 : ifp = if_lookup_by_name(peer->conf_if
837 : ? peer->conf_if
838 : : peer->ifname,
839 0 : peer->bgp->vrf_id);
840 0 : else if (peer->update_if)
841 0 : ifp = if_lookup_by_name(peer->update_if,
842 0 : peer->bgp->vrf_id);
843 5 : } else if (peer->update_if)
844 0 : ifp = if_lookup_by_name(peer->update_if,
845 0 : peer->bgp->vrf_id);
846 : else
847 5 : ifp = if_lookup_by_ipv6_exact(&local->sin6.sin6_addr,
848 5 : local->sin6.sin6_scope_id,
849 5 : peer->bgp->vrf_id);
850 : }
851 :
852 141 : if (!ifp) {
853 : /*
854 : * BGP views do not currently get proper data
855 : * from zebra( when attached ) to be able to
856 : * properly resolve nexthops, so give this
857 : * instance type a pass.
858 : */
859 0 : if (peer->bgp->inst_type == BGP_INSTANCE_TYPE_VIEW)
860 : return true;
861 : /*
862 : * If we have no interface data but we have established
863 : * some connection w/ zebra than something has gone
864 : * terribly terribly wrong here, so say this failed
865 : * If we do not any zebra connection then not
866 : * having a ifp pointer is ok.
867 : */
868 0 : return zclient_num_connects ? false : true;
869 : }
870 :
871 141 : nexthop->ifp = ifp;
872 :
873 : /* IPv4 connection, fetch and store IPv6 local address(es) if any. */
874 141 : if (local->sa.sa_family == AF_INET) {
875 : /* IPv6 nexthop*/
876 136 : ret = if_get_ipv6_global(ifp, &nexthop->v6_global);
877 :
878 136 : if (!ret) {
879 : /* There is no global nexthop. Use link-local address as
880 : * both the
881 : * global and link-local nexthop. In this scenario, the
882 : * expectation
883 : * for interop is that the network admin would use a
884 : * route-map to
885 : * specify the global IPv6 nexthop.
886 : */
887 0 : v6_ll_avail =
888 0 : if_get_ipv6_local(ifp, &nexthop->v6_global);
889 0 : memcpy(&nexthop->v6_local, &nexthop->v6_global,
890 : IPV6_MAX_BYTELEN);
891 : } else
892 136 : v6_ll_avail =
893 136 : if_get_ipv6_local(ifp, &nexthop->v6_local);
894 :
895 : /*
896 : * If we are a v4 connection and we are not doing unnumbered
897 : * not having a v6 LL address is ok
898 : */
899 136 : if (!v6_ll_avail && !peer->conf_if)
900 136 : v6_ll_avail = true;
901 136 : if (if_lookup_by_ipv4(&remote->sin.sin_addr, peer->bgp->vrf_id))
902 136 : peer->shared_network = 1;
903 : else
904 0 : peer->shared_network = 0;
905 : }
906 :
907 : /* IPv6 connection, fetch and store IPv4 local address if any. */
908 141 : if (local->sa.sa_family == AF_INET6) {
909 5 : struct interface *direct = NULL;
910 :
911 : /* IPv4 nexthop. */
912 5 : ret = if_get_ipv4_address(ifp, &nexthop->v4);
913 5 : if (!ret && peer->local_id.s_addr != INADDR_ANY)
914 0 : nexthop->v4 = peer->local_id;
915 :
916 : /* Global address*/
917 5 : if (!IN6_IS_ADDR_LINKLOCAL(&local->sin6.sin6_addr)) {
918 5 : memcpy(&nexthop->v6_global, &local->sin6.sin6_addr,
919 : IPV6_MAX_BYTELEN);
920 :
921 : /* If directly connected set link-local address. */
922 10 : direct = if_lookup_by_ipv6(&remote->sin6.sin6_addr,
923 5 : remote->sin6.sin6_scope_id,
924 5 : peer->bgp->vrf_id);
925 5 : if (direct)
926 5 : v6_ll_avail = if_get_ipv6_local(
927 : ifp, &nexthop->v6_local);
928 : /*
929 : * It's fine to not have a v6 LL when using
930 : * update-source loopback/vrf
931 : */
932 5 : if (!v6_ll_avail && if_is_loopback(ifp))
933 : v6_ll_avail = true;
934 0 : else if (!v6_ll_avail) {
935 0 : flog_warn(
936 : EC_BGP_NO_LL_ADDRESS_AVAILABLE,
937 : "Interface: %s does not have a v6 LL address associated with it, waiting until one is created for it",
938 : ifp->name);
939 : }
940 : } else
941 : /* Link-local address. */
942 : {
943 0 : ret = if_get_ipv6_global(ifp, &nexthop->v6_global);
944 :
945 : /* If there is no global address. Set link-local
946 : address as
947 : global. I know this break RFC specification... */
948 : /* In this scenario, the expectation for interop is that
949 : * the
950 : * network admin would use a route-map to specify the
951 : * global
952 : * IPv6 nexthop.
953 : */
954 0 : if (!ret)
955 0 : memcpy(&nexthop->v6_global,
956 : &local->sin6.sin6_addr,
957 : IPV6_MAX_BYTELEN);
958 : /* Always set the link-local address */
959 0 : memcpy(&nexthop->v6_local, &local->sin6.sin6_addr,
960 : IPV6_MAX_BYTELEN);
961 : }
962 :
963 5 : if (IN6_IS_ADDR_LINKLOCAL(&local->sin6.sin6_addr)
964 5 : || if_lookup_by_ipv6(&remote->sin6.sin6_addr,
965 5 : remote->sin6.sin6_scope_id,
966 5 : peer->bgp->vrf_id))
967 5 : peer->shared_network = 1;
968 : else
969 0 : peer->shared_network = 0;
970 : }
971 :
972 : /* KAME stack specific treatment. */
973 : #ifdef KAME
974 : if (IN6_IS_ADDR_LINKLOCAL(&nexthop->v6_global)
975 : && IN6_LINKLOCAL_IFINDEX(nexthop->v6_global)) {
976 : SET_IN6_LINKLOCAL_IFINDEX(nexthop->v6_global, 0);
977 : }
978 : if (IN6_IS_ADDR_LINKLOCAL(&nexthop->v6_local)
979 : && IN6_LINKLOCAL_IFINDEX(nexthop->v6_local)) {
980 : SET_IN6_LINKLOCAL_IFINDEX(nexthop->v6_local, 0);
981 : }
982 : #endif /* KAME */
983 :
984 : /* If we have identified the local interface, there is no error for now.
985 : */
986 : return v6_ll_avail;
987 : }
988 :
989 : static struct in6_addr *
990 7 : bgp_path_info_to_ipv6_nexthop(struct bgp_path_info *path, ifindex_t *ifindex)
991 : {
992 7 : struct in6_addr *nexthop = NULL;
993 :
994 : /* Only global address nexthop exists. */
995 7 : if (path->attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL
996 7 : || path->attr->mp_nexthop_len == BGP_ATTR_NHLEN_VPNV6_GLOBAL) {
997 2 : nexthop = &path->attr->mp_nexthop_global;
998 2 : if (IN6_IS_ADDR_LINKLOCAL(nexthop))
999 0 : *ifindex = path->attr->nh_ifindex;
1000 : }
1001 :
1002 : /* If both global and link-local address present. */
1003 7 : if (path->attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
1004 7 : || path->attr->mp_nexthop_len
1005 : == BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL) {
1006 : /* Check if route-map is set to prefer global over link-local */
1007 5 : if (path->attr->mp_nexthop_prefer_global) {
1008 0 : nexthop = &path->attr->mp_nexthop_global;
1009 0 : if (IN6_IS_ADDR_LINKLOCAL(nexthop))
1010 0 : *ifindex = path->attr->nh_ifindex;
1011 : } else {
1012 : /* Workaround for Cisco's nexthop bug. */
1013 5 : if (IN6_IS_ADDR_UNSPECIFIED(
1014 : &path->attr->mp_nexthop_global)
1015 0 : && path->peer->su_remote
1016 0 : && path->peer->su_remote->sa.sa_family
1017 : == AF_INET6) {
1018 0 : nexthop =
1019 : &path->peer->su_remote->sin6.sin6_addr;
1020 0 : if (IN6_IS_ADDR_LINKLOCAL(nexthop))
1021 0 : *ifindex = path->peer->nexthop.ifp
1022 0 : ->ifindex;
1023 : } else {
1024 5 : nexthop = &path->attr->mp_nexthop_local;
1025 5 : if (IN6_IS_ADDR_LINKLOCAL(nexthop))
1026 5 : *ifindex = path->attr->nh_lla_ifindex;
1027 : }
1028 : }
1029 : }
1030 :
1031 7 : return nexthop;
1032 : }
1033 :
1034 0 : static bool bgp_table_map_apply(struct route_map *map, const struct prefix *p,
1035 : struct bgp_path_info *path)
1036 : {
1037 0 : route_map_result_t ret;
1038 :
1039 0 : ret = route_map_apply(map, p, path);
1040 0 : bgp_attr_flush(path->attr);
1041 :
1042 0 : if (ret != RMAP_DENYMATCH)
1043 : return true;
1044 :
1045 0 : if (bgp_debug_zebra(p)) {
1046 0 : if (p->family == AF_INET) {
1047 0 : zlog_debug(
1048 : "Zebra rmap deny: IPv4 route %pFX nexthop %pI4",
1049 : p, &path->attr->nexthop);
1050 : }
1051 0 : if (p->family == AF_INET6) {
1052 0 : ifindex_t ifindex;
1053 0 : struct in6_addr *nexthop;
1054 :
1055 0 : nexthop = bgp_path_info_to_ipv6_nexthop(path, &ifindex);
1056 0 : zlog_debug(
1057 : "Zebra rmap deny: IPv6 route %pFX nexthop %pI6",
1058 : p, nexthop);
1059 : }
1060 : }
1061 : return false;
1062 : }
1063 :
1064 : static struct thread *bgp_tm_thread_connect;
1065 : static bool bgp_tm_status_connected;
1066 : static bool bgp_tm_chunk_obtained;
1067 : #define BGP_FLOWSPEC_TABLE_CHUNK 100000
1068 : static uint32_t bgp_tm_min, bgp_tm_max, bgp_tm_chunk_size;
1069 : struct bgp *bgp_tm_bgp;
1070 :
1071 0 : static void bgp_zebra_tm_connect(struct thread *t)
1072 : {
1073 0 : struct zclient *zclient;
1074 0 : int delay = 10, ret = 0;
1075 :
1076 0 : zclient = THREAD_ARG(t);
1077 0 : if (bgp_tm_status_connected && zclient->sock > 0)
1078 : delay = 60;
1079 : else {
1080 0 : bgp_tm_status_connected = false;
1081 0 : ret = tm_table_manager_connect(zclient);
1082 : }
1083 0 : if (ret < 0) {
1084 0 : zlog_info("Error connecting to table manager!");
1085 0 : bgp_tm_status_connected = false;
1086 : } else {
1087 0 : if (!bgp_tm_status_connected)
1088 0 : zlog_debug("Connecting to table manager. Success");
1089 0 : bgp_tm_status_connected = true;
1090 0 : if (!bgp_tm_chunk_obtained) {
1091 0 : if (bgp_zebra_get_table_range(bgp_tm_chunk_size,
1092 : &bgp_tm_min,
1093 : &bgp_tm_max) >= 0) {
1094 0 : bgp_tm_chunk_obtained = true;
1095 : /* parse non installed entries */
1096 0 : bgp_zebra_announce_table(bgp_tm_bgp, AFI_IP, SAFI_FLOWSPEC);
1097 : }
1098 : }
1099 : }
1100 0 : thread_add_timer(bm->master, bgp_zebra_tm_connect, zclient, delay,
1101 : &bgp_tm_thread_connect);
1102 0 : }
1103 :
1104 0 : bool bgp_zebra_tm_chunk_obtained(void)
1105 : {
1106 0 : return bgp_tm_chunk_obtained;
1107 : }
1108 :
1109 0 : uint32_t bgp_zebra_tm_get_id(void)
1110 : {
1111 0 : static int table_id;
1112 :
1113 0 : if (!bgp_tm_chunk_obtained)
1114 0 : return ++table_id;
1115 0 : return bgp_tm_min++;
1116 : }
1117 :
1118 0 : void bgp_zebra_init_tm_connect(struct bgp *bgp)
1119 : {
1120 0 : int delay = 1;
1121 :
1122 : /* if already set, do nothing
1123 : */
1124 0 : if (bgp_tm_thread_connect != NULL)
1125 : return;
1126 0 : bgp_tm_status_connected = false;
1127 0 : bgp_tm_chunk_obtained = false;
1128 0 : bgp_tm_min = bgp_tm_max = 0;
1129 0 : bgp_tm_chunk_size = BGP_FLOWSPEC_TABLE_CHUNK;
1130 0 : bgp_tm_bgp = bgp;
1131 0 : thread_add_timer(bm->master, bgp_zebra_tm_connect, zclient, delay,
1132 : &bgp_tm_thread_connect);
1133 : }
1134 :
1135 0 : int bgp_zebra_get_table_range(uint32_t chunk_size,
1136 : uint32_t *start, uint32_t *end)
1137 : {
1138 0 : int ret;
1139 :
1140 0 : if (!bgp_tm_status_connected)
1141 : return -1;
1142 0 : ret = tm_get_table_chunk(zclient, chunk_size, start, end);
1143 0 : if (ret < 0) {
1144 0 : flog_err(EC_BGP_TABLE_CHUNK,
1145 : "BGP: Error getting table chunk %u", chunk_size);
1146 0 : return -1;
1147 : }
1148 0 : zlog_info("BGP: Table Manager returns range from chunk %u is [%u %u]",
1149 : chunk_size, *start, *end);
1150 0 : return 0;
1151 : }
1152 :
1153 48 : static bool update_ipv4nh_for_route_install(int nh_othervrf, struct bgp *nh_bgp,
1154 : struct in_addr *nexthop,
1155 : struct attr *attr, bool is_evpn,
1156 : struct zapi_nexthop *api_nh)
1157 : {
1158 48 : api_nh->gate.ipv4 = *nexthop;
1159 48 : api_nh->vrf_id = nh_bgp->vrf_id;
1160 :
1161 : /* Need to set fields appropriately for EVPN routes imported into
1162 : * a VRF (which are programmed as onlink on l3-vni SVI) as well as
1163 : * connected routes leaked into a VRF.
1164 : */
1165 48 : if (attr->nh_type == NEXTHOP_TYPE_BLACKHOLE) {
1166 0 : api_nh->type = attr->nh_type;
1167 0 : api_nh->bh_type = attr->bh_type;
1168 48 : } else if (is_evpn) {
1169 : /*
1170 : * If the nexthop is EVPN overlay index gateway IP,
1171 : * treat the nexthop as NEXTHOP_TYPE_IPV4
1172 : * Else, mark the nexthop as onlink.
1173 : */
1174 0 : if (attr->evpn_overlay.type == OVERLAY_INDEX_GATEWAY_IP)
1175 0 : api_nh->type = NEXTHOP_TYPE_IPV4;
1176 : else {
1177 0 : api_nh->type = NEXTHOP_TYPE_IPV4_IFINDEX;
1178 0 : SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_EVPN);
1179 0 : SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_ONLINK);
1180 0 : api_nh->ifindex = nh_bgp->l3vni_svi_ifindex;
1181 : }
1182 48 : } else if (nh_othervrf && api_nh->gate.ipv4.s_addr == INADDR_ANY) {
1183 0 : api_nh->type = NEXTHOP_TYPE_IFINDEX;
1184 0 : api_nh->ifindex = attr->nh_ifindex;
1185 : } else
1186 48 : api_nh->type = NEXTHOP_TYPE_IPV4;
1187 :
1188 48 : return true;
1189 : }
1190 :
1191 7 : static bool update_ipv6nh_for_route_install(int nh_othervrf, struct bgp *nh_bgp,
1192 : struct in6_addr *nexthop,
1193 : ifindex_t ifindex,
1194 : struct bgp_path_info *pi,
1195 : struct bgp_path_info *best_pi,
1196 : bool is_evpn,
1197 : struct zapi_nexthop *api_nh)
1198 : {
1199 7 : struct attr *attr;
1200 :
1201 7 : attr = pi->attr;
1202 7 : api_nh->vrf_id = nh_bgp->vrf_id;
1203 :
1204 7 : if (attr->nh_type == NEXTHOP_TYPE_BLACKHOLE) {
1205 0 : api_nh->type = attr->nh_type;
1206 0 : api_nh->bh_type = attr->bh_type;
1207 7 : } else if (is_evpn) {
1208 : /*
1209 : * If the nexthop is EVPN overlay index gateway IP,
1210 : * treat the nexthop as NEXTHOP_TYPE_IPV4
1211 : * Else, mark the nexthop as onlink.
1212 : */
1213 0 : if (attr->evpn_overlay.type == OVERLAY_INDEX_GATEWAY_IP)
1214 0 : api_nh->type = NEXTHOP_TYPE_IPV6;
1215 : else {
1216 0 : api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX;
1217 0 : SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_EVPN);
1218 0 : SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_ONLINK);
1219 0 : api_nh->ifindex = nh_bgp->l3vni_svi_ifindex;
1220 : }
1221 7 : } else if (nh_othervrf) {
1222 0 : if (IN6_IS_ADDR_UNSPECIFIED(nexthop)) {
1223 0 : api_nh->type = NEXTHOP_TYPE_IFINDEX;
1224 0 : api_nh->ifindex = attr->nh_ifindex;
1225 0 : } else if (IN6_IS_ADDR_LINKLOCAL(nexthop)) {
1226 0 : if (ifindex == 0)
1227 : return false;
1228 0 : api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX;
1229 0 : api_nh->ifindex = ifindex;
1230 : } else {
1231 0 : api_nh->type = NEXTHOP_TYPE_IPV6;
1232 0 : api_nh->ifindex = 0;
1233 : }
1234 : } else {
1235 7 : if (IN6_IS_ADDR_LINKLOCAL(nexthop)) {
1236 5 : if (pi == best_pi
1237 5 : && attr->mp_nexthop_len
1238 : == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
1239 5 : if (pi->peer->nexthop.ifp)
1240 5 : ifindex =
1241 : pi->peer->nexthop.ifp->ifindex;
1242 5 : if (!ifindex) {
1243 0 : if (pi->peer->conf_if)
1244 0 : ifindex = pi->peer->ifp->ifindex;
1245 0 : else if (pi->peer->ifname)
1246 0 : ifindex = ifname2ifindex(
1247 : pi->peer->ifname,
1248 0 : pi->peer->bgp->vrf_id);
1249 0 : else if (pi->peer->nexthop.ifp)
1250 0 : ifindex =
1251 : pi->peer->nexthop.ifp->ifindex;
1252 : }
1253 :
1254 0 : if (ifindex == 0)
1255 : return false;
1256 5 : api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX;
1257 5 : api_nh->ifindex = ifindex;
1258 : } else {
1259 2 : api_nh->type = NEXTHOP_TYPE_IPV6;
1260 2 : api_nh->ifindex = 0;
1261 : }
1262 : }
1263 : /* api_nh structure has union of gate and bh_type */
1264 7 : if (nexthop && api_nh->type != NEXTHOP_TYPE_BLACKHOLE)
1265 7 : api_nh->gate.ipv6 = *nexthop;
1266 :
1267 : return true;
1268 : }
1269 :
1270 0 : static bool bgp_zebra_use_nhop_weighted(struct bgp *bgp, struct attr *attr,
1271 : uint64_t tot_bw, uint32_t *nh_weight)
1272 : {
1273 0 : uint32_t bw;
1274 0 : uint64_t tmp;
1275 :
1276 0 : bw = attr->link_bw;
1277 : /* zero link-bandwidth and link-bandwidth not present are treated
1278 : * as the same situation.
1279 : */
1280 0 : if (!bw) {
1281 : /* the only situations should be if we're either told
1282 : * to skip or use default weight.
1283 : */
1284 0 : if (bgp->lb_handling == BGP_LINK_BW_SKIP_MISSING)
1285 : return false;
1286 : *nh_weight = BGP_ZEBRA_DEFAULT_NHOP_WEIGHT;
1287 : } else {
1288 0 : tmp = (uint64_t)bw * 100;
1289 0 : *nh_weight = ((uint32_t)(tmp / tot_bw));
1290 : }
1291 :
1292 : return true;
1293 : }
1294 :
1295 55 : void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p,
1296 : struct bgp_path_info *info, struct bgp *bgp, afi_t afi,
1297 : safi_t safi)
1298 : {
1299 55 : struct zapi_route api = { 0 };
1300 55 : struct zapi_nexthop *api_nh;
1301 55 : int nh_family;
1302 55 : unsigned int valid_nh_count = 0;
1303 55 : bool allow_recursion = false;
1304 55 : uint8_t distance;
1305 55 : struct peer *peer;
1306 55 : struct bgp_path_info *mpinfo;
1307 55 : struct bgp *bgp_orig;
1308 55 : uint32_t metric;
1309 55 : struct attr local_attr;
1310 55 : struct bgp_path_info local_info;
1311 55 : struct bgp_path_info *mpinfo_cp = &local_info;
1312 55 : route_tag_t tag;
1313 55 : mpls_label_t label;
1314 55 : struct bgp_sid_info *sid_info;
1315 55 : int nh_othervrf = 0;
1316 55 : bool nh_updated = false;
1317 55 : bool do_wt_ecmp;
1318 55 : uint64_t cum_bw = 0;
1319 55 : uint32_t nhg_id = 0;
1320 55 : bool is_add;
1321 55 : uint32_t ttl = 0;
1322 55 : uint32_t bos = 0;
1323 55 : uint32_t exp = 0;
1324 :
1325 : /* Don't try to install if we're not connected to Zebra or Zebra doesn't
1326 : * know of this instance.
1327 : */
1328 55 : if (!bgp_install_info_to_zebra(bgp))
1329 0 : return;
1330 :
1331 55 : if (bgp->main_zebra_update_hold)
1332 : return;
1333 :
1334 55 : if (safi == SAFI_FLOWSPEC) {
1335 0 : bgp_pbr_update_entry(bgp, bgp_dest_get_prefix(dest), info, afi,
1336 : safi, true);
1337 0 : return;
1338 : }
1339 :
1340 : /*
1341 : * vrf leaking support (will have only one nexthop)
1342 : */
1343 55 : if (info->extra && info->extra->bgp_orig)
1344 55 : nh_othervrf = 1;
1345 :
1346 : /* Make Zebra API structure. */
1347 55 : api.vrf_id = bgp->vrf_id;
1348 55 : api.type = ZEBRA_ROUTE_BGP;
1349 55 : api.safi = safi;
1350 55 : api.prefix = *p;
1351 55 : SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP);
1352 :
1353 55 : peer = info->peer;
1354 :
1355 55 : if (info->type == ZEBRA_ROUTE_BGP
1356 55 : && info->sub_type == BGP_ROUTE_IMPORTED) {
1357 :
1358 : /* Obtain peer from parent */
1359 0 : if (info->extra && info->extra->parent)
1360 0 : peer = ((struct bgp_path_info *)(info->extra->parent))
1361 : ->peer;
1362 : }
1363 :
1364 55 : tag = info->attr->tag;
1365 :
1366 55 : if (peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED
1367 55 : || info->sub_type == BGP_ROUTE_AGGREGATE) {
1368 2 : SET_FLAG(api.flags, ZEBRA_FLAG_IBGP);
1369 2 : SET_FLAG(api.flags, ZEBRA_FLAG_ALLOW_RECURSION);
1370 : }
1371 :
1372 55 : if ((peer->sort == BGP_PEER_EBGP && peer->ttl != BGP_DEFAULT_TTL)
1373 55 : || CHECK_FLAG(peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK)
1374 55 : || CHECK_FLAG(bgp->flags, BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
1375 :
1376 0 : allow_recursion = true;
1377 :
1378 55 : if (info->attr->rmap_table_id) {
1379 0 : SET_FLAG(api.message, ZAPI_MESSAGE_TABLEID);
1380 0 : api.tableid = info->attr->rmap_table_id;
1381 : }
1382 :
1383 55 : if (CHECK_FLAG(info->attr->flag, ATTR_FLAG_BIT(BGP_ATTR_SRTE_COLOR)))
1384 0 : SET_FLAG(api.message, ZAPI_MESSAGE_SRTE);
1385 :
1386 : /* Metric is currently based on the best-path only */
1387 55 : metric = info->attr->med;
1388 :
1389 : /* Determine if we're doing weighted ECMP or not */
1390 55 : do_wt_ecmp = bgp_path_info_mpath_chkwtd(bgp, info);
1391 55 : if (do_wt_ecmp)
1392 0 : cum_bw = bgp_path_info_mpath_cumbw(info);
1393 :
1394 : /* EVPN MAC-IP routes are installed with a L3 NHG id */
1395 55 : if (bgp_evpn_path_es_use_nhg(bgp, info, &nhg_id)) {
1396 0 : mpinfo = NULL;
1397 0 : api.nhgid = nhg_id;
1398 0 : if (nhg_id)
1399 0 : SET_FLAG(api.message, ZAPI_MESSAGE_NHG);
1400 : } else {
1401 : mpinfo = info;
1402 : }
1403 :
1404 110 : for (; mpinfo; mpinfo = bgp_path_info_mpath_next(mpinfo)) {
1405 55 : uint32_t nh_weight;
1406 55 : bool is_evpn;
1407 :
1408 55 : if (valid_nh_count >= multipath_num)
1409 : break;
1410 :
1411 55 : *mpinfo_cp = *mpinfo;
1412 55 : nh_weight = 0;
1413 :
1414 : /* Get nexthop address-family */
1415 55 : if (p->family == AF_INET &&
1416 50 : !BGP_ATTR_MP_NEXTHOP_LEN_IP6(mpinfo_cp->attr))
1417 : nh_family = AF_INET;
1418 7 : else if (p->family == AF_INET6 ||
1419 2 : (p->family == AF_INET &&
1420 2 : BGP_ATTR_MP_NEXTHOP_LEN_IP6(mpinfo_cp->attr)))
1421 : nh_family = AF_INET6;
1422 : else
1423 55 : continue;
1424 :
1425 : /* If processing for weighted ECMP, determine the next hop's
1426 : * weight. Based on user setting, we may skip the next hop
1427 : * in some situations.
1428 : */
1429 55 : if (do_wt_ecmp) {
1430 0 : if (!bgp_zebra_use_nhop_weighted(bgp, mpinfo->attr,
1431 : cum_bw, &nh_weight))
1432 0 : continue;
1433 : }
1434 55 : api_nh = &api.nexthops[valid_nh_count];
1435 :
1436 55 : if (CHECK_FLAG(info->attr->flag,
1437 : ATTR_FLAG_BIT(BGP_ATTR_SRTE_COLOR)))
1438 0 : api_nh->srte_color = info->attr->srte_color;
1439 :
1440 55 : if (bgp_debug_zebra(&api.prefix)) {
1441 0 : if (mpinfo->extra) {
1442 0 : zlog_debug("%s: p=%pFX, bgp_is_valid_label: %d",
1443 : __func__, p,
1444 : bgp_is_valid_label(
1445 : &mpinfo->extra->label[0]));
1446 : } else {
1447 0 : zlog_debug(
1448 : "%s: p=%pFX, extra is NULL, no label",
1449 : __func__, p);
1450 : }
1451 : }
1452 :
1453 55 : if (bgp->table_map[afi][safi].name) {
1454 : /* Copy info and attributes, so the route-map
1455 : apply doesn't modify the BGP route info. */
1456 0 : local_attr = *mpinfo->attr;
1457 0 : mpinfo_cp->attr = &local_attr;
1458 0 : if (!bgp_table_map_apply(bgp->table_map[afi][safi].map,
1459 : p, mpinfo_cp))
1460 0 : continue;
1461 :
1462 : /* metric/tag is only allowed to be
1463 : * overridden on 1st nexthop */
1464 0 : if (mpinfo == info) {
1465 0 : metric = mpinfo_cp->attr->med;
1466 0 : tag = mpinfo_cp->attr->tag;
1467 : }
1468 : }
1469 :
1470 55 : BGP_ORIGINAL_UPDATE(bgp_orig, mpinfo, bgp);
1471 :
1472 55 : if (nh_family == AF_INET) {
1473 48 : is_evpn = is_route_parent_evpn(mpinfo);
1474 :
1475 48 : nh_updated = update_ipv4nh_for_route_install(
1476 : nh_othervrf, bgp_orig,
1477 : &mpinfo_cp->attr->nexthop, mpinfo_cp->attr,
1478 : is_evpn, api_nh);
1479 : } else {
1480 7 : ifindex_t ifindex = IFINDEX_INTERNAL;
1481 7 : struct in6_addr *nexthop;
1482 :
1483 7 : nexthop = bgp_path_info_to_ipv6_nexthop(mpinfo_cp,
1484 : &ifindex);
1485 :
1486 7 : is_evpn = is_route_parent_evpn(mpinfo);
1487 :
1488 7 : if (!nexthop)
1489 0 : nh_updated = update_ipv4nh_for_route_install(
1490 : nh_othervrf, bgp_orig,
1491 : &mpinfo_cp->attr->nexthop,
1492 : mpinfo_cp->attr, is_evpn, api_nh);
1493 : else
1494 7 : nh_updated = update_ipv6nh_for_route_install(
1495 : nh_othervrf, bgp_orig, nexthop, ifindex,
1496 : mpinfo, info, is_evpn, api_nh);
1497 : }
1498 :
1499 : /* Did we get proper nexthop info to update zebra? */
1500 55 : if (!nh_updated)
1501 0 : continue;
1502 :
1503 : /* Allow recursion if it is a multipath group with both
1504 : * eBGP and iBGP paths.
1505 : */
1506 55 : if (!allow_recursion
1507 55 : && CHECK_FLAG(bgp->flags, BGP_FLAG_PEERTYPE_MULTIPATH_RELAX)
1508 0 : && (mpinfo->peer->sort == BGP_PEER_IBGP
1509 0 : || mpinfo->peer->sort == BGP_PEER_CONFED))
1510 55 : allow_recursion = true;
1511 :
1512 55 : if (mpinfo->extra &&
1513 0 : bgp_is_valid_label(&mpinfo->extra->label[0]) &&
1514 0 : !CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_EVPN)) {
1515 0 : mpls_lse_decode(mpinfo->extra->label[0], &label, &ttl,
1516 : &exp, &bos);
1517 :
1518 0 : SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_LABEL);
1519 :
1520 0 : api_nh->label_num = 1;
1521 0 : api_nh->labels[0] = label;
1522 : }
1523 :
1524 55 : if (is_evpn
1525 0 : && mpinfo->attr->evpn_overlay.type
1526 : != OVERLAY_INDEX_GATEWAY_IP)
1527 0 : memcpy(&api_nh->rmac, &(mpinfo->attr->rmac),
1528 : sizeof(struct ethaddr));
1529 :
1530 55 : api_nh->weight = nh_weight;
1531 :
1532 55 : if (mpinfo->extra &&
1533 0 : bgp_is_valid_label(&mpinfo->extra->label[0]) &&
1534 0 : !sid_zero(&mpinfo->extra->sid[0].sid) &&
1535 0 : !CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_EVPN)) {
1536 0 : sid_info = &mpinfo->extra->sid[0];
1537 :
1538 0 : memcpy(&api_nh->seg6_segs, &sid_info->sid,
1539 : sizeof(api_nh->seg6_segs));
1540 :
1541 0 : if (sid_info->transposition_len != 0) {
1542 0 : mpls_lse_decode(mpinfo->extra->label[0], &label,
1543 : &ttl, &exp, &bos);
1544 :
1545 0 : if (label < MPLS_LABEL_UNRESERVED_MIN) {
1546 0 : if (bgp_debug_zebra(&api.prefix))
1547 0 : zlog_debug(
1548 : "skip invalid SRv6 routes: transposition scheme is used, but label is too small");
1549 0 : continue;
1550 : }
1551 :
1552 0 : transpose_sid(&api_nh->seg6_segs, label,
1553 0 : sid_info->transposition_offset,
1554 : sid_info->transposition_len);
1555 : }
1556 :
1557 0 : SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_SEG6);
1558 : }
1559 :
1560 55 : valid_nh_count++;
1561 : }
1562 :
1563 55 : is_add = (valid_nh_count || nhg_id) ? true : false;
1564 :
1565 55 : if (is_add && CHECK_FLAG(bm->flags, BM_FLAG_SEND_EXTRA_DATA_TO_ZEBRA)) {
1566 5 : struct bgp_zebra_opaque bzo = {};
1567 5 : const char *reason =
1568 5 : bgp_path_selection_reason2str(dest->reason);
1569 :
1570 5 : strlcpy(bzo.aspath, info->attr->aspath->str,
1571 : sizeof(bzo.aspath));
1572 :
1573 5 : if (info->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES))
1574 5 : strlcpy(bzo.community,
1575 5 : bgp_attr_get_community(info->attr)->str,
1576 : sizeof(bzo.community));
1577 :
1578 5 : if (info->attr->flag
1579 5 : & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES))
1580 0 : strlcpy(bzo.lcommunity,
1581 0 : bgp_attr_get_lcommunity(info->attr)->str,
1582 : sizeof(bzo.lcommunity));
1583 :
1584 5 : strlcpy(bzo.selection_reason, reason,
1585 : sizeof(bzo.selection_reason));
1586 :
1587 5 : SET_FLAG(api.message, ZAPI_MESSAGE_OPAQUE);
1588 5 : api.opaque.length = MIN(sizeof(struct bgp_zebra_opaque),
1589 : ZAPI_MESSAGE_OPAQUE_LENGTH);
1590 5 : memcpy(api.opaque.data, &bzo, api.opaque.length);
1591 : }
1592 :
1593 55 : if (allow_recursion)
1594 0 : SET_FLAG(api.flags, ZEBRA_FLAG_ALLOW_RECURSION);
1595 :
1596 : /*
1597 : * When we create an aggregate route we must also
1598 : * install a Null0 route in the RIB, so overwrite
1599 : * what was written into api with a blackhole route
1600 : */
1601 55 : if (info->sub_type == BGP_ROUTE_AGGREGATE)
1602 2 : zapi_route_set_blackhole(&api, BLACKHOLE_NULL);
1603 : else
1604 53 : api.nexthop_num = valid_nh_count;
1605 :
1606 55 : SET_FLAG(api.message, ZAPI_MESSAGE_METRIC);
1607 55 : api.metric = metric;
1608 :
1609 55 : if (tag) {
1610 0 : SET_FLAG(api.message, ZAPI_MESSAGE_TAG);
1611 0 : api.tag = tag;
1612 : }
1613 :
1614 55 : distance = bgp_distance_apply(p, info, afi, safi, bgp);
1615 55 : if (distance) {
1616 55 : SET_FLAG(api.message, ZAPI_MESSAGE_DISTANCE);
1617 55 : api.distance = distance;
1618 : }
1619 :
1620 55 : if (bgp_debug_zebra(p)) {
1621 0 : char nh_buf[INET6_ADDRSTRLEN];
1622 0 : char eth_buf[ETHER_ADDR_STRLEN + 7] = {'\0'};
1623 0 : char buf1[ETHER_ADDR_STRLEN];
1624 0 : char label_buf[20];
1625 0 : char sid_buf[20];
1626 0 : char segs_buf[256];
1627 0 : int i;
1628 :
1629 0 : zlog_debug(
1630 : "Tx route %s VRF %u %pFX metric %u tag %" ROUTE_TAG_PRI
1631 : " count %d nhg %d",
1632 : is_add ? "add" : "delete", bgp->vrf_id, &api.prefix,
1633 : api.metric, api.tag, api.nexthop_num, nhg_id);
1634 0 : for (i = 0; i < api.nexthop_num; i++) {
1635 0 : api_nh = &api.nexthops[i];
1636 :
1637 0 : switch (api_nh->type) {
1638 0 : case NEXTHOP_TYPE_IFINDEX:
1639 0 : nh_buf[0] = '\0';
1640 0 : break;
1641 0 : case NEXTHOP_TYPE_IPV4:
1642 : case NEXTHOP_TYPE_IPV4_IFINDEX:
1643 0 : nh_family = AF_INET;
1644 0 : inet_ntop(nh_family, &api_nh->gate, nh_buf,
1645 : sizeof(nh_buf));
1646 0 : break;
1647 0 : case NEXTHOP_TYPE_IPV6:
1648 : case NEXTHOP_TYPE_IPV6_IFINDEX:
1649 0 : nh_family = AF_INET6;
1650 0 : inet_ntop(nh_family, &api_nh->gate, nh_buf,
1651 : sizeof(nh_buf));
1652 0 : break;
1653 0 : case NEXTHOP_TYPE_BLACKHOLE:
1654 0 : strlcpy(nh_buf, "blackhole", sizeof(nh_buf));
1655 0 : break;
1656 : default:
1657 : /* Note: add new nexthop case */
1658 0 : assert(0);
1659 : break;
1660 : }
1661 :
1662 0 : label_buf[0] = '\0';
1663 0 : eth_buf[0] = '\0';
1664 0 : segs_buf[0] = '\0';
1665 0 : if (CHECK_FLAG(api_nh->flags,
1666 : ZAPI_NEXTHOP_FLAG_LABEL) &&
1667 : !CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_EVPN))
1668 0 : snprintf(label_buf, sizeof(label_buf),
1669 : "label %u", api_nh->labels[0]);
1670 0 : if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_SEG6) &&
1671 : !CHECK_FLAG(api_nh->flags,
1672 : ZAPI_NEXTHOP_FLAG_EVPN)) {
1673 0 : inet_ntop(AF_INET6, &api_nh->seg6_segs,
1674 : sid_buf, sizeof(sid_buf));
1675 0 : snprintf(segs_buf, sizeof(segs_buf), "segs %s",
1676 : sid_buf);
1677 : }
1678 0 : if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_EVPN) &&
1679 0 : !is_zero_mac(&api_nh->rmac))
1680 0 : snprintf(eth_buf, sizeof(eth_buf), " RMAC %s",
1681 : prefix_mac2str(&api_nh->rmac,
1682 : buf1, sizeof(buf1)));
1683 0 : zlog_debug(" nhop [%d]: %s if %u VRF %u wt %u %s %s %s",
1684 : i + 1, nh_buf, api_nh->ifindex,
1685 : api_nh->vrf_id, api_nh->weight,
1686 : label_buf, segs_buf, eth_buf);
1687 : }
1688 :
1689 0 : int recursion_flag = 0;
1690 :
1691 0 : if (CHECK_FLAG(api.flags, ZEBRA_FLAG_ALLOW_RECURSION))
1692 : recursion_flag = 1;
1693 :
1694 0 : zlog_debug("%s: %pFX: announcing to zebra (recursion %sset)",
1695 : __func__, p, (recursion_flag ? "" : "NOT "));
1696 : }
1697 55 : zclient_route_send(is_add ? ZEBRA_ROUTE_ADD : ZEBRA_ROUTE_DELETE,
1698 : zclient, &api);
1699 : }
1700 :
1701 : /* Announce all routes of a table to zebra */
1702 6 : void bgp_zebra_announce_table(struct bgp *bgp, afi_t afi, safi_t safi)
1703 : {
1704 6 : struct bgp_dest *dest;
1705 6 : struct bgp_table *table;
1706 6 : struct bgp_path_info *pi;
1707 :
1708 : /* Don't try to install if we're not connected to Zebra or Zebra doesn't
1709 : * know of this instance.
1710 : */
1711 6 : if (!bgp_install_info_to_zebra(bgp))
1712 : return;
1713 :
1714 6 : table = bgp->rib[afi][safi];
1715 6 : if (!table)
1716 : return;
1717 :
1718 15 : for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
1719 5 : for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
1720 2 : if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED) &&
1721 :
1722 0 : (pi->type == ZEBRA_ROUTE_BGP
1723 0 : && (pi->sub_type == BGP_ROUTE_NORMAL
1724 0 : || pi->sub_type == BGP_ROUTE_IMPORTED)))
1725 :
1726 0 : bgp_zebra_announce(dest,
1727 : bgp_dest_get_prefix(dest),
1728 : pi, bgp, afi, safi);
1729 : }
1730 :
1731 : /* Announce routes of any bgp subtype of a table to zebra */
1732 0 : void bgp_zebra_announce_table_all_subtypes(struct bgp *bgp, afi_t afi,
1733 : safi_t safi)
1734 : {
1735 0 : struct bgp_dest *dest;
1736 0 : struct bgp_table *table;
1737 0 : struct bgp_path_info *pi;
1738 :
1739 0 : if (!bgp_install_info_to_zebra(bgp))
1740 : return;
1741 :
1742 0 : table = bgp->rib[afi][safi];
1743 0 : if (!table)
1744 : return;
1745 :
1746 0 : for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
1747 0 : for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
1748 0 : if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED) &&
1749 0 : pi->type == ZEBRA_ROUTE_BGP)
1750 0 : bgp_zebra_announce(dest,
1751 : bgp_dest_get_prefix(dest),
1752 : pi, bgp, afi, safi);
1753 : }
1754 :
1755 51 : void bgp_zebra_withdraw(const struct prefix *p, struct bgp_path_info *info,
1756 : struct bgp *bgp, safi_t safi)
1757 : {
1758 51 : struct zapi_route api;
1759 51 : struct peer *peer;
1760 :
1761 : /* Don't try to install if we're not connected to Zebra or Zebra doesn't
1762 : * know of this instance.
1763 : */
1764 51 : if (!bgp_install_info_to_zebra(bgp))
1765 0 : return;
1766 :
1767 51 : if (safi == SAFI_FLOWSPEC) {
1768 0 : peer = info->peer;
1769 0 : bgp_pbr_update_entry(peer->bgp, p, info, AFI_IP, safi, false);
1770 0 : return;
1771 : }
1772 :
1773 51 : memset(&api, 0, sizeof(api));
1774 51 : api.vrf_id = bgp->vrf_id;
1775 51 : api.type = ZEBRA_ROUTE_BGP;
1776 51 : api.safi = safi;
1777 51 : api.prefix = *p;
1778 :
1779 51 : if (info->attr->rmap_table_id) {
1780 0 : SET_FLAG(api.message, ZAPI_MESSAGE_TABLEID);
1781 0 : api.tableid = info->attr->rmap_table_id;
1782 : }
1783 :
1784 51 : if (bgp_debug_zebra(p))
1785 0 : zlog_debug("Tx route delete VRF %u %pFX", bgp->vrf_id,
1786 : &api.prefix);
1787 :
1788 51 : zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api);
1789 : }
1790 :
1791 : /* Withdraw all entries in a BGP instances RIB table from Zebra */
1792 0 : void bgp_zebra_withdraw_table_all_subtypes(struct bgp *bgp, afi_t afi, safi_t safi)
1793 : {
1794 0 : struct bgp_dest *dest;
1795 0 : struct bgp_table *table;
1796 0 : struct bgp_path_info *pi;
1797 :
1798 0 : if (!bgp_install_info_to_zebra(bgp))
1799 : return;
1800 :
1801 0 : table = bgp->rib[afi][safi];
1802 0 : if (!table)
1803 : return;
1804 :
1805 0 : for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
1806 0 : for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
1807 0 : if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)
1808 0 : && (pi->type == ZEBRA_ROUTE_BGP))
1809 0 : bgp_zebra_withdraw(bgp_dest_get_prefix(dest),
1810 : pi, bgp, safi);
1811 : }
1812 : }
1813 : }
1814 :
1815 6216 : struct bgp_redist *bgp_redist_lookup(struct bgp *bgp, afi_t afi, uint8_t type,
1816 : unsigned short instance)
1817 : {
1818 6216 : struct list *red_list;
1819 6216 : struct listnode *node;
1820 6216 : struct bgp_redist *red;
1821 :
1822 6216 : red_list = bgp->redist[afi][type];
1823 6216 : if (!red_list)
1824 : return (NULL);
1825 :
1826 156 : for (ALL_LIST_ELEMENTS_RO(red_list, node, red))
1827 156 : if (red->instance == instance)
1828 156 : return red;
1829 :
1830 : return NULL;
1831 : }
1832 :
1833 20 : struct bgp_redist *bgp_redist_add(struct bgp *bgp, afi_t afi, uint8_t type,
1834 : unsigned short instance)
1835 : {
1836 20 : struct list *red_list;
1837 20 : struct bgp_redist *red;
1838 :
1839 20 : red = bgp_redist_lookup(bgp, afi, type, instance);
1840 20 : if (red)
1841 : return red;
1842 :
1843 20 : if (!bgp->redist[afi][type])
1844 20 : bgp->redist[afi][type] = list_new();
1845 :
1846 20 : red_list = bgp->redist[afi][type];
1847 20 : red = XCALLOC(MTYPE_BGP_REDIST, sizeof(struct bgp_redist));
1848 20 : red->instance = instance;
1849 :
1850 20 : listnode_add(red_list, red);
1851 :
1852 20 : return red;
1853 : }
1854 :
1855 20 : static void bgp_redist_del(struct bgp *bgp, afi_t afi, uint8_t type,
1856 : unsigned short instance)
1857 : {
1858 20 : struct bgp_redist *red;
1859 :
1860 20 : red = bgp_redist_lookup(bgp, afi, type, instance);
1861 :
1862 20 : if (red) {
1863 20 : listnode_delete(bgp->redist[afi][type], red);
1864 20 : XFREE(MTYPE_BGP_REDIST, red);
1865 20 : if (!bgp->redist[afi][type]->count)
1866 20 : list_delete(&bgp->redist[afi][type]);
1867 : }
1868 20 : }
1869 :
1870 : /* Other routes redistribution into BGP. */
1871 20 : int bgp_redistribute_set(struct bgp *bgp, afi_t afi, int type,
1872 : unsigned short instance, bool changed)
1873 : {
1874 : /* If redistribute options are changed call
1875 : * bgp_redistribute_unreg() to reset the option and withdraw
1876 : * the routes
1877 : */
1878 20 : if (changed)
1879 1 : bgp_redistribute_unreg(bgp, afi, type, instance);
1880 :
1881 : /* Return if already redistribute flag is set. */
1882 20 : if (instance) {
1883 0 : if (redist_check_instance(&zclient->mi_redist[afi][type],
1884 : instance))
1885 : return CMD_WARNING;
1886 :
1887 0 : redist_add_instance(&zclient->mi_redist[afi][type], instance);
1888 : } else {
1889 20 : if (vrf_bitmap_check(zclient->redist[afi][type], bgp->vrf_id))
1890 : return CMD_WARNING;
1891 :
1892 : #ifdef ENABLE_BGP_VNC
1893 20 : if (EVPN_ENABLED(bgp) && type == ZEBRA_ROUTE_VNC_DIRECT) {
1894 0 : vnc_export_bgp_enable(
1895 : bgp, afi); /* only enables if mode bits cfg'd */
1896 : }
1897 : #endif
1898 :
1899 20 : vrf_bitmap_set(zclient->redist[afi][type], bgp->vrf_id);
1900 : }
1901 :
1902 : /*
1903 : * Don't try to register if we're not connected to Zebra or Zebra
1904 : * doesn't know of this instance.
1905 : *
1906 : * When we come up later well resend if needed.
1907 : */
1908 20 : if (!bgp_install_info_to_zebra(bgp))
1909 : return CMD_SUCCESS;
1910 :
1911 20 : if (BGP_DEBUG(zebra, ZEBRA))
1912 0 : zlog_debug("Tx redistribute add VRF %u afi %d %s %d",
1913 : bgp->vrf_id, afi, zebra_route_string(type),
1914 : instance);
1915 :
1916 : /* Send distribute add message to zebra. */
1917 20 : zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, zclient, afi, type,
1918 : instance, bgp->vrf_id);
1919 :
1920 20 : return CMD_SUCCESS;
1921 : }
1922 :
1923 1 : int bgp_redistribute_resend(struct bgp *bgp, afi_t afi, int type,
1924 : unsigned short instance)
1925 : {
1926 : /* Don't try to send if we're not connected to Zebra or Zebra doesn't
1927 : * know of this instance.
1928 : */
1929 1 : if (!bgp_install_info_to_zebra(bgp))
1930 : return -1;
1931 :
1932 1 : if (BGP_DEBUG(zebra, ZEBRA))
1933 0 : zlog_debug("Tx redistribute del/add VRF %u afi %d %s %d",
1934 : bgp->vrf_id, afi, zebra_route_string(type),
1935 : instance);
1936 :
1937 : /* Send distribute add message to zebra. */
1938 1 : zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, zclient, afi, type,
1939 : instance, bgp->vrf_id);
1940 1 : zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, zclient, afi, type,
1941 : instance, bgp->vrf_id);
1942 :
1943 1 : return 0;
1944 : }
1945 :
1946 : /* Redistribute with route-map specification. */
1947 1 : bool bgp_redistribute_rmap_set(struct bgp_redist *red, const char *name,
1948 : struct route_map *route_map)
1949 : {
1950 1 : if (red->rmap.name && (strcmp(red->rmap.name, name) == 0))
1951 : return false;
1952 :
1953 1 : XFREE(MTYPE_ROUTE_MAP_NAME, red->rmap.name);
1954 : /* Decrement the count for existing routemap and
1955 : * increment the count for new route map.
1956 : */
1957 1 : route_map_counter_decrement(red->rmap.map);
1958 1 : red->rmap.name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, name);
1959 1 : red->rmap.map = route_map;
1960 1 : route_map_counter_increment(red->rmap.map);
1961 :
1962 1 : return true;
1963 : }
1964 :
1965 : /* Redistribute with metric specification. */
1966 0 : bool bgp_redistribute_metric_set(struct bgp *bgp, struct bgp_redist *red,
1967 : afi_t afi, int type, uint32_t metric)
1968 : {
1969 0 : struct bgp_dest *dest;
1970 0 : struct bgp_path_info *pi;
1971 :
1972 0 : if (red->redist_metric_flag && red->redist_metric == metric)
1973 : return false;
1974 :
1975 0 : red->redist_metric_flag = 1;
1976 0 : red->redist_metric = metric;
1977 :
1978 0 : for (dest = bgp_table_top(bgp->rib[afi][SAFI_UNICAST]); dest;
1979 0 : dest = bgp_route_next(dest)) {
1980 0 : for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
1981 0 : if (pi->sub_type == BGP_ROUTE_REDISTRIBUTE
1982 0 : && pi->type == type
1983 0 : && pi->instance == red->instance) {
1984 0 : struct attr *old_attr;
1985 0 : struct attr new_attr;
1986 :
1987 0 : new_attr = *pi->attr;
1988 0 : new_attr.med = red->redist_metric;
1989 0 : old_attr = pi->attr;
1990 0 : pi->attr = bgp_attr_intern(&new_attr);
1991 0 : bgp_attr_unintern(&old_attr);
1992 :
1993 0 : bgp_path_info_set_flag(dest, pi,
1994 : BGP_PATH_ATTR_CHANGED);
1995 0 : bgp_process(bgp, dest, afi, SAFI_UNICAST);
1996 : }
1997 : }
1998 : }
1999 :
2000 : return true;
2001 : }
2002 :
2003 : /* Unset redistribution. */
2004 21 : int bgp_redistribute_unreg(struct bgp *bgp, afi_t afi, int type,
2005 : unsigned short instance)
2006 : {
2007 21 : struct bgp_redist *red;
2008 :
2009 21 : red = bgp_redist_lookup(bgp, afi, type, instance);
2010 21 : if (!red)
2011 : return CMD_SUCCESS;
2012 :
2013 : /* Return if zebra connection is disabled. */
2014 21 : if (instance) {
2015 0 : if (!redist_check_instance(&zclient->mi_redist[afi][type],
2016 : instance))
2017 : return CMD_WARNING;
2018 0 : redist_del_instance(&zclient->mi_redist[afi][type], instance);
2019 : } else {
2020 21 : if (!vrf_bitmap_check(zclient->redist[afi][type], bgp->vrf_id))
2021 : return CMD_WARNING;
2022 20 : vrf_bitmap_unset(zclient->redist[afi][type], bgp->vrf_id);
2023 : }
2024 :
2025 20 : if (bgp_install_info_to_zebra(bgp)) {
2026 : /* Send distribute delete message to zebra. */
2027 20 : if (BGP_DEBUG(zebra, ZEBRA))
2028 0 : zlog_debug("Tx redistribute del VRF %u afi %d %s %d",
2029 : bgp->vrf_id, afi, zebra_route_string(type),
2030 : instance);
2031 20 : zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, zclient, afi,
2032 : type, instance, bgp->vrf_id);
2033 : }
2034 :
2035 : /* Withdraw redistributed routes from current BGP's routing table. */
2036 20 : bgp_redistribute_withdraw(bgp, afi, type, instance);
2037 :
2038 20 : return CMD_SUCCESS;
2039 : }
2040 :
2041 : /* Unset redistribution. */
2042 4050 : int bgp_redistribute_unset(struct bgp *bgp, afi_t afi, int type,
2043 : unsigned short instance)
2044 : {
2045 4050 : struct bgp_redist *red;
2046 :
2047 : /*
2048 : * vnc and vpn->vrf checks must be before red check because
2049 : * they operate within bgpd irrespective of zebra connection
2050 : * status. red lookup fails if there is no zebra connection.
2051 : */
2052 : #ifdef ENABLE_BGP_VNC
2053 4050 : if (EVPN_ENABLED(bgp) && type == ZEBRA_ROUTE_VNC_DIRECT) {
2054 0 : vnc_export_bgp_disable(bgp, afi);
2055 : }
2056 : #endif
2057 :
2058 4050 : red = bgp_redist_lookup(bgp, afi, type, instance);
2059 4050 : if (!red)
2060 : return CMD_SUCCESS;
2061 :
2062 20 : bgp_redistribute_unreg(bgp, afi, type, instance);
2063 :
2064 : /* Unset route-map. */
2065 20 : XFREE(MTYPE_ROUTE_MAP_NAME, red->rmap.name);
2066 20 : route_map_counter_decrement(red->rmap.map);
2067 20 : red->rmap.map = NULL;
2068 :
2069 : /* Unset metric. */
2070 20 : red->redist_metric_flag = 0;
2071 20 : red->redist_metric = 0;
2072 :
2073 20 : bgp_redist_del(bgp, afi, type, instance);
2074 :
2075 20 : return CMD_SUCCESS;
2076 : }
2077 :
2078 0 : void bgp_redistribute_redo(struct bgp *bgp)
2079 : {
2080 0 : afi_t afi;
2081 0 : int i;
2082 0 : struct list *red_list;
2083 0 : struct listnode *node;
2084 0 : struct bgp_redist *red;
2085 :
2086 0 : for (afi = AFI_IP; afi < AFI_MAX; afi++) {
2087 0 : for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
2088 :
2089 0 : red_list = bgp->redist[afi][i];
2090 0 : if (!red_list)
2091 0 : continue;
2092 :
2093 0 : for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
2094 0 : bgp_redistribute_resend(bgp, afi, i,
2095 0 : red->instance);
2096 : }
2097 : }
2098 : }
2099 0 : }
2100 :
2101 0 : void bgp_zclient_reset(void)
2102 : {
2103 0 : zclient_reset(zclient);
2104 0 : }
2105 :
2106 : /* Register this instance with Zebra. Invoked upon connect (for
2107 : * default instance) and when other VRFs are learnt (or created and
2108 : * already learnt).
2109 : */
2110 45 : void bgp_zebra_instance_register(struct bgp *bgp)
2111 : {
2112 : /* Don't try to register if we're not connected to Zebra */
2113 45 : if (!zclient || zclient->sock < 0)
2114 : return;
2115 :
2116 45 : if (BGP_DEBUG(zebra, ZEBRA))
2117 0 : zlog_debug("Registering VRF %u", bgp->vrf_id);
2118 :
2119 : /* Register for router-id, interfaces, redistributed routes. */
2120 45 : zclient_send_reg_requests(zclient, bgp->vrf_id);
2121 :
2122 : /* For EVPN instance, register to learn about VNIs, if appropriate. */
2123 45 : if (bgp->advertise_all_vni)
2124 0 : bgp_zebra_advertise_all_vni(bgp, 1);
2125 :
2126 45 : bgp_nht_register_nexthops(bgp);
2127 : }
2128 :
2129 : /* Deregister this instance with Zebra. Invoked upon the instance
2130 : * being deleted (default or VRF) and it is already registered.
2131 : */
2132 45 : void bgp_zebra_instance_deregister(struct bgp *bgp)
2133 : {
2134 : /* Don't try to deregister if we're not connected to Zebra */
2135 45 : if (zclient->sock < 0)
2136 : return;
2137 :
2138 45 : if (BGP_DEBUG(zebra, ZEBRA))
2139 0 : zlog_debug("Deregistering VRF %u", bgp->vrf_id);
2140 :
2141 : /* For EVPN instance, unregister learning about VNIs, if appropriate. */
2142 45 : if (bgp->advertise_all_vni)
2143 0 : bgp_zebra_advertise_all_vni(bgp, 0);
2144 :
2145 : /* Deregister for router-id, interfaces, redistributed routes. */
2146 45 : zclient_send_dereg_requests(zclient, bgp->vrf_id);
2147 : }
2148 :
2149 0 : void bgp_zebra_initiate_radv(struct bgp *bgp, struct peer *peer)
2150 : {
2151 0 : uint32_t ra_interval = BGP_UNNUM_DEFAULT_RA_INTERVAL;
2152 :
2153 : /* Don't try to initiate if we're not connected to Zebra */
2154 0 : if (zclient->sock < 0)
2155 : return;
2156 :
2157 0 : if (BGP_DEBUG(zebra, ZEBRA))
2158 0 : zlog_debug("%u: Initiating RA for peer %s", bgp->vrf_id,
2159 : peer->host);
2160 :
2161 : /*
2162 : * If unnumbered peer (peer->ifp) call thru zapi to start RAs.
2163 : * If we don't have an ifp pointer, call function to find the
2164 : * ifps for a numbered enhe peer to turn RAs on.
2165 : */
2166 0 : peer->ifp ? zclient_send_interface_radv_req(zclient, bgp->vrf_id,
2167 : peer->ifp, 1, ra_interval)
2168 0 : : bgp_nht_reg_enhe_cap_intfs(peer);
2169 : }
2170 :
2171 0 : void bgp_zebra_terminate_radv(struct bgp *bgp, struct peer *peer)
2172 : {
2173 : /* Don't try to terminate if we're not connected to Zebra */
2174 0 : if (zclient->sock < 0)
2175 : return;
2176 :
2177 0 : if (BGP_DEBUG(zebra, ZEBRA))
2178 0 : zlog_debug("%u: Terminating RA for peer %s", bgp->vrf_id,
2179 : peer->host);
2180 :
2181 : /*
2182 : * If unnumbered peer (peer->ifp) call thru zapi to stop RAs.
2183 : * If we don't have an ifp pointer, call function to find the
2184 : * ifps for a numbered enhe peer to turn RAs off.
2185 : */
2186 0 : peer->ifp ? zclient_send_interface_radv_req(zclient, bgp->vrf_id,
2187 : peer->ifp, 0, 0)
2188 0 : : bgp_nht_dereg_enhe_cap_intfs(peer);
2189 : }
2190 :
2191 0 : int bgp_zebra_advertise_subnet(struct bgp *bgp, int advertise, vni_t vni)
2192 : {
2193 0 : struct stream *s = NULL;
2194 :
2195 : /* Check socket. */
2196 0 : if (!zclient || zclient->sock < 0)
2197 : return 0;
2198 :
2199 : /* Don't try to register if Zebra doesn't know of this instance. */
2200 0 : if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) {
2201 0 : if (BGP_DEBUG(zebra, ZEBRA))
2202 0 : zlog_debug(
2203 : "%s: No zebra instance to talk to, cannot advertise subnet",
2204 : __func__);
2205 0 : return 0;
2206 : }
2207 :
2208 0 : s = zclient->obuf;
2209 0 : stream_reset(s);
2210 :
2211 0 : zclient_create_header(s, ZEBRA_ADVERTISE_SUBNET, bgp->vrf_id);
2212 0 : stream_putc(s, advertise);
2213 0 : stream_put3(s, vni);
2214 0 : stream_putw_at(s, 0, stream_get_endp(s));
2215 :
2216 0 : return zclient_send_message(zclient);
2217 : }
2218 :
2219 0 : int bgp_zebra_advertise_svi_macip(struct bgp *bgp, int advertise, vni_t vni)
2220 : {
2221 0 : struct stream *s = NULL;
2222 :
2223 : /* Check socket. */
2224 0 : if (!zclient || zclient->sock < 0)
2225 : return 0;
2226 :
2227 : /* Don't try to register if Zebra doesn't know of this instance. */
2228 0 : if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp))
2229 : return 0;
2230 :
2231 0 : s = zclient->obuf;
2232 0 : stream_reset(s);
2233 :
2234 0 : zclient_create_header(s, ZEBRA_ADVERTISE_SVI_MACIP, bgp->vrf_id);
2235 0 : stream_putc(s, advertise);
2236 0 : stream_putl(s, vni);
2237 0 : stream_putw_at(s, 0, stream_get_endp(s));
2238 :
2239 0 : return zclient_send_message(zclient);
2240 : }
2241 :
2242 0 : int bgp_zebra_advertise_gw_macip(struct bgp *bgp, int advertise, vni_t vni)
2243 : {
2244 0 : struct stream *s = NULL;
2245 :
2246 : /* Check socket. */
2247 0 : if (!zclient || zclient->sock < 0)
2248 : return 0;
2249 :
2250 : /* Don't try to register if Zebra doesn't know of this instance. */
2251 0 : if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) {
2252 0 : if (BGP_DEBUG(zebra, ZEBRA))
2253 0 : zlog_debug(
2254 : "%s: No zebra instance to talk to, not installing gw_macip",
2255 : __func__);
2256 0 : return 0;
2257 : }
2258 :
2259 0 : s = zclient->obuf;
2260 0 : stream_reset(s);
2261 :
2262 0 : zclient_create_header(s, ZEBRA_ADVERTISE_DEFAULT_GW, bgp->vrf_id);
2263 0 : stream_putc(s, advertise);
2264 0 : stream_putl(s, vni);
2265 0 : stream_putw_at(s, 0, stream_get_endp(s));
2266 :
2267 0 : return zclient_send_message(zclient);
2268 : }
2269 :
2270 0 : int bgp_zebra_vxlan_flood_control(struct bgp *bgp,
2271 : enum vxlan_flood_control flood_ctrl)
2272 : {
2273 0 : struct stream *s;
2274 :
2275 : /* Check socket. */
2276 0 : if (!zclient || zclient->sock < 0)
2277 : return 0;
2278 :
2279 : /* Don't try to register if Zebra doesn't know of this instance. */
2280 0 : if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) {
2281 0 : if (BGP_DEBUG(zebra, ZEBRA))
2282 0 : zlog_debug(
2283 : "%s: No zebra instance to talk to, not installing all vni",
2284 : __func__);
2285 0 : return 0;
2286 : }
2287 :
2288 0 : s = zclient->obuf;
2289 0 : stream_reset(s);
2290 :
2291 0 : zclient_create_header(s, ZEBRA_VXLAN_FLOOD_CONTROL, bgp->vrf_id);
2292 0 : stream_putc(s, flood_ctrl);
2293 0 : stream_putw_at(s, 0, stream_get_endp(s));
2294 :
2295 0 : return zclient_send_message(zclient);
2296 : }
2297 :
2298 0 : int bgp_zebra_advertise_all_vni(struct bgp *bgp, int advertise)
2299 : {
2300 0 : struct stream *s;
2301 :
2302 : /* Check socket. */
2303 0 : if (!zclient || zclient->sock < 0)
2304 : return 0;
2305 :
2306 : /* Don't try to register if Zebra doesn't know of this instance. */
2307 0 : if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp))
2308 : return 0;
2309 :
2310 0 : s = zclient->obuf;
2311 0 : stream_reset(s);
2312 :
2313 0 : zclient_create_header(s, ZEBRA_ADVERTISE_ALL_VNI, bgp->vrf_id);
2314 0 : stream_putc(s, advertise);
2315 : /* Also inform current BUM handling setting. This is really
2316 : * relevant only when 'advertise' is set.
2317 : */
2318 0 : stream_putc(s, bgp->vxlan_flood_ctrl);
2319 0 : stream_putw_at(s, 0, stream_get_endp(s));
2320 :
2321 0 : return zclient_send_message(zclient);
2322 : }
2323 :
2324 45 : int bgp_zebra_dup_addr_detection(struct bgp *bgp)
2325 : {
2326 45 : struct stream *s;
2327 :
2328 : /* Check socket. */
2329 45 : if (!zclient || zclient->sock < 0)
2330 : return 0;
2331 :
2332 : /* Don't try to register if Zebra doesn't know of this instance. */
2333 45 : if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp))
2334 : return 0;
2335 :
2336 45 : if (BGP_DEBUG(zebra, ZEBRA))
2337 0 : zlog_debug("dup addr detect %s max_moves %u time %u freeze %s freeze_time %u",
2338 : bgp->evpn_info->dup_addr_detect ?
2339 : "enable" : "disable",
2340 : bgp->evpn_info->dad_max_moves,
2341 : bgp->evpn_info->dad_time,
2342 : bgp->evpn_info->dad_freeze ?
2343 : "enable" : "disable",
2344 : bgp->evpn_info->dad_freeze_time);
2345 :
2346 45 : s = zclient->obuf;
2347 45 : stream_reset(s);
2348 45 : zclient_create_header(s, ZEBRA_DUPLICATE_ADDR_DETECTION,
2349 : bgp->vrf_id);
2350 45 : stream_putl(s, bgp->evpn_info->dup_addr_detect);
2351 45 : stream_putl(s, bgp->evpn_info->dad_time);
2352 45 : stream_putl(s, bgp->evpn_info->dad_max_moves);
2353 45 : stream_putl(s, bgp->evpn_info->dad_freeze);
2354 45 : stream_putl(s, bgp->evpn_info->dad_freeze_time);
2355 45 : stream_putw_at(s, 0, stream_get_endp(s));
2356 :
2357 45 : return zclient_send_message(zclient);
2358 : }
2359 :
2360 0 : static int rule_notify_owner(ZAPI_CALLBACK_ARGS)
2361 : {
2362 0 : uint32_t seqno, priority, unique;
2363 0 : enum zapi_rule_notify_owner note;
2364 0 : struct bgp_pbr_action *bgp_pbra;
2365 0 : struct bgp_pbr_rule *bgp_pbr = NULL;
2366 0 : char ifname[INTERFACE_NAMSIZ + 1];
2367 :
2368 0 : if (!zapi_rule_notify_decode(zclient->ibuf, &seqno, &priority, &unique,
2369 : ifname, ¬e))
2370 : return -1;
2371 :
2372 0 : bgp_pbra = bgp_pbr_action_rule_lookup(vrf_id, unique);
2373 0 : if (!bgp_pbra) {
2374 : /* look in bgp pbr rule */
2375 0 : bgp_pbr = bgp_pbr_rule_lookup(vrf_id, unique);
2376 0 : if (!bgp_pbr && note != ZAPI_RULE_REMOVED) {
2377 0 : if (BGP_DEBUG(zebra, ZEBRA))
2378 0 : zlog_debug("%s: Fail to look BGP rule (%u)",
2379 : __func__, unique);
2380 0 : return 0;
2381 : }
2382 : }
2383 :
2384 0 : switch (note) {
2385 0 : case ZAPI_RULE_FAIL_INSTALL:
2386 0 : if (BGP_DEBUG(zebra, ZEBRA))
2387 0 : zlog_debug("%s: Received RULE_FAIL_INSTALL", __func__);
2388 0 : if (bgp_pbra) {
2389 0 : bgp_pbra->installed = false;
2390 0 : bgp_pbra->install_in_progress = false;
2391 : } else {
2392 0 : bgp_pbr->installed = false;
2393 0 : bgp_pbr->install_in_progress = false;
2394 : }
2395 : break;
2396 0 : case ZAPI_RULE_INSTALLED:
2397 0 : if (bgp_pbra) {
2398 0 : bgp_pbra->installed = true;
2399 0 : bgp_pbra->install_in_progress = false;
2400 : } else {
2401 0 : struct bgp_path_info *path;
2402 0 : struct bgp_path_info_extra *extra;
2403 :
2404 0 : bgp_pbr->installed = true;
2405 0 : bgp_pbr->install_in_progress = false;
2406 0 : bgp_pbr->action->refcnt++;
2407 : /* link bgp_info to bgp_pbr */
2408 0 : path = (struct bgp_path_info *)bgp_pbr->path;
2409 0 : extra = bgp_path_info_extra_get(path);
2410 0 : listnode_add_force(&extra->bgp_fs_iprule,
2411 : bgp_pbr);
2412 : }
2413 0 : if (BGP_DEBUG(zebra, ZEBRA))
2414 0 : zlog_debug("%s: Received RULE_INSTALLED", __func__);
2415 : break;
2416 0 : case ZAPI_RULE_FAIL_REMOVE:
2417 : case ZAPI_RULE_REMOVED:
2418 0 : if (BGP_DEBUG(zebra, ZEBRA))
2419 0 : zlog_debug("%s: Received RULE REMOVED", __func__);
2420 : break;
2421 : }
2422 :
2423 : return 0;
2424 : }
2425 :
2426 0 : static int ipset_notify_owner(ZAPI_CALLBACK_ARGS)
2427 : {
2428 0 : uint32_t unique;
2429 0 : enum zapi_ipset_notify_owner note;
2430 0 : struct bgp_pbr_match *bgp_pbim;
2431 :
2432 0 : if (!zapi_ipset_notify_decode(zclient->ibuf,
2433 : &unique,
2434 : ¬e))
2435 : return -1;
2436 :
2437 0 : bgp_pbim = bgp_pbr_match_ipset_lookup(vrf_id, unique);
2438 0 : if (!bgp_pbim) {
2439 0 : if (BGP_DEBUG(zebra, ZEBRA))
2440 0 : zlog_debug("%s: Fail to look BGP match ( %u, ID %u)",
2441 : __func__, note, unique);
2442 0 : return 0;
2443 : }
2444 :
2445 0 : switch (note) {
2446 0 : case ZAPI_IPSET_FAIL_INSTALL:
2447 0 : if (BGP_DEBUG(zebra, ZEBRA))
2448 0 : zlog_debug("%s: Received IPSET_FAIL_INSTALL", __func__);
2449 0 : bgp_pbim->installed = false;
2450 0 : bgp_pbim->install_in_progress = false;
2451 0 : break;
2452 0 : case ZAPI_IPSET_INSTALLED:
2453 0 : bgp_pbim->installed = true;
2454 0 : bgp_pbim->install_in_progress = false;
2455 0 : if (BGP_DEBUG(zebra, ZEBRA))
2456 0 : zlog_debug("%s: Received IPSET_INSTALLED", __func__);
2457 : break;
2458 0 : case ZAPI_IPSET_FAIL_REMOVE:
2459 : case ZAPI_IPSET_REMOVED:
2460 0 : if (BGP_DEBUG(zebra, ZEBRA))
2461 0 : zlog_debug("%s: Received IPSET REMOVED", __func__);
2462 : break;
2463 : }
2464 :
2465 : return 0;
2466 : }
2467 :
2468 0 : static int ipset_entry_notify_owner(ZAPI_CALLBACK_ARGS)
2469 : {
2470 0 : uint32_t unique;
2471 0 : char ipset_name[ZEBRA_IPSET_NAME_SIZE];
2472 0 : enum zapi_ipset_entry_notify_owner note;
2473 0 : struct bgp_pbr_match_entry *bgp_pbime;
2474 :
2475 0 : if (!zapi_ipset_entry_notify_decode(
2476 : zclient->ibuf,
2477 : &unique,
2478 : ipset_name,
2479 : ¬e))
2480 : return -1;
2481 0 : bgp_pbime = bgp_pbr_match_ipset_entry_lookup(vrf_id,
2482 : ipset_name,
2483 : unique);
2484 0 : if (!bgp_pbime) {
2485 0 : if (BGP_DEBUG(zebra, ZEBRA))
2486 0 : zlog_debug(
2487 : "%s: Fail to look BGP match entry (%u, ID %u)",
2488 : __func__, note, unique);
2489 0 : return 0;
2490 : }
2491 :
2492 0 : switch (note) {
2493 0 : case ZAPI_IPSET_ENTRY_FAIL_INSTALL:
2494 0 : if (BGP_DEBUG(zebra, ZEBRA))
2495 0 : zlog_debug("%s: Received IPSET_ENTRY_FAIL_INSTALL",
2496 : __func__);
2497 0 : bgp_pbime->installed = false;
2498 0 : bgp_pbime->install_in_progress = false;
2499 0 : break;
2500 0 : case ZAPI_IPSET_ENTRY_INSTALLED:
2501 : {
2502 0 : struct bgp_path_info *path;
2503 0 : struct bgp_path_info_extra *extra;
2504 :
2505 0 : bgp_pbime->installed = true;
2506 0 : bgp_pbime->install_in_progress = false;
2507 0 : if (BGP_DEBUG(zebra, ZEBRA))
2508 0 : zlog_debug("%s: Received IPSET_ENTRY_INSTALLED",
2509 : __func__);
2510 : /* link bgp_path_info to bpme */
2511 0 : path = (struct bgp_path_info *)bgp_pbime->path;
2512 0 : extra = bgp_path_info_extra_get(path);
2513 0 : listnode_add_force(&extra->bgp_fs_pbr, bgp_pbime);
2514 : }
2515 0 : break;
2516 0 : case ZAPI_IPSET_ENTRY_FAIL_REMOVE:
2517 : case ZAPI_IPSET_ENTRY_REMOVED:
2518 0 : if (BGP_DEBUG(zebra, ZEBRA))
2519 0 : zlog_debug("%s: Received IPSET_ENTRY_REMOVED",
2520 : __func__);
2521 : break;
2522 : }
2523 : return 0;
2524 : }
2525 :
2526 0 : static int iptable_notify_owner(ZAPI_CALLBACK_ARGS)
2527 : {
2528 0 : uint32_t unique;
2529 0 : enum zapi_iptable_notify_owner note;
2530 0 : struct bgp_pbr_match *bgpm;
2531 :
2532 0 : if (!zapi_iptable_notify_decode(
2533 : zclient->ibuf,
2534 : &unique,
2535 : ¬e))
2536 : return -1;
2537 0 : bgpm = bgp_pbr_match_iptable_lookup(vrf_id, unique);
2538 0 : if (!bgpm) {
2539 0 : if (BGP_DEBUG(zebra, ZEBRA))
2540 0 : zlog_debug("%s: Fail to look BGP iptable (%u %u)",
2541 : __func__, note, unique);
2542 0 : return 0;
2543 : }
2544 0 : switch (note) {
2545 0 : case ZAPI_IPTABLE_FAIL_INSTALL:
2546 0 : if (BGP_DEBUG(zebra, ZEBRA))
2547 0 : zlog_debug("%s: Received IPTABLE_FAIL_INSTALL",
2548 : __func__);
2549 0 : bgpm->installed_in_iptable = false;
2550 0 : bgpm->install_iptable_in_progress = false;
2551 0 : break;
2552 0 : case ZAPI_IPTABLE_INSTALLED:
2553 0 : bgpm->installed_in_iptable = true;
2554 0 : bgpm->install_iptable_in_progress = false;
2555 0 : if (BGP_DEBUG(zebra, ZEBRA))
2556 0 : zlog_debug("%s: Received IPTABLE_INSTALLED", __func__);
2557 0 : bgpm->action->refcnt++;
2558 0 : break;
2559 0 : case ZAPI_IPTABLE_FAIL_REMOVE:
2560 : case ZAPI_IPTABLE_REMOVED:
2561 0 : if (BGP_DEBUG(zebra, ZEBRA))
2562 0 : zlog_debug("%s: Received IPTABLE REMOVED", __func__);
2563 : break;
2564 : }
2565 : return 0;
2566 : }
2567 :
2568 : /* Process route notification messages from RIB */
2569 0 : static int bgp_zebra_route_notify_owner(int command, struct zclient *zclient,
2570 : zebra_size_t length, vrf_id_t vrf_id)
2571 : {
2572 0 : struct prefix p;
2573 0 : enum zapi_route_notify_owner note;
2574 0 : uint32_t table_id;
2575 0 : afi_t afi;
2576 0 : safi_t safi;
2577 0 : struct bgp_dest *dest;
2578 0 : struct bgp *bgp;
2579 0 : struct bgp_path_info *pi, *new_select;
2580 :
2581 0 : if (!zapi_route_notify_decode(zclient->ibuf, &p, &table_id, ¬e,
2582 : &afi, &safi)) {
2583 0 : zlog_err("%s : error in msg decode", __func__);
2584 0 : return -1;
2585 : }
2586 :
2587 : /* Get the bgp instance */
2588 0 : bgp = bgp_lookup_by_vrf_id(vrf_id);
2589 0 : if (!bgp) {
2590 0 : flog_err(EC_BGP_INVALID_BGP_INSTANCE,
2591 : "%s : bgp instance not found vrf %d", __func__,
2592 : vrf_id);
2593 0 : return -1;
2594 : }
2595 :
2596 : /* Find the bgp route node */
2597 0 : dest = bgp_afi_node_lookup(bgp->rib[afi][safi], afi, safi, &p,
2598 : &bgp->vrf_prd);
2599 0 : if (!dest)
2600 : return -1;
2601 :
2602 0 : switch (note) {
2603 0 : case ZAPI_ROUTE_INSTALLED:
2604 0 : new_select = NULL;
2605 : /* Clear the flags so that route can be processed */
2606 0 : UNSET_FLAG(dest->flags, BGP_NODE_FIB_INSTALL_PENDING);
2607 0 : SET_FLAG(dest->flags, BGP_NODE_FIB_INSTALLED);
2608 0 : if (BGP_DEBUG(zebra, ZEBRA))
2609 0 : zlog_debug("route %pRN : INSTALLED", dest);
2610 : /* Find the best route */
2611 0 : for (pi = dest->info; pi; pi = pi->next) {
2612 : /* Process aggregate route */
2613 0 : bgp_aggregate_increment(bgp, &p, pi, afi, safi);
2614 0 : if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
2615 0 : new_select = pi;
2616 : }
2617 : /* Advertise the route */
2618 0 : if (new_select)
2619 0 : group_announce_route(bgp, afi, safi, dest, new_select);
2620 : else {
2621 0 : flog_err(EC_BGP_INVALID_ROUTE,
2622 : "selected route %pRN not found", dest);
2623 :
2624 0 : bgp_dest_unlock_node(dest);
2625 0 : return -1;
2626 : }
2627 0 : break;
2628 0 : case ZAPI_ROUTE_REMOVED:
2629 : /* Route deleted from dataplane, reset the installed flag
2630 : * so that route can be reinstalled when client sends
2631 : * route add later
2632 : */
2633 0 : UNSET_FLAG(dest->flags, BGP_NODE_FIB_INSTALLED);
2634 0 : if (BGP_DEBUG(zebra, ZEBRA))
2635 0 : zlog_debug("route %pRN: Removed from Fib", dest);
2636 : break;
2637 0 : case ZAPI_ROUTE_FAIL_INSTALL:
2638 0 : new_select = NULL;
2639 0 : if (BGP_DEBUG(zebra, ZEBRA))
2640 0 : zlog_debug("route: %pRN Failed to Install into Fib",
2641 : dest);
2642 0 : UNSET_FLAG(dest->flags, BGP_NODE_FIB_INSTALL_PENDING);
2643 0 : UNSET_FLAG(dest->flags, BGP_NODE_FIB_INSTALLED);
2644 0 : for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
2645 0 : if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
2646 0 : new_select = pi;
2647 : }
2648 0 : if (new_select)
2649 0 : group_announce_route(bgp, afi, safi, dest, new_select);
2650 : /* Error will be logged by zebra module */
2651 : break;
2652 0 : case ZAPI_ROUTE_BETTER_ADMIN_WON:
2653 0 : if (BGP_DEBUG(zebra, ZEBRA))
2654 0 : zlog_debug("route: %pRN removed due to better admin won",
2655 : dest);
2656 0 : new_select = NULL;
2657 0 : UNSET_FLAG(dest->flags, BGP_NODE_FIB_INSTALL_PENDING);
2658 0 : UNSET_FLAG(dest->flags, BGP_NODE_FIB_INSTALLED);
2659 0 : for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
2660 0 : bgp_aggregate_decrement(bgp, &p, pi, afi, safi);
2661 0 : if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
2662 0 : new_select = pi;
2663 : }
2664 0 : if (new_select)
2665 0 : group_announce_route(bgp, afi, safi, dest, new_select);
2666 : /* No action required */
2667 : break;
2668 0 : case ZAPI_ROUTE_REMOVE_FAIL:
2669 0 : zlog_warn("%s: Route %pRN failure to remove",
2670 : __func__, dest);
2671 0 : break;
2672 : }
2673 :
2674 0 : bgp_dest_unlock_node(dest);
2675 0 : return 0;
2676 : }
2677 :
2678 : /* this function is used to forge ip rule,
2679 : * - either for iptable/ipset using fwmark id
2680 : * - or for sample ip rule cmd
2681 : */
2682 0 : static void bgp_encode_pbr_rule_action(struct stream *s,
2683 : struct bgp_pbr_action *pbra,
2684 : struct bgp_pbr_rule *pbr)
2685 : {
2686 0 : struct prefix pfx;
2687 0 : uint8_t fam = AF_INET;
2688 0 : char ifname[INTERFACE_NAMSIZ];
2689 :
2690 0 : if (pbra->nh.type == NEXTHOP_TYPE_IPV6)
2691 0 : fam = AF_INET6;
2692 0 : stream_putl(s, 0); /* seqno unused */
2693 0 : if (pbr)
2694 0 : stream_putl(s, pbr->priority);
2695 : else
2696 0 : stream_putl(s, 0);
2697 : /* ruleno unused - priority change
2698 : * ruleno permits distinguishing various FS PBR entries
2699 : * - FS PBR entries based on ipset/iptables
2700 : * - FS PBR entries based on iprule
2701 : * the latter may contain default routing information injected by FS
2702 : */
2703 0 : if (pbr)
2704 0 : stream_putl(s, pbr->unique);
2705 : else
2706 0 : stream_putl(s, pbra->unique);
2707 0 : stream_putc(s, 0); /* ip protocol being used */
2708 0 : if (pbr && pbr->flags & MATCH_IP_SRC_SET)
2709 0 : memcpy(&pfx, &(pbr->src), sizeof(struct prefix));
2710 : else {
2711 0 : memset(&pfx, 0, sizeof(pfx));
2712 0 : pfx.family = fam;
2713 : }
2714 0 : stream_putc(s, pfx.family);
2715 0 : stream_putc(s, pfx.prefixlen);
2716 0 : stream_put(s, &pfx.u.prefix, prefix_blen(&pfx));
2717 :
2718 0 : stream_putw(s, 0); /* src port */
2719 :
2720 0 : if (pbr && pbr->flags & MATCH_IP_DST_SET)
2721 0 : memcpy(&pfx, &(pbr->dst), sizeof(struct prefix));
2722 : else {
2723 0 : memset(&pfx, 0, sizeof(pfx));
2724 0 : pfx.family = fam;
2725 : }
2726 0 : stream_putc(s, pfx.family);
2727 0 : stream_putc(s, pfx.prefixlen);
2728 0 : stream_put(s, &pfx.u.prefix, prefix_blen(&pfx));
2729 :
2730 0 : stream_putw(s, 0); /* dst port */
2731 0 : stream_putc(s, 0); /* dsfield */
2732 : /* if pbr present, fwmark is not used */
2733 0 : if (pbr)
2734 0 : stream_putl(s, 0);
2735 : else
2736 0 : stream_putl(s, pbra->fwmark); /* fwmark */
2737 :
2738 0 : stream_putl(s, 0); /* queue id */
2739 0 : stream_putw(s, 0); /* vlan_id */
2740 0 : stream_putw(s, 0); /* vlan_flags */
2741 0 : stream_putw(s, 0); /* pcp */
2742 :
2743 0 : stream_putl(s, pbra->table_id);
2744 :
2745 0 : memset(ifname, 0, sizeof(ifname));
2746 0 : stream_put(s, ifname, INTERFACE_NAMSIZ); /* ifname unused */
2747 0 : }
2748 :
2749 0 : static void bgp_encode_pbr_ipset_match(struct stream *s,
2750 : struct bgp_pbr_match *pbim)
2751 : {
2752 0 : stream_putl(s, pbim->unique);
2753 0 : stream_putl(s, pbim->type);
2754 0 : stream_putc(s, pbim->family);
2755 0 : stream_put(s, pbim->ipset_name,
2756 : ZEBRA_IPSET_NAME_SIZE);
2757 0 : }
2758 :
2759 0 : static void bgp_encode_pbr_ipset_entry_match(struct stream *s,
2760 : struct bgp_pbr_match_entry *pbime)
2761 : {
2762 0 : stream_putl(s, pbime->unique);
2763 : /* check that back pointer is not null */
2764 0 : stream_put(s, pbime->backpointer->ipset_name,
2765 : ZEBRA_IPSET_NAME_SIZE);
2766 :
2767 0 : stream_putc(s, pbime->src.family);
2768 0 : stream_putc(s, pbime->src.prefixlen);
2769 0 : stream_put(s, &pbime->src.u.prefix, prefix_blen(&pbime->src));
2770 :
2771 0 : stream_putc(s, pbime->dst.family);
2772 0 : stream_putc(s, pbime->dst.prefixlen);
2773 0 : stream_put(s, &pbime->dst.u.prefix, prefix_blen(&pbime->dst));
2774 :
2775 0 : stream_putw(s, pbime->src_port_min);
2776 0 : stream_putw(s, pbime->src_port_max);
2777 0 : stream_putw(s, pbime->dst_port_min);
2778 0 : stream_putw(s, pbime->dst_port_max);
2779 0 : stream_putc(s, pbime->proto);
2780 0 : }
2781 :
2782 0 : static void bgp_encode_pbr_iptable_match(struct stream *s,
2783 : struct bgp_pbr_action *bpa,
2784 : struct bgp_pbr_match *pbm)
2785 : {
2786 0 : stream_putl(s, pbm->unique2);
2787 :
2788 0 : stream_putl(s, pbm->type);
2789 :
2790 0 : stream_putl(s, pbm->flags);
2791 :
2792 : /* TODO: correlate with what is contained
2793 : * into bgp_pbr_action.
2794 : * currently only forward supported
2795 : */
2796 0 : if (bpa->nh.type == NEXTHOP_TYPE_BLACKHOLE)
2797 0 : stream_putl(s, ZEBRA_IPTABLES_DROP);
2798 : else
2799 0 : stream_putl(s, ZEBRA_IPTABLES_FORWARD);
2800 0 : stream_putl(s, bpa->fwmark);
2801 0 : stream_put(s, pbm->ipset_name,
2802 : ZEBRA_IPSET_NAME_SIZE);
2803 0 : stream_putc(s, pbm->family);
2804 0 : stream_putw(s, pbm->pkt_len_min);
2805 0 : stream_putw(s, pbm->pkt_len_max);
2806 0 : stream_putw(s, pbm->tcp_flags);
2807 0 : stream_putw(s, pbm->tcp_mask_flags);
2808 0 : stream_putc(s, pbm->dscp_value);
2809 0 : stream_putc(s, pbm->fragment);
2810 0 : stream_putc(s, pbm->protocol);
2811 0 : stream_putw(s, pbm->flow_label);
2812 0 : }
2813 :
2814 : /* BGP has established connection with Zebra. */
2815 48 : static void bgp_zebra_connected(struct zclient *zclient)
2816 : {
2817 48 : struct bgp *bgp;
2818 :
2819 48 : zclient_num_connects++; /* increment even if not responding */
2820 :
2821 : /* Send the client registration */
2822 48 : bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER, VRF_DEFAULT);
2823 :
2824 : /* At this point, we may or may not have BGP instances configured, but
2825 : * we're only interested in the default VRF (others wouldn't have learnt
2826 : * the VRF from Zebra yet.)
2827 : */
2828 48 : bgp = bgp_get_default();
2829 48 : if (!bgp)
2830 : return;
2831 :
2832 0 : bgp_zebra_instance_register(bgp);
2833 :
2834 : /* tell label pool that zebra is connected */
2835 0 : bgp_lp_event_zebra_up();
2836 :
2837 : /* TODO - What if we have peers and networks configured, do we have to
2838 : * kick-start them?
2839 : */
2840 0 : BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA(bgp, bgp->peer);
2841 : }
2842 :
2843 0 : static int bgp_zebra_process_local_es_add(ZAPI_CALLBACK_ARGS)
2844 : {
2845 0 : esi_t esi;
2846 0 : struct bgp *bgp = NULL;
2847 0 : struct stream *s = NULL;
2848 0 : char buf[ESI_STR_LEN];
2849 0 : struct in_addr originator_ip;
2850 0 : uint8_t active;
2851 0 : uint8_t bypass;
2852 0 : uint16_t df_pref;
2853 :
2854 0 : bgp = bgp_lookup_by_vrf_id(vrf_id);
2855 0 : if (!bgp)
2856 : return 0;
2857 :
2858 0 : s = zclient->ibuf;
2859 0 : stream_get(&esi, s, sizeof(esi_t));
2860 0 : originator_ip.s_addr = stream_get_ipv4(s);
2861 0 : active = stream_getc(s);
2862 0 : df_pref = stream_getw(s);
2863 0 : bypass = stream_getc(s);
2864 :
2865 0 : if (BGP_DEBUG(zebra, ZEBRA))
2866 0 : zlog_debug(
2867 : "Rx add ESI %s originator-ip %pI4 active %u df_pref %u %s",
2868 : esi_to_str(&esi, buf, sizeof(buf)), &originator_ip,
2869 : active, df_pref, bypass ? "bypass" : "");
2870 :
2871 0 : frrtrace(5, frr_bgp, evpn_mh_local_es_add_zrecv, &esi, originator_ip,
2872 : active, bypass, df_pref);
2873 :
2874 0 : bgp_evpn_local_es_add(bgp, &esi, originator_ip, active, df_pref,
2875 : !!bypass);
2876 :
2877 0 : return 0;
2878 : }
2879 :
2880 0 : static int bgp_zebra_process_local_es_del(ZAPI_CALLBACK_ARGS)
2881 : {
2882 0 : esi_t esi;
2883 0 : struct bgp *bgp = NULL;
2884 0 : struct stream *s = NULL;
2885 0 : char buf[ESI_STR_LEN];
2886 :
2887 0 : memset(&esi, 0, sizeof(esi_t));
2888 0 : bgp = bgp_lookup_by_vrf_id(vrf_id);
2889 0 : if (!bgp)
2890 : return 0;
2891 :
2892 0 : s = zclient->ibuf;
2893 0 : stream_get(&esi, s, sizeof(esi_t));
2894 :
2895 0 : if (BGP_DEBUG(zebra, ZEBRA))
2896 0 : zlog_debug("Rx del ESI %s",
2897 : esi_to_str(&esi, buf, sizeof(buf)));
2898 :
2899 0 : frrtrace(1, frr_bgp, evpn_mh_local_es_del_zrecv, &esi);
2900 :
2901 0 : bgp_evpn_local_es_del(bgp, &esi);
2902 :
2903 0 : return 0;
2904 : }
2905 :
2906 0 : static int bgp_zebra_process_local_es_evi(ZAPI_CALLBACK_ARGS)
2907 : {
2908 0 : esi_t esi;
2909 0 : vni_t vni;
2910 0 : struct bgp *bgp;
2911 0 : struct stream *s;
2912 0 : char buf[ESI_STR_LEN];
2913 :
2914 0 : bgp = bgp_lookup_by_vrf_id(vrf_id);
2915 0 : if (!bgp)
2916 : return 0;
2917 :
2918 0 : s = zclient->ibuf;
2919 0 : stream_get(&esi, s, sizeof(esi_t));
2920 0 : vni = stream_getl(s);
2921 :
2922 0 : if (BGP_DEBUG(zebra, ZEBRA))
2923 0 : zlog_debug("Rx %s ESI %s VNI %u",
2924 : (cmd == ZEBRA_VNI_ADD) ? "add" : "del",
2925 : esi_to_str(&esi, buf, sizeof(buf)), vni);
2926 :
2927 0 : if (cmd == ZEBRA_LOCAL_ES_EVI_ADD) {
2928 0 : frrtrace(2, frr_bgp, evpn_mh_local_es_evi_add_zrecv, &esi, vni);
2929 :
2930 0 : bgp_evpn_local_es_evi_add(bgp, &esi, vni);
2931 : } else {
2932 0 : frrtrace(2, frr_bgp, evpn_mh_local_es_evi_del_zrecv, &esi, vni);
2933 :
2934 0 : bgp_evpn_local_es_evi_del(bgp, &esi, vni);
2935 : }
2936 :
2937 : return 0;
2938 : }
2939 :
2940 0 : static int bgp_zebra_process_local_l3vni(ZAPI_CALLBACK_ARGS)
2941 : {
2942 0 : int filter = 0;
2943 0 : vni_t l3vni = 0;
2944 0 : struct ethaddr svi_rmac, vrr_rmac = {.octet = {0} };
2945 0 : struct in_addr originator_ip;
2946 0 : struct stream *s;
2947 0 : ifindex_t svi_ifindex;
2948 0 : bool is_anycast_mac = false;
2949 :
2950 0 : memset(&svi_rmac, 0, sizeof(svi_rmac));
2951 0 : memset(&originator_ip, 0, sizeof(originator_ip));
2952 0 : s = zclient->ibuf;
2953 0 : l3vni = stream_getl(s);
2954 0 : if (cmd == ZEBRA_L3VNI_ADD) {
2955 0 : stream_get(&svi_rmac, s, sizeof(struct ethaddr));
2956 0 : originator_ip.s_addr = stream_get_ipv4(s);
2957 0 : stream_get(&filter, s, sizeof(int));
2958 0 : svi_ifindex = stream_getl(s);
2959 0 : stream_get(&vrr_rmac, s, sizeof(struct ethaddr));
2960 0 : is_anycast_mac = stream_getl(s);
2961 :
2962 0 : if (BGP_DEBUG(zebra, ZEBRA))
2963 0 : zlog_debug(
2964 : "Rx L3-VNI ADD VRF %s VNI %u RMAC svi-mac %pEA vrr-mac %pEA filter %s svi-if %u",
2965 : vrf_id_to_name(vrf_id), l3vni, &svi_rmac,
2966 : &vrr_rmac,
2967 : filter ? "prefix-routes-only" : "none",
2968 : svi_ifindex);
2969 :
2970 0 : frrtrace(8, frr_bgp, evpn_local_l3vni_add_zrecv, l3vni, vrf_id,
2971 : &svi_rmac, &vrr_rmac, filter, originator_ip,
2972 : svi_ifindex, is_anycast_mac);
2973 :
2974 0 : bgp_evpn_local_l3vni_add(l3vni, vrf_id, &svi_rmac, &vrr_rmac,
2975 : originator_ip, filter, svi_ifindex,
2976 : is_anycast_mac);
2977 : } else {
2978 0 : if (BGP_DEBUG(zebra, ZEBRA))
2979 0 : zlog_debug("Rx L3-VNI DEL VRF %s VNI %u",
2980 : vrf_id_to_name(vrf_id), l3vni);
2981 :
2982 0 : frrtrace(2, frr_bgp, evpn_local_l3vni_del_zrecv, l3vni, vrf_id);
2983 :
2984 0 : bgp_evpn_local_l3vni_del(l3vni, vrf_id);
2985 : }
2986 :
2987 0 : return 0;
2988 : }
2989 :
2990 0 : static int bgp_zebra_process_local_vni(ZAPI_CALLBACK_ARGS)
2991 : {
2992 0 : struct stream *s;
2993 0 : vni_t vni;
2994 0 : struct bgp *bgp;
2995 0 : struct in_addr vtep_ip = {INADDR_ANY};
2996 0 : vrf_id_t tenant_vrf_id = VRF_DEFAULT;
2997 0 : struct in_addr mcast_grp = {INADDR_ANY};
2998 0 : ifindex_t svi_ifindex = 0;
2999 :
3000 0 : s = zclient->ibuf;
3001 0 : vni = stream_getl(s);
3002 0 : if (cmd == ZEBRA_VNI_ADD) {
3003 0 : vtep_ip.s_addr = stream_get_ipv4(s);
3004 0 : stream_get(&tenant_vrf_id, s, sizeof(vrf_id_t));
3005 0 : mcast_grp.s_addr = stream_get_ipv4(s);
3006 0 : stream_get(&svi_ifindex, s, sizeof(ifindex_t));
3007 : }
3008 :
3009 0 : bgp = bgp_lookup_by_vrf_id(vrf_id);
3010 0 : if (!bgp)
3011 : return 0;
3012 :
3013 0 : if (BGP_DEBUG(zebra, ZEBRA))
3014 0 : zlog_debug(
3015 : "Rx VNI %s VRF %s VNI %u tenant-vrf %s SVI ifindex %u",
3016 : (cmd == ZEBRA_VNI_ADD) ? "add" : "del",
3017 : vrf_id_to_name(vrf_id), vni,
3018 : vrf_id_to_name(tenant_vrf_id), svi_ifindex);
3019 :
3020 0 : if (cmd == ZEBRA_VNI_ADD) {
3021 0 : frrtrace(4, frr_bgp, evpn_local_vni_add_zrecv, vni, vtep_ip,
3022 : tenant_vrf_id, mcast_grp);
3023 :
3024 0 : return bgp_evpn_local_vni_add(
3025 : bgp, vni,
3026 : vtep_ip.s_addr != INADDR_ANY ? vtep_ip : bgp->router_id,
3027 : tenant_vrf_id, mcast_grp, svi_ifindex);
3028 : } else {
3029 0 : frrtrace(1, frr_bgp, evpn_local_vni_del_zrecv, vni);
3030 :
3031 0 : return bgp_evpn_local_vni_del(bgp, vni);
3032 : }
3033 : }
3034 :
3035 0 : static int bgp_zebra_process_local_macip(ZAPI_CALLBACK_ARGS)
3036 : {
3037 0 : struct stream *s;
3038 0 : vni_t vni;
3039 0 : struct bgp *bgp;
3040 0 : struct ethaddr mac;
3041 0 : struct ipaddr ip;
3042 0 : int ipa_len;
3043 0 : uint8_t flags = 0;
3044 0 : uint32_t seqnum = 0;
3045 0 : int state = 0;
3046 0 : char buf2[ESI_STR_LEN];
3047 0 : esi_t esi;
3048 :
3049 0 : memset(&ip, 0, sizeof(ip));
3050 0 : s = zclient->ibuf;
3051 0 : vni = stream_getl(s);
3052 0 : stream_get(&mac.octet, s, ETH_ALEN);
3053 0 : ipa_len = stream_getl(s);
3054 0 : if (ipa_len != 0 && ipa_len != IPV4_MAX_BYTELEN
3055 0 : && ipa_len != IPV6_MAX_BYTELEN) {
3056 0 : flog_err(EC_BGP_MACIP_LEN,
3057 : "%u:Recv MACIP %s with invalid IP addr length %d",
3058 : vrf_id, (cmd == ZEBRA_MACIP_ADD) ? "Add" : "Del",
3059 : ipa_len);
3060 0 : return -1;
3061 : }
3062 :
3063 0 : if (ipa_len) {
3064 0 : ip.ipa_type =
3065 0 : (ipa_len == IPV4_MAX_BYTELEN) ? IPADDR_V4 : IPADDR_V6;
3066 0 : stream_get(&ip.ip.addr, s, ipa_len);
3067 : }
3068 0 : if (cmd == ZEBRA_MACIP_ADD) {
3069 0 : flags = stream_getc(s);
3070 0 : seqnum = stream_getl(s);
3071 0 : stream_get(&esi, s, sizeof(esi_t));
3072 : } else {
3073 0 : state = stream_getl(s);
3074 0 : memset(&esi, 0, sizeof(esi_t));
3075 : }
3076 :
3077 0 : bgp = bgp_lookup_by_vrf_id(vrf_id);
3078 0 : if (!bgp)
3079 : return 0;
3080 :
3081 0 : if (BGP_DEBUG(zebra, ZEBRA))
3082 0 : zlog_debug(
3083 : "%u:Recv MACIP %s f 0x%x MAC %pEA IP %pIA VNI %u seq %u state %d ESI %s",
3084 : vrf_id, (cmd == ZEBRA_MACIP_ADD) ? "Add" : "Del", flags,
3085 : &mac, &ip, vni, seqnum, state,
3086 : esi_to_str(&esi, buf2, sizeof(buf2)));
3087 :
3088 0 : if (cmd == ZEBRA_MACIP_ADD) {
3089 0 : frrtrace(6, frr_bgp, evpn_local_macip_add_zrecv, vni, &mac, &ip,
3090 : flags, seqnum, &esi);
3091 :
3092 0 : return bgp_evpn_local_macip_add(bgp, vni, &mac, &ip,
3093 : flags, seqnum, &esi);
3094 : } else {
3095 0 : frrtrace(4, frr_bgp, evpn_local_macip_del_zrecv, vni, &mac, &ip,
3096 : state);
3097 :
3098 0 : return bgp_evpn_local_macip_del(bgp, vni, &mac, &ip, state);
3099 : }
3100 : }
3101 :
3102 0 : static int bgp_zebra_process_local_ip_prefix(ZAPI_CALLBACK_ARGS)
3103 : {
3104 0 : struct stream *s = NULL;
3105 0 : struct bgp *bgp_vrf = NULL;
3106 0 : struct prefix p;
3107 :
3108 0 : memset(&p, 0, sizeof(p));
3109 0 : s = zclient->ibuf;
3110 0 : stream_get(&p, s, sizeof(struct prefix));
3111 :
3112 0 : bgp_vrf = bgp_lookup_by_vrf_id(vrf_id);
3113 0 : if (!bgp_vrf)
3114 : return 0;
3115 :
3116 0 : if (BGP_DEBUG(zebra, ZEBRA))
3117 0 : zlog_debug("Recv prefix %pFX %s on vrf %s", &p,
3118 : (cmd == ZEBRA_IP_PREFIX_ROUTE_ADD) ? "ADD" : "DEL",
3119 : vrf_id_to_name(vrf_id));
3120 :
3121 0 : if (cmd == ZEBRA_IP_PREFIX_ROUTE_ADD) {
3122 :
3123 0 : if (p.family == AF_INET)
3124 0 : bgp_evpn_advertise_type5_route(bgp_vrf, &p, NULL,
3125 : AFI_IP, SAFI_UNICAST);
3126 : else
3127 0 : bgp_evpn_advertise_type5_route(bgp_vrf, &p, NULL,
3128 : AFI_IP6, SAFI_UNICAST);
3129 :
3130 : } else {
3131 0 : if (p.family == AF_INET)
3132 0 : bgp_evpn_withdraw_type5_route(bgp_vrf, &p, AFI_IP,
3133 : SAFI_UNICAST);
3134 : else
3135 0 : bgp_evpn_withdraw_type5_route(bgp_vrf, &p, AFI_IP6,
3136 : SAFI_UNICAST);
3137 : }
3138 : return 0;
3139 : }
3140 :
3141 0 : static int bgp_zebra_process_label_chunk(ZAPI_CALLBACK_ARGS)
3142 : {
3143 0 : struct stream *s = NULL;
3144 0 : uint8_t response_keep;
3145 0 : uint32_t first;
3146 0 : uint32_t last;
3147 0 : uint8_t proto;
3148 0 : unsigned short instance;
3149 :
3150 0 : s = zclient->ibuf;
3151 0 : STREAM_GETC(s, proto);
3152 0 : STREAM_GETW(s, instance);
3153 0 : STREAM_GETC(s, response_keep);
3154 0 : STREAM_GETL(s, first);
3155 0 : STREAM_GETL(s, last);
3156 :
3157 0 : if (zclient->redist_default != proto) {
3158 0 : flog_err(EC_BGP_LM_ERROR, "Got LM msg with wrong proto %u",
3159 : proto);
3160 0 : return 0;
3161 : }
3162 0 : if (zclient->instance != instance) {
3163 0 : flog_err(EC_BGP_LM_ERROR, "Got LM msg with wrong instance %u",
3164 : proto);
3165 0 : return 0;
3166 : }
3167 :
3168 0 : if (first > last ||
3169 0 : first < MPLS_LABEL_UNRESERVED_MIN ||
3170 : last > MPLS_LABEL_UNRESERVED_MAX) {
3171 :
3172 0 : flog_err(EC_BGP_LM_ERROR, "%s: Invalid Label chunk: %u - %u",
3173 : __func__, first, last);
3174 0 : return 0;
3175 : }
3176 0 : if (BGP_DEBUG(zebra, ZEBRA)) {
3177 0 : zlog_debug("Label Chunk assign: %u - %u (%u) ",
3178 : first, last, response_keep);
3179 : }
3180 :
3181 0 : bgp_lp_event_chunk(response_keep, first, last);
3182 :
3183 0 : return 0;
3184 :
3185 : stream_failure: /* for STREAM_GETX */
3186 : return -1;
3187 : }
3188 :
3189 : extern struct zebra_privs_t bgpd_privs;
3190 :
3191 307 : static int bgp_ifp_create(struct interface *ifp)
3192 : {
3193 307 : struct bgp *bgp;
3194 :
3195 307 : if (BGP_DEBUG(zebra, ZEBRA))
3196 0 : zlog_debug("Rx Intf add VRF %u IF %s", ifp->vrf->vrf_id,
3197 : ifp->name);
3198 :
3199 307 : bgp = ifp->vrf->info;
3200 307 : if (!bgp)
3201 : return 0;
3202 :
3203 295 : bgp_mac_add_mac_entry(ifp);
3204 :
3205 295 : bgp_update_interface_nbrs(bgp, ifp, ifp);
3206 295 : hook_call(bgp_vrf_status_changed, bgp, ifp);
3207 295 : return 0;
3208 : }
3209 :
3210 0 : static int bgp_zebra_process_srv6_locator_chunk(ZAPI_CALLBACK_ARGS)
3211 : {
3212 0 : struct stream *s = NULL;
3213 0 : struct bgp *bgp = bgp_get_default();
3214 0 : struct listnode *node;
3215 0 : struct srv6_locator_chunk *c;
3216 0 : struct srv6_locator_chunk *chunk = srv6_locator_chunk_alloc();
3217 :
3218 0 : s = zclient->ibuf;
3219 0 : zapi_srv6_locator_chunk_decode(s, chunk);
3220 :
3221 0 : if (strcmp(bgp->srv6_locator_name, chunk->locator_name) != 0) {
3222 0 : zlog_err("%s: Locator name unmatch %s:%s", __func__,
3223 : bgp->srv6_locator_name, chunk->locator_name);
3224 0 : srv6_locator_chunk_free(&chunk);
3225 0 : return 0;
3226 : }
3227 :
3228 0 : for (ALL_LIST_ELEMENTS_RO(bgp->srv6_locator_chunks, node, c)) {
3229 0 : if (!prefix_cmp(&c->prefix, &chunk->prefix)) {
3230 0 : srv6_locator_chunk_free(&chunk);
3231 0 : return 0;
3232 : }
3233 : }
3234 :
3235 0 : listnode_add(bgp->srv6_locator_chunks, chunk);
3236 0 : vpn_leak_postchange_all();
3237 0 : return 0;
3238 : }
3239 :
3240 0 : static int bgp_zebra_process_srv6_locator_add(ZAPI_CALLBACK_ARGS)
3241 : {
3242 0 : struct srv6_locator loc = {};
3243 0 : struct bgp *bgp = bgp_get_default();
3244 0 : const char *loc_name = bgp->srv6_locator_name;
3245 :
3246 0 : if (zapi_srv6_locator_decode(zclient->ibuf, &loc) < 0)
3247 : return -1;
3248 :
3249 0 : if (!bgp || !bgp->srv6_enabled)
3250 : return 0;
3251 :
3252 0 : if (bgp_zebra_srv6_manager_get_locator_chunk(loc_name) < 0)
3253 : return -1;
3254 :
3255 : return 0;
3256 : }
3257 :
3258 0 : static int bgp_zebra_process_srv6_locator_delete(ZAPI_CALLBACK_ARGS)
3259 : {
3260 0 : struct srv6_locator loc = {};
3261 0 : struct bgp *bgp = bgp_get_default();
3262 0 : struct listnode *node, *nnode;
3263 0 : struct srv6_locator_chunk *chunk, *tovpn_sid_locator;
3264 0 : struct bgp_srv6_function *func;
3265 0 : struct bgp *bgp_vrf;
3266 0 : struct in6_addr *tovpn_sid;
3267 0 : struct prefix_ipv6 tmp_prefi;
3268 :
3269 0 : if (zapi_srv6_locator_decode(zclient->ibuf, &loc) < 0)
3270 : return -1;
3271 :
3272 : // refresh chunks
3273 0 : for (ALL_LIST_ELEMENTS(bgp->srv6_locator_chunks, node, nnode, chunk))
3274 0 : if (prefix_match((struct prefix *)&loc.prefix,
3275 0 : (struct prefix *)&chunk->prefix)) {
3276 0 : listnode_delete(bgp->srv6_locator_chunks, chunk);
3277 0 : srv6_locator_chunk_free(&chunk);
3278 : }
3279 :
3280 : // refresh functions
3281 0 : for (ALL_LIST_ELEMENTS(bgp->srv6_functions, node, nnode, func)) {
3282 0 : tmp_prefi.family = AF_INET6;
3283 0 : tmp_prefi.prefixlen = 128;
3284 0 : tmp_prefi.prefix = func->sid;
3285 0 : if (prefix_match((struct prefix *)&loc.prefix,
3286 : (struct prefix *)&tmp_prefi)) {
3287 0 : listnode_delete(bgp->srv6_functions, func);
3288 0 : XFREE(MTYPE_BGP_SRV6_FUNCTION, func);
3289 : }
3290 : }
3291 :
3292 : // refresh tovpn_sid
3293 0 : for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, bgp_vrf)) {
3294 0 : if (bgp_vrf->inst_type != BGP_INSTANCE_TYPE_VRF)
3295 0 : continue;
3296 :
3297 : // refresh vpnv4 tovpn_sid
3298 0 : tovpn_sid = bgp_vrf->vpn_policy[AFI_IP].tovpn_sid;
3299 0 : if (tovpn_sid) {
3300 0 : tmp_prefi.family = AF_INET6;
3301 0 : tmp_prefi.prefixlen = 128;
3302 0 : tmp_prefi.prefix = *tovpn_sid;
3303 0 : if (prefix_match((struct prefix *)&loc.prefix,
3304 : (struct prefix *)&tmp_prefi))
3305 0 : XFREE(MTYPE_BGP_SRV6_SID,
3306 : bgp_vrf->vpn_policy[AFI_IP].tovpn_sid);
3307 : }
3308 :
3309 : // refresh vpnv6 tovpn_sid
3310 0 : tovpn_sid = bgp_vrf->vpn_policy[AFI_IP6].tovpn_sid;
3311 0 : if (tovpn_sid) {
3312 0 : tmp_prefi.family = AF_INET6;
3313 0 : tmp_prefi.prefixlen = 128;
3314 0 : tmp_prefi.prefix = *tovpn_sid;
3315 0 : if (prefix_match((struct prefix *)&loc.prefix,
3316 : (struct prefix *)&tmp_prefi))
3317 0 : XFREE(MTYPE_BGP_SRV6_SID,
3318 : bgp_vrf->vpn_policy[AFI_IP6].tovpn_sid);
3319 : }
3320 :
3321 : /* refresh per-vrf tovpn_sid */
3322 0 : tovpn_sid = bgp_vrf->tovpn_sid;
3323 0 : if (tovpn_sid) {
3324 0 : tmp_prefi.family = AF_INET6;
3325 0 : tmp_prefi.prefixlen = IPV6_MAX_BITLEN;
3326 0 : tmp_prefi.prefix = *tovpn_sid;
3327 0 : if (prefix_match((struct prefix *)&loc.prefix,
3328 : (struct prefix *)&tmp_prefi))
3329 0 : XFREE(MTYPE_BGP_SRV6_SID, bgp_vrf->tovpn_sid);
3330 : }
3331 : }
3332 :
3333 0 : vpn_leak_postchange_all();
3334 :
3335 : /* refresh tovpn_sid_locator */
3336 0 : for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, bgp_vrf)) {
3337 0 : if (bgp_vrf->inst_type != BGP_INSTANCE_TYPE_VRF)
3338 0 : continue;
3339 :
3340 : /* refresh vpnv4 tovpn_sid_locator */
3341 0 : tovpn_sid_locator =
3342 : bgp_vrf->vpn_policy[AFI_IP].tovpn_sid_locator;
3343 0 : if (tovpn_sid_locator) {
3344 0 : tmp_prefi.family = AF_INET6;
3345 0 : tmp_prefi.prefixlen = IPV6_MAX_BITLEN;
3346 0 : tmp_prefi.prefix = tovpn_sid_locator->prefix.prefix;
3347 0 : if (prefix_match((struct prefix *)&loc.prefix,
3348 : (struct prefix *)&tmp_prefi))
3349 0 : srv6_locator_chunk_free(
3350 : &bgp_vrf->vpn_policy[AFI_IP]
3351 : .tovpn_sid_locator);
3352 : }
3353 :
3354 : /* refresh vpnv6 tovpn_sid_locator */
3355 0 : tovpn_sid_locator =
3356 : bgp_vrf->vpn_policy[AFI_IP6].tovpn_sid_locator;
3357 0 : if (tovpn_sid_locator) {
3358 0 : tmp_prefi.family = AF_INET6;
3359 0 : tmp_prefi.prefixlen = IPV6_MAX_BITLEN;
3360 0 : tmp_prefi.prefix = tovpn_sid_locator->prefix.prefix;
3361 0 : if (prefix_match((struct prefix *)&loc.prefix,
3362 : (struct prefix *)&tmp_prefi))
3363 0 : srv6_locator_chunk_free(
3364 : &bgp_vrf->vpn_policy[AFI_IP6]
3365 : .tovpn_sid_locator);
3366 : }
3367 :
3368 : /* refresh per-vrf tovpn_sid_locator */
3369 0 : tovpn_sid_locator = bgp_vrf->tovpn_sid_locator;
3370 0 : if (tovpn_sid_locator) {
3371 0 : tmp_prefi.family = AF_INET6;
3372 0 : tmp_prefi.prefixlen = IPV6_MAX_BITLEN;
3373 0 : tmp_prefi.prefix = tovpn_sid_locator->prefix.prefix;
3374 0 : if (prefix_match((struct prefix *)&loc.prefix,
3375 : (struct prefix *)&tmp_prefi))
3376 0 : srv6_locator_chunk_free(
3377 : &bgp_vrf->tovpn_sid_locator);
3378 : }
3379 : }
3380 :
3381 : return 0;
3382 : }
3383 :
3384 : static zclient_handler *const bgp_handlers[] = {
3385 : [ZEBRA_ROUTER_ID_UPDATE] = bgp_router_id_update,
3386 : [ZEBRA_INTERFACE_ADDRESS_ADD] = bgp_interface_address_add,
3387 : [ZEBRA_INTERFACE_ADDRESS_DELETE] = bgp_interface_address_delete,
3388 : [ZEBRA_INTERFACE_NBR_ADDRESS_ADD] = bgp_interface_nbr_address_add,
3389 : [ZEBRA_INTERFACE_NBR_ADDRESS_DELETE] = bgp_interface_nbr_address_delete,
3390 : [ZEBRA_INTERFACE_VRF_UPDATE] = bgp_interface_vrf_update,
3391 : [ZEBRA_REDISTRIBUTE_ROUTE_ADD] = zebra_read_route,
3392 : [ZEBRA_REDISTRIBUTE_ROUTE_DEL] = zebra_read_route,
3393 : [ZEBRA_NEXTHOP_UPDATE] = bgp_read_nexthop_update,
3394 : [ZEBRA_FEC_UPDATE] = bgp_read_fec_update,
3395 : [ZEBRA_LOCAL_ES_ADD] = bgp_zebra_process_local_es_add,
3396 : [ZEBRA_LOCAL_ES_DEL] = bgp_zebra_process_local_es_del,
3397 : [ZEBRA_VNI_ADD] = bgp_zebra_process_local_vni,
3398 : [ZEBRA_LOCAL_ES_EVI_ADD] = bgp_zebra_process_local_es_evi,
3399 : [ZEBRA_LOCAL_ES_EVI_DEL] = bgp_zebra_process_local_es_evi,
3400 : [ZEBRA_VNI_DEL] = bgp_zebra_process_local_vni,
3401 : [ZEBRA_MACIP_ADD] = bgp_zebra_process_local_macip,
3402 : [ZEBRA_MACIP_DEL] = bgp_zebra_process_local_macip,
3403 : [ZEBRA_L3VNI_ADD] = bgp_zebra_process_local_l3vni,
3404 : [ZEBRA_L3VNI_DEL] = bgp_zebra_process_local_l3vni,
3405 : [ZEBRA_IP_PREFIX_ROUTE_ADD] = bgp_zebra_process_local_ip_prefix,
3406 : [ZEBRA_IP_PREFIX_ROUTE_DEL] = bgp_zebra_process_local_ip_prefix,
3407 : [ZEBRA_GET_LABEL_CHUNK] = bgp_zebra_process_label_chunk,
3408 : [ZEBRA_RULE_NOTIFY_OWNER] = rule_notify_owner,
3409 : [ZEBRA_IPSET_NOTIFY_OWNER] = ipset_notify_owner,
3410 : [ZEBRA_IPSET_ENTRY_NOTIFY_OWNER] = ipset_entry_notify_owner,
3411 : [ZEBRA_IPTABLE_NOTIFY_OWNER] = iptable_notify_owner,
3412 : [ZEBRA_ROUTE_NOTIFY_OWNER] = bgp_zebra_route_notify_owner,
3413 : [ZEBRA_SRV6_LOCATOR_ADD] = bgp_zebra_process_srv6_locator_add,
3414 : [ZEBRA_SRV6_LOCATOR_DELETE] = bgp_zebra_process_srv6_locator_delete,
3415 : [ZEBRA_SRV6_MANAGER_GET_LOCATOR_CHUNK] =
3416 : bgp_zebra_process_srv6_locator_chunk,
3417 : };
3418 :
3419 105 : static int bgp_if_new_hook(struct interface *ifp)
3420 : {
3421 105 : struct bgp_interface *iifp;
3422 :
3423 105 : if (ifp->info)
3424 : return 0;
3425 105 : iifp = XCALLOC(MTYPE_BGP_IF_INFO, sizeof(struct bgp_interface));
3426 105 : ifp->info = iifp;
3427 :
3428 105 : return 0;
3429 : }
3430 :
3431 105 : static int bgp_if_delete_hook(struct interface *ifp)
3432 : {
3433 105 : XFREE(MTYPE_BGP_IF_INFO, ifp->info);
3434 105 : return 0;
3435 : }
3436 :
3437 48 : void bgp_if_init(void)
3438 : {
3439 : /* Initialize Zebra interface data structure. */
3440 48 : hook_register_prio(if_add, 0, bgp_if_new_hook);
3441 48 : hook_register_prio(if_del, 0, bgp_if_delete_hook);
3442 48 : }
3443 :
3444 48 : void bgp_zebra_init(struct thread_master *master, unsigned short instance)
3445 : {
3446 48 : zclient_num_connects = 0;
3447 :
3448 48 : if_zapi_callbacks(bgp_ifp_create, bgp_ifp_up,
3449 : bgp_ifp_down, bgp_ifp_destroy);
3450 :
3451 : /* Set default values. */
3452 48 : zclient = zclient_new(master, &zclient_options_default, bgp_handlers,
3453 : array_size(bgp_handlers));
3454 48 : zclient_init(zclient, ZEBRA_ROUTE_BGP, 0, &bgpd_privs);
3455 48 : zclient->zebra_connected = bgp_zebra_connected;
3456 48 : zclient->instance = instance;
3457 48 : }
3458 :
3459 48 : void bgp_zebra_destroy(void)
3460 : {
3461 48 : if (zclient == NULL)
3462 : return;
3463 48 : zclient_stop(zclient);
3464 48 : zclient_free(zclient);
3465 48 : zclient = NULL;
3466 : }
3467 :
3468 422 : int bgp_zebra_num_connects(void)
3469 : {
3470 422 : return zclient_num_connects;
3471 : }
3472 :
3473 0 : void bgp_send_pbr_rule_action(struct bgp_pbr_action *pbra,
3474 : struct bgp_pbr_rule *pbr,
3475 : bool install)
3476 : {
3477 0 : struct stream *s;
3478 :
3479 0 : if (pbra->install_in_progress && !pbr)
3480 : return;
3481 0 : if (pbr && pbr->install_in_progress)
3482 : return;
3483 0 : if (BGP_DEBUG(zebra, ZEBRA)) {
3484 0 : if (pbr)
3485 0 : zlog_debug("%s: table %d (ip rule) %d", __func__,
3486 : pbra->table_id, install);
3487 : else
3488 0 : zlog_debug("%s: table %d fwmark %d %d", __func__,
3489 : pbra->table_id, pbra->fwmark, install);
3490 : }
3491 0 : s = zclient->obuf;
3492 0 : stream_reset(s);
3493 :
3494 0 : zclient_create_header(s,
3495 : install ? ZEBRA_RULE_ADD : ZEBRA_RULE_DELETE,
3496 : VRF_DEFAULT);
3497 0 : stream_putl(s, 1); /* send one pbr action */
3498 :
3499 0 : bgp_encode_pbr_rule_action(s, pbra, pbr);
3500 :
3501 0 : stream_putw_at(s, 0, stream_get_endp(s));
3502 0 : if ((zclient_send_message(zclient) != ZCLIENT_SEND_FAILURE)
3503 0 : && install) {
3504 0 : if (!pbr)
3505 0 : pbra->install_in_progress = true;
3506 : else
3507 0 : pbr->install_in_progress = true;
3508 : }
3509 : }
3510 :
3511 0 : void bgp_send_pbr_ipset_match(struct bgp_pbr_match *pbrim, bool install)
3512 : {
3513 0 : struct stream *s;
3514 :
3515 0 : if (pbrim->install_in_progress)
3516 : return;
3517 0 : if (BGP_DEBUG(zebra, ZEBRA))
3518 0 : zlog_debug("%s: name %s type %d %d, ID %u", __func__,
3519 : pbrim->ipset_name, pbrim->type, install,
3520 : pbrim->unique);
3521 0 : s = zclient->obuf;
3522 0 : stream_reset(s);
3523 :
3524 0 : zclient_create_header(s,
3525 : install ? ZEBRA_IPSET_CREATE :
3526 : ZEBRA_IPSET_DESTROY,
3527 : VRF_DEFAULT);
3528 :
3529 0 : stream_putl(s, 1); /* send one pbr action */
3530 :
3531 0 : bgp_encode_pbr_ipset_match(s, pbrim);
3532 :
3533 0 : stream_putw_at(s, 0, stream_get_endp(s));
3534 0 : if ((zclient_send_message(zclient) != ZCLIENT_SEND_FAILURE) && install)
3535 0 : pbrim->install_in_progress = true;
3536 : }
3537 :
3538 0 : void bgp_send_pbr_ipset_entry_match(struct bgp_pbr_match_entry *pbrime,
3539 : bool install)
3540 : {
3541 0 : struct stream *s;
3542 :
3543 0 : if (pbrime->install_in_progress)
3544 : return;
3545 0 : if (BGP_DEBUG(zebra, ZEBRA))
3546 0 : zlog_debug("%s: name %s %d %d, ID %u", __func__,
3547 : pbrime->backpointer->ipset_name, pbrime->unique,
3548 : install, pbrime->unique);
3549 0 : s = zclient->obuf;
3550 0 : stream_reset(s);
3551 :
3552 0 : zclient_create_header(s,
3553 : install ? ZEBRA_IPSET_ENTRY_ADD :
3554 : ZEBRA_IPSET_ENTRY_DELETE,
3555 : VRF_DEFAULT);
3556 :
3557 0 : stream_putl(s, 1); /* send one pbr action */
3558 :
3559 0 : bgp_encode_pbr_ipset_entry_match(s, pbrime);
3560 :
3561 0 : stream_putw_at(s, 0, stream_get_endp(s));
3562 0 : if ((zclient_send_message(zclient) != ZCLIENT_SEND_FAILURE) && install)
3563 0 : pbrime->install_in_progress = true;
3564 : }
3565 :
3566 0 : static void bgp_encode_pbr_interface_list(struct bgp *bgp, struct stream *s,
3567 : uint8_t family)
3568 : {
3569 0 : struct bgp_pbr_config *bgp_pbr_cfg = bgp->bgp_pbr_cfg;
3570 0 : struct bgp_pbr_interface_head *head;
3571 0 : struct bgp_pbr_interface *pbr_if;
3572 0 : struct interface *ifp;
3573 :
3574 0 : if (!bgp_pbr_cfg)
3575 : return;
3576 0 : if (family == AF_INET)
3577 0 : head = &(bgp_pbr_cfg->ifaces_by_name_ipv4);
3578 : else
3579 0 : head = &(bgp_pbr_cfg->ifaces_by_name_ipv6);
3580 0 : RB_FOREACH (pbr_if, bgp_pbr_interface_head, head) {
3581 0 : ifp = if_lookup_by_name(pbr_if->name, bgp->vrf_id);
3582 0 : if (ifp)
3583 0 : stream_putl(s, ifp->ifindex);
3584 : }
3585 : }
3586 :
3587 0 : static int bgp_pbr_get_ifnumber(struct bgp *bgp, uint8_t family)
3588 : {
3589 0 : struct bgp_pbr_config *bgp_pbr_cfg = bgp->bgp_pbr_cfg;
3590 0 : struct bgp_pbr_interface_head *head;
3591 0 : struct bgp_pbr_interface *pbr_if;
3592 0 : int cnt = 0;
3593 :
3594 0 : if (!bgp_pbr_cfg)
3595 : return 0;
3596 0 : if (family == AF_INET)
3597 0 : head = &(bgp_pbr_cfg->ifaces_by_name_ipv4);
3598 : else
3599 0 : head = &(bgp_pbr_cfg->ifaces_by_name_ipv6);
3600 0 : RB_FOREACH (pbr_if, bgp_pbr_interface_head, head) {
3601 0 : if (if_lookup_by_name(pbr_if->name, bgp->vrf_id))
3602 0 : cnt++;
3603 : }
3604 : return cnt;
3605 : }
3606 :
3607 0 : void bgp_send_pbr_iptable(struct bgp_pbr_action *pba,
3608 : struct bgp_pbr_match *pbm,
3609 : bool install)
3610 : {
3611 0 : struct stream *s;
3612 0 : int ret = 0;
3613 0 : int nb_interface;
3614 :
3615 0 : if (pbm->install_iptable_in_progress)
3616 : return;
3617 0 : if (BGP_DEBUG(zebra, ZEBRA))
3618 0 : zlog_debug("%s: name %s type %d mark %d %d, ID %u", __func__,
3619 : pbm->ipset_name, pbm->type, pba->fwmark, install,
3620 : pbm->unique2);
3621 0 : s = zclient->obuf;
3622 0 : stream_reset(s);
3623 :
3624 0 : zclient_create_header(s,
3625 : install ? ZEBRA_IPTABLE_ADD :
3626 : ZEBRA_IPTABLE_DELETE,
3627 : VRF_DEFAULT);
3628 :
3629 0 : bgp_encode_pbr_iptable_match(s, pba, pbm);
3630 0 : nb_interface = bgp_pbr_get_ifnumber(pba->bgp, pbm->family);
3631 0 : stream_putl(s, nb_interface);
3632 0 : if (nb_interface)
3633 0 : bgp_encode_pbr_interface_list(pba->bgp, s, pbm->family);
3634 0 : stream_putw_at(s, 0, stream_get_endp(s));
3635 0 : ret = zclient_send_message(zclient);
3636 0 : if (install) {
3637 0 : if (ret != ZCLIENT_SEND_FAILURE)
3638 0 : pba->refcnt++;
3639 : else
3640 0 : pbm->install_iptable_in_progress = true;
3641 : }
3642 : }
3643 :
3644 : /* inject in table <table_id> a default route to:
3645 : * - if nexthop IP is present : to this nexthop
3646 : * - if vrf is different from local : to the matching VRF
3647 : */
3648 0 : void bgp_zebra_announce_default(struct bgp *bgp, struct nexthop *nh,
3649 : afi_t afi, uint32_t table_id, bool announce)
3650 : {
3651 0 : struct zapi_nexthop *api_nh;
3652 0 : struct zapi_route api;
3653 0 : struct prefix p;
3654 :
3655 0 : if (!nh || (nh->type != NEXTHOP_TYPE_IPV4
3656 0 : && nh->type != NEXTHOP_TYPE_IPV6)
3657 0 : || nh->vrf_id == VRF_UNKNOWN)
3658 0 : return;
3659 :
3660 : /* in vrf-lite, no default route has to be announced
3661 : * the table id of vrf is directly used to divert traffic
3662 : */
3663 0 : if (!vrf_is_backend_netns() && bgp->vrf_id != nh->vrf_id)
3664 : return;
3665 :
3666 0 : memset(&p, 0, sizeof(p));
3667 0 : if (afi != AFI_IP && afi != AFI_IP6)
3668 : return;
3669 0 : p.family = afi2family(afi);
3670 0 : memset(&api, 0, sizeof(api));
3671 0 : api.vrf_id = bgp->vrf_id;
3672 0 : api.type = ZEBRA_ROUTE_BGP;
3673 0 : api.safi = SAFI_UNICAST;
3674 0 : api.prefix = p;
3675 0 : api.tableid = table_id;
3676 0 : api.nexthop_num = 1;
3677 0 : SET_FLAG(api.message, ZAPI_MESSAGE_TABLEID);
3678 0 : SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP);
3679 0 : api_nh = &api.nexthops[0];
3680 :
3681 0 : api.distance = ZEBRA_EBGP_DISTANCE_DEFAULT;
3682 0 : SET_FLAG(api.message, ZAPI_MESSAGE_DISTANCE);
3683 :
3684 : /* redirect IP */
3685 0 : if (afi == AFI_IP && nh->gate.ipv4.s_addr != INADDR_ANY) {
3686 0 : api_nh->vrf_id = nh->vrf_id;
3687 0 : api_nh->gate.ipv4 = nh->gate.ipv4;
3688 0 : api_nh->type = NEXTHOP_TYPE_IPV4;
3689 :
3690 0 : if (BGP_DEBUG(zebra, ZEBRA))
3691 0 : zlog_debug(
3692 : "BGP: %s default route to %pI4 table %d (redirect IP)",
3693 : announce ? "adding" : "withdrawing",
3694 : &nh->gate.ipv4, table_id);
3695 :
3696 0 : zclient_route_send(announce ? ZEBRA_ROUTE_ADD
3697 : : ZEBRA_ROUTE_DELETE,
3698 : zclient, &api);
3699 0 : } else if (afi == AFI_IP6 &&
3700 0 : memcmp(&nh->gate.ipv6,
3701 : &in6addr_any, sizeof(struct in6_addr))) {
3702 0 : api_nh->vrf_id = nh->vrf_id;
3703 0 : memcpy(&api_nh->gate.ipv6, &nh->gate.ipv6,
3704 : sizeof(struct in6_addr));
3705 0 : api_nh->type = NEXTHOP_TYPE_IPV6;
3706 :
3707 0 : if (BGP_DEBUG(zebra, ZEBRA))
3708 0 : zlog_debug(
3709 : "BGP: %s default route to %pI6 table %d (redirect IP)",
3710 : announce ? "adding" : "withdrawing",
3711 : &nh->gate.ipv6, table_id);
3712 :
3713 0 : zclient_route_send(announce ? ZEBRA_ROUTE_ADD
3714 : : ZEBRA_ROUTE_DELETE,
3715 : zclient, &api);
3716 0 : } else if (nh->vrf_id != bgp->vrf_id) {
3717 0 : struct vrf *vrf;
3718 0 : struct interface *ifp;
3719 :
3720 0 : vrf = vrf_lookup_by_id(nh->vrf_id);
3721 0 : if (!vrf)
3722 : return;
3723 : /* create default route with interface <VRF>
3724 : * with nexthop-vrf <VRF>
3725 : */
3726 0 : ifp = if_lookup_by_name_vrf(vrf->name, vrf);
3727 0 : if (!ifp)
3728 : return;
3729 0 : api_nh->vrf_id = nh->vrf_id;
3730 0 : api_nh->type = NEXTHOP_TYPE_IFINDEX;
3731 0 : api_nh->ifindex = ifp->ifindex;
3732 0 : if (BGP_DEBUG(zebra, ZEBRA))
3733 0 : zlog_info("BGP: %s default route to %s table %d (redirect VRF)",
3734 : announce ? "adding" : "withdrawing",
3735 : vrf->name, table_id);
3736 0 : zclient_route_send(announce ? ZEBRA_ROUTE_ADD
3737 : : ZEBRA_ROUTE_DELETE,
3738 : zclient, &api);
3739 0 : return;
3740 : }
3741 : }
3742 :
3743 : /* Send capabilities to RIB */
3744 0 : int bgp_zebra_send_capabilities(struct bgp *bgp, bool disable)
3745 : {
3746 0 : struct zapi_cap api;
3747 0 : int ret = BGP_GR_SUCCESS;
3748 :
3749 0 : if (zclient == NULL) {
3750 0 : if (BGP_DEBUG(zebra, ZEBRA))
3751 0 : zlog_debug("zclient invalid");
3752 0 : return BGP_GR_FAILURE;
3753 : }
3754 :
3755 : /* Check if the client is connected */
3756 0 : if ((zclient->sock < 0) || (zclient->t_connect)) {
3757 0 : if (BGP_DEBUG(zebra, ZEBRA))
3758 0 : zlog_debug("client not connected");
3759 0 : return BGP_GR_FAILURE;
3760 : }
3761 :
3762 : /* Check if capability is already sent. If the flag force is set
3763 : * send the capability since this can be initial bgp configuration
3764 : */
3765 0 : memset(&api, 0, sizeof(api));
3766 0 : if (disable) {
3767 0 : api.cap = ZEBRA_CLIENT_GR_DISABLE;
3768 0 : api.vrf_id = bgp->vrf_id;
3769 : } else {
3770 0 : api.cap = ZEBRA_CLIENT_GR_CAPABILITIES;
3771 0 : api.stale_removal_time = bgp->rib_stale_time;
3772 0 : api.vrf_id = bgp->vrf_id;
3773 : }
3774 :
3775 0 : if (zclient_capabilities_send(ZEBRA_CLIENT_CAPABILITIES, zclient, &api)
3776 : == ZCLIENT_SEND_FAILURE) {
3777 0 : zlog_err("error sending capability");
3778 0 : ret = BGP_GR_FAILURE;
3779 : } else {
3780 0 : if (disable)
3781 0 : bgp->present_zebra_gr_state = ZEBRA_GR_DISABLE;
3782 : else
3783 0 : bgp->present_zebra_gr_state = ZEBRA_GR_ENABLE;
3784 :
3785 0 : if (BGP_DEBUG(zebra, ZEBRA))
3786 0 : zlog_debug("send capabilty success");
3787 : ret = BGP_GR_SUCCESS;
3788 : }
3789 : return ret;
3790 : }
3791 :
3792 : /* Send route update pesding or completed status to RIB for the
3793 : * specific AFI, SAFI
3794 : */
3795 948 : int bgp_zebra_update(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type)
3796 : {
3797 948 : struct zapi_cap api = {0};
3798 :
3799 948 : if (zclient == NULL) {
3800 0 : if (BGP_DEBUG(zebra, ZEBRA))
3801 0 : zlog_debug("zclient == NULL, invalid");
3802 0 : return BGP_GR_FAILURE;
3803 : }
3804 :
3805 : /* Check if the client is connected */
3806 948 : if ((zclient->sock < 0) || (zclient->t_connect)) {
3807 0 : if (BGP_DEBUG(zebra, ZEBRA))
3808 0 : zlog_debug("client not connected");
3809 0 : return BGP_GR_FAILURE;
3810 : }
3811 :
3812 948 : api.afi = afi;
3813 948 : api.safi = safi;
3814 948 : api.vrf_id = vrf_id;
3815 948 : api.cap = type;
3816 :
3817 948 : if (zclient_capabilities_send(ZEBRA_CLIENT_CAPABILITIES, zclient, &api)
3818 : == ZCLIENT_SEND_FAILURE) {
3819 0 : if (BGP_DEBUG(zebra, ZEBRA))
3820 0 : zlog_debug("error sending capability");
3821 0 : return BGP_GR_FAILURE;
3822 : }
3823 : return BGP_GR_SUCCESS;
3824 : }
3825 :
3826 :
3827 : /* Send RIB stale timer update */
3828 0 : int bgp_zebra_stale_timer_update(struct bgp *bgp)
3829 : {
3830 0 : struct zapi_cap api;
3831 :
3832 0 : if (zclient == NULL) {
3833 0 : if (BGP_DEBUG(zebra, ZEBRA))
3834 0 : zlog_debug("zclient invalid");
3835 0 : return BGP_GR_FAILURE;
3836 : }
3837 :
3838 : /* Check if the client is connected */
3839 0 : if ((zclient->sock < 0) || (zclient->t_connect)) {
3840 0 : if (BGP_DEBUG(zebra, ZEBRA))
3841 0 : zlog_debug("client not connected");
3842 0 : return BGP_GR_FAILURE;
3843 : }
3844 :
3845 0 : memset(&api, 0, sizeof(api));
3846 0 : api.cap = ZEBRA_CLIENT_RIB_STALE_TIME;
3847 0 : api.stale_removal_time = bgp->rib_stale_time;
3848 0 : api.vrf_id = bgp->vrf_id;
3849 0 : if (zclient_capabilities_send(ZEBRA_CLIENT_CAPABILITIES, zclient, &api)
3850 : == ZCLIENT_SEND_FAILURE) {
3851 0 : if (BGP_DEBUG(zebra, ZEBRA))
3852 0 : zlog_debug("error sending capability");
3853 0 : return BGP_GR_FAILURE;
3854 : }
3855 0 : if (BGP_DEBUG(zebra, ZEBRA))
3856 0 : zlog_debug("send capabilty success");
3857 : return BGP_GR_SUCCESS;
3858 : }
3859 :
3860 0 : int bgp_zebra_srv6_manager_get_locator_chunk(const char *name)
3861 : {
3862 0 : return srv6_manager_get_locator_chunk(zclient, name);
3863 : }
3864 :
3865 0 : int bgp_zebra_srv6_manager_release_locator_chunk(const char *name)
3866 : {
3867 0 : return srv6_manager_release_locator_chunk(zclient, name);
3868 : }
|