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