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