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