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