]> git.proxmox.com Git - mirror_frr.git/blame - lib/zclient.c
zebra: Fix 'show ip route babel'...
[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
0a589359 980/*
981 * send a ZEBRA_REDISTRIBUTE_ADD or ZEBRA_REDISTRIBUTE_DELETE
982 * for the route type (ZEBRA_ROUTE_KERNEL etc.). The zebra server will
983 * then set/unset redist[type] in the client handle (a struct zserv) for the
984 * sending client
985 */
718e3744 986int
8bb0831e 987zebra_redistribute_send (int command, struct zclient *zclient, afi_t afi, int type,
7076bb2f 988 u_short instance, vrf_id_t vrf_id)
718e3744 989{
718e3744 990 struct stream *s;
991
634f9ea2 992 s = zclient->obuf;
993 stream_reset(s);
718e3744 994
7076bb2f 995 zclient_create_header (s, command, vrf_id);
8bb0831e 996 stream_putc (s, afi);
718e3744 997 stream_putc (s, type);
7c8ff89e 998 stream_putw (s, instance);
c1b9800a 999
1000 stream_putw_at (s, 0, stream_get_endp (s));
1001
634f9ea2 1002 return zclient_send_message(zclient);
718e3744 1003}
1004
d9178828
PJ
1005/* Get prefix in ZServ format; family should be filled in on prefix */
1006static void
1007zclient_stream_get_prefix (struct stream *s, struct prefix *p)
1008{
1009 size_t plen = prefix_blen (p);
1010 u_char c;
1011 p->prefixlen = 0;
1012
1013 if (plen == 0)
1014 return;
1015
1016 stream_get (&p->u.prefix, s, plen);
1017 c = stream_getc(s);
1018 p->prefixlen = MIN(plen * 8, c);
1019}
1020
18a6dce6 1021/* Router-id update from zebra daemon. */
1022void
1023zebra_router_id_update_read (struct stream *s, struct prefix *rid)
1024{
18a6dce6 1025 /* Fetch interface address. */
1026 rid->family = stream_getc (s);
d9178828
PJ
1027
1028 zclient_stream_get_prefix (s, rid);
18a6dce6 1029}
1030
718e3744 1031/* Interface addition from zebra daemon. */
0a589359 1032/*
1033 * The format of the message sent with type ZEBRA_INTERFACE_ADD or
1034 * ZEBRA_INTERFACE_DELETE from zebra to the client is:
1035 * 0 1 2 3
1036 * 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 1037 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1038 * | ifname |
1039 * | |
1040 * | |
1041 * | |
1042 * | |
1043 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee
OD
1044 * | ifindex |
1045 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1046 * | status |
0a589359 1047 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee 1048 * | if_flags |
c77d4546 1049 * | |
0a589359 1050 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee
OD
1051 * | metric |
1052 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2d7f0d76
DS
1053 * | speed |
1054 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee
OD
1055 * | ifmtu |
1056 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1057 * | ifmtu6 |
1058 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1059 * | bandwidth |
1060 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1061 * | Link Layer Type |
0a589359 1062 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee 1063 * | Harware Address Length |
0a589359 1064 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee
OD
1065 * | Hardware Address if HW lenght different from 0 |
1066 * | ... max INTERFACE_HWADDR_MAX |
0a589359 1067 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee 1068 * | Link_params? | Whether a link-params follows: 1 or 0.
0a589359 1069 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee
OD
1070 * | Link_params 0 or 1 INTERFACE_LINK_PARAMS_SIZE sized |
1071 * | .... (struct if_link_params). |
0a589359 1072 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1073 */
1074
2fcc254e 1075static void
ebe32f70 1076zclient_vrf_add (struct zclient *zclient, vrf_id_t vrf_id)
1892f15e
DS
1077{
1078 struct vrf *vrf;
1079 char vrfname_tmp[VRF_NAMSIZ];
1080
1081 /* Read interface name. */
ebe32f70 1082 stream_get (vrfname_tmp, zclient->ibuf, VRF_NAMSIZ);
1892f15e
DS
1083
1084 /* Lookup/create vrf by vrf_id. */
1085 vrf = vrf_get (vrf_id, vrfname_tmp);
1086
2fcc254e 1087 vrf_enable (vrf);
1892f15e
DS
1088}
1089
2fcc254e 1090static void
ebe32f70 1091zclient_vrf_delete (struct zclient *zclient, vrf_id_t vrf_id)
1892f15e
DS
1092{
1093 struct vrf *vrf;
1094
1095 /* Lookup vrf by vrf_id. */
5f3d1bdf 1096 vrf = vrf_lookup_by_id (vrf_id);
1892f15e 1097
beef1990
DS
1098 /*
1099 * If a routing protocol doesn't know about a
1100 * vrf that is about to be deleted. There is
1101 * no point in attempting to delete it.
1102 */
1103 if (!vrf)
1104 return;
1105
2fcc254e 1106 vrf_delete (vrf);
1892f15e
DS
1107}
1108
718e3744 1109struct interface *
7076bb2f 1110zebra_interface_add_read (struct stream *s, vrf_id_t vrf_id)
718e3744 1111{
1112 struct interface *ifp;
02ff83c5 1113 char ifname_tmp[INTERFACE_NAMSIZ];
718e3744 1114
1115 /* Read interface name. */
1116 stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
1117
a349198f 1118 /* Lookup/create interface by name. */
07a112a1
DS
1119 ifp = if_get_by_name_len (ifname_tmp,
1120 strnlen (ifname_tmp, INTERFACE_NAMSIZ),
1121 vrf_id, 0);
718e3744 1122
51d4ef83 1123 zebra_interface_if_set_value (s, ifp);
718e3744 1124
718e3744 1125 return ifp;
1126}
1127
0a589359 1128/*
1129 * Read interface up/down msg (ZEBRA_INTERFACE_UP/ZEBRA_INTERFACE_DOWN)
1130 * from zebra server. The format of this message is the same as
1131 * that sent for ZEBRA_INTERFACE_ADD/ZEBRA_INTERFACE_DELETE (see
1132 * comments for zebra_interface_add_read), except that no sockaddr_dl
1133 * is sent at the tail of the message.
1134 */
718e3744 1135struct interface *
7076bb2f 1136zebra_interface_state_read (struct stream *s, vrf_id_t vrf_id)
718e3744 1137{
1138 struct interface *ifp;
02ff83c5 1139 char ifname_tmp[INTERFACE_NAMSIZ];
718e3744 1140
1141 /* Read interface name. */
1142 stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
1143
1144 /* Lookup this by interface index. */
fa787f91
DS
1145 ifp = if_lookup_by_name_len (ifname_tmp,
1146 strnlen (ifname_tmp, INTERFACE_NAMSIZ),
1147 vrf_id);
b4dd5eaa 1148 if (ifp == NULL)
1149 {
1150 zlog_warn ("INTERFACE_STATE: Cannot find IF %s in VRF %d",
1151 ifname_tmp, vrf_id);
1152 return NULL;
1153 }
718e3744 1154
51d4ef83 1155 zebra_interface_if_set_value (s, ifp);
718e3744 1156
1157 return ifp;
1158}
1159
16f1b9ee
OD
1160static void
1161link_params_set_value(struct stream *s, struct if_link_params *iflp)
1162{
1163
1164 if (iflp == NULL)
1165 return;
1166
1167 iflp->lp_status = stream_getl (s);
1168 iflp->te_metric = stream_getl (s);
1169 iflp->max_bw = stream_getf (s);
1170 iflp->max_rsv_bw = stream_getf (s);
1171 uint32_t bwclassnum = stream_getl (s);
1172 {
1173 unsigned int i;
1174 for (i = 0; i < bwclassnum && i < MAX_CLASS_TYPE; i++)
1175 iflp->unrsv_bw[i] = stream_getf (s);
1176 if (i < bwclassnum)
1177 zlog_err ("%s: received %d > %d (MAX_CLASS_TYPE) bw entries"
1178 " - outdated library?",
1179 __func__, bwclassnum, MAX_CLASS_TYPE);
1180 }
1181 iflp->admin_grp = stream_getl (s);
1182 iflp->rmt_as = stream_getl (s);
1183 iflp->rmt_ip.s_addr = stream_get_ipv4 (s);
1184
1185 iflp->av_delay = stream_getl (s);
1186 iflp->min_delay = stream_getl (s);
1187 iflp->max_delay = stream_getl (s);
1188 iflp->delay_var = stream_getl (s);
1189
1190 iflp->pkt_loss = stream_getf (s);
1191 iflp->res_bw = stream_getf (s);
1192 iflp->ava_bw = stream_getf (s);
1193 iflp->use_bw = stream_getf (s);
1194}
1195
1196struct interface *
1197zebra_interface_link_params_read (struct stream *s)
1198{
1199 struct if_link_params *iflp;
c28e5b2a
DS
1200 ifindex_t ifindex;
1201
1202 assert (s);
1203
1204 ifindex = stream_getl (s);
16f1b9ee 1205
7e2b7603 1206 struct interface *ifp = if_lookup_by_index (ifindex, VRF_DEFAULT);
16f1b9ee 1207
c28e5b2a 1208 if (ifp == NULL)
16f1b9ee
OD
1209 {
1210 zlog_err ("%s: unknown ifindex %u, shouldn't happen",
1211 __func__, ifindex);
1212 return NULL;
1213 }
1214
1215 if ((iflp = if_link_params_get (ifp)) == NULL)
1216 return NULL;
1217
1218 link_params_set_value(s, iflp);
1219
1220 return ifp;
1221}
1222
1223void
1224zebra_interface_if_set_value (struct stream *s, struct interface *ifp)
1225{
1226 u_char link_params_status = 0;
1227
1228 /* Read interface's index. */
1229 ifp->ifindex = stream_getl (s);
1230 ifp->status = stream_getc (s);
1231
1232 /* Read interface's value. */
1233 ifp->flags = stream_getq (s);
1234 ifp->ptm_enable = stream_getc (s);
1235 ifp->ptm_status = stream_getc (s);
1236 ifp->metric = stream_getl (s);
2d7f0d76 1237 ifp->speed = stream_getl (s);
16f1b9ee
OD
1238 ifp->mtu = stream_getl (s);
1239 ifp->mtu6 = stream_getl (s);
1240 ifp->bandwidth = stream_getl (s);
1241 ifp->ll_type = stream_getl (s);
1242 ifp->hw_addr_len = stream_getl (s);
1243 if (ifp->hw_addr_len)
1244 stream_get (ifp->hw_addr, s, MIN(ifp->hw_addr_len, INTERFACE_HWADDR_MAX));
1245
1246 /* Read Traffic Engineering status */
1247 link_params_status = stream_getc (s);
1248 /* Then, Traffic Engineering parameters if any */
1249 if (link_params_status)
1250 {
1251 struct if_link_params *iflp = if_link_params_get (ifp);
1252 link_params_set_value(s, iflp);
1253 }
1254}
1255
1256size_t
1257zebra_interface_link_params_write (struct stream *s, struct interface *ifp)
1258{
1259 size_t w;
1260 struct if_link_params *iflp;
1261 int i;
1262
1263 if (s == NULL || ifp == NULL || ifp->link_params == NULL)
1264 return 0;
1265
1266 iflp = ifp->link_params;
1267 w = 0;
1268
1269 w += stream_putl (s, iflp->lp_status);
1270
1271 w += stream_putl (s, iflp->te_metric);
1272 w += stream_putf (s, iflp->max_bw);
1273 w += stream_putf (s, iflp->max_rsv_bw);
1274
1275 w += stream_putl (s, MAX_CLASS_TYPE);
1276 for (i = 0; i < MAX_CLASS_TYPE; i++)
1277 w += stream_putf (s, iflp->unrsv_bw[i]);
1278
1279 w += stream_putl (s, iflp->admin_grp);
1280 w += stream_putl (s, iflp->rmt_as);
1281 w += stream_put_in_addr (s, &iflp->rmt_ip);
1282
1283 w += stream_putl (s, iflp->av_delay);
1284 w += stream_putl (s, iflp->min_delay);
1285 w += stream_putl (s, iflp->max_delay);
1286 w += stream_putl (s, iflp->delay_var);
1287
1288 w += stream_putf (s, iflp->pkt_loss);
1289 w += stream_putf (s, iflp->res_bw);
1290 w += stream_putf (s, iflp->ava_bw);
1291 w += stream_putf (s, iflp->use_bw);
1292
1293 return w;
1294}
1295
1296/*
0a589359 1297 * format of message for address additon is:
1298 * 0
1299 * 0 1 2 3 4 5 6 7
1300 * +-+-+-+-+-+-+-+-+
1301 * | type | ZEBRA_INTERFACE_ADDRESS_ADD or
1302 * +-+-+-+-+-+-+-+-+ ZEBRA_INTERFACE_ADDRES_DELETE
1303 * | |
1304 * + +
1305 * | ifindex |
1306 * + +
1307 * | |
1308 * + +
1309 * | |
1310 * +-+-+-+-+-+-+-+-+
1311 * | ifc_flags | flags for connected address
1312 * +-+-+-+-+-+-+-+-+
1313 * | addr_family |
1314 * +-+-+-+-+-+-+-+-+
1315 * | addr... |
1316 * : :
1317 * | |
1318 * +-+-+-+-+-+-+-+-+
1319 * | addr_len | len of addr. E.g., addr_len = 4 for ipv4 addrs.
1320 * +-+-+-+-+-+-+-+-+
1321 * | daddr.. |
1322 * : :
1323 * | |
1324 * +-+-+-+-+-+-+-+-+
0a589359 1325 */
1326
3fb9cd6e 1327static int
1328memconstant(const void *s, int c, size_t n)
1329{
1330 const u_char *p = s;
1331
1332 while (n-- > 0)
1333 if (*p++ != c)
1334 return 0;
1335 return 1;
1336}
1337
d5a5c8f0 1338
718e3744 1339struct connected *
7076bb2f 1340zebra_interface_address_read (int type, struct stream *s, vrf_id_t vrf_id)
718e3744 1341{
b892f1dd 1342 ifindex_t ifindex;
718e3744 1343 struct interface *ifp;
1344 struct connected *ifc;
d9178828 1345 struct prefix p, d, *dp;
718e3744 1346 int plen;
0a589359 1347 u_char ifc_flags;
718e3744 1348
0a589359 1349 memset (&p, 0, sizeof(p));
1350 memset (&d, 0, sizeof(d));
718e3744 1351
1352 /* Get interface index. */
1353 ifindex = stream_getl (s);
1354
1355 /* Lookup index. */
7e2b7603 1356 ifp = if_lookup_by_index (ifindex, vrf_id);
718e3744 1357 if (ifp == NULL)
1358 {
b4dd5eaa 1359 zlog_warn ("INTERFACE_ADDRESS_%s: Cannot find IF %u in VRF %d",
1360 (type == ZEBRA_INTERFACE_ADDRESS_ADD) ? "ADD" : "DEL",
1361 ifindex, vrf_id);
718e3744 1362 return NULL;
1363 }
1364
1365 /* Fetch flag. */
0a589359 1366 ifc_flags = stream_getc (s);
718e3744 1367
1368 /* Fetch interface address. */
d9178828
PJ
1369 d.family = p.family = stream_getc (s);
1370 plen = prefix_blen (&d);
1371
1372 zclient_stream_get_prefix (s, &p);
718e3744 1373
1374 /* Fetch destination address. */
0a589359 1375 stream_get (&d.u.prefix, s, plen);
d9178828
PJ
1376
1377 /* N.B. NULL destination pointers are encoded as all zeroes */
1378 dp = memconstant(&d.u.prefix,0,plen) ? NULL : &d;
1379
0a589359 1380 if (type == ZEBRA_INTERFACE_ADDRESS_ADD)
1381 {
38485402
DS
1382 ifc = connected_lookup_prefix_exact (ifp, &p);
1383 if (!ifc)
1384 {
1385 /* N.B. NULL destination pointers are encoded as all zeroes */
d9178828 1386 ifc = connected_add_by_prefix(ifp, &p, dp);
38485402
DS
1387 }
1388 if (ifc)
e4529636
AS
1389 {
1390 ifc->flags = ifc_flags;
1391 if (ifc->destination)
1392 ifc->destination->prefixlen = ifc->address->prefixlen;
90444ca3
DL
1393 else if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_PEER))
1394 {
1395 /* carp interfaces on OpenBSD with 0.0.0.0/0 as "peer" */
855110bb 1396 char buf[PREFIX_STRLEN];
90444ca3
DL
1397 zlog_warn("warning: interface %s address %s "
1398 "with peer flag set, but no peer address!",
855110bb
TT
1399 ifp->name,
1400 prefix2str (ifc->address, buf, sizeof buf));
90444ca3
DL
1401 UNSET_FLAG(ifc->flags, ZEBRA_IFA_PEER);
1402 }
e4529636 1403 }
0a589359 1404 }
1405 else
1406 {
1407 assert (type == ZEBRA_INTERFACE_ADDRESS_DELETE);
1408 ifc = connected_delete_by_prefix(ifp, &p);
1409 }
718e3744 1410
1411 return ifc;
1412}
0a589359 1413
a80beece
DS
1414/*
1415 * format of message for neighbor connected address is:
1416 * 0
1417 * 0 1 2 3 4 5 6 7
1418 * +-+-+-+-+-+-+-+-+
1419 * | type | ZEBRA_INTERFACE_NBR_ADDRESS_ADD or
1420 * +-+-+-+-+-+-+-+-+ ZEBRA_INTERFACE_NBR_ADDRES_DELETE
1421 * | |
1422 * + +
1423 * | ifindex |
1424 * + +
1425 * | |
1426 * + +
1427 * | |
1428 * +-+-+-+-+-+-+-+-+
1429 * | addr_family |
1430 * +-+-+-+-+-+-+-+-+
1431 * | addr... |
1432 * : :
1433 * | |
1434 * +-+-+-+-+-+-+-+-+
1435 * | addr_len | len of addr.
1436 * +-+-+-+-+-+-+-+-+
1437 */
1438struct nbr_connected *
7076bb2f 1439zebra_interface_nbr_address_read (int type, struct stream *s, vrf_id_t vrf_id)
a80beece
DS
1440{
1441 unsigned int ifindex;
1442 struct interface *ifp;
1443 struct prefix p;
1444 struct nbr_connected *ifc;
1445
1446 /* Get interface index. */
1447 ifindex = stream_getl (s);
1448
1449 /* Lookup index. */
7e2b7603 1450 ifp = if_lookup_by_index (ifindex, vrf_id);
a80beece
DS
1451 if (ifp == NULL)
1452 {
f1aa3df6 1453 zlog_warn ("INTERFACE_NBR_%s: Cannot find IF %u in VRF %d",
1454 (type == ZEBRA_INTERFACE_NBR_ADDRESS_ADD) ? "ADD" : "DELETE",
1455 ifindex, vrf_id);
a80beece
DS
1456 return NULL;
1457 }
1458
1459 p.family = stream_getc (s);
1460 stream_get (&p.u.prefix, s, prefix_blen (&p));
1461 p.prefixlen = stream_getc (s);
1462
1463 if (type == ZEBRA_INTERFACE_NBR_ADDRESS_ADD)
1464 {
1465 /* Currently only supporting P2P links, so any new RA source address is
1466 considered as the replacement of the previously learnt Link-Local address. */
1467 if (!(ifc = listnode_head(ifp->nbr_connected)))
1468 {
1469 ifc = nbr_connected_new ();
1470 ifc->address = prefix_new ();
1471 ifc->ifp = ifp;
1472 listnode_add (ifp->nbr_connected, ifc);
1473 }
1474
1475 prefix_copy(ifc->address, &p);
1476 }
1477 else
1478 {
1479 assert (type == ZEBRA_INTERFACE_NBR_ADDRESS_DELETE);
1480
1481 ifc = nbr_connected_check(ifp, &p);
1482 if (ifc)
1483 listnode_delete (ifp->nbr_connected, ifc);
1484 }
1485
1486 return ifc;
1487}
6b0655a2 1488
c8e264b6 1489struct interface *
1490zebra_interface_vrf_update_read (struct stream *s, vrf_id_t vrf_id,
1491 vrf_id_t *new_vrf_id)
1492{
1493 unsigned int ifindex;
1494 struct interface *ifp;
1495 vrf_id_t new_id = VRF_DEFAULT;
1496
1497 /* Get interface index. */
1498 ifindex = stream_getl (s);
1499
1500 /* Lookup interface. */
7e2b7603 1501 ifp = if_lookup_by_index (ifindex, vrf_id);
c8e264b6 1502 if (ifp == NULL)
1503 {
1504 zlog_warn ("INTERFACE_VRF_UPDATE: Cannot find IF %u in VRF %d",
1505 ifindex, vrf_id);
1506 return NULL;
1507 }
1508
1509 /* Fetch new VRF Id. */
1510 new_id = stream_getw (s);
1511
1512 *new_vrf_id = new_id;
1513 return ifp;
1514}
5c7ef8dc 1515
1516/* filter unwanted messages until the expected one arrives */
1517static int
1518zclient_read_sync_response (struct zclient *zclient, u_int16_t expected_cmd)
1519{
1520 struct stream *s;
1521 u_int16_t size;
1522 u_char marker;
1523 u_char version;
1524 vrf_id_t vrf_id;
1525 u_int16_t cmd;
1526 fd_set readfds;
1527 int ret;
1528
1529 ret = 0;
1530 cmd = expected_cmd + 1;
1531 while (ret == 0 && cmd != expected_cmd)
1532 {
1533 s = zclient->ibuf;
1534 stream_reset (s);
1535
1536 /* wait until response arrives */
1537 FD_ZERO (&readfds);
1538 FD_SET (zclient->sock, &readfds);
1539 select (zclient->sock+1, &readfds, NULL, NULL, NULL);
1540 if (!FD_ISSET(zclient->sock, &readfds))
1541 continue;
1542 /* read response */
1543 ret = zclient_read_header (s, zclient->sock, &size, &marker, &version,
1544 &vrf_id, &cmd);
1545 if (zclient_debug)
1546 zlog_debug ("%s: Response (%d bytes) received", __func__, size);
1547 }
1548 if (ret != 0)
1549 {
1550 zlog_err ("%s: Invalid Sync Message Reply", __func__);
1551 return -1;
1552 }
1553
1554 return 0;
1555}
fea12efb 1556/**
1557 * Connect to label manager in a syncronous way
1558 *
1559 * It first writes the request to zcient output buffer and then
1560 * immediately reads the answer from the input buffer.
1561 *
1562 * @param zclient Zclient used to connect to label manager (zebra)
1563 * @result Result of response
1564 */
1565int
1566lm_label_manager_connect (struct zclient *zclient)
1567{
1568 int ret;
1569 struct stream *s;
1570 u_char result;
fea12efb 1571
08c08a35
DS
1572 if (zclient_debug)
1573 zlog_debug ("Connecting to Label Manager");
1574
fea12efb 1575 if (zclient->sock < 0)
1576 return -1;
1577
1578 /* send request */
1579 s = zclient->obuf;
1580 stream_reset (s);
1581 zclient_create_header (s, ZEBRA_LABEL_MANAGER_CONNECT, VRF_DEFAULT);
1582
1583 /* proto */
1584 stream_putc (s, zclient->redist_default);
1585 /* instance */
1586 stream_putw (s, zclient->instance);
1587
1588 /* Put length at the first point of the stream. */
1589 stream_putw_at(s, 0, stream_get_endp(s));
1590
1591 ret = writen (zclient->sock, s->data, stream_get_endp (s));
1592 if (ret < 0)
1593 {
1594 zlog_err ("%s: can't write to zclient->sock", __func__);
1595 close (zclient->sock);
1596 zclient->sock = -1;
1597 return -1;
1598 }
1599 if (ret == 0)
1600 {
1601 zlog_err ("%s: zclient->sock connection closed", __func__);
1602 close (zclient->sock);
1603 zclient->sock = -1;
1604 return -1;
1605 }
08c08a35
DS
1606 if (zclient_debug)
1607 zlog_debug ("%s: Label manager connect request (%d bytes) sent", __func__, ret);
fea12efb 1608
1609 /* read response */
5c7ef8dc 1610 if (zclient_read_sync_response (zclient, ZEBRA_LABEL_MANAGER_CONNECT) != 0)
1611 return -1;
fea12efb 1612
fea12efb 1613 /* result */
5c7ef8dc 1614 s = zclient->ibuf;
fea12efb 1615 result = stream_getc(s);
08c08a35 1616 if (zclient_debug)
5c7ef8dc 1617 zlog_debug ("%s: Label Manager connect response received, result %u",
1618 __func__, result);
fea12efb 1619
1620 return (int)result;
1621}
1622
1623/**
1624 * Function to request a label chunk in a syncronous way
1625 *
1626 * It first writes the request to zlcient output buffer and then
1627 * immediately reads the answer from the input buffer.
1628 *
1629 * @param zclient Zclient used to connect to label manager (zebra)
1630 * @param keep Avoid garbage collection
1631 * @param chunk_size Amount of labels requested
1632 * @param start To write first assigned chunk label to
1633 * @param end To write last assigned chunk label to
1634 * @result 0 on success, -1 otherwise
1635 */
1636int
1637lm_get_label_chunk (struct zclient *zclient, u_char keep, uint32_t chunk_size,
1638 uint32_t *start, uint32_t *end)
1639{
1640 int ret;
1641 struct stream *s;
fea12efb 1642 u_char response_keep;
1643
08c08a35
DS
1644 if (zclient_debug)
1645 zlog_debug ("Getting Label Chunk");
1646
fea12efb 1647 if (zclient->sock < 0)
1648 return -1;
1649
1650 /* send request */
1651 s = zclient->obuf;
1652 stream_reset (s);
1653 zclient_create_header (s, ZEBRA_GET_LABEL_CHUNK, VRF_DEFAULT);
1654 /* keep */
1655 stream_putc (s, keep);
1656 /* chunk size */
1657 stream_putl (s, chunk_size);
1658 /* Put length at the first point of the stream. */
1659 stream_putw_at(s, 0, stream_get_endp(s));
1660
1661 ret = writen (zclient->sock, s->data, stream_get_endp (s));
1662 if (ret < 0)
1663 {
1664 zlog_err ("%s: can't write to zclient->sock", __func__);
1665 close (zclient->sock);
1666 zclient->sock = -1;
1667 return -1;
1668 }
1669 if (ret == 0)
1670 {
1671 zlog_err ("%s: zclient->sock connection closed", __func__);
1672 close (zclient->sock);
1673 zclient->sock = -1;
1674 return -1;
1675 }
08c08a35
DS
1676 if (zclient_debug)
1677 zlog_debug ("%s: Label chunk request (%d bytes) sent", __func__, ret);
fea12efb 1678
1679 /* read response */
5c7ef8dc 1680 if (zclient_read_sync_response (zclient, ZEBRA_GET_LABEL_CHUNK) != 0)
1681 return -1;
08c08a35 1682
5c7ef8dc 1683 s = zclient->ibuf;
fea12efb 1684 /* keep */
1685 response_keep = stream_getc(s);
1686 /* start and end labels */
1687 *start = stream_getl(s);
1688 *end = stream_getl(s);
1689
1690 /* not owning this response */
5c7ef8dc 1691 if (keep != response_keep)
1692 {
1693 zlog_err ("%s: Invalid Label chunk: %u - %u, keeps mismatch %u != %u",
1694 __func__, *start, *end, keep, response_keep);
1695 }
fea12efb 1696 /* sanity */
1697 if (*start > *end
1698 || *start < MPLS_MIN_UNRESERVED_LABEL
5c7ef8dc 1699 || *end > MPLS_MAX_UNRESERVED_LABEL)
1700 {
1701 zlog_err ("%s: Invalid Label chunk: %u - %u", __func__,
1702 *start, *end);
1703 return -1;
1704 }
fea12efb 1705
08c08a35
DS
1706 if (zclient_debug)
1707 zlog_debug ("Label Chunk assign: %u - %u (%u) ",
1708 *start, *end, response_keep);
fea12efb 1709
1710 return 0;
1711}
1712
1713/**
1714 * Function to release a label chunk
1715 *
1716 * @param zclient Zclient used to connect to label manager (zebra)
1717 * @param start First label of chunk
1718 * @param end Last label of chunk
1719 * @result 0 on success, -1 otherwise
1720 */
1721int
1722lm_release_label_chunk (struct zclient *zclient, uint32_t start, uint32_t end)
1723{
1724 int ret;
1725 struct stream *s;
1726
08c08a35
DS
1727 if (zclient_debug)
1728 zlog_debug ("Releasing Label Chunk");
1729
fea12efb 1730 if (zclient->sock < 0)
1731 return -1;
1732
1733 /* send request */
1734 s = zclient->obuf;
1735 stream_reset (s);
1736 zclient_create_header (s, ZEBRA_RELEASE_LABEL_CHUNK, VRF_DEFAULT);
1737
1738 /* start */
1739 stream_putl (s, start);
1740 /* end */
1741 stream_putl (s, end);
1742
1743 /* Put length at the first point of the stream. */
1744 stream_putw_at(s, 0, stream_get_endp(s));
1745
1746 ret = writen (zclient->sock, s->data, stream_get_endp (s));
1747 if (ret < 0)
1748 {
1749 zlog_err ("%s: can't write to zclient->sock", __func__);
1750 close (zclient->sock);
1751 zclient->sock = -1;
1752 return -1;
1753 }
1754 if (ret == 0)
1755 {
1756 zlog_err ("%s: zclient->sock connection closed", __func__);
1757 close (zclient->sock);
1758 zclient->sock = -1;
1759 return -1;
1760 }
1761
1762 return 0;
1763}
c8e264b6 1764
718e3744 1765/* Zebra client message read function. */
634f9ea2 1766static int
718e3744 1767zclient_read (struct thread *thread)
1768{
634f9ea2 1769 size_t already;
c1b9800a 1770 uint16_t length, command;
1771 uint8_t marker, version;
7076bb2f 1772 vrf_id_t vrf_id;
718e3744 1773 struct zclient *zclient;
1774
1775 /* Get socket to zebra. */
718e3744 1776 zclient = THREAD_ARG (thread);
1777 zclient->t_read = NULL;
1778
634f9ea2 1779 /* Read zebra header (if we don't have it already). */
1780 if ((already = stream_get_endp(zclient->ibuf)) < ZEBRA_HEADER_SIZE)
718e3744 1781 {
634f9ea2 1782 ssize_t nbyte;
1783 if (((nbyte = stream_read_try(zclient->ibuf, zclient->sock,
1784 ZEBRA_HEADER_SIZE-already)) == 0) ||
1785 (nbyte == -1))
1786 {
1787 if (zclient_debug)
1788 zlog_debug ("zclient connection closed socket [%d].", zclient->sock);
1789 return zclient_failed(zclient);
1790 }
1791 if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE-already))
1792 {
1793 /* Try again later. */
1794 zclient_event (ZCLIENT_READ, zclient);
1795 return 0;
1796 }
1797 already = ZEBRA_HEADER_SIZE;
718e3744 1798 }
1799
634f9ea2 1800 /* Reset to read from the beginning of the incoming packet. */
1801 stream_set_getp(zclient->ibuf, 0);
718e3744 1802
c1b9800a 1803 /* Fetch header values. */
718e3744 1804 length = stream_getw (zclient->ibuf);
c1b9800a 1805 marker = stream_getc (zclient->ibuf);
1806 version = stream_getc (zclient->ibuf);
7076bb2f 1807 vrf_id = stream_getw (zclient->ibuf);
c1b9800a 1808 command = stream_getw (zclient->ibuf);
1809
1810 if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION)
1811 {
1812 zlog_err("%s: socket %d version mismatch, marker %d, version %d",
1813 __func__, zclient->sock, marker, version);
1814 return zclient_failed(zclient);
1815 }
1816
634f9ea2 1817 if (length < ZEBRA_HEADER_SIZE)
1818 {
1819 zlog_err("%s: socket %d message length %u is less than %d ",
1820 __func__, zclient->sock, length, ZEBRA_HEADER_SIZE);
1821 return zclient_failed(zclient);
1822 }
1823
718e3744 1824 /* Length check. */
634f9ea2 1825 if (length > STREAM_SIZE(zclient->ibuf))
718e3744 1826 {
634f9ea2 1827 struct stream *ns;
1828 zlog_warn("%s: message size %u exceeds buffer size %lu, expanding...",
1829 __func__, length, (u_long)STREAM_SIZE(zclient->ibuf));
1830 ns = stream_new(length);
1831 stream_copy(ns, zclient->ibuf);
718e3744 1832 stream_free (zclient->ibuf);
634f9ea2 1833 zclient->ibuf = ns;
718e3744 1834 }
718e3744 1835
1836 /* Read rest of zebra packet. */
634f9ea2 1837 if (already < length)
1838 {
1839 ssize_t nbyte;
1840 if (((nbyte = stream_read_try(zclient->ibuf, zclient->sock,
1841 length-already)) == 0) ||
1842 (nbyte == -1))
1843 {
1844 if (zclient_debug)
1845 zlog_debug("zclient connection closed socket [%d].", zclient->sock);
1846 return zclient_failed(zclient);
1847 }
1848 if (nbyte != (ssize_t)(length-already))
1849 {
1850 /* Try again later. */
1851 zclient_event (ZCLIENT_READ, zclient);
1852 return 0;
1853 }
1854 }
1855
1856 length -= ZEBRA_HEADER_SIZE;
718e3744 1857
0a589359 1858 if (zclient_debug)
7076bb2f 1859 zlog_debug("zclient 0x%p command 0x%x VRF %u\n", (void *)zclient, command, vrf_id);
0a589359 1860
718e3744 1861 switch (command)
1862 {
18a6dce6 1863 case ZEBRA_ROUTER_ID_UPDATE:
1864 if (zclient->router_id_update)
7076bb2f 1865 (*zclient->router_id_update) (command, zclient, length, vrf_id);
18a6dce6 1866 break;
1892f15e 1867 case ZEBRA_VRF_ADD:
ebe32f70 1868 zclient_vrf_add (zclient, vrf_id);
1892f15e
DS
1869 break;
1870 case ZEBRA_VRF_DELETE:
ebe32f70 1871 zclient_vrf_delete (zclient, vrf_id);
1892f15e 1872 break;
718e3744 1873 case ZEBRA_INTERFACE_ADD:
1874 if (zclient->interface_add)
7076bb2f 1875 (*zclient->interface_add) (command, zclient, length, vrf_id);
718e3744 1876 break;
1877 case ZEBRA_INTERFACE_DELETE:
1878 if (zclient->interface_delete)
7076bb2f 1879 (*zclient->interface_delete) (command, zclient, length, vrf_id);
718e3744 1880 break;
1881 case ZEBRA_INTERFACE_ADDRESS_ADD:
1882 if (zclient->interface_address_add)
7076bb2f 1883 (*zclient->interface_address_add) (command, zclient, length, vrf_id);
718e3744 1884 break;
1885 case ZEBRA_INTERFACE_ADDRESS_DELETE:
1886 if (zclient->interface_address_delete)
7076bb2f 1887 (*zclient->interface_address_delete) (command, zclient, length, vrf_id);
718e3744 1888 break;
68fe91d6 1889 case ZEBRA_INTERFACE_BFD_DEST_UPDATE:
1890 if (zclient->interface_bfd_dest_update)
7076bb2f 1891 (*zclient->interface_bfd_dest_update) (command, zclient, length, vrf_id);
d5a5c8f0 1892 break;
a80beece
DS
1893 case ZEBRA_INTERFACE_NBR_ADDRESS_ADD:
1894 if (zclient->interface_nbr_address_add)
7076bb2f 1895 (*zclient->interface_nbr_address_add) (command, zclient, length, vrf_id);
a80beece
DS
1896 break;
1897 case ZEBRA_INTERFACE_NBR_ADDRESS_DELETE:
1898 if (zclient->interface_nbr_address_delete)
7076bb2f 1899 (*zclient->interface_nbr_address_delete) (command, zclient, length, vrf_id);
a80beece 1900 break;
718e3744 1901 case ZEBRA_INTERFACE_UP:
1902 if (zclient->interface_up)
7076bb2f 1903 (*zclient->interface_up) (command, zclient, length, vrf_id);
718e3744 1904 break;
1905 case ZEBRA_INTERFACE_DOWN:
1906 if (zclient->interface_down)
7076bb2f 1907 (*zclient->interface_down) (command, zclient, length, vrf_id);
c8e264b6 1908 break;
1909 case ZEBRA_INTERFACE_VRF_UPDATE:
1910 if (zclient->interface_vrf_update)
1911 (*zclient->interface_vrf_update) (command, zclient, length, vrf_id);
718e3744 1912 break;
fb018d25
DS
1913 case ZEBRA_NEXTHOP_UPDATE:
1914 if (zclient_debug)
1915 zlog_debug("zclient rcvd nexthop update\n");
1916 if (zclient->nexthop_update)
7076bb2f 1917 (*zclient->nexthop_update) (command, zclient, length, vrf_id);
fb018d25 1918 break;
078430f6
DS
1919 case ZEBRA_IMPORT_CHECK_UPDATE:
1920 if (zclient_debug)
1921 zlog_debug("zclient rcvd import check update\n");
1922 if (zclient->import_check_update)
7076bb2f 1923 (*zclient->import_check_update) (command, zclient, length, vrf_id);
078430f6 1924 break;
c43ed2e4
DS
1925 case ZEBRA_BFD_DEST_REPLAY:
1926 if (zclient->bfd_dest_replay)
7076bb2f 1927 (*zclient->bfd_dest_replay) (command, zclient, length, vrf_id);
c43ed2e4 1928 break;
5048fe14 1929 case ZEBRA_REDISTRIBUTE_IPV4_ADD:
1930 if (zclient->redistribute_route_ipv4_add)
7076bb2f 1931 (*zclient->redistribute_route_ipv4_add) (command, zclient, length, vrf_id);
5048fe14 1932 break;
1933 case ZEBRA_REDISTRIBUTE_IPV4_DEL:
1934 if (zclient->redistribute_route_ipv4_del)
7076bb2f 1935 (*zclient->redistribute_route_ipv4_del) (command, zclient, length, vrf_id);
5048fe14 1936 break;
1937 case ZEBRA_REDISTRIBUTE_IPV6_ADD:
1938 if (zclient->redistribute_route_ipv6_add)
7076bb2f 1939 (*zclient->redistribute_route_ipv6_add) (command, zclient, length, vrf_id);
5048fe14 1940 break;
1941 case ZEBRA_REDISTRIBUTE_IPV6_DEL:
1942 if (zclient->redistribute_route_ipv6_del)
7076bb2f 1943 (*zclient->redistribute_route_ipv6_del) (command, zclient, length, vrf_id);
5cd459e8 1944 break;
16f1b9ee
OD
1945 case ZEBRA_INTERFACE_LINK_PARAMS:
1946 if (zclient->interface_link_params)
1947 (*zclient->interface_link_params) (command, zclient, length);
5048fe14 1948 break;
5aba114a
DS
1949 case ZEBRA_FEC_UPDATE:
1950 if (zclient_debug)
1951 zlog_debug("zclient rcvd fec update\n");
1952 if (zclient->fec_update)
1953 (*zclient->fec_update) (command, zclient, length);
1954 break;
718e3744 1955 default:
1956 break;
1957 }
1958
634f9ea2 1959 if (zclient->sock < 0)
1960 /* Connection was closed during packet processing. */
1961 return -1;
1962
718e3744 1963 /* Register read thread. */
634f9ea2 1964 stream_reset(zclient->ibuf);
718e3744 1965 zclient_event (ZCLIENT_READ, zclient);
1966
1967 return 0;
1968}
1969
1970void
8bb0831e 1971zclient_redistribute (int command, struct zclient *zclient, afi_t afi, int type,
7076bb2f 1972 u_short instance, vrf_id_t vrf_id)
718e3744 1973{
718e3744 1974
7076bb2f
FL
1975 if (instance) {
1976 if (command == ZEBRA_REDISTRIBUTE_ADD)
1977 {
1978 if (redist_check_instance(&zclient->mi_redist[afi][type], instance))
1979 return;
1980 redist_add_instance(&zclient->mi_redist[afi][type], instance);
1981 }
1982 else
1983 {
1984 if (!redist_check_instance(&zclient->mi_redist[afi][type], instance))
1985 return;
1986 redist_del_instance(&zclient->mi_redist[afi][type], instance);
1987 }
1988
1989 } else {
1990 if (command == ZEBRA_REDISTRIBUTE_ADD)
1991 {
1992 if (vrf_bitmap_check (zclient->redist[afi][type], vrf_id))
1993 return;
1994 vrf_bitmap_set (zclient->redist[afi][type], vrf_id);
1995 }
1996 else
1997 {
1998 if (!vrf_bitmap_check (zclient->redist[afi][type], vrf_id))
1999 return;
2000 vrf_bitmap_unset (zclient->redist[afi][type], vrf_id);
2001 }
2002 }
718e3744 2003
2004 if (zclient->sock > 0)
7076bb2f 2005 zebra_redistribute_send (command, zclient, afi, type, instance, vrf_id);
718e3744 2006}
2007
718e3744 2008
2009void
7076bb2f
FL
2010zclient_redistribute_default (int command, struct zclient *zclient,
2011 vrf_id_t vrf_id)
718e3744 2012{
718e3744 2013
0a589359 2014 if (command == ZEBRA_REDISTRIBUTE_DEFAULT_ADD)
2015 {
7076bb2f 2016 if (vrf_bitmap_check (zclient->default_information, vrf_id))
0a589359 2017 return;
7076bb2f 2018 vrf_bitmap_set (zclient->default_information, vrf_id);
0a589359 2019 }
2020 else
2021 {
7076bb2f 2022 if (!vrf_bitmap_check (zclient->default_information, vrf_id))
0a589359 2023 return;
7076bb2f 2024 vrf_bitmap_unset (zclient->default_information, vrf_id);
0a589359 2025 }
718e3744 2026
2027 if (zclient->sock > 0)
7076bb2f 2028 zebra_message_send (zclient, command, vrf_id);
718e3744 2029}
2030
718e3744 2031static void
2032zclient_event (enum event event, struct zclient *zclient)
2033{
2034 switch (event)
2035 {
2036 case ZCLIENT_SCHEDULE:
ffa2c898
QY
2037 thread_add_event(zclient->master, zclient_connect, zclient, 0,
2038 &zclient->t_connect);
718e3744 2039 break;
2040 case ZCLIENT_CONNECT:
718e3744 2041 if (zclient_debug)
b0e67bb0
DS
2042 zlog_debug ("zclient connect failures: %d schedule interval is now %d",
2043 zclient->fail, zclient->fail < 3 ? 10 : 60);
ffa2c898
QY
2044 thread_add_timer(zclient->master, zclient_connect, zclient,
2045 zclient->fail < 3 ? 10 : 60, &zclient->t_connect);
718e3744 2046 break;
2047 case ZCLIENT_READ:
66e78ae6
QY
2048 zclient->t_read = NULL;
2049 thread_add_read(zclient->master, zclient_read, zclient, zclient->sock,
2050 &zclient->t_read);
718e3744 2051 break;
2052 }
2053}
b5114685 2054
744f4685 2055const char *zclient_serv_path_get()
12e41d03
DL
2056{
2057 return zclient_serv_path ? zclient_serv_path : ZEBRA_SERV_PATH;
2058}
2059
b5114685
VT
2060void
2061zclient_serv_path_set (char *path)
2062{
2063 struct stat sb;
2064
2065 /* reset */
2066 zclient_serv_path = NULL;
2067
2068 /* test if `path' is socket. don't set it otherwise. */
2069 if (stat(path, &sb) == -1)
2070 {
2071 zlog_warn ("%s: zebra socket `%s' does not exist", __func__, path);
2072 return;
2073 }
2074
2075 if ((sb.st_mode & S_IFMT) != S_IFSOCK)
2076 {
2077 zlog_warn ("%s: `%s' is not unix socket, sir", __func__, path);
2078 return;
2079 }
2080
2081 /* it seems that path is unix socket */
2082 zclient_serv_path = path;
2083}
2084