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