]> git.proxmox.com Git - mirror_frr.git/blame - lib/zclient.c
Merge pull request #5793 from ton31337/fix/formatting_show_bgp_summary_failed
[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:
68a02e06
MS
914 case NEXTHOP_TYPE_IPV4_IFINDEX:
915 stream_put_in_addr(s, &api_nh->gate.ipv4);
916 stream_putl(s, api_nh->ifindex);
917 break;
918 case NEXTHOP_TYPE_IFINDEX:
919 stream_putl(s, api_nh->ifindex);
920 break;
921 case NEXTHOP_TYPE_IPV6:
68a02e06
MS
922 case NEXTHOP_TYPE_IPV6_IFINDEX:
923 stream_write(s, (uint8_t *)&api_nh->gate.ipv6,
924 16);
925 stream_putl(s, api_nh->ifindex);
926 break;
927 }
928
929 /* We only encode labels if we have >0 - we use
930 * the per-nexthop flag above to signal that the count
931 * is present in the payload.
932 */
933 if (api_nh->label_num > 0) {
934 stream_putc(s, api_nh->label_num);
935 stream_put(s, &api_nh->labels[0],
936 api_nh->label_num * sizeof(mpls_label_t));
937 }
938
bd054c1a
DS
939 if (api_nh->weight)
940 stream_putl(s, api_nh->weight);
941
68a02e06
MS
942 /* Router MAC for EVPN routes. */
943 if (CHECK_FLAG(api_flags, ZEBRA_FLAG_EVPN_ROUTE))
944 stream_put(s, &(api_nh->rmac),
945 sizeof(struct ethaddr));
946
947done:
948 return ret;
949}
950
d7c0a89a 951int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api)
0e51b4a3
RW
952{
953 struct zapi_nexthop *api_nh;
d62a17ae 954 int i;
955 int psize;
d62a17ae 956
d62a17ae 957 stream_reset(s);
d62a17ae 958 zclient_create_header(s, cmd, api->vrf_id);
959
e4081c0e
RW
960 if (api->type >= ZEBRA_ROUTE_MAX) {
961 flog_err(EC_LIB_ZAPI_ENCODE,
962 "%s: Specified route type (%u) is not a legal value\n",
963 __PRETTY_FUNCTION__, api->type);
964 return -1;
965 }
d62a17ae 966 stream_putc(s, api->type);
e4081c0e 967
d62a17ae 968 stream_putw(s, api->instance);
969 stream_putl(s, api->flags);
970 stream_putc(s, api->message);
e4081c0e
RW
971
972 if (api->safi < SAFI_UNICAST || api->safi >= SAFI_MAX) {
973 flog_err(EC_LIB_ZAPI_ENCODE,
974 "%s: Specified route SAFI (%u) is not a legal value\n",
975 __PRETTY_FUNCTION__, api->safi);
976 return -1;
977 }
832d0f56 978 stream_putc(s, api->safi);
d62a17ae 979
980 /* Put prefix information. */
0e51b4a3 981 stream_putc(s, api->prefix.family);
bb1b9c47
RW
982 psize = PSIZE(api->prefix.prefixlen);
983 stream_putc(s, api->prefix.prefixlen);
d7c0a89a 984 stream_write(s, (uint8_t *)&api->prefix.u.prefix, psize);
d62a17ae 985
986 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_SRCPFX)) {
bb1b9c47
RW
987 psize = PSIZE(api->src_prefix.prefixlen);
988 stream_putc(s, api->src_prefix.prefixlen);
d7c0a89a 989 stream_write(s, (uint8_t *)&api->src_prefix.prefix, psize);
d62a17ae 990 }
991
0e51b4a3 992 /* Nexthops. */
d62a17ae 993 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) {
bb1b9c47
RW
994 /* limit the number of nexthops if necessary */
995 if (api->nexthop_num > MULTIPATH_NUM) {
996 char buf[PREFIX2STR_BUFFER];
997
998 prefix2str(&api->prefix, buf, sizeof(buf));
ade6974d 999 flog_err(
450971aa 1000 EC_LIB_ZAPI_ENCODE,
ade6974d
QY
1001 "%s: prefix %s: can't encode %u nexthops (maximum is %u)",
1002 __func__, buf, api->nexthop_num, MULTIPATH_NUM);
a74e593b 1003 return -1;
bb1b9c47
RW
1004 }
1005
3c6e0bd4
SW
1006 zapi_nexthop_group_sort(api->nexthops, api->nexthop_num);
1007
b5f79651 1008 stream_putw(s, api->nexthop_num);
d62a17ae 1009
1010 for (i = 0; i < api->nexthop_num; i++) {
bb1b9c47
RW
1011 api_nh = &api->nexthops[i];
1012
52dd3aa4 1013 /* MPLS labels for BGP-LU or Segment Routing */
68a02e06
MS
1014 if (api_nh->label_num > MPLS_MAX_LABELS) {
1015 char buf[PREFIX2STR_BUFFER];
1016
1017 prefix2str(&api->prefix, buf, sizeof(buf));
1018
1019 flog_err(EC_LIB_ZAPI_ENCODE,
1020 "%s: prefix %s: can't encode %u labels (maximum is %u)",
1021 __func__, buf,
1022 api_nh->label_num,
1023 MPLS_MAX_LABELS);
1024 return -1;
52dd3aa4 1025 }
a317a9b9 1026
68a02e06
MS
1027 if (zapi_nexthop_encode(s, api_nh, api->flags) != 0)
1028 return -1;
d62a17ae 1029 }
1030 }
1031
0e51b4a3 1032 /* Attributes. */
d62a17ae 1033 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_DISTANCE))
1034 stream_putc(s, api->distance);
1035 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_METRIC))
1036 stream_putl(s, api->metric);
1037 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TAG))
1038 stream_putl(s, api->tag);
1039 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_MTU))
1040 stream_putl(s, api->mtu);
ba1849ef
DS
1041 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TABLEID))
1042 stream_putl(s, api->tableid);
d62a17ae 1043
1044 /* Put length at the first point of the stream. */
1045 stream_putw_at(s, 0, stream_get_endp(s));
1046
0e51b4a3
RW
1047 return 0;
1048}
1049
68a02e06
MS
1050/*
1051 * Decode a single zapi nexthop object
1052 */
1053static int zapi_nexthop_decode(struct stream *s, struct zapi_nexthop *api_nh,
1054 uint32_t api_flags)
1055{
1056 int ret = -1;
1057
1058 STREAM_GETL(s, api_nh->vrf_id);
1059 STREAM_GETC(s, api_nh->type);
1060
1061 /* Note that we're only using a single octet of flags */
1062 STREAM_GETC(s, api_nh->flags);
1063
1064 switch (api_nh->type) {
1065 case NEXTHOP_TYPE_BLACKHOLE:
1066 STREAM_GETC(s, api_nh->bh_type);
1067 break;
1068 case NEXTHOP_TYPE_IPV4:
68a02e06
MS
1069 case NEXTHOP_TYPE_IPV4_IFINDEX:
1070 STREAM_GET(&api_nh->gate.ipv4.s_addr, s,
1071 IPV4_MAX_BYTELEN);
1072 STREAM_GETL(s, api_nh->ifindex);
1073 break;
1074 case NEXTHOP_TYPE_IFINDEX:
1075 STREAM_GETL(s, api_nh->ifindex);
1076 break;
1077 case NEXTHOP_TYPE_IPV6:
68a02e06
MS
1078 case NEXTHOP_TYPE_IPV6_IFINDEX:
1079 STREAM_GET(&api_nh->gate.ipv6, s, 16);
1080 STREAM_GETL(s, api_nh->ifindex);
1081 break;
1082 }
1083
1084 /* MPLS labels for BGP-LU or Segment Routing */
1085 if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_LABEL)) {
1086 STREAM_GETC(s, api_nh->label_num);
1087 if (api_nh->label_num > MPLS_MAX_LABELS) {
1088 flog_err(
1089 EC_LIB_ZAPI_ENCODE,
1090 "%s: invalid number of MPLS labels (%u)",
1091 __func__, api_nh->label_num);
1092 return -1;
1093 }
1094
1095 STREAM_GET(&api_nh->labels[0], s,
1096 api_nh->label_num * sizeof(mpls_label_t));
1097 }
1098
bd054c1a
DS
1099 if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_WEIGHT))
1100 STREAM_GETL(s, api_nh->weight);
1101
68a02e06
MS
1102 /* Router MAC for EVPN routes. */
1103 if (CHECK_FLAG(api_flags, ZEBRA_FLAG_EVPN_ROUTE))
1104 STREAM_GET(&(api_nh->rmac), s,
1105 sizeof(struct ethaddr));
1106
1107 /* Success */
1108 ret = 0;
1109
1110stream_failure:
1111
1112 return ret;
1113}
1114
0e51b4a3
RW
1115int zapi_route_decode(struct stream *s, struct zapi_route *api)
1116{
1117 struct zapi_nexthop *api_nh;
1118 int i;
1119
1120 memset(api, 0, sizeof(*api));
1121
1122 /* Type, flags, message. */
ec93aa12 1123 STREAM_GETC(s, api->type);
e4081c0e 1124 if (api->type >= ZEBRA_ROUTE_MAX) {
450971aa 1125 flog_err(EC_LIB_ZAPI_ENCODE,
decbd929
DS
1126 "%s: Specified route type: %d is not a legal value\n",
1127 __PRETTY_FUNCTION__, api->type);
ec93aa12
DS
1128 return -1;
1129 }
1130
1131 STREAM_GETW(s, api->instance);
1132 STREAM_GETL(s, api->flags);
1133 STREAM_GETC(s, api->message);
832d0f56 1134 STREAM_GETC(s, api->safi);
e4081c0e
RW
1135 if (api->safi < SAFI_UNICAST || api->safi >= SAFI_MAX) {
1136 flog_err(EC_LIB_ZAPI_ENCODE,
1137 "%s: Specified route SAFI (%u) is not a legal value\n",
1138 __PRETTY_FUNCTION__, api->safi);
1139 return -1;
1140 }
0e51b4a3
RW
1141
1142 /* Prefix. */
ec93aa12
DS
1143 STREAM_GETC(s, api->prefix.family);
1144 STREAM_GETC(s, api->prefix.prefixlen);
0e51b4a3
RW
1145 switch (api->prefix.family) {
1146 case AF_INET:
ec93aa12 1147 if (api->prefix.prefixlen > IPV4_MAX_PREFIXLEN) {
ade6974d 1148 flog_err(
450971aa 1149 EC_LIB_ZAPI_ENCODE,
ade6974d
QY
1150 "%s: V4 prefixlen is %d which should not be more than 32",
1151 __PRETTY_FUNCTION__, api->prefix.prefixlen);
ec93aa12
DS
1152 return -1;
1153 }
0e51b4a3
RW
1154 break;
1155 case AF_INET6:
ec93aa12 1156 if (api->prefix.prefixlen > IPV6_MAX_PREFIXLEN) {
ade6974d 1157 flog_err(
450971aa 1158 EC_LIB_ZAPI_ENCODE,
ade6974d
QY
1159 "%s: v6 prefixlen is %d which should not be more than 128",
1160 __PRETTY_FUNCTION__, api->prefix.prefixlen);
ec93aa12
DS
1161 return -1;
1162 }
0e51b4a3 1163 break;
ec93aa12 1164 default:
450971aa 1165 flog_err(EC_LIB_ZAPI_ENCODE,
decbd929
DS
1166 "%s: Specified family %d is not v4 or v6",
1167 __PRETTY_FUNCTION__, api->prefix.family);
ec93aa12 1168 return -1;
0e51b4a3 1169 }
ec93aa12
DS
1170 STREAM_GET(&api->prefix.u.prefix, s, PSIZE(api->prefix.prefixlen));
1171
0e51b4a3
RW
1172 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_SRCPFX)) {
1173 api->src_prefix.family = AF_INET6;
ec93aa12
DS
1174 STREAM_GETC(s, api->src_prefix.prefixlen);
1175 if (api->src_prefix.prefixlen > IPV6_MAX_PREFIXLEN) {
ade6974d 1176 flog_err(
450971aa 1177 EC_LIB_ZAPI_ENCODE,
ade6974d
QY
1178 "%s: SRC Prefix prefixlen received: %d is too large",
1179 __PRETTY_FUNCTION__, api->src_prefix.prefixlen);
ec93aa12
DS
1180 return -1;
1181 }
1182 STREAM_GET(&api->src_prefix.prefix, s,
0e51b4a3
RW
1183 PSIZE(api->src_prefix.prefixlen));
1184
1185 if (api->prefix.family != AF_INET6
ec93aa12 1186 || api->src_prefix.prefixlen == 0) {
ade6974d 1187 flog_err(
450971aa 1188 EC_LIB_ZAPI_ENCODE,
ade6974d
QY
1189 "%s: SRC prefix specified in some manner that makes no sense",
1190 __PRETTY_FUNCTION__);
ec93aa12
DS
1191 return -1;
1192 }
0e51b4a3
RW
1193 }
1194
1195 /* Nexthops. */
1196 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) {
ec93aa12 1197 STREAM_GETW(s, api->nexthop_num);
0e51b4a3 1198 if (api->nexthop_num > MULTIPATH_NUM) {
450971aa 1199 flog_err(EC_LIB_ZAPI_ENCODE,
decbd929
DS
1200 "%s: invalid number of nexthops (%u)",
1201 __func__, api->nexthop_num);
0e51b4a3
RW
1202 return -1;
1203 }
1204
1205 for (i = 0; i < api->nexthop_num; i++) {
1206 api_nh = &api->nexthops[i];
1207
68a02e06
MS
1208 if (zapi_nexthop_decode(s, api_nh, api->flags) != 0)
1209 return -1;
0e51b4a3
RW
1210 }
1211 }
1212
1213 /* Attributes. */
1214 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_DISTANCE))
ec93aa12 1215 STREAM_GETC(s, api->distance);
0e51b4a3 1216 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_METRIC))
ec93aa12 1217 STREAM_GETL(s, api->metric);
0e51b4a3 1218 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TAG))
ec93aa12 1219 STREAM_GETL(s, api->tag);
0e51b4a3 1220 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_MTU))
ec93aa12 1221 STREAM_GETL(s, api->mtu);
ba1849ef
DS
1222 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TABLEID))
1223 STREAM_GETL(s, api->tableid);
0e51b4a3
RW
1224
1225 return 0;
6a2b0d9a
RW
1226stream_failure:
1227 return -1;
657cde12
DS
1228}
1229
0313523d
FR
1230static void zapi_encode_prefix(struct stream *s, struct prefix *p,
1231 uint8_t family)
0031a6bb
PG
1232{
1233 struct prefix any;
1234
1235 if (!p) {
1236 memset(&any, 0, sizeof(any));
1237 any.family = family;
1238 p = &any;
1239 }
1240
1241 stream_putc(s, p->family);
1242 stream_putc(s, p->prefixlen);
1243 stream_put(s, &p->u.prefix, prefix_blen(p));
1244}
1245
0313523d 1246int zapi_pbr_rule_encode(uint8_t cmd, struct stream *s, struct pbr_rule *zrule)
0031a6bb
PG
1247{
1248 stream_reset(s);
1249 zclient_create_header(s, cmd, zrule->vrf_id);
1250
1251 /*
1252 * We are sending one item at a time at the moment
1253 */
1254 stream_putl(s, 1);
1255
1256 stream_putl(s, zrule->seq);
1257 stream_putl(s, zrule->priority);
1258 stream_putl(s, zrule->unique);
1259
1260 zapi_encode_prefix(s, &(zrule->filter.src_ip),
1261 zrule->filter.src_ip.family);
0313523d 1262 stream_putw(s, zrule->filter.src_port); /* src port */
0031a6bb
PG
1263 zapi_encode_prefix(s, &(zrule->filter.dst_ip),
1264 zrule->filter.src_ip.family);
0313523d
FR
1265 stream_putw(s, zrule->filter.dst_port); /* dst port */
1266 stream_putw(s, zrule->filter.fwmark); /* fwmark */
0031a6bb
PG
1267
1268 stream_putl(s, zrule->action.table);
1269 stream_putl(s, zrule->ifindex);
1270
1271 /* Put length at the first point of the stream. */
1272 stream_putw_at(s, 0, stream_get_endp(s));
1273
1274 return 0;
1275}
1276
7ea7b86e 1277bool zapi_route_notify_decode(struct stream *s, struct prefix *p,
28610f7e 1278 uint32_t *tableid,
7ea7b86e
DS
1279 enum zapi_route_notify_owner *note)
1280{
7a1eb44b
DS
1281 uint32_t t;
1282
7ea7b86e
DS
1283 STREAM_GET(note, s, sizeof(*note));
1284
1285 STREAM_GETC(s, p->family);
1286 STREAM_GETC(s, p->prefixlen);
996c9314 1287 STREAM_GET(&p->u.prefix, s, prefix_blen(p));
7a1eb44b
DS
1288 STREAM_GETL(s, t);
1289
1290 *tableid = t;
7ea7b86e
DS
1291
1292 return true;
1293
1294stream_failure:
1295 return false;
1296}
1297
b6c5d343
DS
1298bool zapi_rule_notify_decode(struct stream *s, uint32_t *seqno,
1299 uint32_t *priority, uint32_t *unique,
1300 ifindex_t *ifindex,
1301 enum zapi_rule_notify_owner *note)
1302{
1303 uint32_t prio, seq, uni;
1304 ifindex_t ifi;
1305
1306 STREAM_GET(note, s, sizeof(*note));
1307
1308 STREAM_GETL(s, seq);
1309 STREAM_GETL(s, prio);
1310 STREAM_GETL(s, uni);
1311 STREAM_GETL(s, ifi);
1312
1313 if (zclient_debug)
0313523d
FR
1314 zlog_debug("%s: %u %u %u %u", __PRETTY_FUNCTION__, seq, prio,
1315 uni, ifi);
b6c5d343
DS
1316 *seqno = seq;
1317 *priority = prio;
1318 *unique = uni;
1319 *ifindex = ifi;
1320
1321 return true;
1322
1323stream_failure:
1324 return false;
1325}
1326
0313523d
FR
1327bool zapi_ipset_notify_decode(struct stream *s, uint32_t *unique,
1328 enum zapi_ipset_notify_owner *note)
425bdd6b
PG
1329{
1330 uint32_t uni;
1331
1332 STREAM_GET(note, s, sizeof(*note));
1333
1334 STREAM_GETL(s, uni);
1335
1336 if (zclient_debug)
1337 zlog_debug("%s: %u", __PRETTY_FUNCTION__, uni);
1338 *unique = uni;
1339
1340 return true;
1341
1342stream_failure:
1343 return false;
1344}
1345
0313523d
FR
1346bool zapi_ipset_entry_notify_decode(struct stream *s, uint32_t *unique,
1347 char *ipset_name,
1348 enum zapi_ipset_entry_notify_owner *note)
425bdd6b
PG
1349{
1350 uint32_t uni;
1351
1352 STREAM_GET(note, s, sizeof(*note));
1353
1354 STREAM_GETL(s, uni);
1355
0313523d 1356 STREAM_GET(ipset_name, s, ZEBRA_IPSET_NAME_SIZE);
425bdd6b
PG
1357
1358 if (zclient_debug)
1359 zlog_debug("%s: %u", __PRETTY_FUNCTION__, uni);
1360 *unique = uni;
1361
1362 return true;
1363
1364stream_failure:
1365 return false;
1366}
1367
c16a0a62
PG
1368bool zapi_iptable_notify_decode(struct stream *s,
1369 uint32_t *unique,
1370 enum zapi_iptable_notify_owner *note)
1371{
1372 uint32_t uni;
1373
1374 STREAM_GET(note, s, sizeof(*note));
1375
1376 STREAM_GETL(s, uni);
1377
1378 if (zclient_debug)
1379 zlog_debug("%s: %u", __PRETTY_FUNCTION__, uni);
1380 *unique = uni;
1381
1382 return true;
1383
1384stream_failure:
1385 return false;
1386}
1387
4a749e2c
DS
1388struct nexthop *nexthop_from_zapi_nexthop(struct zapi_nexthop *znh)
1389{
1390 struct nexthop *n = nexthop_new();
1391
1392 n->type = znh->type;
4a7371e9 1393 n->vrf_id = znh->vrf_id;
4a749e2c
DS
1394 n->ifindex = znh->ifindex;
1395 n->gate = znh->gate;
1396
1397 /*
960035b2 1398 * This function currently handles labels
4a749e2c 1399 */
960035b2
PZ
1400 if (znh->label_num) {
1401 nexthop_add_labels(n, ZEBRA_LSP_NONE, znh->label_num,
0313523d 1402 znh->labels);
960035b2 1403 }
4a749e2c
DS
1404
1405 return n;
1406}
1407
68a02e06
MS
1408/*
1409 * Convert nexthop to zapi nexthop
1410 */
1411int zapi_nexthop_from_nexthop(struct zapi_nexthop *znh,
1412 const struct nexthop *nh)
1413{
1414 int i;
1415
1416 memset(znh, 0, sizeof(*znh));
1417
1418 znh->type = nh->type;
1419 znh->vrf_id = nh->vrf_id;
1420 znh->ifindex = nh->ifindex;
1421 znh->gate = nh->gate;
1422
1423 if (nh->nh_label && (nh->nh_label->num_labels > 0)) {
1424 for (i = 0; i < nh->nh_label->num_labels; i++)
1425 znh->labels[i] = nh->nh_label->label[i];
1426
1427 znh->label_num = i;
1428 SET_FLAG(znh->flags, ZAPI_NEXTHOP_FLAG_LABEL);
1429 }
1430
1431 return 0;
1432}
1433
1434/*
1435 * Decode the nexthop-tracking update message
1436 */
4a749e2c
DS
1437bool zapi_nexthop_update_decode(struct stream *s, struct zapi_route *nhr)
1438{
1439 uint32_t i;
1440
1441 memset(nhr, 0, sizeof(*nhr));
1442
1443 STREAM_GETW(s, nhr->prefix.family);
1444 STREAM_GETC(s, nhr->prefix.prefixlen);
996c9314 1445 switch (nhr->prefix.family) {
4a749e2c
DS
1446 case AF_INET:
1447 STREAM_GET(&nhr->prefix.u.prefix4.s_addr, s, IPV4_MAX_BYTELEN);
1448 break;
1449 case AF_INET6:
1450 STREAM_GET(&nhr->prefix.u.prefix6, s, IPV6_MAX_BYTELEN);
1451 break;
1452 default:
1453 break;
1454 }
1455
05dd5aaf
DS
1456 STREAM_GETC(s, nhr->type);
1457 STREAM_GETW(s, nhr->instance);
4a749e2c
DS
1458 STREAM_GETC(s, nhr->distance);
1459 STREAM_GETL(s, nhr->metric);
1460 STREAM_GETC(s, nhr->nexthop_num);
1461
996c9314 1462 for (i = 0; i < nhr->nexthop_num; i++) {
68a02e06
MS
1463 if (zapi_nexthop_decode(s, &(nhr->nexthops[i]), 0) != 0)
1464 return -1;
4a749e2c
DS
1465 }
1466
1467 return true;
1468stream_failure:
1469 return false;
1470}
1471
9ab0b2a3
SW
1472bool zapi_error_decode(struct stream *s, enum zebra_error_types *error)
1473{
1474 memset(error, 0, sizeof(*error));
1475
1476 STREAM_GET(error, s, sizeof(*error));
1477
1478 if (zclient_debug)
1479 zlog_debug("%s: type: %s", __func__,
1480 zebra_error_type2str(*error));
1481
1482 return true;
1483stream_failure:
1484 return false;
1485}
1486
d62a17ae 1487/*
0a589359 1488 * send a ZEBRA_REDISTRIBUTE_ADD or ZEBRA_REDISTRIBUTE_DELETE
1489 * for the route type (ZEBRA_ROUTE_KERNEL etc.). The zebra server will
d62a17ae 1490 * then set/unset redist[type] in the client handle (a struct zserv) for the
0a589359 1491 * sending client
1492 */
d62a17ae 1493int zebra_redistribute_send(int command, struct zclient *zclient, afi_t afi,
d7c0a89a 1494 int type, unsigned short instance, vrf_id_t vrf_id)
718e3744 1495{
d62a17ae 1496 struct stream *s;
1497
1498 s = zclient->obuf;
1499 stream_reset(s);
1500
1501 zclient_create_header(s, command, vrf_id);
1502 stream_putc(s, afi);
1503 stream_putc(s, type);
1504 stream_putw(s, instance);
1505
1506 stream_putw_at(s, 0, stream_get_endp(s));
1507
1508 return zclient_send_message(zclient);
718e3744 1509}
1510
49db7a7b
RW
1511int zebra_redistribute_default_send(int command, struct zclient *zclient,
1512 afi_t afi, vrf_id_t vrf_id)
1513{
1514 struct stream *s;
1515
1516 s = zclient->obuf;
1517 stream_reset(s);
1518
1519 zclient_create_header(s, command, vrf_id);
1520 stream_putc(s, afi);
1521
1522 stream_putw_at(s, 0, stream_get_endp(s));
1523
1524 return zclient_send_message(zclient);
1525}
1526
d9178828 1527/* Get prefix in ZServ format; family should be filled in on prefix */
d62a17ae 1528static void zclient_stream_get_prefix(struct stream *s, struct prefix *p)
d9178828 1529{
d62a17ae 1530 size_t plen = prefix_blen(p);
d7c0a89a 1531 uint8_t c;
d62a17ae 1532 p->prefixlen = 0;
1533
1534 if (plen == 0)
1535 return;
1536
1537 stream_get(&p->u.prefix, s, plen);
ec93aa12 1538 STREAM_GETC(s, c);
d62a17ae 1539 p->prefixlen = MIN(plen * 8, c);
ec93aa12
DS
1540
1541stream_failure:
1542 return;
d9178828
PJ
1543}
1544
18a6dce6 1545/* Router-id update from zebra daemon. */
d62a17ae 1546void zebra_router_id_update_read(struct stream *s, struct prefix *rid)
18a6dce6 1547{
d62a17ae 1548 /* Fetch interface address. */
ec93aa12 1549 STREAM_GETC(s, rid->family);
d62a17ae 1550
1551 zclient_stream_get_prefix(s, rid);
ec93aa12
DS
1552
1553stream_failure:
1554 return;
18a6dce6 1555}
1556
718e3744 1557/* Interface addition from zebra daemon. */
d62a17ae 1558/*
0a589359 1559 * The format of the message sent with type ZEBRA_INTERFACE_ADD or
1560 * ZEBRA_INTERFACE_DELETE from zebra to the client is:
1561 * 0 1 2 3
1562 * 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 1563 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1564 * | ifname |
1565 * | |
1566 * | |
1567 * | |
1568 * | |
1569 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee
OD
1570 * | ifindex |
1571 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1572 * | status |
0a589359 1573 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee 1574 * | if_flags |
c77d4546 1575 * | |
0a589359 1576 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee
OD
1577 * | metric |
1578 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2d7f0d76
DS
1579 * | speed |
1580 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee
OD
1581 * | ifmtu |
1582 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1583 * | ifmtu6 |
1584 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1585 * | bandwidth |
1586 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
53e60e5c
QY
1587 * | parent ifindex |
1588 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee 1589 * | Link Layer Type |
0a589359 1590 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee 1591 * | Harware Address Length |
0a589359 1592 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee
OD
1593 * | Hardware Address if HW lenght different from 0 |
1594 * | ... max INTERFACE_HWADDR_MAX |
0a589359 1595 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee 1596 * | Link_params? | Whether a link-params follows: 1 or 0.
0a589359 1597 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee
OD
1598 * | Link_params 0 or 1 INTERFACE_LINK_PARAMS_SIZE sized |
1599 * | .... (struct if_link_params). |
0a589359 1600 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1601 */
1602
d62a17ae 1603static void zclient_vrf_add(struct zclient *zclient, vrf_id_t vrf_id)
1892f15e 1604{
d62a17ae 1605 struct vrf *vrf;
1606 char vrfname_tmp[VRF_NAMSIZ];
1607 struct vrf_data data;
1892f15e 1608
d62a17ae 1609 stream_get(&data, zclient->ibuf, sizeof(struct vrf_data));
1610 /* Read interface name. */
1611 stream_get(vrfname_tmp, zclient->ibuf, VRF_NAMSIZ);
1892f15e 1612
d62a17ae 1613 /* Lookup/create vrf by vrf_id. */
1614 vrf = vrf_get(vrf_id, vrfname_tmp);
4691b65a
PG
1615 vrf->data.l.table_id = data.l.table_id;
1616 memcpy(vrf->data.l.netns_name, data.l.netns_name, NS_NAMSIZ);
4931a365
PG
1617 /* overwrite default vrf */
1618 if (vrf_id == VRF_DEFAULT)
4fe52e76 1619 vrf_set_default_name(vrfname_tmp, false);
d62a17ae 1620 vrf_enable(vrf);
1892f15e
DS
1621}
1622
d62a17ae 1623static void zclient_vrf_delete(struct zclient *zclient, vrf_id_t vrf_id)
1892f15e 1624{
d62a17ae 1625 struct vrf *vrf;
1892f15e 1626
d62a17ae 1627 /* Lookup vrf by vrf_id. */
1628 vrf = vrf_lookup_by_id(vrf_id);
1892f15e 1629
d62a17ae 1630 /*
1631 * If a routing protocol doesn't know about a
1632 * vrf that is about to be deleted. There is
1633 * no point in attempting to delete it.
1634 */
1635 if (!vrf)
1636 return;
beef1990 1637
d62a17ae 1638 vrf_delete(vrf);
1892f15e
DS
1639}
1640
ef7bd2a3 1641static void zclient_interface_add(struct zclient *zclient, vrf_id_t vrf_id)
718e3744 1642{
d62a17ae 1643 struct interface *ifp;
1644 char ifname_tmp[INTERFACE_NAMSIZ];
ef7bd2a3 1645 struct stream *s = zclient->ibuf;
718e3744 1646
d62a17ae 1647 /* Read interface name. */
1648 stream_get(ifname_tmp, s, INTERFACE_NAMSIZ);
718e3744 1649
d62a17ae 1650 /* Lookup/create interface by name. */
a36898e7 1651 ifp = if_get_by_name(ifname_tmp, vrf_id);
a41c4e1b 1652
d62a17ae 1653 zebra_interface_if_set_value(s, ifp);
718e3744 1654
ef7bd2a3 1655 if_new_via_zapi(ifp);
718e3744 1656}
1657
d62a17ae 1658/*
0a589359 1659 * Read interface up/down msg (ZEBRA_INTERFACE_UP/ZEBRA_INTERFACE_DOWN)
1660 * from zebra server. The format of this message is the same as
ef7bd2a3
DS
1661 * that sent for ZEBRA_INTERFACE_ADD/ZEBRA_INTERFACE_DELETE,
1662 * except that no sockaddr_dl is sent at the tail of the message.
0a589359 1663 */
d62a17ae 1664struct interface *zebra_interface_state_read(struct stream *s, vrf_id_t vrf_id)
718e3744 1665{
d62a17ae 1666 struct interface *ifp;
1667 char ifname_tmp[INTERFACE_NAMSIZ];
1668
1669 /* Read interface name. */
1670 stream_get(ifname_tmp, s, INTERFACE_NAMSIZ);
1671
1672 /* Lookup this by interface index. */
a36898e7 1673 ifp = if_lookup_by_name(ifname_tmp, vrf_id);
d62a17ae 1674 if (ifp == NULL) {
450971aa 1675 flog_err(EC_LIB_ZAPI_ENCODE,
decbd929
DS
1676 "INTERFACE_STATE: Cannot find IF %s in VRF %d",
1677 ifname_tmp, vrf_id);
d62a17ae 1678 return NULL;
1679 }
1680
1681 zebra_interface_if_set_value(s, ifp);
1682
1683 return ifp;
718e3744 1684}
1685
3c3c3252
DS
1686static void zclient_interface_delete(struct zclient *zclient, vrf_id_t vrf_id)
1687{
1688 struct interface *ifp;
1689 struct stream *s = zclient->ibuf;
1690
1691 ifp = zebra_interface_state_read(s, vrf_id);
1692
1693 if (ifp == NULL)
1694 return;
1695
1696 if_destroy_via_zapi(ifp);
1697 return;
1698}
1699
ddbf3e60
DS
1700static void zclient_interface_up(struct zclient *zclient, vrf_id_t vrf_id)
1701{
1702 struct interface *ifp;
1703 struct stream *s = zclient->ibuf;
1704
1705 ifp = zebra_interface_state_read(s, vrf_id);
1706
1707 if (!ifp)
1708 return;
1709
1710 if_up_via_zapi(ifp);
1711}
1712
b0b69e59
DS
1713static void zclient_interface_down(struct zclient *zclient, vrf_id_t vrf_id)
1714{
1715 struct interface *ifp;
1716 struct stream *s = zclient->ibuf;
1717
1718 ifp = zebra_interface_state_read(s, vrf_id);
1719
1720 if (!ifp)
1721 return;
1722
1723 if_down_via_zapi(ifp);
1724}
1725
9ab0b2a3
SW
1726static void zclient_handle_error(ZAPI_CALLBACK_ARGS)
1727{
1728 enum zebra_error_types error;
1729 struct stream *s = zclient->ibuf;
1730
1731 zapi_error_decode(s, &error);
1732
1733 if (zclient->handle_error)
1734 (*zclient->handle_error)(error);
1735}
1736
d62a17ae 1737static void link_params_set_value(struct stream *s, struct if_link_params *iflp)
16f1b9ee
OD
1738{
1739
d62a17ae 1740 if (iflp == NULL)
1741 return;
1742
1743 iflp->lp_status = stream_getl(s);
1744 iflp->te_metric = stream_getl(s);
1745 iflp->max_bw = stream_getf(s);
1746 iflp->max_rsv_bw = stream_getf(s);
1747 uint32_t bwclassnum = stream_getl(s);
1748 {
1749 unsigned int i;
1750 for (i = 0; i < bwclassnum && i < MAX_CLASS_TYPE; i++)
1751 iflp->unrsv_bw[i] = stream_getf(s);
1752 if (i < bwclassnum)
1c50c1c0
QY
1753 flog_err(
1754 EC_LIB_ZAPI_MISSMATCH,
1755 "%s: received %d > %d (MAX_CLASS_TYPE) bw entries"
1756 " - outdated library?",
1757 __func__, bwclassnum, MAX_CLASS_TYPE);
d62a17ae 1758 }
1759 iflp->admin_grp = stream_getl(s);
1760 iflp->rmt_as = stream_getl(s);
1761 iflp->rmt_ip.s_addr = stream_get_ipv4(s);
1762
1763 iflp->av_delay = stream_getl(s);
1764 iflp->min_delay = stream_getl(s);
1765 iflp->max_delay = stream_getl(s);
1766 iflp->delay_var = stream_getl(s);
1767
1768 iflp->pkt_loss = stream_getf(s);
1769 iflp->res_bw = stream_getf(s);
1770 iflp->ava_bw = stream_getf(s);
1771 iflp->use_bw = stream_getf(s);
16f1b9ee
OD
1772}
1773
edc12762
RW
1774struct interface *zebra_interface_link_params_read(struct stream *s,
1775 vrf_id_t vrf_id)
16f1b9ee 1776{
d62a17ae 1777 struct if_link_params *iflp;
1778 ifindex_t ifindex;
c28e5b2a 1779
d62a17ae 1780 assert(s);
c28e5b2a 1781
d62a17ae 1782 ifindex = stream_getl(s);
16f1b9ee 1783
a36898e7 1784 struct interface *ifp = if_lookup_by_index(ifindex, vrf_id);
16f1b9ee 1785
d62a17ae 1786 if (ifp == NULL) {
450971aa 1787 flog_err(EC_LIB_ZAPI_ENCODE,
1c50c1c0
QY
1788 "%s: unknown ifindex %u, shouldn't happen", __func__,
1789 ifindex);
d62a17ae 1790 return NULL;
1791 }
16f1b9ee 1792
d62a17ae 1793 if ((iflp = if_link_params_get(ifp)) == NULL)
1794 return NULL;
16f1b9ee 1795
d62a17ae 1796 link_params_set_value(s, iflp);
16f1b9ee 1797
d62a17ae 1798 return ifp;
16f1b9ee
OD
1799}
1800
26f8f6fe
DS
1801static void zebra_interface_if_set_value(struct stream *s,
1802 struct interface *ifp)
16f1b9ee 1803{
d7c0a89a 1804 uint8_t link_params_status = 0;
98cbbaea 1805 ifindex_t old_ifindex;
d62a17ae 1806
98cbbaea 1807 old_ifindex = ifp->ifindex;
d62a17ae 1808 /* Read interface's index. */
ff880b78 1809 if_set_index(ifp, stream_getl(s));
d62a17ae 1810 ifp->status = stream_getc(s);
1811
1812 /* Read interface's value. */
1813 ifp->flags = stream_getq(s);
1814 ifp->ptm_enable = stream_getc(s);
1815 ifp->ptm_status = stream_getc(s);
1816 ifp->metric = stream_getl(s);
1817 ifp->speed = stream_getl(s);
1818 ifp->mtu = stream_getl(s);
1819 ifp->mtu6 = stream_getl(s);
1820 ifp->bandwidth = stream_getl(s);
53e60e5c 1821 ifp->link_ifindex = stream_getl(s);
d62a17ae 1822 ifp->ll_type = stream_getl(s);
1823 ifp->hw_addr_len = stream_getl(s);
1824 if (ifp->hw_addr_len)
1825 stream_get(ifp->hw_addr, s,
1826 MIN(ifp->hw_addr_len, INTERFACE_HWADDR_MAX));
1827
1828 /* Read Traffic Engineering status */
1829 link_params_status = stream_getc(s);
1830 /* Then, Traffic Engineering parameters if any */
1831 if (link_params_status) {
1832 struct if_link_params *iflp = if_link_params_get(ifp);
1833 link_params_set_value(s, iflp);
1834 }
98cbbaea
DS
1835
1836 nexthop_group_interface_state_change(ifp, old_ifindex);
16f1b9ee
OD
1837}
1838
d62a17ae 1839size_t zebra_interface_link_params_write(struct stream *s,
1840 struct interface *ifp)
16f1b9ee 1841{
d62a17ae 1842 size_t w;
1843 struct if_link_params *iflp;
1844 int i;
16f1b9ee 1845
d62a17ae 1846 if (s == NULL || ifp == NULL || ifp->link_params == NULL)
1847 return 0;
16f1b9ee 1848
d62a17ae 1849 iflp = ifp->link_params;
1850 w = 0;
16f1b9ee 1851
d62a17ae 1852 w += stream_putl(s, iflp->lp_status);
16f1b9ee 1853
d62a17ae 1854 w += stream_putl(s, iflp->te_metric);
1855 w += stream_putf(s, iflp->max_bw);
1856 w += stream_putf(s, iflp->max_rsv_bw);
16f1b9ee 1857
d62a17ae 1858 w += stream_putl(s, MAX_CLASS_TYPE);
1859 for (i = 0; i < MAX_CLASS_TYPE; i++)
1860 w += stream_putf(s, iflp->unrsv_bw[i]);
16f1b9ee 1861
d62a17ae 1862 w += stream_putl(s, iflp->admin_grp);
1863 w += stream_putl(s, iflp->rmt_as);
1864 w += stream_put_in_addr(s, &iflp->rmt_ip);
16f1b9ee 1865
d62a17ae 1866 w += stream_putl(s, iflp->av_delay);
1867 w += stream_putl(s, iflp->min_delay);
1868 w += stream_putl(s, iflp->max_delay);
1869 w += stream_putl(s, iflp->delay_var);
16f1b9ee 1870
d62a17ae 1871 w += stream_putf(s, iflp->pkt_loss);
1872 w += stream_putf(s, iflp->res_bw);
1873 w += stream_putf(s, iflp->ava_bw);
1874 w += stream_putf(s, iflp->use_bw);
16f1b9ee 1875
d62a17ae 1876 return w;
16f1b9ee
OD
1877}
1878
1879/*
0a589359 1880 * format of message for address additon is:
1881 * 0
1882 * 0 1 2 3 4 5 6 7
1883 * +-+-+-+-+-+-+-+-+
1884 * | type | ZEBRA_INTERFACE_ADDRESS_ADD or
1885 * +-+-+-+-+-+-+-+-+ ZEBRA_INTERFACE_ADDRES_DELETE
1886 * | |
1887 * + +
1888 * | ifindex |
1889 * + +
1890 * | |
1891 * + +
1892 * | |
1893 * +-+-+-+-+-+-+-+-+
1894 * | ifc_flags | flags for connected address
1895 * +-+-+-+-+-+-+-+-+
1896 * | addr_family |
1897 * +-+-+-+-+-+-+-+-+
1898 * | addr... |
1899 * : :
1900 * | |
1901 * +-+-+-+-+-+-+-+-+
1902 * | addr_len | len of addr. E.g., addr_len = 4 for ipv4 addrs.
1903 * +-+-+-+-+-+-+-+-+
1904 * | daddr.. |
1905 * : :
1906 * | |
1907 * +-+-+-+-+-+-+-+-+
0a589359 1908 */
1909
d62a17ae 1910static int memconstant(const void *s, int c, size_t n)
3fb9cd6e 1911{
d7c0a89a 1912 const uint8_t *p = s;
3fb9cd6e 1913
d62a17ae 1914 while (n-- > 0)
1915 if (*p++ != c)
1916 return 0;
1917 return 1;
3fb9cd6e 1918}
1919
d5a5c8f0 1920
d62a17ae 1921struct connected *zebra_interface_address_read(int type, struct stream *s,
1922 vrf_id_t vrf_id)
718e3744 1923{
d62a17ae 1924 ifindex_t ifindex;
1925 struct interface *ifp;
1926 struct connected *ifc;
1927 struct prefix p, d, *dp;
1928 int plen;
d7c0a89a 1929 uint8_t ifc_flags;
d62a17ae 1930
1931 memset(&p, 0, sizeof(p));
1932 memset(&d, 0, sizeof(d));
1933
1934 /* Get interface index. */
1935 ifindex = stream_getl(s);
1936
1937 /* Lookup index. */
1938 ifp = if_lookup_by_index(ifindex, vrf_id);
1939 if (ifp == NULL) {
450971aa 1940 flog_err(EC_LIB_ZAPI_ENCODE,
decbd929
DS
1941 "INTERFACE_ADDRESS_%s: Cannot find IF %u in VRF %d",
1942 (type == ZEBRA_INTERFACE_ADDRESS_ADD) ? "ADD" : "DEL",
1943 ifindex, vrf_id);
d62a17ae 1944 return NULL;
1945 }
1946
1947 /* Fetch flag. */
1948 ifc_flags = stream_getc(s);
1949
1950 /* Fetch interface address. */
1951 d.family = p.family = stream_getc(s);
1952 plen = prefix_blen(&d);
1953
1954 zclient_stream_get_prefix(s, &p);
1955
1956 /* Fetch destination address. */
1957 stream_get(&d.u.prefix, s, plen);
1958
1959 /* N.B. NULL destination pointers are encoded as all zeroes */
1960 dp = memconstant(&d.u.prefix, 0, plen) ? NULL : &d;
1961
1962 if (type == ZEBRA_INTERFACE_ADDRESS_ADD) {
1963 ifc = connected_lookup_prefix_exact(ifp, &p);
1964 if (!ifc) {
1965 /* N.B. NULL destination pointers are encoded as all
1966 * zeroes */
1967 ifc = connected_add_by_prefix(ifp, &p, dp);
1968 }
1969 if (ifc) {
1970 ifc->flags = ifc_flags;
1971 if (ifc->destination)
1972 ifc->destination->prefixlen =
1973 ifc->address->prefixlen;
1974 else if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_PEER)) {
1975 /* carp interfaces on OpenBSD with 0.0.0.0/0 as
1976 * "peer" */
1977 char buf[PREFIX_STRLEN];
ade6974d 1978 flog_err(
450971aa 1979 EC_LIB_ZAPI_ENCODE,
ade6974d
QY
1980 "warning: interface %s address %s with peer flag set, but no peer address!",
1981 ifp->name,
1982 prefix2str(ifc->address, buf,
1983 sizeof buf));
d62a17ae 1984 UNSET_FLAG(ifc->flags, ZEBRA_IFA_PEER);
1985 }
1986 }
1987 } else {
1988 assert(type == ZEBRA_INTERFACE_ADDRESS_DELETE);
1989 ifc = connected_delete_by_prefix(ifp, &p);
1990 }
1991
1992 return ifc;
718e3744 1993}
0a589359 1994
a80beece
DS
1995/*
1996 * format of message for neighbor connected address is:
1997 * 0
1998 * 0 1 2 3 4 5 6 7
1999 * +-+-+-+-+-+-+-+-+
2000 * | type | ZEBRA_INTERFACE_NBR_ADDRESS_ADD or
2001 * +-+-+-+-+-+-+-+-+ ZEBRA_INTERFACE_NBR_ADDRES_DELETE
2002 * | |
2003 * + +
2004 * | ifindex |
2005 * + +
2006 * | |
2007 * + +
2008 * | |
2009 * +-+-+-+-+-+-+-+-+
2010 * | addr_family |
2011 * +-+-+-+-+-+-+-+-+
2012 * | addr... |
2013 * : :
2014 * | |
2015 * +-+-+-+-+-+-+-+-+
2016 * | addr_len | len of addr.
2017 * +-+-+-+-+-+-+-+-+
2018 */
2019struct nbr_connected *
d62a17ae 2020zebra_interface_nbr_address_read(int type, struct stream *s, vrf_id_t vrf_id)
a80beece 2021{
d62a17ae 2022 unsigned int ifindex;
2023 struct interface *ifp;
2024 struct prefix p;
2025 struct nbr_connected *ifc;
2026
2027 /* Get interface index. */
2028 ifindex = stream_getl(s);
2029
2030 /* Lookup index. */
2031 ifp = if_lookup_by_index(ifindex, vrf_id);
2032 if (ifp == NULL) {
450971aa 2033 flog_err(EC_LIB_ZAPI_ENCODE,
decbd929
DS
2034 "INTERFACE_NBR_%s: Cannot find IF %u in VRF %d",
2035 (type == ZEBRA_INTERFACE_NBR_ADDRESS_ADD) ? "ADD"
ade6974d
QY
2036 : "DELETE",
2037 ifindex, vrf_id);
d62a17ae 2038 return NULL;
2039 }
2040
2041 p.family = stream_getc(s);
2042 stream_get(&p.u.prefix, s, prefix_blen(&p));
2043 p.prefixlen = stream_getc(s);
2044
2045 if (type == ZEBRA_INTERFACE_NBR_ADDRESS_ADD) {
2046 /* Currently only supporting P2P links, so any new RA source
2047 address is
2048 considered as the replacement of the previously learnt
2049 Link-Local address. */
2050 if (!(ifc = listnode_head(ifp->nbr_connected))) {
2051 ifc = nbr_connected_new();
2052 ifc->address = prefix_new();
2053 ifc->ifp = ifp;
2054 listnode_add(ifp->nbr_connected, ifc);
2055 }
2056
2057 prefix_copy(ifc->address, &p);
2058 } else {
2059 assert(type == ZEBRA_INTERFACE_NBR_ADDRESS_DELETE);
2060
2061 ifc = nbr_connected_check(ifp, &p);
2062 if (ifc)
2063 listnode_delete(ifp->nbr_connected, ifc);
2064 }
2065
2066 return ifc;
a80beece 2067}
6b0655a2 2068
d62a17ae 2069struct interface *zebra_interface_vrf_update_read(struct stream *s,
2070 vrf_id_t vrf_id,
2071 vrf_id_t *new_vrf_id)
c8e264b6 2072{
91d227b7 2073 char ifname[INTERFACE_NAMSIZ];
d62a17ae 2074 struct interface *ifp;
a9ff90c4 2075 vrf_id_t new_id;
d62a17ae 2076
91d227b7
RW
2077 /* Read interface name. */
2078 stream_get(ifname, s, INTERFACE_NAMSIZ);
d62a17ae 2079
2080 /* Lookup interface. */
a36898e7 2081 ifp = if_lookup_by_name(ifname, vrf_id);
d62a17ae 2082 if (ifp == NULL) {
450971aa 2083 flog_err(EC_LIB_ZAPI_ENCODE,
91d227b7
RW
2084 "INTERFACE_VRF_UPDATE: Cannot find IF %s in VRF %d",
2085 ifname, vrf_id);
d62a17ae 2086 return NULL;
2087 }
2088
2089 /* Fetch new VRF Id. */
66cd1bb3 2090 new_id = stream_getl(s);
d62a17ae 2091
2092 *new_vrf_id = new_id;
2093 return ifp;
c8e264b6 2094}
5c7ef8dc 2095
2096/* filter unwanted messages until the expected one arrives */
d62a17ae 2097static int zclient_read_sync_response(struct zclient *zclient,
d7c0a89a 2098 uint16_t expected_cmd)
5c7ef8dc 2099{
d62a17ae 2100 struct stream *s;
d7c0a89a
QY
2101 uint16_t size = -1;
2102 uint8_t marker;
2103 uint8_t version;
d62a17ae 2104 vrf_id_t vrf_id;
d7c0a89a 2105 uint16_t cmd;
d62a17ae 2106 fd_set readfds;
2107 int ret;
2108
2109 ret = 0;
2110 cmd = expected_cmd + 1;
2111 while (ret == 0 && cmd != expected_cmd) {
2112 s = zclient->ibuf;
2113 stream_reset(s);
2114
2115 /* wait until response arrives */
2116 FD_ZERO(&readfds);
2117 FD_SET(zclient->sock, &readfds);
2118 select(zclient->sock + 1, &readfds, NULL, NULL, NULL);
2119 if (!FD_ISSET(zclient->sock, &readfds))
2120 continue;
2121 /* read response */
2122 ret = zclient_read_header(s, zclient->sock, &size, &marker,
2123 &version, &vrf_id, &cmd);
2124 if (zclient_debug)
2125 zlog_debug("%s: Response (%d bytes) received", __func__,
2126 size);
2127 }
2128 if (ret != 0) {
1c50c1c0
QY
2129 flog_err(EC_LIB_ZAPI_ENCODE, "%s: Invalid Sync Message Reply",
2130 __func__);
d62a17ae 2131 return -1;
2132 }
2133
2134 return 0;
5c7ef8dc 2135}
fea12efb 2136/**
2137 * Connect to label manager in a syncronous way
2138 *
2139 * It first writes the request to zcient output buffer and then
2140 * immediately reads the answer from the input buffer.
2141 *
2142 * @param zclient Zclient used to connect to label manager (zebra)
f533be73 2143 * @param async Synchronous (0) or asynchronous (1) operation
fea12efb 2144 * @result Result of response
2145 */
f533be73 2146int lm_label_manager_connect(struct zclient *zclient, int async)
fea12efb 2147{
d62a17ae 2148 int ret;
2149 struct stream *s;
d7c0a89a 2150 uint8_t result;
f533be73 2151 uint16_t cmd = async ? ZEBRA_LABEL_MANAGER_CONNECT_ASYNC :
2152 ZEBRA_LABEL_MANAGER_CONNECT;
d62a17ae 2153
2154 if (zclient_debug)
35cbe02a 2155 zlog_debug("Connecting to Label Manager (LM)");
d62a17ae 2156
f533be73 2157 if (zclient->sock < 0) {
2158 zlog_debug("%s: invalid zclient socket", __func__);
d62a17ae 2159 return -1;
f533be73 2160 }
d62a17ae 2161
2162 /* send request */
2163 s = zclient->obuf;
2164 stream_reset(s);
f533be73 2165 zclient_create_header(s, cmd, VRF_DEFAULT);
d62a17ae 2166
2167 /* proto */
2168 stream_putc(s, zclient->redist_default);
2169 /* instance */
2170 stream_putw(s, zclient->instance);
2171
2172 /* Put length at the first point of the stream. */
2173 stream_putw_at(s, 0, stream_get_endp(s));
2174
2175 ret = writen(zclient->sock, s->data, stream_get_endp(s));
2176 if (ret < 0) {
450971aa 2177 flog_err(EC_LIB_ZAPI_SOCKET, "Can't write to zclient sock");
d62a17ae 2178 close(zclient->sock);
2179 zclient->sock = -1;
2180 return -1;
2181 }
2182 if (ret == 0) {
450971aa 2183 flog_err(EC_LIB_ZAPI_SOCKET, "Zclient sock closed");
d62a17ae 2184 close(zclient->sock);
2185 zclient->sock = -1;
2186 return -1;
2187 }
2188 if (zclient_debug)
35cbe02a 2189 zlog_debug("LM connect request sent (%d bytes)", ret);
d62a17ae 2190
f533be73 2191 if (async)
2192 return 0;
2193
d62a17ae 2194 /* read response */
f533be73 2195 if (zclient_read_sync_response(zclient, cmd)
d62a17ae 2196 != 0)
2197 return -1;
2198
d62a17ae 2199 s = zclient->ibuf;
5dffb0e9
FR
2200
2201 /* read instance and proto */
2202 uint8_t proto = stream_getc(s);
2203 uint16_t instance = stream_getw(s);
2204
2205 /* sanity */
2206 if (proto != zclient->redist_default)
1c50c1c0
QY
2207 flog_err(
2208 EC_LIB_ZAPI_ENCODE,
2209 "Wrong proto (%u) in LM connect response. Should be %u",
2210 proto, zclient->redist_default);
5dffb0e9 2211 if (instance != zclient->instance)
1c50c1c0
QY
2212 flog_err(
2213 EC_LIB_ZAPI_ENCODE,
2214 "Wrong instId (%u) in LM connect response. Should be %u",
2215 instance, zclient->instance);
5dffb0e9
FR
2216
2217 /* result code */
d62a17ae 2218 result = stream_getc(s);
2219 if (zclient_debug)
0313523d 2220 zlog_debug("LM connect-response received, result %u", result);
d62a17ae 2221
2222 return (int)result;
fea12efb 2223}
2224
955bfd98
PZ
2225/*
2226 * Asynchronous label chunk request
2227 *
2228 * @param zclient Zclient used to connect to label manager (zebra)
2229 * @param keep Avoid garbage collection
2230 * @param chunk_size Amount of labels requested
0e3b6a92 2231 * @param base Base for the label chunk. if MPLS_LABEL_BASE_ANY we do not care
955bfd98
PZ
2232 * @result 0 on success, -1 otherwise
2233 */
0313523d 2234int zclient_send_get_label_chunk(struct zclient *zclient, uint8_t keep,
0e3b6a92 2235 uint32_t chunk_size, uint32_t base)
955bfd98
PZ
2236{
2237 struct stream *s;
2238
2239 if (zclient_debug)
2240 zlog_debug("Getting Label Chunk");
2241
2242 if (zclient->sock < 0)
2243 return -1;
2244
2245 s = zclient->obuf;
2246 stream_reset(s);
2247
2248 zclient_create_header(s, ZEBRA_GET_LABEL_CHUNK, VRF_DEFAULT);
5dffb0e9
FR
2249 /* proto */
2250 stream_putc(s, zclient->redist_default);
2251 /* instance */
2252 stream_putw(s, zclient->instance);
955bfd98
PZ
2253 stream_putc(s, keep);
2254 stream_putl(s, chunk_size);
0e3b6a92 2255 stream_putl(s, base);
955bfd98
PZ
2256
2257 /* Put length at the first point of the stream. */
2258 stream_putw_at(s, 0, stream_get_endp(s));
2259
2260 return zclient_send_message(zclient);
2261}
2262
fea12efb 2263/**
2264 * Function to request a label chunk in a syncronous way
2265 *
2266 * It first writes the request to zlcient output buffer and then
2267 * immediately reads the answer from the input buffer.
2268 *
2269 * @param zclient Zclient used to connect to label manager (zebra)
2270 * @param keep Avoid garbage collection
2271 * @param chunk_size Amount of labels requested
2272 * @param start To write first assigned chunk label to
2273 * @param end To write last assigned chunk label to
2274 * @result 0 on success, -1 otherwise
2275 */
0e3b6a92 2276int lm_get_label_chunk(struct zclient *zclient, uint8_t keep, uint32_t base,
d62a17ae 2277 uint32_t chunk_size, uint32_t *start, uint32_t *end)
fea12efb 2278{
d62a17ae 2279 int ret;
2280 struct stream *s;
d7c0a89a 2281 uint8_t response_keep;
d62a17ae 2282
2283 if (zclient_debug)
2284 zlog_debug("Getting Label Chunk");
2285
2286 if (zclient->sock < 0)
2287 return -1;
2288
2289 /* send request */
2290 s = zclient->obuf;
2291 stream_reset(s);
2292 zclient_create_header(s, ZEBRA_GET_LABEL_CHUNK, VRF_DEFAULT);
5dffb0e9
FR
2293 /* proto */
2294 stream_putc(s, zclient->redist_default);
2295 /* instance */
2296 stream_putw(s, zclient->instance);
d62a17ae 2297 /* keep */
2298 stream_putc(s, keep);
2299 /* chunk size */
2300 stream_putl(s, chunk_size);
0e3b6a92
EDP
2301 /* requested chunk base */
2302 stream_putl(s, base);
d62a17ae 2303 /* Put length at the first point of the stream. */
2304 stream_putw_at(s, 0, stream_get_endp(s));
2305
2306 ret = writen(zclient->sock, s->data, stream_get_endp(s));
2307 if (ret < 0) {
1c50c1c0 2308 flog_err(EC_LIB_ZAPI_SOCKET, "Can't write to zclient sock");
d62a17ae 2309 close(zclient->sock);
2310 zclient->sock = -1;
2311 return -1;
2312 }
2313 if (ret == 0) {
1c50c1c0 2314 flog_err(EC_LIB_ZAPI_SOCKET, "Zclient sock closed");
d62a17ae 2315 close(zclient->sock);
2316 zclient->sock = -1;
2317 return -1;
2318 }
2319 if (zclient_debug)
35cbe02a 2320 zlog_debug("Label chunk request (%d bytes) sent", ret);
d62a17ae 2321
2322 /* read response */
2323 if (zclient_read_sync_response(zclient, ZEBRA_GET_LABEL_CHUNK) != 0)
2324 return -1;
2325
5dffb0e9 2326 /* parse response */
d62a17ae 2327 s = zclient->ibuf;
5dffb0e9
FR
2328
2329 /* read proto and instance */
2330 uint8_t proto = stream_getc(s);
2331 uint16_t instance = stream_getw(s);
2332
2333 /* sanities */
2334 if (proto != zclient->redist_default)
450971aa 2335 flog_err(EC_LIB_ZAPI_ENCODE,
1c50c1c0
QY
2336 "Wrong proto (%u) in get chunk response. Should be %u",
2337 proto, zclient->redist_default);
5dffb0e9 2338 if (instance != zclient->instance)
450971aa 2339 flog_err(EC_LIB_ZAPI_ENCODE,
1c50c1c0
QY
2340 "Wrong instId (%u) in get chunk response Should be %u",
2341 instance, zclient->instance);
5dffb0e9 2342
f004f7c3
EDP
2343 /* if we requested a specific chunk and it could not be allocated, the
2344 * response message will end here
2345 */
2346 if (!STREAM_READABLE(s)) {
2347 zlog_info("Unable to assign Label Chunk to %s instance %u",
2348 zebra_route_string(proto), instance);
2349 return -1;
2350 }
2351
d62a17ae 2352 /* keep */
2353 response_keep = stream_getc(s);
2354 /* start and end labels */
2355 *start = stream_getl(s);
2356 *end = stream_getl(s);
2357
2358 /* not owning this response */
2359 if (keep != response_keep) {
1c50c1c0
QY
2360 flog_err(
2361 EC_LIB_ZAPI_ENCODE,
2362 "Invalid Label chunk: %u - %u, keeps mismatch %u != %u",
2363 *start, *end, keep, response_keep);
d62a17ae 2364 }
2365 /* sanity */
70e98a7f
DS
2366 if (*start > *end || *start < MPLS_LABEL_UNRESERVED_MIN
2367 || *end > MPLS_LABEL_UNRESERVED_MAX) {
1c50c1c0
QY
2368 flog_err(EC_LIB_ZAPI_ENCODE, "Invalid Label chunk: %u - %u",
2369 *start, *end);
d62a17ae 2370 return -1;
2371 }
2372
2373 if (zclient_debug)
35cbe02a 2374 zlog_debug("Label Chunk assign: %u - %u (%u)", *start, *end,
d62a17ae 2375 response_keep);
2376
2377 return 0;
fea12efb 2378}
2379
2380/**
2381 * Function to release a label chunk
2382 *
2383 * @param zclient Zclient used to connect to label manager (zebra)
2384 * @param start First label of chunk
2385 * @param end Last label of chunk
2386 * @result 0 on success, -1 otherwise
2387 */
d62a17ae 2388int lm_release_label_chunk(struct zclient *zclient, uint32_t start,
2389 uint32_t end)
fea12efb 2390{
d62a17ae 2391 int ret;
2392 struct stream *s;
2393
2394 if (zclient_debug)
35cbe02a 2395 zlog_debug("Releasing Label Chunk %u - %u", start, end);
d62a17ae 2396
2397 if (zclient->sock < 0)
2398 return -1;
2399
2400 /* send request */
2401 s = zclient->obuf;
2402 stream_reset(s);
2403 zclient_create_header(s, ZEBRA_RELEASE_LABEL_CHUNK, VRF_DEFAULT);
2404
5dffb0e9
FR
2405 /* proto */
2406 stream_putc(s, zclient->redist_default);
2407 /* instance */
2408 stream_putw(s, zclient->instance);
d62a17ae 2409 /* start */
2410 stream_putl(s, start);
2411 /* end */
2412 stream_putl(s, end);
2413
2414 /* Put length at the first point of the stream. */
2415 stream_putw_at(s, 0, stream_get_endp(s));
2416
2417 ret = writen(zclient->sock, s->data, stream_get_endp(s));
2418 if (ret < 0) {
450971aa 2419 flog_err(EC_LIB_ZAPI_SOCKET, "Can't write to zclient sock");
d62a17ae 2420 close(zclient->sock);
2421 zclient->sock = -1;
2422 return -1;
2423 }
2424 if (ret == 0) {
1c50c1c0 2425 flog_err(EC_LIB_ZAPI_SOCKET, "Zclient sock connection closed");
d62a17ae 2426 close(zclient->sock);
2427 zclient->sock = -1;
2428 return -1;
2429 }
2430
2431 return 0;
fea12efb 2432}
c8e264b6 2433
75fb51c1
PG
2434/**
2435 * Connect to table manager in a syncronous way
2436 *
2437 * It first writes the request to zcient output buffer and then
2438 * immediately reads the answer from the input buffer.
2439 *
2440 * @param zclient Zclient used to connect to table manager (zebra)
2441 * @result Result of response
2442 */
2443int tm_table_manager_connect(struct zclient *zclient)
2444{
2445 int ret;
2446 struct stream *s;
2447 uint8_t result;
2448
2449 if (zclient_debug)
2450 zlog_debug("Connecting to Table Manager");
2451
2452 if (zclient->sock < 0)
2453 return -1;
2454
2455 /* send request */
2456 s = zclient->obuf;
2457 stream_reset(s);
2458 zclient_create_header(s, ZEBRA_TABLE_MANAGER_CONNECT, VRF_DEFAULT);
2459
2460 /* proto */
2461 stream_putc(s, zclient->redist_default);
2462 /* instance */
2463 stream_putw(s, zclient->instance);
2464
2465 /* Put length at the first point of the stream. */
2466 stream_putw_at(s, 0, stream_get_endp(s));
2467
2468 ret = zclient_send_message(zclient);
2469 if (ret < 0)
2470 return -1;
2471
2472 if (zclient_debug)
0313523d 2473 zlog_debug("%s: Table manager connect request sent", __func__);
75fb51c1
PG
2474
2475 /* read response */
2476 if (zclient_read_sync_response(zclient, ZEBRA_TABLE_MANAGER_CONNECT)
2477 != 0)
2478 return -1;
2479
2480 /* result */
2481 s = zclient->ibuf;
2482 STREAM_GETC(s, result);
2483 if (zclient_debug)
2484 zlog_debug(
2485 "%s: Table Manager connect response received, result %u",
2486 __func__, result);
2487
2488 return (int)result;
2489stream_failure:
6a2b0d9a 2490 return -1;
75fb51c1
PG
2491}
2492
2493/**
2494 * Function to request a table chunk in a syncronous way
2495 *
2496 * It first writes the request to zclient output buffer and then
2497 * immediately reads the answer from the input buffer.
2498 *
2499 * @param zclient Zclient used to connect to table manager (zebra)
2500 * @param chunk_size Amount of table requested
2501 * @param start to write first assigned chunk table RT ID to
2502 * @param end To write last assigned chunk table RT ID to
2503 * @result 0 on success, -1 otherwise
2504 */
2505int tm_get_table_chunk(struct zclient *zclient, uint32_t chunk_size,
2506 uint32_t *start, uint32_t *end)
2507{
2508 int ret;
2509 struct stream *s;
2510
2511 if (zclient_debug)
2512 zlog_debug("Getting Table Chunk");
2513
2514 if (zclient->sock < 0)
2515 return -1;
2516
2517 /* send request */
2518 s = zclient->obuf;
2519 stream_reset(s);
2520 zclient_create_header(s, ZEBRA_GET_TABLE_CHUNK, VRF_DEFAULT);
2521 /* chunk size */
2522 stream_putl(s, chunk_size);
2523 /* Put length at the first point of the stream. */
2524 stream_putw_at(s, 0, stream_get_endp(s));
2525
2526 ret = writen(zclient->sock, s->data, stream_get_endp(s));
2527 if (ret < 0) {
1c50c1c0
QY
2528 flog_err(EC_LIB_ZAPI_SOCKET, "%s: can't write to zclient->sock",
2529 __func__);
75fb51c1
PG
2530 close(zclient->sock);
2531 zclient->sock = -1;
2532 return -1;
2533 }
2534 if (ret == 0) {
450971aa 2535 flog_err(EC_LIB_ZAPI_SOCKET,
1c50c1c0 2536 "%s: zclient->sock connection closed", __func__);
75fb51c1
PG
2537 close(zclient->sock);
2538 zclient->sock = -1;
2539 return -1;
2540 }
2541 if (zclient_debug)
2542 zlog_debug("%s: Table chunk request (%d bytes) sent", __func__,
2543 ret);
2544
2545 /* read response */
2546 if (zclient_read_sync_response(zclient, ZEBRA_GET_TABLE_CHUNK) != 0)
2547 return -1;
2548
2549 s = zclient->ibuf;
2550 /* start and end table IDs */
2551 STREAM_GETL(s, *start);
2552 STREAM_GETL(s, *end);
2553
2554 if (zclient_debug)
2555 zlog_debug("Table Chunk assign: %u - %u ", *start, *end);
2556
75fb51c1 2557 return 0;
6a2b0d9a
RW
2558stream_failure:
2559 return -1;
75fb51c1
PG
2560}
2561
2562/**
2563 * Function to release a table chunk
2564 *
2565 * @param zclient Zclient used to connect to table manager (zebra)
2566 * @param start First label of table
2567 * @param end Last label of chunk
2568 * @result 0 on success, -1 otherwise
2569 */
2570int tm_release_table_chunk(struct zclient *zclient, uint32_t start,
2571 uint32_t end)
2572{
2573 struct stream *s;
2574
2575 if (zclient_debug)
2576 zlog_debug("Releasing Table Chunk");
2577
2578 if (zclient->sock < 0)
2579 return -1;
2580
2581 /* send request */
2582 s = zclient->obuf;
2583 stream_reset(s);
2584 zclient_create_header(s, ZEBRA_RELEASE_TABLE_CHUNK, VRF_DEFAULT);
2585
2586 /* start */
2587 stream_putl(s, start);
2588 /* end */
2589 stream_putl(s, end);
2590
2591 /* Put length at the first point of the stream. */
2592 stream_putw_at(s, 0, stream_get_endp(s));
2593
2594 return zclient_send_message(zclient);
2595}
2596
bad6b0e7
RW
2597int zebra_send_mpls_labels(struct zclient *zclient, int cmd,
2598 struct zapi_labels *zl)
2599{
2600 if (zapi_labels_encode(zclient->obuf, cmd, zl) < 0)
2601 return -1;
2602 return zclient_send_message(zclient);
2603}
2604
2605int zapi_labels_encode(struct stream *s, int cmd, struct zapi_labels *zl)
2606{
ea6b290b
RW
2607 struct zapi_nexthop_label *znh;
2608
bad6b0e7
RW
2609 stream_reset(s);
2610
2611 zclient_create_header(s, cmd, VRF_DEFAULT);
b3c49d0e 2612 stream_putc(s, zl->message);
bad6b0e7 2613 stream_putc(s, zl->type);
b3c49d0e
RW
2614 stream_putl(s, zl->local_label);
2615
2616 if (CHECK_FLAG(zl->message, ZAPI_LABELS_FTN)) {
2617 stream_putw(s, zl->route.prefix.family);
2618 stream_put_prefix(s, &zl->route.prefix);
2619 stream_putc(s, zl->route.type);
2620 stream_putw(s, zl->route.instance);
2621 }
2622
ea6b290b
RW
2623 if (zl->nexthop_num > MULTIPATH_NUM) {
2624 flog_err(
2625 EC_LIB_ZAPI_ENCODE,
2626 "%s: label %u: can't encode %u nexthops (maximum is %u)",
2627 __func__, zl->local_label, zl->nexthop_num,
2628 MULTIPATH_NUM);
2629 return -1;
2630 }
2631 stream_putw(s, zl->nexthop_num);
2632
2633 for (int i = 0; i < zl->nexthop_num; i++) {
2634 znh = &zl->nexthops[i];
2635
2636 stream_putc(s, znh->type);
2637 stream_putw(s, znh->family);
2638 switch (znh->family) {
2639 case AF_INET:
2640 stream_put_in_addr(s, &znh->address.ipv4);
2641 break;
2642 case AF_INET6:
2643 stream_write(s, (uint8_t *)&znh->address.ipv6, 16);
2644 break;
2645 default:
2646 break;
2647 }
2648 stream_putl(s, znh->ifindex);
2649 stream_putl(s, znh->label);
bad6b0e7 2650 }
bad6b0e7
RW
2651
2652 /* Put length at the first point of the stream. */
2653 stream_putw_at(s, 0, stream_get_endp(s));
2654
2655 return 0;
2656}
2657
2658int zapi_labels_decode(struct stream *s, struct zapi_labels *zl)
2659{
ea6b290b
RW
2660 struct zapi_nexthop_label *znh;
2661
bad6b0e7
RW
2662 memset(zl, 0, sizeof(*zl));
2663
2664 /* Get data. */
b3c49d0e 2665 STREAM_GETC(s, zl->message);
bad6b0e7 2666 STREAM_GETC(s, zl->type);
b3c49d0e 2667 STREAM_GETL(s, zl->local_label);
bad6b0e7 2668
b3c49d0e
RW
2669 if (CHECK_FLAG(zl->message, ZAPI_LABELS_FTN)) {
2670 size_t psize;
2671
2672 STREAM_GETW(s, zl->route.prefix.family);
2673 STREAM_GETC(s, zl->route.prefix.prefixlen);
2674
2675 psize = PSIZE(zl->route.prefix.prefixlen);
2676 switch (zl->route.prefix.family) {
2677 case AF_INET:
2678 if (zl->route.prefix.prefixlen > IPV4_MAX_BITLEN) {
2679 zlog_debug(
2680 "%s: Specified prefix length %d is greater than a v4 address can support",
2681 __PRETTY_FUNCTION__,
2682 zl->route.prefix.prefixlen);
2683 return -1;
2684 }
2685 STREAM_GET(&zl->route.prefix.u.prefix4.s_addr, s,
2686 psize);
2687 break;
2688 case AF_INET6:
2689 if (zl->route.prefix.prefixlen > IPV6_MAX_BITLEN) {
2690 zlog_debug(
2691 "%s: Specified prefix length %d is greater than a v6 address can support",
2692 __PRETTY_FUNCTION__,
2693 zl->route.prefix.prefixlen);
2694 return -1;
2695 }
2696 STREAM_GET(&zl->route.prefix.u.prefix6, s, psize);
2697 break;
2698 default:
2699 flog_err(EC_LIB_ZAPI_ENCODE,
2700 "%s: Specified family %u is not v4 or v6",
2701 __PRETTY_FUNCTION__, zl->route.prefix.family);
bad6b0e7
RW
2702 return -1;
2703 }
b3c49d0e
RW
2704
2705 STREAM_GETC(s, zl->route.type);
2706 STREAM_GETW(s, zl->route.instance);
2707 }
2708
ea6b290b 2709 STREAM_GETW(s, zl->nexthop_num);
b900b3c6
QY
2710
2711 if (zl->nexthop_num > MULTIPATH_NUM) {
2712 flog_warn(
2713 EC_LIB_ZAPI_ENCODE,
2714 "%s: Prefix %pFX has %d nexthops, but we can only use the first %d",
2715 __func__, &zl->route.prefix, zl->nexthop_num,
2716 MULTIPATH_NUM);
2717 }
2718
2719 zl->nexthop_num = MIN(MULTIPATH_NUM, zl->nexthop_num);
2720
ea6b290b
RW
2721 for (int i = 0; i < zl->nexthop_num; i++) {
2722 znh = &zl->nexthops[i];
2723
2724 STREAM_GETC(s, znh->type);
2725 STREAM_GETW(s, znh->family);
2726 switch (znh->family) {
2727 case AF_INET:
2728 STREAM_GET(&znh->address.ipv4.s_addr, s,
2729 IPV4_MAX_BYTELEN);
2730 break;
2731 case AF_INET6:
2732 STREAM_GET(&znh->address.ipv6, s, 16);
2733 break;
2734 default:
2735 break;
2736 }
2737 STREAM_GETL(s, znh->ifindex);
2738 STREAM_GETL(s, znh->label);
bad6b0e7 2739 }
bad6b0e7
RW
2740
2741 return 0;
2742stream_failure:
2743 return -1;
2744}
75fb51c1 2745
6833ae01 2746int zebra_send_pw(struct zclient *zclient, int command, struct zapi_pw *pw)
2747{
2748 struct stream *s;
2749
2750 /* Reset stream. */
2751 s = zclient->obuf;
2752 stream_reset(s);
2753
2754 zclient_create_header(s, command, VRF_DEFAULT);
2755 stream_write(s, pw->ifname, IF_NAMESIZE);
2756 stream_putl(s, pw->ifindex);
2757
2758 /* Put type */
2759 stream_putl(s, pw->type);
2760
2761 /* Put nexthop */
2762 stream_putl(s, pw->af);
2763 switch (pw->af) {
2764 case AF_INET:
2765 stream_put_in_addr(s, &pw->nexthop.ipv4);
2766 break;
2767 case AF_INET6:
d7c0a89a 2768 stream_write(s, (uint8_t *)&pw->nexthop.ipv6, 16);
6833ae01 2769 break;
2770 default:
1c50c1c0 2771 flog_err(EC_LIB_ZAPI_ENCODE, "%s: unknown af", __func__);
6833ae01 2772 return -1;
2773 }
2774
2775 /* Put labels */
2776 stream_putl(s, pw->local_label);
2777 stream_putl(s, pw->remote_label);
2778
2779 /* Put flags */
2780 stream_putc(s, pw->flags);
2781
2782 /* Protocol specific fields */
2783 stream_write(s, &pw->data, sizeof(union pw_protocol_fields));
2784
2785 /* Put length at the first point of the stream. */
2786 stream_putw_at(s, 0, stream_get_endp(s));
2787
2788 return zclient_send_message(zclient);
2789}
2790
2791/*
2792 * Receive PW status update from Zebra and send it to LDE process.
2793 */
121f9dee 2794void zebra_read_pw_status_update(ZAPI_CALLBACK_ARGS, struct zapi_pw_status *pw)
6833ae01 2795{
2796 struct stream *s;
2797
2798 memset(pw, 0, sizeof(struct zapi_pw_status));
2799 s = zclient->ibuf;
2800
2801 /* Get data. */
2802 stream_get(pw->ifname, s, IF_NAMESIZE);
2803 pw->ifindex = stream_getl(s);
2804 pw->status = stream_getl(s);
2805}
2806
121f9dee 2807static void zclient_capability_decode(ZAPI_CALLBACK_ARGS)
09924cff
DS
2808{
2809 struct zclient_capabilities cap;
2810 struct stream *s = zclient->ibuf;
bb6b7f79 2811 int vrf_backend;
09924cff
DS
2812 uint8_t mpls_enabled;
2813
bb6b7f79
RW
2814 STREAM_GETL(s, vrf_backend);
2815 vrf_configure_backend(vrf_backend);
2816
09924cff
DS
2817 memset(&cap, 0, sizeof(cap));
2818 STREAM_GETC(s, mpls_enabled);
2819 cap.mpls_enabled = !!mpls_enabled;
2820 STREAM_GETL(s, cap.ecmp);
02c0866d 2821 STREAM_GETC(s, cap.role);
09924cff
DS
2822
2823 if (zclient->zebra_capabilities)
2824 (*zclient->zebra_capabilities)(&cap);
2825
2826stream_failure:
2827 return;
2828}
2829
36b5b98f
SK
2830void zclient_send_mlag_register(struct zclient *client, uint32_t bit_map)
2831{
2832 struct stream *s;
2833
2834 s = client->obuf;
2835 stream_reset(s);
2836
2837 zclient_create_header(s, ZEBRA_MLAG_CLIENT_REGISTER, VRF_DEFAULT);
2838 stream_putl(s, bit_map);
2839
2840 stream_putw_at(s, 0, stream_get_endp(s));
2841 zclient_send_message(client);
2842}
2843
2844void zclient_send_mlag_deregister(struct zclient *client)
2845{
2846 zebra_message_send(client, ZEBRA_MLAG_CLIENT_UNREGISTER, VRF_DEFAULT);
2847}
2848
2849void zclient_send_mlag_data(struct zclient *client, struct stream *client_s)
2850{
2851 struct stream *s;
2852
2853 s = client->obuf;
2854 stream_reset(s);
2855
2856 zclient_create_header(s, ZEBRA_MLAG_FORWARD_MSG, VRF_DEFAULT);
2857 stream_put(s, client_s->data, client_s->endp);
2858
2859 stream_putw_at(s, 0, stream_get_endp(s));
2860 zclient_send_message(client);
2861}
2862
46c2687c
SK
2863static void zclient_mlag_process_up(ZAPI_CALLBACK_ARGS)
2864{
2865 if (zclient->mlag_process_up)
2866 (*zclient->mlag_process_up)();
2867}
2868
2869static void zclient_mlag_process_down(ZAPI_CALLBACK_ARGS)
2870{
2871 if (zclient->mlag_process_down)
2872 (*zclient->mlag_process_down)();
2873}
2874
2875static void zclient_mlag_handle_msg(ZAPI_CALLBACK_ARGS)
2876{
2877 if (zclient->mlag_handle_msg)
2878 (*zclient->mlag_handle_msg)(zclient->ibuf, length);
2879}
2880
718e3744 2881/* Zebra client message read function. */
d62a17ae 2882static int zclient_read(struct thread *thread)
718e3744 2883{
d62a17ae 2884 size_t already;
2885 uint16_t length, command;
2886 uint8_t marker, version;
2887 vrf_id_t vrf_id;
2888 struct zclient *zclient;
2889
2890 /* Get socket to zebra. */
2891 zclient = THREAD_ARG(thread);
2892 zclient->t_read = NULL;
2893
2894 /* Read zebra header (if we don't have it already). */
2895 if ((already = stream_get_endp(zclient->ibuf)) < ZEBRA_HEADER_SIZE) {
2896 ssize_t nbyte;
2897 if (((nbyte = stream_read_try(zclient->ibuf, zclient->sock,
2898 ZEBRA_HEADER_SIZE - already))
2899 == 0)
2900 || (nbyte == -1)) {
2901 if (zclient_debug)
2902 zlog_debug(
2903 "zclient connection closed socket [%d].",
2904 zclient->sock);
2905 return zclient_failed(zclient);
2906 }
2907 if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE - already)) {
2908 /* Try again later. */
2909 zclient_event(ZCLIENT_READ, zclient);
2910 return 0;
2911 }
2912 already = ZEBRA_HEADER_SIZE;
634f9ea2 2913 }
d62a17ae 2914
2915 /* Reset to read from the beginning of the incoming packet. */
2916 stream_set_getp(zclient->ibuf, 0);
2917
2918 /* Fetch header values. */
2919 length = stream_getw(zclient->ibuf);
2920 marker = stream_getc(zclient->ibuf);
2921 version = stream_getc(zclient->ibuf);
a9ff90c4 2922 vrf_id = stream_getl(zclient->ibuf);
d62a17ae 2923 command = stream_getw(zclient->ibuf);
2924
2925 if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION) {
1c50c1c0
QY
2926 flog_err(
2927 EC_LIB_ZAPI_MISSMATCH,
2928 "%s: socket %d version mismatch, marker %d, version %d",
2929 __func__, zclient->sock, marker, version);
d62a17ae 2930 return zclient_failed(zclient);
634f9ea2 2931 }
d62a17ae 2932
2933 if (length < ZEBRA_HEADER_SIZE) {
450971aa 2934 flog_err(EC_LIB_ZAPI_MISSMATCH,
1c50c1c0
QY
2935 "%s: socket %d message length %u is less than %d ",
2936 __func__, zclient->sock, length, ZEBRA_HEADER_SIZE);
d62a17ae 2937 return zclient_failed(zclient);
634f9ea2 2938 }
d62a17ae 2939
2940 /* Length check. */
2941 if (length > STREAM_SIZE(zclient->ibuf)) {
2942 struct stream *ns;
ade6974d 2943 flog_err(
450971aa 2944 EC_LIB_ZAPI_ENCODE,
ade6974d
QY
2945 "%s: message size %u exceeds buffer size %lu, expanding...",
2946 __func__, length,
2947 (unsigned long)STREAM_SIZE(zclient->ibuf));
d62a17ae 2948 ns = stream_new(length);
2949 stream_copy(ns, zclient->ibuf);
2950 stream_free(zclient->ibuf);
2951 zclient->ibuf = ns;
2952 }
2953
2954 /* Read rest of zebra packet. */
2955 if (already < length) {
2956 ssize_t nbyte;
2957 if (((nbyte = stream_read_try(zclient->ibuf, zclient->sock,
2958 length - already))
2959 == 0)
2960 || (nbyte == -1)) {
2961 if (zclient_debug)
2962 zlog_debug(
2963 "zclient connection closed socket [%d].",
2964 zclient->sock);
2965 return zclient_failed(zclient);
2966 }
2967 if (nbyte != (ssize_t)(length - already)) {
2968 /* Try again later. */
2969 zclient_event(ZCLIENT_READ, zclient);
2970 return 0;
2971 }
2972 }
2973
2974 length -= ZEBRA_HEADER_SIZE;
2975
2976 if (zclient_debug)
cdc6ed90
DS
2977 zlog_debug("zclient 0x%p command %s VRF %u",
2978 (void *)zclient, zserv_command_string(command),
2979 vrf_id);
d62a17ae 2980
2981 switch (command) {
09924cff
DS
2982 case ZEBRA_CAPABILITIES:
2983 zclient_capability_decode(command, zclient, length, vrf_id);
2984 break;
d62a17ae 2985 case ZEBRA_ROUTER_ID_UPDATE:
2986 if (zclient->router_id_update)
2987 (*zclient->router_id_update)(command, zclient, length,
2988 vrf_id);
2989 break;
2990 case ZEBRA_VRF_ADD:
2991 zclient_vrf_add(zclient, vrf_id);
2992 break;
2993 case ZEBRA_VRF_DELETE:
2994 zclient_vrf_delete(zclient, vrf_id);
2995 break;
2996 case ZEBRA_INTERFACE_ADD:
ef7bd2a3 2997 zclient_interface_add(zclient, vrf_id);
d62a17ae 2998 break;
2999 case ZEBRA_INTERFACE_DELETE:
3c3c3252 3000 zclient_interface_delete(zclient, vrf_id);
d62a17ae 3001 break;
3002 case ZEBRA_INTERFACE_ADDRESS_ADD:
3003 if (zclient->interface_address_add)
3004 (*zclient->interface_address_add)(command, zclient,
3005 length, vrf_id);
3006 break;
3007 case ZEBRA_INTERFACE_ADDRESS_DELETE:
3008 if (zclient->interface_address_delete)
3009 (*zclient->interface_address_delete)(command, zclient,
3010 length, vrf_id);
3011 break;
3012 case ZEBRA_INTERFACE_BFD_DEST_UPDATE:
3013 if (zclient->interface_bfd_dest_update)
3014 (*zclient->interface_bfd_dest_update)(command, zclient,
3015 length, vrf_id);
3016 break;
3017 case ZEBRA_INTERFACE_NBR_ADDRESS_ADD:
3018 if (zclient->interface_nbr_address_add)
3019 (*zclient->interface_nbr_address_add)(command, zclient,
3020 length, vrf_id);
3021 break;
3022 case ZEBRA_INTERFACE_NBR_ADDRESS_DELETE:
3023 if (zclient->interface_nbr_address_delete)
3024 (*zclient->interface_nbr_address_delete)(
3025 command, zclient, length, vrf_id);
3026 break;
3027 case ZEBRA_INTERFACE_UP:
ddbf3e60 3028 zclient_interface_up(zclient, vrf_id);
d62a17ae 3029 break;
3030 case ZEBRA_INTERFACE_DOWN:
b0b69e59 3031 zclient_interface_down(zclient, vrf_id);
d62a17ae 3032 break;
3033 case ZEBRA_INTERFACE_VRF_UPDATE:
3034 if (zclient->interface_vrf_update)
3035 (*zclient->interface_vrf_update)(command, zclient,
3036 length, vrf_id);
3037 break;
3038 case ZEBRA_NEXTHOP_UPDATE:
3039 if (zclient_debug)
9165c5f5 3040 zlog_debug("zclient rcvd nexthop update");
d62a17ae 3041 if (zclient->nexthop_update)
3042 (*zclient->nexthop_update)(command, zclient, length,
3043 vrf_id);
3044 break;
3045 case ZEBRA_IMPORT_CHECK_UPDATE:
3046 if (zclient_debug)
9165c5f5 3047 zlog_debug("zclient rcvd import check update");
d62a17ae 3048 if (zclient->import_check_update)
3049 (*zclient->import_check_update)(command, zclient,
3050 length, vrf_id);
3051 break;
3052 case ZEBRA_BFD_DEST_REPLAY:
3053 if (zclient->bfd_dest_replay)
3054 (*zclient->bfd_dest_replay)(command, zclient, length,
3055 vrf_id);
3056 break;
74489921
RW
3057 case ZEBRA_REDISTRIBUTE_ROUTE_ADD:
3058 if (zclient->redistribute_route_add)
3059 (*zclient->redistribute_route_add)(command, zclient,
3060 length, vrf_id);
d62a17ae 3061 break;
74489921
RW
3062 case ZEBRA_REDISTRIBUTE_ROUTE_DEL:
3063 if (zclient->redistribute_route_del)
3064 (*zclient->redistribute_route_del)(command, zclient,
3065 length, vrf_id);
d62a17ae 3066 break;
3067 case ZEBRA_INTERFACE_LINK_PARAMS:
3068 if (zclient->interface_link_params)
3069 (*zclient->interface_link_params)(command, zclient,
edc12762 3070 length, vrf_id);
d62a17ae 3071 break;
3072 case ZEBRA_FEC_UPDATE:
3073 if (zclient_debug)
9165c5f5 3074 zlog_debug("zclient rcvd fec update");
d62a17ae 3075 if (zclient->fec_update)
3076 (*zclient->fec_update)(command, zclient, length);
3077 break;
50f74cf1 3078 case ZEBRA_LOCAL_ES_ADD:
3079 if (zclient->local_es_add)
3080 (*zclient->local_es_add)(command, zclient, length,
3081 vrf_id);
3082 break;
3083 case ZEBRA_LOCAL_ES_DEL:
3084 if (zclient->local_es_del)
3085 (*zclient->local_es_del)(command, zclient, length,
3086 vrf_id);
3087 break;
d62a17ae 3088 case ZEBRA_VNI_ADD:
3089 if (zclient->local_vni_add)
3090 (*zclient->local_vni_add)(command, zclient, length,
3091 vrf_id);
3092 break;
3093 case ZEBRA_VNI_DEL:
3094 if (zclient->local_vni_del)
3095 (*zclient->local_vni_del)(command, zclient, length,
3096 vrf_id);
3097 break;
b7cfce93
MK
3098 case ZEBRA_L3VNI_ADD:
3099 if (zclient->local_l3vni_add)
3100 (*zclient->local_l3vni_add)(command, zclient, length,
3101 vrf_id);
3102 break;
3103 case ZEBRA_L3VNI_DEL:
3104 if (zclient->local_l3vni_del)
3105 (*zclient->local_l3vni_del)(command, zclient, length,
3106 vrf_id);
3107 break;
d62a17ae 3108 case ZEBRA_MACIP_ADD:
3109 if (zclient->local_macip_add)
3110 (*zclient->local_macip_add)(command, zclient, length,
3111 vrf_id);
3112 break;
3113 case ZEBRA_MACIP_DEL:
3114 if (zclient->local_macip_del)
3115 (*zclient->local_macip_del)(command, zclient, length,
3116 vrf_id);
3117 break;
31310b25
MK
3118 case ZEBRA_IP_PREFIX_ROUTE_ADD:
3119 if (zclient->local_ip_prefix_add)
3120 (*zclient->local_ip_prefix_add)(command, zclient,
3121 length, vrf_id);
3122 break;
3123 case ZEBRA_IP_PREFIX_ROUTE_DEL:
3124 if (zclient->local_ip_prefix_del)
3125 (*zclient->local_ip_prefix_del)(command, zclient,
3126 length, vrf_id);
3127 break;
6833ae01 3128 case ZEBRA_PW_STATUS_UPDATE:
3129 if (zclient->pw_status_update)
3130 (*zclient->pw_status_update)(command, zclient, length,
3131 vrf_id);
3132 break;
7ea7b86e 3133 case ZEBRA_ROUTE_NOTIFY_OWNER:
28b11f81
DS
3134 if (zclient->route_notify_owner)
3135 (*zclient->route_notify_owner)(command, zclient, length,
3136 vrf_id);
7ea7b86e 3137 break;
b6c5d343
DS
3138 case ZEBRA_RULE_NOTIFY_OWNER:
3139 if (zclient->rule_notify_owner)
3140 (*zclient->rule_notify_owner)(command, zclient, length,
3141 vrf_id);
955bfd98
PZ
3142 break;
3143 case ZEBRA_GET_LABEL_CHUNK:
3144 if (zclient->label_chunk)
3145 (*zclient->label_chunk)(command, zclient, length,
0313523d 3146 vrf_id);
955bfd98 3147 break;
c16a0a62
PG
3148 case ZEBRA_IPSET_NOTIFY_OWNER:
3149 if (zclient->ipset_notify_owner)
3150 (*zclient->ipset_notify_owner)(command, zclient, length,
3151 vrf_id);
3152 break;
3153 case ZEBRA_IPSET_ENTRY_NOTIFY_OWNER:
3154 if (zclient->ipset_entry_notify_owner)
3155 (*zclient->ipset_entry_notify_owner)(command,
3156 zclient, length,
3157 vrf_id);
3158 break;
3159 case ZEBRA_IPTABLE_NOTIFY_OWNER:
3160 if (zclient->iptable_notify_owner)
3161 (*zclient->iptable_notify_owner)(command,
3162 zclient, length,
3163 vrf_id);
4ab3321f
AK
3164 break;
3165 case ZEBRA_VXLAN_SG_ADD:
3166 if (zclient->vxlan_sg_add)
3167 (*zclient->vxlan_sg_add)(command, zclient, length,
3168 vrf_id);
3169 break;
3170 case ZEBRA_VXLAN_SG_DEL:
3171 if (zclient->vxlan_sg_del)
3172 (*zclient->vxlan_sg_del)(command, zclient, length,
3173 vrf_id);
3174 break;
46c2687c
SK
3175 case ZEBRA_MLAG_PROCESS_UP:
3176 zclient_mlag_process_up(command, zclient, length, vrf_id);
3177 break;
3178 case ZEBRA_MLAG_PROCESS_DOWN:
3179 zclient_mlag_process_down(command, zclient, length, vrf_id);
3180 break;
3181 case ZEBRA_MLAG_FORWARD_MSG:
3182 zclient_mlag_handle_msg(command, zclient, length, vrf_id);
3183 break;
9ab0b2a3
SW
3184 case ZEBRA_ERROR:
3185 zclient_handle_error(command, zclient, length, vrf_id);
d62a17ae 3186 default:
3187 break;
634f9ea2 3188 }
d62a17ae 3189
3190 if (zclient->sock < 0)
3191 /* Connection was closed during packet processing. */
3192 return -1;
3193
3194 /* Register read thread. */
3195 stream_reset(zclient->ibuf);
3196 zclient_event(ZCLIENT_READ, zclient);
3197
3198 return 0;
718e3744 3199}
3200
d62a17ae 3201void zclient_redistribute(int command, struct zclient *zclient, afi_t afi,
d7c0a89a 3202 int type, unsigned short instance, vrf_id_t vrf_id)
718e3744 3203{
718e3744 3204
d62a17ae 3205 if (instance) {
3206 if (command == ZEBRA_REDISTRIBUTE_ADD) {
3207 if (redist_check_instance(
3208 &zclient->mi_redist[afi][type], instance))
3209 return;
3210 redist_add_instance(&zclient->mi_redist[afi][type],
3211 instance);
3212 } else {
3213 if (!redist_check_instance(
3214 &zclient->mi_redist[afi][type], instance))
3215 return;
3216 redist_del_instance(&zclient->mi_redist[afi][type],
3217 instance);
3218 }
3219
3220 } else {
3221 if (command == ZEBRA_REDISTRIBUTE_ADD) {
3222 if (vrf_bitmap_check(zclient->redist[afi][type],
3223 vrf_id))
3224 return;
3225 vrf_bitmap_set(zclient->redist[afi][type], vrf_id);
3226 } else {
3227 if (!vrf_bitmap_check(zclient->redist[afi][type],
3228 vrf_id))
3229 return;
3230 vrf_bitmap_unset(zclient->redist[afi][type], vrf_id);
3231 }
3232 }
3233
3234 if (zclient->sock > 0)
3235 zebra_redistribute_send(command, zclient, afi, type, instance,
3236 vrf_id);
718e3744 3237}
3238
718e3744 3239
d62a17ae 3240void zclient_redistribute_default(int command, struct zclient *zclient,
49db7a7b 3241 afi_t afi, vrf_id_t vrf_id)
718e3744 3242{
718e3744 3243
d62a17ae 3244 if (command == ZEBRA_REDISTRIBUTE_DEFAULT_ADD) {
49db7a7b 3245 if (vrf_bitmap_check(zclient->default_information[afi], vrf_id))
d62a17ae 3246 return;
49db7a7b 3247 vrf_bitmap_set(zclient->default_information[afi], vrf_id);
d62a17ae 3248 } else {
49db7a7b
RW
3249 if (!vrf_bitmap_check(zclient->default_information[afi],
3250 vrf_id))
d62a17ae 3251 return;
49db7a7b 3252 vrf_bitmap_unset(zclient->default_information[afi], vrf_id);
d62a17ae 3253 }
3254
3255 if (zclient->sock > 0)
49db7a7b 3256 zebra_redistribute_default_send(command, zclient, afi, vrf_id);
718e3744 3257}
3258
d62a17ae 3259static void zclient_event(enum event event, struct zclient *zclient)
718e3744 3260{
d62a17ae 3261 switch (event) {
3262 case ZCLIENT_SCHEDULE:
3263 thread_add_event(zclient->master, zclient_connect, zclient, 0,
3264 &zclient->t_connect);
3265 break;
3266 case ZCLIENT_CONNECT:
3267 if (zclient_debug)
3268 zlog_debug(
3269 "zclient connect failures: %d schedule interval is now %d",
3270 zclient->fail, zclient->fail < 3 ? 10 : 60);
3271 thread_add_timer(zclient->master, zclient_connect, zclient,
3272 zclient->fail < 3 ? 10 : 60,
3273 &zclient->t_connect);
3274 break;
3275 case ZCLIENT_READ:
3276 zclient->t_read = NULL;
3277 thread_add_read(zclient->master, zclient_read, zclient,
3278 zclient->sock, &zclient->t_read);
3279 break;
3280 }
718e3744 3281}
b5114685 3282
e0ae31b8
DS
3283void zclient_interface_set_master(struct zclient *client,
3284 struct interface *master,
3285 struct interface *slave)
3286{
3287 struct stream *s;
3288
3289 s = client->obuf;
3290 stream_reset(s);
3291
a36898e7 3292 zclient_create_header(s, ZEBRA_INTERFACE_SET_MASTER, master->vrf_id);
e0ae31b8 3293
a36898e7 3294 stream_putl(s, master->vrf_id);
e0ae31b8 3295 stream_putl(s, master->ifindex);
a36898e7 3296 stream_putl(s, slave->vrf_id);
e0ae31b8
DS
3297 stream_putl(s, slave->ifindex);
3298
3299 stream_putw_at(s, 0, stream_get_endp(s));
3300 zclient_send_message(client);
3301}
eb451ee5 3302
be7bbe52
S
3303/*
3304 * Send capabilities message to zebra
3305 */
3306int32_t zclient_capabilities_send(uint32_t cmd, struct zclient *zclient,
3307 struct zapi_cap *api)
eb451ee5 3308{
be7bbe52
S
3309
3310 struct stream *s;
3311
3312 if (zclient == NULL)
3313 return -1;
3314
3315 s = zclient->obuf;
3316 stream_reset(s);
3317 zclient_create_header(s, cmd, 0);
3318 stream_putl(s, api->cap);
3319
3320 switch (api->cap) {
3321 case ZEBRA_CLIENT_GR_CAPABILITIES:
3322 case ZEBRA_CLIENT_RIB_STALE_TIME:
3323 stream_putl(s, api->stale_removal_time);
3324 stream_putl(s, api->vrf_id);
3325 break;
3326 case ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE:
3327 case ZEBRA_CLIENT_ROUTE_UPDATE_PENDING:
3328 stream_putl(s, api->afi);
3329 stream_putl(s, api->safi);
3330 stream_putl(s, api->vrf_id);
3331 break;
3332 case ZEBRA_CLIENT_GR_DISABLE:
3333 stream_putl(s, api->vrf_id);
3334 break;
3335 }
3336
3337 /* Put length at the first point of the stream */
3338 stream_putw_at(s, 0, stream_get_endp(s));
3339
3340 return zclient_send_message(zclient);
3341}
3342
3343/*
3344 * Process capabilities message from zebra
3345 */
3346int32_t zapi_capabilities_decode(struct stream *s, struct zapi_cap *api)
3347{
3348
eb451ee5 3349 memset(api, 0, sizeof(*api));
3350
3351 STREAM_GETL(s, api->cap);
3352 switch (api->cap) {
3353 case ZEBRA_CLIENT_GR_CAPABILITIES:
3354 case ZEBRA_CLIENT_RIB_STALE_TIME:
be7bbe52
S
3355 STREAM_GETL(s, api->stale_removal_time);
3356 STREAM_GETL(s, api->vrf_id);
3357 break;
eb451ee5 3358 case ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE:
3359 case ZEBRA_CLIENT_ROUTE_UPDATE_PENDING:
be7bbe52
S
3360 STREAM_GETL(s, api->afi);
3361 STREAM_GETL(s, api->safi);
3362 STREAM_GETL(s, api->vrf_id);
3363 break;
eb451ee5 3364 case ZEBRA_CLIENT_GR_DISABLE:
be7bbe52
S
3365 STREAM_GETL(s, api->vrf_id);
3366 break;
eb451ee5 3367 }
3368stream_failure:
3369 return 0;
3370}