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