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