]> git.proxmox.com Git - mirror_frr.git/blame - lib/zclient.c
Merge pull request #429 from hwchiu/fix_clang_sa
[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 {
ff9eb96a
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 {
ff9eb96a
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
ff9eb96a 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
789#ifdef HAVE_IPV6
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,
718e3744 858 struct zapi_ipv6 *api)
859{
860 int i;
861 int psize;
862 struct stream *s;
863
864 /* Reset stream. */
865 s = zclient->obuf;
866 stream_reset (s);
867
7076bb2f 868 zclient_create_header (s, cmd, api->vrf_id);
718e3744 869
c1b9800a 870 /* Put type and nexthop. */
718e3744 871 stream_putc (s, api->type);
7c8ff89e 872 stream_putw (s, api->instance);
0fc452dc 873 stream_putl (s, api->flags);
718e3744 874 stream_putc (s, api->message);
c7ec179a 875 stream_putw (s, api->safi);
718e3744 876
877 /* Put prefix information. */
878 psize = PSIZE (p->prefixlen);
879 stream_putc (s, p->prefixlen);
880 stream_write (s, (u_char *)&p->prefix, psize);
881
882 /* Nexthop, ifindex, distance and metric information. */
883 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
884 {
c3c0ac83
DS
885 if (CHECK_FLAG (api->flags, ZEBRA_FLAG_BLACKHOLE))
886 {
887 stream_putc (s, 1);
5b30316e 888 stream_putc (s, NEXTHOP_TYPE_BLACKHOLE);
c3c0ac83
DS
889 /* XXX assert(api->nexthop_num == 0); */
890 /* XXX assert(api->ifindex_num == 0); */
891 }
892 else
893 stream_putc (s, api->nexthop_num + api->ifindex_num);
718e3744 894
895 for (i = 0; i < api->nexthop_num; i++)
896 {
5b30316e 897 stream_putc (s, NEXTHOP_TYPE_IPV6);
718e3744 898 stream_write (s, (u_char *)api->nexthop[i], 16);
899 }
900 for (i = 0; i < api->ifindex_num; i++)
901 {
5b30316e 902 stream_putc (s, NEXTHOP_TYPE_IFINDEX);
718e3744 903 stream_putl (s, api->ifindex[i]);
904 }
905 }
906
907 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE))
908 stream_putc (s, api->distance);
909 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC))
910 stream_putl (s, api->metric);
0d9551dc 911 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_TAG))
dc9ffce8 912 stream_putl (s, api->tag);
c50ca33a
TT
913 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_MTU))
914 stream_putl (s, api->mtu);
718e3744 915
916 /* Put length at the first point of the stream. */
917 stream_putw_at (s, 0, stream_get_endp (s));
918
634f9ea2 919 return zclient_send_message(zclient);
718e3744 920}
718e3744 921#endif /* HAVE_IPV6 */
922
0a589359 923/*
924 * send a ZEBRA_REDISTRIBUTE_ADD or ZEBRA_REDISTRIBUTE_DELETE
925 * for the route type (ZEBRA_ROUTE_KERNEL etc.). The zebra server will
926 * then set/unset redist[type] in the client handle (a struct zserv) for the
927 * sending client
928 */
718e3744 929int
8bb0831e 930zebra_redistribute_send (int command, struct zclient *zclient, afi_t afi, int type,
7076bb2f 931 u_short instance, vrf_id_t vrf_id)
718e3744 932{
718e3744 933 struct stream *s;
934
634f9ea2 935 s = zclient->obuf;
936 stream_reset(s);
718e3744 937
7076bb2f 938 zclient_create_header (s, command, vrf_id);
8bb0831e 939 stream_putc (s, afi);
718e3744 940 stream_putc (s, type);
7c8ff89e 941 stream_putw (s, instance);
c1b9800a 942
943 stream_putw_at (s, 0, stream_get_endp (s));
944
634f9ea2 945 return zclient_send_message(zclient);
718e3744 946}
947
d9178828
PJ
948/* Get prefix in ZServ format; family should be filled in on prefix */
949static void
950zclient_stream_get_prefix (struct stream *s, struct prefix *p)
951{
952 size_t plen = prefix_blen (p);
953 u_char c;
954 p->prefixlen = 0;
955
956 if (plen == 0)
957 return;
958
959 stream_get (&p->u.prefix, s, plen);
960 c = stream_getc(s);
961 p->prefixlen = MIN(plen * 8, c);
962}
963
18a6dce6 964/* Router-id update from zebra daemon. */
965void
966zebra_router_id_update_read (struct stream *s, struct prefix *rid)
967{
18a6dce6 968 /* Fetch interface address. */
969 rid->family = stream_getc (s);
d9178828
PJ
970
971 zclient_stream_get_prefix (s, rid);
18a6dce6 972}
973
718e3744 974/* Interface addition from zebra daemon. */
0a589359 975/*
976 * The format of the message sent with type ZEBRA_INTERFACE_ADD or
977 * ZEBRA_INTERFACE_DELETE from zebra to the client is:
978 * 0 1 2 3
979 * 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 980 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
981 * | ifname |
982 * | |
983 * | |
984 * | |
985 * | |
986 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee
OD
987 * | ifindex |
988 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
989 * | status |
0a589359 990 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee 991 * | if_flags |
c77d4546 992 * | |
0a589359 993 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee
OD
994 * | metric |
995 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
996 * | ifmtu |
997 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
998 * | ifmtu6 |
999 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1000 * | bandwidth |
1001 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1002 * | Link Layer Type |
0a589359 1003 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee 1004 * | Harware Address Length |
0a589359 1005 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee
OD
1006 * | Hardware Address if HW lenght different from 0 |
1007 * | ... max INTERFACE_HWADDR_MAX |
0a589359 1008 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee 1009 * | Link_params? | Whether a link-params follows: 1 or 0.
0a589359 1010 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee
OD
1011 * | Link_params 0 or 1 INTERFACE_LINK_PARAMS_SIZE sized |
1012 * | .... (struct if_link_params). |
0a589359 1013 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1014 */
1015
2fcc254e 1016static void
ebe32f70 1017zclient_vrf_add (struct zclient *zclient, vrf_id_t vrf_id)
1892f15e
DS
1018{
1019 struct vrf *vrf;
1020 char vrfname_tmp[VRF_NAMSIZ];
1021
1022 /* Read interface name. */
ebe32f70 1023 stream_get (vrfname_tmp, zclient->ibuf, VRF_NAMSIZ);
1892f15e
DS
1024
1025 /* Lookup/create vrf by vrf_id. */
1026 vrf = vrf_get (vrf_id, vrfname_tmp);
1027
2fcc254e 1028 vrf_enable (vrf);
1892f15e
DS
1029}
1030
2fcc254e 1031static void
ebe32f70 1032zclient_vrf_delete (struct zclient *zclient, vrf_id_t vrf_id)
1892f15e
DS
1033{
1034 struct vrf *vrf;
1035
1036 /* Lookup vrf by vrf_id. */
5f3d1bdf 1037 vrf = vrf_lookup_by_id (vrf_id);
1892f15e 1038
beef1990
DS
1039 /*
1040 * If a routing protocol doesn't know about a
1041 * vrf that is about to be deleted. There is
1042 * no point in attempting to delete it.
1043 */
1044 if (!vrf)
1045 return;
1046
2fcc254e 1047 vrf_delete (vrf);
1892f15e
DS
1048}
1049
718e3744 1050struct interface *
7076bb2f 1051zebra_interface_add_read (struct stream *s, vrf_id_t vrf_id)
718e3744 1052{
1053 struct interface *ifp;
02ff83c5 1054 char ifname_tmp[INTERFACE_NAMSIZ];
718e3744 1055
1056 /* Read interface name. */
1057 stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
1058
a349198f 1059 /* Lookup/create interface by name. */
7076bb2f
FL
1060 ifp = if_get_by_name_len_vrf (ifname_tmp,
1061 strnlen (ifname_tmp, INTERFACE_NAMSIZ),
85f9da7f 1062 vrf_id, 0);
718e3744 1063
51d4ef83 1064 zebra_interface_if_set_value (s, ifp);
718e3744 1065
718e3744 1066 return ifp;
1067}
1068
0a589359 1069/*
1070 * Read interface up/down msg (ZEBRA_INTERFACE_UP/ZEBRA_INTERFACE_DOWN)
1071 * from zebra server. The format of this message is the same as
1072 * that sent for ZEBRA_INTERFACE_ADD/ZEBRA_INTERFACE_DELETE (see
1073 * comments for zebra_interface_add_read), except that no sockaddr_dl
1074 * is sent at the tail of the message.
1075 */
718e3744 1076struct interface *
7076bb2f 1077zebra_interface_state_read (struct stream *s, vrf_id_t vrf_id)
718e3744 1078{
1079 struct interface *ifp;
02ff83c5 1080 char ifname_tmp[INTERFACE_NAMSIZ];
718e3744 1081
1082 /* Read interface name. */
1083 stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
1084
1085 /* Lookup this by interface index. */
7076bb2f
FL
1086 ifp = if_lookup_by_name_len_vrf (ifname_tmp,
1087 strnlen (ifname_tmp, INTERFACE_NAMSIZ),
1088 vrf_id);
b4dd5eaa 1089 if (ifp == NULL)
1090 {
1091 zlog_warn ("INTERFACE_STATE: Cannot find IF %s in VRF %d",
1092 ifname_tmp, vrf_id);
1093 return NULL;
1094 }
718e3744 1095
51d4ef83 1096 zebra_interface_if_set_value (s, ifp);
718e3744 1097
1098 return ifp;
1099}
1100
16f1b9ee
OD
1101static void
1102link_params_set_value(struct stream *s, struct if_link_params *iflp)
1103{
1104
1105 if (iflp == NULL)
1106 return;
1107
1108 iflp->lp_status = stream_getl (s);
1109 iflp->te_metric = stream_getl (s);
1110 iflp->max_bw = stream_getf (s);
1111 iflp->max_rsv_bw = stream_getf (s);
1112 uint32_t bwclassnum = stream_getl (s);
1113 {
1114 unsigned int i;
1115 for (i = 0; i < bwclassnum && i < MAX_CLASS_TYPE; i++)
1116 iflp->unrsv_bw[i] = stream_getf (s);
1117 if (i < bwclassnum)
1118 zlog_err ("%s: received %d > %d (MAX_CLASS_TYPE) bw entries"
1119 " - outdated library?",
1120 __func__, bwclassnum, MAX_CLASS_TYPE);
1121 }
1122 iflp->admin_grp = stream_getl (s);
1123 iflp->rmt_as = stream_getl (s);
1124 iflp->rmt_ip.s_addr = stream_get_ipv4 (s);
1125
1126 iflp->av_delay = stream_getl (s);
1127 iflp->min_delay = stream_getl (s);
1128 iflp->max_delay = stream_getl (s);
1129 iflp->delay_var = stream_getl (s);
1130
1131 iflp->pkt_loss = stream_getf (s);
1132 iflp->res_bw = stream_getf (s);
1133 iflp->ava_bw = stream_getf (s);
1134 iflp->use_bw = stream_getf (s);
1135}
1136
1137struct interface *
1138zebra_interface_link_params_read (struct stream *s)
1139{
1140 struct if_link_params *iflp;
1141 uint32_t ifindex = stream_getl (s);
1142
1143 struct interface *ifp = if_lookup_by_index (ifindex);
1144
1145 if (ifp == NULL || s == NULL)
1146 {
1147 zlog_err ("%s: unknown ifindex %u, shouldn't happen",
1148 __func__, ifindex);
1149 return NULL;
1150 }
1151
1152 if ((iflp = if_link_params_get (ifp)) == NULL)
1153 return NULL;
1154
1155 link_params_set_value(s, iflp);
1156
1157 return ifp;
1158}
1159
1160void
1161zebra_interface_if_set_value (struct stream *s, struct interface *ifp)
1162{
1163 u_char link_params_status = 0;
1164
1165 /* Read interface's index. */
1166 ifp->ifindex = stream_getl (s);
1167 ifp->status = stream_getc (s);
1168
1169 /* Read interface's value. */
1170 ifp->flags = stream_getq (s);
1171 ifp->ptm_enable = stream_getc (s);
1172 ifp->ptm_status = stream_getc (s);
1173 ifp->metric = stream_getl (s);
1174 ifp->mtu = stream_getl (s);
1175 ifp->mtu6 = stream_getl (s);
1176 ifp->bandwidth = stream_getl (s);
1177 ifp->ll_type = stream_getl (s);
1178 ifp->hw_addr_len = stream_getl (s);
1179 if (ifp->hw_addr_len)
1180 stream_get (ifp->hw_addr, s, MIN(ifp->hw_addr_len, INTERFACE_HWADDR_MAX));
1181
1182 /* Read Traffic Engineering status */
1183 link_params_status = stream_getc (s);
1184 /* Then, Traffic Engineering parameters if any */
1185 if (link_params_status)
1186 {
1187 struct if_link_params *iflp = if_link_params_get (ifp);
1188 link_params_set_value(s, iflp);
1189 }
1190}
1191
1192size_t
1193zebra_interface_link_params_write (struct stream *s, struct interface *ifp)
1194{
1195 size_t w;
1196 struct if_link_params *iflp;
1197 int i;
1198
1199 if (s == NULL || ifp == NULL || ifp->link_params == NULL)
1200 return 0;
1201
1202 iflp = ifp->link_params;
1203 w = 0;
1204
1205 w += stream_putl (s, iflp->lp_status);
1206
1207 w += stream_putl (s, iflp->te_metric);
1208 w += stream_putf (s, iflp->max_bw);
1209 w += stream_putf (s, iflp->max_rsv_bw);
1210
1211 w += stream_putl (s, MAX_CLASS_TYPE);
1212 for (i = 0; i < MAX_CLASS_TYPE; i++)
1213 w += stream_putf (s, iflp->unrsv_bw[i]);
1214
1215 w += stream_putl (s, iflp->admin_grp);
1216 w += stream_putl (s, iflp->rmt_as);
1217 w += stream_put_in_addr (s, &iflp->rmt_ip);
1218
1219 w += stream_putl (s, iflp->av_delay);
1220 w += stream_putl (s, iflp->min_delay);
1221 w += stream_putl (s, iflp->max_delay);
1222 w += stream_putl (s, iflp->delay_var);
1223
1224 w += stream_putf (s, iflp->pkt_loss);
1225 w += stream_putf (s, iflp->res_bw);
1226 w += stream_putf (s, iflp->ava_bw);
1227 w += stream_putf (s, iflp->use_bw);
1228
1229 return w;
1230}
1231
1232/*
0a589359 1233 * format of message for address additon is:
1234 * 0
1235 * 0 1 2 3 4 5 6 7
1236 * +-+-+-+-+-+-+-+-+
1237 * | type | ZEBRA_INTERFACE_ADDRESS_ADD or
1238 * +-+-+-+-+-+-+-+-+ ZEBRA_INTERFACE_ADDRES_DELETE
1239 * | |
1240 * + +
1241 * | ifindex |
1242 * + +
1243 * | |
1244 * + +
1245 * | |
1246 * +-+-+-+-+-+-+-+-+
1247 * | ifc_flags | flags for connected address
1248 * +-+-+-+-+-+-+-+-+
1249 * | addr_family |
1250 * +-+-+-+-+-+-+-+-+
1251 * | addr... |
1252 * : :
1253 * | |
1254 * +-+-+-+-+-+-+-+-+
1255 * | addr_len | len of addr. E.g., addr_len = 4 for ipv4 addrs.
1256 * +-+-+-+-+-+-+-+-+
1257 * | daddr.. |
1258 * : :
1259 * | |
1260 * +-+-+-+-+-+-+-+-+
0a589359 1261 */
1262
3fb9cd6e 1263static int
1264memconstant(const void *s, int c, size_t n)
1265{
1266 const u_char *p = s;
1267
1268 while (n-- > 0)
1269 if (*p++ != c)
1270 return 0;
1271 return 1;
1272}
1273
d5a5c8f0 1274
718e3744 1275struct connected *
7076bb2f 1276zebra_interface_address_read (int type, struct stream *s, vrf_id_t vrf_id)
718e3744 1277{
b892f1dd 1278 ifindex_t ifindex;
718e3744 1279 struct interface *ifp;
1280 struct connected *ifc;
d9178828 1281 struct prefix p, d, *dp;
718e3744 1282 int plen;
0a589359 1283 u_char ifc_flags;
718e3744 1284
0a589359 1285 memset (&p, 0, sizeof(p));
1286 memset (&d, 0, sizeof(d));
718e3744 1287
1288 /* Get interface index. */
1289 ifindex = stream_getl (s);
1290
1291 /* Lookup index. */
7076bb2f 1292 ifp = if_lookup_by_index_vrf (ifindex, vrf_id);
718e3744 1293 if (ifp == NULL)
1294 {
b4dd5eaa 1295 zlog_warn ("INTERFACE_ADDRESS_%s: Cannot find IF %u in VRF %d",
1296 (type == ZEBRA_INTERFACE_ADDRESS_ADD) ? "ADD" : "DEL",
1297 ifindex, vrf_id);
718e3744 1298 return NULL;
1299 }
1300
1301 /* Fetch flag. */
0a589359 1302 ifc_flags = stream_getc (s);
718e3744 1303
1304 /* Fetch interface address. */
d9178828
PJ
1305 d.family = p.family = stream_getc (s);
1306 plen = prefix_blen (&d);
1307
1308 zclient_stream_get_prefix (s, &p);
718e3744 1309
1310 /* Fetch destination address. */
0a589359 1311 stream_get (&d.u.prefix, s, plen);
d9178828
PJ
1312
1313 /* N.B. NULL destination pointers are encoded as all zeroes */
1314 dp = memconstant(&d.u.prefix,0,plen) ? NULL : &d;
1315
0a589359 1316 if (type == ZEBRA_INTERFACE_ADDRESS_ADD)
1317 {
38485402
DS
1318 ifc = connected_lookup_prefix_exact (ifp, &p);
1319 if (!ifc)
1320 {
1321 /* N.B. NULL destination pointers are encoded as all zeroes */
d9178828 1322 ifc = connected_add_by_prefix(ifp, &p, dp);
38485402
DS
1323 }
1324 if (ifc)
e4529636
AS
1325 {
1326 ifc->flags = ifc_flags;
1327 if (ifc->destination)
1328 ifc->destination->prefixlen = ifc->address->prefixlen;
90444ca3
DL
1329 else if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_PEER))
1330 {
1331 /* carp interfaces on OpenBSD with 0.0.0.0/0 as "peer" */
855110bb 1332 char buf[PREFIX_STRLEN];
90444ca3
DL
1333 zlog_warn("warning: interface %s address %s "
1334 "with peer flag set, but no peer address!",
855110bb
TT
1335 ifp->name,
1336 prefix2str (ifc->address, buf, sizeof buf));
90444ca3
DL
1337 UNSET_FLAG(ifc->flags, ZEBRA_IFA_PEER);
1338 }
e4529636 1339 }
0a589359 1340 }
1341 else
1342 {
1343 assert (type == ZEBRA_INTERFACE_ADDRESS_DELETE);
1344 ifc = connected_delete_by_prefix(ifp, &p);
1345 }
718e3744 1346
1347 return ifc;
1348}
0a589359 1349
a80beece
DS
1350/*
1351 * format of message for neighbor connected address is:
1352 * 0
1353 * 0 1 2 3 4 5 6 7
1354 * +-+-+-+-+-+-+-+-+
1355 * | type | ZEBRA_INTERFACE_NBR_ADDRESS_ADD or
1356 * +-+-+-+-+-+-+-+-+ ZEBRA_INTERFACE_NBR_ADDRES_DELETE
1357 * | |
1358 * + +
1359 * | ifindex |
1360 * + +
1361 * | |
1362 * + +
1363 * | |
1364 * +-+-+-+-+-+-+-+-+
1365 * | addr_family |
1366 * +-+-+-+-+-+-+-+-+
1367 * | addr... |
1368 * : :
1369 * | |
1370 * +-+-+-+-+-+-+-+-+
1371 * | addr_len | len of addr.
1372 * +-+-+-+-+-+-+-+-+
1373 */
1374struct nbr_connected *
7076bb2f 1375zebra_interface_nbr_address_read (int type, struct stream *s, vrf_id_t vrf_id)
a80beece
DS
1376{
1377 unsigned int ifindex;
1378 struct interface *ifp;
1379 struct prefix p;
1380 struct nbr_connected *ifc;
1381
1382 /* Get interface index. */
1383 ifindex = stream_getl (s);
1384
1385 /* Lookup index. */
f1aa3df6 1386 ifp = if_lookup_by_index_vrf (ifindex, vrf_id);
a80beece
DS
1387 if (ifp == NULL)
1388 {
f1aa3df6 1389 zlog_warn ("INTERFACE_NBR_%s: Cannot find IF %u in VRF %d",
1390 (type == ZEBRA_INTERFACE_NBR_ADDRESS_ADD) ? "ADD" : "DELETE",
1391 ifindex, vrf_id);
a80beece
DS
1392 return NULL;
1393 }
1394
1395 p.family = stream_getc (s);
1396 stream_get (&p.u.prefix, s, prefix_blen (&p));
1397 p.prefixlen = stream_getc (s);
1398
1399 if (type == ZEBRA_INTERFACE_NBR_ADDRESS_ADD)
1400 {
1401 /* Currently only supporting P2P links, so any new RA source address is
1402 considered as the replacement of the previously learnt Link-Local address. */
1403 if (!(ifc = listnode_head(ifp->nbr_connected)))
1404 {
1405 ifc = nbr_connected_new ();
1406 ifc->address = prefix_new ();
1407 ifc->ifp = ifp;
1408 listnode_add (ifp->nbr_connected, ifc);
1409 }
1410
1411 prefix_copy(ifc->address, &p);
1412 }
1413 else
1414 {
1415 assert (type == ZEBRA_INTERFACE_NBR_ADDRESS_DELETE);
1416
1417 ifc = nbr_connected_check(ifp, &p);
1418 if (ifc)
1419 listnode_delete (ifp->nbr_connected, ifc);
1420 }
1421
1422 return ifc;
1423}
6b0655a2 1424
c8e264b6 1425struct interface *
1426zebra_interface_vrf_update_read (struct stream *s, vrf_id_t vrf_id,
1427 vrf_id_t *new_vrf_id)
1428{
1429 unsigned int ifindex;
1430 struct interface *ifp;
1431 vrf_id_t new_id = VRF_DEFAULT;
1432
1433 /* Get interface index. */
1434 ifindex = stream_getl (s);
1435
1436 /* Lookup interface. */
1437 ifp = if_lookup_by_index_vrf (ifindex, vrf_id);
1438 if (ifp == NULL)
1439 {
1440 zlog_warn ("INTERFACE_VRF_UPDATE: Cannot find IF %u in VRF %d",
1441 ifindex, vrf_id);
1442 return NULL;
1443 }
1444
1445 /* Fetch new VRF Id. */
1446 new_id = stream_getw (s);
1447
1448 *new_vrf_id = new_id;
1449 return ifp;
1450}
1451
718e3744 1452/* Zebra client message read function. */
634f9ea2 1453static int
718e3744 1454zclient_read (struct thread *thread)
1455{
634f9ea2 1456 size_t already;
c1b9800a 1457 uint16_t length, command;
1458 uint8_t marker, version;
7076bb2f 1459 vrf_id_t vrf_id;
718e3744 1460 struct zclient *zclient;
1461
1462 /* Get socket to zebra. */
718e3744 1463 zclient = THREAD_ARG (thread);
1464 zclient->t_read = NULL;
1465
634f9ea2 1466 /* Read zebra header (if we don't have it already). */
1467 if ((already = stream_get_endp(zclient->ibuf)) < ZEBRA_HEADER_SIZE)
718e3744 1468 {
634f9ea2 1469 ssize_t nbyte;
1470 if (((nbyte = stream_read_try(zclient->ibuf, zclient->sock,
1471 ZEBRA_HEADER_SIZE-already)) == 0) ||
1472 (nbyte == -1))
1473 {
1474 if (zclient_debug)
1475 zlog_debug ("zclient connection closed socket [%d].", zclient->sock);
1476 return zclient_failed(zclient);
1477 }
1478 if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE-already))
1479 {
1480 /* Try again later. */
1481 zclient_event (ZCLIENT_READ, zclient);
1482 return 0;
1483 }
1484 already = ZEBRA_HEADER_SIZE;
718e3744 1485 }
1486
634f9ea2 1487 /* Reset to read from the beginning of the incoming packet. */
1488 stream_set_getp(zclient->ibuf, 0);
718e3744 1489
c1b9800a 1490 /* Fetch header values. */
718e3744 1491 length = stream_getw (zclient->ibuf);
c1b9800a 1492 marker = stream_getc (zclient->ibuf);
1493 version = stream_getc (zclient->ibuf);
7076bb2f 1494 vrf_id = stream_getw (zclient->ibuf);
c1b9800a 1495 command = stream_getw (zclient->ibuf);
1496
1497 if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION)
1498 {
1499 zlog_err("%s: socket %d version mismatch, marker %d, version %d",
1500 __func__, zclient->sock, marker, version);
1501 return zclient_failed(zclient);
1502 }
1503
634f9ea2 1504 if (length < ZEBRA_HEADER_SIZE)
1505 {
1506 zlog_err("%s: socket %d message length %u is less than %d ",
1507 __func__, zclient->sock, length, ZEBRA_HEADER_SIZE);
1508 return zclient_failed(zclient);
1509 }
1510
718e3744 1511 /* Length check. */
634f9ea2 1512 if (length > STREAM_SIZE(zclient->ibuf))
718e3744 1513 {
634f9ea2 1514 struct stream *ns;
1515 zlog_warn("%s: message size %u exceeds buffer size %lu, expanding...",
1516 __func__, length, (u_long)STREAM_SIZE(zclient->ibuf));
1517 ns = stream_new(length);
1518 stream_copy(ns, zclient->ibuf);
718e3744 1519 stream_free (zclient->ibuf);
634f9ea2 1520 zclient->ibuf = ns;
718e3744 1521 }
718e3744 1522
1523 /* Read rest of zebra packet. */
634f9ea2 1524 if (already < length)
1525 {
1526 ssize_t nbyte;
1527 if (((nbyte = stream_read_try(zclient->ibuf, zclient->sock,
1528 length-already)) == 0) ||
1529 (nbyte == -1))
1530 {
1531 if (zclient_debug)
1532 zlog_debug("zclient connection closed socket [%d].", zclient->sock);
1533 return zclient_failed(zclient);
1534 }
1535 if (nbyte != (ssize_t)(length-already))
1536 {
1537 /* Try again later. */
1538 zclient_event (ZCLIENT_READ, zclient);
1539 return 0;
1540 }
1541 }
1542
1543 length -= ZEBRA_HEADER_SIZE;
718e3744 1544
0a589359 1545 if (zclient_debug)
7076bb2f 1546 zlog_debug("zclient 0x%p command 0x%x VRF %u\n", (void *)zclient, command, vrf_id);
0a589359 1547
718e3744 1548 switch (command)
1549 {
18a6dce6 1550 case ZEBRA_ROUTER_ID_UPDATE:
1551 if (zclient->router_id_update)
7076bb2f 1552 (*zclient->router_id_update) (command, zclient, length, vrf_id);
18a6dce6 1553 break;
1892f15e 1554 case ZEBRA_VRF_ADD:
ebe32f70 1555 zclient_vrf_add (zclient, vrf_id);
1892f15e
DS
1556 break;
1557 case ZEBRA_VRF_DELETE:
ebe32f70 1558 zclient_vrf_delete (zclient, vrf_id);
1892f15e 1559 break;
718e3744 1560 case ZEBRA_INTERFACE_ADD:
1561 if (zclient->interface_add)
7076bb2f 1562 (*zclient->interface_add) (command, zclient, length, vrf_id);
718e3744 1563 break;
1564 case ZEBRA_INTERFACE_DELETE:
1565 if (zclient->interface_delete)
7076bb2f 1566 (*zclient->interface_delete) (command, zclient, length, vrf_id);
718e3744 1567 break;
1568 case ZEBRA_INTERFACE_ADDRESS_ADD:
1569 if (zclient->interface_address_add)
7076bb2f 1570 (*zclient->interface_address_add) (command, zclient, length, vrf_id);
718e3744 1571 break;
1572 case ZEBRA_INTERFACE_ADDRESS_DELETE:
1573 if (zclient->interface_address_delete)
7076bb2f 1574 (*zclient->interface_address_delete) (command, zclient, length, vrf_id);
718e3744 1575 break;
68fe91d6 1576 case ZEBRA_INTERFACE_BFD_DEST_UPDATE:
1577 if (zclient->interface_bfd_dest_update)
7076bb2f 1578 (*zclient->interface_bfd_dest_update) (command, zclient, length, vrf_id);
d5a5c8f0 1579 break;
a80beece
DS
1580 case ZEBRA_INTERFACE_NBR_ADDRESS_ADD:
1581 if (zclient->interface_nbr_address_add)
7076bb2f 1582 (*zclient->interface_nbr_address_add) (command, zclient, length, vrf_id);
a80beece
DS
1583 break;
1584 case ZEBRA_INTERFACE_NBR_ADDRESS_DELETE:
1585 if (zclient->interface_nbr_address_delete)
7076bb2f 1586 (*zclient->interface_nbr_address_delete) (command, zclient, length, vrf_id);
a80beece 1587 break;
718e3744 1588 case ZEBRA_INTERFACE_UP:
1589 if (zclient->interface_up)
7076bb2f 1590 (*zclient->interface_up) (command, zclient, length, vrf_id);
718e3744 1591 break;
1592 case ZEBRA_INTERFACE_DOWN:
1593 if (zclient->interface_down)
7076bb2f 1594 (*zclient->interface_down) (command, zclient, length, vrf_id);
c8e264b6 1595 break;
1596 case ZEBRA_INTERFACE_VRF_UPDATE:
1597 if (zclient->interface_vrf_update)
1598 (*zclient->interface_vrf_update) (command, zclient, length, vrf_id);
718e3744 1599 break;
fb018d25
DS
1600 case ZEBRA_NEXTHOP_UPDATE:
1601 if (zclient_debug)
1602 zlog_debug("zclient rcvd nexthop update\n");
1603 if (zclient->nexthop_update)
7076bb2f 1604 (*zclient->nexthop_update) (command, zclient, length, vrf_id);
fb018d25 1605 break;
078430f6
DS
1606 case ZEBRA_IMPORT_CHECK_UPDATE:
1607 if (zclient_debug)
1608 zlog_debug("zclient rcvd import check update\n");
1609 if (zclient->import_check_update)
7076bb2f 1610 (*zclient->import_check_update) (command, zclient, length, vrf_id);
078430f6 1611 break;
c43ed2e4
DS
1612 case ZEBRA_BFD_DEST_REPLAY:
1613 if (zclient->bfd_dest_replay)
7076bb2f 1614 (*zclient->bfd_dest_replay) (command, zclient, length, vrf_id);
c43ed2e4 1615 break;
5048fe14 1616 case ZEBRA_REDISTRIBUTE_IPV4_ADD:
1617 if (zclient->redistribute_route_ipv4_add)
7076bb2f 1618 (*zclient->redistribute_route_ipv4_add) (command, zclient, length, vrf_id);
5048fe14 1619 break;
1620 case ZEBRA_REDISTRIBUTE_IPV4_DEL:
1621 if (zclient->redistribute_route_ipv4_del)
7076bb2f 1622 (*zclient->redistribute_route_ipv4_del) (command, zclient, length, vrf_id);
5048fe14 1623 break;
1624 case ZEBRA_REDISTRIBUTE_IPV6_ADD:
1625 if (zclient->redistribute_route_ipv6_add)
7076bb2f 1626 (*zclient->redistribute_route_ipv6_add) (command, zclient, length, vrf_id);
5048fe14 1627 break;
1628 case ZEBRA_REDISTRIBUTE_IPV6_DEL:
1629 if (zclient->redistribute_route_ipv6_del)
7076bb2f 1630 (*zclient->redistribute_route_ipv6_del) (command, zclient, length, vrf_id);
16f1b9ee
OD
1631 case ZEBRA_INTERFACE_LINK_PARAMS:
1632 if (zclient->interface_link_params)
1633 (*zclient->interface_link_params) (command, zclient, length);
5048fe14 1634 break;
718e3744 1635 default:
1636 break;
1637 }
1638
634f9ea2 1639 if (zclient->sock < 0)
1640 /* Connection was closed during packet processing. */
1641 return -1;
1642
718e3744 1643 /* Register read thread. */
634f9ea2 1644 stream_reset(zclient->ibuf);
718e3744 1645 zclient_event (ZCLIENT_READ, zclient);
1646
1647 return 0;
1648}
1649
1650void
8bb0831e 1651zclient_redistribute (int command, struct zclient *zclient, afi_t afi, int type,
7076bb2f 1652 u_short instance, vrf_id_t vrf_id)
718e3744 1653{
718e3744 1654
7076bb2f
FL
1655 if (instance) {
1656 if (command == ZEBRA_REDISTRIBUTE_ADD)
1657 {
1658 if (redist_check_instance(&zclient->mi_redist[afi][type], instance))
1659 return;
1660 redist_add_instance(&zclient->mi_redist[afi][type], instance);
1661 }
1662 else
1663 {
1664 if (!redist_check_instance(&zclient->mi_redist[afi][type], instance))
1665 return;
1666 redist_del_instance(&zclient->mi_redist[afi][type], instance);
1667 }
1668
1669 } else {
1670 if (command == ZEBRA_REDISTRIBUTE_ADD)
1671 {
1672 if (vrf_bitmap_check (zclient->redist[afi][type], vrf_id))
1673 return;
1674 vrf_bitmap_set (zclient->redist[afi][type], vrf_id);
1675 }
1676 else
1677 {
1678 if (!vrf_bitmap_check (zclient->redist[afi][type], vrf_id))
1679 return;
1680 vrf_bitmap_unset (zclient->redist[afi][type], vrf_id);
1681 }
1682 }
718e3744 1683
1684 if (zclient->sock > 0)
7076bb2f 1685 zebra_redistribute_send (command, zclient, afi, type, instance, vrf_id);
718e3744 1686}
1687
718e3744 1688
1689void
7076bb2f
FL
1690zclient_redistribute_default (int command, struct zclient *zclient,
1691 vrf_id_t vrf_id)
718e3744 1692{
718e3744 1693
0a589359 1694 if (command == ZEBRA_REDISTRIBUTE_DEFAULT_ADD)
1695 {
7076bb2f 1696 if (vrf_bitmap_check (zclient->default_information, vrf_id))
0a589359 1697 return;
7076bb2f 1698 vrf_bitmap_set (zclient->default_information, vrf_id);
0a589359 1699 }
1700 else
1701 {
7076bb2f 1702 if (!vrf_bitmap_check (zclient->default_information, vrf_id))
0a589359 1703 return;
7076bb2f 1704 vrf_bitmap_unset (zclient->default_information, vrf_id);
0a589359 1705 }
718e3744 1706
1707 if (zclient->sock > 0)
7076bb2f 1708 zebra_message_send (zclient, command, vrf_id);
718e3744 1709}
1710
718e3744 1711static void
1712zclient_event (enum event event, struct zclient *zclient)
1713{
1714 switch (event)
1715 {
1716 case ZCLIENT_SCHEDULE:
1717 if (! zclient->t_connect)
1718 zclient->t_connect =
4140ca4d 1719 thread_add_event (zclient->master, zclient_connect, zclient, 0);
718e3744 1720 break;
1721 case ZCLIENT_CONNECT:
718e3744 1722 if (zclient_debug)
ff9eb96a
DS
1723 zlog_debug ("zclient connect failures: %d schedule interval is now %d",
1724 zclient->fail, zclient->fail < 3 ? 10 : 60);
718e3744 1725 if (! zclient->t_connect)
1726 zclient->t_connect =
4140ca4d 1727 thread_add_timer (zclient->master, zclient_connect, zclient,
718e3744 1728 zclient->fail < 3 ? 10 : 60);
1729 break;
1730 case ZCLIENT_READ:
1731 zclient->t_read =
4140ca4d 1732 thread_add_read (zclient->master, zclient_read, zclient, zclient->sock);
718e3744 1733 break;
1734 }
1735}
b5114685 1736
744f4685 1737const char *zclient_serv_path_get()
12e41d03
DL
1738{
1739 return zclient_serv_path ? zclient_serv_path : ZEBRA_SERV_PATH;
1740}
1741
b5114685
VT
1742void
1743zclient_serv_path_set (char *path)
1744{
1745 struct stat sb;
1746
1747 /* reset */
1748 zclient_serv_path = NULL;
1749
1750 /* test if `path' is socket. don't set it otherwise. */
1751 if (stat(path, &sb) == -1)
1752 {
1753 zlog_warn ("%s: zebra socket `%s' does not exist", __func__, path);
1754 return;
1755 }
1756
1757 if ((sb.st_mode & S_IFMT) != S_IFSOCK)
1758 {
1759 zlog_warn ("%s: `%s' is not unix socket, sir", __func__, path);
1760 return;
1761 }
1762
1763 /* it seems that path is unix socket */
1764 zclient_serv_path = path;
1765}
1766