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