]> git.proxmox.com Git - mirror_frr.git/blame - lib/zclient.c
isisd: Free up some memory allocated.
[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
e1a1880d
DS
55struct zclient_options zclient_options_default = { .receive_notify = false };
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
342213ea
DS
189 zclient_init(zclient, zclient->redist_default,
190 zclient->instance, 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. */
689f5a8c
DL
217 ret = connect(sock, (struct sockaddr *)&zclient_addr,
218 zclient_addr_len);
d62a17ae 219 if (ret < 0) {
220 if (zclient_debug)
221 zlog_warn("%s connect failure: %d(%s)",
222 __PRETTY_FUNCTION__, errno,
223 safe_strerror(errno));
224 close(sock);
225 return -1;
226 }
718e3744 227
689f5a8c 228 zclient->sock = sock;
d62a17ae 229 return sock;
718e3744 230}
231
d62a17ae 232static int zclient_failed(struct zclient *zclient)
634f9ea2 233{
d62a17ae 234 zclient->fail++;
235 zclient_stop(zclient);
236 zclient_event(ZCLIENT_CONNECT, zclient);
237 return -1;
634f9ea2 238}
239
d62a17ae 240static int zclient_flush_data(struct thread *thread)
634f9ea2 241{
d62a17ae 242 struct zclient *zclient = THREAD_ARG(thread);
243
244 zclient->t_write = NULL;
245 if (zclient->sock < 0)
246 return -1;
247 switch (buffer_flush_available(zclient->wb, zclient->sock)) {
248 case BUFFER_ERROR:
249 zlog_warn(
250 "%s: buffer_flush_available failed on zclient fd %d, closing",
251 __func__, zclient->sock);
252 return zclient_failed(zclient);
253 break;
254 case BUFFER_PENDING:
255 zclient->t_write = NULL;
256 thread_add_write(zclient->master, zclient_flush_data, zclient,
257 zclient->sock, &zclient->t_write);
258 break;
259 case BUFFER_EMPTY:
260 break;
261 }
262 return 0;
634f9ea2 263}
264
d62a17ae 265int zclient_send_message(struct zclient *zclient)
634f9ea2 266{
d62a17ae 267 if (zclient->sock < 0)
268 return -1;
269 switch (buffer_write(zclient->wb, zclient->sock,
270 STREAM_DATA(zclient->obuf),
271 stream_get_endp(zclient->obuf))) {
272 case BUFFER_ERROR:
273 zlog_warn("%s: buffer_write failed to zclient fd %d, closing",
274 __func__, zclient->sock);
275 return zclient_failed(zclient);
276 break;
277 case BUFFER_EMPTY:
278 THREAD_OFF(zclient->t_write);
279 break;
280 case BUFFER_PENDING:
281 thread_add_write(zclient->master, zclient_flush_data, zclient,
282 zclient->sock, &zclient->t_write);
283 break;
284 }
285 return 0;
634f9ea2 286}
287
d62a17ae 288void zclient_create_header(struct stream *s, uint16_t command, vrf_id_t vrf_id)
c1b9800a 289{
d62a17ae 290 /* length placeholder, caller can update */
291 stream_putw(s, ZEBRA_HEADER_SIZE);
292 stream_putc(s, ZEBRA_HEADER_MARKER);
293 stream_putc(s, ZSERV_VERSION);
a9ff90c4 294 stream_putl(s, vrf_id);
d62a17ae 295 stream_putw(s, command);
c1b9800a 296}
297
d62a17ae 298int zclient_read_header(struct stream *s, int sock, u_int16_t *size,
299 u_char *marker, u_char *version, vrf_id_t *vrf_id,
300 u_int16_t *cmd)
55119089 301{
d62a17ae 302 if (stream_read(s, sock, ZEBRA_HEADER_SIZE) != ZEBRA_HEADER_SIZE)
303 return -1;
304
ec93aa12
DS
305 STREAM_GETW(s, *size);
306 *size -= ZEBRA_HEADER_SIZE;
307 STREAM_GETC(s, *marker);
308 STREAM_GETC(s, *version);
a9ff90c4 309 STREAM_GETL(s, *vrf_id);
ec93aa12 310 STREAM_GETW(s, *cmd);
d62a17ae 311
312 if (*version != ZSERV_VERSION || *marker != ZEBRA_HEADER_MARKER) {
313 zlog_err(
314 "%s: socket %d version mismatch, marker %d, version %d",
315 __func__, sock, *marker, *version);
316 return -1;
317 }
318
319 if (*size && stream_read(s, sock, *size) != *size)
320 return -1;
321
ec93aa12 322stream_failure:
d62a17ae 323 return 0;
55119089
ND
324}
325
634f9ea2 326/* Send simple Zebra message. */
d62a17ae 327static int zebra_message_send(struct zclient *zclient, int command,
328 vrf_id_t vrf_id)
718e3744 329{
d62a17ae 330 struct stream *s;
718e3744 331
d62a17ae 332 /* Get zclient output buffer. */
333 s = zclient->obuf;
334 stream_reset(s);
718e3744 335
d62a17ae 336 /* Send very simple command only Zebra message. */
337 zclient_create_header(s, command, vrf_id);
338
339 return zclient_send_message(zclient);
718e3744 340}
341
d62a17ae 342static int zebra_hello_send(struct zclient *zclient)
2ea1ab1c 343{
d62a17ae 344 struct stream *s;
345
346 if (zclient->redist_default) {
347 s = zclient->obuf;
348 stream_reset(s);
349
350 /* The VRF ID in the HELLO message is always 0. */
351 zclient_create_header(s, ZEBRA_HELLO, VRF_DEFAULT);
352 stream_putc(s, zclient->redist_default);
353 stream_putw(s, zclient->instance);
e1a1880d
DS
354 if (zclient->receive_notify)
355 stream_putc(s, 1);
356 else
357 stream_putc(s, 0);
358
d62a17ae 359 stream_putw_at(s, 0, stream_get_endp(s));
360 return zclient_send_message(zclient);
361 }
362
363 return 0;
2ea1ab1c
VT
364}
365
c83c5e44 366void zclient_send_vrf_label(struct zclient *zclient, vrf_id_t vrf_id,
339e36d2 367 mpls_label_t label, enum lsp_types_t ltype)
c83c5e44
DS
368{
369 struct stream *s;
370
371 s = zclient->obuf;
372 stream_reset(s);
373
374 zclient_create_header(s, ZEBRA_VRF_LABEL, vrf_id);
375 stream_putl(s, label);
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]
418 .instances, node, id))
419 if (!(i == zclient->redist_default
420 && *id == zclient->instance))
421 zebra_redistribute_send(
422 ZEBRA_REDISTRIBUTE_ADD,
423 zclient, afi, i,
424 *id,
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]
483 .instances, node, id))
484 if (!(i == zclient->redist_default
485 && *id == zclient->instance))
486 zebra_redistribute_send(
487 ZEBRA_REDISTRIBUTE_DELETE,
488 zclient, afi, i,
489 *id,
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. */
342213ea
DS
585void zclient_init(struct zclient *zclient, int redist_default,
586 u_short instance, 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
DS
1022 default:
1023 zlog_warn("%s: Specified Nexthop type %d does not exist",
1024 __PRETTY_FUNCTION__, api_nh->type);
1025 return -1;
d62a17ae 1026 }
bb1b9c47 1027
52dd3aa4
RW
1028 /* MPLS labels for BGP-LU or Segment Routing */
1029 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_LABEL)) {
1030 if (api_nh->label_num > MPLS_MAX_LABELS) {
1031 char buf[PREFIX2STR_BUFFER];
1032 prefix2str(&api->prefix, buf,
1033 sizeof(buf));
1034 zlog_err(
1035 "%s: prefix %s: can't encode "
1036 "%u labels (maximum is %u)",
1037 __func__, buf,
1038 api_nh->label_num,
1039 MPLS_MAX_LABELS);
1040 return -1;
1041 }
1042
1043 stream_putc(s, api_nh->label_num);
1044 stream_put(s, &api_nh->labels[0],
1045 api_nh->label_num
1046 * sizeof(mpls_label_t));
1047 }
d62a17ae 1048 }
1049 }
1050
0e51b4a3 1051 /* Attributes. */
d62a17ae 1052 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_DISTANCE))
1053 stream_putc(s, api->distance);
1054 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_METRIC))
1055 stream_putl(s, api->metric);
1056 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TAG))
1057 stream_putl(s, api->tag);
1058 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_MTU))
1059 stream_putl(s, api->mtu);
1060
1061 /* Put length at the first point of the stream. */
1062 stream_putw_at(s, 0, stream_get_endp(s));
1063
0e51b4a3
RW
1064 return 0;
1065}
1066
1067int zapi_route_decode(struct stream *s, struct zapi_route *api)
1068{
1069 struct zapi_nexthop *api_nh;
1070 int i;
1071
1072 memset(api, 0, sizeof(*api));
1073
1074 /* Type, flags, message. */
ec93aa12
DS
1075 STREAM_GETC(s, api->type);
1076 if (api->type > ZEBRA_ROUTE_MAX) {
1077 zlog_warn("%s: Specified route type: %d is not a legal value\n",
1078 __PRETTY_FUNCTION__, api->type);
1079 return -1;
1080 }
1081
1082 STREAM_GETW(s, api->instance);
1083 STREAM_GETL(s, api->flags);
1084 STREAM_GETC(s, api->message);
832d0f56 1085 STREAM_GETC(s, api->safi);
90264d64 1086 if (CHECK_FLAG(api->flags, ZEBRA_FLAG_EVPN_ROUTE))
2dbad57f 1087 stream_get(&(api->rmac), s, sizeof(struct ethaddr));
0e51b4a3
RW
1088
1089 /* Prefix. */
ec93aa12
DS
1090 STREAM_GETC(s, api->prefix.family);
1091 STREAM_GETC(s, api->prefix.prefixlen);
0e51b4a3
RW
1092 switch (api->prefix.family) {
1093 case AF_INET:
ec93aa12
DS
1094 if (api->prefix.prefixlen > IPV4_MAX_PREFIXLEN) {
1095 zlog_warn("%s: V4 prefixlen is %d which should not be more than 32",
1096 __PRETTY_FUNCTION__, api->prefix.prefixlen);
1097 return -1;
1098 }
0e51b4a3
RW
1099 break;
1100 case AF_INET6:
ec93aa12
DS
1101 if (api->prefix.prefixlen > IPV6_MAX_PREFIXLEN) {
1102 zlog_warn("%s: v6 prefixlen is %d which should not be more than 128",
1103 __PRETTY_FUNCTION__, api->prefix.prefixlen);
1104 return -1;
1105 }
0e51b4a3 1106 break;
ec93aa12
DS
1107 default:
1108 zlog_warn("%s: Specified family %d is not v4 or v6",
1109 __PRETTY_FUNCTION__, api->prefix.family);
1110 return -1;
0e51b4a3 1111 }
ec93aa12
DS
1112 STREAM_GET(&api->prefix.u.prefix, s, PSIZE(api->prefix.prefixlen));
1113
0e51b4a3
RW
1114 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_SRCPFX)) {
1115 api->src_prefix.family = AF_INET6;
ec93aa12
DS
1116 STREAM_GETC(s, api->src_prefix.prefixlen);
1117 if (api->src_prefix.prefixlen > IPV6_MAX_PREFIXLEN) {
1118 zlog_warn("%s: SRC Prefix prefixlen received: %d is too large",
1119 __PRETTY_FUNCTION__,
1120 api->src_prefix.prefixlen);
1121 return -1;
1122 }
1123 STREAM_GET(&api->src_prefix.prefix, s,
0e51b4a3
RW
1124 PSIZE(api->src_prefix.prefixlen));
1125
1126 if (api->prefix.family != AF_INET6
ec93aa12
DS
1127 || api->src_prefix.prefixlen == 0) {
1128 zlog_warn("%s: SRC prefix specified in some manner that makes no sense",
1129 __PRETTY_FUNCTION__);
1130 return -1;
1131 }
0e51b4a3
RW
1132 }
1133
1134 /* Nexthops. */
1135 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) {
ec93aa12 1136 STREAM_GETW(s, api->nexthop_num);
0e51b4a3
RW
1137 if (api->nexthop_num > MULTIPATH_NUM) {
1138 zlog_warn("%s: invalid number of nexthops (%u)",
1139 __func__, api->nexthop_num);
1140 return -1;
1141 }
1142
1143 for (i = 0; i < api->nexthop_num; i++) {
1144 api_nh = &api->nexthops[i];
1145
4a7371e9 1146 STREAM_GETL(s, api_nh->vrf_id);
ec93aa12 1147 STREAM_GETC(s, api_nh->type);
0e51b4a3
RW
1148 switch (api_nh->type) {
1149 case NEXTHOP_TYPE_BLACKHOLE:
ec93aa12 1150 STREAM_GETC(s, api_nh->bh_type);
0e51b4a3
RW
1151 break;
1152 case NEXTHOP_TYPE_IPV4:
ec93aa12
DS
1153 STREAM_GET(&api_nh->gate.ipv4.s_addr, s,
1154 IPV4_MAX_BYTELEN);
0e51b4a3
RW
1155 break;
1156 case NEXTHOP_TYPE_IPV4_IFINDEX:
ec93aa12
DS
1157 STREAM_GET(&api_nh->gate.ipv4.s_addr, s,
1158 IPV4_MAX_BYTELEN);
1159 STREAM_GETL(s, api_nh->ifindex);
0e51b4a3
RW
1160 break;
1161 case NEXTHOP_TYPE_IFINDEX:
ec93aa12 1162 STREAM_GETL(s, api_nh->ifindex);
0e51b4a3
RW
1163 break;
1164 case NEXTHOP_TYPE_IPV6:
ec93aa12 1165 STREAM_GET(&api_nh->gate.ipv6, s, 16);
0e51b4a3
RW
1166 break;
1167 case NEXTHOP_TYPE_IPV6_IFINDEX:
ec93aa12
DS
1168 STREAM_GET(&api_nh->gate.ipv6, s, 16);
1169 STREAM_GETL(s, api_nh->ifindex);
0e51b4a3 1170 break;
ec93aa12
DS
1171 default:
1172 zlog_warn("%s: Specified nexthop type %d does not exist",
1173 __PRETTY_FUNCTION__,
1174 api_nh->type);
1175 return -1;
0e51b4a3
RW
1176 }
1177
52dd3aa4 1178 /* MPLS labels for BGP-LU or Segment Routing */
0e51b4a3 1179 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_LABEL)) {
ec93aa12 1180 STREAM_GETC(s, api_nh->label_num);
52dd3aa4
RW
1181
1182 if (api_nh->label_num > MPLS_MAX_LABELS) {
1183 zlog_warn(
1184 "%s: invalid number of MPLS "
1185 "labels (%u)",
1186 __func__, api_nh->label_num);
1187 return -1;
1188 }
1189
ec93aa12 1190 STREAM_GET(&api_nh->labels[0], s,
52dd3aa4
RW
1191 api_nh->label_num
1192 * sizeof(mpls_label_t));
0e51b4a3
RW
1193 }
1194 }
1195 }
1196
1197 /* Attributes. */
1198 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_DISTANCE))
ec93aa12 1199 STREAM_GETC(s, api->distance);
0e51b4a3 1200 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_METRIC))
ec93aa12 1201 STREAM_GETL(s, api->metric);
0e51b4a3 1202 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TAG))
ec93aa12 1203 STREAM_GETL(s, api->tag);
0e51b4a3 1204 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_MTU))
ec93aa12 1205 STREAM_GETL(s, api->mtu);
0e51b4a3 1206
ec93aa12 1207stream_failure:
0e51b4a3 1208 return 0;
657cde12
DS
1209}
1210
7ea7b86e
DS
1211bool zapi_route_notify_decode(struct stream *s, struct prefix *p,
1212 enum zapi_route_notify_owner *note)
1213{
1214 STREAM_GET(note, s, sizeof(*note));
1215
1216 STREAM_GETC(s, p->family);
1217 STREAM_GETC(s, p->prefixlen);
1218 STREAM_GET(&p->u.prefix, s,
1219 PSIZE(p->prefixlen));
1220
1221 return true;
1222
1223stream_failure:
1224 return false;
1225}
1226
4a749e2c
DS
1227struct nexthop *nexthop_from_zapi_nexthop(struct zapi_nexthop *znh)
1228{
1229 struct nexthop *n = nexthop_new();
1230
1231 n->type = znh->type;
4a7371e9 1232 n->vrf_id = znh->vrf_id;
4a749e2c
DS
1233 n->ifindex = znh->ifindex;
1234 n->gate = znh->gate;
1235
1236 /*
1237 * This function does not currently handle labels
1238 */
1239
1240 return n;
1241}
1242
1243bool zapi_nexthop_update_decode(struct stream *s, struct zapi_route *nhr)
1244{
1245 uint32_t i;
1246
1247 memset(nhr, 0, sizeof(*nhr));
1248
1249 STREAM_GETW(s, nhr->prefix.family);
1250 STREAM_GETC(s, nhr->prefix.prefixlen);
1251 switch(nhr->prefix.family) {
1252 case AF_INET:
1253 STREAM_GET(&nhr->prefix.u.prefix4.s_addr, s, IPV4_MAX_BYTELEN);
1254 break;
1255 case AF_INET6:
1256 STREAM_GET(&nhr->prefix.u.prefix6, s, IPV6_MAX_BYTELEN);
1257 break;
1258 default:
1259 break;
1260 }
1261
1262 STREAM_GETC(s, nhr->distance);
1263 STREAM_GETL(s, nhr->metric);
1264 STREAM_GETC(s, nhr->nexthop_num);
1265
1266 for (i = 0; i < nhr->nexthop_num ; i++) {
1267 STREAM_GETC(s, nhr->nexthops[i].type);
1268 switch (nhr->nexthops[i].type) {
1269 case NEXTHOP_TYPE_IPV4:
1270 case NEXTHOP_TYPE_IPV4_IFINDEX:
1271 STREAM_GET(&nhr->nexthops[i].gate.ipv4.s_addr,
1272 s, IPV4_MAX_BYTELEN);
1273 STREAM_GETL(s, nhr->nexthops[i].ifindex);
1274 break;
1275 case NEXTHOP_TYPE_IFINDEX:
1276 STREAM_GETL(s, nhr->nexthops[i].ifindex);
1277 break;
1278 case NEXTHOP_TYPE_IPV6:
1279 case NEXTHOP_TYPE_IPV6_IFINDEX:
1280 STREAM_GET(&nhr->nexthops[i].gate.ipv6,
1281 s, IPV6_MAX_BYTELEN);
1282 STREAM_GETL(s, nhr->nexthops[i].ifindex);
1283 break;
1284 case NEXTHOP_TYPE_BLACKHOLE:
1285 break;
1286 }
1287 }
1288
1289 return true;
1290stream_failure:
1291 return false;
1292}
1293
d62a17ae 1294/*
0a589359 1295 * send a ZEBRA_REDISTRIBUTE_ADD or ZEBRA_REDISTRIBUTE_DELETE
1296 * for the route type (ZEBRA_ROUTE_KERNEL etc.). The zebra server will
d62a17ae 1297 * then set/unset redist[type] in the client handle (a struct zserv) for the
0a589359 1298 * sending client
1299 */
d62a17ae 1300int zebra_redistribute_send(int command, struct zclient *zclient, afi_t afi,
1301 int type, u_short instance, vrf_id_t vrf_id)
718e3744 1302{
d62a17ae 1303 struct stream *s;
1304
1305 s = zclient->obuf;
1306 stream_reset(s);
1307
1308 zclient_create_header(s, command, vrf_id);
1309 stream_putc(s, afi);
1310 stream_putc(s, type);
1311 stream_putw(s, instance);
1312
1313 stream_putw_at(s, 0, stream_get_endp(s));
1314
1315 return zclient_send_message(zclient);
718e3744 1316}
1317
d9178828 1318/* Get prefix in ZServ format; family should be filled in on prefix */
d62a17ae 1319static void zclient_stream_get_prefix(struct stream *s, struct prefix *p)
d9178828 1320{
d62a17ae 1321 size_t plen = prefix_blen(p);
1322 u_char c;
1323 p->prefixlen = 0;
1324
1325 if (plen == 0)
1326 return;
1327
1328 stream_get(&p->u.prefix, s, plen);
ec93aa12 1329 STREAM_GETC(s, c);
d62a17ae 1330 p->prefixlen = MIN(plen * 8, c);
ec93aa12
DS
1331
1332stream_failure:
1333 return;
d9178828
PJ
1334}
1335
18a6dce6 1336/* Router-id update from zebra daemon. */
d62a17ae 1337void zebra_router_id_update_read(struct stream *s, struct prefix *rid)
18a6dce6 1338{
d62a17ae 1339 /* Fetch interface address. */
ec93aa12 1340 STREAM_GETC(s, rid->family);
d62a17ae 1341
1342 zclient_stream_get_prefix(s, rid);
ec93aa12
DS
1343
1344stream_failure:
1345 return;
18a6dce6 1346}
1347
718e3744 1348/* Interface addition from zebra daemon. */
d62a17ae 1349/*
0a589359 1350 * The format of the message sent with type ZEBRA_INTERFACE_ADD or
1351 * ZEBRA_INTERFACE_DELETE from zebra to the client is:
1352 * 0 1 2 3
1353 * 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 1354 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1355 * | ifname |
1356 * | |
1357 * | |
1358 * | |
1359 * | |
1360 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee
OD
1361 * | ifindex |
1362 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1363 * | status |
0a589359 1364 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee 1365 * | if_flags |
c77d4546 1366 * | |
0a589359 1367 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee
OD
1368 * | metric |
1369 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2d7f0d76
DS
1370 * | speed |
1371 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee
OD
1372 * | ifmtu |
1373 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1374 * | ifmtu6 |
1375 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1376 * | bandwidth |
1377 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1378 * | Link Layer Type |
0a589359 1379 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee 1380 * | Harware Address Length |
0a589359 1381 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee
OD
1382 * | Hardware Address if HW lenght different from 0 |
1383 * | ... max INTERFACE_HWADDR_MAX |
0a589359 1384 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee 1385 * | Link_params? | Whether a link-params follows: 1 or 0.
0a589359 1386 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee
OD
1387 * | Link_params 0 or 1 INTERFACE_LINK_PARAMS_SIZE sized |
1388 * | .... (struct if_link_params). |
0a589359 1389 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1390 */
1391
d62a17ae 1392static void zclient_vrf_add(struct zclient *zclient, vrf_id_t vrf_id)
1892f15e 1393{
d62a17ae 1394 struct vrf *vrf;
1395 char vrfname_tmp[VRF_NAMSIZ];
1396 struct vrf_data data;
1892f15e 1397
d62a17ae 1398 stream_get(&data, zclient->ibuf, sizeof(struct vrf_data));
1399 /* Read interface name. */
1400 stream_get(vrfname_tmp, zclient->ibuf, VRF_NAMSIZ);
1892f15e 1401
d62a17ae 1402 /* Lookup/create vrf by vrf_id. */
1403 vrf = vrf_get(vrf_id, vrfname_tmp);
1404 vrf->data = data;
1892f15e 1405
d62a17ae 1406 vrf_enable(vrf);
1892f15e
DS
1407}
1408
d62a17ae 1409static void zclient_vrf_delete(struct zclient *zclient, vrf_id_t vrf_id)
1892f15e 1410{
d62a17ae 1411 struct vrf *vrf;
1892f15e 1412
d62a17ae 1413 /* Lookup vrf by vrf_id. */
1414 vrf = vrf_lookup_by_id(vrf_id);
1892f15e 1415
d62a17ae 1416 /*
1417 * If a routing protocol doesn't know about a
1418 * vrf that is about to be deleted. There is
1419 * no point in attempting to delete it.
1420 */
1421 if (!vrf)
1422 return;
beef1990 1423
d62a17ae 1424 vrf_delete(vrf);
1892f15e
DS
1425}
1426
d62a17ae 1427struct interface *zebra_interface_add_read(struct stream *s, vrf_id_t vrf_id)
718e3744 1428{
d62a17ae 1429 struct interface *ifp;
1430 char ifname_tmp[INTERFACE_NAMSIZ];
718e3744 1431
d62a17ae 1432 /* Read interface name. */
1433 stream_get(ifname_tmp, s, INTERFACE_NAMSIZ);
718e3744 1434
d62a17ae 1435 /* Lookup/create interface by name. */
bcc24579 1436 ifp = if_get_by_name(ifname_tmp, vrf_id, 0);
718e3744 1437
d62a17ae 1438 zebra_interface_if_set_value(s, ifp);
718e3744 1439
d62a17ae 1440 return ifp;
718e3744 1441}
1442
d62a17ae 1443/*
0a589359 1444 * Read interface up/down msg (ZEBRA_INTERFACE_UP/ZEBRA_INTERFACE_DOWN)
1445 * from zebra server. The format of this message is the same as
1446 * that sent for ZEBRA_INTERFACE_ADD/ZEBRA_INTERFACE_DELETE (see
1447 * comments for zebra_interface_add_read), except that no sockaddr_dl
1448 * is sent at the tail of the message.
1449 */
d62a17ae 1450struct interface *zebra_interface_state_read(struct stream *s, vrf_id_t vrf_id)
718e3744 1451{
d62a17ae 1452 struct interface *ifp;
1453 char ifname_tmp[INTERFACE_NAMSIZ];
1454
1455 /* Read interface name. */
1456 stream_get(ifname_tmp, s, INTERFACE_NAMSIZ);
1457
1458 /* Lookup this by interface index. */
bcc24579 1459 ifp = if_lookup_by_name(ifname_tmp, vrf_id);
d62a17ae 1460 if (ifp == NULL) {
1461 zlog_warn("INTERFACE_STATE: Cannot find IF %s in VRF %d",
1462 ifname_tmp, vrf_id);
1463 return NULL;
1464 }
1465
1466 zebra_interface_if_set_value(s, ifp);
1467
1468 return ifp;
718e3744 1469}
1470
d62a17ae 1471static void link_params_set_value(struct stream *s, struct if_link_params *iflp)
16f1b9ee
OD
1472{
1473
d62a17ae 1474 if (iflp == NULL)
1475 return;
1476
1477 iflp->lp_status = stream_getl(s);
1478 iflp->te_metric = stream_getl(s);
1479 iflp->max_bw = stream_getf(s);
1480 iflp->max_rsv_bw = stream_getf(s);
1481 uint32_t bwclassnum = stream_getl(s);
1482 {
1483 unsigned int i;
1484 for (i = 0; i < bwclassnum && i < MAX_CLASS_TYPE; i++)
1485 iflp->unrsv_bw[i] = stream_getf(s);
1486 if (i < bwclassnum)
1487 zlog_err(
1488 "%s: received %d > %d (MAX_CLASS_TYPE) bw entries"
1489 " - outdated library?",
1490 __func__, bwclassnum, MAX_CLASS_TYPE);
1491 }
1492 iflp->admin_grp = stream_getl(s);
1493 iflp->rmt_as = stream_getl(s);
1494 iflp->rmt_ip.s_addr = stream_get_ipv4(s);
1495
1496 iflp->av_delay = stream_getl(s);
1497 iflp->min_delay = stream_getl(s);
1498 iflp->max_delay = stream_getl(s);
1499 iflp->delay_var = stream_getl(s);
1500
1501 iflp->pkt_loss = stream_getf(s);
1502 iflp->res_bw = stream_getf(s);
1503 iflp->ava_bw = stream_getf(s);
1504 iflp->use_bw = stream_getf(s);
16f1b9ee
OD
1505}
1506
d62a17ae 1507struct interface *zebra_interface_link_params_read(struct stream *s)
16f1b9ee 1508{
d62a17ae 1509 struct if_link_params *iflp;
1510 ifindex_t ifindex;
c28e5b2a 1511
d62a17ae 1512 assert(s);
c28e5b2a 1513
d62a17ae 1514 ifindex = stream_getl(s);
16f1b9ee 1515
d62a17ae 1516 struct interface *ifp = if_lookup_by_index(ifindex, VRF_DEFAULT);
16f1b9ee 1517
d62a17ae 1518 if (ifp == NULL) {
1519 zlog_err("%s: unknown ifindex %u, shouldn't happen", __func__,
1520 ifindex);
1521 return NULL;
1522 }
16f1b9ee 1523
d62a17ae 1524 if ((iflp = if_link_params_get(ifp)) == NULL)
1525 return NULL;
16f1b9ee 1526
d62a17ae 1527 link_params_set_value(s, iflp);
16f1b9ee 1528
d62a17ae 1529 return ifp;
16f1b9ee
OD
1530}
1531
d62a17ae 1532void zebra_interface_if_set_value(struct stream *s, struct interface *ifp)
16f1b9ee 1533{
d62a17ae 1534 u_char link_params_status = 0;
1535
1536 /* Read interface's index. */
ff880b78 1537 if_set_index(ifp, stream_getl(s));
d62a17ae 1538 ifp->status = stream_getc(s);
1539
1540 /* Read interface's value. */
1541 ifp->flags = stream_getq(s);
1542 ifp->ptm_enable = stream_getc(s);
1543 ifp->ptm_status = stream_getc(s);
1544 ifp->metric = stream_getl(s);
1545 ifp->speed = stream_getl(s);
1546 ifp->mtu = stream_getl(s);
1547 ifp->mtu6 = stream_getl(s);
1548 ifp->bandwidth = stream_getl(s);
1549 ifp->ll_type = stream_getl(s);
1550 ifp->hw_addr_len = stream_getl(s);
1551 if (ifp->hw_addr_len)
1552 stream_get(ifp->hw_addr, s,
1553 MIN(ifp->hw_addr_len, INTERFACE_HWADDR_MAX));
1554
1555 /* Read Traffic Engineering status */
1556 link_params_status = stream_getc(s);
1557 /* Then, Traffic Engineering parameters if any */
1558 if (link_params_status) {
1559 struct if_link_params *iflp = if_link_params_get(ifp);
1560 link_params_set_value(s, iflp);
1561 }
16f1b9ee
OD
1562}
1563
d62a17ae 1564size_t zebra_interface_link_params_write(struct stream *s,
1565 struct interface *ifp)
16f1b9ee 1566{
d62a17ae 1567 size_t w;
1568 struct if_link_params *iflp;
1569 int i;
16f1b9ee 1570
d62a17ae 1571 if (s == NULL || ifp == NULL || ifp->link_params == NULL)
1572 return 0;
16f1b9ee 1573
d62a17ae 1574 iflp = ifp->link_params;
1575 w = 0;
16f1b9ee 1576
d62a17ae 1577 w += stream_putl(s, iflp->lp_status);
16f1b9ee 1578
d62a17ae 1579 w += stream_putl(s, iflp->te_metric);
1580 w += stream_putf(s, iflp->max_bw);
1581 w += stream_putf(s, iflp->max_rsv_bw);
16f1b9ee 1582
d62a17ae 1583 w += stream_putl(s, MAX_CLASS_TYPE);
1584 for (i = 0; i < MAX_CLASS_TYPE; i++)
1585 w += stream_putf(s, iflp->unrsv_bw[i]);
16f1b9ee 1586
d62a17ae 1587 w += stream_putl(s, iflp->admin_grp);
1588 w += stream_putl(s, iflp->rmt_as);
1589 w += stream_put_in_addr(s, &iflp->rmt_ip);
16f1b9ee 1590
d62a17ae 1591 w += stream_putl(s, iflp->av_delay);
1592 w += stream_putl(s, iflp->min_delay);
1593 w += stream_putl(s, iflp->max_delay);
1594 w += stream_putl(s, iflp->delay_var);
16f1b9ee 1595
d62a17ae 1596 w += stream_putf(s, iflp->pkt_loss);
1597 w += stream_putf(s, iflp->res_bw);
1598 w += stream_putf(s, iflp->ava_bw);
1599 w += stream_putf(s, iflp->use_bw);
16f1b9ee 1600
d62a17ae 1601 return w;
16f1b9ee
OD
1602}
1603
1604/*
0a589359 1605 * format of message for address additon is:
1606 * 0
1607 * 0 1 2 3 4 5 6 7
1608 * +-+-+-+-+-+-+-+-+
1609 * | type | ZEBRA_INTERFACE_ADDRESS_ADD or
1610 * +-+-+-+-+-+-+-+-+ ZEBRA_INTERFACE_ADDRES_DELETE
1611 * | |
1612 * + +
1613 * | ifindex |
1614 * + +
1615 * | |
1616 * + +
1617 * | |
1618 * +-+-+-+-+-+-+-+-+
1619 * | ifc_flags | flags for connected address
1620 * +-+-+-+-+-+-+-+-+
1621 * | addr_family |
1622 * +-+-+-+-+-+-+-+-+
1623 * | addr... |
1624 * : :
1625 * | |
1626 * +-+-+-+-+-+-+-+-+
1627 * | addr_len | len of addr. E.g., addr_len = 4 for ipv4 addrs.
1628 * +-+-+-+-+-+-+-+-+
1629 * | daddr.. |
1630 * : :
1631 * | |
1632 * +-+-+-+-+-+-+-+-+
0a589359 1633 */
1634
d62a17ae 1635static int memconstant(const void *s, int c, size_t n)
3fb9cd6e 1636{
d62a17ae 1637 const u_char *p = s;
3fb9cd6e 1638
d62a17ae 1639 while (n-- > 0)
1640 if (*p++ != c)
1641 return 0;
1642 return 1;
3fb9cd6e 1643}
1644
d5a5c8f0 1645
d62a17ae 1646struct connected *zebra_interface_address_read(int type, struct stream *s,
1647 vrf_id_t vrf_id)
718e3744 1648{
d62a17ae 1649 ifindex_t ifindex;
1650 struct interface *ifp;
1651 struct connected *ifc;
1652 struct prefix p, d, *dp;
1653 int plen;
1654 u_char ifc_flags;
1655
1656 memset(&p, 0, sizeof(p));
1657 memset(&d, 0, sizeof(d));
1658
1659 /* Get interface index. */
1660 ifindex = stream_getl(s);
1661
1662 /* Lookup index. */
1663 ifp = if_lookup_by_index(ifindex, vrf_id);
1664 if (ifp == NULL) {
1665 zlog_warn("INTERFACE_ADDRESS_%s: Cannot find IF %u in VRF %d",
1666 (type == ZEBRA_INTERFACE_ADDRESS_ADD) ? "ADD" : "DEL",
1667 ifindex, vrf_id);
1668 return NULL;
1669 }
1670
1671 /* Fetch flag. */
1672 ifc_flags = stream_getc(s);
1673
1674 /* Fetch interface address. */
1675 d.family = p.family = stream_getc(s);
1676 plen = prefix_blen(&d);
1677
1678 zclient_stream_get_prefix(s, &p);
1679
1680 /* Fetch destination address. */
1681 stream_get(&d.u.prefix, s, plen);
1682
1683 /* N.B. NULL destination pointers are encoded as all zeroes */
1684 dp = memconstant(&d.u.prefix, 0, plen) ? NULL : &d;
1685
1686 if (type == ZEBRA_INTERFACE_ADDRESS_ADD) {
1687 ifc = connected_lookup_prefix_exact(ifp, &p);
1688 if (!ifc) {
1689 /* N.B. NULL destination pointers are encoded as all
1690 * zeroes */
1691 ifc = connected_add_by_prefix(ifp, &p, dp);
1692 }
1693 if (ifc) {
1694 ifc->flags = ifc_flags;
1695 if (ifc->destination)
1696 ifc->destination->prefixlen =
1697 ifc->address->prefixlen;
1698 else if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_PEER)) {
1699 /* carp interfaces on OpenBSD with 0.0.0.0/0 as
1700 * "peer" */
1701 char buf[PREFIX_STRLEN];
1702 zlog_warn(
1703 "warning: interface %s address %s "
1704 "with peer flag set, but no peer address!",
9d303b37
DL
1705 ifp->name, prefix2str(ifc->address, buf,
1706 sizeof buf));
d62a17ae 1707 UNSET_FLAG(ifc->flags, ZEBRA_IFA_PEER);
1708 }
1709 }
1710 } else {
1711 assert(type == ZEBRA_INTERFACE_ADDRESS_DELETE);
1712 ifc = connected_delete_by_prefix(ifp, &p);
1713 }
1714
1715 return ifc;
718e3744 1716}
0a589359 1717
a80beece
DS
1718/*
1719 * format of message for neighbor connected address is:
1720 * 0
1721 * 0 1 2 3 4 5 6 7
1722 * +-+-+-+-+-+-+-+-+
1723 * | type | ZEBRA_INTERFACE_NBR_ADDRESS_ADD or
1724 * +-+-+-+-+-+-+-+-+ ZEBRA_INTERFACE_NBR_ADDRES_DELETE
1725 * | |
1726 * + +
1727 * | ifindex |
1728 * + +
1729 * | |
1730 * + +
1731 * | |
1732 * +-+-+-+-+-+-+-+-+
1733 * | addr_family |
1734 * +-+-+-+-+-+-+-+-+
1735 * | addr... |
1736 * : :
1737 * | |
1738 * +-+-+-+-+-+-+-+-+
1739 * | addr_len | len of addr.
1740 * +-+-+-+-+-+-+-+-+
1741 */
1742struct nbr_connected *
d62a17ae 1743zebra_interface_nbr_address_read(int type, struct stream *s, vrf_id_t vrf_id)
a80beece 1744{
d62a17ae 1745 unsigned int ifindex;
1746 struct interface *ifp;
1747 struct prefix p;
1748 struct nbr_connected *ifc;
1749
1750 /* Get interface index. */
1751 ifindex = stream_getl(s);
1752
1753 /* Lookup index. */
1754 ifp = if_lookup_by_index(ifindex, vrf_id);
1755 if (ifp == NULL) {
1756 zlog_warn("INTERFACE_NBR_%s: Cannot find IF %u in VRF %d",
1757 (type == ZEBRA_INTERFACE_NBR_ADDRESS_ADD) ? "ADD"
1758 : "DELETE",
1759 ifindex, vrf_id);
1760 return NULL;
1761 }
1762
1763 p.family = stream_getc(s);
1764 stream_get(&p.u.prefix, s, prefix_blen(&p));
1765 p.prefixlen = stream_getc(s);
1766
1767 if (type == ZEBRA_INTERFACE_NBR_ADDRESS_ADD) {
1768 /* Currently only supporting P2P links, so any new RA source
1769 address is
1770 considered as the replacement of the previously learnt
1771 Link-Local address. */
1772 if (!(ifc = listnode_head(ifp->nbr_connected))) {
1773 ifc = nbr_connected_new();
1774 ifc->address = prefix_new();
1775 ifc->ifp = ifp;
1776 listnode_add(ifp->nbr_connected, ifc);
1777 }
1778
1779 prefix_copy(ifc->address, &p);
1780 } else {
1781 assert(type == ZEBRA_INTERFACE_NBR_ADDRESS_DELETE);
1782
1783 ifc = nbr_connected_check(ifp, &p);
1784 if (ifc)
1785 listnode_delete(ifp->nbr_connected, ifc);
1786 }
1787
1788 return ifc;
a80beece 1789}
6b0655a2 1790
d62a17ae 1791struct interface *zebra_interface_vrf_update_read(struct stream *s,
1792 vrf_id_t vrf_id,
1793 vrf_id_t *new_vrf_id)
c8e264b6 1794{
d62a17ae 1795 unsigned int ifindex;
1796 struct interface *ifp;
a9ff90c4 1797 vrf_id_t new_id;
d62a17ae 1798
1799 /* Get interface index. */
1800 ifindex = stream_getl(s);
1801
1802 /* Lookup interface. */
1803 ifp = if_lookup_by_index(ifindex, vrf_id);
1804 if (ifp == NULL) {
1805 zlog_warn("INTERFACE_VRF_UPDATE: Cannot find IF %u in VRF %d",
1806 ifindex, vrf_id);
1807 return NULL;
1808 }
1809
1810 /* Fetch new VRF Id. */
1811 new_id = stream_getw(s);
1812
1813 *new_vrf_id = new_id;
1814 return ifp;
c8e264b6 1815}
5c7ef8dc 1816
1817/* filter unwanted messages until the expected one arrives */
d62a17ae 1818static int zclient_read_sync_response(struct zclient *zclient,
1819 u_int16_t expected_cmd)
5c7ef8dc 1820{
d62a17ae 1821 struct stream *s;
c31a793b 1822 u_int16_t size = -1;
d62a17ae 1823 u_char marker;
1824 u_char version;
1825 vrf_id_t vrf_id;
1826 u_int16_t cmd;
1827 fd_set readfds;
1828 int ret;
1829
1830 ret = 0;
1831 cmd = expected_cmd + 1;
1832 while (ret == 0 && cmd != expected_cmd) {
1833 s = zclient->ibuf;
1834 stream_reset(s);
1835
1836 /* wait until response arrives */
1837 FD_ZERO(&readfds);
1838 FD_SET(zclient->sock, &readfds);
1839 select(zclient->sock + 1, &readfds, NULL, NULL, NULL);
1840 if (!FD_ISSET(zclient->sock, &readfds))
1841 continue;
1842 /* read response */
1843 ret = zclient_read_header(s, zclient->sock, &size, &marker,
1844 &version, &vrf_id, &cmd);
1845 if (zclient_debug)
1846 zlog_debug("%s: Response (%d bytes) received", __func__,
1847 size);
1848 }
1849 if (ret != 0) {
1850 zlog_err("%s: Invalid Sync Message Reply", __func__);
1851 return -1;
1852 }
1853
1854 return 0;
5c7ef8dc 1855}
fea12efb 1856/**
1857 * Connect to label manager in a syncronous way
1858 *
1859 * It first writes the request to zcient output buffer and then
1860 * immediately reads the answer from the input buffer.
1861 *
1862 * @param zclient Zclient used to connect to label manager (zebra)
1863 * @result Result of response
1864 */
d62a17ae 1865int lm_label_manager_connect(struct zclient *zclient)
fea12efb 1866{
d62a17ae 1867 int ret;
1868 struct stream *s;
1869 u_char result;
1870
1871 if (zclient_debug)
1872 zlog_debug("Connecting to Label Manager");
1873
1874 if (zclient->sock < 0)
1875 return -1;
1876
1877 /* send request */
1878 s = zclient->obuf;
1879 stream_reset(s);
1880 zclient_create_header(s, ZEBRA_LABEL_MANAGER_CONNECT, VRF_DEFAULT);
1881
1882 /* proto */
1883 stream_putc(s, zclient->redist_default);
1884 /* instance */
1885 stream_putw(s, zclient->instance);
1886
1887 /* Put length at the first point of the stream. */
1888 stream_putw_at(s, 0, stream_get_endp(s));
1889
1890 ret = writen(zclient->sock, s->data, stream_get_endp(s));
1891 if (ret < 0) {
1892 zlog_err("%s: can't write to zclient->sock", __func__);
1893 close(zclient->sock);
1894 zclient->sock = -1;
1895 return -1;
1896 }
1897 if (ret == 0) {
1898 zlog_err("%s: zclient->sock connection closed", __func__);
1899 close(zclient->sock);
1900 zclient->sock = -1;
1901 return -1;
1902 }
1903 if (zclient_debug)
1904 zlog_debug("%s: Label manager connect request (%d bytes) sent",
1905 __func__, ret);
1906
1907 /* read response */
1908 if (zclient_read_sync_response(zclient, ZEBRA_LABEL_MANAGER_CONNECT)
1909 != 0)
1910 return -1;
1911
1912 /* result */
1913 s = zclient->ibuf;
1914 result = stream_getc(s);
1915 if (zclient_debug)
1916 zlog_debug(
1917 "%s: Label Manager connect response received, result %u",
1918 __func__, result);
1919
1920 return (int)result;
fea12efb 1921}
1922
1923/**
1924 * Function to request a label chunk in a syncronous way
1925 *
1926 * It first writes the request to zlcient output buffer and then
1927 * immediately reads the answer from the input buffer.
1928 *
1929 * @param zclient Zclient used to connect to label manager (zebra)
1930 * @param keep Avoid garbage collection
1931 * @param chunk_size Amount of labels requested
1932 * @param start To write first assigned chunk label to
1933 * @param end To write last assigned chunk label to
1934 * @result 0 on success, -1 otherwise
1935 */
d62a17ae 1936int lm_get_label_chunk(struct zclient *zclient, u_char keep,
1937 uint32_t chunk_size, uint32_t *start, uint32_t *end)
fea12efb 1938{
d62a17ae 1939 int ret;
1940 struct stream *s;
1941 u_char response_keep;
1942
1943 if (zclient_debug)
1944 zlog_debug("Getting Label Chunk");
1945
1946 if (zclient->sock < 0)
1947 return -1;
1948
1949 /* send request */
1950 s = zclient->obuf;
1951 stream_reset(s);
1952 zclient_create_header(s, ZEBRA_GET_LABEL_CHUNK, VRF_DEFAULT);
1953 /* keep */
1954 stream_putc(s, keep);
1955 /* chunk size */
1956 stream_putl(s, chunk_size);
1957 /* Put length at the first point of the stream. */
1958 stream_putw_at(s, 0, stream_get_endp(s));
1959
1960 ret = writen(zclient->sock, s->data, stream_get_endp(s));
1961 if (ret < 0) {
1962 zlog_err("%s: can't write to zclient->sock", __func__);
1963 close(zclient->sock);
1964 zclient->sock = -1;
1965 return -1;
1966 }
1967 if (ret == 0) {
1968 zlog_err("%s: zclient->sock connection closed", __func__);
1969 close(zclient->sock);
1970 zclient->sock = -1;
1971 return -1;
1972 }
1973 if (zclient_debug)
1974 zlog_debug("%s: Label chunk request (%d bytes) sent", __func__,
1975 ret);
1976
1977 /* read response */
1978 if (zclient_read_sync_response(zclient, ZEBRA_GET_LABEL_CHUNK) != 0)
1979 return -1;
1980
1981 s = zclient->ibuf;
1982 /* keep */
1983 response_keep = stream_getc(s);
1984 /* start and end labels */
1985 *start = stream_getl(s);
1986 *end = stream_getl(s);
1987
1988 /* not owning this response */
1989 if (keep != response_keep) {
1990 zlog_err(
1991 "%s: Invalid Label chunk: %u - %u, keeps mismatch %u != %u",
1992 __func__, *start, *end, keep, response_keep);
1993 }
1994 /* sanity */
70e98a7f
DS
1995 if (*start > *end || *start < MPLS_LABEL_UNRESERVED_MIN
1996 || *end > MPLS_LABEL_UNRESERVED_MAX) {
d62a17ae 1997 zlog_err("%s: Invalid Label chunk: %u - %u", __func__, *start,
1998 *end);
1999 return -1;
2000 }
2001
2002 if (zclient_debug)
2003 zlog_debug("Label Chunk assign: %u - %u (%u) ", *start, *end,
2004 response_keep);
2005
2006 return 0;
fea12efb 2007}
2008
2009/**
2010 * Function to release a label chunk
2011 *
2012 * @param zclient Zclient used to connect to label manager (zebra)
2013 * @param start First label of chunk
2014 * @param end Last label of chunk
2015 * @result 0 on success, -1 otherwise
2016 */
d62a17ae 2017int lm_release_label_chunk(struct zclient *zclient, uint32_t start,
2018 uint32_t end)
fea12efb 2019{
d62a17ae 2020 int ret;
2021 struct stream *s;
2022
2023 if (zclient_debug)
2024 zlog_debug("Releasing Label Chunk");
2025
2026 if (zclient->sock < 0)
2027 return -1;
2028
2029 /* send request */
2030 s = zclient->obuf;
2031 stream_reset(s);
2032 zclient_create_header(s, ZEBRA_RELEASE_LABEL_CHUNK, VRF_DEFAULT);
2033
2034 /* start */
2035 stream_putl(s, start);
2036 /* end */
2037 stream_putl(s, end);
2038
2039 /* Put length at the first point of the stream. */
2040 stream_putw_at(s, 0, stream_get_endp(s));
2041
2042 ret = writen(zclient->sock, s->data, stream_get_endp(s));
2043 if (ret < 0) {
2044 zlog_err("%s: can't write to zclient->sock", __func__);
2045 close(zclient->sock);
2046 zclient->sock = -1;
2047 return -1;
2048 }
2049 if (ret == 0) {
2050 zlog_err("%s: zclient->sock connection closed", __func__);
2051 close(zclient->sock);
2052 zclient->sock = -1;
2053 return -1;
2054 }
2055
2056 return 0;
fea12efb 2057}
c8e264b6 2058
6833ae01 2059int zebra_send_pw(struct zclient *zclient, int command, struct zapi_pw *pw)
2060{
2061 struct stream *s;
2062
2063 /* Reset stream. */
2064 s = zclient->obuf;
2065 stream_reset(s);
2066
2067 zclient_create_header(s, command, VRF_DEFAULT);
2068 stream_write(s, pw->ifname, IF_NAMESIZE);
2069 stream_putl(s, pw->ifindex);
2070
2071 /* Put type */
2072 stream_putl(s, pw->type);
2073
2074 /* Put nexthop */
2075 stream_putl(s, pw->af);
2076 switch (pw->af) {
2077 case AF_INET:
2078 stream_put_in_addr(s, &pw->nexthop.ipv4);
2079 break;
2080 case AF_INET6:
2081 stream_write(s, (u_char *)&pw->nexthop.ipv6, 16);
2082 break;
2083 default:
2084 zlog_err("%s: unknown af", __func__);
2085 return -1;
2086 }
2087
2088 /* Put labels */
2089 stream_putl(s, pw->local_label);
2090 stream_putl(s, pw->remote_label);
2091
2092 /* Put flags */
2093 stream_putc(s, pw->flags);
2094
2095 /* Protocol specific fields */
2096 stream_write(s, &pw->data, sizeof(union pw_protocol_fields));
2097
2098 /* Put length at the first point of the stream. */
2099 stream_putw_at(s, 0, stream_get_endp(s));
2100
2101 return zclient_send_message(zclient);
2102}
2103
2104/*
2105 * Receive PW status update from Zebra and send it to LDE process.
2106 */
2107void zebra_read_pw_status_update(int command, struct zclient *zclient,
2108 zebra_size_t length, vrf_id_t vrf_id,
2109 struct zapi_pw_status *pw)
2110{
2111 struct stream *s;
2112
2113 memset(pw, 0, sizeof(struct zapi_pw_status));
2114 s = zclient->ibuf;
2115
2116 /* Get data. */
2117 stream_get(pw->ifname, s, IF_NAMESIZE);
2118 pw->ifindex = stream_getl(s);
2119 pw->status = stream_getl(s);
2120}
2121
718e3744 2122/* Zebra client message read function. */
d62a17ae 2123static int zclient_read(struct thread *thread)
718e3744 2124{
d62a17ae 2125 size_t already;
2126 uint16_t length, command;
2127 uint8_t marker, version;
2128 vrf_id_t vrf_id;
2129 struct zclient *zclient;
2130
2131 /* Get socket to zebra. */
2132 zclient = THREAD_ARG(thread);
2133 zclient->t_read = NULL;
2134
2135 /* Read zebra header (if we don't have it already). */
2136 if ((already = stream_get_endp(zclient->ibuf)) < ZEBRA_HEADER_SIZE) {
2137 ssize_t nbyte;
2138 if (((nbyte = stream_read_try(zclient->ibuf, zclient->sock,
2139 ZEBRA_HEADER_SIZE - already))
2140 == 0)
2141 || (nbyte == -1)) {
2142 if (zclient_debug)
2143 zlog_debug(
2144 "zclient connection closed socket [%d].",
2145 zclient->sock);
2146 return zclient_failed(zclient);
2147 }
2148 if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE - already)) {
2149 /* Try again later. */
2150 zclient_event(ZCLIENT_READ, zclient);
2151 return 0;
2152 }
2153 already = ZEBRA_HEADER_SIZE;
634f9ea2 2154 }
d62a17ae 2155
2156 /* Reset to read from the beginning of the incoming packet. */
2157 stream_set_getp(zclient->ibuf, 0);
2158
2159 /* Fetch header values. */
2160 length = stream_getw(zclient->ibuf);
2161 marker = stream_getc(zclient->ibuf);
2162 version = stream_getc(zclient->ibuf);
a9ff90c4 2163 vrf_id = stream_getl(zclient->ibuf);
d62a17ae 2164 command = stream_getw(zclient->ibuf);
2165
2166 if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION) {
2167 zlog_err(
2168 "%s: socket %d version mismatch, marker %d, version %d",
2169 __func__, zclient->sock, marker, version);
2170 return zclient_failed(zclient);
634f9ea2 2171 }
d62a17ae 2172
2173 if (length < ZEBRA_HEADER_SIZE) {
2174 zlog_err("%s: socket %d message length %u is less than %d ",
2175 __func__, zclient->sock, length, ZEBRA_HEADER_SIZE);
2176 return zclient_failed(zclient);
634f9ea2 2177 }
d62a17ae 2178
2179 /* Length check. */
2180 if (length > STREAM_SIZE(zclient->ibuf)) {
2181 struct stream *ns;
2182 zlog_warn(
2183 "%s: message size %u exceeds buffer size %lu, expanding...",
2184 __func__, length, (u_long)STREAM_SIZE(zclient->ibuf));
2185 ns = stream_new(length);
2186 stream_copy(ns, zclient->ibuf);
2187 stream_free(zclient->ibuf);
2188 zclient->ibuf = ns;
2189 }
2190
2191 /* Read rest of zebra packet. */
2192 if (already < length) {
2193 ssize_t nbyte;
2194 if (((nbyte = stream_read_try(zclient->ibuf, zclient->sock,
2195 length - already))
2196 == 0)
2197 || (nbyte == -1)) {
2198 if (zclient_debug)
2199 zlog_debug(
2200 "zclient connection closed socket [%d].",
2201 zclient->sock);
2202 return zclient_failed(zclient);
2203 }
2204 if (nbyte != (ssize_t)(length - already)) {
2205 /* Try again later. */
2206 zclient_event(ZCLIENT_READ, zclient);
2207 return 0;
2208 }
2209 }
2210
2211 length -= ZEBRA_HEADER_SIZE;
2212
2213 if (zclient_debug)
2214 zlog_debug("zclient 0x%p command 0x%x VRF %u\n",
2215 (void *)zclient, command, vrf_id);
2216
2217 switch (command) {
2218 case ZEBRA_ROUTER_ID_UPDATE:
2219 if (zclient->router_id_update)
2220 (*zclient->router_id_update)(command, zclient, length,
2221 vrf_id);
2222 break;
2223 case ZEBRA_VRF_ADD:
2224 zclient_vrf_add(zclient, vrf_id);
2225 break;
2226 case ZEBRA_VRF_DELETE:
2227 zclient_vrf_delete(zclient, vrf_id);
2228 break;
2229 case ZEBRA_INTERFACE_ADD:
2230 if (zclient->interface_add)
2231 (*zclient->interface_add)(command, zclient, length,
2232 vrf_id);
2233 break;
2234 case ZEBRA_INTERFACE_DELETE:
2235 if (zclient->interface_delete)
2236 (*zclient->interface_delete)(command, zclient, length,
2237 vrf_id);
2238 break;
2239 case ZEBRA_INTERFACE_ADDRESS_ADD:
2240 if (zclient->interface_address_add)
2241 (*zclient->interface_address_add)(command, zclient,
2242 length, vrf_id);
2243 break;
2244 case ZEBRA_INTERFACE_ADDRESS_DELETE:
2245 if (zclient->interface_address_delete)
2246 (*zclient->interface_address_delete)(command, zclient,
2247 length, vrf_id);
2248 break;
2249 case ZEBRA_INTERFACE_BFD_DEST_UPDATE:
2250 if (zclient->interface_bfd_dest_update)
2251 (*zclient->interface_bfd_dest_update)(command, zclient,
2252 length, vrf_id);
2253 break;
2254 case ZEBRA_INTERFACE_NBR_ADDRESS_ADD:
2255 if (zclient->interface_nbr_address_add)
2256 (*zclient->interface_nbr_address_add)(command, zclient,
2257 length, vrf_id);
2258 break;
2259 case ZEBRA_INTERFACE_NBR_ADDRESS_DELETE:
2260 if (zclient->interface_nbr_address_delete)
2261 (*zclient->interface_nbr_address_delete)(
2262 command, zclient, length, vrf_id);
2263 break;
2264 case ZEBRA_INTERFACE_UP:
2265 if (zclient->interface_up)
2266 (*zclient->interface_up)(command, zclient, length,
2267 vrf_id);
2268 break;
2269 case ZEBRA_INTERFACE_DOWN:
2270 if (zclient->interface_down)
2271 (*zclient->interface_down)(command, zclient, length,
2272 vrf_id);
2273 break;
2274 case ZEBRA_INTERFACE_VRF_UPDATE:
2275 if (zclient->interface_vrf_update)
2276 (*zclient->interface_vrf_update)(command, zclient,
2277 length, vrf_id);
2278 break;
2279 case ZEBRA_NEXTHOP_UPDATE:
2280 if (zclient_debug)
2281 zlog_debug("zclient rcvd nexthop update\n");
2282 if (zclient->nexthop_update)
2283 (*zclient->nexthop_update)(command, zclient, length,
2284 vrf_id);
2285 break;
2286 case ZEBRA_IMPORT_CHECK_UPDATE:
2287 if (zclient_debug)
2288 zlog_debug("zclient rcvd import check update\n");
2289 if (zclient->import_check_update)
2290 (*zclient->import_check_update)(command, zclient,
2291 length, vrf_id);
2292 break;
2293 case ZEBRA_BFD_DEST_REPLAY:
2294 if (zclient->bfd_dest_replay)
2295 (*zclient->bfd_dest_replay)(command, zclient, length,
2296 vrf_id);
2297 break;
74489921
RW
2298 case ZEBRA_REDISTRIBUTE_ROUTE_ADD:
2299 if (zclient->redistribute_route_add)
2300 (*zclient->redistribute_route_add)(command, zclient,
2301 length, vrf_id);
d62a17ae 2302 break;
74489921
RW
2303 case ZEBRA_REDISTRIBUTE_ROUTE_DEL:
2304 if (zclient->redistribute_route_del)
2305 (*zclient->redistribute_route_del)(command, zclient,
2306 length, vrf_id);
d62a17ae 2307 break;
2308 case ZEBRA_INTERFACE_LINK_PARAMS:
2309 if (zclient->interface_link_params)
2310 (*zclient->interface_link_params)(command, zclient,
2311 length);
2312 break;
2313 case ZEBRA_FEC_UPDATE:
2314 if (zclient_debug)
2315 zlog_debug("zclient rcvd fec update\n");
2316 if (zclient->fec_update)
2317 (*zclient->fec_update)(command, zclient, length);
2318 break;
2319 case ZEBRA_VNI_ADD:
2320 if (zclient->local_vni_add)
2321 (*zclient->local_vni_add)(command, zclient, length,
2322 vrf_id);
2323 break;
2324 case ZEBRA_VNI_DEL:
2325 if (zclient->local_vni_del)
2326 (*zclient->local_vni_del)(command, zclient, length,
2327 vrf_id);
2328 break;
b7cfce93
MK
2329 case ZEBRA_L3VNI_ADD:
2330 if (zclient->local_l3vni_add)
2331 (*zclient->local_l3vni_add)(command, zclient, length,
2332 vrf_id);
2333 break;
2334 case ZEBRA_L3VNI_DEL:
2335 if (zclient->local_l3vni_del)
2336 (*zclient->local_l3vni_del)(command, zclient, length,
2337 vrf_id);
2338 break;
d62a17ae 2339 case ZEBRA_MACIP_ADD:
2340 if (zclient->local_macip_add)
2341 (*zclient->local_macip_add)(command, zclient, length,
2342 vrf_id);
2343 break;
2344 case ZEBRA_MACIP_DEL:
2345 if (zclient->local_macip_del)
2346 (*zclient->local_macip_del)(command, zclient, length,
2347 vrf_id);
2348 break;
31310b25
MK
2349 case ZEBRA_IP_PREFIX_ROUTE_ADD:
2350 if (zclient->local_ip_prefix_add)
2351 (*zclient->local_ip_prefix_add)(command, zclient,
2352 length, vrf_id);
2353 break;
2354 case ZEBRA_IP_PREFIX_ROUTE_DEL:
2355 if (zclient->local_ip_prefix_del)
2356 (*zclient->local_ip_prefix_del)(command, zclient,
2357 length, vrf_id);
2358 break;
6833ae01 2359 case ZEBRA_PW_STATUS_UPDATE:
2360 if (zclient->pw_status_update)
2361 (*zclient->pw_status_update)(command, zclient, length,
2362 vrf_id);
2363 break;
7ea7b86e
DS
2364 case ZEBRA_ROUTE_NOTIFY_OWNER:
2365 if (zclient->notify_owner)
2366 (*zclient->notify_owner)(command, zclient,
2367 length, vrf_id);
2368 break;
d62a17ae 2369 default:
2370 break;
634f9ea2 2371 }
d62a17ae 2372
2373 if (zclient->sock < 0)
2374 /* Connection was closed during packet processing. */
2375 return -1;
2376
2377 /* Register read thread. */
2378 stream_reset(zclient->ibuf);
2379 zclient_event(ZCLIENT_READ, zclient);
2380
2381 return 0;
718e3744 2382}
2383
d62a17ae 2384void zclient_redistribute(int command, struct zclient *zclient, afi_t afi,
2385 int type, u_short instance, vrf_id_t vrf_id)
718e3744 2386{
718e3744 2387
d62a17ae 2388 if (instance) {
2389 if (command == ZEBRA_REDISTRIBUTE_ADD) {
2390 if (redist_check_instance(
2391 &zclient->mi_redist[afi][type], instance))
2392 return;
2393 redist_add_instance(&zclient->mi_redist[afi][type],
2394 instance);
2395 } else {
2396 if (!redist_check_instance(
2397 &zclient->mi_redist[afi][type], instance))
2398 return;
2399 redist_del_instance(&zclient->mi_redist[afi][type],
2400 instance);
2401 }
2402
2403 } else {
2404 if (command == ZEBRA_REDISTRIBUTE_ADD) {
2405 if (vrf_bitmap_check(zclient->redist[afi][type],
2406 vrf_id))
2407 return;
2408 vrf_bitmap_set(zclient->redist[afi][type], vrf_id);
2409 } else {
2410 if (!vrf_bitmap_check(zclient->redist[afi][type],
2411 vrf_id))
2412 return;
2413 vrf_bitmap_unset(zclient->redist[afi][type], vrf_id);
2414 }
2415 }
2416
2417 if (zclient->sock > 0)
2418 zebra_redistribute_send(command, zclient, afi, type, instance,
2419 vrf_id);
718e3744 2420}
2421
718e3744 2422
d62a17ae 2423void zclient_redistribute_default(int command, struct zclient *zclient,
2424 vrf_id_t vrf_id)
718e3744 2425{
718e3744 2426
d62a17ae 2427 if (command == ZEBRA_REDISTRIBUTE_DEFAULT_ADD) {
2428 if (vrf_bitmap_check(zclient->default_information, vrf_id))
2429 return;
2430 vrf_bitmap_set(zclient->default_information, vrf_id);
2431 } else {
2432 if (!vrf_bitmap_check(zclient->default_information, vrf_id))
2433 return;
2434 vrf_bitmap_unset(zclient->default_information, vrf_id);
2435 }
2436
2437 if (zclient->sock > 0)
2438 zebra_message_send(zclient, command, vrf_id);
718e3744 2439}
2440
d62a17ae 2441static void zclient_event(enum event event, struct zclient *zclient)
718e3744 2442{
d62a17ae 2443 switch (event) {
2444 case ZCLIENT_SCHEDULE:
2445 thread_add_event(zclient->master, zclient_connect, zclient, 0,
2446 &zclient->t_connect);
2447 break;
2448 case ZCLIENT_CONNECT:
2449 if (zclient_debug)
2450 zlog_debug(
2451 "zclient connect failures: %d schedule interval is now %d",
2452 zclient->fail, zclient->fail < 3 ? 10 : 60);
2453 thread_add_timer(zclient->master, zclient_connect, zclient,
2454 zclient->fail < 3 ? 10 : 60,
2455 &zclient->t_connect);
2456 break;
2457 case ZCLIENT_READ:
2458 zclient->t_read = NULL;
2459 thread_add_read(zclient->master, zclient_read, zclient,
2460 zclient->sock, &zclient->t_read);
2461 break;
2462 }
718e3744 2463}
b5114685 2464
e0ae31b8
DS
2465void zclient_interface_set_master(struct zclient *client,
2466 struct interface *master,
2467 struct interface *slave)
2468{
2469 struct stream *s;
2470
2471 s = client->obuf;
2472 stream_reset(s);
2473
2474 zclient_create_header(s, ZEBRA_INTERFACE_SET_MASTER, master->vrf_id);
2475
a9ff90c4 2476 stream_putl(s, master->vrf_id);
e0ae31b8 2477 stream_putl(s, master->ifindex);
a9ff90c4 2478 stream_putl(s, slave->vrf_id);
e0ae31b8
DS
2479 stream_putl(s, slave->ifindex);
2480
2481 stream_putw_at(s, 0, stream_get_endp(s));
2482 zclient_send_message(client);
2483}