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