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