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