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