]> git.proxmox.com Git - mirror_frr.git/blame - lib/zclient.c
Merge pull request #7261 from Niral-Networks/niral_dev_vrf_ospf6
[mirror_frr.git] / lib / zclient.c
CommitLineData
718e3744 1/* Zebra's client library.
2 * Copyright (C) 1999 Kunihiro Ishiguro
634f9ea2 3 * Copyright (C) 2005 Andrew J. Schorr
718e3744 4 *
5 * This file is part of GNU Zebra.
6 *
7 * GNU Zebra is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published
9 * by the Free Software Foundation; either version 2, or (at your
10 * option) any later version.
11 *
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
896014f4
DL
17 * You should have received a copy of the GNU General Public License along
18 * with this program; see the file COPYING; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
718e3744 20 */
21
22#include <zebra.h>
23
24#include "prefix.h"
25#include "stream.h"
634f9ea2 26#include "buffer.h"
718e3744 27#include "network.h"
7922fc65
DS
28#include "vrf.h"
29#include "vrf_int.h"
718e3744 30#include "if.h"
31#include "log.h"
32#include "thread.h"
33#include "zclient.h"
34#include "memory.h"
35#include "table.h"
5b30316e 36#include "nexthop.h"
fea12efb 37#include "mpls.h"
342213ea 38#include "sockopt.h"
0031a6bb 39#include "pbr.h"
98cbbaea 40#include "nexthop_group.h"
1ca3850c 41#include "lib_errors.h"
31f937fb 42#include "srte.h"
6b0655a2 43
4a1ab8e4 44DEFINE_MTYPE_STATIC(LIB, ZCLIENT, "Zclient")
14878121 45DEFINE_MTYPE_STATIC(LIB, REDIST_INST, "Redistribution instance IDs")
4a1ab8e4 46
718e3744 47/* Zebra client events. */
d62a17ae 48enum event { ZCLIENT_SCHEDULE, ZCLIENT_READ, ZCLIENT_CONNECT };
718e3744 49
50/* Prototype for event manager. */
d62a17ae 51static void zclient_event(enum event, struct zclient *);
718e3744 52
41ce5384
QY
53static void zebra_interface_if_set_value(struct stream *s,
54 struct interface *ifp);
26f8f6fe 55
17da84a4
KS
56struct zclient_options zclient_options_default = {.receive_notify = false,
57 .synchronous = false};
c17faa4b 58
689f5a8c
DL
59struct sockaddr_storage zclient_addr;
60socklen_t zclient_addr_len;
b5114685 61
718e3744 62/* This file local debug flag. */
c17faa4b 63static int zclient_debug;
e1a1880d 64
718e3744 65/* Allocate zclient structure. */
26f63a1e
DS
66struct zclient *zclient_new(struct thread_master *master,
67 struct zclient_options *opt)
718e3744 68{
d62a17ae 69 struct zclient *zclient;
f3f45626
DS
70 size_t stream_size =
71 MAX(ZEBRA_MAX_PACKET_SIZ, sizeof(struct zapi_route));
72
d62a17ae 73 zclient = XCALLOC(MTYPE_ZCLIENT, sizeof(struct zclient));
718e3744 74
f3f45626
DS
75 zclient->ibuf = stream_new(stream_size);
76 zclient->obuf = stream_new(stream_size);
d62a17ae 77 zclient->wb = buffer_new(0);
78 zclient->master = master;
718e3744 79
e1a1880d 80 zclient->receive_notify = opt->receive_notify;
17da84a4 81 zclient->synchronous = opt->synchronous;
e1a1880d 82
d62a17ae 83 return zclient;
718e3744 84}
85
228da428 86/* This function is only called when exiting, because
634f9ea2 87 many parts of the code do not check for I/O errors, so they could
88 reference an invalid pointer if the structure was ever freed.
634f9ea2 89
228da428 90 Free zclient structure. */
d62a17ae 91void zclient_free(struct zclient *zclient)
718e3744 92{
d62a17ae 93 if (zclient->ibuf)
94 stream_free(zclient->ibuf);
95 if (zclient->obuf)
96 stream_free(zclient->obuf);
97 if (zclient->wb)
98 buffer_free(zclient->wb);
99
100 XFREE(MTYPE_ZCLIENT, zclient);
718e3744 101}
102
d7c0a89a
QY
103unsigned short *redist_check_instance(struct redist_proto *red,
104 unsigned short instance)
7c8ff89e 105{
d62a17ae 106 struct listnode *node;
d7c0a89a 107 unsigned short *id;
7c8ff89e 108
d62a17ae 109 if (!red->instances)
110 return NULL;
7c8ff89e 111
d62a17ae 112 for (ALL_LIST_ELEMENTS_RO(red->instances, node, id))
113 if (*id == instance)
114 return id;
7c8ff89e 115
d62a17ae 116 return NULL;
7c8ff89e
DS
117}
118
d7c0a89a 119void redist_add_instance(struct redist_proto *red, unsigned short instance)
7c8ff89e 120{
d7c0a89a 121 unsigned short *in;
7c8ff89e 122
d62a17ae 123 red->enabled = 1;
7c8ff89e 124
d62a17ae 125 if (!red->instances)
126 red->instances = list_new();
7c8ff89e 127
d7c0a89a 128 in = XMALLOC(MTYPE_REDIST_INST, sizeof(unsigned short));
d62a17ae 129 *in = instance;
130 listnode_add(red->instances, in);
7c8ff89e
DS
131}
132
d7c0a89a 133void redist_del_instance(struct redist_proto *red, unsigned short instance)
7c8ff89e 134{
d7c0a89a 135 unsigned short *id;
d62a17ae 136
137 id = redist_check_instance(red, instance);
138 if (!id)
139 return;
140
141 listnode_delete(red->instances, id);
142 XFREE(MTYPE_REDIST_INST, id);
143 if (!red->instances->count) {
144 red->enabled = 0;
6a154c88 145 list_delete(&red->instances);
d62a17ae 146 }
7c8ff89e
DS
147}
148
24c370dd
QY
149void redist_del_all_instances(struct redist_proto *red)
150{
151 struct listnode *ln, *nn;
152 unsigned short *id;
153
154 if (!red->instances)
155 return;
156
157 for (ALL_LIST_ELEMENTS(red->instances, ln, nn, id))
158 redist_del_instance(red, *id);
159}
160
718e3744 161/* Stop zebra client services. */
d62a17ae 162void zclient_stop(struct zclient *zclient)
718e3744 163{
d62a17ae 164 afi_t afi;
165 int i;
166
167 if (zclient_debug)
2be4d61a 168 zlog_debug("zclient %p stopped", zclient);
d62a17ae 169
170 /* Stop threads. */
171 THREAD_OFF(zclient->t_read);
172 THREAD_OFF(zclient->t_connect);
173 THREAD_OFF(zclient->t_write);
174
175 /* Reset streams. */
176 stream_reset(zclient->ibuf);
177 stream_reset(zclient->obuf);
178
179 /* Empty the write buffer. */
180 buffer_reset(zclient->wb);
181
182 /* Close socket. */
183 if (zclient->sock >= 0) {
184 close(zclient->sock);
185 zclient->sock = -1;
186 }
187 zclient->fail = 0;
188
189 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
190 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
191 vrf_bitmap_free(zclient->redist[afi][i]);
192 zclient->redist[afi][i] = VRF_BITMAP_NULL;
193 }
194 redist_del_instance(
195 &zclient->mi_redist[afi][zclient->redist_default],
196 zclient->instance);
41246cb6 197
49db7a7b
RW
198 vrf_bitmap_free(zclient->default_information[afi]);
199 zclient->default_information[afi] = VRF_BITMAP_NULL;
200 }
718e3744 201}
202
d62a17ae 203void zclient_reset(struct zclient *zclient)
718e3744 204{
d62a17ae 205 afi_t afi;
3d68677e 206
d62a17ae 207 zclient_stop(zclient);
3d68677e 208
d62a17ae 209 for (afi = AFI_IP; afi < AFI_MAX; afi++)
210 redist_del_instance(
211 &zclient->mi_redist[afi][zclient->redist_default],
212 zclient->instance);
3d68677e 213
996c9314
LB
214 zclient_init(zclient, zclient->redist_default, zclient->instance,
215 zclient->privs);
718e3744 216}
217
689f5a8c
DL
218/**
219 * Connect to zebra daemon.
220 * @param zclient a pointer to zclient structure
221 * @return socket fd just to make sure that connection established
222 * @see zclient_init
26f63a1e 223 * @see zclient_new
689f5a8c
DL
224 */
225int zclient_socket_connect(struct zclient *zclient)
718e3744 226{
d62a17ae 227 int sock;
228 int ret;
d62a17ae 229
230 /* We should think about IPv6 connection. */
689f5a8c 231 sock = socket(zclient_addr.ss_family, SOCK_STREAM, 0);
d62a17ae 232 if (sock < 0)
233 return -1;
234
689f5a8c 235 set_cloexec(sock);
338b8e91 236 setsockopt_so_sendbuf(sock, 1048576);
342213ea 237
d62a17ae 238 /* Connect to zebra. */
996c9314 239 ret = connect(sock, (struct sockaddr *)&zclient_addr, zclient_addr_len);
d62a17ae 240 if (ret < 0) {
241 if (zclient_debug)
15569c58
DA
242 zlog_debug("%s connect failure: %d(%s)", __func__,
243 errno, safe_strerror(errno));
d62a17ae 244 close(sock);
245 return -1;
246 }
718e3744 247
689f5a8c 248 zclient->sock = sock;
d62a17ae 249 return sock;
718e3744 250}
251
d62a17ae 252static int zclient_failed(struct zclient *zclient)
634f9ea2 253{
d62a17ae 254 zclient->fail++;
255 zclient_stop(zclient);
256 zclient_event(ZCLIENT_CONNECT, zclient);
257 return -1;
634f9ea2 258}
259
d62a17ae 260static int zclient_flush_data(struct thread *thread)
634f9ea2 261{
d62a17ae 262 struct zclient *zclient = THREAD_ARG(thread);
263
264 zclient->t_write = NULL;
265 if (zclient->sock < 0)
266 return -1;
267 switch (buffer_flush_available(zclient->wb, zclient->sock)) {
268 case BUFFER_ERROR:
ade6974d 269 flog_err(
450971aa 270 EC_LIB_ZAPI_SOCKET,
ade6974d
QY
271 "%s: buffer_flush_available failed on zclient fd %d, closing",
272 __func__, zclient->sock);
d62a17ae 273 return zclient_failed(zclient);
d62a17ae 274 case BUFFER_PENDING:
275 zclient->t_write = NULL;
276 thread_add_write(zclient->master, zclient_flush_data, zclient,
277 zclient->sock, &zclient->t_write);
278 break;
279 case BUFFER_EMPTY:
280 break;
281 }
282 return 0;
634f9ea2 283}
284
d62a17ae 285int zclient_send_message(struct zclient *zclient)
634f9ea2 286{
d62a17ae 287 if (zclient->sock < 0)
288 return -1;
289 switch (buffer_write(zclient->wb, zclient->sock,
290 STREAM_DATA(zclient->obuf),
291 stream_get_endp(zclient->obuf))) {
292 case BUFFER_ERROR:
450971aa 293 flog_err(EC_LIB_ZAPI_SOCKET,
decbd929
DS
294 "%s: buffer_write failed to zclient fd %d, closing",
295 __func__, zclient->sock);
d62a17ae 296 return zclient_failed(zclient);
d62a17ae 297 case BUFFER_EMPTY:
298 THREAD_OFF(zclient->t_write);
299 break;
300 case BUFFER_PENDING:
301 thread_add_write(zclient->master, zclient_flush_data, zclient,
302 zclient->sock, &zclient->t_write);
303 break;
304 }
305 return 0;
634f9ea2 306}
307
6e8e0925
DS
308/*
309 * If we add more data to this structure please ensure that
310 * struct zmsghdr in lib/zclient.h is updated as appropriate.
311 */
d62a17ae 312void zclient_create_header(struct stream *s, uint16_t command, vrf_id_t vrf_id)
c1b9800a 313{
d62a17ae 314 /* length placeholder, caller can update */
315 stream_putw(s, ZEBRA_HEADER_SIZE);
316 stream_putc(s, ZEBRA_HEADER_MARKER);
317 stream_putc(s, ZSERV_VERSION);
a9ff90c4 318 stream_putl(s, vrf_id);
d62a17ae 319 stream_putw(s, command);
c1b9800a 320}
321
d7c0a89a
QY
322int zclient_read_header(struct stream *s, int sock, uint16_t *size,
323 uint8_t *marker, uint8_t *version, vrf_id_t *vrf_id,
324 uint16_t *cmd)
55119089 325{
d62a17ae 326 if (stream_read(s, sock, ZEBRA_HEADER_SIZE) != ZEBRA_HEADER_SIZE)
327 return -1;
328
ec93aa12
DS
329 STREAM_GETW(s, *size);
330 *size -= ZEBRA_HEADER_SIZE;
331 STREAM_GETC(s, *marker);
332 STREAM_GETC(s, *version);
a9ff90c4 333 STREAM_GETL(s, *vrf_id);
ec93aa12 334 STREAM_GETW(s, *cmd);
d62a17ae 335
336 if (*version != ZSERV_VERSION || *marker != ZEBRA_HEADER_MARKER) {
1c50c1c0
QY
337 flog_err(
338 EC_LIB_ZAPI_MISSMATCH,
339 "%s: socket %d version mismatch, marker %d, version %d",
340 __func__, sock, *marker, *version);
d62a17ae 341 return -1;
342 }
343
344 if (*size && stream_read(s, sock, *size) != *size)
345 return -1;
346
347 return 0;
6a2b0d9a
RW
348stream_failure:
349 return -1;
55119089
ND
350}
351
124ead27
QY
352bool zapi_parse_header(struct stream *zmsg, struct zmsghdr *hdr)
353{
354 STREAM_GETW(zmsg, hdr->length);
355 STREAM_GETC(zmsg, hdr->marker);
356 STREAM_GETC(zmsg, hdr->version);
107afcd1 357 STREAM_GETL(zmsg, hdr->vrf_id);
124ead27
QY
358 STREAM_GETW(zmsg, hdr->command);
359 return true;
360stream_failure:
361 return false;
362}
363
634f9ea2 364/* Send simple Zebra message. */
d62a17ae 365static int zebra_message_send(struct zclient *zclient, int command,
366 vrf_id_t vrf_id)
718e3744 367{
d62a17ae 368 struct stream *s;
718e3744 369
d62a17ae 370 /* Get zclient output buffer. */
371 s = zclient->obuf;
372 stream_reset(s);
718e3744 373
d62a17ae 374 /* Send very simple command only Zebra message. */
375 zclient_create_header(s, command, vrf_id);
376
377 return zclient_send_message(zclient);
718e3744 378}
379
17da84a4 380int zclient_send_hello(struct zclient *zclient)
2ea1ab1c 381{
d62a17ae 382 struct stream *s;
383
17da84a4 384 if (zclient->redist_default || zclient->synchronous) {
d62a17ae 385 s = zclient->obuf;
386 stream_reset(s);
387
388 /* The VRF ID in the HELLO message is always 0. */
389 zclient_create_header(s, ZEBRA_HELLO, VRF_DEFAULT);
390 stream_putc(s, zclient->redist_default);
391 stream_putw(s, zclient->instance);
4e0b5b31 392 stream_putl(s, zclient->session_id);
e1a1880d
DS
393 if (zclient->receive_notify)
394 stream_putc(s, 1);
395 else
396 stream_putc(s, 0);
17da84a4
KS
397 if (zclient->synchronous)
398 stream_putc(s, 1);
399 else
400 stream_putc(s, 0);
e1a1880d 401
d62a17ae 402 stream_putw_at(s, 0, stream_get_endp(s));
403 return zclient_send_message(zclient);
404 }
405
406 return 0;
2ea1ab1c
VT
407}
408
7d061b3c 409void zclient_send_vrf_label(struct zclient *zclient, vrf_id_t vrf_id, afi_t afi,
339e36d2 410 mpls_label_t label, enum lsp_types_t ltype)
c83c5e44
DS
411{
412 struct stream *s;
413
414 s = zclient->obuf;
415 stream_reset(s);
416
417 zclient_create_header(s, ZEBRA_VRF_LABEL, vrf_id);
418 stream_putl(s, label);
7d061b3c 419 stream_putc(s, afi);
339e36d2 420 stream_putc(s, ltype);
c83c5e44
DS
421 stream_putw_at(s, 0, stream_get_endp(s));
422 zclient_send_message(zclient);
423}
424
0e5223e7 425/* Send register requests to zebra daemon for the information in a VRF. */
d62a17ae 426void zclient_send_reg_requests(struct zclient *zclient, vrf_id_t vrf_id)
7076bb2f 427{
d62a17ae 428 int i;
429 afi_t afi;
430
d62a17ae 431 /* If not connected to the zebra yet. */
432 if (zclient->sock < 0)
433 return;
434
435 if (zclient_debug)
436 zlog_debug("%s: send register messages for VRF %u", __func__,
437 vrf_id);
438
439 /* We need router-id information. */
98a3fb0a
SM
440 zclient_send_router_id_update(zclient, ZEBRA_ROUTER_ID_ADD, AFI_IP,
441 vrf_id);
d62a17ae 442
eeb2dfa3
DS
443 /* We need interface information. */
444 zebra_message_send(zclient, ZEBRA_INTERFACE_ADD, vrf_id);
445
d62a17ae 446 /* Set unwanted redistribute route. */
447 for (afi = AFI_IP; afi < AFI_MAX; afi++)
448 vrf_bitmap_set(zclient->redist[afi][zclient->redist_default],
449 vrf_id);
450
451 /* Flush all redistribute request. */
0d9e7f45
DS
452 if (vrf_id == VRF_DEFAULT) {
453 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
454 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
455 if (!zclient->mi_redist[afi][i].enabled)
456 continue;
457
458 struct listnode *node;
d7c0a89a 459 unsigned short *id;
0d9e7f45
DS
460
461 for (ALL_LIST_ELEMENTS_RO(
462 zclient->mi_redist[afi][i]
996c9314
LB
463 .instances,
464 node, id))
0d9e7f45
DS
465 if (!(i == zclient->redist_default
466 && *id == zclient->instance))
467 zebra_redistribute_send(
468 ZEBRA_REDISTRIBUTE_ADD,
996c9314 469 zclient, afi, i, *id,
0d9e7f45
DS
470 VRF_DEFAULT);
471 }
472 }
473 }
d62a17ae 474
70172b1c 475 /* Resend all redistribute request. */
49db7a7b 476 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
d62a17ae 477 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
478 if (i != zclient->redist_default
479 && vrf_bitmap_check(zclient->redist[afi][i],
480 vrf_id))
481 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD,
482 zclient, afi, i, 0,
483 vrf_id);
484
49db7a7b 485 /* If default information is needed. */
d7637898 486 if (vrf_bitmap_check(zclient->default_information[afi], vrf_id))
49db7a7b
RW
487 zebra_redistribute_default_send(
488 ZEBRA_REDISTRIBUTE_DEFAULT_ADD, zclient, afi,
489 vrf_id);
490 }
7076bb2f
FL
491}
492
0e5223e7 493/* Send unregister requests to zebra daemon for the information in a VRF. */
d62a17ae 494void zclient_send_dereg_requests(struct zclient *zclient, vrf_id_t vrf_id)
0e5223e7 495{
d62a17ae 496 int i;
497 afi_t afi;
498
d62a17ae 499 /* If not connected to the zebra yet. */
500 if (zclient->sock < 0)
501 return;
502
503 if (zclient_debug)
504 zlog_debug("%s: send deregister messages for VRF %u", __func__,
505 vrf_id);
506
507 /* We need router-id information. */
98a3fb0a
SM
508 zclient_send_router_id_update(zclient, ZEBRA_ROUTER_ID_DELETE, AFI_IP,
509 vrf_id);
d62a17ae 510
eeb2dfa3 511 zebra_message_send(zclient, ZEBRA_INTERFACE_DELETE, vrf_id);
d62a17ae 512
d62a17ae 513 /* Set unwanted redistribute route. */
514 for (afi = AFI_IP; afi < AFI_MAX; afi++)
09eef679
DS
515 vrf_bitmap_unset(zclient->redist[afi][zclient->redist_default],
516 vrf_id);
d62a17ae 517
518 /* Flush all redistribute request. */
0d9e7f45
DS
519 if (vrf_id == VRF_DEFAULT) {
520 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
521 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
522 if (!zclient->mi_redist[afi][i].enabled)
523 continue;
524
525 struct listnode *node;
d7c0a89a 526 unsigned short *id;
0d9e7f45
DS
527
528 for (ALL_LIST_ELEMENTS_RO(
529 zclient->mi_redist[afi][i]
996c9314
LB
530 .instances,
531 node, id))
0d9e7f45
DS
532 if (!(i == zclient->redist_default
533 && *id == zclient->instance))
534 zebra_redistribute_send(
535 ZEBRA_REDISTRIBUTE_DELETE,
996c9314 536 zclient, afi, i, *id,
0d9e7f45
DS
537 VRF_DEFAULT);
538 }
539 }
540 }
d62a17ae 541
542 /* Flush all redistribute request. */
49db7a7b 543 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
d62a17ae 544 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
545 if (i != zclient->redist_default
546 && vrf_bitmap_check(zclient->redist[afi][i],
547 vrf_id))
548 zebra_redistribute_send(
549 ZEBRA_REDISTRIBUTE_DELETE, zclient, afi,
550 i, 0, vrf_id);
551
49db7a7b 552 /* If default information is needed. */
d7637898 553 if (vrf_bitmap_check(zclient->default_information[afi], vrf_id))
49db7a7b
RW
554 zebra_redistribute_default_send(
555 ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, zclient, afi,
556 vrf_id);
557 }
0e5223e7 558}
559
98a3fb0a
SM
560int zclient_send_router_id_update(struct zclient *zclient,
561 zebra_message_types_t type, afi_t afi,
562 vrf_id_t vrf_id)
563{
564 struct stream *s = zclient->obuf;
565 stream_reset(s);
566 zclient_create_header(s, type, vrf_id);
567 stream_putw(s, afi);
568 stream_putw_at(s, 0, stream_get_endp(s));
569 return zclient_send_message(zclient);
570}
571
4a04e5f7 572/* Send request to zebra daemon to start or stop RA. */
d62a17ae 573void zclient_send_interface_radv_req(struct zclient *zclient, vrf_id_t vrf_id,
574 struct interface *ifp, int enable,
575 int ra_interval)
4a04e5f7 576{
d62a17ae 577 struct stream *s;
4a04e5f7 578
d62a17ae 579 /* If not connected to the zebra yet. */
580 if (zclient->sock < 0)
581 return;
4a04e5f7 582
d62a17ae 583 /* Form and send message. */
584 s = zclient->obuf;
585 stream_reset(s);
4a04e5f7 586
d62a17ae 587 if (enable)
588 zclient_create_header(s, ZEBRA_INTERFACE_ENABLE_RADV, vrf_id);
589 else
590 zclient_create_header(s, ZEBRA_INTERFACE_DISABLE_RADV, vrf_id);
4a04e5f7 591
d62a17ae 592 stream_putl(s, ifp->ifindex);
593 stream_putl(s, ra_interval);
4a04e5f7 594
d62a17ae 595 stream_putw_at(s, 0, stream_get_endp(s));
4a04e5f7 596
d62a17ae 597 zclient_send_message(zclient);
4a04e5f7 598}
599
c3bd894e
QY
600int zclient_send_interface_protodown(struct zclient *zclient, vrf_id_t vrf_id,
601 struct interface *ifp, bool down)
602{
603 struct stream *s;
604
605 if (zclient->sock < 0)
606 return -1;
607
608 s = zclient->obuf;
609 stream_reset(s);
610 zclient_create_header(s, ZEBRA_INTERFACE_SET_PROTODOWN, vrf_id);
611 stream_putl(s, ifp->ifindex);
612 stream_putc(s, !!down);
613 stream_putw_at(s, 0, stream_get_endp(s));
614 zclient_send_message(zclient);
615
616 return 0;
617}
618
718e3744 619/* Make connection to zebra daemon. */
d62a17ae 620int zclient_start(struct zclient *zclient)
718e3744 621{
d62a17ae 622 if (zclient_debug)
623 zlog_info("zclient_start is called");
624
d62a17ae 625 /* If already connected to the zebra. */
626 if (zclient->sock >= 0)
627 return 0;
628
629 /* Check connect thread. */
630 if (zclient->t_connect)
631 return 0;
632
633 if (zclient_socket_connect(zclient) < 0) {
634 if (zclient_debug)
635 zlog_debug("zclient connection fail");
636 zclient->fail++;
637 zclient_event(ZCLIENT_CONNECT, zclient);
638 return -1;
639 }
718e3744 640
d62a17ae 641 if (set_nonblocking(zclient->sock) < 0)
450971aa 642 flog_err(EC_LIB_ZAPI_SOCKET, "%s: set_nonblocking(%d) failed",
ade6974d 643 __func__, zclient->sock);
718e3744 644
d62a17ae 645 /* Clear fail count. */
646 zclient->fail = 0;
647 if (zclient_debug)
648 zlog_debug("zclient connect success with socket [%d]",
649 zclient->sock);
718e3744 650
d62a17ae 651 /* Create read thread. */
652 zclient_event(ZCLIENT_READ, zclient);
718e3744 653
17da84a4 654 zclient_send_hello(zclient);
718e3744 655
22761baa
DS
656 zebra_message_send(zclient, ZEBRA_INTERFACE_ADD, VRF_DEFAULT);
657
d62a17ae 658 /* Inform the successful connection. */
659 if (zclient->zebra_connected)
660 (*zclient->zebra_connected)(zclient);
718e3744 661
d62a17ae 662 return 0;
718e3744 663}
6b0655a2 664
078430f6
DS
665/* Initialize zebra client. Argument redist_default is unwanted
666 redistribute route type. */
d7c0a89a
QY
667void zclient_init(struct zclient *zclient, int redist_default,
668 unsigned short instance, struct zebra_privs_t *privs)
078430f6 669{
d62a17ae 670 int afi, i;
671
d62a17ae 672 /* Set -1 to the default socket value. */
673 zclient->sock = -1;
342213ea 674 zclient->privs = privs;
d62a17ae 675
676 /* Clear redistribution flags. */
677 for (afi = AFI_IP; afi < AFI_MAX; afi++)
678 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
679 zclient->redist[afi][i] = vrf_bitmap_init();
680
681 /* Set unwanted redistribute route. bgpd does not need BGP route
682 redistribution. */
683 zclient->redist_default = redist_default;
684 zclient->instance = instance;
685 /* Pending: make afi(s) an arg. */
49db7a7b 686 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
d62a17ae 687 redist_add_instance(&zclient->mi_redist[afi][redist_default],
688 instance);
689
49db7a7b
RW
690 /* Set default-information redistribute to zero. */
691 zclient->default_information[afi] = vrf_bitmap_init();
692 }
d62a17ae 693
694 if (zclient_debug)
cdc6ed90 695 zlog_debug("scheduling zclient connection");
d62a17ae 696
697 zclient_event(ZCLIENT_SCHEDULE, zclient);
7076bb2f 698}
078430f6 699
7076bb2f
FL
700/* This function is a wrapper function for calling zclient_start from
701 timer or event thread. */
d62a17ae 702static int zclient_connect(struct thread *t)
7076bb2f 703{
d62a17ae 704 struct zclient *zclient;
078430f6 705
d62a17ae 706 zclient = THREAD_ARG(t);
707 zclient->t_connect = NULL;
078430f6 708
d62a17ae 709 if (zclient_debug)
710 zlog_debug("zclient_connect is called");
078430f6 711
d62a17ae 712 return zclient_start(zclient);
078430f6
DS
713}
714
46f56dad
DS
715int zclient_send_rnh(struct zclient *zclient, int command,
716 const struct prefix *p, bool exact_match,
717 vrf_id_t vrf_id)
3c192540
DS
718{
719 struct stream *s;
720
721 s = zclient->obuf;
722 stream_reset(s);
723 zclient_create_header(s, command, vrf_id);
724 stream_putc(s, (exact_match) ? 1 : 0);
725
726 stream_putw(s, PREFIX_FAMILY(p));
727 stream_putc(s, p->prefixlen);
728 switch (PREFIX_FAMILY(p)) {
729 case AF_INET:
730 stream_put_in_addr(s, &p->u.prefix4);
731 break;
732 case AF_INET6:
733 stream_put(s, &(p->u.prefix6), 16);
734 break;
735 default:
736 break;
737 }
738 stream_putw_at(s, 0, stream_get_endp(s));
739
740 return zclient_send_message(zclient);
741}
742
d62a17ae 743/*
744 * "xdr_encode"-like interface that allows daemon (client) to send
745 * a message to zebra server for a route that needs to be
746 * added/deleted to the kernel. Info about the route is specified
04772760 747 * by the caller in a struct zapi_route. zapi_route_encode() then writes
d62a17ae 748 * the info down the zclient socket using the stream_* functions.
749 *
750 * The corresponding read ("xdr_decode") function on the server
04772760 751 * side is zapi_route_decode().
d62a17ae 752 *
753 * 0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F
754 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
755 * | Length (2) | Command | Route Type |
756 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
757 * | ZEBRA Flags | Message Flags | Prefix length |
758 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
759 * | Destination IPv4 Prefix for route |
760 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
761 * | Nexthop count |
762 * +-+-+-+-+-+-+-+-+
763 *
764 *
765 * A number of IPv4 nexthop(s) or nexthop interface index(es) are then
766 * described, as per the Nexthop count. Each nexthop described as:
767 *
768 * +-+-+-+-+-+-+-+-+
769 * | Nexthop Type | Set to one of ZEBRA_NEXTHOP_*
770 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
771 * | IPv4 Nexthop address or Interface Index number |
772 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
773 *
09a484dd
DL
774 * Alternatively, if the route is a blackhole route, then Nexthop count
775 * is set to 1 and a nexthop of type NEXTHOP_TYPE_BLACKHOLE is the sole
776 * nexthop.
d62a17ae 777 *
04772760
DS
778 * The original struct zapi_route_*() infrastructure was built around
779 * the traditional (32-bit "gate OR ifindex") nexthop data unit.
780 * A special encoding can be used to feed onlink (64-bit "gate AND ifindex")
781 * nexthops into zapi_route_encode() using the same zapi_route structure.
782 * This is done by setting zapi_route fields as follows:
d62a17ae 783 * - .message |= ZAPI_MESSAGE_NEXTHOP | ZAPI_MESSAGE_ONLINK
784 * - .nexthop_num == .ifindex_num
785 * - .nexthop and .ifindex are filled with gate and ifindex parts of
786 * each compound nexthop, both in the same order
787 *
d62a17ae 788 * If ZAPI_MESSAGE_DISTANCE is set, the distance value is written as a 1
789 * byte value.
790 *
791 * If ZAPI_MESSAGE_METRIC is set, the metric value is written as an 8
792 * byte value.
793 *
794 * If ZAPI_MESSAGE_TAG is set, the tag value is written as a 4 byte value
795 *
796 * If ZAPI_MESSAGE_MTU is set, the mtu value is written as a 4 byte value
797 *
798 * XXX: No attention paid to alignment.
799 */
d7c0a89a 800int zclient_route_send(uint8_t cmd, struct zclient *zclient,
0e51b4a3 801 struct zapi_route *api)
657cde12 802{
0e51b4a3
RW
803 if (zapi_route_encode(cmd, zclient->obuf, api) < 0)
804 return -1;
805 return zclient_send_message(zclient);
806}
807
3c6e0bd4
SW
808static int zapi_nexthop_labels_cmp(const struct zapi_nexthop *next1,
809 const struct zapi_nexthop *next2)
810{
811 if (next1->label_num > next2->label_num)
812 return 1;
813
814 if (next1->label_num < next2->label_num)
815 return -1;
816
817 return memcmp(next1->labels, next2->labels, next1->label_num);
818}
819
820static int zapi_nexthop_cmp_no_labels(const struct zapi_nexthop *next1,
821 const struct zapi_nexthop *next2)
822{
823 int ret = 0;
824
825 if (next1->vrf_id < next2->vrf_id)
826 return -1;
827
828 if (next1->vrf_id > next2->vrf_id)
829 return 1;
830
831 if (next1->type < next2->type)
832 return -1;
833
834 if (next1->type > next2->type)
835 return 1;
836
bd054c1a
DS
837 if (next1->weight < next2->weight)
838 return -1;
839
840 if (next1->weight > next2->weight)
841 return 1;
842
3c6e0bd4
SW
843 switch (next1->type) {
844 case NEXTHOP_TYPE_IPV4:
845 case NEXTHOP_TYPE_IPV6:
846 ret = nexthop_g_addr_cmp(next1->type, &next1->gate,
847 &next2->gate);
848 if (ret != 0)
849 return ret;
850 break;
851 case NEXTHOP_TYPE_IPV4_IFINDEX:
852 case NEXTHOP_TYPE_IPV6_IFINDEX:
853 ret = nexthop_g_addr_cmp(next1->type, &next1->gate,
854 &next2->gate);
855 if (ret != 0)
856 return ret;
857 /* Intentional Fall-Through */
858 case NEXTHOP_TYPE_IFINDEX:
859 if (next1->ifindex < next2->ifindex)
860 return -1;
861
862 if (next1->ifindex > next2->ifindex)
863 return 1;
864 break;
865 case NEXTHOP_TYPE_BLACKHOLE:
866 if (next1->bh_type < next2->bh_type)
867 return -1;
868
869 if (next1->bh_type > next2->bh_type)
870 return 1;
871 break;
872 }
873
38fd3eda
MS
874 if (next1->srte_color < next2->srte_color)
875 return -1;
876 if (next1->srte_color > next2->srte_color)
877 return 1;
878
879 if (CHECK_FLAG(next1->flags, NEXTHOP_FLAG_HAS_BACKUP) ||
880 CHECK_FLAG(next2->flags, NEXTHOP_FLAG_HAS_BACKUP)) {
881
882 if (!CHECK_FLAG(next1->flags, NEXTHOP_FLAG_HAS_BACKUP) &&
883 CHECK_FLAG(next2->flags, NEXTHOP_FLAG_HAS_BACKUP))
884 return -1;
885
886 if (CHECK_FLAG(next1->flags, NEXTHOP_FLAG_HAS_BACKUP) &&
887 !CHECK_FLAG(next2->flags, NEXTHOP_FLAG_HAS_BACKUP))
888 return 1;
889
890 if (next1->backup_num > 0 || next2->backup_num > 0) {
891
892 if (next1->backup_num < next2->backup_num)
893 return -1;
894
895 if (next1->backup_num > next2->backup_num)
896 return 1;
897
898 ret = memcmp(next1->backup_idx,
899 next2->backup_idx, next1->backup_num);
900 if (ret != 0)
901 return ret;
902 }
903 }
904
3c6e0bd4
SW
905 return 0;
906}
907
908static int zapi_nexthop_cmp(const void *item1, const void *item2)
909{
910 int ret = 0;
911
912 const struct zapi_nexthop *next1 = item1;
913 const struct zapi_nexthop *next2 = item2;
914
915 ret = zapi_nexthop_cmp_no_labels(next1, next2);
916 if (ret != 0)
917 return ret;
918
919 ret = zapi_nexthop_labels_cmp(next1, next2);
920
921 return ret;
922}
923
924static void zapi_nexthop_group_sort(struct zapi_nexthop *nh_grp,
925 uint16_t nexthop_num)
926{
927 qsort(nh_grp, nexthop_num, sizeof(struct zapi_nexthop),
928 &zapi_nexthop_cmp);
929}
930
68a02e06
MS
931/*
932 * Encode a single zapi nexthop
933 */
934int zapi_nexthop_encode(struct stream *s, const struct zapi_nexthop *api_nh,
31f937fb 935 uint32_t api_flags, uint32_t api_message)
68a02e06 936{
474aebd9 937 int i, ret = 0;
68a02e06
MS
938 int nh_flags = api_nh->flags;
939
940 stream_putl(s, api_nh->vrf_id);
941 stream_putc(s, api_nh->type);
942
943 /* If needed, set 'labelled nexthop' flag */
944 if (api_nh->label_num > 0) {
945 SET_FLAG(nh_flags, ZAPI_NEXTHOP_FLAG_LABEL);
946
947 /* Validate label count */
948 if (api_nh->label_num > MPLS_MAX_LABELS) {
949 ret = -1;
950 goto done;
951 }
952 }
953
0a8881b4 954 /* If present, set 'weight' flag before encoding flags */
bd054c1a
DS
955 if (api_nh->weight)
956 SET_FLAG(nh_flags, ZAPI_NEXTHOP_FLAG_WEIGHT);
957
68a02e06
MS
958 /* Note that we're only encoding a single octet */
959 stream_putc(s, nh_flags);
960
961 switch (api_nh->type) {
962 case NEXTHOP_TYPE_BLACKHOLE:
963 stream_putc(s, api_nh->bh_type);
964 break;
965 case NEXTHOP_TYPE_IPV4:
68a02e06
MS
966 case NEXTHOP_TYPE_IPV4_IFINDEX:
967 stream_put_in_addr(s, &api_nh->gate.ipv4);
968 stream_putl(s, api_nh->ifindex);
969 break;
970 case NEXTHOP_TYPE_IFINDEX:
971 stream_putl(s, api_nh->ifindex);
972 break;
973 case NEXTHOP_TYPE_IPV6:
68a02e06
MS
974 case NEXTHOP_TYPE_IPV6_IFINDEX:
975 stream_write(s, (uint8_t *)&api_nh->gate.ipv6,
976 16);
977 stream_putl(s, api_nh->ifindex);
978 break;
979 }
980
981 /* We only encode labels if we have >0 - we use
982 * the per-nexthop flag above to signal that the count
983 * is present in the payload.
984 */
985 if (api_nh->label_num > 0) {
986 stream_putc(s, api_nh->label_num);
987 stream_put(s, &api_nh->labels[0],
988 api_nh->label_num * sizeof(mpls_label_t));
989 }
990
bd054c1a
DS
991 if (api_nh->weight)
992 stream_putl(s, api_nh->weight);
993
68a02e06
MS
994 /* Router MAC for EVPN routes. */
995 if (CHECK_FLAG(api_flags, ZEBRA_FLAG_EVPN_ROUTE))
996 stream_put(s, &(api_nh->rmac),
997 sizeof(struct ethaddr));
998
31f937fb
SM
999 /* Color for Segment Routing TE. */
1000 if (CHECK_FLAG(api_message, ZAPI_MESSAGE_SRTE))
1001 stream_putl(s, api_nh->srte_color);
1002
018c6488 1003 /* Index of backup nexthop */
474aebd9
MS
1004 if (CHECK_FLAG(nh_flags, ZAPI_NEXTHOP_FLAG_HAS_BACKUP)) {
1005 /* Validate backup count */
1006 if (api_nh->backup_num > NEXTHOP_MAX_BACKUPS) {
1007 ret = -1;
1008 goto done;
1009 }
1010
1011 stream_putc(s, api_nh->backup_num);
1012 for (i = 0; i < api_nh->backup_num; i++)
1013 stream_putc(s, api_nh->backup_idx[i]);
1014 }
018c6488 1015
68a02e06
MS
1016done:
1017 return ret;
1018}
1019
21735352 1020int zapi_nhg_encode(struct stream *s, int cmd, struct zapi_nhg *api_nhg)
2f35a820 1021{
21735352
SW
1022 int i;
1023
c6ce9334
SW
1024 if (cmd != ZEBRA_NHG_DEL && cmd != ZEBRA_NHG_ADD) {
1025 flog_err(EC_LIB_ZAPI_ENCODE,
1026 "%s: Specified zapi NHG command (%d) doesn't exist\n",
1027 __func__, cmd);
1028 return -1;
1029 }
2f35a820
DS
1030
1031 stream_reset(s);
c6ce9334 1032 zclient_create_header(s, cmd, VRF_DEFAULT);
2f35a820 1033
21735352 1034 stream_putw(s, api_nhg->proto);
c6ce9334 1035 stream_putl(s, api_nhg->id);
2f35a820 1036
c6ce9334 1037 if (cmd == ZEBRA_NHG_ADD) {
21735352 1038 /* Nexthops */
c6ce9334
SW
1039 zapi_nexthop_group_sort(api_nhg->nexthops,
1040 api_nhg->nexthop_num);
2f35a820 1041
c6ce9334 1042 stream_putw(s, api_nhg->nexthop_num);
2f35a820 1043
21735352 1044 for (i = 0; i < api_nhg->nexthop_num; i++)
c6ce9334 1045 zapi_nexthop_encode(s, &api_nhg->nexthops[i], 0, 0);
21735352
SW
1046
1047 /* Backup nexthops */
1048
1049 stream_putw(s, api_nhg->backup_nexthop_num);
1050
1051 for (i = 0; i < api_nhg->backup_nexthop_num; i++)
1052 zapi_nexthop_encode(s, &api_nhg->backup_nexthops[i], 0,
1053 0);
2f35a820
DS
1054 }
1055
1056 stream_putw_at(s, 0, stream_get_endp(s));
c6ce9334
SW
1057
1058 return 0;
2f35a820
DS
1059}
1060
c6ce9334 1061int zclient_nhg_send(struct zclient *zclient, int cmd, struct zapi_nhg *api_nhg)
2f35a820 1062{
21735352
SW
1063 api_nhg->proto = zclient->redist_default;
1064
1065 if (zapi_nhg_encode(zclient->obuf, cmd, api_nhg))
c6ce9334 1066 return -1;
2f35a820 1067
c6ce9334 1068 return zclient_send_message(zclient);
2f35a820
DS
1069}
1070
d7c0a89a 1071int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api)
0e51b4a3
RW
1072{
1073 struct zapi_nexthop *api_nh;
d62a17ae 1074 int i;
1075 int psize;
d62a17ae 1076
d62a17ae 1077 stream_reset(s);
d62a17ae 1078 zclient_create_header(s, cmd, api->vrf_id);
1079
e4081c0e
RW
1080 if (api->type >= ZEBRA_ROUTE_MAX) {
1081 flog_err(EC_LIB_ZAPI_ENCODE,
1082 "%s: Specified route type (%u) is not a legal value\n",
15569c58 1083 __func__, api->type);
e4081c0e
RW
1084 return -1;
1085 }
d62a17ae 1086 stream_putc(s, api->type);
e4081c0e 1087
d62a17ae 1088 stream_putw(s, api->instance);
1089 stream_putl(s, api->flags);
31f937fb 1090 stream_putl(s, api->message);
e4081c0e
RW
1091
1092 if (api->safi < SAFI_UNICAST || api->safi >= SAFI_MAX) {
1093 flog_err(EC_LIB_ZAPI_ENCODE,
1094 "%s: Specified route SAFI (%u) is not a legal value\n",
15569c58 1095 __func__, api->safi);
e4081c0e
RW
1096 return -1;
1097 }
832d0f56 1098 stream_putc(s, api->safi);
d62a17ae 1099
1100 /* Put prefix information. */
0e51b4a3 1101 stream_putc(s, api->prefix.family);
bb1b9c47
RW
1102 psize = PSIZE(api->prefix.prefixlen);
1103 stream_putc(s, api->prefix.prefixlen);
c4efd0f4 1104 stream_write(s, &api->prefix.u.prefix, psize);
d62a17ae 1105
1106 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_SRCPFX)) {
bb1b9c47
RW
1107 psize = PSIZE(api->src_prefix.prefixlen);
1108 stream_putc(s, api->src_prefix.prefixlen);
d7c0a89a 1109 stream_write(s, (uint8_t *)&api->src_prefix.prefix, psize);
d62a17ae 1110 }
1111
27141ea9
DS
1112 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NHG))
1113 stream_putl(s, api->nhgid);
1114
0e51b4a3 1115 /* Nexthops. */
d62a17ae 1116 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) {
bb1b9c47
RW
1117 /* limit the number of nexthops if necessary */
1118 if (api->nexthop_num > MULTIPATH_NUM) {
ade6974d 1119 flog_err(
450971aa 1120 EC_LIB_ZAPI_ENCODE,
2dbe669b
DA
1121 "%s: prefix %pFX: can't encode %u nexthops (maximum is %u)",
1122 __func__, &api->prefix, api->nexthop_num,
1123 MULTIPATH_NUM);
a74e593b 1124 return -1;
bb1b9c47
RW
1125 }
1126
018c6488
MS
1127 /* We canonicalize the nexthops by sorting them; this allows
1128 * zebra to resolve the list of nexthops to a nexthop-group
1129 * more efficiently.
1130 */
3c6e0bd4
SW
1131 zapi_nexthop_group_sort(api->nexthops, api->nexthop_num);
1132
b5f79651 1133 stream_putw(s, api->nexthop_num);
d62a17ae 1134
1135 for (i = 0; i < api->nexthop_num; i++) {
bb1b9c47
RW
1136 api_nh = &api->nexthops[i];
1137
52dd3aa4 1138 /* MPLS labels for BGP-LU or Segment Routing */
68a02e06 1139 if (api_nh->label_num > MPLS_MAX_LABELS) {
2dbe669b
DA
1140 flog_err(
1141 EC_LIB_ZAPI_ENCODE,
1142 "%s: prefix %pFX: can't encode %u labels (maximum is %u)",
1143 __func__, &api->prefix,
1144 api_nh->label_num, MPLS_MAX_LABELS);
68a02e06 1145 return -1;
52dd3aa4 1146 }
a317a9b9 1147
31f937fb
SM
1148 if (zapi_nexthop_encode(s, api_nh, api->flags,
1149 api->message)
1150 != 0)
68a02e06 1151 return -1;
d62a17ae 1152 }
1153 }
1154
018c6488
MS
1155 /* Backup nexthops */
1156 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_BACKUP_NEXTHOPS)) {
1157 /* limit the number of nexthops if necessary */
1158 if (api->backup_nexthop_num > MULTIPATH_NUM) {
018c6488
MS
1159 flog_err(
1160 EC_LIB_ZAPI_ENCODE,
2dbe669b
DA
1161 "%s: prefix %pFX: can't encode %u backup nexthops (maximum is %u)",
1162 __func__, &api->prefix, api->backup_nexthop_num,
018c6488
MS
1163 MULTIPATH_NUM);
1164 return -1;
1165 }
1166
1167 /* Note that we do not sort the list of backup nexthops -
1168 * this list is treated as an array and indexed by each
1169 * primary nexthop that is associated with a backup.
1170 */
1171
1172 stream_putw(s, api->backup_nexthop_num);
1173
1174 for (i = 0; i < api->backup_nexthop_num; i++) {
1175 api_nh = &api->backup_nexthops[i];
1176
1177 /* MPLS labels for BGP-LU or Segment Routing */
1178 if (api_nh->label_num > MPLS_MAX_LABELS) {
2dbe669b
DA
1179 flog_err(
1180 EC_LIB_ZAPI_ENCODE,
1181 "%s: prefix %pFX: backup: can't encode %u labels (maximum is %u)",
1182 __func__, &api->prefix,
1183 api_nh->label_num, MPLS_MAX_LABELS);
018c6488
MS
1184 return -1;
1185 }
1186
31f937fb
SM
1187 if (zapi_nexthop_encode(s, api_nh, api->flags,
1188 api->message)
1189 != 0)
018c6488
MS
1190 return -1;
1191 }
1192 }
1193
0e51b4a3 1194 /* Attributes. */
d62a17ae 1195 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_DISTANCE))
1196 stream_putc(s, api->distance);
1197 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_METRIC))
1198 stream_putl(s, api->metric);
1199 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TAG))
1200 stream_putl(s, api->tag);
1201 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_MTU))
1202 stream_putl(s, api->mtu);
ba1849ef
DS
1203 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TABLEID))
1204 stream_putl(s, api->tableid);
d62a17ae 1205
1206 /* Put length at the first point of the stream. */
1207 stream_putw_at(s, 0, stream_get_endp(s));
1208
0e51b4a3
RW
1209 return 0;
1210}
1211
68a02e06
MS
1212/*
1213 * Decode a single zapi nexthop object
1214 */
2f35a820
DS
1215int zapi_nexthop_decode(struct stream *s, struct zapi_nexthop *api_nh,
1216 uint32_t api_flags, uint32_t api_message)
68a02e06 1217{
474aebd9 1218 int i, ret = -1;
68a02e06
MS
1219
1220 STREAM_GETL(s, api_nh->vrf_id);
1221 STREAM_GETC(s, api_nh->type);
1222
1223 /* Note that we're only using a single octet of flags */
1224 STREAM_GETC(s, api_nh->flags);
1225
1226 switch (api_nh->type) {
1227 case NEXTHOP_TYPE_BLACKHOLE:
1228 STREAM_GETC(s, api_nh->bh_type);
1229 break;
1230 case NEXTHOP_TYPE_IPV4:
68a02e06
MS
1231 case NEXTHOP_TYPE_IPV4_IFINDEX:
1232 STREAM_GET(&api_nh->gate.ipv4.s_addr, s,
1233 IPV4_MAX_BYTELEN);
1234 STREAM_GETL(s, api_nh->ifindex);
1235 break;
1236 case NEXTHOP_TYPE_IFINDEX:
1237 STREAM_GETL(s, api_nh->ifindex);
1238 break;
1239 case NEXTHOP_TYPE_IPV6:
68a02e06
MS
1240 case NEXTHOP_TYPE_IPV6_IFINDEX:
1241 STREAM_GET(&api_nh->gate.ipv6, s, 16);
1242 STREAM_GETL(s, api_nh->ifindex);
1243 break;
1244 }
1245
1246 /* MPLS labels for BGP-LU or Segment Routing */
1247 if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_LABEL)) {
1248 STREAM_GETC(s, api_nh->label_num);
1249 if (api_nh->label_num > MPLS_MAX_LABELS) {
1250 flog_err(
1251 EC_LIB_ZAPI_ENCODE,
1252 "%s: invalid number of MPLS labels (%u)",
1253 __func__, api_nh->label_num);
1254 return -1;
1255 }
1256
1257 STREAM_GET(&api_nh->labels[0], s,
1258 api_nh->label_num * sizeof(mpls_label_t));
1259 }
1260
bd054c1a
DS
1261 if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_WEIGHT))
1262 STREAM_GETL(s, api_nh->weight);
1263
68a02e06
MS
1264 /* Router MAC for EVPN routes. */
1265 if (CHECK_FLAG(api_flags, ZEBRA_FLAG_EVPN_ROUTE))
1266 STREAM_GET(&(api_nh->rmac), s,
1267 sizeof(struct ethaddr));
1268
31f937fb
SM
1269 /* Color for Segment Routing TE. */
1270 if (CHECK_FLAG(api_message, ZAPI_MESSAGE_SRTE))
1271 STREAM_GETL(s, api_nh->srte_color);
1272
018c6488 1273 /* Backup nexthop index */
474aebd9
MS
1274 if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_HAS_BACKUP)) {
1275 STREAM_GETC(s, api_nh->backup_num);
1276
1277 if (api_nh->backup_num > NEXTHOP_MAX_BACKUPS)
1278 return -1;
1279
1280 for (i = 0; i < api_nh->backup_num; i++)
1281 STREAM_GETC(s, api_nh->backup_idx[i]);
1282 }
018c6488 1283
68a02e06
MS
1284 /* Success */
1285 ret = 0;
1286
1287stream_failure:
1288
1289 return ret;
1290}
1291
0e51b4a3
RW
1292int zapi_route_decode(struct stream *s, struct zapi_route *api)
1293{
1294 struct zapi_nexthop *api_nh;
1295 int i;
1296
1297 memset(api, 0, sizeof(*api));
1298
1299 /* Type, flags, message. */
ec93aa12 1300 STREAM_GETC(s, api->type);
e4081c0e 1301 if (api->type >= ZEBRA_ROUTE_MAX) {
450971aa 1302 flog_err(EC_LIB_ZAPI_ENCODE,
decbd929 1303 "%s: Specified route type: %d is not a legal value\n",
15569c58 1304 __func__, api->type);
ec93aa12
DS
1305 return -1;
1306 }
1307
1308 STREAM_GETW(s, api->instance);
1309 STREAM_GETL(s, api->flags);
31f937fb 1310 STREAM_GETL(s, api->message);
832d0f56 1311 STREAM_GETC(s, api->safi);
e4081c0e
RW
1312 if (api->safi < SAFI_UNICAST || api->safi >= SAFI_MAX) {
1313 flog_err(EC_LIB_ZAPI_ENCODE,
1314 "%s: Specified route SAFI (%u) is not a legal value\n",
15569c58 1315 __func__, api->safi);
e4081c0e
RW
1316 return -1;
1317 }
0e51b4a3
RW
1318
1319 /* Prefix. */
ec93aa12
DS
1320 STREAM_GETC(s, api->prefix.family);
1321 STREAM_GETC(s, api->prefix.prefixlen);
0e51b4a3
RW
1322 switch (api->prefix.family) {
1323 case AF_INET:
ec93aa12 1324 if (api->prefix.prefixlen > IPV4_MAX_PREFIXLEN) {
ade6974d 1325 flog_err(
450971aa 1326 EC_LIB_ZAPI_ENCODE,
ade6974d 1327 "%s: V4 prefixlen is %d which should not be more than 32",
15569c58 1328 __func__, api->prefix.prefixlen);
ec93aa12
DS
1329 return -1;
1330 }
0e51b4a3
RW
1331 break;
1332 case AF_INET6:
ec93aa12 1333 if (api->prefix.prefixlen > IPV6_MAX_PREFIXLEN) {
ade6974d 1334 flog_err(
450971aa 1335 EC_LIB_ZAPI_ENCODE,
ade6974d 1336 "%s: v6 prefixlen is %d which should not be more than 128",
15569c58 1337 __func__, api->prefix.prefixlen);
ec93aa12
DS
1338 return -1;
1339 }
0e51b4a3 1340 break;
ec93aa12 1341 default:
450971aa 1342 flog_err(EC_LIB_ZAPI_ENCODE,
15569c58
DA
1343 "%s: Specified family %d is not v4 or v6", __func__,
1344 api->prefix.family);
ec93aa12 1345 return -1;
0e51b4a3 1346 }
ec93aa12
DS
1347 STREAM_GET(&api->prefix.u.prefix, s, PSIZE(api->prefix.prefixlen));
1348
0e51b4a3
RW
1349 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_SRCPFX)) {
1350 api->src_prefix.family = AF_INET6;
ec93aa12
DS
1351 STREAM_GETC(s, api->src_prefix.prefixlen);
1352 if (api->src_prefix.prefixlen > IPV6_MAX_PREFIXLEN) {
ade6974d 1353 flog_err(
450971aa 1354 EC_LIB_ZAPI_ENCODE,
ade6974d 1355 "%s: SRC Prefix prefixlen received: %d is too large",
15569c58 1356 __func__, api->src_prefix.prefixlen);
ec93aa12
DS
1357 return -1;
1358 }
1359 STREAM_GET(&api->src_prefix.prefix, s,
0e51b4a3
RW
1360 PSIZE(api->src_prefix.prefixlen));
1361
1362 if (api->prefix.family != AF_INET6
ec93aa12 1363 || api->src_prefix.prefixlen == 0) {
ade6974d 1364 flog_err(
450971aa 1365 EC_LIB_ZAPI_ENCODE,
ade6974d 1366 "%s: SRC prefix specified in some manner that makes no sense",
15569c58 1367 __func__);
ec93aa12
DS
1368 return -1;
1369 }
0e51b4a3
RW
1370 }
1371
27141ea9
DS
1372 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NHG))
1373 STREAM_GETL(s, api->nhgid);
1374
0e51b4a3
RW
1375 /* Nexthops. */
1376 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) {
ec93aa12 1377 STREAM_GETW(s, api->nexthop_num);
0e51b4a3 1378 if (api->nexthop_num > MULTIPATH_NUM) {
450971aa 1379 flog_err(EC_LIB_ZAPI_ENCODE,
decbd929
DS
1380 "%s: invalid number of nexthops (%u)",
1381 __func__, api->nexthop_num);
0e51b4a3
RW
1382 return -1;
1383 }
1384
1385 for (i = 0; i < api->nexthop_num; i++) {
1386 api_nh = &api->nexthops[i];
1387
31f937fb
SM
1388 if (zapi_nexthop_decode(s, api_nh, api->flags,
1389 api->message)
1390 != 0)
68a02e06 1391 return -1;
0e51b4a3
RW
1392 }
1393 }
1394
018c6488
MS
1395 /* Backup nexthops. */
1396 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_BACKUP_NEXTHOPS)) {
1397 STREAM_GETW(s, api->backup_nexthop_num);
1398 if (api->backup_nexthop_num > MULTIPATH_NUM) {
1399 flog_err(EC_LIB_ZAPI_ENCODE,
1400 "%s: invalid number of backup nexthops (%u)",
1401 __func__, api->backup_nexthop_num);
1402 return -1;
1403 }
1404
1405 for (i = 0; i < api->backup_nexthop_num; i++) {
1406 api_nh = &api->backup_nexthops[i];
1407
31f937fb
SM
1408 if (zapi_nexthop_decode(s, api_nh, api->flags,
1409 api->message)
1410 != 0)
018c6488
MS
1411 return -1;
1412 }
1413 }
1414
0e51b4a3
RW
1415 /* Attributes. */
1416 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_DISTANCE))
ec93aa12 1417 STREAM_GETC(s, api->distance);
0e51b4a3 1418 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_METRIC))
ec93aa12 1419 STREAM_GETL(s, api->metric);
0e51b4a3 1420 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TAG))
ec93aa12 1421 STREAM_GETL(s, api->tag);
0e51b4a3 1422 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_MTU))
ec93aa12 1423 STREAM_GETL(s, api->mtu);
ba1849ef
DS
1424 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TABLEID))
1425 STREAM_GETL(s, api->tableid);
0e51b4a3
RW
1426
1427 return 0;
6a2b0d9a
RW
1428stream_failure:
1429 return -1;
657cde12
DS
1430}
1431
0313523d
FR
1432static void zapi_encode_prefix(struct stream *s, struct prefix *p,
1433 uint8_t family)
0031a6bb
PG
1434{
1435 struct prefix any;
1436
1437 if (!p) {
1438 memset(&any, 0, sizeof(any));
1439 any.family = family;
1440 p = &any;
1441 }
1442
1443 stream_putc(s, p->family);
1444 stream_putc(s, p->prefixlen);
1445 stream_put(s, &p->u.prefix, prefix_blen(p));
1446}
1447
0313523d 1448int zapi_pbr_rule_encode(uint8_t cmd, struct stream *s, struct pbr_rule *zrule)
0031a6bb
PG
1449{
1450 stream_reset(s);
1451 zclient_create_header(s, cmd, zrule->vrf_id);
1452
1453 /*
1454 * We are sending one item at a time at the moment
1455 */
1456 stream_putl(s, 1);
1457
1458 stream_putl(s, zrule->seq);
1459 stream_putl(s, zrule->priority);
1460 stream_putl(s, zrule->unique);
1461
1462 zapi_encode_prefix(s, &(zrule->filter.src_ip),
1463 zrule->filter.src_ip.family);
0313523d 1464 stream_putw(s, zrule->filter.src_port); /* src port */
0031a6bb
PG
1465 zapi_encode_prefix(s, &(zrule->filter.dst_ip),
1466 zrule->filter.src_ip.family);
0313523d
FR
1467 stream_putw(s, zrule->filter.dst_port); /* dst port */
1468 stream_putw(s, zrule->filter.fwmark); /* fwmark */
0031a6bb
PG
1469
1470 stream_putl(s, zrule->action.table);
58a1d249 1471 stream_put(s, zrule->ifname, INTERFACE_NAMSIZ);
0031a6bb
PG
1472
1473 /* Put length at the first point of the stream. */
1474 stream_putw_at(s, 0, stream_get_endp(s));
1475
1476 return 0;
1477}
1478
2f35a820
DS
1479bool zapi_nhg_notify_decode(struct stream *s, uint32_t *id,
1480 enum zapi_nhg_notify_owner *note)
1481{
2c7819b9 1482 uint32_t read_id;
2f35a820 1483
2f35a820 1484 STREAM_GET(note, s, sizeof(*note));
2c7819b9 1485 STREAM_GETL(s, read_id);
2f35a820
DS
1486
1487 *id = read_id;
1488
1489 return true;
1490
1491stream_failure:
1492 return false;
1493}
1494
7ea7b86e 1495bool zapi_route_notify_decode(struct stream *s, struct prefix *p,
28610f7e 1496 uint32_t *tableid,
7ea7b86e
DS
1497 enum zapi_route_notify_owner *note)
1498{
7a1eb44b
DS
1499 uint32_t t;
1500
7ea7b86e
DS
1501 STREAM_GET(note, s, sizeof(*note));
1502
1503 STREAM_GETC(s, p->family);
1504 STREAM_GETC(s, p->prefixlen);
996c9314 1505 STREAM_GET(&p->u.prefix, s, prefix_blen(p));
7a1eb44b
DS
1506 STREAM_GETL(s, t);
1507
1508 *tableid = t;
7ea7b86e
DS
1509
1510 return true;
1511
1512stream_failure:
1513 return false;
1514}
1515
b6c5d343 1516bool zapi_rule_notify_decode(struct stream *s, uint32_t *seqno,
58a1d249 1517 uint32_t *priority, uint32_t *unique, char *ifname,
b6c5d343
DS
1518 enum zapi_rule_notify_owner *note)
1519{
1520 uint32_t prio, seq, uni;
b6c5d343
DS
1521
1522 STREAM_GET(note, s, sizeof(*note));
1523
1524 STREAM_GETL(s, seq);
1525 STREAM_GETL(s, prio);
1526 STREAM_GETL(s, uni);
58a1d249 1527 STREAM_GET(ifname, s, INTERFACE_NAMSIZ);
b6c5d343
DS
1528
1529 if (zclient_debug)
58a1d249 1530 zlog_debug("%s: %u %u %u %s", __func__, seq, prio, uni, ifname);
b6c5d343
DS
1531 *seqno = seq;
1532 *priority = prio;
1533 *unique = uni;
b6c5d343
DS
1534
1535 return true;
1536
1537stream_failure:
1538 return false;
1539}
1540
0313523d
FR
1541bool zapi_ipset_notify_decode(struct stream *s, uint32_t *unique,
1542 enum zapi_ipset_notify_owner *note)
425bdd6b
PG
1543{
1544 uint32_t uni;
1545
1546 STREAM_GET(note, s, sizeof(*note));
1547
1548 STREAM_GETL(s, uni);
1549
1550 if (zclient_debug)
15569c58 1551 zlog_debug("%s: %u", __func__, uni);
425bdd6b
PG
1552 *unique = uni;
1553
1554 return true;
1555
1556stream_failure:
1557 return false;
1558}
1559
0313523d
FR
1560bool zapi_ipset_entry_notify_decode(struct stream *s, uint32_t *unique,
1561 char *ipset_name,
1562 enum zapi_ipset_entry_notify_owner *note)
425bdd6b
PG
1563{
1564 uint32_t uni;
1565
1566 STREAM_GET(note, s, sizeof(*note));
1567
1568 STREAM_GETL(s, uni);
1569
0313523d 1570 STREAM_GET(ipset_name, s, ZEBRA_IPSET_NAME_SIZE);
425bdd6b
PG
1571
1572 if (zclient_debug)
15569c58 1573 zlog_debug("%s: %u", __func__, uni);
425bdd6b
PG
1574 *unique = uni;
1575
1576 return true;
1577
1578stream_failure:
1579 return false;
1580}
1581
c16a0a62
PG
1582bool zapi_iptable_notify_decode(struct stream *s,
1583 uint32_t *unique,
1584 enum zapi_iptable_notify_owner *note)
1585{
1586 uint32_t uni;
1587
1588 STREAM_GET(note, s, sizeof(*note));
1589
1590 STREAM_GETL(s, uni);
1591
1592 if (zclient_debug)
15569c58 1593 zlog_debug("%s: %u", __func__, uni);
c16a0a62
PG
1594 *unique = uni;
1595
1596 return true;
1597
1598stream_failure:
1599 return false;
1600}
1601
e4a1ec74 1602struct nexthop *nexthop_from_zapi_nexthop(const struct zapi_nexthop *znh)
4a749e2c
DS
1603{
1604 struct nexthop *n = nexthop_new();
1605
1606 n->type = znh->type;
4a7371e9 1607 n->vrf_id = znh->vrf_id;
4a749e2c
DS
1608 n->ifindex = znh->ifindex;
1609 n->gate = znh->gate;
31f937fb 1610 n->srte_color = znh->srte_color;
4a749e2c
DS
1611
1612 /*
960035b2 1613 * This function currently handles labels
4a749e2c 1614 */
960035b2
PZ
1615 if (znh->label_num) {
1616 nexthop_add_labels(n, ZEBRA_LSP_NONE, znh->label_num,
0313523d 1617 znh->labels);
960035b2 1618 }
4a749e2c 1619
0a8881b4
MS
1620 if (CHECK_FLAG(znh->flags, ZAPI_NEXTHOP_FLAG_HAS_BACKUP)) {
1621 SET_FLAG(n->flags, NEXTHOP_FLAG_HAS_BACKUP);
474aebd9
MS
1622 n->backup_num = znh->backup_num;
1623 memcpy(n->backup_idx, znh->backup_idx, n->backup_num);
0a8881b4
MS
1624 }
1625
4a749e2c
DS
1626 return n;
1627}
1628
68a02e06
MS
1629/*
1630 * Convert nexthop to zapi nexthop
1631 */
1632int zapi_nexthop_from_nexthop(struct zapi_nexthop *znh,
1633 const struct nexthop *nh)
1634{
1635 int i;
1636
1637 memset(znh, 0, sizeof(*znh));
1638
1639 znh->type = nh->type;
1640 znh->vrf_id = nh->vrf_id;
1df3b1dc 1641 znh->weight = nh->weight;
68a02e06
MS
1642 znh->ifindex = nh->ifindex;
1643 znh->gate = nh->gate;
1644
e90284d7
SW
1645 if (CHECK_FLAG(nh->flags, NEXTHOP_FLAG_ONLINK))
1646 SET_FLAG(znh->flags, ZAPI_NEXTHOP_FLAG_ONLINK);
1647
68a02e06 1648 if (nh->nh_label && (nh->nh_label->num_labels > 0)) {
018c6488
MS
1649
1650 /* Validate */
1651 if (nh->nh_label->num_labels > MPLS_MAX_LABELS)
1652 return -1;
1653
68a02e06
MS
1654 for (i = 0; i < nh->nh_label->num_labels; i++)
1655 znh->labels[i] = nh->nh_label->label[i];
1656
1657 znh->label_num = i;
1658 SET_FLAG(znh->flags, ZAPI_NEXTHOP_FLAG_LABEL);
1659 }
1660
0a8881b4 1661 if (CHECK_FLAG(nh->flags, NEXTHOP_FLAG_HAS_BACKUP)) {
474aebd9
MS
1662 if (nh->backup_num > NEXTHOP_MAX_BACKUPS)
1663 return -1;
1664
0a8881b4 1665 SET_FLAG(znh->flags, ZAPI_NEXTHOP_FLAG_HAS_BACKUP);
474aebd9
MS
1666 znh->backup_num = nh->backup_num;
1667 memcpy(znh->backup_idx, nh->backup_idx, znh->backup_num);
0a8881b4
MS
1668 }
1669
68a02e06
MS
1670 return 0;
1671}
1672
0a8881b4
MS
1673/*
1674 * Wrapper that converts backup nexthop
1675 */
1676int zapi_backup_nexthop_from_nexthop(struct zapi_nexthop *znh,
1677 const struct nexthop *nh)
1678{
1679 int ret;
1680
1681 /* Ensure that zapi flags are correct: backups don't have backups */
1682 ret = zapi_nexthop_from_nexthop(znh, nh);
1683 if (ret == 0)
1684 UNSET_FLAG(znh->flags, ZAPI_NEXTHOP_FLAG_HAS_BACKUP);
1685
1686 return ret;
1687}
1688
ae076fc2
MS
1689/*
1690 * Format some info about a zapi nexthop, for debug or logging.
1691 */
1692const char *zapi_nexthop2str(const struct zapi_nexthop *znh, char *buf,
1693 int bufsize)
1694{
1695 char tmp[INET6_ADDRSTRLEN];
1696
1697 switch (znh->type) {
1698 case NEXTHOP_TYPE_IFINDEX:
1699 snprintf(buf, bufsize, "if %u", znh->ifindex);
1700 break;
1701 case NEXTHOP_TYPE_IPV4:
1702 case NEXTHOP_TYPE_IPV4_IFINDEX:
1703 inet_ntop(AF_INET, &znh->gate.ipv4, tmp, sizeof(tmp));
1704 snprintf(buf, bufsize, "%s if %u", tmp, znh->ifindex);
1705 break;
1706 case NEXTHOP_TYPE_IPV6:
1707 case NEXTHOP_TYPE_IPV6_IFINDEX:
1708 inet_ntop(AF_INET6, &znh->gate.ipv6, tmp, sizeof(tmp));
1709 snprintf(buf, bufsize, "%s if %u", tmp, znh->ifindex);
1710 break;
1711 case NEXTHOP_TYPE_BLACKHOLE:
1712 snprintf(buf, bufsize, "blackhole");
1713 break;
1714 default:
1715 snprintf(buf, bufsize, "unknown");
1716 break;
1717 }
1718
1719 return buf;
1720}
1721
68a02e06
MS
1722/*
1723 * Decode the nexthop-tracking update message
1724 */
4a749e2c
DS
1725bool zapi_nexthop_update_decode(struct stream *s, struct zapi_route *nhr)
1726{
1727 uint32_t i;
1728
1729 memset(nhr, 0, sizeof(*nhr));
1730
31f937fb 1731 STREAM_GETL(s, nhr->message);
4a749e2c
DS
1732 STREAM_GETW(s, nhr->prefix.family);
1733 STREAM_GETC(s, nhr->prefix.prefixlen);
996c9314 1734 switch (nhr->prefix.family) {
4a749e2c
DS
1735 case AF_INET:
1736 STREAM_GET(&nhr->prefix.u.prefix4.s_addr, s, IPV4_MAX_BYTELEN);
1737 break;
1738 case AF_INET6:
1739 STREAM_GET(&nhr->prefix.u.prefix6, s, IPV6_MAX_BYTELEN);
1740 break;
1741 default:
1742 break;
1743 }
31f937fb
SM
1744 if (CHECK_FLAG(nhr->message, ZAPI_MESSAGE_SRTE))
1745 STREAM_GETL(s, nhr->srte_color);
4a749e2c 1746
05dd5aaf
DS
1747 STREAM_GETC(s, nhr->type);
1748 STREAM_GETW(s, nhr->instance);
4a749e2c
DS
1749 STREAM_GETC(s, nhr->distance);
1750 STREAM_GETL(s, nhr->metric);
1751 STREAM_GETC(s, nhr->nexthop_num);
1752
996c9314 1753 for (i = 0; i < nhr->nexthop_num; i++) {
31f937fb 1754 if (zapi_nexthop_decode(s, &(nhr->nexthops[i]), 0, 0) != 0)
2fec17cd 1755 return false;
4a749e2c
DS
1756 }
1757
1758 return true;
1759stream_failure:
1760 return false;
1761}
1762
9ab0b2a3
SW
1763bool zapi_error_decode(struct stream *s, enum zebra_error_types *error)
1764{
1765 memset(error, 0, sizeof(*error));
1766
1767 STREAM_GET(error, s, sizeof(*error));
1768
1769 if (zclient_debug)
1770 zlog_debug("%s: type: %s", __func__,
1771 zebra_error_type2str(*error));
1772
1773 return true;
1774stream_failure:
1775 return false;
1776}
1777
d62a17ae 1778/*
0a589359 1779 * send a ZEBRA_REDISTRIBUTE_ADD or ZEBRA_REDISTRIBUTE_DELETE
1780 * for the route type (ZEBRA_ROUTE_KERNEL etc.). The zebra server will
d62a17ae 1781 * then set/unset redist[type] in the client handle (a struct zserv) for the
0a589359 1782 * sending client
1783 */
d62a17ae 1784int zebra_redistribute_send(int command, struct zclient *zclient, afi_t afi,
d7c0a89a 1785 int type, unsigned short instance, vrf_id_t vrf_id)
718e3744 1786{
d62a17ae 1787 struct stream *s;
1788
1789 s = zclient->obuf;
1790 stream_reset(s);
1791
1792 zclient_create_header(s, command, vrf_id);
1793 stream_putc(s, afi);
1794 stream_putc(s, type);
1795 stream_putw(s, instance);
1796
1797 stream_putw_at(s, 0, stream_get_endp(s));
1798
1799 return zclient_send_message(zclient);
718e3744 1800}
1801
49db7a7b
RW
1802int zebra_redistribute_default_send(int command, struct zclient *zclient,
1803 afi_t afi, vrf_id_t vrf_id)
1804{
1805 struct stream *s;
1806
1807 s = zclient->obuf;
1808 stream_reset(s);
1809
1810 zclient_create_header(s, command, vrf_id);
1811 stream_putc(s, afi);
1812
1813 stream_putw_at(s, 0, stream_get_endp(s));
1814
1815 return zclient_send_message(zclient);
1816}
1817
d9178828 1818/* Get prefix in ZServ format; family should be filled in on prefix */
efc7191b 1819static int zclient_stream_get_prefix(struct stream *s, struct prefix *p)
d9178828 1820{
d62a17ae 1821 size_t plen = prefix_blen(p);
d7c0a89a 1822 uint8_t c;
d62a17ae 1823 p->prefixlen = 0;
1824
1825 if (plen == 0)
efc7191b 1826 return -1;
d62a17ae 1827
efc7191b 1828 STREAM_GET(&p->u.prefix, s, plen);
ec93aa12 1829 STREAM_GETC(s, c);
d62a17ae 1830 p->prefixlen = MIN(plen * 8, c);
ec93aa12 1831
efc7191b 1832 return 0;
ec93aa12 1833stream_failure:
efc7191b 1834 return -1;
d9178828
PJ
1835}
1836
18a6dce6 1837/* Router-id update from zebra daemon. */
efc7191b 1838int zebra_router_id_update_read(struct stream *s, struct prefix *rid)
18a6dce6 1839{
d62a17ae 1840 /* Fetch interface address. */
ec93aa12 1841 STREAM_GETC(s, rid->family);
d62a17ae 1842
efc7191b 1843 return zclient_stream_get_prefix(s, rid);
ec93aa12
DS
1844
1845stream_failure:
efc7191b 1846 return -1;
18a6dce6 1847}
1848
718e3744 1849/* Interface addition from zebra daemon. */
d62a17ae 1850/*
0a589359 1851 * The format of the message sent with type ZEBRA_INTERFACE_ADD or
1852 * ZEBRA_INTERFACE_DELETE from zebra to the client is:
1853 * 0 1 2 3
1854 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
0a589359 1855 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1856 * | ifname |
1857 * | |
1858 * | |
1859 * | |
1860 * | |
1861 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee
OD
1862 * | ifindex |
1863 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1864 * | status |
0a589359 1865 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee 1866 * | if_flags |
c77d4546 1867 * | |
0a589359 1868 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee
OD
1869 * | metric |
1870 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2d7f0d76
DS
1871 * | speed |
1872 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee
OD
1873 * | ifmtu |
1874 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1875 * | ifmtu6 |
1876 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1877 * | bandwidth |
1878 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
53e60e5c
QY
1879 * | parent ifindex |
1880 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee 1881 * | Link Layer Type |
0a589359 1882 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee 1883 * | Harware Address Length |
0a589359 1884 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee
OD
1885 * | Hardware Address if HW lenght different from 0 |
1886 * | ... max INTERFACE_HWADDR_MAX |
0a589359 1887 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee 1888 * | Link_params? | Whether a link-params follows: 1 or 0.
0a589359 1889 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee
OD
1890 * | Link_params 0 or 1 INTERFACE_LINK_PARAMS_SIZE sized |
1891 * | .... (struct if_link_params). |
0a589359 1892 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1893 */
1894
efc7191b 1895static int zclient_vrf_add(struct zclient *zclient, vrf_id_t vrf_id)
1892f15e 1896{
d62a17ae 1897 struct vrf *vrf;
f17a9d0a 1898 char vrfname_tmp[VRF_NAMSIZ + 1] = {};
d62a17ae 1899 struct vrf_data data;
1892f15e 1900
efc7191b 1901 STREAM_GET(&data, zclient->ibuf, sizeof(struct vrf_data));
d62a17ae 1902 /* Read interface name. */
efc7191b 1903 STREAM_GET(vrfname_tmp, zclient->ibuf, VRF_NAMSIZ);
1892f15e 1904
f17a9d0a
QY
1905 if (strlen(vrfname_tmp) == 0)
1906 goto stream_failure;
1907
cff0de12 1908 /* Lookup/create vrf by name, then vrf_id. */
d62a17ae 1909 vrf = vrf_get(vrf_id, vrfname_tmp);
f17a9d0a 1910
cff0de12
QY
1911 /* If there's already a VRF with this name, don't create vrf */
1912 if (!vrf)
f17a9d0a
QY
1913 return 0;
1914
4691b65a
PG
1915 vrf->data.l.table_id = data.l.table_id;
1916 memcpy(vrf->data.l.netns_name, data.l.netns_name, NS_NAMSIZ);
4931a365
PG
1917 /* overwrite default vrf */
1918 if (vrf_id == VRF_DEFAULT)
4fe52e76 1919 vrf_set_default_name(vrfname_tmp, false);
d62a17ae 1920 vrf_enable(vrf);
efc7191b
QY
1921
1922 return 0;
1923stream_failure:
1924 return -1;
1892f15e
DS
1925}
1926
d62a17ae 1927static void zclient_vrf_delete(struct zclient *zclient, vrf_id_t vrf_id)
1892f15e 1928{
d62a17ae 1929 struct vrf *vrf;
1892f15e 1930
d62a17ae 1931 /* Lookup vrf by vrf_id. */
1932 vrf = vrf_lookup_by_id(vrf_id);
1892f15e 1933
d62a17ae 1934 /*
1935 * If a routing protocol doesn't know about a
1936 * vrf that is about to be deleted. There is
1937 * no point in attempting to delete it.
1938 */
1939 if (!vrf)
1940 return;
beef1990 1941
d62a17ae 1942 vrf_delete(vrf);
1892f15e
DS
1943}
1944
efc7191b 1945static int zclient_interface_add(struct zclient *zclient, vrf_id_t vrf_id)
718e3744 1946{
d62a17ae 1947 struct interface *ifp;
b98edbcc 1948 char ifname_tmp[INTERFACE_NAMSIZ + 1] = {};
ef7bd2a3 1949 struct stream *s = zclient->ibuf;
718e3744 1950
d62a17ae 1951 /* Read interface name. */
efc7191b 1952 STREAM_GET(ifname_tmp, s, INTERFACE_NAMSIZ);
718e3744 1953
d62a17ae 1954 /* Lookup/create interface by name. */
229d0d4e
QY
1955 if (!vrf_get(vrf_id, NULL)) {
1956 zlog_debug(
1957 "Rx'd interface add from Zebra, but VRF %u does not exist",
1958 vrf_id);
1959 return -1;
1960 }
1961
a36898e7 1962 ifp = if_get_by_name(ifname_tmp, vrf_id);
a41c4e1b 1963
d62a17ae 1964 zebra_interface_if_set_value(s, ifp);
718e3744 1965
ef7bd2a3 1966 if_new_via_zapi(ifp);
efc7191b
QY
1967
1968 return 0;
1969stream_failure:
1970 return -1;
718e3744 1971}
1972
d62a17ae 1973/*
0a589359 1974 * Read interface up/down msg (ZEBRA_INTERFACE_UP/ZEBRA_INTERFACE_DOWN)
1975 * from zebra server. The format of this message is the same as
ef7bd2a3
DS
1976 * that sent for ZEBRA_INTERFACE_ADD/ZEBRA_INTERFACE_DELETE,
1977 * except that no sockaddr_dl is sent at the tail of the message.
0a589359 1978 */
d62a17ae 1979struct interface *zebra_interface_state_read(struct stream *s, vrf_id_t vrf_id)
718e3744 1980{
d62a17ae 1981 struct interface *ifp;
f17a9d0a 1982 char ifname_tmp[INTERFACE_NAMSIZ + 1] = {};
d62a17ae 1983
1984 /* Read interface name. */
efc7191b 1985 STREAM_GET(ifname_tmp, s, INTERFACE_NAMSIZ);
d62a17ae 1986
1987 /* Lookup this by interface index. */
a36898e7 1988 ifp = if_lookup_by_name(ifname_tmp, vrf_id);
d62a17ae 1989 if (ifp == NULL) {
450971aa 1990 flog_err(EC_LIB_ZAPI_ENCODE,
decbd929
DS
1991 "INTERFACE_STATE: Cannot find IF %s in VRF %d",
1992 ifname_tmp, vrf_id);
d62a17ae 1993 return NULL;
1994 }
1995
1996 zebra_interface_if_set_value(s, ifp);
1997
1998 return ifp;
efc7191b
QY
1999stream_failure:
2000 return NULL;
718e3744 2001}
2002
3c3c3252
DS
2003static void zclient_interface_delete(struct zclient *zclient, vrf_id_t vrf_id)
2004{
2005 struct interface *ifp;
2006 struct stream *s = zclient->ibuf;
2007
2008 ifp = zebra_interface_state_read(s, vrf_id);
2009
2010 if (ifp == NULL)
2011 return;
2012
2013 if_destroy_via_zapi(ifp);
2014 return;
2015}
2016
ddbf3e60
DS
2017static void zclient_interface_up(struct zclient *zclient, vrf_id_t vrf_id)
2018{
2019 struct interface *ifp;
2020 struct stream *s = zclient->ibuf;
2021
2022 ifp = zebra_interface_state_read(s, vrf_id);
2023
2024 if (!ifp)
2025 return;
2026
2027 if_up_via_zapi(ifp);
2028}
2029
b0b69e59
DS
2030static void zclient_interface_down(struct zclient *zclient, vrf_id_t vrf_id)
2031{
2032 struct interface *ifp;
2033 struct stream *s = zclient->ibuf;
2034
2035 ifp = zebra_interface_state_read(s, vrf_id);
2036
2037 if (!ifp)
2038 return;
2039
2040 if_down_via_zapi(ifp);
2041}
2042
9ab0b2a3
SW
2043static void zclient_handle_error(ZAPI_CALLBACK_ARGS)
2044{
2045 enum zebra_error_types error;
2046 struct stream *s = zclient->ibuf;
2047
2048 zapi_error_decode(s, &error);
2049
2050 if (zclient->handle_error)
2051 (*zclient->handle_error)(error);
2052}
2053
efc7191b 2054static int link_params_set_value(struct stream *s, struct if_link_params *iflp)
16f1b9ee
OD
2055{
2056
d62a17ae 2057 if (iflp == NULL)
efc7191b 2058 return -1;
d62a17ae 2059
efc7191b
QY
2060 uint32_t bwclassnum;
2061
2062 STREAM_GETL(s, iflp->lp_status);
2063 STREAM_GETL(s, iflp->te_metric);
2064 STREAM_GETF(s, iflp->max_bw);
2065 STREAM_GETF(s, iflp->max_rsv_bw);
2066 STREAM_GETL(s, bwclassnum);
d62a17ae 2067 {
2068 unsigned int i;
2069 for (i = 0; i < bwclassnum && i < MAX_CLASS_TYPE; i++)
efc7191b 2070 STREAM_GETF(s, iflp->unrsv_bw[i]);
d62a17ae 2071 if (i < bwclassnum)
1c50c1c0
QY
2072 flog_err(
2073 EC_LIB_ZAPI_MISSMATCH,
3efd0893 2074 "%s: received %d > %d (MAX_CLASS_TYPE) bw entries - outdated library?",
1c50c1c0 2075 __func__, bwclassnum, MAX_CLASS_TYPE);
d62a17ae 2076 }
efc7191b
QY
2077 STREAM_GETL(s, iflp->admin_grp);
2078 STREAM_GETL(s, iflp->rmt_as);
d62a17ae 2079 iflp->rmt_ip.s_addr = stream_get_ipv4(s);
2080
efc7191b
QY
2081 STREAM_GETL(s, iflp->av_delay);
2082 STREAM_GETL(s, iflp->min_delay);
2083 STREAM_GETL(s, iflp->max_delay);
2084 STREAM_GETL(s, iflp->delay_var);
2085
2086 STREAM_GETF(s, iflp->pkt_loss);
2087 STREAM_GETF(s, iflp->res_bw);
2088 STREAM_GETF(s, iflp->ava_bw);
2089 STREAM_GETF(s, iflp->use_bw);
d62a17ae 2090
efc7191b
QY
2091 return 0;
2092stream_failure:
2093 return -1;
16f1b9ee
OD
2094}
2095
edc12762
RW
2096struct interface *zebra_interface_link_params_read(struct stream *s,
2097 vrf_id_t vrf_id)
16f1b9ee 2098{
d62a17ae 2099 struct if_link_params *iflp;
2100 ifindex_t ifindex;
c28e5b2a 2101
efc7191b 2102 STREAM_GETL(s, ifindex);
16f1b9ee 2103
a36898e7 2104 struct interface *ifp = if_lookup_by_index(ifindex, vrf_id);
16f1b9ee 2105
d62a17ae 2106 if (ifp == NULL) {
450971aa 2107 flog_err(EC_LIB_ZAPI_ENCODE,
1c50c1c0
QY
2108 "%s: unknown ifindex %u, shouldn't happen", __func__,
2109 ifindex);
d62a17ae 2110 return NULL;
2111 }
16f1b9ee 2112
d62a17ae 2113 if ((iflp = if_link_params_get(ifp)) == NULL)
2114 return NULL;
16f1b9ee 2115
efc7191b
QY
2116 if (link_params_set_value(s, iflp) != 0)
2117 goto stream_failure;
16f1b9ee 2118
d62a17ae 2119 return ifp;
efc7191b
QY
2120
2121stream_failure:
2122 return NULL;
16f1b9ee
OD
2123}
2124
41ce5384
QY
2125static void zebra_interface_if_set_value(struct stream *s,
2126 struct interface *ifp)
16f1b9ee 2127{
d7c0a89a 2128 uint8_t link_params_status = 0;
41ce5384 2129 ifindex_t old_ifindex, new_ifindex;
efc7191b 2130
e7ff0253 2131 old_ifindex = ifp->oldifindex;
d62a17ae 2132 /* Read interface's index. */
41ce5384
QY
2133 STREAM_GETL(s, new_ifindex);
2134 if_set_index(ifp, new_ifindex);
2135 STREAM_GETC(s, ifp->status);
d62a17ae 2136
2137 /* Read interface's value. */
41ce5384
QY
2138 STREAM_GETQ(s, ifp->flags);
2139 STREAM_GETC(s, ifp->ptm_enable);
2140 STREAM_GETC(s, ifp->ptm_status);
2141 STREAM_GETL(s, ifp->metric);
2142 STREAM_GETL(s, ifp->speed);
2143 STREAM_GETL(s, ifp->mtu);
2144 STREAM_GETL(s, ifp->mtu6);
2145 STREAM_GETL(s, ifp->bandwidth);
2146 STREAM_GETL(s, ifp->link_ifindex);
2147 STREAM_GETL(s, ifp->ll_type);
2148 STREAM_GETL(s, ifp->hw_addr_len);
2149 if (ifp->hw_addr_len)
2150 STREAM_GET(ifp->hw_addr, s,
2151 MIN(ifp->hw_addr_len, INTERFACE_HWADDR_MAX));
d62a17ae 2152
2153 /* Read Traffic Engineering status */
41ce5384 2154 link_params_status = stream_getc(s);
d62a17ae 2155 /* Then, Traffic Engineering parameters if any */
2156 if (link_params_status) {
41ce5384
QY
2157 struct if_link_params *iflp = if_link_params_get(ifp);
2158 link_params_set_value(s, iflp);
d62a17ae 2159 }
98cbbaea
DS
2160
2161 nexthop_group_interface_state_change(ifp, old_ifindex);
efc7191b 2162
41ce5384 2163 return;
efc7191b 2164stream_failure:
41ce5384
QY
2165 zlog_err("Could not parse interface values; aborting");
2166 assert(!"Failed to parse interface values");
16f1b9ee
OD
2167}
2168
d62a17ae 2169size_t zebra_interface_link_params_write(struct stream *s,
2170 struct interface *ifp)
16f1b9ee 2171{
d62a17ae 2172 size_t w;
2173 struct if_link_params *iflp;
2174 int i;
16f1b9ee 2175
d62a17ae 2176 if (s == NULL || ifp == NULL || ifp->link_params == NULL)
2177 return 0;
16f1b9ee 2178
d62a17ae 2179 iflp = ifp->link_params;
2180 w = 0;
16f1b9ee 2181
d62a17ae 2182 w += stream_putl(s, iflp->lp_status);
16f1b9ee 2183
d62a17ae 2184 w += stream_putl(s, iflp->te_metric);
2185 w += stream_putf(s, iflp->max_bw);
2186 w += stream_putf(s, iflp->max_rsv_bw);
16f1b9ee 2187
d62a17ae 2188 w += stream_putl(s, MAX_CLASS_TYPE);
2189 for (i = 0; i < MAX_CLASS_TYPE; i++)
2190 w += stream_putf(s, iflp->unrsv_bw[i]);
16f1b9ee 2191
d62a17ae 2192 w += stream_putl(s, iflp->admin_grp);
2193 w += stream_putl(s, iflp->rmt_as);
2194 w += stream_put_in_addr(s, &iflp->rmt_ip);
16f1b9ee 2195
d62a17ae 2196 w += stream_putl(s, iflp->av_delay);
2197 w += stream_putl(s, iflp->min_delay);
2198 w += stream_putl(s, iflp->max_delay);
2199 w += stream_putl(s, iflp->delay_var);
16f1b9ee 2200
d62a17ae 2201 w += stream_putf(s, iflp->pkt_loss);
2202 w += stream_putf(s, iflp->res_bw);
2203 w += stream_putf(s, iflp->ava_bw);
2204 w += stream_putf(s, iflp->use_bw);
16f1b9ee 2205
d62a17ae 2206 return w;
16f1b9ee
OD
2207}
2208
2209/*
0a589359 2210 * format of message for address additon is:
2211 * 0
2212 * 0 1 2 3 4 5 6 7
2213 * +-+-+-+-+-+-+-+-+
2214 * | type | ZEBRA_INTERFACE_ADDRESS_ADD or
2215 * +-+-+-+-+-+-+-+-+ ZEBRA_INTERFACE_ADDRES_DELETE
2216 * | |
2217 * + +
2218 * | ifindex |
2219 * + +
2220 * | |
2221 * + +
2222 * | |
2223 * +-+-+-+-+-+-+-+-+
2224 * | ifc_flags | flags for connected address
2225 * +-+-+-+-+-+-+-+-+
2226 * | addr_family |
2227 * +-+-+-+-+-+-+-+-+
2228 * | addr... |
2229 * : :
2230 * | |
2231 * +-+-+-+-+-+-+-+-+
2232 * | addr_len | len of addr. E.g., addr_len = 4 for ipv4 addrs.
2233 * +-+-+-+-+-+-+-+-+
2234 * | daddr.. |
2235 * : :
2236 * | |
2237 * +-+-+-+-+-+-+-+-+
0a589359 2238 */
2239
d62a17ae 2240static int memconstant(const void *s, int c, size_t n)
3fb9cd6e 2241{
d7c0a89a 2242 const uint8_t *p = s;
3fb9cd6e 2243
d62a17ae 2244 while (n-- > 0)
2245 if (*p++ != c)
2246 return 0;
2247 return 1;
3fb9cd6e 2248}
2249
d5a5c8f0 2250
d62a17ae 2251struct connected *zebra_interface_address_read(int type, struct stream *s,
2252 vrf_id_t vrf_id)
718e3744 2253{
d62a17ae 2254 ifindex_t ifindex;
2255 struct interface *ifp;
2256 struct connected *ifc;
2257 struct prefix p, d, *dp;
2258 int plen;
d7c0a89a 2259 uint8_t ifc_flags;
d62a17ae 2260
2261 memset(&p, 0, sizeof(p));
2262 memset(&d, 0, sizeof(d));
2263
2264 /* Get interface index. */
efc7191b 2265 STREAM_GETL(s, ifindex);
d62a17ae 2266
2267 /* Lookup index. */
2268 ifp = if_lookup_by_index(ifindex, vrf_id);
2269 if (ifp == NULL) {
450971aa 2270 flog_err(EC_LIB_ZAPI_ENCODE,
decbd929
DS
2271 "INTERFACE_ADDRESS_%s: Cannot find IF %u in VRF %d",
2272 (type == ZEBRA_INTERFACE_ADDRESS_ADD) ? "ADD" : "DEL",
2273 ifindex, vrf_id);
d62a17ae 2274 return NULL;
2275 }
2276
2277 /* Fetch flag. */
efc7191b 2278 STREAM_GETC(s, ifc_flags);
d62a17ae 2279
2280 /* Fetch interface address. */
efc7191b 2281 STREAM_GETC(s, d.family);
e4f5680d 2282 p.family = d.family;
d62a17ae 2283 plen = prefix_blen(&d);
2284
efc7191b
QY
2285 if (zclient_stream_get_prefix(s, &p) != 0)
2286 goto stream_failure;
d62a17ae 2287
2288 /* Fetch destination address. */
efc7191b 2289 STREAM_GET(&d.u.prefix, s, plen);
d62a17ae 2290
2291 /* N.B. NULL destination pointers are encoded as all zeroes */
2292 dp = memconstant(&d.u.prefix, 0, plen) ? NULL : &d;
2293
2294 if (type == ZEBRA_INTERFACE_ADDRESS_ADD) {
2295 ifc = connected_lookup_prefix_exact(ifp, &p);
2296 if (!ifc) {
2297 /* N.B. NULL destination pointers are encoded as all
2298 * zeroes */
2299 ifc = connected_add_by_prefix(ifp, &p, dp);
2300 }
2301 if (ifc) {
2302 ifc->flags = ifc_flags;
2303 if (ifc->destination)
2304 ifc->destination->prefixlen =
2305 ifc->address->prefixlen;
2306 else if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_PEER)) {
2307 /* carp interfaces on OpenBSD with 0.0.0.0/0 as
2308 * "peer" */
ade6974d 2309 flog_err(
450971aa 2310 EC_LIB_ZAPI_ENCODE,
2dbe669b
DA
2311 "warning: interface %s address %pFX with peer flag set, but no peer address!",
2312 ifp->name, ifc->address);
d62a17ae 2313 UNSET_FLAG(ifc->flags, ZEBRA_IFA_PEER);
2314 }
2315 }
2316 } else {
2317 assert(type == ZEBRA_INTERFACE_ADDRESS_DELETE);
2318 ifc = connected_delete_by_prefix(ifp, &p);
2319 }
2320
2321 return ifc;
efc7191b
QY
2322
2323stream_failure:
2324 return NULL;
718e3744 2325}
0a589359 2326
a80beece
DS
2327/*
2328 * format of message for neighbor connected address is:
2329 * 0
2330 * 0 1 2 3 4 5 6 7
2331 * +-+-+-+-+-+-+-+-+
2332 * | type | ZEBRA_INTERFACE_NBR_ADDRESS_ADD or
2333 * +-+-+-+-+-+-+-+-+ ZEBRA_INTERFACE_NBR_ADDRES_DELETE
2334 * | |
2335 * + +
2336 * | ifindex |
2337 * + +
2338 * | |
2339 * + +
2340 * | |
2341 * +-+-+-+-+-+-+-+-+
2342 * | addr_family |
2343 * +-+-+-+-+-+-+-+-+
2344 * | addr... |
2345 * : :
2346 * | |
2347 * +-+-+-+-+-+-+-+-+
2348 * | addr_len | len of addr.
2349 * +-+-+-+-+-+-+-+-+
2350 */
2351struct nbr_connected *
d62a17ae 2352zebra_interface_nbr_address_read(int type, struct stream *s, vrf_id_t vrf_id)
a80beece 2353{
d62a17ae 2354 unsigned int ifindex;
2355 struct interface *ifp;
2356 struct prefix p;
2357 struct nbr_connected *ifc;
2358
2359 /* Get interface index. */
efc7191b 2360 STREAM_GETL(s, ifindex);
d62a17ae 2361
2362 /* Lookup index. */
2363 ifp = if_lookup_by_index(ifindex, vrf_id);
2364 if (ifp == NULL) {
450971aa 2365 flog_err(EC_LIB_ZAPI_ENCODE,
decbd929
DS
2366 "INTERFACE_NBR_%s: Cannot find IF %u in VRF %d",
2367 (type == ZEBRA_INTERFACE_NBR_ADDRESS_ADD) ? "ADD"
ade6974d
QY
2368 : "DELETE",
2369 ifindex, vrf_id);
d62a17ae 2370 return NULL;
2371 }
2372
efc7191b
QY
2373 STREAM_GETC(s, p.family);
2374 STREAM_GET(&p.u.prefix, s, prefix_blen(&p));
2375 STREAM_GETC(s, p.prefixlen);
d62a17ae 2376
2377 if (type == ZEBRA_INTERFACE_NBR_ADDRESS_ADD) {
2378 /* Currently only supporting P2P links, so any new RA source
2379 address is
2380 considered as the replacement of the previously learnt
2381 Link-Local address. */
2382 if (!(ifc = listnode_head(ifp->nbr_connected))) {
2383 ifc = nbr_connected_new();
2384 ifc->address = prefix_new();
2385 ifc->ifp = ifp;
2386 listnode_add(ifp->nbr_connected, ifc);
2387 }
2388
2389 prefix_copy(ifc->address, &p);
2390 } else {
2391 assert(type == ZEBRA_INTERFACE_NBR_ADDRESS_DELETE);
2392
2393 ifc = nbr_connected_check(ifp, &p);
2394 if (ifc)
2395 listnode_delete(ifp->nbr_connected, ifc);
2396 }
2397
2398 return ifc;
efc7191b
QY
2399
2400stream_failure:
2401 return NULL;
a80beece 2402}
6b0655a2 2403
d62a17ae 2404struct interface *zebra_interface_vrf_update_read(struct stream *s,
2405 vrf_id_t vrf_id,
2406 vrf_id_t *new_vrf_id)
c8e264b6 2407{
f17a9d0a 2408 char ifname[INTERFACE_NAMSIZ + 1] = {};
d62a17ae 2409 struct interface *ifp;
a9ff90c4 2410 vrf_id_t new_id;
d62a17ae 2411
91d227b7 2412 /* Read interface name. */
efc7191b 2413 STREAM_GET(ifname, s, INTERFACE_NAMSIZ);
d62a17ae 2414
2415 /* Lookup interface. */
a36898e7 2416 ifp = if_lookup_by_name(ifname, vrf_id);
d62a17ae 2417 if (ifp == NULL) {
450971aa 2418 flog_err(EC_LIB_ZAPI_ENCODE,
91d227b7
RW
2419 "INTERFACE_VRF_UPDATE: Cannot find IF %s in VRF %d",
2420 ifname, vrf_id);
d62a17ae 2421 return NULL;
2422 }
2423
2424 /* Fetch new VRF Id. */
efc7191b 2425 STREAM_GETL(s, new_id);
d62a17ae 2426
2427 *new_vrf_id = new_id;
2428 return ifp;
efc7191b
QY
2429
2430stream_failure:
2431 return NULL;
c8e264b6 2432}
5c7ef8dc 2433
2434/* filter unwanted messages until the expected one arrives */
d62a17ae 2435static int zclient_read_sync_response(struct zclient *zclient,
d7c0a89a 2436 uint16_t expected_cmd)
5c7ef8dc 2437{
d62a17ae 2438 struct stream *s;
d7c0a89a
QY
2439 uint16_t size = -1;
2440 uint8_t marker;
2441 uint8_t version;
d62a17ae 2442 vrf_id_t vrf_id;
d7c0a89a 2443 uint16_t cmd;
d62a17ae 2444 fd_set readfds;
2445 int ret;
2446
2447 ret = 0;
2448 cmd = expected_cmd + 1;
2449 while (ret == 0 && cmd != expected_cmd) {
2450 s = zclient->ibuf;
2451 stream_reset(s);
2452
2453 /* wait until response arrives */
2454 FD_ZERO(&readfds);
2455 FD_SET(zclient->sock, &readfds);
2456 select(zclient->sock + 1, &readfds, NULL, NULL, NULL);
2457 if (!FD_ISSET(zclient->sock, &readfds))
2458 continue;
2459 /* read response */
2460 ret = zclient_read_header(s, zclient->sock, &size, &marker,
2461 &version, &vrf_id, &cmd);
2462 if (zclient_debug)
2463 zlog_debug("%s: Response (%d bytes) received", __func__,
2464 size);
2465 }
2466 if (ret != 0) {
1c50c1c0
QY
2467 flog_err(EC_LIB_ZAPI_ENCODE, "%s: Invalid Sync Message Reply",
2468 __func__);
d62a17ae 2469 return -1;
2470 }
2471
2472 return 0;
5c7ef8dc 2473}
fea12efb 2474/**
2475 * Connect to label manager in a syncronous way
2476 *
2477 * It first writes the request to zcient output buffer and then
2478 * immediately reads the answer from the input buffer.
2479 *
2480 * @param zclient Zclient used to connect to label manager (zebra)
f533be73 2481 * @param async Synchronous (0) or asynchronous (1) operation
fea12efb 2482 * @result Result of response
2483 */
f533be73 2484int lm_label_manager_connect(struct zclient *zclient, int async)
fea12efb 2485{
d62a17ae 2486 int ret;
2487 struct stream *s;
d7c0a89a 2488 uint8_t result;
f533be73 2489 uint16_t cmd = async ? ZEBRA_LABEL_MANAGER_CONNECT_ASYNC :
2490 ZEBRA_LABEL_MANAGER_CONNECT;
d62a17ae 2491
2492 if (zclient_debug)
35cbe02a 2493 zlog_debug("Connecting to Label Manager (LM)");
d62a17ae 2494
f533be73 2495 if (zclient->sock < 0) {
2496 zlog_debug("%s: invalid zclient socket", __func__);
d62a17ae 2497 return -1;
f533be73 2498 }
d62a17ae 2499
2500 /* send request */
2501 s = zclient->obuf;
2502 stream_reset(s);
f533be73 2503 zclient_create_header(s, cmd, VRF_DEFAULT);
d62a17ae 2504
2505 /* proto */
2506 stream_putc(s, zclient->redist_default);
2507 /* instance */
2508 stream_putw(s, zclient->instance);
2509
2510 /* Put length at the first point of the stream. */
2511 stream_putw_at(s, 0, stream_get_endp(s));
2512
2513 ret = writen(zclient->sock, s->data, stream_get_endp(s));
2514 if (ret < 0) {
450971aa 2515 flog_err(EC_LIB_ZAPI_SOCKET, "Can't write to zclient sock");
d62a17ae 2516 close(zclient->sock);
2517 zclient->sock = -1;
2518 return -1;
2519 }
2520 if (ret == 0) {
450971aa 2521 flog_err(EC_LIB_ZAPI_SOCKET, "Zclient sock closed");
d62a17ae 2522 close(zclient->sock);
2523 zclient->sock = -1;
2524 return -1;
2525 }
2526 if (zclient_debug)
35cbe02a 2527 zlog_debug("LM connect request sent (%d bytes)", ret);
d62a17ae 2528
f533be73 2529 if (async)
2530 return 0;
2531
d62a17ae 2532 /* read response */
f533be73 2533 if (zclient_read_sync_response(zclient, cmd)
d62a17ae 2534 != 0)
2535 return -1;
2536
d62a17ae 2537 s = zclient->ibuf;
5dffb0e9
FR
2538
2539 /* read instance and proto */
efc7191b
QY
2540 uint8_t proto;
2541 uint16_t instance;
2542
2543 STREAM_GETC(s, proto);
2544 STREAM_GETW(s, instance);
5dffb0e9
FR
2545
2546 /* sanity */
2547 if (proto != zclient->redist_default)
1c50c1c0
QY
2548 flog_err(
2549 EC_LIB_ZAPI_ENCODE,
2550 "Wrong proto (%u) in LM connect response. Should be %u",
2551 proto, zclient->redist_default);
5dffb0e9 2552 if (instance != zclient->instance)
1c50c1c0
QY
2553 flog_err(
2554 EC_LIB_ZAPI_ENCODE,
2555 "Wrong instId (%u) in LM connect response. Should be %u",
2556 instance, zclient->instance);
5dffb0e9
FR
2557
2558 /* result code */
efc7191b 2559 STREAM_GETC(s, result);
d62a17ae 2560 if (zclient_debug)
0313523d 2561 zlog_debug("LM connect-response received, result %u", result);
d62a17ae 2562
2563 return (int)result;
efc7191b
QY
2564
2565stream_failure:
2566 return -1;
fea12efb 2567}
2568
955bfd98
PZ
2569/*
2570 * Asynchronous label chunk request
2571 *
2572 * @param zclient Zclient used to connect to label manager (zebra)
2573 * @param keep Avoid garbage collection
2574 * @param chunk_size Amount of labels requested
0e3b6a92 2575 * @param base Base for the label chunk. if MPLS_LABEL_BASE_ANY we do not care
955bfd98
PZ
2576 * @result 0 on success, -1 otherwise
2577 */
0313523d 2578int zclient_send_get_label_chunk(struct zclient *zclient, uint8_t keep,
0e3b6a92 2579 uint32_t chunk_size, uint32_t base)
955bfd98
PZ
2580{
2581 struct stream *s;
2582
2583 if (zclient_debug)
2584 zlog_debug("Getting Label Chunk");
2585
2586 if (zclient->sock < 0)
2587 return -1;
2588
2589 s = zclient->obuf;
2590 stream_reset(s);
2591
2592 zclient_create_header(s, ZEBRA_GET_LABEL_CHUNK, VRF_DEFAULT);
5dffb0e9
FR
2593 /* proto */
2594 stream_putc(s, zclient->redist_default);
2595 /* instance */
2596 stream_putw(s, zclient->instance);
955bfd98
PZ
2597 stream_putc(s, keep);
2598 stream_putl(s, chunk_size);
0e3b6a92 2599 stream_putl(s, base);
955bfd98
PZ
2600
2601 /* Put length at the first point of the stream. */
2602 stream_putw_at(s, 0, stream_get_endp(s));
2603
2604 return zclient_send_message(zclient);
2605}
2606
fea12efb 2607/**
2608 * Function to request a label chunk in a syncronous way
2609 *
2610 * It first writes the request to zlcient output buffer and then
2611 * immediately reads the answer from the input buffer.
2612 *
2613 * @param zclient Zclient used to connect to label manager (zebra)
2614 * @param keep Avoid garbage collection
2615 * @param chunk_size Amount of labels requested
2616 * @param start To write first assigned chunk label to
2617 * @param end To write last assigned chunk label to
2618 * @result 0 on success, -1 otherwise
2619 */
0e3b6a92 2620int lm_get_label_chunk(struct zclient *zclient, uint8_t keep, uint32_t base,
d62a17ae 2621 uint32_t chunk_size, uint32_t *start, uint32_t *end)
fea12efb 2622{
d62a17ae 2623 int ret;
2624 struct stream *s;
d7c0a89a 2625 uint8_t response_keep;
d62a17ae 2626
2627 if (zclient_debug)
2628 zlog_debug("Getting Label Chunk");
2629
2630 if (zclient->sock < 0)
2631 return -1;
2632
2633 /* send request */
2634 s = zclient->obuf;
2635 stream_reset(s);
2636 zclient_create_header(s, ZEBRA_GET_LABEL_CHUNK, VRF_DEFAULT);
5dffb0e9
FR
2637 /* proto */
2638 stream_putc(s, zclient->redist_default);
2639 /* instance */
2640 stream_putw(s, zclient->instance);
d62a17ae 2641 /* keep */
2642 stream_putc(s, keep);
2643 /* chunk size */
2644 stream_putl(s, chunk_size);
0e3b6a92
EDP
2645 /* requested chunk base */
2646 stream_putl(s, base);
d62a17ae 2647 /* Put length at the first point of the stream. */
2648 stream_putw_at(s, 0, stream_get_endp(s));
2649
2650 ret = writen(zclient->sock, s->data, stream_get_endp(s));
2651 if (ret < 0) {
1c50c1c0 2652 flog_err(EC_LIB_ZAPI_SOCKET, "Can't write to zclient sock");
d62a17ae 2653 close(zclient->sock);
2654 zclient->sock = -1;
2655 return -1;
2656 }
2657 if (ret == 0) {
1c50c1c0 2658 flog_err(EC_LIB_ZAPI_SOCKET, "Zclient sock closed");
d62a17ae 2659 close(zclient->sock);
2660 zclient->sock = -1;
2661 return -1;
2662 }
2663 if (zclient_debug)
35cbe02a 2664 zlog_debug("Label chunk request (%d bytes) sent", ret);
d62a17ae 2665
2666 /* read response */
2667 if (zclient_read_sync_response(zclient, ZEBRA_GET_LABEL_CHUNK) != 0)
2668 return -1;
2669
5dffb0e9 2670 /* parse response */
d62a17ae 2671 s = zclient->ibuf;
5dffb0e9
FR
2672
2673 /* read proto and instance */
efc7191b
QY
2674 uint8_t proto;
2675 uint8_t instance;
2676
2677 STREAM_GETC(s, proto);
2678 STREAM_GETW(s, instance);
5dffb0e9
FR
2679
2680 /* sanities */
2681 if (proto != zclient->redist_default)
450971aa 2682 flog_err(EC_LIB_ZAPI_ENCODE,
1c50c1c0
QY
2683 "Wrong proto (%u) in get chunk response. Should be %u",
2684 proto, zclient->redist_default);
5dffb0e9 2685 if (instance != zclient->instance)
450971aa 2686 flog_err(EC_LIB_ZAPI_ENCODE,
1c50c1c0
QY
2687 "Wrong instId (%u) in get chunk response Should be %u",
2688 instance, zclient->instance);
5dffb0e9 2689
f004f7c3
EDP
2690 /* if we requested a specific chunk and it could not be allocated, the
2691 * response message will end here
2692 */
2693 if (!STREAM_READABLE(s)) {
2694 zlog_info("Unable to assign Label Chunk to %s instance %u",
2695 zebra_route_string(proto), instance);
2696 return -1;
2697 }
2698
d62a17ae 2699 /* keep */
efc7191b 2700 STREAM_GETC(s, response_keep);
d62a17ae 2701 /* start and end labels */
efc7191b
QY
2702 STREAM_GETL(s, *start);
2703 STREAM_GETL(s, *end);
d62a17ae 2704
2705 /* not owning this response */
2706 if (keep != response_keep) {
1c50c1c0
QY
2707 flog_err(
2708 EC_LIB_ZAPI_ENCODE,
2709 "Invalid Label chunk: %u - %u, keeps mismatch %u != %u",
2710 *start, *end, keep, response_keep);
d62a17ae 2711 }
2712 /* sanity */
70e98a7f
DS
2713 if (*start > *end || *start < MPLS_LABEL_UNRESERVED_MIN
2714 || *end > MPLS_LABEL_UNRESERVED_MAX) {
1c50c1c0
QY
2715 flog_err(EC_LIB_ZAPI_ENCODE, "Invalid Label chunk: %u - %u",
2716 *start, *end);
d62a17ae 2717 return -1;
2718 }
2719
2720 if (zclient_debug)
35cbe02a 2721 zlog_debug("Label Chunk assign: %u - %u (%u)", *start, *end,
d62a17ae 2722 response_keep);
2723
2724 return 0;
efc7191b
QY
2725
2726stream_failure:
2727 return -1;
fea12efb 2728}
2729
2730/**
2731 * Function to release a label chunk
2732 *
2733 * @param zclient Zclient used to connect to label manager (zebra)
2734 * @param start First label of chunk
2735 * @param end Last label of chunk
2736 * @result 0 on success, -1 otherwise
2737 */
d62a17ae 2738int lm_release_label_chunk(struct zclient *zclient, uint32_t start,
2739 uint32_t end)
fea12efb 2740{
d62a17ae 2741 int ret;
2742 struct stream *s;
2743
2744 if (zclient_debug)
35cbe02a 2745 zlog_debug("Releasing Label Chunk %u - %u", start, end);
d62a17ae 2746
2747 if (zclient->sock < 0)
2748 return -1;
2749
2750 /* send request */
2751 s = zclient->obuf;
2752 stream_reset(s);
2753 zclient_create_header(s, ZEBRA_RELEASE_LABEL_CHUNK, VRF_DEFAULT);
2754
5dffb0e9
FR
2755 /* proto */
2756 stream_putc(s, zclient->redist_default);
2757 /* instance */
2758 stream_putw(s, zclient->instance);
d62a17ae 2759 /* start */
2760 stream_putl(s, start);
2761 /* end */
2762 stream_putl(s, end);
2763
2764 /* Put length at the first point of the stream. */
2765 stream_putw_at(s, 0, stream_get_endp(s));
2766
2767 ret = writen(zclient->sock, s->data, stream_get_endp(s));
2768 if (ret < 0) {
450971aa 2769 flog_err(EC_LIB_ZAPI_SOCKET, "Can't write to zclient sock");
d62a17ae 2770 close(zclient->sock);
2771 zclient->sock = -1;
2772 return -1;
2773 }
2774 if (ret == 0) {
1c50c1c0 2775 flog_err(EC_LIB_ZAPI_SOCKET, "Zclient sock connection closed");
d62a17ae 2776 close(zclient->sock);
2777 zclient->sock = -1;
2778 return -1;
2779 }
2780
2781 return 0;
fea12efb 2782}
c8e264b6 2783
75fb51c1
PG
2784/**
2785 * Connect to table manager in a syncronous way
2786 *
2787 * It first writes the request to zcient output buffer and then
2788 * immediately reads the answer from the input buffer.
2789 *
2790 * @param zclient Zclient used to connect to table manager (zebra)
2791 * @result Result of response
2792 */
2793int tm_table_manager_connect(struct zclient *zclient)
2794{
2795 int ret;
2796 struct stream *s;
2797 uint8_t result;
2798
2799 if (zclient_debug)
2800 zlog_debug("Connecting to Table Manager");
2801
2802 if (zclient->sock < 0)
2803 return -1;
2804
2805 /* send request */
2806 s = zclient->obuf;
2807 stream_reset(s);
2808 zclient_create_header(s, ZEBRA_TABLE_MANAGER_CONNECT, VRF_DEFAULT);
2809
2810 /* proto */
2811 stream_putc(s, zclient->redist_default);
2812 /* instance */
2813 stream_putw(s, zclient->instance);
2814
2815 /* Put length at the first point of the stream. */
2816 stream_putw_at(s, 0, stream_get_endp(s));
2817
2818 ret = zclient_send_message(zclient);
2819 if (ret < 0)
2820 return -1;
2821
2822 if (zclient_debug)
0313523d 2823 zlog_debug("%s: Table manager connect request sent", __func__);
75fb51c1
PG
2824
2825 /* read response */
2826 if (zclient_read_sync_response(zclient, ZEBRA_TABLE_MANAGER_CONNECT)
2827 != 0)
2828 return -1;
2829
2830 /* result */
2831 s = zclient->ibuf;
2832 STREAM_GETC(s, result);
2833 if (zclient_debug)
2834 zlog_debug(
2835 "%s: Table Manager connect response received, result %u",
2836 __func__, result);
2837
2838 return (int)result;
2839stream_failure:
6a2b0d9a 2840 return -1;
75fb51c1
PG
2841}
2842
2843/**
2844 * Function to request a table chunk in a syncronous way
2845 *
2846 * It first writes the request to zclient output buffer and then
2847 * immediately reads the answer from the input buffer.
2848 *
2849 * @param zclient Zclient used to connect to table manager (zebra)
2850 * @param chunk_size Amount of table requested
2851 * @param start to write first assigned chunk table RT ID to
2852 * @param end To write last assigned chunk table RT ID to
2853 * @result 0 on success, -1 otherwise
2854 */
2855int tm_get_table_chunk(struct zclient *zclient, uint32_t chunk_size,
2856 uint32_t *start, uint32_t *end)
2857{
2858 int ret;
2859 struct stream *s;
2860
2861 if (zclient_debug)
2862 zlog_debug("Getting Table Chunk");
2863
2864 if (zclient->sock < 0)
2865 return -1;
2866
2867 /* send request */
2868 s = zclient->obuf;
2869 stream_reset(s);
2870 zclient_create_header(s, ZEBRA_GET_TABLE_CHUNK, VRF_DEFAULT);
2871 /* chunk size */
2872 stream_putl(s, chunk_size);
2873 /* Put length at the first point of the stream. */
2874 stream_putw_at(s, 0, stream_get_endp(s));
2875
2876 ret = writen(zclient->sock, s->data, stream_get_endp(s));
2877 if (ret < 0) {
1c50c1c0
QY
2878 flog_err(EC_LIB_ZAPI_SOCKET, "%s: can't write to zclient->sock",
2879 __func__);
75fb51c1
PG
2880 close(zclient->sock);
2881 zclient->sock = -1;
2882 return -1;
2883 }
2884 if (ret == 0) {
450971aa 2885 flog_err(EC_LIB_ZAPI_SOCKET,
1c50c1c0 2886 "%s: zclient->sock connection closed", __func__);
75fb51c1
PG
2887 close(zclient->sock);
2888 zclient->sock = -1;
2889 return -1;
2890 }
2891 if (zclient_debug)
2892 zlog_debug("%s: Table chunk request (%d bytes) sent", __func__,
2893 ret);
2894
2895 /* read response */
2896 if (zclient_read_sync_response(zclient, ZEBRA_GET_TABLE_CHUNK) != 0)
2897 return -1;
2898
2899 s = zclient->ibuf;
2900 /* start and end table IDs */
2901 STREAM_GETL(s, *start);
2902 STREAM_GETL(s, *end);
2903
2904 if (zclient_debug)
2905 zlog_debug("Table Chunk assign: %u - %u ", *start, *end);
2906
75fb51c1 2907 return 0;
6a2b0d9a
RW
2908stream_failure:
2909 return -1;
75fb51c1
PG
2910}
2911
2912/**
2913 * Function to release a table chunk
2914 *
2915 * @param zclient Zclient used to connect to table manager (zebra)
2916 * @param start First label of table
2917 * @param end Last label of chunk
2918 * @result 0 on success, -1 otherwise
2919 */
2920int tm_release_table_chunk(struct zclient *zclient, uint32_t start,
2921 uint32_t end)
2922{
2923 struct stream *s;
2924
2925 if (zclient_debug)
2926 zlog_debug("Releasing Table Chunk");
2927
2928 if (zclient->sock < 0)
2929 return -1;
2930
2931 /* send request */
2932 s = zclient->obuf;
2933 stream_reset(s);
2934 zclient_create_header(s, ZEBRA_RELEASE_TABLE_CHUNK, VRF_DEFAULT);
2935
2936 /* start */
2937 stream_putl(s, start);
2938 /* end */
2939 stream_putl(s, end);
2940
2941 /* Put length at the first point of the stream. */
2942 stream_putw_at(s, 0, stream_get_endp(s));
2943
2944 return zclient_send_message(zclient);
2945}
2946
31f937fb
SM
2947int zebra_send_sr_policy(struct zclient *zclient, int cmd,
2948 struct zapi_sr_policy *zp)
2949{
2950 if (zapi_sr_policy_encode(zclient->obuf, cmd, zp) < 0)
2951 return -1;
2952 return zclient_send_message(zclient);
2953}
2954
2955int zapi_sr_policy_encode(struct stream *s, int cmd, struct zapi_sr_policy *zp)
2956{
2957 struct zapi_srte_tunnel *zt = &zp->segment_list;
2958
2959 stream_reset(s);
2960
2961 zclient_create_header(s, cmd, VRF_DEFAULT);
2962 stream_putl(s, zp->color);
2963 stream_put_ipaddr(s, &zp->endpoint);
2964 stream_write(s, &zp->name, SRTE_POLICY_NAME_MAX_LENGTH);
2965
2966 stream_putc(s, zt->type);
2967 stream_putl(s, zt->local_label);
2968
2969 if (zt->label_num > MPLS_MAX_LABELS) {
2970 flog_err(EC_LIB_ZAPI_ENCODE,
2971 "%s: label %u: can't encode %u labels (maximum is %u)",
2972 __func__, zt->local_label, zt->label_num,
2973 MPLS_MAX_LABELS);
2974 return -1;
2975 }
2976 stream_putw(s, zt->label_num);
2977
2978 for (int i = 0; i < zt->label_num; i++)
2979 stream_putl(s, zt->labels[i]);
2980
2981 /* Put length at the first point of the stream. */
2982 stream_putw_at(s, 0, stream_get_endp(s));
2983
2984 return 0;
2985}
2986
2987int zapi_sr_policy_decode(struct stream *s, struct zapi_sr_policy *zp)
2988{
2989 memset(zp, 0, sizeof(*zp));
2990
2991 struct zapi_srte_tunnel *zt = &zp->segment_list;
2992
2993 STREAM_GETL(s, zp->color);
2994 STREAM_GET_IPADDR(s, &zp->endpoint);
2995 STREAM_GET(&zp->name, s, SRTE_POLICY_NAME_MAX_LENGTH);
2996
2997 /* segment list of active candidate path */
2998 STREAM_GETC(s, zt->type);
2999 STREAM_GETL(s, zt->local_label);
3000 STREAM_GETW(s, zt->label_num);
3001 if (zt->label_num > MPLS_MAX_LABELS) {
3002 flog_err(EC_LIB_ZAPI_ENCODE,
3003 "%s: label %u: can't decode %u labels (maximum is %u)",
3004 __func__, zt->local_label, zt->label_num,
3005 MPLS_MAX_LABELS);
3006 return -1;
3007 }
3008 for (int i = 0; i < zt->label_num; i++)
3009 STREAM_GETL(s, zt->labels[i]);
3010
3011 return 0;
3012
3013stream_failure:
3014 return -1;
3015}
3016
3017int zapi_sr_policy_notify_status_decode(struct stream *s,
3018 struct zapi_sr_policy *zp)
3019{
3020 memset(zp, 0, sizeof(*zp));
3021
3022 STREAM_GETL(s, zp->color);
3023 STREAM_GET_IPADDR(s, &zp->endpoint);
3024 STREAM_GET(&zp->name, s, SRTE_POLICY_NAME_MAX_LENGTH);
3025 STREAM_GETL(s, zp->status);
3026
3027 return 0;
3028
3029stream_failure:
3030 return -1;
3031}
3032
bad6b0e7
RW
3033int zebra_send_mpls_labels(struct zclient *zclient, int cmd,
3034 struct zapi_labels *zl)
3035{
3036 if (zapi_labels_encode(zclient->obuf, cmd, zl) < 0)
3037 return -1;
3038 return zclient_send_message(zclient);
3039}
3040
3041int zapi_labels_encode(struct stream *s, int cmd, struct zapi_labels *zl)
3042{
4945002d 3043 struct zapi_nexthop *znh;
ea6b290b 3044
bad6b0e7
RW
3045 stream_reset(s);
3046
3047 zclient_create_header(s, cmd, VRF_DEFAULT);
b3c49d0e 3048 stream_putc(s, zl->message);
bad6b0e7 3049 stream_putc(s, zl->type);
b3c49d0e
RW
3050 stream_putl(s, zl->local_label);
3051
3052 if (CHECK_FLAG(zl->message, ZAPI_LABELS_FTN)) {
3053 stream_putw(s, zl->route.prefix.family);
3054 stream_put_prefix(s, &zl->route.prefix);
3055 stream_putc(s, zl->route.type);
3056 stream_putw(s, zl->route.instance);
3057 }
3058
ea6b290b
RW
3059 if (zl->nexthop_num > MULTIPATH_NUM) {
3060 flog_err(
3061 EC_LIB_ZAPI_ENCODE,
3062 "%s: label %u: can't encode %u nexthops (maximum is %u)",
3063 __func__, zl->local_label, zl->nexthop_num,
3064 MULTIPATH_NUM);
3065 return -1;
3066 }
3067 stream_putw(s, zl->nexthop_num);
3068
3069 for (int i = 0; i < zl->nexthop_num; i++) {
3070 znh = &zl->nexthops[i];
3071
31f937fb 3072 if (zapi_nexthop_encode(s, znh, 0, 0) < 0)
4945002d 3073 return -1;
bad6b0e7 3074 }
bad6b0e7 3075
34f86754
MS
3076 if (CHECK_FLAG(zl->message, ZAPI_LABELS_HAS_BACKUPS)) {
3077
3078 if (zl->backup_nexthop_num > MULTIPATH_NUM) {
3079 flog_err(
3080 EC_LIB_ZAPI_ENCODE,
3081 "%s: label %u: can't encode %u nexthops (maximum is %u)",
3082 __func__, zl->local_label, zl->nexthop_num,
3083 MULTIPATH_NUM);
3084 return -1;
3085 }
3086 stream_putw(s, zl->backup_nexthop_num);
3087
3088 for (int i = 0; i < zl->backup_nexthop_num; i++) {
3089 znh = &zl->backup_nexthops[i];
3090
31f937fb 3091 if (zapi_nexthop_encode(s, znh, 0, 0) < 0)
34f86754
MS
3092 return -1;
3093 }
3094
3095 }
3096
bad6b0e7
RW
3097 /* Put length at the first point of the stream. */
3098 stream_putw_at(s, 0, stream_get_endp(s));
3099
3100 return 0;
3101}
3102
3103int zapi_labels_decode(struct stream *s, struct zapi_labels *zl)
3104{
4945002d 3105 struct zapi_nexthop *znh;
ea6b290b 3106
bad6b0e7
RW
3107 memset(zl, 0, sizeof(*zl));
3108
3109 /* Get data. */
b3c49d0e 3110 STREAM_GETC(s, zl->message);
bad6b0e7 3111 STREAM_GETC(s, zl->type);
b3c49d0e 3112 STREAM_GETL(s, zl->local_label);
bad6b0e7 3113
b3c49d0e
RW
3114 if (CHECK_FLAG(zl->message, ZAPI_LABELS_FTN)) {
3115 size_t psize;
3116
3117 STREAM_GETW(s, zl->route.prefix.family);
3118 STREAM_GETC(s, zl->route.prefix.prefixlen);
3119
3120 psize = PSIZE(zl->route.prefix.prefixlen);
3121 switch (zl->route.prefix.family) {
3122 case AF_INET:
3123 if (zl->route.prefix.prefixlen > IPV4_MAX_BITLEN) {
3124 zlog_debug(
3125 "%s: Specified prefix length %d is greater than a v4 address can support",
15569c58 3126 __func__, zl->route.prefix.prefixlen);
b3c49d0e
RW
3127 return -1;
3128 }
3129 STREAM_GET(&zl->route.prefix.u.prefix4.s_addr, s,
3130 psize);
3131 break;
3132 case AF_INET6:
3133 if (zl->route.prefix.prefixlen > IPV6_MAX_BITLEN) {
3134 zlog_debug(
3135 "%s: Specified prefix length %d is greater than a v6 address can support",
15569c58 3136 __func__, zl->route.prefix.prefixlen);
b3c49d0e
RW
3137 return -1;
3138 }
3139 STREAM_GET(&zl->route.prefix.u.prefix6, s, psize);
3140 break;
3141 default:
3142 flog_err(EC_LIB_ZAPI_ENCODE,
3143 "%s: Specified family %u is not v4 or v6",
15569c58 3144 __func__, zl->route.prefix.family);
bad6b0e7
RW
3145 return -1;
3146 }
b3c49d0e
RW
3147
3148 STREAM_GETC(s, zl->route.type);
3149 STREAM_GETW(s, zl->route.instance);
3150 }
3151
ea6b290b 3152 STREAM_GETW(s, zl->nexthop_num);
b900b3c6
QY
3153
3154 if (zl->nexthop_num > MULTIPATH_NUM) {
3155 flog_warn(
3156 EC_LIB_ZAPI_ENCODE,
3157 "%s: Prefix %pFX has %d nexthops, but we can only use the first %d",
3158 __func__, &zl->route.prefix, zl->nexthop_num,
3159 MULTIPATH_NUM);
3160 }
3161
3162 zl->nexthop_num = MIN(MULTIPATH_NUM, zl->nexthop_num);
3163
ea6b290b
RW
3164 for (int i = 0; i < zl->nexthop_num; i++) {
3165 znh = &zl->nexthops[i];
3166
31f937fb 3167 if (zapi_nexthop_decode(s, znh, 0, 0) < 0)
4945002d 3168 return -1;
bad6b0e7 3169 }
bad6b0e7 3170
34f86754
MS
3171 if (CHECK_FLAG(zl->message, ZAPI_LABELS_HAS_BACKUPS)) {
3172 STREAM_GETW(s, zl->backup_nexthop_num);
3173
3174 if (zl->backup_nexthop_num > MULTIPATH_NUM) {
3175 flog_warn(
3176 EC_LIB_ZAPI_ENCODE,
3177 "%s: Prefix %pFX has %d backup nexthops, but we can only use the first %d",
3178 __func__, &zl->route.prefix,
3179 zl->backup_nexthop_num, MULTIPATH_NUM);
3180 }
3181
3182 zl->backup_nexthop_num = MIN(MULTIPATH_NUM,
3183 zl->backup_nexthop_num);
3184
3185 for (int i = 0; i < zl->backup_nexthop_num; i++) {
3186 znh = &zl->backup_nexthops[i];
3187
31f937fb 3188 if (zapi_nexthop_decode(s, znh, 0, 0) < 0)
34f86754
MS
3189 return -1;
3190 }
3191 }
3192
bad6b0e7
RW
3193 return 0;
3194stream_failure:
3195 return -1;
3196}
75fb51c1 3197
6833ae01 3198int zebra_send_pw(struct zclient *zclient, int command, struct zapi_pw *pw)
3199{
3200 struct stream *s;
3201
3202 /* Reset stream. */
3203 s = zclient->obuf;
3204 stream_reset(s);
3205
3206 zclient_create_header(s, command, VRF_DEFAULT);
3207 stream_write(s, pw->ifname, IF_NAMESIZE);
3208 stream_putl(s, pw->ifindex);
3209
3210 /* Put type */
3211 stream_putl(s, pw->type);
3212
3213 /* Put nexthop */
3214 stream_putl(s, pw->af);
3215 switch (pw->af) {
3216 case AF_INET:
3217 stream_put_in_addr(s, &pw->nexthop.ipv4);
3218 break;
3219 case AF_INET6:
d7c0a89a 3220 stream_write(s, (uint8_t *)&pw->nexthop.ipv6, 16);
6833ae01 3221 break;
3222 default:
1c50c1c0 3223 flog_err(EC_LIB_ZAPI_ENCODE, "%s: unknown af", __func__);
6833ae01 3224 return -1;
3225 }
3226
3227 /* Put labels */
3228 stream_putl(s, pw->local_label);
3229 stream_putl(s, pw->remote_label);
3230
3231 /* Put flags */
3232 stream_putc(s, pw->flags);
3233
3234 /* Protocol specific fields */
3235 stream_write(s, &pw->data, sizeof(union pw_protocol_fields));
3236
3237 /* Put length at the first point of the stream. */
3238 stream_putw_at(s, 0, stream_get_endp(s));
3239
3240 return zclient_send_message(zclient);
3241}
3242
3243/*
3244 * Receive PW status update from Zebra and send it to LDE process.
3245 */
efc7191b 3246int zebra_read_pw_status_update(ZAPI_CALLBACK_ARGS, struct zapi_pw_status *pw)
6833ae01 3247{
3248 struct stream *s;
3249
3250 memset(pw, 0, sizeof(struct zapi_pw_status));
3251 s = zclient->ibuf;
3252
3253 /* Get data. */
3254 stream_get(pw->ifname, s, IF_NAMESIZE);
efc7191b
QY
3255 STREAM_GETL(s, pw->ifindex);
3256 STREAM_GETL(s, pw->status);
3257
3258 return 0;
3259stream_failure:
3260 return -1;
6833ae01 3261}
3262
121f9dee 3263static void zclient_capability_decode(ZAPI_CALLBACK_ARGS)
09924cff
DS
3264{
3265 struct zclient_capabilities cap;
3266 struct stream *s = zclient->ibuf;
bb6b7f79 3267 int vrf_backend;
09924cff
DS
3268 uint8_t mpls_enabled;
3269
bb6b7f79 3270 STREAM_GETL(s, vrf_backend);
7239d3d9
QY
3271
3272 if (vrf_backend < 0 || vrf_configure_backend(vrf_backend)) {
3273 flog_err(EC_LIB_ZAPI_ENCODE,
3274 "%s: Garbage VRF backend type: %d\n", __func__,
3275 vrf_backend);
3276 goto stream_failure;
3277 }
3278
bb6b7f79 3279
09924cff
DS
3280 memset(&cap, 0, sizeof(cap));
3281 STREAM_GETC(s, mpls_enabled);
3282 cap.mpls_enabled = !!mpls_enabled;
3283 STREAM_GETL(s, cap.ecmp);
02c0866d 3284 STREAM_GETC(s, cap.role);
09924cff
DS
3285
3286 if (zclient->zebra_capabilities)
3287 (*zclient->zebra_capabilities)(&cap);
3288
3289stream_failure:
3290 return;
3291}
3292
36b5b98f
SK
3293void zclient_send_mlag_register(struct zclient *client, uint32_t bit_map)
3294{
3295 struct stream *s;
3296
3297 s = client->obuf;
3298 stream_reset(s);
3299
3300 zclient_create_header(s, ZEBRA_MLAG_CLIENT_REGISTER, VRF_DEFAULT);
3301 stream_putl(s, bit_map);
3302
3303 stream_putw_at(s, 0, stream_get_endp(s));
3304 zclient_send_message(client);
3305}
3306
3307void zclient_send_mlag_deregister(struct zclient *client)
3308{
3309 zebra_message_send(client, ZEBRA_MLAG_CLIENT_UNREGISTER, VRF_DEFAULT);
3310}
3311
3312void zclient_send_mlag_data(struct zclient *client, struct stream *client_s)
3313{
3314 struct stream *s;
3315
3316 s = client->obuf;
3317 stream_reset(s);
3318
3319 zclient_create_header(s, ZEBRA_MLAG_FORWARD_MSG, VRF_DEFAULT);
3320 stream_put(s, client_s->data, client_s->endp);
3321
3322 stream_putw_at(s, 0, stream_get_endp(s));
3323 zclient_send_message(client);
3324}
3325
46c2687c
SK
3326static void zclient_mlag_process_up(ZAPI_CALLBACK_ARGS)
3327{
3328 if (zclient->mlag_process_up)
3329 (*zclient->mlag_process_up)();
3330}
3331
3332static void zclient_mlag_process_down(ZAPI_CALLBACK_ARGS)
3333{
3334 if (zclient->mlag_process_down)
3335 (*zclient->mlag_process_down)();
3336}
3337
3338static void zclient_mlag_handle_msg(ZAPI_CALLBACK_ARGS)
3339{
3340 if (zclient->mlag_handle_msg)
3341 (*zclient->mlag_handle_msg)(zclient->ibuf, length);
3342}
3343
ff491140
MS
3344/*
3345 * Send an OPAQUE message, contents opaque to zebra. The message header
3346 * is a message subtype.
3347 */
3348int zclient_send_opaque(struct zclient *zclient, uint32_t type,
3349 const uint8_t *data, size_t datasize)
3350{
3351 int ret;
3352 struct stream *s;
387831ff 3353 uint16_t flags = 0;
ff491140
MS
3354
3355 /* Check buffer size */
3356 if (STREAM_SIZE(zclient->obuf) <
3357 (ZEBRA_HEADER_SIZE + sizeof(type) + datasize))
3358 return -1;
3359
3360 s = zclient->obuf;
3361 stream_reset(s);
3362
3363 zclient_create_header(s, ZEBRA_OPAQUE_MESSAGE, VRF_DEFAULT);
3364
387831ff 3365 /* Send sub-type and flags */
ff491140 3366 stream_putl(s, type);
387831ff 3367 stream_putw(s, flags);
ff491140
MS
3368
3369 /* Send opaque data */
3370 stream_write(s, data, datasize);
3371
3372 /* Put length into the header at the start of the stream. */
3373 stream_putw_at(s, 0, stream_get_endp(s));
3374
3375 ret = zclient_send_message(zclient);
3376
3377 return ret;
3378}
3379
387831ff
MS
3380/*
3381 * Send an OPAQUE message to a specific zclient. The contents are opaque
3382 * to zebra.
3383 */
3384int zclient_send_opaque_unicast(struct zclient *zclient, uint32_t type,
3385 uint8_t proto, uint16_t instance,
3386 uint32_t session_id, const uint8_t *data,
3387 size_t datasize)
3388{
3389 int ret;
3390 struct stream *s;
3391 uint16_t flags = 0;
3392
3393 /* Check buffer size */
3394 if (STREAM_SIZE(zclient->obuf) <
3395 (ZEBRA_HEADER_SIZE + sizeof(struct zapi_opaque_msg) + datasize))
3396 return -1;
3397
3398 s = zclient->obuf;
3399 stream_reset(s);
3400
3401 zclient_create_header(s, ZEBRA_OPAQUE_MESSAGE, VRF_DEFAULT);
3402
3403 /* Send sub-type and flags */
3404 SET_FLAG(flags, ZAPI_OPAQUE_FLAG_UNICAST);
3405 stream_putl(s, type);
3406 stream_putw(s, flags);
3407
3408 /* Send destination client info */
3409 stream_putc(s, proto);
3410 stream_putw(s, instance);
3411 stream_putl(s, session_id);
3412
3413 /* Send opaque data */
3414 stream_write(s, data, datasize);
3415
3416 /* Put length into the header at the start of the stream. */
3417 stream_putw_at(s, 0, stream_get_endp(s));
3418
3419 ret = zclient_send_message(zclient);
3420
3421 return ret;
3422}
3423
3424/*
3425 * Decode incoming opaque message into info struct
3426 */
3427int zclient_opaque_decode(struct stream *s, struct zapi_opaque_msg *info)
3428{
3429 memset(info, 0, sizeof(*info));
3430
3431 /* Decode subtype and flags */
3432 STREAM_GETL(s, info->type);
3433 STREAM_GETW(s, info->flags);
3434
3435 /* Decode unicast client info if present */
3436 if (CHECK_FLAG(info->flags, ZAPI_OPAQUE_FLAG_UNICAST)) {
3437 STREAM_GETC(s, info->proto);
3438 STREAM_GETW(s, info->instance);
3439 STREAM_GETL(s, info->session_id);
3440 }
3441
3442 info->len = STREAM_READABLE(s);
3443
3444 return 0;
3445
3446stream_failure:
3447
3448 return -1;
3449}
3450
ff491140
MS
3451/*
3452 * Send a registration request for opaque messages with a specified subtype.
3453 */
3454int zclient_register_opaque(struct zclient *zclient, uint32_t type)
3455{
3456 int ret;
3457 struct stream *s;
3458
3459 s = zclient->obuf;
3460 stream_reset(s);
3461
3462 zclient_create_header(s, ZEBRA_OPAQUE_REGISTER, VRF_DEFAULT);
3463
3464 /* Send sub-type */
3465 stream_putl(s, type);
3466
3467 /* Add zclient info */
3468 stream_putc(s, zclient->redist_default);
3469 stream_putw(s, zclient->instance);
3470 stream_putl(s, zclient->session_id);
3471
3472 /* Put length at the first point of the stream. */
3473 stream_putw_at(s, 0, stream_get_endp(s));
3474
3475 ret = zclient_send_message(zclient);
3476
3477 return ret;
3478}
3479
3480/*
3481 * Send an un-registration request for a specified opaque subtype.
3482 */
3483int zclient_unregister_opaque(struct zclient *zclient, uint32_t type)
3484{
3485 int ret;
3486 struct stream *s;
3487
3488 s = zclient->obuf;
3489 stream_reset(s);
3490
3491 zclient_create_header(s, ZEBRA_OPAQUE_UNREGISTER, VRF_DEFAULT);
3492
3493 /* Send sub-type */
3494 stream_putl(s, type);
3495
3496 /* Add zclient info */
3497 stream_putc(s, zclient->redist_default);
3498 stream_putw(s, zclient->instance);
3499 stream_putl(s, zclient->session_id);
3500
3501 /* Put length at the first point of the stream. */
3502 stream_putw_at(s, 0, stream_get_endp(s));
3503
3504 ret = zclient_send_message(zclient);
3505
3506 return ret;
3507}
3508
d2ddc141 3509/* Utility to decode opaque registration info */
387831ff 3510int zapi_opaque_reg_decode(struct stream *s, struct zapi_opaque_reg_info *info)
ff491140
MS
3511{
3512 STREAM_GETL(s, info->type);
3513 STREAM_GETC(s, info->proto);
3514 STREAM_GETW(s, info->instance);
3515 STREAM_GETL(s, info->session_id);
3516
3517 return 0;
3518
3519stream_failure:
3520
3521 return -1;
3522}
3523
718e3744 3524/* Zebra client message read function. */
d62a17ae 3525static int zclient_read(struct thread *thread)
718e3744 3526{
d62a17ae 3527 size_t already;
3528 uint16_t length, command;
3529 uint8_t marker, version;
3530 vrf_id_t vrf_id;
3531 struct zclient *zclient;
3532
3533 /* Get socket to zebra. */
3534 zclient = THREAD_ARG(thread);
3535 zclient->t_read = NULL;
3536
3537 /* Read zebra header (if we don't have it already). */
3538 if ((already = stream_get_endp(zclient->ibuf)) < ZEBRA_HEADER_SIZE) {
3539 ssize_t nbyte;
3540 if (((nbyte = stream_read_try(zclient->ibuf, zclient->sock,
3541 ZEBRA_HEADER_SIZE - already))
3542 == 0)
3543 || (nbyte == -1)) {
3544 if (zclient_debug)
3545 zlog_debug(
3546 "zclient connection closed socket [%d].",
3547 zclient->sock);
3548 return zclient_failed(zclient);
3549 }
3550 if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE - already)) {
3551 /* Try again later. */
3552 zclient_event(ZCLIENT_READ, zclient);
3553 return 0;
3554 }
3555 already = ZEBRA_HEADER_SIZE;
634f9ea2 3556 }
d62a17ae 3557
3558 /* Reset to read from the beginning of the incoming packet. */
3559 stream_set_getp(zclient->ibuf, 0);
3560
3561 /* Fetch header values. */
3562 length = stream_getw(zclient->ibuf);
3563 marker = stream_getc(zclient->ibuf);
3564 version = stream_getc(zclient->ibuf);
a9ff90c4 3565 vrf_id = stream_getl(zclient->ibuf);
d62a17ae 3566 command = stream_getw(zclient->ibuf);
3567
3568 if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION) {
1c50c1c0
QY
3569 flog_err(
3570 EC_LIB_ZAPI_MISSMATCH,
3571 "%s: socket %d version mismatch, marker %d, version %d",
3572 __func__, zclient->sock, marker, version);
d62a17ae 3573 return zclient_failed(zclient);
634f9ea2 3574 }
d62a17ae 3575
3576 if (length < ZEBRA_HEADER_SIZE) {
450971aa 3577 flog_err(EC_LIB_ZAPI_MISSMATCH,
1c50c1c0
QY
3578 "%s: socket %d message length %u is less than %d ",
3579 __func__, zclient->sock, length, ZEBRA_HEADER_SIZE);
d62a17ae 3580 return zclient_failed(zclient);
634f9ea2 3581 }
d62a17ae 3582
3583 /* Length check. */
3584 if (length > STREAM_SIZE(zclient->ibuf)) {
3585 struct stream *ns;
ade6974d 3586 flog_err(
450971aa 3587 EC_LIB_ZAPI_ENCODE,
ade6974d
QY
3588 "%s: message size %u exceeds buffer size %lu, expanding...",
3589 __func__, length,
3590 (unsigned long)STREAM_SIZE(zclient->ibuf));
d62a17ae 3591 ns = stream_new(length);
3592 stream_copy(ns, zclient->ibuf);
3593 stream_free(zclient->ibuf);
3594 zclient->ibuf = ns;
3595 }
3596
3597 /* Read rest of zebra packet. */
3598 if (already < length) {
3599 ssize_t nbyte;
3600 if (((nbyte = stream_read_try(zclient->ibuf, zclient->sock,
3601 length - already))
3602 == 0)
3603 || (nbyte == -1)) {
3604 if (zclient_debug)
3605 zlog_debug(
3606 "zclient connection closed socket [%d].",
3607 zclient->sock);
3608 return zclient_failed(zclient);
3609 }
3610 if (nbyte != (ssize_t)(length - already)) {
3611 /* Try again later. */
3612 zclient_event(ZCLIENT_READ, zclient);
3613 return 0;
3614 }
3615 }
3616
3617 length -= ZEBRA_HEADER_SIZE;
3618
3619 if (zclient_debug)
cdc6ed90
DS
3620 zlog_debug("zclient 0x%p command %s VRF %u",
3621 (void *)zclient, zserv_command_string(command),
3622 vrf_id);
d62a17ae 3623
3624 switch (command) {
09924cff
DS
3625 case ZEBRA_CAPABILITIES:
3626 zclient_capability_decode(command, zclient, length, vrf_id);
3627 break;
d62a17ae 3628 case ZEBRA_ROUTER_ID_UPDATE:
3629 if (zclient->router_id_update)
3630 (*zclient->router_id_update)(command, zclient, length,
3631 vrf_id);
3632 break;
3633 case ZEBRA_VRF_ADD:
3634 zclient_vrf_add(zclient, vrf_id);
3635 break;
3636 case ZEBRA_VRF_DELETE:
3637 zclient_vrf_delete(zclient, vrf_id);
3638 break;
3639 case ZEBRA_INTERFACE_ADD:
ef7bd2a3 3640 zclient_interface_add(zclient, vrf_id);
d62a17ae 3641 break;
3642 case ZEBRA_INTERFACE_DELETE:
3c3c3252 3643 zclient_interface_delete(zclient, vrf_id);
d62a17ae 3644 break;
3645 case ZEBRA_INTERFACE_ADDRESS_ADD:
3646 if (zclient->interface_address_add)
3647 (*zclient->interface_address_add)(command, zclient,
3648 length, vrf_id);
3649 break;
3650 case ZEBRA_INTERFACE_ADDRESS_DELETE:
3651 if (zclient->interface_address_delete)
3652 (*zclient->interface_address_delete)(command, zclient,
3653 length, vrf_id);
3654 break;
3655 case ZEBRA_INTERFACE_BFD_DEST_UPDATE:
3656 if (zclient->interface_bfd_dest_update)
3657 (*zclient->interface_bfd_dest_update)(command, zclient,
3658 length, vrf_id);
3659 break;
3660 case ZEBRA_INTERFACE_NBR_ADDRESS_ADD:
3661 if (zclient->interface_nbr_address_add)
3662 (*zclient->interface_nbr_address_add)(command, zclient,
3663 length, vrf_id);
3664 break;
3665 case ZEBRA_INTERFACE_NBR_ADDRESS_DELETE:
3666 if (zclient->interface_nbr_address_delete)
3667 (*zclient->interface_nbr_address_delete)(
3668 command, zclient, length, vrf_id);
3669 break;
3670 case ZEBRA_INTERFACE_UP:
ddbf3e60 3671 zclient_interface_up(zclient, vrf_id);
d62a17ae 3672 break;
3673 case ZEBRA_INTERFACE_DOWN:
b0b69e59 3674 zclient_interface_down(zclient, vrf_id);
d62a17ae 3675 break;
3676 case ZEBRA_INTERFACE_VRF_UPDATE:
3677 if (zclient->interface_vrf_update)
3678 (*zclient->interface_vrf_update)(command, zclient,
3679 length, vrf_id);
3680 break;
3681 case ZEBRA_NEXTHOP_UPDATE:
3682 if (zclient_debug)
9165c5f5 3683 zlog_debug("zclient rcvd nexthop update");
d62a17ae 3684 if (zclient->nexthop_update)
3685 (*zclient->nexthop_update)(command, zclient, length,
3686 vrf_id);
3687 break;
3688 case ZEBRA_IMPORT_CHECK_UPDATE:
3689 if (zclient_debug)
9165c5f5 3690 zlog_debug("zclient rcvd import check update");
d62a17ae 3691 if (zclient->import_check_update)
3692 (*zclient->import_check_update)(command, zclient,
3693 length, vrf_id);
3694 break;
3695 case ZEBRA_BFD_DEST_REPLAY:
3696 if (zclient->bfd_dest_replay)
3697 (*zclient->bfd_dest_replay)(command, zclient, length,
3698 vrf_id);
3699 break;
74489921
RW
3700 case ZEBRA_REDISTRIBUTE_ROUTE_ADD:
3701 if (zclient->redistribute_route_add)
3702 (*zclient->redistribute_route_add)(command, zclient,
3703 length, vrf_id);
d62a17ae 3704 break;
74489921
RW
3705 case ZEBRA_REDISTRIBUTE_ROUTE_DEL:
3706 if (zclient->redistribute_route_del)
3707 (*zclient->redistribute_route_del)(command, zclient,
3708 length, vrf_id);
d62a17ae 3709 break;
3710 case ZEBRA_INTERFACE_LINK_PARAMS:
3711 if (zclient->interface_link_params)
3712 (*zclient->interface_link_params)(command, zclient,
edc12762 3713 length, vrf_id);
d62a17ae 3714 break;
3715 case ZEBRA_FEC_UPDATE:
3716 if (zclient_debug)
9165c5f5 3717 zlog_debug("zclient rcvd fec update");
d62a17ae 3718 if (zclient->fec_update)
3719 (*zclient->fec_update)(command, zclient, length);
3720 break;
50f74cf1 3721 case ZEBRA_LOCAL_ES_ADD:
3722 if (zclient->local_es_add)
3723 (*zclient->local_es_add)(command, zclient, length,
3724 vrf_id);
3725 break;
3726 case ZEBRA_LOCAL_ES_DEL:
3727 if (zclient->local_es_del)
3728 (*zclient->local_es_del)(command, zclient, length,
3729 vrf_id);
3730 break;
ce5160c0
AK
3731 case ZEBRA_LOCAL_ES_EVI_ADD:
3732 if (zclient->local_es_evi_add)
3733 (*zclient->local_es_evi_add)(command, zclient, length,
3734 vrf_id);
3735 break;
3736 case ZEBRA_LOCAL_ES_EVI_DEL:
3737 if (zclient->local_es_evi_del)
3738 (*zclient->local_es_evi_del)(command, zclient, length,
3739 vrf_id);
3740 break;
d62a17ae 3741 case ZEBRA_VNI_ADD:
3742 if (zclient->local_vni_add)
3743 (*zclient->local_vni_add)(command, zclient, length,
3744 vrf_id);
3745 break;
3746 case ZEBRA_VNI_DEL:
3747 if (zclient->local_vni_del)
3748 (*zclient->local_vni_del)(command, zclient, length,
3749 vrf_id);
3750 break;
b7cfce93
MK
3751 case ZEBRA_L3VNI_ADD:
3752 if (zclient->local_l3vni_add)
3753 (*zclient->local_l3vni_add)(command, zclient, length,
3754 vrf_id);
3755 break;
3756 case ZEBRA_L3VNI_DEL:
3757 if (zclient->local_l3vni_del)
3758 (*zclient->local_l3vni_del)(command, zclient, length,
3759 vrf_id);
3760 break;
d62a17ae 3761 case ZEBRA_MACIP_ADD:
3762 if (zclient->local_macip_add)
3763 (*zclient->local_macip_add)(command, zclient, length,
3764 vrf_id);
3765 break;
3766 case ZEBRA_MACIP_DEL:
3767 if (zclient->local_macip_del)
3768 (*zclient->local_macip_del)(command, zclient, length,
3769 vrf_id);
3770 break;
31310b25
MK
3771 case ZEBRA_IP_PREFIX_ROUTE_ADD:
3772 if (zclient->local_ip_prefix_add)
3773 (*zclient->local_ip_prefix_add)(command, zclient,
3774 length, vrf_id);
3775 break;
3776 case ZEBRA_IP_PREFIX_ROUTE_DEL:
3777 if (zclient->local_ip_prefix_del)
3778 (*zclient->local_ip_prefix_del)(command, zclient,
3779 length, vrf_id);
3780 break;
6833ae01 3781 case ZEBRA_PW_STATUS_UPDATE:
3782 if (zclient->pw_status_update)
3783 (*zclient->pw_status_update)(command, zclient, length,
3784 vrf_id);
3785 break;
7ea7b86e 3786 case ZEBRA_ROUTE_NOTIFY_OWNER:
28b11f81
DS
3787 if (zclient->route_notify_owner)
3788 (*zclient->route_notify_owner)(command, zclient, length,
3789 vrf_id);
7ea7b86e 3790 break;
b6c5d343
DS
3791 case ZEBRA_RULE_NOTIFY_OWNER:
3792 if (zclient->rule_notify_owner)
3793 (*zclient->rule_notify_owner)(command, zclient, length,
3794 vrf_id);
955bfd98 3795 break;
2f35a820
DS
3796 case ZEBRA_NHG_NOTIFY_OWNER:
3797 if (zclient->nhg_notify_owner)
3798 (*zclient->nhg_notify_owner)(command, zclient, length,
3799 vrf_id);
3800 break;
955bfd98
PZ
3801 case ZEBRA_GET_LABEL_CHUNK:
3802 if (zclient->label_chunk)
3803 (*zclient->label_chunk)(command, zclient, length,
0313523d 3804 vrf_id);
955bfd98 3805 break;
c16a0a62
PG
3806 case ZEBRA_IPSET_NOTIFY_OWNER:
3807 if (zclient->ipset_notify_owner)
3808 (*zclient->ipset_notify_owner)(command, zclient, length,
3809 vrf_id);
3810 break;
3811 case ZEBRA_IPSET_ENTRY_NOTIFY_OWNER:
3812 if (zclient->ipset_entry_notify_owner)
3813 (*zclient->ipset_entry_notify_owner)(command,
3814 zclient, length,
3815 vrf_id);
3816 break;
3817 case ZEBRA_IPTABLE_NOTIFY_OWNER:
3818 if (zclient->iptable_notify_owner)
3819 (*zclient->iptable_notify_owner)(command,
3820 zclient, length,
3821 vrf_id);
4ab3321f
AK
3822 break;
3823 case ZEBRA_VXLAN_SG_ADD:
3824 if (zclient->vxlan_sg_add)
3825 (*zclient->vxlan_sg_add)(command, zclient, length,
3826 vrf_id);
3827 break;
3828 case ZEBRA_VXLAN_SG_DEL:
3829 if (zclient->vxlan_sg_del)
3830 (*zclient->vxlan_sg_del)(command, zclient, length,
3831 vrf_id);
3832 break;
46c2687c
SK
3833 case ZEBRA_MLAG_PROCESS_UP:
3834 zclient_mlag_process_up(command, zclient, length, vrf_id);
3835 break;
3836 case ZEBRA_MLAG_PROCESS_DOWN:
3837 zclient_mlag_process_down(command, zclient, length, vrf_id);
3838 break;
3839 case ZEBRA_MLAG_FORWARD_MSG:
3840 zclient_mlag_handle_msg(command, zclient, length, vrf_id);
3841 break;
9ab0b2a3
SW
3842 case ZEBRA_ERROR:
3843 zclient_handle_error(command, zclient, length, vrf_id);
ff491140
MS
3844 break;
3845 case ZEBRA_OPAQUE_MESSAGE:
3846 if (zclient->opaque_msg_handler)
3847 (*zclient->opaque_msg_handler)(command, zclient, length,
3848 vrf_id);
3849 break;
3850 case ZEBRA_OPAQUE_REGISTER:
3851 if (zclient->opaque_register_handler)
3852 (*zclient->opaque_register_handler)(command, zclient,
3853 length, vrf_id);
3854 break;
3855 case ZEBRA_OPAQUE_UNREGISTER:
3856 if (zclient->opaque_unregister_handler)
3857 (*zclient->opaque_unregister_handler)(command, zclient,
3858 length, vrf_id);
3859 break;
31f937fb
SM
3860 case ZEBRA_SR_POLICY_NOTIFY_STATUS:
3861 if (zclient->sr_policy_notify_status)
3862 (*zclient->sr_policy_notify_status)(command, zclient,
3863 length, vrf_id);
d62a17ae 3864 default:
3865 break;
634f9ea2 3866 }
d62a17ae 3867
3868 if (zclient->sock < 0)
3869 /* Connection was closed during packet processing. */
3870 return -1;
3871
3872 /* Register read thread. */
3873 stream_reset(zclient->ibuf);
3874 zclient_event(ZCLIENT_READ, zclient);
3875
3876 return 0;
718e3744 3877}
3878
d62a17ae 3879void zclient_redistribute(int command, struct zclient *zclient, afi_t afi,
d7c0a89a 3880 int type, unsigned short instance, vrf_id_t vrf_id)
718e3744 3881{
718e3744 3882
d62a17ae 3883 if (instance) {
3884 if (command == ZEBRA_REDISTRIBUTE_ADD) {
3885 if (redist_check_instance(
3886 &zclient->mi_redist[afi][type], instance))
3887 return;
3888 redist_add_instance(&zclient->mi_redist[afi][type],
3889 instance);
3890 } else {
3891 if (!redist_check_instance(
3892 &zclient->mi_redist[afi][type], instance))
3893 return;
3894 redist_del_instance(&zclient->mi_redist[afi][type],
3895 instance);
3896 }
3897
3898 } else {
3899 if (command == ZEBRA_REDISTRIBUTE_ADD) {
3900 if (vrf_bitmap_check(zclient->redist[afi][type],
3901 vrf_id))
3902 return;
3903 vrf_bitmap_set(zclient->redist[afi][type], vrf_id);
3904 } else {
3905 if (!vrf_bitmap_check(zclient->redist[afi][type],
3906 vrf_id))
3907 return;
3908 vrf_bitmap_unset(zclient->redist[afi][type], vrf_id);
3909 }
3910 }
3911
3912 if (zclient->sock > 0)
3913 zebra_redistribute_send(command, zclient, afi, type, instance,
3914 vrf_id);
718e3744 3915}
3916
718e3744 3917
d62a17ae 3918void zclient_redistribute_default(int command, struct zclient *zclient,
49db7a7b 3919 afi_t afi, vrf_id_t vrf_id)
718e3744 3920{
718e3744 3921
d62a17ae 3922 if (command == ZEBRA_REDISTRIBUTE_DEFAULT_ADD) {
49db7a7b 3923 if (vrf_bitmap_check(zclient->default_information[afi], vrf_id))
d62a17ae 3924 return;
49db7a7b 3925 vrf_bitmap_set(zclient->default_information[afi], vrf_id);
d62a17ae 3926 } else {
49db7a7b
RW
3927 if (!vrf_bitmap_check(zclient->default_information[afi],
3928 vrf_id))
d62a17ae 3929 return;
49db7a7b 3930 vrf_bitmap_unset(zclient->default_information[afi], vrf_id);
d62a17ae 3931 }
3932
3933 if (zclient->sock > 0)
49db7a7b 3934 zebra_redistribute_default_send(command, zclient, afi, vrf_id);
718e3744 3935}
3936
d62a17ae 3937static void zclient_event(enum event event, struct zclient *zclient)
718e3744 3938{
d62a17ae 3939 switch (event) {
3940 case ZCLIENT_SCHEDULE:
3941 thread_add_event(zclient->master, zclient_connect, zclient, 0,
3942 &zclient->t_connect);
3943 break;
3944 case ZCLIENT_CONNECT:
3945 if (zclient_debug)
3946 zlog_debug(
3947 "zclient connect failures: %d schedule interval is now %d",
3948 zclient->fail, zclient->fail < 3 ? 10 : 60);
3949 thread_add_timer(zclient->master, zclient_connect, zclient,
3950 zclient->fail < 3 ? 10 : 60,
3951 &zclient->t_connect);
3952 break;
3953 case ZCLIENT_READ:
3954 zclient->t_read = NULL;
3955 thread_add_read(zclient->master, zclient_read, zclient,
3956 zclient->sock, &zclient->t_read);
3957 break;
3958 }
718e3744 3959}
b5114685 3960
e0ae31b8
DS
3961void zclient_interface_set_master(struct zclient *client,
3962 struct interface *master,
3963 struct interface *slave)
3964{
3965 struct stream *s;
3966
3967 s = client->obuf;
3968 stream_reset(s);
3969
a36898e7 3970 zclient_create_header(s, ZEBRA_INTERFACE_SET_MASTER, master->vrf_id);
e0ae31b8 3971
a36898e7 3972 stream_putl(s, master->vrf_id);
e0ae31b8 3973 stream_putl(s, master->ifindex);
a36898e7 3974 stream_putl(s, slave->vrf_id);
e0ae31b8
DS
3975 stream_putl(s, slave->ifindex);
3976
3977 stream_putw_at(s, 0, stream_get_endp(s));
3978 zclient_send_message(client);
3979}
eb451ee5 3980
be7bbe52
S
3981/*
3982 * Send capabilities message to zebra
3983 */
3984int32_t zclient_capabilities_send(uint32_t cmd, struct zclient *zclient,
3985 struct zapi_cap *api)
eb451ee5 3986{
be7bbe52
S
3987
3988 struct stream *s;
3989
3990 if (zclient == NULL)
3991 return -1;
3992
3993 s = zclient->obuf;
3994 stream_reset(s);
3995 zclient_create_header(s, cmd, 0);
3996 stream_putl(s, api->cap);
3997
3998 switch (api->cap) {
3999 case ZEBRA_CLIENT_GR_CAPABILITIES:
4000 case ZEBRA_CLIENT_RIB_STALE_TIME:
4001 stream_putl(s, api->stale_removal_time);
4002 stream_putl(s, api->vrf_id);
4003 break;
4004 case ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE:
4005 case ZEBRA_CLIENT_ROUTE_UPDATE_PENDING:
4006 stream_putl(s, api->afi);
4007 stream_putl(s, api->safi);
4008 stream_putl(s, api->vrf_id);
4009 break;
4010 case ZEBRA_CLIENT_GR_DISABLE:
4011 stream_putl(s, api->vrf_id);
4012 break;
4013 }
4014
4015 /* Put length at the first point of the stream */
4016 stream_putw_at(s, 0, stream_get_endp(s));
4017
4018 return zclient_send_message(zclient);
4019}
4020
4021/*
4022 * Process capabilities message from zebra
4023 */
4024int32_t zapi_capabilities_decode(struct stream *s, struct zapi_cap *api)
4025{
4026
eb451ee5 4027 memset(api, 0, sizeof(*api));
4028
4029 STREAM_GETL(s, api->cap);
4030 switch (api->cap) {
4031 case ZEBRA_CLIENT_GR_CAPABILITIES:
4032 case ZEBRA_CLIENT_RIB_STALE_TIME:
be7bbe52
S
4033 STREAM_GETL(s, api->stale_removal_time);
4034 STREAM_GETL(s, api->vrf_id);
4035 break;
eb451ee5 4036 case ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE:
4037 case ZEBRA_CLIENT_ROUTE_UPDATE_PENDING:
be7bbe52
S
4038 STREAM_GETL(s, api->afi);
4039 STREAM_GETL(s, api->safi);
4040 STREAM_GETL(s, api->vrf_id);
4041 break;
eb451ee5 4042 case ZEBRA_CLIENT_GR_DISABLE:
be7bbe52
S
4043 STREAM_GETL(s, api->vrf_id);
4044 break;
eb451ee5 4045 }
4046stream_failure:
4047 return 0;
4048}
d68e74b4
JU
4049
4050int zclient_send_neigh_discovery_req(struct zclient *zclient,
4051 const struct interface *ifp,
4052 const struct prefix *p)
4053{
4054 struct stream *s;
4055
4056 s = zclient->obuf;
4057 stream_reset(s);
4058
4059 zclient_create_header(s, ZEBRA_NEIGH_DISCOVER, ifp->vrf_id);
4060 stream_putl(s, ifp->ifindex);
4061
4062 stream_putc(s, p->family);
4063 stream_putc(s, p->prefixlen);
4064 stream_put(s, &p->u.prefix, prefix_blen(p));
4065
4066 stream_putw_at(s, 0, stream_get_endp(s));
4067 return zclient_send_message(zclient);
4068}
224b3c8a
DS
4069
4070/*
4071 * Get a starting nhg point for a routing protocol
4072 */
4073uint32_t zclient_get_nhg_start(uint32_t proto)
4074{
4075 assert(proto < ZEBRA_ROUTE_MAX);
4076
54c89c93 4077 return ZEBRA_NHG_PROTO_SPACING * proto;
6c67f41f 4078}