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