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