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