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