]> git.proxmox.com Git - mirror_frr.git/blame - lib/zclient.c
*: add git-reindent-branch.py
[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!",
c14777c6 1483 ifp->name,
1484 prefix2str(ifc->address, buf,
1485 sizeof buf));
d62a17ae 1486 UNSET_FLAG(ifc->flags, ZEBRA_IFA_PEER);
1487 }
1488 }
1489 } else {
1490 assert(type == ZEBRA_INTERFACE_ADDRESS_DELETE);
1491 ifc = connected_delete_by_prefix(ifp, &p);
1492 }
1493
1494 return ifc;
718e3744 1495}
0a589359 1496
a80beece
DS
1497/*
1498 * format of message for neighbor connected address is:
1499 * 0
1500 * 0 1 2 3 4 5 6 7
1501 * +-+-+-+-+-+-+-+-+
1502 * | type | ZEBRA_INTERFACE_NBR_ADDRESS_ADD or
1503 * +-+-+-+-+-+-+-+-+ ZEBRA_INTERFACE_NBR_ADDRES_DELETE
1504 * | |
1505 * + +
1506 * | ifindex |
1507 * + +
1508 * | |
1509 * + +
1510 * | |
1511 * +-+-+-+-+-+-+-+-+
1512 * | addr_family |
1513 * +-+-+-+-+-+-+-+-+
1514 * | addr... |
1515 * : :
1516 * | |
1517 * +-+-+-+-+-+-+-+-+
1518 * | addr_len | len of addr.
1519 * +-+-+-+-+-+-+-+-+
1520 */
1521struct nbr_connected *
d62a17ae 1522zebra_interface_nbr_address_read(int type, struct stream *s, vrf_id_t vrf_id)
a80beece 1523{
d62a17ae 1524 unsigned int ifindex;
1525 struct interface *ifp;
1526 struct prefix p;
1527 struct nbr_connected *ifc;
1528
1529 /* Get interface index. */
1530 ifindex = stream_getl(s);
1531
1532 /* Lookup index. */
1533 ifp = if_lookup_by_index(ifindex, vrf_id);
1534 if (ifp == NULL) {
1535 zlog_warn("INTERFACE_NBR_%s: Cannot find IF %u in VRF %d",
1536 (type == ZEBRA_INTERFACE_NBR_ADDRESS_ADD) ? "ADD"
1537 : "DELETE",
1538 ifindex, vrf_id);
1539 return NULL;
1540 }
1541
1542 p.family = stream_getc(s);
1543 stream_get(&p.u.prefix, s, prefix_blen(&p));
1544 p.prefixlen = stream_getc(s);
1545
1546 if (type == ZEBRA_INTERFACE_NBR_ADDRESS_ADD) {
1547 /* Currently only supporting P2P links, so any new RA source
1548 address is
1549 considered as the replacement of the previously learnt
1550 Link-Local address. */
1551 if (!(ifc = listnode_head(ifp->nbr_connected))) {
1552 ifc = nbr_connected_new();
1553 ifc->address = prefix_new();
1554 ifc->ifp = ifp;
1555 listnode_add(ifp->nbr_connected, ifc);
1556 }
1557
1558 prefix_copy(ifc->address, &p);
1559 } else {
1560 assert(type == ZEBRA_INTERFACE_NBR_ADDRESS_DELETE);
1561
1562 ifc = nbr_connected_check(ifp, &p);
1563 if (ifc)
1564 listnode_delete(ifp->nbr_connected, ifc);
1565 }
1566
1567 return ifc;
a80beece 1568}
6b0655a2 1569
d62a17ae 1570struct interface *zebra_interface_vrf_update_read(struct stream *s,
1571 vrf_id_t vrf_id,
1572 vrf_id_t *new_vrf_id)
c8e264b6 1573{
d62a17ae 1574 unsigned int ifindex;
1575 struct interface *ifp;
1576 vrf_id_t new_id = VRF_DEFAULT;
1577
1578 /* Get interface index. */
1579 ifindex = stream_getl(s);
1580
1581 /* Lookup interface. */
1582 ifp = if_lookup_by_index(ifindex, vrf_id);
1583 if (ifp == NULL) {
1584 zlog_warn("INTERFACE_VRF_UPDATE: Cannot find IF %u in VRF %d",
1585 ifindex, vrf_id);
1586 return NULL;
1587 }
1588
1589 /* Fetch new VRF Id. */
1590 new_id = stream_getw(s);
1591
1592 *new_vrf_id = new_id;
1593 return ifp;
c8e264b6 1594}
5c7ef8dc 1595
1596/* filter unwanted messages until the expected one arrives */
d62a17ae 1597static int zclient_read_sync_response(struct zclient *zclient,
1598 u_int16_t expected_cmd)
5c7ef8dc 1599{
d62a17ae 1600 struct stream *s;
1601 u_int16_t size;
1602 u_char marker;
1603 u_char version;
1604 vrf_id_t vrf_id;
1605 u_int16_t cmd;
1606 fd_set readfds;
1607 int ret;
1608
1609 ret = 0;
1610 cmd = expected_cmd + 1;
1611 while (ret == 0 && cmd != expected_cmd) {
1612 s = zclient->ibuf;
1613 stream_reset(s);
1614
1615 /* wait until response arrives */
1616 FD_ZERO(&readfds);
1617 FD_SET(zclient->sock, &readfds);
1618 select(zclient->sock + 1, &readfds, NULL, NULL, NULL);
1619 if (!FD_ISSET(zclient->sock, &readfds))
1620 continue;
1621 /* read response */
1622 ret = zclient_read_header(s, zclient->sock, &size, &marker,
1623 &version, &vrf_id, &cmd);
1624 if (zclient_debug)
1625 zlog_debug("%s: Response (%d bytes) received", __func__,
1626 size);
1627 }
1628 if (ret != 0) {
1629 zlog_err("%s: Invalid Sync Message Reply", __func__);
1630 return -1;
1631 }
1632
1633 return 0;
5c7ef8dc 1634}
fea12efb 1635/**
1636 * Connect to label manager in a syncronous way
1637 *
1638 * It first writes the request to zcient output buffer and then
1639 * immediately reads the answer from the input buffer.
1640 *
1641 * @param zclient Zclient used to connect to label manager (zebra)
1642 * @result Result of response
1643 */
d62a17ae 1644int lm_label_manager_connect(struct zclient *zclient)
fea12efb 1645{
d62a17ae 1646 int ret;
1647 struct stream *s;
1648 u_char result;
1649
1650 if (zclient_debug)
1651 zlog_debug("Connecting to Label Manager");
1652
1653 if (zclient->sock < 0)
1654 return -1;
1655
1656 /* send request */
1657 s = zclient->obuf;
1658 stream_reset(s);
1659 zclient_create_header(s, ZEBRA_LABEL_MANAGER_CONNECT, VRF_DEFAULT);
1660
1661 /* proto */
1662 stream_putc(s, zclient->redist_default);
1663 /* instance */
1664 stream_putw(s, zclient->instance);
1665
1666 /* Put length at the first point of the stream. */
1667 stream_putw_at(s, 0, stream_get_endp(s));
1668
1669 ret = writen(zclient->sock, s->data, stream_get_endp(s));
1670 if (ret < 0) {
1671 zlog_err("%s: can't write to zclient->sock", __func__);
1672 close(zclient->sock);
1673 zclient->sock = -1;
1674 return -1;
1675 }
1676 if (ret == 0) {
1677 zlog_err("%s: zclient->sock connection closed", __func__);
1678 close(zclient->sock);
1679 zclient->sock = -1;
1680 return -1;
1681 }
1682 if (zclient_debug)
1683 zlog_debug("%s: Label manager connect request (%d bytes) sent",
1684 __func__, ret);
1685
1686 /* read response */
1687 if (zclient_read_sync_response(zclient, ZEBRA_LABEL_MANAGER_CONNECT)
1688 != 0)
1689 return -1;
1690
1691 /* result */
1692 s = zclient->ibuf;
1693 result = stream_getc(s);
1694 if (zclient_debug)
1695 zlog_debug(
1696 "%s: Label Manager connect response received, result %u",
1697 __func__, result);
1698
1699 return (int)result;
fea12efb 1700}
1701
1702/**
1703 * Function to request a label chunk in a syncronous way
1704 *
1705 * It first writes the request to zlcient output buffer and then
1706 * immediately reads the answer from the input buffer.
1707 *
1708 * @param zclient Zclient used to connect to label manager (zebra)
1709 * @param keep Avoid garbage collection
1710 * @param chunk_size Amount of labels requested
1711 * @param start To write first assigned chunk label to
1712 * @param end To write last assigned chunk label to
1713 * @result 0 on success, -1 otherwise
1714 */
d62a17ae 1715int lm_get_label_chunk(struct zclient *zclient, u_char keep,
1716 uint32_t chunk_size, uint32_t *start, uint32_t *end)
fea12efb 1717{
d62a17ae 1718 int ret;
1719 struct stream *s;
1720 u_char response_keep;
1721
1722 if (zclient_debug)
1723 zlog_debug("Getting Label Chunk");
1724
1725 if (zclient->sock < 0)
1726 return -1;
1727
1728 /* send request */
1729 s = zclient->obuf;
1730 stream_reset(s);
1731 zclient_create_header(s, ZEBRA_GET_LABEL_CHUNK, VRF_DEFAULT);
1732 /* keep */
1733 stream_putc(s, keep);
1734 /* chunk size */
1735 stream_putl(s, chunk_size);
1736 /* Put length at the first point of the stream. */
1737 stream_putw_at(s, 0, stream_get_endp(s));
1738
1739 ret = writen(zclient->sock, s->data, stream_get_endp(s));
1740 if (ret < 0) {
1741 zlog_err("%s: can't write to zclient->sock", __func__);
1742 close(zclient->sock);
1743 zclient->sock = -1;
1744 return -1;
1745 }
1746 if (ret == 0) {
1747 zlog_err("%s: zclient->sock connection closed", __func__);
1748 close(zclient->sock);
1749 zclient->sock = -1;
1750 return -1;
1751 }
1752 if (zclient_debug)
1753 zlog_debug("%s: Label chunk request (%d bytes) sent", __func__,
1754 ret);
1755
1756 /* read response */
1757 if (zclient_read_sync_response(zclient, ZEBRA_GET_LABEL_CHUNK) != 0)
1758 return -1;
1759
1760 s = zclient->ibuf;
1761 /* keep */
1762 response_keep = stream_getc(s);
1763 /* start and end labels */
1764 *start = stream_getl(s);
1765 *end = stream_getl(s);
1766
1767 /* not owning this response */
1768 if (keep != response_keep) {
1769 zlog_err(
1770 "%s: Invalid Label chunk: %u - %u, keeps mismatch %u != %u",
1771 __func__, *start, *end, keep, response_keep);
1772 }
1773 /* sanity */
1774 if (*start > *end || *start < MPLS_MIN_UNRESERVED_LABEL
1775 || *end > MPLS_MAX_UNRESERVED_LABEL) {
1776 zlog_err("%s: Invalid Label chunk: %u - %u", __func__, *start,
1777 *end);
1778 return -1;
1779 }
1780
1781 if (zclient_debug)
1782 zlog_debug("Label Chunk assign: %u - %u (%u) ", *start, *end,
1783 response_keep);
1784
1785 return 0;
fea12efb 1786}
1787
1788/**
1789 * Function to release a label chunk
1790 *
1791 * @param zclient Zclient used to connect to label manager (zebra)
1792 * @param start First label of chunk
1793 * @param end Last label of chunk
1794 * @result 0 on success, -1 otherwise
1795 */
d62a17ae 1796int lm_release_label_chunk(struct zclient *zclient, uint32_t start,
1797 uint32_t end)
fea12efb 1798{
d62a17ae 1799 int ret;
1800 struct stream *s;
1801
1802 if (zclient_debug)
1803 zlog_debug("Releasing Label Chunk");
1804
1805 if (zclient->sock < 0)
1806 return -1;
1807
1808 /* send request */
1809 s = zclient->obuf;
1810 stream_reset(s);
1811 zclient_create_header(s, ZEBRA_RELEASE_LABEL_CHUNK, VRF_DEFAULT);
1812
1813 /* start */
1814 stream_putl(s, start);
1815 /* end */
1816 stream_putl(s, end);
1817
1818 /* Put length at the first point of the stream. */
1819 stream_putw_at(s, 0, stream_get_endp(s));
1820
1821 ret = writen(zclient->sock, s->data, stream_get_endp(s));
1822 if (ret < 0) {
1823 zlog_err("%s: can't write to zclient->sock", __func__);
1824 close(zclient->sock);
1825 zclient->sock = -1;
1826 return -1;
1827 }
1828 if (ret == 0) {
1829 zlog_err("%s: zclient->sock connection closed", __func__);
1830 close(zclient->sock);
1831 zclient->sock = -1;
1832 return -1;
1833 }
1834
1835 return 0;
fea12efb 1836}
c8e264b6 1837
718e3744 1838/* Zebra client message read function. */
d62a17ae 1839static int zclient_read(struct thread *thread)
718e3744 1840{
d62a17ae 1841 size_t already;
1842 uint16_t length, command;
1843 uint8_t marker, version;
1844 vrf_id_t vrf_id;
1845 struct zclient *zclient;
1846
1847 /* Get socket to zebra. */
1848 zclient = THREAD_ARG(thread);
1849 zclient->t_read = NULL;
1850
1851 /* Read zebra header (if we don't have it already). */
1852 if ((already = stream_get_endp(zclient->ibuf)) < ZEBRA_HEADER_SIZE) {
1853 ssize_t nbyte;
1854 if (((nbyte = stream_read_try(zclient->ibuf, zclient->sock,
1855 ZEBRA_HEADER_SIZE - already))
1856 == 0)
1857 || (nbyte == -1)) {
1858 if (zclient_debug)
1859 zlog_debug(
1860 "zclient connection closed socket [%d].",
1861 zclient->sock);
1862 return zclient_failed(zclient);
1863 }
1864 if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE - already)) {
1865 /* Try again later. */
1866 zclient_event(ZCLIENT_READ, zclient);
1867 return 0;
1868 }
1869 already = ZEBRA_HEADER_SIZE;
634f9ea2 1870 }
d62a17ae 1871
1872 /* Reset to read from the beginning of the incoming packet. */
1873 stream_set_getp(zclient->ibuf, 0);
1874
1875 /* Fetch header values. */
1876 length = stream_getw(zclient->ibuf);
1877 marker = stream_getc(zclient->ibuf);
1878 version = stream_getc(zclient->ibuf);
1879 vrf_id = stream_getw(zclient->ibuf);
1880 command = stream_getw(zclient->ibuf);
1881
1882 if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION) {
1883 zlog_err(
1884 "%s: socket %d version mismatch, marker %d, version %d",
1885 __func__, zclient->sock, marker, version);
1886 return zclient_failed(zclient);
634f9ea2 1887 }
d62a17ae 1888
1889 if (length < ZEBRA_HEADER_SIZE) {
1890 zlog_err("%s: socket %d message length %u is less than %d ",
1891 __func__, zclient->sock, length, ZEBRA_HEADER_SIZE);
1892 return zclient_failed(zclient);
634f9ea2 1893 }
d62a17ae 1894
1895 /* Length check. */
1896 if (length > STREAM_SIZE(zclient->ibuf)) {
1897 struct stream *ns;
1898 zlog_warn(
1899 "%s: message size %u exceeds buffer size %lu, expanding...",
1900 __func__, length, (u_long)STREAM_SIZE(zclient->ibuf));
1901 ns = stream_new(length);
1902 stream_copy(ns, zclient->ibuf);
1903 stream_free(zclient->ibuf);
1904 zclient->ibuf = ns;
1905 }
1906
1907 /* Read rest of zebra packet. */
1908 if (already < length) {
1909 ssize_t nbyte;
1910 if (((nbyte = stream_read_try(zclient->ibuf, zclient->sock,
1911 length - already))
1912 == 0)
1913 || (nbyte == -1)) {
1914 if (zclient_debug)
1915 zlog_debug(
1916 "zclient connection closed socket [%d].",
1917 zclient->sock);
1918 return zclient_failed(zclient);
1919 }
1920 if (nbyte != (ssize_t)(length - already)) {
1921 /* Try again later. */
1922 zclient_event(ZCLIENT_READ, zclient);
1923 return 0;
1924 }
1925 }
1926
1927 length -= ZEBRA_HEADER_SIZE;
1928
1929 if (zclient_debug)
1930 zlog_debug("zclient 0x%p command 0x%x VRF %u\n",
1931 (void *)zclient, command, vrf_id);
1932
1933 switch (command) {
1934 case ZEBRA_ROUTER_ID_UPDATE:
1935 if (zclient->router_id_update)
1936 (*zclient->router_id_update)(command, zclient, length,
1937 vrf_id);
1938 break;
1939 case ZEBRA_VRF_ADD:
1940 zclient_vrf_add(zclient, vrf_id);
1941 break;
1942 case ZEBRA_VRF_DELETE:
1943 zclient_vrf_delete(zclient, vrf_id);
1944 break;
1945 case ZEBRA_INTERFACE_ADD:
1946 if (zclient->interface_add)
1947 (*zclient->interface_add)(command, zclient, length,
1948 vrf_id);
1949 break;
1950 case ZEBRA_INTERFACE_DELETE:
1951 if (zclient->interface_delete)
1952 (*zclient->interface_delete)(command, zclient, length,
1953 vrf_id);
1954 break;
1955 case ZEBRA_INTERFACE_ADDRESS_ADD:
1956 if (zclient->interface_address_add)
1957 (*zclient->interface_address_add)(command, zclient,
1958 length, vrf_id);
1959 break;
1960 case ZEBRA_INTERFACE_ADDRESS_DELETE:
1961 if (zclient->interface_address_delete)
1962 (*zclient->interface_address_delete)(command, zclient,
1963 length, vrf_id);
1964 break;
1965 case ZEBRA_INTERFACE_BFD_DEST_UPDATE:
1966 if (zclient->interface_bfd_dest_update)
1967 (*zclient->interface_bfd_dest_update)(command, zclient,
1968 length, vrf_id);
1969 break;
1970 case ZEBRA_INTERFACE_NBR_ADDRESS_ADD:
1971 if (zclient->interface_nbr_address_add)
1972 (*zclient->interface_nbr_address_add)(command, zclient,
1973 length, vrf_id);
1974 break;
1975 case ZEBRA_INTERFACE_NBR_ADDRESS_DELETE:
1976 if (zclient->interface_nbr_address_delete)
1977 (*zclient->interface_nbr_address_delete)(
1978 command, zclient, length, vrf_id);
1979 break;
1980 case ZEBRA_INTERFACE_UP:
1981 if (zclient->interface_up)
1982 (*zclient->interface_up)(command, zclient, length,
1983 vrf_id);
1984 break;
1985 case ZEBRA_INTERFACE_DOWN:
1986 if (zclient->interface_down)
1987 (*zclient->interface_down)(command, zclient, length,
1988 vrf_id);
1989 break;
1990 case ZEBRA_INTERFACE_VRF_UPDATE:
1991 if (zclient->interface_vrf_update)
1992 (*zclient->interface_vrf_update)(command, zclient,
1993 length, vrf_id);
1994 break;
1995 case ZEBRA_NEXTHOP_UPDATE:
1996 if (zclient_debug)
1997 zlog_debug("zclient rcvd nexthop update\n");
1998 if (zclient->nexthop_update)
1999 (*zclient->nexthop_update)(command, zclient, length,
2000 vrf_id);
2001 break;
2002 case ZEBRA_IMPORT_CHECK_UPDATE:
2003 if (zclient_debug)
2004 zlog_debug("zclient rcvd import check update\n");
2005 if (zclient->import_check_update)
2006 (*zclient->import_check_update)(command, zclient,
2007 length, vrf_id);
2008 break;
2009 case ZEBRA_BFD_DEST_REPLAY:
2010 if (zclient->bfd_dest_replay)
2011 (*zclient->bfd_dest_replay)(command, zclient, length,
2012 vrf_id);
2013 break;
2014 case ZEBRA_REDISTRIBUTE_IPV4_ADD:
2015 if (zclient->redistribute_route_ipv4_add)
2016 (*zclient->redistribute_route_ipv4_add)(
2017 command, zclient, length, vrf_id);
2018 break;
2019 case ZEBRA_REDISTRIBUTE_IPV4_DEL:
2020 if (zclient->redistribute_route_ipv4_del)
2021 (*zclient->redistribute_route_ipv4_del)(
2022 command, zclient, length, vrf_id);
2023 break;
2024 case ZEBRA_REDISTRIBUTE_IPV6_ADD:
2025 if (zclient->redistribute_route_ipv6_add)
2026 (*zclient->redistribute_route_ipv6_add)(
2027 command, zclient, length, vrf_id);
2028 break;
2029 case ZEBRA_REDISTRIBUTE_IPV6_DEL:
2030 if (zclient->redistribute_route_ipv6_del)
2031 (*zclient->redistribute_route_ipv6_del)(
2032 command, zclient, length, vrf_id);
2033 break;
2034 case ZEBRA_INTERFACE_LINK_PARAMS:
2035 if (zclient->interface_link_params)
2036 (*zclient->interface_link_params)(command, zclient,
2037 length);
2038 break;
2039 case ZEBRA_FEC_UPDATE:
2040 if (zclient_debug)
2041 zlog_debug("zclient rcvd fec update\n");
2042 if (zclient->fec_update)
2043 (*zclient->fec_update)(command, zclient, length);
2044 break;
2045 case ZEBRA_VNI_ADD:
2046 if (zclient->local_vni_add)
2047 (*zclient->local_vni_add)(command, zclient, length,
2048 vrf_id);
2049 break;
2050 case ZEBRA_VNI_DEL:
2051 if (zclient->local_vni_del)
2052 (*zclient->local_vni_del)(command, zclient, length,
2053 vrf_id);
2054 break;
2055 case ZEBRA_MACIP_ADD:
2056 if (zclient->local_macip_add)
2057 (*zclient->local_macip_add)(command, zclient, length,
2058 vrf_id);
2059 break;
2060 case ZEBRA_MACIP_DEL:
2061 if (zclient->local_macip_del)
2062 (*zclient->local_macip_del)(command, zclient, length,
2063 vrf_id);
2064 break;
2065 default:
2066 break;
634f9ea2 2067 }
d62a17ae 2068
2069 if (zclient->sock < 0)
2070 /* Connection was closed during packet processing. */
2071 return -1;
2072
2073 /* Register read thread. */
2074 stream_reset(zclient->ibuf);
2075 zclient_event(ZCLIENT_READ, zclient);
2076
2077 return 0;
718e3744 2078}
2079
d62a17ae 2080void zclient_redistribute(int command, struct zclient *zclient, afi_t afi,
2081 int type, u_short instance, vrf_id_t vrf_id)
718e3744 2082{
718e3744 2083
d62a17ae 2084 if (instance) {
2085 if (command == ZEBRA_REDISTRIBUTE_ADD) {
2086 if (redist_check_instance(
2087 &zclient->mi_redist[afi][type], instance))
2088 return;
2089 redist_add_instance(&zclient->mi_redist[afi][type],
2090 instance);
2091 } else {
2092 if (!redist_check_instance(
2093 &zclient->mi_redist[afi][type], instance))
2094 return;
2095 redist_del_instance(&zclient->mi_redist[afi][type],
2096 instance);
2097 }
2098
2099 } else {
2100 if (command == ZEBRA_REDISTRIBUTE_ADD) {
2101 if (vrf_bitmap_check(zclient->redist[afi][type],
2102 vrf_id))
2103 return;
2104 vrf_bitmap_set(zclient->redist[afi][type], vrf_id);
2105 } else {
2106 if (!vrf_bitmap_check(zclient->redist[afi][type],
2107 vrf_id))
2108 return;
2109 vrf_bitmap_unset(zclient->redist[afi][type], vrf_id);
2110 }
2111 }
2112
2113 if (zclient->sock > 0)
2114 zebra_redistribute_send(command, zclient, afi, type, instance,
2115 vrf_id);
718e3744 2116}
2117
718e3744 2118
d62a17ae 2119void zclient_redistribute_default(int command, struct zclient *zclient,
2120 vrf_id_t vrf_id)
718e3744 2121{
718e3744 2122
d62a17ae 2123 if (command == ZEBRA_REDISTRIBUTE_DEFAULT_ADD) {
2124 if (vrf_bitmap_check(zclient->default_information, vrf_id))
2125 return;
2126 vrf_bitmap_set(zclient->default_information, vrf_id);
2127 } else {
2128 if (!vrf_bitmap_check(zclient->default_information, vrf_id))
2129 return;
2130 vrf_bitmap_unset(zclient->default_information, vrf_id);
2131 }
2132
2133 if (zclient->sock > 0)
2134 zebra_message_send(zclient, command, vrf_id);
718e3744 2135}
2136
d62a17ae 2137static void zclient_event(enum event event, struct zclient *zclient)
718e3744 2138{
d62a17ae 2139 switch (event) {
2140 case ZCLIENT_SCHEDULE:
2141 thread_add_event(zclient->master, zclient_connect, zclient, 0,
2142 &zclient->t_connect);
2143 break;
2144 case ZCLIENT_CONNECT:
2145 if (zclient_debug)
2146 zlog_debug(
2147 "zclient connect failures: %d schedule interval is now %d",
2148 zclient->fail, zclient->fail < 3 ? 10 : 60);
2149 thread_add_timer(zclient->master, zclient_connect, zclient,
2150 zclient->fail < 3 ? 10 : 60,
2151 &zclient->t_connect);
2152 break;
2153 case ZCLIENT_READ:
2154 zclient->t_read = NULL;
2155 thread_add_read(zclient->master, zclient_read, zclient,
2156 zclient->sock, &zclient->t_read);
2157 break;
2158 }
718e3744 2159}
b5114685 2160
744f4685 2161const char *zclient_serv_path_get()
12e41d03 2162{
d62a17ae 2163 return zclient_serv_path ? zclient_serv_path : ZEBRA_SERV_PATH;
12e41d03
DL
2164}
2165
d62a17ae 2166void zclient_serv_path_set(char *path)
b5114685 2167{
d62a17ae 2168 struct stat sb;
b5114685 2169
d62a17ae 2170 /* reset */
2171 zclient_serv_path = NULL;
2172
2173 /* test if `path' is socket. don't set it otherwise. */
2174 if (stat(path, &sb) == -1) {
2175 zlog_warn("%s: zebra socket `%s' does not exist", __func__,
2176 path);
2177 return;
2178 }
2179
2180 if ((sb.st_mode & S_IFMT) != S_IFSOCK) {
2181 zlog_warn("%s: `%s' is not unix socket, sir", __func__, path);
2182 return;
2183 }
2184
2185 /* it seems that path is unix socket */
2186 zclient_serv_path = path;
2187}