]> git.proxmox.com Git - mirror_frr.git/blame - lib/zclient.c
zebra: Fix label manager memory leak (#5680)
[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"
6b0655a2 42
4a1ab8e4 43DEFINE_MTYPE_STATIC(LIB, ZCLIENT, "Zclient")
14878121 44DEFINE_MTYPE_STATIC(LIB, REDIST_INST, "Redistribution instance IDs")
4a1ab8e4 45
718e3744 46/* Zebra client events. */
d62a17ae 47enum event { ZCLIENT_SCHEDULE, ZCLIENT_READ, ZCLIENT_CONNECT };
718e3744 48
49/* Prototype for event manager. */
d62a17ae 50static void zclient_event(enum event, struct zclient *);
718e3744 51
26f8f6fe
DS
52static void zebra_interface_if_set_value(struct stream *s,
53 struct interface *ifp);
54
c17faa4b
QY
55struct zclient_options zclient_options_default = {.receive_notify = false};
56
689f5a8c
DL
57struct sockaddr_storage zclient_addr;
58socklen_t zclient_addr_len;
b5114685 59
718e3744 60/* This file local debug flag. */
c17faa4b 61static int zclient_debug;
e1a1880d 62
718e3744 63/* Allocate zclient structure. */
26f63a1e
DS
64struct zclient *zclient_new(struct thread_master *master,
65 struct zclient_options *opt)
718e3744 66{
d62a17ae 67 struct zclient *zclient;
f3f45626
DS
68 size_t stream_size =
69 MAX(ZEBRA_MAX_PACKET_SIZ, sizeof(struct zapi_route));
70
d62a17ae 71 zclient = XCALLOC(MTYPE_ZCLIENT, sizeof(struct zclient));
718e3744 72
f3f45626
DS
73 zclient->ibuf = stream_new(stream_size);
74 zclient->obuf = stream_new(stream_size);
d62a17ae 75 zclient->wb = buffer_new(0);
76 zclient->master = master;
718e3744 77
e1a1880d
DS
78 zclient->receive_notify = opt->receive_notify;
79
d62a17ae 80 return zclient;
718e3744 81}
82
228da428 83/* This function is only called when exiting, because
634f9ea2 84 many parts of the code do not check for I/O errors, so they could
85 reference an invalid pointer if the structure was ever freed.
634f9ea2 86
228da428 87 Free zclient structure. */
d62a17ae 88void zclient_free(struct zclient *zclient)
718e3744 89{
d62a17ae 90 if (zclient->ibuf)
91 stream_free(zclient->ibuf);
92 if (zclient->obuf)
93 stream_free(zclient->obuf);
94 if (zclient->wb)
95 buffer_free(zclient->wb);
96
97 XFREE(MTYPE_ZCLIENT, zclient);
718e3744 98}
99
d7c0a89a
QY
100unsigned short *redist_check_instance(struct redist_proto *red,
101 unsigned short instance)
7c8ff89e 102{
d62a17ae 103 struct listnode *node;
d7c0a89a 104 unsigned short *id;
7c8ff89e 105
d62a17ae 106 if (!red->instances)
107 return NULL;
7c8ff89e 108
d62a17ae 109 for (ALL_LIST_ELEMENTS_RO(red->instances, node, id))
110 if (*id == instance)
111 return id;
7c8ff89e 112
d62a17ae 113 return NULL;
7c8ff89e
DS
114}
115
d7c0a89a 116void redist_add_instance(struct redist_proto *red, unsigned short instance)
7c8ff89e 117{
d7c0a89a 118 unsigned short *in;
7c8ff89e 119
d62a17ae 120 red->enabled = 1;
7c8ff89e 121
d62a17ae 122 if (!red->instances)
123 red->instances = list_new();
7c8ff89e 124
d7c0a89a 125 in = XMALLOC(MTYPE_REDIST_INST, sizeof(unsigned short));
d62a17ae 126 *in = instance;
127 listnode_add(red->instances, in);
7c8ff89e
DS
128}
129
d7c0a89a 130void redist_del_instance(struct redist_proto *red, unsigned short instance)
7c8ff89e 131{
d7c0a89a 132 unsigned short *id;
d62a17ae 133
134 id = redist_check_instance(red, instance);
135 if (!id)
136 return;
137
138 listnode_delete(red->instances, id);
139 XFREE(MTYPE_REDIST_INST, id);
140 if (!red->instances->count) {
141 red->enabled = 0;
6a154c88 142 list_delete(&red->instances);
d62a17ae 143 }
7c8ff89e
DS
144}
145
24c370dd
QY
146void redist_del_all_instances(struct redist_proto *red)
147{
148 struct listnode *ln, *nn;
149 unsigned short *id;
150
151 if (!red->instances)
152 return;
153
154 for (ALL_LIST_ELEMENTS(red->instances, ln, nn, id))
155 redist_del_instance(red, *id);
156}
157
718e3744 158/* Stop zebra client services. */
d62a17ae 159void zclient_stop(struct zclient *zclient)
718e3744 160{
d62a17ae 161 afi_t afi;
162 int i;
163
164 if (zclient_debug)
165 zlog_debug("zclient stopped");
166
167 /* Stop threads. */
168 THREAD_OFF(zclient->t_read);
169 THREAD_OFF(zclient->t_connect);
170 THREAD_OFF(zclient->t_write);
171
172 /* Reset streams. */
173 stream_reset(zclient->ibuf);
174 stream_reset(zclient->obuf);
175
176 /* Empty the write buffer. */
177 buffer_reset(zclient->wb);
178
179 /* Close socket. */
180 if (zclient->sock >= 0) {
181 close(zclient->sock);
182 zclient->sock = -1;
183 }
184 zclient->fail = 0;
185
186 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
187 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
188 vrf_bitmap_free(zclient->redist[afi][i]);
189 zclient->redist[afi][i] = VRF_BITMAP_NULL;
190 }
191 redist_del_instance(
192 &zclient->mi_redist[afi][zclient->redist_default],
193 zclient->instance);
41246cb6 194
49db7a7b
RW
195 vrf_bitmap_free(zclient->default_information[afi]);
196 zclient->default_information[afi] = VRF_BITMAP_NULL;
197 }
718e3744 198}
199
d62a17ae 200void zclient_reset(struct zclient *zclient)
718e3744 201{
d62a17ae 202 afi_t afi;
3d68677e 203
d62a17ae 204 zclient_stop(zclient);
3d68677e 205
d62a17ae 206 for (afi = AFI_IP; afi < AFI_MAX; afi++)
207 redist_del_instance(
208 &zclient->mi_redist[afi][zclient->redist_default],
209 zclient->instance);
3d68677e 210
996c9314
LB
211 zclient_init(zclient, zclient->redist_default, zclient->instance,
212 zclient->privs);
718e3744 213}
214
689f5a8c
DL
215/**
216 * Connect to zebra daemon.
217 * @param zclient a pointer to zclient structure
218 * @return socket fd just to make sure that connection established
219 * @see zclient_init
26f63a1e 220 * @see zclient_new
689f5a8c
DL
221 */
222int zclient_socket_connect(struct zclient *zclient)
718e3744 223{
d62a17ae 224 int sock;
225 int ret;
d62a17ae 226
227 /* We should think about IPv6 connection. */
689f5a8c 228 sock = socket(zclient_addr.ss_family, SOCK_STREAM, 0);
d62a17ae 229 if (sock < 0)
230 return -1;
231
689f5a8c 232 set_cloexec(sock);
338b8e91 233 setsockopt_so_sendbuf(sock, 1048576);
342213ea 234
d62a17ae 235 /* Connect to zebra. */
996c9314 236 ret = connect(sock, (struct sockaddr *)&zclient_addr, zclient_addr_len);
d62a17ae 237 if (ret < 0) {
238 if (zclient_debug)
decbd929
DS
239 zlog_debug("%s connect failure: %d(%s)",
240 __PRETTY_FUNCTION__, errno,
241 safe_strerror(errno));
d62a17ae 242 close(sock);
243 return -1;
244 }
718e3744 245
689f5a8c 246 zclient->sock = sock;
d62a17ae 247 return sock;
718e3744 248}
249
d62a17ae 250static int zclient_failed(struct zclient *zclient)
634f9ea2 251{
d62a17ae 252 zclient->fail++;
253 zclient_stop(zclient);
254 zclient_event(ZCLIENT_CONNECT, zclient);
255 return -1;
634f9ea2 256}
257
d62a17ae 258static int zclient_flush_data(struct thread *thread)
634f9ea2 259{
d62a17ae 260 struct zclient *zclient = THREAD_ARG(thread);
261
262 zclient->t_write = NULL;
263 if (zclient->sock < 0)
264 return -1;
265 switch (buffer_flush_available(zclient->wb, zclient->sock)) {
266 case BUFFER_ERROR:
ade6974d 267 flog_err(
450971aa 268 EC_LIB_ZAPI_SOCKET,
ade6974d
QY
269 "%s: buffer_flush_available failed on zclient fd %d, closing",
270 __func__, zclient->sock);
d62a17ae 271 return zclient_failed(zclient);
272 break;
273 case BUFFER_PENDING:
274 zclient->t_write = NULL;
275 thread_add_write(zclient->master, zclient_flush_data, zclient,
276 zclient->sock, &zclient->t_write);
277 break;
278 case BUFFER_EMPTY:
279 break;
280 }
281 return 0;
634f9ea2 282}
283
d62a17ae 284int zclient_send_message(struct zclient *zclient)
634f9ea2 285{
d62a17ae 286 if (zclient->sock < 0)
287 return -1;
288 switch (buffer_write(zclient->wb, zclient->sock,
289 STREAM_DATA(zclient->obuf),
290 stream_get_endp(zclient->obuf))) {
291 case BUFFER_ERROR:
450971aa 292 flog_err(EC_LIB_ZAPI_SOCKET,
decbd929
DS
293 "%s: buffer_write failed to zclient fd %d, closing",
294 __func__, zclient->sock);
d62a17ae 295 return zclient_failed(zclient);
296 break;
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
d62a17ae 380static int zebra_hello_send(struct zclient *zclient)
2ea1ab1c 381{
d62a17ae 382 struct stream *s;
383
384 if (zclient->redist_default) {
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);
e1a1880d
DS
392 if (zclient->receive_notify)
393 stream_putc(s, 1);
394 else
395 stream_putc(s, 0);
396
d62a17ae 397 stream_putw_at(s, 0, stream_get_endp(s));
398 return zclient_send_message(zclient);
399 }
400
401 return 0;
2ea1ab1c
VT
402}
403
7d061b3c 404void zclient_send_vrf_label(struct zclient *zclient, vrf_id_t vrf_id, afi_t afi,
339e36d2 405 mpls_label_t label, enum lsp_types_t ltype)
c83c5e44
DS
406{
407 struct stream *s;
408
409 s = zclient->obuf;
410 stream_reset(s);
411
412 zclient_create_header(s, ZEBRA_VRF_LABEL, vrf_id);
413 stream_putl(s, label);
7d061b3c 414 stream_putc(s, afi);
339e36d2 415 stream_putc(s, ltype);
c83c5e44
DS
416 stream_putw_at(s, 0, stream_get_endp(s));
417 zclient_send_message(zclient);
418}
419
0e5223e7 420/* Send register requests to zebra daemon for the information in a VRF. */
d62a17ae 421void zclient_send_reg_requests(struct zclient *zclient, vrf_id_t vrf_id)
7076bb2f 422{
d62a17ae 423 int i;
424 afi_t afi;
425
d62a17ae 426 /* If not connected to the zebra yet. */
427 if (zclient->sock < 0)
428 return;
429
430 if (zclient_debug)
431 zlog_debug("%s: send register messages for VRF %u", __func__,
432 vrf_id);
433
434 /* We need router-id information. */
435 zebra_message_send(zclient, ZEBRA_ROUTER_ID_ADD, vrf_id);
436
eeb2dfa3
DS
437 /* We need interface information. */
438 zebra_message_send(zclient, ZEBRA_INTERFACE_ADD, vrf_id);
439
d62a17ae 440 /* Set unwanted redistribute route. */
441 for (afi = AFI_IP; afi < AFI_MAX; afi++)
442 vrf_bitmap_set(zclient->redist[afi][zclient->redist_default],
443 vrf_id);
444
445 /* Flush all redistribute request. */
0d9e7f45
DS
446 if (vrf_id == VRF_DEFAULT) {
447 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
448 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
449 if (!zclient->mi_redist[afi][i].enabled)
450 continue;
451
452 struct listnode *node;
d7c0a89a 453 unsigned short *id;
0d9e7f45
DS
454
455 for (ALL_LIST_ELEMENTS_RO(
456 zclient->mi_redist[afi][i]
996c9314
LB
457 .instances,
458 node, id))
0d9e7f45
DS
459 if (!(i == zclient->redist_default
460 && *id == zclient->instance))
461 zebra_redistribute_send(
462 ZEBRA_REDISTRIBUTE_ADD,
996c9314 463 zclient, afi, i, *id,
0d9e7f45
DS
464 VRF_DEFAULT);
465 }
466 }
467 }
d62a17ae 468
70172b1c 469 /* Resend all redistribute request. */
49db7a7b 470 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
d62a17ae 471 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
472 if (i != zclient->redist_default
473 && vrf_bitmap_check(zclient->redist[afi][i],
474 vrf_id))
475 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD,
476 zclient, afi, i, 0,
477 vrf_id);
478
49db7a7b 479 /* If default information is needed. */
d7637898 480 if (vrf_bitmap_check(zclient->default_information[afi], vrf_id))
49db7a7b
RW
481 zebra_redistribute_default_send(
482 ZEBRA_REDISTRIBUTE_DEFAULT_ADD, zclient, afi,
483 vrf_id);
484 }
7076bb2f
FL
485}
486
0e5223e7 487/* Send unregister requests to zebra daemon for the information in a VRF. */
d62a17ae 488void zclient_send_dereg_requests(struct zclient *zclient, vrf_id_t vrf_id)
0e5223e7 489{
d62a17ae 490 int i;
491 afi_t afi;
492
d62a17ae 493 /* If not connected to the zebra yet. */
494 if (zclient->sock < 0)
495 return;
496
497 if (zclient_debug)
498 zlog_debug("%s: send deregister messages for VRF %u", __func__,
499 vrf_id);
500
501 /* We need router-id information. */
502 zebra_message_send(zclient, ZEBRA_ROUTER_ID_DELETE, vrf_id);
503
eeb2dfa3 504 zebra_message_send(zclient, ZEBRA_INTERFACE_DELETE, vrf_id);
d62a17ae 505
d62a17ae 506 /* Set unwanted redistribute route. */
507 for (afi = AFI_IP; afi < AFI_MAX; afi++)
09eef679
DS
508 vrf_bitmap_unset(zclient->redist[afi][zclient->redist_default],
509 vrf_id);
d62a17ae 510
511 /* Flush all redistribute request. */
0d9e7f45
DS
512 if (vrf_id == VRF_DEFAULT) {
513 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
514 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
515 if (!zclient->mi_redist[afi][i].enabled)
516 continue;
517
518 struct listnode *node;
d7c0a89a 519 unsigned short *id;
0d9e7f45
DS
520
521 for (ALL_LIST_ELEMENTS_RO(
522 zclient->mi_redist[afi][i]
996c9314
LB
523 .instances,
524 node, id))
0d9e7f45
DS
525 if (!(i == zclient->redist_default
526 && *id == zclient->instance))
527 zebra_redistribute_send(
528 ZEBRA_REDISTRIBUTE_DELETE,
996c9314 529 zclient, afi, i, *id,
0d9e7f45
DS
530 VRF_DEFAULT);
531 }
532 }
533 }
d62a17ae 534
535 /* Flush all redistribute request. */
49db7a7b 536 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
d62a17ae 537 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
538 if (i != zclient->redist_default
539 && vrf_bitmap_check(zclient->redist[afi][i],
540 vrf_id))
541 zebra_redistribute_send(
542 ZEBRA_REDISTRIBUTE_DELETE, zclient, afi,
543 i, 0, vrf_id);
544
49db7a7b 545 /* If default information is needed. */
d7637898 546 if (vrf_bitmap_check(zclient->default_information[afi], vrf_id))
49db7a7b
RW
547 zebra_redistribute_default_send(
548 ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, zclient, afi,
549 vrf_id);
550 }
0e5223e7 551}
552
4a04e5f7 553/* Send request to zebra daemon to start or stop RA. */
d62a17ae 554void zclient_send_interface_radv_req(struct zclient *zclient, vrf_id_t vrf_id,
555 struct interface *ifp, int enable,
556 int ra_interval)
4a04e5f7 557{
d62a17ae 558 struct stream *s;
4a04e5f7 559
d62a17ae 560 /* If not connected to the zebra yet. */
561 if (zclient->sock < 0)
562 return;
4a04e5f7 563
d62a17ae 564 /* Form and send message. */
565 s = zclient->obuf;
566 stream_reset(s);
4a04e5f7 567
d62a17ae 568 if (enable)
569 zclient_create_header(s, ZEBRA_INTERFACE_ENABLE_RADV, vrf_id);
570 else
571 zclient_create_header(s, ZEBRA_INTERFACE_DISABLE_RADV, vrf_id);
4a04e5f7 572
d62a17ae 573 stream_putl(s, ifp->ifindex);
574 stream_putl(s, ra_interval);
4a04e5f7 575
d62a17ae 576 stream_putw_at(s, 0, stream_get_endp(s));
4a04e5f7 577
d62a17ae 578 zclient_send_message(zclient);
4a04e5f7 579}
580
c3bd894e
QY
581int zclient_send_interface_protodown(struct zclient *zclient, vrf_id_t vrf_id,
582 struct interface *ifp, bool down)
583{
584 struct stream *s;
585
586 if (zclient->sock < 0)
587 return -1;
588
589 s = zclient->obuf;
590 stream_reset(s);
591 zclient_create_header(s, ZEBRA_INTERFACE_SET_PROTODOWN, vrf_id);
592 stream_putl(s, ifp->ifindex);
593 stream_putc(s, !!down);
594 stream_putw_at(s, 0, stream_get_endp(s));
595 zclient_send_message(zclient);
596
597 return 0;
598}
599
718e3744 600/* Make connection to zebra daemon. */
d62a17ae 601int zclient_start(struct zclient *zclient)
718e3744 602{
d62a17ae 603 if (zclient_debug)
604 zlog_info("zclient_start is called");
605
d62a17ae 606 /* If already connected to the zebra. */
607 if (zclient->sock >= 0)
608 return 0;
609
610 /* Check connect thread. */
611 if (zclient->t_connect)
612 return 0;
613
614 if (zclient_socket_connect(zclient) < 0) {
615 if (zclient_debug)
616 zlog_debug("zclient connection fail");
617 zclient->fail++;
618 zclient_event(ZCLIENT_CONNECT, zclient);
619 return -1;
620 }
718e3744 621
d62a17ae 622 if (set_nonblocking(zclient->sock) < 0)
450971aa 623 flog_err(EC_LIB_ZAPI_SOCKET, "%s: set_nonblocking(%d) failed",
ade6974d 624 __func__, zclient->sock);
718e3744 625
d62a17ae 626 /* Clear fail count. */
627 zclient->fail = 0;
628 if (zclient_debug)
629 zlog_debug("zclient connect success with socket [%d]",
630 zclient->sock);
718e3744 631
d62a17ae 632 /* Create read thread. */
633 zclient_event(ZCLIENT_READ, zclient);
718e3744 634
d62a17ae 635 zebra_hello_send(zclient);
718e3744 636
22761baa
DS
637 zebra_message_send(zclient, ZEBRA_INTERFACE_ADD, VRF_DEFAULT);
638
d62a17ae 639 /* Inform the successful connection. */
640 if (zclient->zebra_connected)
641 (*zclient->zebra_connected)(zclient);
718e3744 642
d62a17ae 643 return 0;
718e3744 644}
6b0655a2 645
078430f6
DS
646/* Initialize zebra client. Argument redist_default is unwanted
647 redistribute route type. */
d7c0a89a
QY
648void zclient_init(struct zclient *zclient, int redist_default,
649 unsigned short instance, struct zebra_privs_t *privs)
078430f6 650{
d62a17ae 651 int afi, i;
652
d62a17ae 653 /* Set -1 to the default socket value. */
654 zclient->sock = -1;
342213ea 655 zclient->privs = privs;
d62a17ae 656
657 /* Clear redistribution flags. */
658 for (afi = AFI_IP; afi < AFI_MAX; afi++)
659 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
660 zclient->redist[afi][i] = vrf_bitmap_init();
661
662 /* Set unwanted redistribute route. bgpd does not need BGP route
663 redistribution. */
664 zclient->redist_default = redist_default;
665 zclient->instance = instance;
666 /* Pending: make afi(s) an arg. */
49db7a7b 667 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
d62a17ae 668 redist_add_instance(&zclient->mi_redist[afi][redist_default],
669 instance);
670
49db7a7b
RW
671 /* Set default-information redistribute to zero. */
672 zclient->default_information[afi] = vrf_bitmap_init();
673 }
d62a17ae 674
675 if (zclient_debug)
cdc6ed90 676 zlog_debug("scheduling zclient connection");
d62a17ae 677
678 zclient_event(ZCLIENT_SCHEDULE, zclient);
7076bb2f 679}
078430f6 680
7076bb2f
FL
681/* This function is a wrapper function for calling zclient_start from
682 timer or event thread. */
d62a17ae 683static int zclient_connect(struct thread *t)
7076bb2f 684{
d62a17ae 685 struct zclient *zclient;
078430f6 686
d62a17ae 687 zclient = THREAD_ARG(t);
688 zclient->t_connect = NULL;
078430f6 689
d62a17ae 690 if (zclient_debug)
691 zlog_debug("zclient_connect is called");
078430f6 692
d62a17ae 693 return zclient_start(zclient);
078430f6
DS
694}
695
3c192540
DS
696int zclient_send_rnh(struct zclient *zclient, int command, struct prefix *p,
697 bool exact_match, vrf_id_t vrf_id)
698{
699 struct stream *s;
700
701 s = zclient->obuf;
702 stream_reset(s);
703 zclient_create_header(s, command, vrf_id);
704 stream_putc(s, (exact_match) ? 1 : 0);
705
706 stream_putw(s, PREFIX_FAMILY(p));
707 stream_putc(s, p->prefixlen);
708 switch (PREFIX_FAMILY(p)) {
709 case AF_INET:
710 stream_put_in_addr(s, &p->u.prefix4);
711 break;
712 case AF_INET6:
713 stream_put(s, &(p->u.prefix6), 16);
714 break;
715 default:
716 break;
717 }
718 stream_putw_at(s, 0, stream_get_endp(s));
719
720 return zclient_send_message(zclient);
721}
722
d62a17ae 723/*
724 * "xdr_encode"-like interface that allows daemon (client) to send
725 * a message to zebra server for a route that needs to be
726 * added/deleted to the kernel. Info about the route is specified
04772760 727 * by the caller in a struct zapi_route. zapi_route_encode() then writes
d62a17ae 728 * the info down the zclient socket using the stream_* functions.
729 *
730 * The corresponding read ("xdr_decode") function on the server
04772760 731 * side is zapi_route_decode().
d62a17ae 732 *
733 * 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
734 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
735 * | Length (2) | Command | Route Type |
736 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
737 * | ZEBRA Flags | Message Flags | Prefix length |
738 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
739 * | Destination IPv4 Prefix for route |
740 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
741 * | Nexthop count |
742 * +-+-+-+-+-+-+-+-+
743 *
744 *
745 * A number of IPv4 nexthop(s) or nexthop interface index(es) are then
746 * described, as per the Nexthop count. Each nexthop described as:
747 *
748 * +-+-+-+-+-+-+-+-+
749 * | Nexthop Type | Set to one of ZEBRA_NEXTHOP_*
750 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
751 * | IPv4 Nexthop address or Interface Index number |
752 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
753 *
09a484dd
DL
754 * Alternatively, if the route is a blackhole route, then Nexthop count
755 * is set to 1 and a nexthop of type NEXTHOP_TYPE_BLACKHOLE is the sole
756 * nexthop.
d62a17ae 757 *
04772760
DS
758 * The original struct zapi_route_*() infrastructure was built around
759 * the traditional (32-bit "gate OR ifindex") nexthop data unit.
760 * A special encoding can be used to feed onlink (64-bit "gate AND ifindex")
761 * nexthops into zapi_route_encode() using the same zapi_route structure.
762 * This is done by setting zapi_route fields as follows:
d62a17ae 763 * - .message |= ZAPI_MESSAGE_NEXTHOP | ZAPI_MESSAGE_ONLINK
764 * - .nexthop_num == .ifindex_num
765 * - .nexthop and .ifindex are filled with gate and ifindex parts of
766 * each compound nexthop, both in the same order
767 *
d62a17ae 768 * If ZAPI_MESSAGE_DISTANCE is set, the distance value is written as a 1
769 * byte value.
770 *
771 * If ZAPI_MESSAGE_METRIC is set, the metric value is written as an 8
772 * byte value.
773 *
774 * If ZAPI_MESSAGE_TAG is set, the tag value is written as a 4 byte value
775 *
776 * If ZAPI_MESSAGE_MTU is set, the mtu value is written as a 4 byte value
777 *
778 * XXX: No attention paid to alignment.
779 */
d7c0a89a 780int zclient_route_send(uint8_t cmd, struct zclient *zclient,
0e51b4a3 781 struct zapi_route *api)
657cde12 782{
0e51b4a3
RW
783 if (zapi_route_encode(cmd, zclient->obuf, api) < 0)
784 return -1;
785 return zclient_send_message(zclient);
786}
787
3c6e0bd4
SW
788static int zapi_nexthop_labels_cmp(const struct zapi_nexthop *next1,
789 const struct zapi_nexthop *next2)
790{
791 if (next1->label_num > next2->label_num)
792 return 1;
793
794 if (next1->label_num < next2->label_num)
795 return -1;
796
797 return memcmp(next1->labels, next2->labels, next1->label_num);
798}
799
800static int zapi_nexthop_cmp_no_labels(const struct zapi_nexthop *next1,
801 const struct zapi_nexthop *next2)
802{
803 int ret = 0;
804
805 if (next1->vrf_id < next2->vrf_id)
806 return -1;
807
808 if (next1->vrf_id > next2->vrf_id)
809 return 1;
810
811 if (next1->type < next2->type)
812 return -1;
813
814 if (next1->type > next2->type)
815 return 1;
816
bd054c1a
DS
817 if (next1->weight < next2->weight)
818 return -1;
819
820 if (next1->weight > next2->weight)
821 return 1;
822
3c6e0bd4
SW
823 switch (next1->type) {
824 case NEXTHOP_TYPE_IPV4:
825 case NEXTHOP_TYPE_IPV6:
826 ret = nexthop_g_addr_cmp(next1->type, &next1->gate,
827 &next2->gate);
828 if (ret != 0)
829 return ret;
830 break;
831 case NEXTHOP_TYPE_IPV4_IFINDEX:
832 case NEXTHOP_TYPE_IPV6_IFINDEX:
833 ret = nexthop_g_addr_cmp(next1->type, &next1->gate,
834 &next2->gate);
835 if (ret != 0)
836 return ret;
837 /* Intentional Fall-Through */
838 case NEXTHOP_TYPE_IFINDEX:
839 if (next1->ifindex < next2->ifindex)
840 return -1;
841
842 if (next1->ifindex > next2->ifindex)
843 return 1;
844 break;
845 case NEXTHOP_TYPE_BLACKHOLE:
846 if (next1->bh_type < next2->bh_type)
847 return -1;
848
849 if (next1->bh_type > next2->bh_type)
850 return 1;
851 break;
852 }
853
854 return 0;
855}
856
857static int zapi_nexthop_cmp(const void *item1, const void *item2)
858{
859 int ret = 0;
860
861 const struct zapi_nexthop *next1 = item1;
862 const struct zapi_nexthop *next2 = item2;
863
864 ret = zapi_nexthop_cmp_no_labels(next1, next2);
865 if (ret != 0)
866 return ret;
867
868 ret = zapi_nexthop_labels_cmp(next1, next2);
869
870 return ret;
871}
872
873static void zapi_nexthop_group_sort(struct zapi_nexthop *nh_grp,
874 uint16_t nexthop_num)
875{
876 qsort(nh_grp, nexthop_num, sizeof(struct zapi_nexthop),
877 &zapi_nexthop_cmp);
878}
879
68a02e06
MS
880/*
881 * Encode a single zapi nexthop
882 */
883int zapi_nexthop_encode(struct stream *s, const struct zapi_nexthop *api_nh,
884 uint32_t api_flags)
885{
886 int ret = 0;
887 int nh_flags = api_nh->flags;
888
889 stream_putl(s, api_nh->vrf_id);
890 stream_putc(s, api_nh->type);
891
892 /* If needed, set 'labelled nexthop' flag */
893 if (api_nh->label_num > 0) {
894 SET_FLAG(nh_flags, ZAPI_NEXTHOP_FLAG_LABEL);
895
896 /* Validate label count */
897 if (api_nh->label_num > MPLS_MAX_LABELS) {
898 ret = -1;
899 goto done;
900 }
901 }
902
bd054c1a
DS
903 if (api_nh->weight)
904 SET_FLAG(nh_flags, ZAPI_NEXTHOP_FLAG_WEIGHT);
905
68a02e06
MS
906 /* Note that we're only encoding a single octet */
907 stream_putc(s, nh_flags);
908
909 switch (api_nh->type) {
910 case NEXTHOP_TYPE_BLACKHOLE:
911 stream_putc(s, api_nh->bh_type);
912 break;
913 case NEXTHOP_TYPE_IPV4:
914 stream_put_in_addr(s, &api_nh->gate.ipv4);
915 break;
916 case NEXTHOP_TYPE_IPV4_IFINDEX:
917 stream_put_in_addr(s, &api_nh->gate.ipv4);
918 stream_putl(s, api_nh->ifindex);
919 break;
920 case NEXTHOP_TYPE_IFINDEX:
921 stream_putl(s, api_nh->ifindex);
922 break;
923 case NEXTHOP_TYPE_IPV6:
924 stream_write(s, (uint8_t *)&api_nh->gate.ipv6,
925 16);
926 break;
927 case NEXTHOP_TYPE_IPV6_IFINDEX:
928 stream_write(s, (uint8_t *)&api_nh->gate.ipv6,
929 16);
930 stream_putl(s, api_nh->ifindex);
931 break;
932 }
933
934 /* We only encode labels if we have >0 - we use
935 * the per-nexthop flag above to signal that the count
936 * is present in the payload.
937 */
938 if (api_nh->label_num > 0) {
939 stream_putc(s, api_nh->label_num);
940 stream_put(s, &api_nh->labels[0],
941 api_nh->label_num * sizeof(mpls_label_t));
942 }
943
bd054c1a
DS
944 if (api_nh->weight)
945 stream_putl(s, api_nh->weight);
946
68a02e06
MS
947 /* Router MAC for EVPN routes. */
948 if (CHECK_FLAG(api_flags, ZEBRA_FLAG_EVPN_ROUTE))
949 stream_put(s, &(api_nh->rmac),
950 sizeof(struct ethaddr));
951
952done:
953 return ret;
954}
955
d7c0a89a 956int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api)
0e51b4a3
RW
957{
958 struct zapi_nexthop *api_nh;
d62a17ae 959 int i;
960 int psize;
d62a17ae 961
d62a17ae 962 stream_reset(s);
d62a17ae 963 zclient_create_header(s, cmd, api->vrf_id);
964
e4081c0e
RW
965 if (api->type >= ZEBRA_ROUTE_MAX) {
966 flog_err(EC_LIB_ZAPI_ENCODE,
967 "%s: Specified route type (%u) is not a legal value\n",
968 __PRETTY_FUNCTION__, api->type);
969 return -1;
970 }
d62a17ae 971 stream_putc(s, api->type);
e4081c0e 972
d62a17ae 973 stream_putw(s, api->instance);
974 stream_putl(s, api->flags);
975 stream_putc(s, api->message);
e4081c0e
RW
976
977 if (api->safi < SAFI_UNICAST || api->safi >= SAFI_MAX) {
978 flog_err(EC_LIB_ZAPI_ENCODE,
979 "%s: Specified route SAFI (%u) is not a legal value\n",
980 __PRETTY_FUNCTION__, api->safi);
981 return -1;
982 }
832d0f56 983 stream_putc(s, api->safi);
d62a17ae 984
985 /* Put prefix information. */
0e51b4a3 986 stream_putc(s, api->prefix.family);
bb1b9c47
RW
987 psize = PSIZE(api->prefix.prefixlen);
988 stream_putc(s, api->prefix.prefixlen);
d7c0a89a 989 stream_write(s, (uint8_t *)&api->prefix.u.prefix, psize);
d62a17ae 990
991 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_SRCPFX)) {
bb1b9c47
RW
992 psize = PSIZE(api->src_prefix.prefixlen);
993 stream_putc(s, api->src_prefix.prefixlen);
d7c0a89a 994 stream_write(s, (uint8_t *)&api->src_prefix.prefix, psize);
d62a17ae 995 }
996
0e51b4a3 997 /* Nexthops. */
d62a17ae 998 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) {
bb1b9c47
RW
999 /* limit the number of nexthops if necessary */
1000 if (api->nexthop_num > MULTIPATH_NUM) {
1001 char buf[PREFIX2STR_BUFFER];
1002
1003 prefix2str(&api->prefix, buf, sizeof(buf));
ade6974d 1004 flog_err(
450971aa 1005 EC_LIB_ZAPI_ENCODE,
ade6974d
QY
1006 "%s: prefix %s: can't encode %u nexthops (maximum is %u)",
1007 __func__, buf, api->nexthop_num, MULTIPATH_NUM);
a74e593b 1008 return -1;
bb1b9c47
RW
1009 }
1010
3c6e0bd4
SW
1011 zapi_nexthop_group_sort(api->nexthops, api->nexthop_num);
1012
b5f79651 1013 stream_putw(s, api->nexthop_num);
d62a17ae 1014
1015 for (i = 0; i < api->nexthop_num; i++) {
bb1b9c47
RW
1016 api_nh = &api->nexthops[i];
1017
52dd3aa4 1018 /* MPLS labels for BGP-LU or Segment Routing */
68a02e06
MS
1019 if (api_nh->label_num > MPLS_MAX_LABELS) {
1020 char buf[PREFIX2STR_BUFFER];
1021
1022 prefix2str(&api->prefix, buf, sizeof(buf));
1023
1024 flog_err(EC_LIB_ZAPI_ENCODE,
1025 "%s: prefix %s: can't encode %u labels (maximum is %u)",
1026 __func__, buf,
1027 api_nh->label_num,
1028 MPLS_MAX_LABELS);
1029 return -1;
52dd3aa4 1030 }
a317a9b9 1031
68a02e06
MS
1032 if (zapi_nexthop_encode(s, api_nh, api->flags) != 0)
1033 return -1;
d62a17ae 1034 }
1035 }
1036
0e51b4a3 1037 /* Attributes. */
d62a17ae 1038 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_DISTANCE))
1039 stream_putc(s, api->distance);
1040 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_METRIC))
1041 stream_putl(s, api->metric);
1042 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TAG))
1043 stream_putl(s, api->tag);
1044 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_MTU))
1045 stream_putl(s, api->mtu);
ba1849ef
DS
1046 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TABLEID))
1047 stream_putl(s, api->tableid);
d62a17ae 1048
1049 /* Put length at the first point of the stream. */
1050 stream_putw_at(s, 0, stream_get_endp(s));
1051
0e51b4a3
RW
1052 return 0;
1053}
1054
68a02e06
MS
1055/*
1056 * Decode a single zapi nexthop object
1057 */
1058static int zapi_nexthop_decode(struct stream *s, struct zapi_nexthop *api_nh,
1059 uint32_t api_flags)
1060{
1061 int ret = -1;
1062
1063 STREAM_GETL(s, api_nh->vrf_id);
1064 STREAM_GETC(s, api_nh->type);
1065
1066 /* Note that we're only using a single octet of flags */
1067 STREAM_GETC(s, api_nh->flags);
1068
1069 switch (api_nh->type) {
1070 case NEXTHOP_TYPE_BLACKHOLE:
1071 STREAM_GETC(s, api_nh->bh_type);
1072 break;
1073 case NEXTHOP_TYPE_IPV4:
1074 STREAM_GET(&api_nh->gate.ipv4.s_addr, s,
1075 IPV4_MAX_BYTELEN);
1076 break;
1077 case NEXTHOP_TYPE_IPV4_IFINDEX:
1078 STREAM_GET(&api_nh->gate.ipv4.s_addr, s,
1079 IPV4_MAX_BYTELEN);
1080 STREAM_GETL(s, api_nh->ifindex);
1081 break;
1082 case NEXTHOP_TYPE_IFINDEX:
1083 STREAM_GETL(s, api_nh->ifindex);
1084 break;
1085 case NEXTHOP_TYPE_IPV6:
1086 STREAM_GET(&api_nh->gate.ipv6, s, 16);
1087 break;
1088 case NEXTHOP_TYPE_IPV6_IFINDEX:
1089 STREAM_GET(&api_nh->gate.ipv6, s, 16);
1090 STREAM_GETL(s, api_nh->ifindex);
1091 break;
1092 }
1093
1094 /* MPLS labels for BGP-LU or Segment Routing */
1095 if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_LABEL)) {
1096 STREAM_GETC(s, api_nh->label_num);
1097 if (api_nh->label_num > MPLS_MAX_LABELS) {
1098 flog_err(
1099 EC_LIB_ZAPI_ENCODE,
1100 "%s: invalid number of MPLS labels (%u)",
1101 __func__, api_nh->label_num);
1102 return -1;
1103 }
1104
1105 STREAM_GET(&api_nh->labels[0], s,
1106 api_nh->label_num * sizeof(mpls_label_t));
1107 }
1108
bd054c1a
DS
1109 if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_WEIGHT))
1110 STREAM_GETL(s, api_nh->weight);
1111
68a02e06
MS
1112 /* Router MAC for EVPN routes. */
1113 if (CHECK_FLAG(api_flags, ZEBRA_FLAG_EVPN_ROUTE))
1114 STREAM_GET(&(api_nh->rmac), s,
1115 sizeof(struct ethaddr));
1116
1117 /* Success */
1118 ret = 0;
1119
1120stream_failure:
1121
1122 return ret;
1123}
1124
0e51b4a3
RW
1125int zapi_route_decode(struct stream *s, struct zapi_route *api)
1126{
1127 struct zapi_nexthop *api_nh;
1128 int i;
1129
1130 memset(api, 0, sizeof(*api));
1131
1132 /* Type, flags, message. */
ec93aa12 1133 STREAM_GETC(s, api->type);
e4081c0e 1134 if (api->type >= ZEBRA_ROUTE_MAX) {
450971aa 1135 flog_err(EC_LIB_ZAPI_ENCODE,
decbd929
DS
1136 "%s: Specified route type: %d is not a legal value\n",
1137 __PRETTY_FUNCTION__, api->type);
ec93aa12
DS
1138 return -1;
1139 }
1140
1141 STREAM_GETW(s, api->instance);
1142 STREAM_GETL(s, api->flags);
1143 STREAM_GETC(s, api->message);
832d0f56 1144 STREAM_GETC(s, api->safi);
e4081c0e
RW
1145 if (api->safi < SAFI_UNICAST || api->safi >= SAFI_MAX) {
1146 flog_err(EC_LIB_ZAPI_ENCODE,
1147 "%s: Specified route SAFI (%u) is not a legal value\n",
1148 __PRETTY_FUNCTION__, api->safi);
1149 return -1;
1150 }
0e51b4a3
RW
1151
1152 /* Prefix. */
ec93aa12
DS
1153 STREAM_GETC(s, api->prefix.family);
1154 STREAM_GETC(s, api->prefix.prefixlen);
0e51b4a3
RW
1155 switch (api->prefix.family) {
1156 case AF_INET:
ec93aa12 1157 if (api->prefix.prefixlen > IPV4_MAX_PREFIXLEN) {
ade6974d 1158 flog_err(
450971aa 1159 EC_LIB_ZAPI_ENCODE,
ade6974d
QY
1160 "%s: V4 prefixlen is %d which should not be more than 32",
1161 __PRETTY_FUNCTION__, api->prefix.prefixlen);
ec93aa12
DS
1162 return -1;
1163 }
0e51b4a3
RW
1164 break;
1165 case AF_INET6:
ec93aa12 1166 if (api->prefix.prefixlen > IPV6_MAX_PREFIXLEN) {
ade6974d 1167 flog_err(
450971aa 1168 EC_LIB_ZAPI_ENCODE,
ade6974d
QY
1169 "%s: v6 prefixlen is %d which should not be more than 128",
1170 __PRETTY_FUNCTION__, api->prefix.prefixlen);
ec93aa12
DS
1171 return -1;
1172 }
0e51b4a3 1173 break;
ec93aa12 1174 default:
450971aa 1175 flog_err(EC_LIB_ZAPI_ENCODE,
decbd929
DS
1176 "%s: Specified family %d is not v4 or v6",
1177 __PRETTY_FUNCTION__, api->prefix.family);
ec93aa12 1178 return -1;
0e51b4a3 1179 }
ec93aa12
DS
1180 STREAM_GET(&api->prefix.u.prefix, s, PSIZE(api->prefix.prefixlen));
1181
0e51b4a3
RW
1182 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_SRCPFX)) {
1183 api->src_prefix.family = AF_INET6;
ec93aa12
DS
1184 STREAM_GETC(s, api->src_prefix.prefixlen);
1185 if (api->src_prefix.prefixlen > IPV6_MAX_PREFIXLEN) {
ade6974d 1186 flog_err(
450971aa 1187 EC_LIB_ZAPI_ENCODE,
ade6974d
QY
1188 "%s: SRC Prefix prefixlen received: %d is too large",
1189 __PRETTY_FUNCTION__, api->src_prefix.prefixlen);
ec93aa12
DS
1190 return -1;
1191 }
1192 STREAM_GET(&api->src_prefix.prefix, s,
0e51b4a3
RW
1193 PSIZE(api->src_prefix.prefixlen));
1194
1195 if (api->prefix.family != AF_INET6
ec93aa12 1196 || api->src_prefix.prefixlen == 0) {
ade6974d 1197 flog_err(
450971aa 1198 EC_LIB_ZAPI_ENCODE,
ade6974d
QY
1199 "%s: SRC prefix specified in some manner that makes no sense",
1200 __PRETTY_FUNCTION__);
ec93aa12
DS
1201 return -1;
1202 }
0e51b4a3
RW
1203 }
1204
1205 /* Nexthops. */
1206 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) {
ec93aa12 1207 STREAM_GETW(s, api->nexthop_num);
0e51b4a3 1208 if (api->nexthop_num > MULTIPATH_NUM) {
450971aa 1209 flog_err(EC_LIB_ZAPI_ENCODE,
decbd929
DS
1210 "%s: invalid number of nexthops (%u)",
1211 __func__, api->nexthop_num);
0e51b4a3
RW
1212 return -1;
1213 }
1214
1215 for (i = 0; i < api->nexthop_num; i++) {
1216 api_nh = &api->nexthops[i];
1217
68a02e06
MS
1218 if (zapi_nexthop_decode(s, api_nh, api->flags) != 0)
1219 return -1;
0e51b4a3
RW
1220 }
1221 }
1222
1223 /* Attributes. */
1224 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_DISTANCE))
ec93aa12 1225 STREAM_GETC(s, api->distance);
0e51b4a3 1226 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_METRIC))
ec93aa12 1227 STREAM_GETL(s, api->metric);
0e51b4a3 1228 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TAG))
ec93aa12 1229 STREAM_GETL(s, api->tag);
0e51b4a3 1230 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_MTU))
ec93aa12 1231 STREAM_GETL(s, api->mtu);
ba1849ef
DS
1232 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TABLEID))
1233 STREAM_GETL(s, api->tableid);
0e51b4a3
RW
1234
1235 return 0;
6a2b0d9a
RW
1236stream_failure:
1237 return -1;
657cde12
DS
1238}
1239
0313523d
FR
1240static void zapi_encode_prefix(struct stream *s, struct prefix *p,
1241 uint8_t family)
0031a6bb
PG
1242{
1243 struct prefix any;
1244
1245 if (!p) {
1246 memset(&any, 0, sizeof(any));
1247 any.family = family;
1248 p = &any;
1249 }
1250
1251 stream_putc(s, p->family);
1252 stream_putc(s, p->prefixlen);
1253 stream_put(s, &p->u.prefix, prefix_blen(p));
1254}
1255
0313523d 1256int zapi_pbr_rule_encode(uint8_t cmd, struct stream *s, struct pbr_rule *zrule)
0031a6bb
PG
1257{
1258 stream_reset(s);
1259 zclient_create_header(s, cmd, zrule->vrf_id);
1260
1261 /*
1262 * We are sending one item at a time at the moment
1263 */
1264 stream_putl(s, 1);
1265
1266 stream_putl(s, zrule->seq);
1267 stream_putl(s, zrule->priority);
1268 stream_putl(s, zrule->unique);
1269
1270 zapi_encode_prefix(s, &(zrule->filter.src_ip),
1271 zrule->filter.src_ip.family);
0313523d 1272 stream_putw(s, zrule->filter.src_port); /* src port */
0031a6bb
PG
1273 zapi_encode_prefix(s, &(zrule->filter.dst_ip),
1274 zrule->filter.src_ip.family);
0313523d
FR
1275 stream_putw(s, zrule->filter.dst_port); /* dst port */
1276 stream_putw(s, zrule->filter.fwmark); /* fwmark */
0031a6bb
PG
1277
1278 stream_putl(s, zrule->action.table);
1279 stream_putl(s, zrule->ifindex);
1280
1281 /* Put length at the first point of the stream. */
1282 stream_putw_at(s, 0, stream_get_endp(s));
1283
1284 return 0;
1285}
1286
7ea7b86e 1287bool zapi_route_notify_decode(struct stream *s, struct prefix *p,
28610f7e 1288 uint32_t *tableid,
7ea7b86e
DS
1289 enum zapi_route_notify_owner *note)
1290{
7a1eb44b
DS
1291 uint32_t t;
1292
7ea7b86e
DS
1293 STREAM_GET(note, s, sizeof(*note));
1294
1295 STREAM_GETC(s, p->family);
1296 STREAM_GETC(s, p->prefixlen);
996c9314 1297 STREAM_GET(&p->u.prefix, s, prefix_blen(p));
7a1eb44b
DS
1298 STREAM_GETL(s, t);
1299
1300 *tableid = t;
7ea7b86e
DS
1301
1302 return true;
1303
1304stream_failure:
1305 return false;
1306}
1307
b6c5d343
DS
1308bool zapi_rule_notify_decode(struct stream *s, uint32_t *seqno,
1309 uint32_t *priority, uint32_t *unique,
1310 ifindex_t *ifindex,
1311 enum zapi_rule_notify_owner *note)
1312{
1313 uint32_t prio, seq, uni;
1314 ifindex_t ifi;
1315
1316 STREAM_GET(note, s, sizeof(*note));
1317
1318 STREAM_GETL(s, seq);
1319 STREAM_GETL(s, prio);
1320 STREAM_GETL(s, uni);
1321 STREAM_GETL(s, ifi);
1322
1323 if (zclient_debug)
0313523d
FR
1324 zlog_debug("%s: %u %u %u %u", __PRETTY_FUNCTION__, seq, prio,
1325 uni, ifi);
b6c5d343
DS
1326 *seqno = seq;
1327 *priority = prio;
1328 *unique = uni;
1329 *ifindex = ifi;
1330
1331 return true;
1332
1333stream_failure:
1334 return false;
1335}
1336
0313523d
FR
1337bool zapi_ipset_notify_decode(struct stream *s, uint32_t *unique,
1338 enum zapi_ipset_notify_owner *note)
425bdd6b
PG
1339{
1340 uint32_t uni;
1341
1342 STREAM_GET(note, s, sizeof(*note));
1343
1344 STREAM_GETL(s, uni);
1345
1346 if (zclient_debug)
1347 zlog_debug("%s: %u", __PRETTY_FUNCTION__, uni);
1348 *unique = uni;
1349
1350 return true;
1351
1352stream_failure:
1353 return false;
1354}
1355
0313523d
FR
1356bool zapi_ipset_entry_notify_decode(struct stream *s, uint32_t *unique,
1357 char *ipset_name,
1358 enum zapi_ipset_entry_notify_owner *note)
425bdd6b
PG
1359{
1360 uint32_t uni;
1361
1362 STREAM_GET(note, s, sizeof(*note));
1363
1364 STREAM_GETL(s, uni);
1365
0313523d 1366 STREAM_GET(ipset_name, s, ZEBRA_IPSET_NAME_SIZE);
425bdd6b
PG
1367
1368 if (zclient_debug)
1369 zlog_debug("%s: %u", __PRETTY_FUNCTION__, uni);
1370 *unique = uni;
1371
1372 return true;
1373
1374stream_failure:
1375 return false;
1376}
1377
c16a0a62
PG
1378bool zapi_iptable_notify_decode(struct stream *s,
1379 uint32_t *unique,
1380 enum zapi_iptable_notify_owner *note)
1381{
1382 uint32_t uni;
1383
1384 STREAM_GET(note, s, sizeof(*note));
1385
1386 STREAM_GETL(s, uni);
1387
1388 if (zclient_debug)
1389 zlog_debug("%s: %u", __PRETTY_FUNCTION__, uni);
1390 *unique = uni;
1391
1392 return true;
1393
1394stream_failure:
1395 return false;
1396}
1397
4a749e2c
DS
1398struct nexthop *nexthop_from_zapi_nexthop(struct zapi_nexthop *znh)
1399{
1400 struct nexthop *n = nexthop_new();
1401
1402 n->type = znh->type;
4a7371e9 1403 n->vrf_id = znh->vrf_id;
4a749e2c
DS
1404 n->ifindex = znh->ifindex;
1405 n->gate = znh->gate;
1406
1407 /*
960035b2 1408 * This function currently handles labels
4a749e2c 1409 */
960035b2
PZ
1410 if (znh->label_num) {
1411 nexthop_add_labels(n, ZEBRA_LSP_NONE, znh->label_num,
0313523d 1412 znh->labels);
960035b2 1413 }
4a749e2c
DS
1414
1415 return n;
1416}
1417
68a02e06
MS
1418/*
1419 * Convert nexthop to zapi nexthop
1420 */
1421int zapi_nexthop_from_nexthop(struct zapi_nexthop *znh,
1422 const struct nexthop *nh)
1423{
1424 int i;
1425
1426 memset(znh, 0, sizeof(*znh));
1427
1428 znh->type = nh->type;
1429 znh->vrf_id = nh->vrf_id;
1430 znh->ifindex = nh->ifindex;
1431 znh->gate = nh->gate;
1432
1433 if (nh->nh_label && (nh->nh_label->num_labels > 0)) {
1434 for (i = 0; i < nh->nh_label->num_labels; i++)
1435 znh->labels[i] = nh->nh_label->label[i];
1436
1437 znh->label_num = i;
1438 SET_FLAG(znh->flags, ZAPI_NEXTHOP_FLAG_LABEL);
1439 }
1440
1441 return 0;
1442}
1443
1444/*
1445 * Decode the nexthop-tracking update message
1446 */
4a749e2c
DS
1447bool zapi_nexthop_update_decode(struct stream *s, struct zapi_route *nhr)
1448{
1449 uint32_t i;
1450
1451 memset(nhr, 0, sizeof(*nhr));
1452
1453 STREAM_GETW(s, nhr->prefix.family);
1454 STREAM_GETC(s, nhr->prefix.prefixlen);
996c9314 1455 switch (nhr->prefix.family) {
4a749e2c
DS
1456 case AF_INET:
1457 STREAM_GET(&nhr->prefix.u.prefix4.s_addr, s, IPV4_MAX_BYTELEN);
1458 break;
1459 case AF_INET6:
1460 STREAM_GET(&nhr->prefix.u.prefix6, s, IPV6_MAX_BYTELEN);
1461 break;
1462 default:
1463 break;
1464 }
1465
05dd5aaf
DS
1466 STREAM_GETC(s, nhr->type);
1467 STREAM_GETW(s, nhr->instance);
4a749e2c
DS
1468 STREAM_GETC(s, nhr->distance);
1469 STREAM_GETL(s, nhr->metric);
1470 STREAM_GETC(s, nhr->nexthop_num);
1471
996c9314 1472 for (i = 0; i < nhr->nexthop_num; i++) {
68a02e06
MS
1473 if (zapi_nexthop_decode(s, &(nhr->nexthops[i]), 0) != 0)
1474 return -1;
4a749e2c
DS
1475 }
1476
1477 return true;
1478stream_failure:
1479 return false;
1480}
1481
9ab0b2a3
SW
1482bool zapi_error_decode(struct stream *s, enum zebra_error_types *error)
1483{
1484 memset(error, 0, sizeof(*error));
1485
1486 STREAM_GET(error, s, sizeof(*error));
1487
1488 if (zclient_debug)
1489 zlog_debug("%s: type: %s", __func__,
1490 zebra_error_type2str(*error));
1491
1492 return true;
1493stream_failure:
1494 return false;
1495}
1496
d62a17ae 1497/*
0a589359 1498 * send a ZEBRA_REDISTRIBUTE_ADD or ZEBRA_REDISTRIBUTE_DELETE
1499 * for the route type (ZEBRA_ROUTE_KERNEL etc.). The zebra server will
d62a17ae 1500 * then set/unset redist[type] in the client handle (a struct zserv) for the
0a589359 1501 * sending client
1502 */
d62a17ae 1503int zebra_redistribute_send(int command, struct zclient *zclient, afi_t afi,
d7c0a89a 1504 int type, unsigned short instance, vrf_id_t vrf_id)
718e3744 1505{
d62a17ae 1506 struct stream *s;
1507
1508 s = zclient->obuf;
1509 stream_reset(s);
1510
1511 zclient_create_header(s, command, vrf_id);
1512 stream_putc(s, afi);
1513 stream_putc(s, type);
1514 stream_putw(s, instance);
1515
1516 stream_putw_at(s, 0, stream_get_endp(s));
1517
1518 return zclient_send_message(zclient);
718e3744 1519}
1520
49db7a7b
RW
1521int zebra_redistribute_default_send(int command, struct zclient *zclient,
1522 afi_t afi, vrf_id_t vrf_id)
1523{
1524 struct stream *s;
1525
1526 s = zclient->obuf;
1527 stream_reset(s);
1528
1529 zclient_create_header(s, command, vrf_id);
1530 stream_putc(s, afi);
1531
1532 stream_putw_at(s, 0, stream_get_endp(s));
1533
1534 return zclient_send_message(zclient);
1535}
1536
d9178828 1537/* Get prefix in ZServ format; family should be filled in on prefix */
d62a17ae 1538static void zclient_stream_get_prefix(struct stream *s, struct prefix *p)
d9178828 1539{
d62a17ae 1540 size_t plen = prefix_blen(p);
d7c0a89a 1541 uint8_t c;
d62a17ae 1542 p->prefixlen = 0;
1543
1544 if (plen == 0)
1545 return;
1546
1547 stream_get(&p->u.prefix, s, plen);
ec93aa12 1548 STREAM_GETC(s, c);
d62a17ae 1549 p->prefixlen = MIN(plen * 8, c);
ec93aa12
DS
1550
1551stream_failure:
1552 return;
d9178828
PJ
1553}
1554
18a6dce6 1555/* Router-id update from zebra daemon. */
d62a17ae 1556void zebra_router_id_update_read(struct stream *s, struct prefix *rid)
18a6dce6 1557{
d62a17ae 1558 /* Fetch interface address. */
ec93aa12 1559 STREAM_GETC(s, rid->family);
d62a17ae 1560
1561 zclient_stream_get_prefix(s, rid);
ec93aa12
DS
1562
1563stream_failure:
1564 return;
18a6dce6 1565}
1566
718e3744 1567/* Interface addition from zebra daemon. */
d62a17ae 1568/*
0a589359 1569 * The format of the message sent with type ZEBRA_INTERFACE_ADD or
1570 * ZEBRA_INTERFACE_DELETE from zebra to the client is:
1571 * 0 1 2 3
1572 * 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 1573 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1574 * | ifname |
1575 * | |
1576 * | |
1577 * | |
1578 * | |
1579 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee
OD
1580 * | ifindex |
1581 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1582 * | status |
0a589359 1583 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee 1584 * | if_flags |
c77d4546 1585 * | |
0a589359 1586 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee
OD
1587 * | metric |
1588 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2d7f0d76
DS
1589 * | speed |
1590 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee
OD
1591 * | ifmtu |
1592 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1593 * | ifmtu6 |
1594 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1595 * | bandwidth |
1596 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
53e60e5c
QY
1597 * | parent ifindex |
1598 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee 1599 * | Link Layer Type |
0a589359 1600 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee 1601 * | Harware Address Length |
0a589359 1602 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee
OD
1603 * | Hardware Address if HW lenght different from 0 |
1604 * | ... max INTERFACE_HWADDR_MAX |
0a589359 1605 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee 1606 * | Link_params? | Whether a link-params follows: 1 or 0.
0a589359 1607 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee
OD
1608 * | Link_params 0 or 1 INTERFACE_LINK_PARAMS_SIZE sized |
1609 * | .... (struct if_link_params). |
0a589359 1610 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1611 */
1612
d62a17ae 1613static void zclient_vrf_add(struct zclient *zclient, vrf_id_t vrf_id)
1892f15e 1614{
d62a17ae 1615 struct vrf *vrf;
1616 char vrfname_tmp[VRF_NAMSIZ];
1617 struct vrf_data data;
1892f15e 1618
d62a17ae 1619 stream_get(&data, zclient->ibuf, sizeof(struct vrf_data));
1620 /* Read interface name. */
1621 stream_get(vrfname_tmp, zclient->ibuf, VRF_NAMSIZ);
1892f15e 1622
d62a17ae 1623 /* Lookup/create vrf by vrf_id. */
1624 vrf = vrf_get(vrf_id, vrfname_tmp);
4691b65a
PG
1625 vrf->data.l.table_id = data.l.table_id;
1626 memcpy(vrf->data.l.netns_name, data.l.netns_name, NS_NAMSIZ);
4931a365
PG
1627 /* overwrite default vrf */
1628 if (vrf_id == VRF_DEFAULT)
4fe52e76 1629 vrf_set_default_name(vrfname_tmp, false);
d62a17ae 1630 vrf_enable(vrf);
1892f15e
DS
1631}
1632
d62a17ae 1633static void zclient_vrf_delete(struct zclient *zclient, vrf_id_t vrf_id)
1892f15e 1634{
d62a17ae 1635 struct vrf *vrf;
1892f15e 1636
d62a17ae 1637 /* Lookup vrf by vrf_id. */
1638 vrf = vrf_lookup_by_id(vrf_id);
1892f15e 1639
d62a17ae 1640 /*
1641 * If a routing protocol doesn't know about a
1642 * vrf that is about to be deleted. There is
1643 * no point in attempting to delete it.
1644 */
1645 if (!vrf)
1646 return;
beef1990 1647
d62a17ae 1648 vrf_delete(vrf);
1892f15e
DS
1649}
1650
ef7bd2a3 1651static void zclient_interface_add(struct zclient *zclient, vrf_id_t vrf_id)
718e3744 1652{
d62a17ae 1653 struct interface *ifp;
1654 char ifname_tmp[INTERFACE_NAMSIZ];
ef7bd2a3 1655 struct stream *s = zclient->ibuf;
718e3744 1656
d62a17ae 1657 /* Read interface name. */
1658 stream_get(ifname_tmp, s, INTERFACE_NAMSIZ);
718e3744 1659
d62a17ae 1660 /* Lookup/create interface by name. */
a36898e7 1661 ifp = if_get_by_name(ifname_tmp, vrf_id);
a41c4e1b 1662
d62a17ae 1663 zebra_interface_if_set_value(s, ifp);
718e3744 1664
ef7bd2a3 1665 if_new_via_zapi(ifp);
718e3744 1666}
1667
d62a17ae 1668/*
0a589359 1669 * Read interface up/down msg (ZEBRA_INTERFACE_UP/ZEBRA_INTERFACE_DOWN)
1670 * from zebra server. The format of this message is the same as
ef7bd2a3
DS
1671 * that sent for ZEBRA_INTERFACE_ADD/ZEBRA_INTERFACE_DELETE,
1672 * except that no sockaddr_dl is sent at the tail of the message.
0a589359 1673 */
d62a17ae 1674struct interface *zebra_interface_state_read(struct stream *s, vrf_id_t vrf_id)
718e3744 1675{
d62a17ae 1676 struct interface *ifp;
1677 char ifname_tmp[INTERFACE_NAMSIZ];
1678
1679 /* Read interface name. */
1680 stream_get(ifname_tmp, s, INTERFACE_NAMSIZ);
1681
1682 /* Lookup this by interface index. */
a36898e7 1683 ifp = if_lookup_by_name(ifname_tmp, vrf_id);
d62a17ae 1684 if (ifp == NULL) {
450971aa 1685 flog_err(EC_LIB_ZAPI_ENCODE,
decbd929
DS
1686 "INTERFACE_STATE: Cannot find IF %s in VRF %d",
1687 ifname_tmp, vrf_id);
d62a17ae 1688 return NULL;
1689 }
1690
1691 zebra_interface_if_set_value(s, ifp);
1692
1693 return ifp;
718e3744 1694}
1695
3c3c3252
DS
1696static void zclient_interface_delete(struct zclient *zclient, vrf_id_t vrf_id)
1697{
1698 struct interface *ifp;
1699 struct stream *s = zclient->ibuf;
1700
1701 ifp = zebra_interface_state_read(s, vrf_id);
1702
1703 if (ifp == NULL)
1704 return;
1705
1706 if_destroy_via_zapi(ifp);
1707 return;
1708}
1709
ddbf3e60
DS
1710static void zclient_interface_up(struct zclient *zclient, vrf_id_t vrf_id)
1711{
1712 struct interface *ifp;
1713 struct stream *s = zclient->ibuf;
1714
1715 ifp = zebra_interface_state_read(s, vrf_id);
1716
1717 if (!ifp)
1718 return;
1719
1720 if_up_via_zapi(ifp);
1721}
1722
b0b69e59
DS
1723static void zclient_interface_down(struct zclient *zclient, vrf_id_t vrf_id)
1724{
1725 struct interface *ifp;
1726 struct stream *s = zclient->ibuf;
1727
1728 ifp = zebra_interface_state_read(s, vrf_id);
1729
1730 if (!ifp)
1731 return;
1732
1733 if_down_via_zapi(ifp);
1734}
1735
9ab0b2a3
SW
1736static void zclient_handle_error(ZAPI_CALLBACK_ARGS)
1737{
1738 enum zebra_error_types error;
1739 struct stream *s = zclient->ibuf;
1740
1741 zapi_error_decode(s, &error);
1742
1743 if (zclient->handle_error)
1744 (*zclient->handle_error)(error);
1745}
1746
d62a17ae 1747static void link_params_set_value(struct stream *s, struct if_link_params *iflp)
16f1b9ee
OD
1748{
1749
d62a17ae 1750 if (iflp == NULL)
1751 return;
1752
1753 iflp->lp_status = stream_getl(s);
1754 iflp->te_metric = stream_getl(s);
1755 iflp->max_bw = stream_getf(s);
1756 iflp->max_rsv_bw = stream_getf(s);
1757 uint32_t bwclassnum = stream_getl(s);
1758 {
1759 unsigned int i;
1760 for (i = 0; i < bwclassnum && i < MAX_CLASS_TYPE; i++)
1761 iflp->unrsv_bw[i] = stream_getf(s);
1762 if (i < bwclassnum)
1c50c1c0
QY
1763 flog_err(
1764 EC_LIB_ZAPI_MISSMATCH,
1765 "%s: received %d > %d (MAX_CLASS_TYPE) bw entries"
1766 " - outdated library?",
1767 __func__, bwclassnum, MAX_CLASS_TYPE);
d62a17ae 1768 }
1769 iflp->admin_grp = stream_getl(s);
1770 iflp->rmt_as = stream_getl(s);
1771 iflp->rmt_ip.s_addr = stream_get_ipv4(s);
1772
1773 iflp->av_delay = stream_getl(s);
1774 iflp->min_delay = stream_getl(s);
1775 iflp->max_delay = stream_getl(s);
1776 iflp->delay_var = stream_getl(s);
1777
1778 iflp->pkt_loss = stream_getf(s);
1779 iflp->res_bw = stream_getf(s);
1780 iflp->ava_bw = stream_getf(s);
1781 iflp->use_bw = stream_getf(s);
16f1b9ee
OD
1782}
1783
edc12762
RW
1784struct interface *zebra_interface_link_params_read(struct stream *s,
1785 vrf_id_t vrf_id)
16f1b9ee 1786{
d62a17ae 1787 struct if_link_params *iflp;
1788 ifindex_t ifindex;
c28e5b2a 1789
d62a17ae 1790 assert(s);
c28e5b2a 1791
d62a17ae 1792 ifindex = stream_getl(s);
16f1b9ee 1793
a36898e7 1794 struct interface *ifp = if_lookup_by_index(ifindex, vrf_id);
16f1b9ee 1795
d62a17ae 1796 if (ifp == NULL) {
450971aa 1797 flog_err(EC_LIB_ZAPI_ENCODE,
1c50c1c0
QY
1798 "%s: unknown ifindex %u, shouldn't happen", __func__,
1799 ifindex);
d62a17ae 1800 return NULL;
1801 }
16f1b9ee 1802
d62a17ae 1803 if ((iflp = if_link_params_get(ifp)) == NULL)
1804 return NULL;
16f1b9ee 1805
d62a17ae 1806 link_params_set_value(s, iflp);
16f1b9ee 1807
d62a17ae 1808 return ifp;
16f1b9ee
OD
1809}
1810
26f8f6fe
DS
1811static void zebra_interface_if_set_value(struct stream *s,
1812 struct interface *ifp)
16f1b9ee 1813{
d7c0a89a 1814 uint8_t link_params_status = 0;
98cbbaea 1815 ifindex_t old_ifindex;
d62a17ae 1816
98cbbaea 1817 old_ifindex = ifp->ifindex;
d62a17ae 1818 /* Read interface's index. */
ff880b78 1819 if_set_index(ifp, stream_getl(s));
d62a17ae 1820 ifp->status = stream_getc(s);
1821
1822 /* Read interface's value. */
1823 ifp->flags = stream_getq(s);
1824 ifp->ptm_enable = stream_getc(s);
1825 ifp->ptm_status = stream_getc(s);
1826 ifp->metric = stream_getl(s);
1827 ifp->speed = stream_getl(s);
1828 ifp->mtu = stream_getl(s);
1829 ifp->mtu6 = stream_getl(s);
1830 ifp->bandwidth = stream_getl(s);
53e60e5c 1831 ifp->link_ifindex = stream_getl(s);
d62a17ae 1832 ifp->ll_type = stream_getl(s);
1833 ifp->hw_addr_len = stream_getl(s);
1834 if (ifp->hw_addr_len)
1835 stream_get(ifp->hw_addr, s,
1836 MIN(ifp->hw_addr_len, INTERFACE_HWADDR_MAX));
1837
1838 /* Read Traffic Engineering status */
1839 link_params_status = stream_getc(s);
1840 /* Then, Traffic Engineering parameters if any */
1841 if (link_params_status) {
1842 struct if_link_params *iflp = if_link_params_get(ifp);
1843 link_params_set_value(s, iflp);
1844 }
98cbbaea
DS
1845
1846 nexthop_group_interface_state_change(ifp, old_ifindex);
16f1b9ee
OD
1847}
1848
d62a17ae 1849size_t zebra_interface_link_params_write(struct stream *s,
1850 struct interface *ifp)
16f1b9ee 1851{
d62a17ae 1852 size_t w;
1853 struct if_link_params *iflp;
1854 int i;
16f1b9ee 1855
d62a17ae 1856 if (s == NULL || ifp == NULL || ifp->link_params == NULL)
1857 return 0;
16f1b9ee 1858
d62a17ae 1859 iflp = ifp->link_params;
1860 w = 0;
16f1b9ee 1861
d62a17ae 1862 w += stream_putl(s, iflp->lp_status);
16f1b9ee 1863
d62a17ae 1864 w += stream_putl(s, iflp->te_metric);
1865 w += stream_putf(s, iflp->max_bw);
1866 w += stream_putf(s, iflp->max_rsv_bw);
16f1b9ee 1867
d62a17ae 1868 w += stream_putl(s, MAX_CLASS_TYPE);
1869 for (i = 0; i < MAX_CLASS_TYPE; i++)
1870 w += stream_putf(s, iflp->unrsv_bw[i]);
16f1b9ee 1871
d62a17ae 1872 w += stream_putl(s, iflp->admin_grp);
1873 w += stream_putl(s, iflp->rmt_as);
1874 w += stream_put_in_addr(s, &iflp->rmt_ip);
16f1b9ee 1875
d62a17ae 1876 w += stream_putl(s, iflp->av_delay);
1877 w += stream_putl(s, iflp->min_delay);
1878 w += stream_putl(s, iflp->max_delay);
1879 w += stream_putl(s, iflp->delay_var);
16f1b9ee 1880
d62a17ae 1881 w += stream_putf(s, iflp->pkt_loss);
1882 w += stream_putf(s, iflp->res_bw);
1883 w += stream_putf(s, iflp->ava_bw);
1884 w += stream_putf(s, iflp->use_bw);
16f1b9ee 1885
d62a17ae 1886 return w;
16f1b9ee
OD
1887}
1888
1889/*
0a589359 1890 * format of message for address additon is:
1891 * 0
1892 * 0 1 2 3 4 5 6 7
1893 * +-+-+-+-+-+-+-+-+
1894 * | type | ZEBRA_INTERFACE_ADDRESS_ADD or
1895 * +-+-+-+-+-+-+-+-+ ZEBRA_INTERFACE_ADDRES_DELETE
1896 * | |
1897 * + +
1898 * | ifindex |
1899 * + +
1900 * | |
1901 * + +
1902 * | |
1903 * +-+-+-+-+-+-+-+-+
1904 * | ifc_flags | flags for connected address
1905 * +-+-+-+-+-+-+-+-+
1906 * | addr_family |
1907 * +-+-+-+-+-+-+-+-+
1908 * | addr... |
1909 * : :
1910 * | |
1911 * +-+-+-+-+-+-+-+-+
1912 * | addr_len | len of addr. E.g., addr_len = 4 for ipv4 addrs.
1913 * +-+-+-+-+-+-+-+-+
1914 * | daddr.. |
1915 * : :
1916 * | |
1917 * +-+-+-+-+-+-+-+-+
0a589359 1918 */
1919
d62a17ae 1920static int memconstant(const void *s, int c, size_t n)
3fb9cd6e 1921{
d7c0a89a 1922 const uint8_t *p = s;
3fb9cd6e 1923
d62a17ae 1924 while (n-- > 0)
1925 if (*p++ != c)
1926 return 0;
1927 return 1;
3fb9cd6e 1928}
1929
d5a5c8f0 1930
d62a17ae 1931struct connected *zebra_interface_address_read(int type, struct stream *s,
1932 vrf_id_t vrf_id)
718e3744 1933{
d62a17ae 1934 ifindex_t ifindex;
1935 struct interface *ifp;
1936 struct connected *ifc;
1937 struct prefix p, d, *dp;
1938 int plen;
d7c0a89a 1939 uint8_t ifc_flags;
d62a17ae 1940
1941 memset(&p, 0, sizeof(p));
1942 memset(&d, 0, sizeof(d));
1943
1944 /* Get interface index. */
1945 ifindex = stream_getl(s);
1946
1947 /* Lookup index. */
1948 ifp = if_lookup_by_index(ifindex, vrf_id);
1949 if (ifp == NULL) {
450971aa 1950 flog_err(EC_LIB_ZAPI_ENCODE,
decbd929
DS
1951 "INTERFACE_ADDRESS_%s: Cannot find IF %u in VRF %d",
1952 (type == ZEBRA_INTERFACE_ADDRESS_ADD) ? "ADD" : "DEL",
1953 ifindex, vrf_id);
d62a17ae 1954 return NULL;
1955 }
1956
1957 /* Fetch flag. */
1958 ifc_flags = stream_getc(s);
1959
1960 /* Fetch interface address. */
1961 d.family = p.family = stream_getc(s);
1962 plen = prefix_blen(&d);
1963
1964 zclient_stream_get_prefix(s, &p);
1965
1966 /* Fetch destination address. */
1967 stream_get(&d.u.prefix, s, plen);
1968
1969 /* N.B. NULL destination pointers are encoded as all zeroes */
1970 dp = memconstant(&d.u.prefix, 0, plen) ? NULL : &d;
1971
1972 if (type == ZEBRA_INTERFACE_ADDRESS_ADD) {
1973 ifc = connected_lookup_prefix_exact(ifp, &p);
1974 if (!ifc) {
1975 /* N.B. NULL destination pointers are encoded as all
1976 * zeroes */
1977 ifc = connected_add_by_prefix(ifp, &p, dp);
1978 }
1979 if (ifc) {
1980 ifc->flags = ifc_flags;
1981 if (ifc->destination)
1982 ifc->destination->prefixlen =
1983 ifc->address->prefixlen;
1984 else if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_PEER)) {
1985 /* carp interfaces on OpenBSD with 0.0.0.0/0 as
1986 * "peer" */
1987 char buf[PREFIX_STRLEN];
ade6974d 1988 flog_err(
450971aa 1989 EC_LIB_ZAPI_ENCODE,
ade6974d
QY
1990 "warning: interface %s address %s with peer flag set, but no peer address!",
1991 ifp->name,
1992 prefix2str(ifc->address, buf,
1993 sizeof buf));
d62a17ae 1994 UNSET_FLAG(ifc->flags, ZEBRA_IFA_PEER);
1995 }
1996 }
1997 } else {
1998 assert(type == ZEBRA_INTERFACE_ADDRESS_DELETE);
1999 ifc = connected_delete_by_prefix(ifp, &p);
2000 }
2001
2002 return ifc;
718e3744 2003}
0a589359 2004
a80beece
DS
2005/*
2006 * format of message for neighbor connected address is:
2007 * 0
2008 * 0 1 2 3 4 5 6 7
2009 * +-+-+-+-+-+-+-+-+
2010 * | type | ZEBRA_INTERFACE_NBR_ADDRESS_ADD or
2011 * +-+-+-+-+-+-+-+-+ ZEBRA_INTERFACE_NBR_ADDRES_DELETE
2012 * | |
2013 * + +
2014 * | ifindex |
2015 * + +
2016 * | |
2017 * + +
2018 * | |
2019 * +-+-+-+-+-+-+-+-+
2020 * | addr_family |
2021 * +-+-+-+-+-+-+-+-+
2022 * | addr... |
2023 * : :
2024 * | |
2025 * +-+-+-+-+-+-+-+-+
2026 * | addr_len | len of addr.
2027 * +-+-+-+-+-+-+-+-+
2028 */
2029struct nbr_connected *
d62a17ae 2030zebra_interface_nbr_address_read(int type, struct stream *s, vrf_id_t vrf_id)
a80beece 2031{
d62a17ae 2032 unsigned int ifindex;
2033 struct interface *ifp;
2034 struct prefix p;
2035 struct nbr_connected *ifc;
2036
2037 /* Get interface index. */
2038 ifindex = stream_getl(s);
2039
2040 /* Lookup index. */
2041 ifp = if_lookup_by_index(ifindex, vrf_id);
2042 if (ifp == NULL) {
450971aa 2043 flog_err(EC_LIB_ZAPI_ENCODE,
decbd929
DS
2044 "INTERFACE_NBR_%s: Cannot find IF %u in VRF %d",
2045 (type == ZEBRA_INTERFACE_NBR_ADDRESS_ADD) ? "ADD"
ade6974d
QY
2046 : "DELETE",
2047 ifindex, vrf_id);
d62a17ae 2048 return NULL;
2049 }
2050
2051 p.family = stream_getc(s);
2052 stream_get(&p.u.prefix, s, prefix_blen(&p));
2053 p.prefixlen = stream_getc(s);
2054
2055 if (type == ZEBRA_INTERFACE_NBR_ADDRESS_ADD) {
2056 /* Currently only supporting P2P links, so any new RA source
2057 address is
2058 considered as the replacement of the previously learnt
2059 Link-Local address. */
2060 if (!(ifc = listnode_head(ifp->nbr_connected))) {
2061 ifc = nbr_connected_new();
2062 ifc->address = prefix_new();
2063 ifc->ifp = ifp;
2064 listnode_add(ifp->nbr_connected, ifc);
2065 }
2066
2067 prefix_copy(ifc->address, &p);
2068 } else {
2069 assert(type == ZEBRA_INTERFACE_NBR_ADDRESS_DELETE);
2070
2071 ifc = nbr_connected_check(ifp, &p);
2072 if (ifc)
2073 listnode_delete(ifp->nbr_connected, ifc);
2074 }
2075
2076 return ifc;
a80beece 2077}
6b0655a2 2078
d62a17ae 2079struct interface *zebra_interface_vrf_update_read(struct stream *s,
2080 vrf_id_t vrf_id,
2081 vrf_id_t *new_vrf_id)
c8e264b6 2082{
91d227b7 2083 char ifname[INTERFACE_NAMSIZ];
d62a17ae 2084 struct interface *ifp;
a9ff90c4 2085 vrf_id_t new_id;
d62a17ae 2086
91d227b7
RW
2087 /* Read interface name. */
2088 stream_get(ifname, s, INTERFACE_NAMSIZ);
d62a17ae 2089
2090 /* Lookup interface. */
a36898e7 2091 ifp = if_lookup_by_name(ifname, vrf_id);
d62a17ae 2092 if (ifp == NULL) {
450971aa 2093 flog_err(EC_LIB_ZAPI_ENCODE,
91d227b7
RW
2094 "INTERFACE_VRF_UPDATE: Cannot find IF %s in VRF %d",
2095 ifname, vrf_id);
d62a17ae 2096 return NULL;
2097 }
2098
2099 /* Fetch new VRF Id. */
66cd1bb3 2100 new_id = stream_getl(s);
d62a17ae 2101
2102 *new_vrf_id = new_id;
2103 return ifp;
c8e264b6 2104}
5c7ef8dc 2105
2106/* filter unwanted messages until the expected one arrives */
d62a17ae 2107static int zclient_read_sync_response(struct zclient *zclient,
d7c0a89a 2108 uint16_t expected_cmd)
5c7ef8dc 2109{
d62a17ae 2110 struct stream *s;
d7c0a89a
QY
2111 uint16_t size = -1;
2112 uint8_t marker;
2113 uint8_t version;
d62a17ae 2114 vrf_id_t vrf_id;
d7c0a89a 2115 uint16_t cmd;
d62a17ae 2116 fd_set readfds;
2117 int ret;
2118
2119 ret = 0;
2120 cmd = expected_cmd + 1;
2121 while (ret == 0 && cmd != expected_cmd) {
2122 s = zclient->ibuf;
2123 stream_reset(s);
2124
2125 /* wait until response arrives */
2126 FD_ZERO(&readfds);
2127 FD_SET(zclient->sock, &readfds);
2128 select(zclient->sock + 1, &readfds, NULL, NULL, NULL);
2129 if (!FD_ISSET(zclient->sock, &readfds))
2130 continue;
2131 /* read response */
2132 ret = zclient_read_header(s, zclient->sock, &size, &marker,
2133 &version, &vrf_id, &cmd);
2134 if (zclient_debug)
2135 zlog_debug("%s: Response (%d bytes) received", __func__,
2136 size);
2137 }
2138 if (ret != 0) {
1c50c1c0
QY
2139 flog_err(EC_LIB_ZAPI_ENCODE, "%s: Invalid Sync Message Reply",
2140 __func__);
d62a17ae 2141 return -1;
2142 }
2143
2144 return 0;
5c7ef8dc 2145}
fea12efb 2146/**
2147 * Connect to label manager in a syncronous way
2148 *
2149 * It first writes the request to zcient output buffer and then
2150 * immediately reads the answer from the input buffer.
2151 *
2152 * @param zclient Zclient used to connect to label manager (zebra)
f533be73 2153 * @param async Synchronous (0) or asynchronous (1) operation
fea12efb 2154 * @result Result of response
2155 */
f533be73 2156int lm_label_manager_connect(struct zclient *zclient, int async)
fea12efb 2157{
d62a17ae 2158 int ret;
2159 struct stream *s;
d7c0a89a 2160 uint8_t result;
f533be73 2161 uint16_t cmd = async ? ZEBRA_LABEL_MANAGER_CONNECT_ASYNC :
2162 ZEBRA_LABEL_MANAGER_CONNECT;
d62a17ae 2163
2164 if (zclient_debug)
35cbe02a 2165 zlog_debug("Connecting to Label Manager (LM)");
d62a17ae 2166
f533be73 2167 if (zclient->sock < 0) {
2168 zlog_debug("%s: invalid zclient socket", __func__);
d62a17ae 2169 return -1;
f533be73 2170 }
d62a17ae 2171
2172 /* send request */
2173 s = zclient->obuf;
2174 stream_reset(s);
f533be73 2175 zclient_create_header(s, cmd, VRF_DEFAULT);
d62a17ae 2176
2177 /* proto */
2178 stream_putc(s, zclient->redist_default);
2179 /* instance */
2180 stream_putw(s, zclient->instance);
2181
2182 /* Put length at the first point of the stream. */
2183 stream_putw_at(s, 0, stream_get_endp(s));
2184
2185 ret = writen(zclient->sock, s->data, stream_get_endp(s));
2186 if (ret < 0) {
450971aa 2187 flog_err(EC_LIB_ZAPI_SOCKET, "Can't write to zclient sock");
d62a17ae 2188 close(zclient->sock);
2189 zclient->sock = -1;
2190 return -1;
2191 }
2192 if (ret == 0) {
450971aa 2193 flog_err(EC_LIB_ZAPI_SOCKET, "Zclient sock closed");
d62a17ae 2194 close(zclient->sock);
2195 zclient->sock = -1;
2196 return -1;
2197 }
2198 if (zclient_debug)
35cbe02a 2199 zlog_debug("LM connect request sent (%d bytes)", ret);
d62a17ae 2200
f533be73 2201 if (async)
2202 return 0;
2203
d62a17ae 2204 /* read response */
f533be73 2205 if (zclient_read_sync_response(zclient, cmd)
d62a17ae 2206 != 0)
2207 return -1;
2208
d62a17ae 2209 s = zclient->ibuf;
5dffb0e9
FR
2210
2211 /* read instance and proto */
2212 uint8_t proto = stream_getc(s);
2213 uint16_t instance = stream_getw(s);
2214
2215 /* sanity */
2216 if (proto != zclient->redist_default)
1c50c1c0
QY
2217 flog_err(
2218 EC_LIB_ZAPI_ENCODE,
2219 "Wrong proto (%u) in LM connect response. Should be %u",
2220 proto, zclient->redist_default);
5dffb0e9 2221 if (instance != zclient->instance)
1c50c1c0
QY
2222 flog_err(
2223 EC_LIB_ZAPI_ENCODE,
2224 "Wrong instId (%u) in LM connect response. Should be %u",
2225 instance, zclient->instance);
5dffb0e9
FR
2226
2227 /* result code */
d62a17ae 2228 result = stream_getc(s);
2229 if (zclient_debug)
0313523d 2230 zlog_debug("LM connect-response received, result %u", result);
d62a17ae 2231
2232 return (int)result;
fea12efb 2233}
2234
955bfd98
PZ
2235/*
2236 * Asynchronous label chunk request
2237 *
2238 * @param zclient Zclient used to connect to label manager (zebra)
2239 * @param keep Avoid garbage collection
2240 * @param chunk_size Amount of labels requested
0e3b6a92 2241 * @param base Base for the label chunk. if MPLS_LABEL_BASE_ANY we do not care
955bfd98
PZ
2242 * @result 0 on success, -1 otherwise
2243 */
0313523d 2244int zclient_send_get_label_chunk(struct zclient *zclient, uint8_t keep,
0e3b6a92 2245 uint32_t chunk_size, uint32_t base)
955bfd98
PZ
2246{
2247 struct stream *s;
2248
2249 if (zclient_debug)
2250 zlog_debug("Getting Label Chunk");
2251
2252 if (zclient->sock < 0)
2253 return -1;
2254
2255 s = zclient->obuf;
2256 stream_reset(s);
2257
2258 zclient_create_header(s, ZEBRA_GET_LABEL_CHUNK, VRF_DEFAULT);
5dffb0e9
FR
2259 /* proto */
2260 stream_putc(s, zclient->redist_default);
2261 /* instance */
2262 stream_putw(s, zclient->instance);
955bfd98
PZ
2263 stream_putc(s, keep);
2264 stream_putl(s, chunk_size);
0e3b6a92 2265 stream_putl(s, base);
955bfd98
PZ
2266
2267 /* Put length at the first point of the stream. */
2268 stream_putw_at(s, 0, stream_get_endp(s));
2269
2270 return zclient_send_message(zclient);
2271}
2272
fea12efb 2273/**
2274 * Function to request a label chunk in a syncronous way
2275 *
2276 * It first writes the request to zlcient output buffer and then
2277 * immediately reads the answer from the input buffer.
2278 *
2279 * @param zclient Zclient used to connect to label manager (zebra)
2280 * @param keep Avoid garbage collection
2281 * @param chunk_size Amount of labels requested
2282 * @param start To write first assigned chunk label to
2283 * @param end To write last assigned chunk label to
2284 * @result 0 on success, -1 otherwise
2285 */
0e3b6a92 2286int lm_get_label_chunk(struct zclient *zclient, uint8_t keep, uint32_t base,
d62a17ae 2287 uint32_t chunk_size, uint32_t *start, uint32_t *end)
fea12efb 2288{
d62a17ae 2289 int ret;
2290 struct stream *s;
d7c0a89a 2291 uint8_t response_keep;
d62a17ae 2292
2293 if (zclient_debug)
2294 zlog_debug("Getting Label Chunk");
2295
2296 if (zclient->sock < 0)
2297 return -1;
2298
2299 /* send request */
2300 s = zclient->obuf;
2301 stream_reset(s);
2302 zclient_create_header(s, ZEBRA_GET_LABEL_CHUNK, VRF_DEFAULT);
5dffb0e9
FR
2303 /* proto */
2304 stream_putc(s, zclient->redist_default);
2305 /* instance */
2306 stream_putw(s, zclient->instance);
d62a17ae 2307 /* keep */
2308 stream_putc(s, keep);
2309 /* chunk size */
2310 stream_putl(s, chunk_size);
0e3b6a92
EDP
2311 /* requested chunk base */
2312 stream_putl(s, base);
d62a17ae 2313 /* Put length at the first point of the stream. */
2314 stream_putw_at(s, 0, stream_get_endp(s));
2315
2316 ret = writen(zclient->sock, s->data, stream_get_endp(s));
2317 if (ret < 0) {
1c50c1c0 2318 flog_err(EC_LIB_ZAPI_SOCKET, "Can't write to zclient sock");
d62a17ae 2319 close(zclient->sock);
2320 zclient->sock = -1;
2321 return -1;
2322 }
2323 if (ret == 0) {
1c50c1c0 2324 flog_err(EC_LIB_ZAPI_SOCKET, "Zclient sock closed");
d62a17ae 2325 close(zclient->sock);
2326 zclient->sock = -1;
2327 return -1;
2328 }
2329 if (zclient_debug)
35cbe02a 2330 zlog_debug("Label chunk request (%d bytes) sent", ret);
d62a17ae 2331
2332 /* read response */
2333 if (zclient_read_sync_response(zclient, ZEBRA_GET_LABEL_CHUNK) != 0)
2334 return -1;
2335
5dffb0e9 2336 /* parse response */
d62a17ae 2337 s = zclient->ibuf;
5dffb0e9
FR
2338
2339 /* read proto and instance */
2340 uint8_t proto = stream_getc(s);
2341 uint16_t instance = stream_getw(s);
2342
2343 /* sanities */
2344 if (proto != zclient->redist_default)
450971aa 2345 flog_err(EC_LIB_ZAPI_ENCODE,
1c50c1c0
QY
2346 "Wrong proto (%u) in get chunk response. Should be %u",
2347 proto, zclient->redist_default);
5dffb0e9 2348 if (instance != zclient->instance)
450971aa 2349 flog_err(EC_LIB_ZAPI_ENCODE,
1c50c1c0
QY
2350 "Wrong instId (%u) in get chunk response Should be %u",
2351 instance, zclient->instance);
5dffb0e9 2352
f004f7c3
EDP
2353 /* if we requested a specific chunk and it could not be allocated, the
2354 * response message will end here
2355 */
2356 if (!STREAM_READABLE(s)) {
2357 zlog_info("Unable to assign Label Chunk to %s instance %u",
2358 zebra_route_string(proto), instance);
2359 return -1;
2360 }
2361
d62a17ae 2362 /* keep */
2363 response_keep = stream_getc(s);
2364 /* start and end labels */
2365 *start = stream_getl(s);
2366 *end = stream_getl(s);
2367
2368 /* not owning this response */
2369 if (keep != response_keep) {
1c50c1c0
QY
2370 flog_err(
2371 EC_LIB_ZAPI_ENCODE,
2372 "Invalid Label chunk: %u - %u, keeps mismatch %u != %u",
2373 *start, *end, keep, response_keep);
d62a17ae 2374 }
2375 /* sanity */
70e98a7f
DS
2376 if (*start > *end || *start < MPLS_LABEL_UNRESERVED_MIN
2377 || *end > MPLS_LABEL_UNRESERVED_MAX) {
1c50c1c0
QY
2378 flog_err(EC_LIB_ZAPI_ENCODE, "Invalid Label chunk: %u - %u",
2379 *start, *end);
d62a17ae 2380 return -1;
2381 }
2382
2383 if (zclient_debug)
35cbe02a 2384 zlog_debug("Label Chunk assign: %u - %u (%u)", *start, *end,
d62a17ae 2385 response_keep);
2386
2387 return 0;
fea12efb 2388}
2389
2390/**
2391 * Function to release a label chunk
2392 *
2393 * @param zclient Zclient used to connect to label manager (zebra)
2394 * @param start First label of chunk
2395 * @param end Last label of chunk
2396 * @result 0 on success, -1 otherwise
2397 */
d62a17ae 2398int lm_release_label_chunk(struct zclient *zclient, uint32_t start,
2399 uint32_t end)
fea12efb 2400{
d62a17ae 2401 int ret;
2402 struct stream *s;
2403
2404 if (zclient_debug)
35cbe02a 2405 zlog_debug("Releasing Label Chunk %u - %u", start, end);
d62a17ae 2406
2407 if (zclient->sock < 0)
2408 return -1;
2409
2410 /* send request */
2411 s = zclient->obuf;
2412 stream_reset(s);
2413 zclient_create_header(s, ZEBRA_RELEASE_LABEL_CHUNK, VRF_DEFAULT);
2414
5dffb0e9
FR
2415 /* proto */
2416 stream_putc(s, zclient->redist_default);
2417 /* instance */
2418 stream_putw(s, zclient->instance);
d62a17ae 2419 /* start */
2420 stream_putl(s, start);
2421 /* end */
2422 stream_putl(s, end);
2423
2424 /* Put length at the first point of the stream. */
2425 stream_putw_at(s, 0, stream_get_endp(s));
2426
2427 ret = writen(zclient->sock, s->data, stream_get_endp(s));
2428 if (ret < 0) {
450971aa 2429 flog_err(EC_LIB_ZAPI_SOCKET, "Can't write to zclient sock");
d62a17ae 2430 close(zclient->sock);
2431 zclient->sock = -1;
2432 return -1;
2433 }
2434 if (ret == 0) {
1c50c1c0 2435 flog_err(EC_LIB_ZAPI_SOCKET, "Zclient sock connection closed");
d62a17ae 2436 close(zclient->sock);
2437 zclient->sock = -1;
2438 return -1;
2439 }
2440
2441 return 0;
fea12efb 2442}
c8e264b6 2443
75fb51c1
PG
2444/**
2445 * Connect to table manager in a syncronous way
2446 *
2447 * It first writes the request to zcient output buffer and then
2448 * immediately reads the answer from the input buffer.
2449 *
2450 * @param zclient Zclient used to connect to table manager (zebra)
2451 * @result Result of response
2452 */
2453int tm_table_manager_connect(struct zclient *zclient)
2454{
2455 int ret;
2456 struct stream *s;
2457 uint8_t result;
2458
2459 if (zclient_debug)
2460 zlog_debug("Connecting to Table Manager");
2461
2462 if (zclient->sock < 0)
2463 return -1;
2464
2465 /* send request */
2466 s = zclient->obuf;
2467 stream_reset(s);
2468 zclient_create_header(s, ZEBRA_TABLE_MANAGER_CONNECT, VRF_DEFAULT);
2469
2470 /* proto */
2471 stream_putc(s, zclient->redist_default);
2472 /* instance */
2473 stream_putw(s, zclient->instance);
2474
2475 /* Put length at the first point of the stream. */
2476 stream_putw_at(s, 0, stream_get_endp(s));
2477
2478 ret = zclient_send_message(zclient);
2479 if (ret < 0)
2480 return -1;
2481
2482 if (zclient_debug)
0313523d 2483 zlog_debug("%s: Table manager connect request sent", __func__);
75fb51c1
PG
2484
2485 /* read response */
2486 if (zclient_read_sync_response(zclient, ZEBRA_TABLE_MANAGER_CONNECT)
2487 != 0)
2488 return -1;
2489
2490 /* result */
2491 s = zclient->ibuf;
2492 STREAM_GETC(s, result);
2493 if (zclient_debug)
2494 zlog_debug(
2495 "%s: Table Manager connect response received, result %u",
2496 __func__, result);
2497
2498 return (int)result;
2499stream_failure:
6a2b0d9a 2500 return -1;
75fb51c1
PG
2501}
2502
2503/**
2504 * Function to request a table chunk in a syncronous way
2505 *
2506 * It first writes the request to zclient output buffer and then
2507 * immediately reads the answer from the input buffer.
2508 *
2509 * @param zclient Zclient used to connect to table manager (zebra)
2510 * @param chunk_size Amount of table requested
2511 * @param start to write first assigned chunk table RT ID to
2512 * @param end To write last assigned chunk table RT ID to
2513 * @result 0 on success, -1 otherwise
2514 */
2515int tm_get_table_chunk(struct zclient *zclient, uint32_t chunk_size,
2516 uint32_t *start, uint32_t *end)
2517{
2518 int ret;
2519 struct stream *s;
2520
2521 if (zclient_debug)
2522 zlog_debug("Getting Table Chunk");
2523
2524 if (zclient->sock < 0)
2525 return -1;
2526
2527 /* send request */
2528 s = zclient->obuf;
2529 stream_reset(s);
2530 zclient_create_header(s, ZEBRA_GET_TABLE_CHUNK, VRF_DEFAULT);
2531 /* chunk size */
2532 stream_putl(s, chunk_size);
2533 /* Put length at the first point of the stream. */
2534 stream_putw_at(s, 0, stream_get_endp(s));
2535
2536 ret = writen(zclient->sock, s->data, stream_get_endp(s));
2537 if (ret < 0) {
1c50c1c0
QY
2538 flog_err(EC_LIB_ZAPI_SOCKET, "%s: can't write to zclient->sock",
2539 __func__);
75fb51c1
PG
2540 close(zclient->sock);
2541 zclient->sock = -1;
2542 return -1;
2543 }
2544 if (ret == 0) {
450971aa 2545 flog_err(EC_LIB_ZAPI_SOCKET,
1c50c1c0 2546 "%s: zclient->sock connection closed", __func__);
75fb51c1
PG
2547 close(zclient->sock);
2548 zclient->sock = -1;
2549 return -1;
2550 }
2551 if (zclient_debug)
2552 zlog_debug("%s: Table chunk request (%d bytes) sent", __func__,
2553 ret);
2554
2555 /* read response */
2556 if (zclient_read_sync_response(zclient, ZEBRA_GET_TABLE_CHUNK) != 0)
2557 return -1;
2558
2559 s = zclient->ibuf;
2560 /* start and end table IDs */
2561 STREAM_GETL(s, *start);
2562 STREAM_GETL(s, *end);
2563
2564 if (zclient_debug)
2565 zlog_debug("Table Chunk assign: %u - %u ", *start, *end);
2566
75fb51c1 2567 return 0;
6a2b0d9a
RW
2568stream_failure:
2569 return -1;
75fb51c1
PG
2570}
2571
2572/**
2573 * Function to release a table chunk
2574 *
2575 * @param zclient Zclient used to connect to table manager (zebra)
2576 * @param start First label of table
2577 * @param end Last label of chunk
2578 * @result 0 on success, -1 otherwise
2579 */
2580int tm_release_table_chunk(struct zclient *zclient, uint32_t start,
2581 uint32_t end)
2582{
2583 struct stream *s;
2584
2585 if (zclient_debug)
2586 zlog_debug("Releasing Table Chunk");
2587
2588 if (zclient->sock < 0)
2589 return -1;
2590
2591 /* send request */
2592 s = zclient->obuf;
2593 stream_reset(s);
2594 zclient_create_header(s, ZEBRA_RELEASE_TABLE_CHUNK, VRF_DEFAULT);
2595
2596 /* start */
2597 stream_putl(s, start);
2598 /* end */
2599 stream_putl(s, end);
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
bad6b0e7
RW
2607int zebra_send_mpls_labels(struct zclient *zclient, int cmd,
2608 struct zapi_labels *zl)
2609{
2610 if (zapi_labels_encode(zclient->obuf, cmd, zl) < 0)
2611 return -1;
2612 return zclient_send_message(zclient);
2613}
2614
2615int zapi_labels_encode(struct stream *s, int cmd, struct zapi_labels *zl)
2616{
ea6b290b
RW
2617 struct zapi_nexthop_label *znh;
2618
bad6b0e7
RW
2619 stream_reset(s);
2620
2621 zclient_create_header(s, cmd, VRF_DEFAULT);
b3c49d0e 2622 stream_putc(s, zl->message);
bad6b0e7 2623 stream_putc(s, zl->type);
b3c49d0e
RW
2624 stream_putl(s, zl->local_label);
2625
2626 if (CHECK_FLAG(zl->message, ZAPI_LABELS_FTN)) {
2627 stream_putw(s, zl->route.prefix.family);
2628 stream_put_prefix(s, &zl->route.prefix);
2629 stream_putc(s, zl->route.type);
2630 stream_putw(s, zl->route.instance);
2631 }
2632
ea6b290b
RW
2633 if (zl->nexthop_num > MULTIPATH_NUM) {
2634 flog_err(
2635 EC_LIB_ZAPI_ENCODE,
2636 "%s: label %u: can't encode %u nexthops (maximum is %u)",
2637 __func__, zl->local_label, zl->nexthop_num,
2638 MULTIPATH_NUM);
2639 return -1;
2640 }
2641 stream_putw(s, zl->nexthop_num);
2642
2643 for (int i = 0; i < zl->nexthop_num; i++) {
2644 znh = &zl->nexthops[i];
2645
2646 stream_putc(s, znh->type);
2647 stream_putw(s, znh->family);
2648 switch (znh->family) {
2649 case AF_INET:
2650 stream_put_in_addr(s, &znh->address.ipv4);
2651 break;
2652 case AF_INET6:
2653 stream_write(s, (uint8_t *)&znh->address.ipv6, 16);
2654 break;
2655 default:
2656 break;
2657 }
2658 stream_putl(s, znh->ifindex);
2659 stream_putl(s, znh->label);
bad6b0e7 2660 }
bad6b0e7
RW
2661
2662 /* Put length at the first point of the stream. */
2663 stream_putw_at(s, 0, stream_get_endp(s));
2664
2665 return 0;
2666}
2667
2668int zapi_labels_decode(struct stream *s, struct zapi_labels *zl)
2669{
ea6b290b
RW
2670 struct zapi_nexthop_label *znh;
2671
bad6b0e7
RW
2672 memset(zl, 0, sizeof(*zl));
2673
2674 /* Get data. */
b3c49d0e 2675 STREAM_GETC(s, zl->message);
bad6b0e7 2676 STREAM_GETC(s, zl->type);
b3c49d0e 2677 STREAM_GETL(s, zl->local_label);
bad6b0e7 2678
b3c49d0e
RW
2679 if (CHECK_FLAG(zl->message, ZAPI_LABELS_FTN)) {
2680 size_t psize;
2681
2682 STREAM_GETW(s, zl->route.prefix.family);
2683 STREAM_GETC(s, zl->route.prefix.prefixlen);
2684
2685 psize = PSIZE(zl->route.prefix.prefixlen);
2686 switch (zl->route.prefix.family) {
2687 case AF_INET:
2688 if (zl->route.prefix.prefixlen > IPV4_MAX_BITLEN) {
2689 zlog_debug(
2690 "%s: Specified prefix length %d is greater than a v4 address can support",
2691 __PRETTY_FUNCTION__,
2692 zl->route.prefix.prefixlen);
2693 return -1;
2694 }
2695 STREAM_GET(&zl->route.prefix.u.prefix4.s_addr, s,
2696 psize);
2697 break;
2698 case AF_INET6:
2699 if (zl->route.prefix.prefixlen > IPV6_MAX_BITLEN) {
2700 zlog_debug(
2701 "%s: Specified prefix length %d is greater than a v6 address can support",
2702 __PRETTY_FUNCTION__,
2703 zl->route.prefix.prefixlen);
2704 return -1;
2705 }
2706 STREAM_GET(&zl->route.prefix.u.prefix6, s, psize);
2707 break;
2708 default:
2709 flog_err(EC_LIB_ZAPI_ENCODE,
2710 "%s: Specified family %u is not v4 or v6",
2711 __PRETTY_FUNCTION__, zl->route.prefix.family);
bad6b0e7
RW
2712 return -1;
2713 }
b3c49d0e
RW
2714
2715 STREAM_GETC(s, zl->route.type);
2716 STREAM_GETW(s, zl->route.instance);
2717 }
2718
ea6b290b 2719 STREAM_GETW(s, zl->nexthop_num);
b900b3c6
QY
2720
2721 if (zl->nexthop_num > MULTIPATH_NUM) {
2722 flog_warn(
2723 EC_LIB_ZAPI_ENCODE,
2724 "%s: Prefix %pFX has %d nexthops, but we can only use the first %d",
2725 __func__, &zl->route.prefix, zl->nexthop_num,
2726 MULTIPATH_NUM);
2727 }
2728
2729 zl->nexthop_num = MIN(MULTIPATH_NUM, zl->nexthop_num);
2730
ea6b290b
RW
2731 for (int i = 0; i < zl->nexthop_num; i++) {
2732 znh = &zl->nexthops[i];
2733
2734 STREAM_GETC(s, znh->type);
2735 STREAM_GETW(s, znh->family);
2736 switch (znh->family) {
2737 case AF_INET:
2738 STREAM_GET(&znh->address.ipv4.s_addr, s,
2739 IPV4_MAX_BYTELEN);
2740 break;
2741 case AF_INET6:
2742 STREAM_GET(&znh->address.ipv6, s, 16);
2743 break;
2744 default:
2745 break;
2746 }
2747 STREAM_GETL(s, znh->ifindex);
2748 STREAM_GETL(s, znh->label);
bad6b0e7 2749 }
bad6b0e7
RW
2750
2751 return 0;
2752stream_failure:
2753 return -1;
2754}
75fb51c1 2755
6833ae01 2756int zebra_send_pw(struct zclient *zclient, int command, struct zapi_pw *pw)
2757{
2758 struct stream *s;
2759
2760 /* Reset stream. */
2761 s = zclient->obuf;
2762 stream_reset(s);
2763
2764 zclient_create_header(s, command, VRF_DEFAULT);
2765 stream_write(s, pw->ifname, IF_NAMESIZE);
2766 stream_putl(s, pw->ifindex);
2767
2768 /* Put type */
2769 stream_putl(s, pw->type);
2770
2771 /* Put nexthop */
2772 stream_putl(s, pw->af);
2773 switch (pw->af) {
2774 case AF_INET:
2775 stream_put_in_addr(s, &pw->nexthop.ipv4);
2776 break;
2777 case AF_INET6:
d7c0a89a 2778 stream_write(s, (uint8_t *)&pw->nexthop.ipv6, 16);
6833ae01 2779 break;
2780 default:
1c50c1c0 2781 flog_err(EC_LIB_ZAPI_ENCODE, "%s: unknown af", __func__);
6833ae01 2782 return -1;
2783 }
2784
2785 /* Put labels */
2786 stream_putl(s, pw->local_label);
2787 stream_putl(s, pw->remote_label);
2788
2789 /* Put flags */
2790 stream_putc(s, pw->flags);
2791
2792 /* Protocol specific fields */
2793 stream_write(s, &pw->data, sizeof(union pw_protocol_fields));
2794
2795 /* Put length at the first point of the stream. */
2796 stream_putw_at(s, 0, stream_get_endp(s));
2797
2798 return zclient_send_message(zclient);
2799}
2800
2801/*
2802 * Receive PW status update from Zebra and send it to LDE process.
2803 */
121f9dee 2804void zebra_read_pw_status_update(ZAPI_CALLBACK_ARGS, struct zapi_pw_status *pw)
6833ae01 2805{
2806 struct stream *s;
2807
2808 memset(pw, 0, sizeof(struct zapi_pw_status));
2809 s = zclient->ibuf;
2810
2811 /* Get data. */
2812 stream_get(pw->ifname, s, IF_NAMESIZE);
2813 pw->ifindex = stream_getl(s);
2814 pw->status = stream_getl(s);
2815}
2816
121f9dee 2817static void zclient_capability_decode(ZAPI_CALLBACK_ARGS)
09924cff
DS
2818{
2819 struct zclient_capabilities cap;
2820 struct stream *s = zclient->ibuf;
bb6b7f79 2821 int vrf_backend;
09924cff
DS
2822 uint8_t mpls_enabled;
2823
bb6b7f79
RW
2824 STREAM_GETL(s, vrf_backend);
2825 vrf_configure_backend(vrf_backend);
2826
09924cff
DS
2827 memset(&cap, 0, sizeof(cap));
2828 STREAM_GETC(s, mpls_enabled);
2829 cap.mpls_enabled = !!mpls_enabled;
2830 STREAM_GETL(s, cap.ecmp);
02c0866d 2831 STREAM_GETC(s, cap.role);
09924cff
DS
2832
2833 if (zclient->zebra_capabilities)
2834 (*zclient->zebra_capabilities)(&cap);
2835
2836stream_failure:
2837 return;
2838}
2839
36b5b98f
SK
2840void zclient_send_mlag_register(struct zclient *client, uint32_t bit_map)
2841{
2842 struct stream *s;
2843
2844 s = client->obuf;
2845 stream_reset(s);
2846
2847 zclient_create_header(s, ZEBRA_MLAG_CLIENT_REGISTER, VRF_DEFAULT);
2848 stream_putl(s, bit_map);
2849
2850 stream_putw_at(s, 0, stream_get_endp(s));
2851 zclient_send_message(client);
2852}
2853
2854void zclient_send_mlag_deregister(struct zclient *client)
2855{
2856 zebra_message_send(client, ZEBRA_MLAG_CLIENT_UNREGISTER, VRF_DEFAULT);
2857}
2858
2859void zclient_send_mlag_data(struct zclient *client, struct stream *client_s)
2860{
2861 struct stream *s;
2862
2863 s = client->obuf;
2864 stream_reset(s);
2865
2866 zclient_create_header(s, ZEBRA_MLAG_FORWARD_MSG, VRF_DEFAULT);
2867 stream_put(s, client_s->data, client_s->endp);
2868
2869 stream_putw_at(s, 0, stream_get_endp(s));
2870 zclient_send_message(client);
2871}
2872
46c2687c
SK
2873static void zclient_mlag_process_up(ZAPI_CALLBACK_ARGS)
2874{
2875 if (zclient->mlag_process_up)
2876 (*zclient->mlag_process_up)();
2877}
2878
2879static void zclient_mlag_process_down(ZAPI_CALLBACK_ARGS)
2880{
2881 if (zclient->mlag_process_down)
2882 (*zclient->mlag_process_down)();
2883}
2884
2885static void zclient_mlag_handle_msg(ZAPI_CALLBACK_ARGS)
2886{
2887 if (zclient->mlag_handle_msg)
2888 (*zclient->mlag_handle_msg)(zclient->ibuf, length);
2889}
2890
718e3744 2891/* Zebra client message read function. */
d62a17ae 2892static int zclient_read(struct thread *thread)
718e3744 2893{
d62a17ae 2894 size_t already;
2895 uint16_t length, command;
2896 uint8_t marker, version;
2897 vrf_id_t vrf_id;
2898 struct zclient *zclient;
2899
2900 /* Get socket to zebra. */
2901 zclient = THREAD_ARG(thread);
2902 zclient->t_read = NULL;
2903
2904 /* Read zebra header (if we don't have it already). */
2905 if ((already = stream_get_endp(zclient->ibuf)) < ZEBRA_HEADER_SIZE) {
2906 ssize_t nbyte;
2907 if (((nbyte = stream_read_try(zclient->ibuf, zclient->sock,
2908 ZEBRA_HEADER_SIZE - already))
2909 == 0)
2910 || (nbyte == -1)) {
2911 if (zclient_debug)
2912 zlog_debug(
2913 "zclient connection closed socket [%d].",
2914 zclient->sock);
2915 return zclient_failed(zclient);
2916 }
2917 if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE - already)) {
2918 /* Try again later. */
2919 zclient_event(ZCLIENT_READ, zclient);
2920 return 0;
2921 }
2922 already = ZEBRA_HEADER_SIZE;
634f9ea2 2923 }
d62a17ae 2924
2925 /* Reset to read from the beginning of the incoming packet. */
2926 stream_set_getp(zclient->ibuf, 0);
2927
2928 /* Fetch header values. */
2929 length = stream_getw(zclient->ibuf);
2930 marker = stream_getc(zclient->ibuf);
2931 version = stream_getc(zclient->ibuf);
a9ff90c4 2932 vrf_id = stream_getl(zclient->ibuf);
d62a17ae 2933 command = stream_getw(zclient->ibuf);
2934
2935 if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION) {
1c50c1c0
QY
2936 flog_err(
2937 EC_LIB_ZAPI_MISSMATCH,
2938 "%s: socket %d version mismatch, marker %d, version %d",
2939 __func__, zclient->sock, marker, version);
d62a17ae 2940 return zclient_failed(zclient);
634f9ea2 2941 }
d62a17ae 2942
2943 if (length < ZEBRA_HEADER_SIZE) {
450971aa 2944 flog_err(EC_LIB_ZAPI_MISSMATCH,
1c50c1c0
QY
2945 "%s: socket %d message length %u is less than %d ",
2946 __func__, zclient->sock, length, ZEBRA_HEADER_SIZE);
d62a17ae 2947 return zclient_failed(zclient);
634f9ea2 2948 }
d62a17ae 2949
2950 /* Length check. */
2951 if (length > STREAM_SIZE(zclient->ibuf)) {
2952 struct stream *ns;
ade6974d 2953 flog_err(
450971aa 2954 EC_LIB_ZAPI_ENCODE,
ade6974d
QY
2955 "%s: message size %u exceeds buffer size %lu, expanding...",
2956 __func__, length,
2957 (unsigned long)STREAM_SIZE(zclient->ibuf));
d62a17ae 2958 ns = stream_new(length);
2959 stream_copy(ns, zclient->ibuf);
2960 stream_free(zclient->ibuf);
2961 zclient->ibuf = ns;
2962 }
2963
2964 /* Read rest of zebra packet. */
2965 if (already < length) {
2966 ssize_t nbyte;
2967 if (((nbyte = stream_read_try(zclient->ibuf, zclient->sock,
2968 length - already))
2969 == 0)
2970 || (nbyte == -1)) {
2971 if (zclient_debug)
2972 zlog_debug(
2973 "zclient connection closed socket [%d].",
2974 zclient->sock);
2975 return zclient_failed(zclient);
2976 }
2977 if (nbyte != (ssize_t)(length - already)) {
2978 /* Try again later. */
2979 zclient_event(ZCLIENT_READ, zclient);
2980 return 0;
2981 }
2982 }
2983
2984 length -= ZEBRA_HEADER_SIZE;
2985
2986 if (zclient_debug)
cdc6ed90
DS
2987 zlog_debug("zclient 0x%p command %s VRF %u",
2988 (void *)zclient, zserv_command_string(command),
2989 vrf_id);
d62a17ae 2990
2991 switch (command) {
09924cff
DS
2992 case ZEBRA_CAPABILITIES:
2993 zclient_capability_decode(command, zclient, length, vrf_id);
2994 break;
d62a17ae 2995 case ZEBRA_ROUTER_ID_UPDATE:
2996 if (zclient->router_id_update)
2997 (*zclient->router_id_update)(command, zclient, length,
2998 vrf_id);
2999 break;
3000 case ZEBRA_VRF_ADD:
3001 zclient_vrf_add(zclient, vrf_id);
3002 break;
3003 case ZEBRA_VRF_DELETE:
3004 zclient_vrf_delete(zclient, vrf_id);
3005 break;
3006 case ZEBRA_INTERFACE_ADD:
ef7bd2a3 3007 zclient_interface_add(zclient, vrf_id);
d62a17ae 3008 break;
3009 case ZEBRA_INTERFACE_DELETE:
3c3c3252 3010 zclient_interface_delete(zclient, vrf_id);
d62a17ae 3011 break;
3012 case ZEBRA_INTERFACE_ADDRESS_ADD:
3013 if (zclient->interface_address_add)
3014 (*zclient->interface_address_add)(command, zclient,
3015 length, vrf_id);
3016 break;
3017 case ZEBRA_INTERFACE_ADDRESS_DELETE:
3018 if (zclient->interface_address_delete)
3019 (*zclient->interface_address_delete)(command, zclient,
3020 length, vrf_id);
3021 break;
3022 case ZEBRA_INTERFACE_BFD_DEST_UPDATE:
3023 if (zclient->interface_bfd_dest_update)
3024 (*zclient->interface_bfd_dest_update)(command, zclient,
3025 length, vrf_id);
3026 break;
3027 case ZEBRA_INTERFACE_NBR_ADDRESS_ADD:
3028 if (zclient->interface_nbr_address_add)
3029 (*zclient->interface_nbr_address_add)(command, zclient,
3030 length, vrf_id);
3031 break;
3032 case ZEBRA_INTERFACE_NBR_ADDRESS_DELETE:
3033 if (zclient->interface_nbr_address_delete)
3034 (*zclient->interface_nbr_address_delete)(
3035 command, zclient, length, vrf_id);
3036 break;
3037 case ZEBRA_INTERFACE_UP:
ddbf3e60 3038 zclient_interface_up(zclient, vrf_id);
d62a17ae 3039 break;
3040 case ZEBRA_INTERFACE_DOWN:
b0b69e59 3041 zclient_interface_down(zclient, vrf_id);
d62a17ae 3042 break;
3043 case ZEBRA_INTERFACE_VRF_UPDATE:
3044 if (zclient->interface_vrf_update)
3045 (*zclient->interface_vrf_update)(command, zclient,
3046 length, vrf_id);
3047 break;
3048 case ZEBRA_NEXTHOP_UPDATE:
3049 if (zclient_debug)
9165c5f5 3050 zlog_debug("zclient rcvd nexthop update");
d62a17ae 3051 if (zclient->nexthop_update)
3052 (*zclient->nexthop_update)(command, zclient, length,
3053 vrf_id);
3054 break;
3055 case ZEBRA_IMPORT_CHECK_UPDATE:
3056 if (zclient_debug)
9165c5f5 3057 zlog_debug("zclient rcvd import check update");
d62a17ae 3058 if (zclient->import_check_update)
3059 (*zclient->import_check_update)(command, zclient,
3060 length, vrf_id);
3061 break;
3062 case ZEBRA_BFD_DEST_REPLAY:
3063 if (zclient->bfd_dest_replay)
3064 (*zclient->bfd_dest_replay)(command, zclient, length,
3065 vrf_id);
3066 break;
74489921
RW
3067 case ZEBRA_REDISTRIBUTE_ROUTE_ADD:
3068 if (zclient->redistribute_route_add)
3069 (*zclient->redistribute_route_add)(command, zclient,
3070 length, vrf_id);
d62a17ae 3071 break;
74489921
RW
3072 case ZEBRA_REDISTRIBUTE_ROUTE_DEL:
3073 if (zclient->redistribute_route_del)
3074 (*zclient->redistribute_route_del)(command, zclient,
3075 length, vrf_id);
d62a17ae 3076 break;
3077 case ZEBRA_INTERFACE_LINK_PARAMS:
3078 if (zclient->interface_link_params)
3079 (*zclient->interface_link_params)(command, zclient,
edc12762 3080 length, vrf_id);
d62a17ae 3081 break;
3082 case ZEBRA_FEC_UPDATE:
3083 if (zclient_debug)
9165c5f5 3084 zlog_debug("zclient rcvd fec update");
d62a17ae 3085 if (zclient->fec_update)
3086 (*zclient->fec_update)(command, zclient, length);
3087 break;
50f74cf1 3088 case ZEBRA_LOCAL_ES_ADD:
3089 if (zclient->local_es_add)
3090 (*zclient->local_es_add)(command, zclient, length,
3091 vrf_id);
3092 break;
3093 case ZEBRA_LOCAL_ES_DEL:
3094 if (zclient->local_es_del)
3095 (*zclient->local_es_del)(command, zclient, length,
3096 vrf_id);
3097 break;
d62a17ae 3098 case ZEBRA_VNI_ADD:
3099 if (zclient->local_vni_add)
3100 (*zclient->local_vni_add)(command, zclient, length,
3101 vrf_id);
3102 break;
3103 case ZEBRA_VNI_DEL:
3104 if (zclient->local_vni_del)
3105 (*zclient->local_vni_del)(command, zclient, length,
3106 vrf_id);
3107 break;
b7cfce93
MK
3108 case ZEBRA_L3VNI_ADD:
3109 if (zclient->local_l3vni_add)
3110 (*zclient->local_l3vni_add)(command, zclient, length,
3111 vrf_id);
3112 break;
3113 case ZEBRA_L3VNI_DEL:
3114 if (zclient->local_l3vni_del)
3115 (*zclient->local_l3vni_del)(command, zclient, length,
3116 vrf_id);
3117 break;
d62a17ae 3118 case ZEBRA_MACIP_ADD:
3119 if (zclient->local_macip_add)
3120 (*zclient->local_macip_add)(command, zclient, length,
3121 vrf_id);
3122 break;
3123 case ZEBRA_MACIP_DEL:
3124 if (zclient->local_macip_del)
3125 (*zclient->local_macip_del)(command, zclient, length,
3126 vrf_id);
3127 break;
31310b25
MK
3128 case ZEBRA_IP_PREFIX_ROUTE_ADD:
3129 if (zclient->local_ip_prefix_add)
3130 (*zclient->local_ip_prefix_add)(command, zclient,
3131 length, vrf_id);
3132 break;
3133 case ZEBRA_IP_PREFIX_ROUTE_DEL:
3134 if (zclient->local_ip_prefix_del)
3135 (*zclient->local_ip_prefix_del)(command, zclient,
3136 length, vrf_id);
3137 break;
6833ae01 3138 case ZEBRA_PW_STATUS_UPDATE:
3139 if (zclient->pw_status_update)
3140 (*zclient->pw_status_update)(command, zclient, length,
3141 vrf_id);
3142 break;
7ea7b86e 3143 case ZEBRA_ROUTE_NOTIFY_OWNER:
28b11f81
DS
3144 if (zclient->route_notify_owner)
3145 (*zclient->route_notify_owner)(command, zclient, length,
3146 vrf_id);
7ea7b86e 3147 break;
b6c5d343
DS
3148 case ZEBRA_RULE_NOTIFY_OWNER:
3149 if (zclient->rule_notify_owner)
3150 (*zclient->rule_notify_owner)(command, zclient, length,
3151 vrf_id);
955bfd98
PZ
3152 break;
3153 case ZEBRA_GET_LABEL_CHUNK:
3154 if (zclient->label_chunk)
3155 (*zclient->label_chunk)(command, zclient, length,
0313523d 3156 vrf_id);
955bfd98 3157 break;
c16a0a62
PG
3158 case ZEBRA_IPSET_NOTIFY_OWNER:
3159 if (zclient->ipset_notify_owner)
3160 (*zclient->ipset_notify_owner)(command, zclient, length,
3161 vrf_id);
3162 break;
3163 case ZEBRA_IPSET_ENTRY_NOTIFY_OWNER:
3164 if (zclient->ipset_entry_notify_owner)
3165 (*zclient->ipset_entry_notify_owner)(command,
3166 zclient, length,
3167 vrf_id);
3168 break;
3169 case ZEBRA_IPTABLE_NOTIFY_OWNER:
3170 if (zclient->iptable_notify_owner)
3171 (*zclient->iptable_notify_owner)(command,
3172 zclient, length,
3173 vrf_id);
4ab3321f
AK
3174 break;
3175 case ZEBRA_VXLAN_SG_ADD:
3176 if (zclient->vxlan_sg_add)
3177 (*zclient->vxlan_sg_add)(command, zclient, length,
3178 vrf_id);
3179 break;
3180 case ZEBRA_VXLAN_SG_DEL:
3181 if (zclient->vxlan_sg_del)
3182 (*zclient->vxlan_sg_del)(command, zclient, length,
3183 vrf_id);
3184 break;
46c2687c
SK
3185 case ZEBRA_MLAG_PROCESS_UP:
3186 zclient_mlag_process_up(command, zclient, length, vrf_id);
3187 break;
3188 case ZEBRA_MLAG_PROCESS_DOWN:
3189 zclient_mlag_process_down(command, zclient, length, vrf_id);
3190 break;
3191 case ZEBRA_MLAG_FORWARD_MSG:
3192 zclient_mlag_handle_msg(command, zclient, length, vrf_id);
3193 break;
9ab0b2a3
SW
3194 case ZEBRA_ERROR:
3195 zclient_handle_error(command, zclient, length, vrf_id);
d62a17ae 3196 default:
3197 break;
634f9ea2 3198 }
d62a17ae 3199
3200 if (zclient->sock < 0)
3201 /* Connection was closed during packet processing. */
3202 return -1;
3203
3204 /* Register read thread. */
3205 stream_reset(zclient->ibuf);
3206 zclient_event(ZCLIENT_READ, zclient);
3207
3208 return 0;
718e3744 3209}
3210
d62a17ae 3211void zclient_redistribute(int command, struct zclient *zclient, afi_t afi,
d7c0a89a 3212 int type, unsigned short instance, vrf_id_t vrf_id)
718e3744 3213{
718e3744 3214
d62a17ae 3215 if (instance) {
3216 if (command == ZEBRA_REDISTRIBUTE_ADD) {
3217 if (redist_check_instance(
3218 &zclient->mi_redist[afi][type], instance))
3219 return;
3220 redist_add_instance(&zclient->mi_redist[afi][type],
3221 instance);
3222 } else {
3223 if (!redist_check_instance(
3224 &zclient->mi_redist[afi][type], instance))
3225 return;
3226 redist_del_instance(&zclient->mi_redist[afi][type],
3227 instance);
3228 }
3229
3230 } else {
3231 if (command == ZEBRA_REDISTRIBUTE_ADD) {
3232 if (vrf_bitmap_check(zclient->redist[afi][type],
3233 vrf_id))
3234 return;
3235 vrf_bitmap_set(zclient->redist[afi][type], vrf_id);
3236 } else {
3237 if (!vrf_bitmap_check(zclient->redist[afi][type],
3238 vrf_id))
3239 return;
3240 vrf_bitmap_unset(zclient->redist[afi][type], vrf_id);
3241 }
3242 }
3243
3244 if (zclient->sock > 0)
3245 zebra_redistribute_send(command, zclient, afi, type, instance,
3246 vrf_id);
718e3744 3247}
3248
718e3744 3249
d62a17ae 3250void zclient_redistribute_default(int command, struct zclient *zclient,
49db7a7b 3251 afi_t afi, vrf_id_t vrf_id)
718e3744 3252{
718e3744 3253
d62a17ae 3254 if (command == ZEBRA_REDISTRIBUTE_DEFAULT_ADD) {
49db7a7b 3255 if (vrf_bitmap_check(zclient->default_information[afi], vrf_id))
d62a17ae 3256 return;
49db7a7b 3257 vrf_bitmap_set(zclient->default_information[afi], vrf_id);
d62a17ae 3258 } else {
49db7a7b
RW
3259 if (!vrf_bitmap_check(zclient->default_information[afi],
3260 vrf_id))
d62a17ae 3261 return;
49db7a7b 3262 vrf_bitmap_unset(zclient->default_information[afi], vrf_id);
d62a17ae 3263 }
3264
3265 if (zclient->sock > 0)
49db7a7b 3266 zebra_redistribute_default_send(command, zclient, afi, vrf_id);
718e3744 3267}
3268
d62a17ae 3269static void zclient_event(enum event event, struct zclient *zclient)
718e3744 3270{
d62a17ae 3271 switch (event) {
3272 case ZCLIENT_SCHEDULE:
3273 thread_add_event(zclient->master, zclient_connect, zclient, 0,
3274 &zclient->t_connect);
3275 break;
3276 case ZCLIENT_CONNECT:
3277 if (zclient_debug)
3278 zlog_debug(
3279 "zclient connect failures: %d schedule interval is now %d",
3280 zclient->fail, zclient->fail < 3 ? 10 : 60);
3281 thread_add_timer(zclient->master, zclient_connect, zclient,
3282 zclient->fail < 3 ? 10 : 60,
3283 &zclient->t_connect);
3284 break;
3285 case ZCLIENT_READ:
3286 zclient->t_read = NULL;
3287 thread_add_read(zclient->master, zclient_read, zclient,
3288 zclient->sock, &zclient->t_read);
3289 break;
3290 }
718e3744 3291}
b5114685 3292
e0ae31b8
DS
3293void zclient_interface_set_master(struct zclient *client,
3294 struct interface *master,
3295 struct interface *slave)
3296{
3297 struct stream *s;
3298
3299 s = client->obuf;
3300 stream_reset(s);
3301
a36898e7 3302 zclient_create_header(s, ZEBRA_INTERFACE_SET_MASTER, master->vrf_id);
e0ae31b8 3303
a36898e7 3304 stream_putl(s, master->vrf_id);
e0ae31b8 3305 stream_putl(s, master->ifindex);
a36898e7 3306 stream_putl(s, slave->vrf_id);
e0ae31b8
DS
3307 stream_putl(s, slave->ifindex);
3308
3309 stream_putw_at(s, 0, stream_get_endp(s));
3310 zclient_send_message(client);
3311}