]> git.proxmox.com Git - mirror_frr.git/blame - lib/zclient.c
ospfd: ospfd-virtual-link.patch
[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"
6b0655a2 35
718e3744 36/* Zebra client events. */
37enum event {ZCLIENT_SCHEDULE, ZCLIENT_READ, ZCLIENT_CONNECT};
38
39/* Prototype for event manager. */
40static void zclient_event (enum event, struct zclient *);
41
634f9ea2 42extern struct thread_master *master;
43
b5114685
VT
44char *zclient_serv_path = NULL;
45
718e3744 46/* This file local debug flag. */
47int zclient_debug = 0;
6b0655a2 48
718e3744 49/* Allocate zclient structure. */
50struct zclient *
51zclient_new ()
52{
53 struct zclient *zclient;
393deb9b 54 zclient = XCALLOC (MTYPE_ZCLIENT, sizeof (struct zclient));
718e3744 55
56 zclient->ibuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
57 zclient->obuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
634f9ea2 58 zclient->wb = buffer_new(0);
718e3744 59
60 return zclient;
61}
62
228da428 63/* This function is only called when exiting, because
634f9ea2 64 many parts of the code do not check for I/O errors, so they could
65 reference an invalid pointer if the structure was ever freed.
634f9ea2 66
228da428 67 Free zclient structure. */
718e3744 68void
69zclient_free (struct zclient *zclient)
70{
634f9ea2 71 if (zclient->ibuf)
72 stream_free(zclient->ibuf);
73 if (zclient->obuf)
74 stream_free(zclient->obuf);
75 if (zclient->wb)
76 buffer_free(zclient->wb);
77
718e3744 78 XFREE (MTYPE_ZCLIENT, zclient);
79}
80
7c8ff89e
DS
81int
82redist_check_instance (struct redist_proto *red, u_short instance)
83{
84 struct listnode *node;
85 u_short *id;
86
87 if (!red->instances)
88 return 0;
89
90 for (ALL_LIST_ELEMENTS_RO (red->instances, node, id))
91 if (*id == instance)
92 return 1;
93
94 return 0;
95}
96
97void
98redist_add_instance (struct redist_proto *red, u_short instance)
99{
100 u_short *in;
101
102 red->enabled = 1;
103
104 if (!red->instances)
105 red->instances = list_new();
106
107 in = (u_short *)calloc(1, sizeof(u_short));
108 *in = instance;
109 listnode_add (red->instances, in);
110}
111
112void
113redist_del_instance (struct redist_proto *red, u_short instance)
114{
115 struct listnode *node;
116 u_short *id = NULL;
117
118 if (!red->instances)
24873f0c 119 return;
7c8ff89e
DS
120
121 for (ALL_LIST_ELEMENTS_RO (red->instances, node, id))
122 if (*id == instance)
123 break;
124
125 if (id)
126 {
127 listnode_delete(red->instances, id);
128 if (!red->instances->count)
129 {
130 red->enabled = 0;
131 list_free(red->instances);
132 red->instances = NULL;
133 }
134 }
135}
136
718e3744 137/* Stop zebra client services. */
138void
139zclient_stop (struct zclient *zclient)
140{
141 if (zclient_debug)
8ddca704 142 zlog_debug ("zclient stopped");
718e3744 143
144 /* Stop threads. */
634f9ea2 145 THREAD_OFF(zclient->t_read);
146 THREAD_OFF(zclient->t_connect);
147 THREAD_OFF(zclient->t_write);
148
149 /* Reset streams. */
150 stream_reset(zclient->ibuf);
151 stream_reset(zclient->obuf);
152
153 /* Empty the write buffer. */
154 buffer_reset(zclient->wb);
718e3744 155
156 /* Close socket. */
157 if (zclient->sock >= 0)
158 {
159 close (zclient->sock);
160 zclient->sock = -1;
161 }
162 zclient->fail = 0;
163}
164
165void
166zclient_reset (struct zclient *zclient)
167{
168 zclient_stop (zclient);
7c8ff89e 169 zclient_init (zclient, zclient->redist_default, zclient->instance);
718e3744 170}
171
b5114685
VT
172#ifdef HAVE_TCP_ZEBRA
173
718e3744 174/* Make socket to zebra daemon. Return zebra socket. */
b5114685 175static int
634f9ea2 176zclient_socket(void)
718e3744 177{
178 int sock;
179 int ret;
180 struct sockaddr_in serv;
181
182 /* We should think about IPv6 connection. */
183 sock = socket (AF_INET, SOCK_STREAM, 0);
184 if (sock < 0)
185 return -1;
186
187 /* Make server socket. */
188 memset (&serv, 0, sizeof (struct sockaddr_in));
189 serv.sin_family = AF_INET;
190 serv.sin_port = htons (ZEBRA_PORT);
6f0e3f6e 191#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
718e3744 192 serv.sin_len = sizeof (struct sockaddr_in);
6f0e3f6e 193#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
718e3744 194 serv.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
195
196 /* Connect to zebra. */
197 ret = connect (sock, (struct sockaddr *) &serv, sizeof (serv));
198 if (ret < 0)
199 {
200 close (sock);
201 return -1;
202 }
203 return sock;
204}
205
3414d035 206#else
b5114685 207
718e3744 208/* For sockaddr_un. */
209#include <sys/un.h>
210
b5114685 211static int
8c328f11 212zclient_socket_un (const char *path)
718e3744 213{
214 int ret;
215 int sock, len;
216 struct sockaddr_un addr;
217
218 sock = socket (AF_UNIX, SOCK_STREAM, 0);
219 if (sock < 0)
220 return -1;
221
222 /* Make server socket. */
223 memset (&addr, 0, sizeof (struct sockaddr_un));
224 addr.sun_family = AF_UNIX;
225 strncpy (addr.sun_path, path, strlen (path));
6f0e3f6e 226#ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
718e3744 227 len = addr.sun_len = SUN_LEN(&addr);
228#else
229 len = sizeof (addr.sun_family) + strlen (addr.sun_path);
6f0e3f6e 230#endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
718e3744 231
232 ret = connect (sock, (struct sockaddr *) &addr, len);
233 if (ret < 0)
234 {
235 close (sock);
236 return -1;
237 }
238 return sock;
239}
240
3414d035
VT
241#endif /* HAVE_TCP_ZEBRA */
242
b5114685
VT
243/**
244 * Connect to zebra daemon.
245 * @param zclient a pointer to zclient structure
246 * @return socket fd just to make sure that connection established
247 * @see zclient_init
248 * @see zclient_new
249 */
250int
251zclient_socket_connect (struct zclient *zclient)
252{
253#ifdef HAVE_TCP_ZEBRA
254 zclient->sock = zclient_socket ();
255#else
256 zclient->sock = zclient_socket_un (zclient_serv_path ? zclient_serv_path : ZEBRA_SERV_PATH);
257#endif
258 return zclient->sock;
259}
260
634f9ea2 261static int
262zclient_failed(struct zclient *zclient)
263{
264 zclient->fail++;
265 zclient_stop(zclient);
266 zclient_event(ZCLIENT_CONNECT, zclient);
267 return -1;
268}
269
270static int
271zclient_flush_data(struct thread *thread)
272{
273 struct zclient *zclient = THREAD_ARG(thread);
274
275 zclient->t_write = NULL;
276 if (zclient->sock < 0)
277 return -1;
278 switch (buffer_flush_available(zclient->wb, zclient->sock))
279 {
280 case BUFFER_ERROR:
281 zlog_warn("%s: buffer_flush_available failed on zclient fd %d, closing",
282 __func__, zclient->sock);
283 return zclient_failed(zclient);
284 break;
285 case BUFFER_PENDING:
286 zclient->t_write = thread_add_write(master, zclient_flush_data,
287 zclient, zclient->sock);
288 break;
289 case BUFFER_EMPTY:
290 break;
291 }
292 return 0;
293}
294
718e3744 295int
634f9ea2 296zclient_send_message(struct zclient *zclient)
297{
298 if (zclient->sock < 0)
299 return -1;
300 switch (buffer_write(zclient->wb, zclient->sock, STREAM_DATA(zclient->obuf),
301 stream_get_endp(zclient->obuf)))
302 {
303 case BUFFER_ERROR:
304 zlog_warn("%s: buffer_write failed to zclient fd %d, closing",
305 __func__, zclient->sock);
306 return zclient_failed(zclient);
307 break;
308 case BUFFER_EMPTY:
309 THREAD_OFF(zclient->t_write);
310 break;
311 case BUFFER_PENDING:
312 THREAD_WRITE_ON(master, zclient->t_write,
313 zclient_flush_data, zclient, zclient->sock);
314 break;
315 }
316 return 0;
317}
318
d211086a 319void
c1b9800a 320zclient_create_header (struct stream *s, uint16_t command)
321{
322 /* length placeholder, caller can update */
323 stream_putw (s, ZEBRA_HEADER_SIZE);
324 stream_putc (s, ZEBRA_HEADER_MARKER);
325 stream_putc (s, ZSERV_VERSION);
326 stream_putw (s, command);
327}
328
634f9ea2 329/* Send simple Zebra message. */
330static int
718e3744 331zebra_message_send (struct zclient *zclient, int command)
332{
333 struct stream *s;
334
335 /* Get zclient output buffer. */
336 s = zclient->obuf;
337 stream_reset (s);
338
339 /* Send very simple command only Zebra message. */
c1b9800a 340 zclient_create_header (s, command);
341
634f9ea2 342 return zclient_send_message(zclient);
718e3744 343}
344
2ea1ab1c
VT
345static int
346zebra_hello_send (struct zclient *zclient)
347{
348 struct stream *s;
349
350 if (zclient->redist_default)
351 {
352 s = zclient->obuf;
353 stream_reset (s);
354
355 zclient_create_header (s, ZEBRA_HELLO);
356 stream_putc (s, zclient->redist_default);
7c8ff89e 357 stream_putw (s, zclient->instance);
2ea1ab1c
VT
358 stream_putw_at (s, 0, stream_get_endp (s));
359 return zclient_send_message(zclient);
360 }
361
362 return 0;
363}
364
718e3744 365/* Make connection to zebra daemon. */
366int
367zclient_start (struct zclient *zclient)
368{
369 int i;
8bb0831e 370 afi_t afi;
718e3744 371
718e3744 372 /* If already connected to the zebra. */
373 if (zclient->sock >= 0)
374 return 0;
375
376 /* Check connect thread. */
377 if (zclient->t_connect)
378 return 0;
379
718e3744 380 /* Flush all redistribute request. */
8bb0831e
DS
381 for (afi = AFI_IP; afi < AFI_MAX; afi++)
382 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
383 if (zclient->redist[afi][i].enabled)
384 {
385 struct listnode *node;
386 u_short *id;
7c8ff89e 387
8bb0831e
DS
388 for (ALL_LIST_ELEMENTS_RO(zclient->redist[afi][i].instances, node, id))
389 if (!(i == zclient->redist_default && *id == zclient->instance))
390 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, afi, i, *id);
391 }
718e3744 392
393 /* If default information is needed. */
394 if (zclient->default_information)
395 zebra_message_send (zclient, ZEBRA_REDISTRIBUTE_DEFAULT_ADD);
396
397 return 0;
398}
399
400/* This function is a wrapper function for calling zclient_start from
401 timer or event thread. */
634f9ea2 402static int
718e3744 403zclient_connect (struct thread *t)
404{
405 struct zclient *zclient;
406
407 zclient = THREAD_ARG (t);
408 zclient->t_connect = NULL;
409
410 if (zclient_debug)
8ddca704 411 zlog_debug ("zclient_connect is called");
718e3744 412
413 return zclient_start (zclient);
414}
6b0655a2 415
078430f6
DS
416/* Initialize zebra client. Argument redist_default is unwanted
417 redistribute route type. */
418void
419zclient_init (struct zclient *zclient, int redist_default, u_short instance)
420{
421 int afi, i;
422
423 /* Enable zebra client connection by default. */
424 zclient->enable = 1;
425
426 /* Set -1 to the default socket value. */
427 zclient->sock = -1;
428
429 /* Clear redistribution flags. */
430 for (afi = AFI_IP; afi < AFI_MAX; afi++)
431 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
432 memset(&zclient->redist[afi][i], 0, sizeof(struct redist_proto));
433
434 /* Set unwanted redistribute route. bgpd does not need BGP route
435 redistribution. */
436 zclient->redist_default = redist_default;
437 zclient->instance = instance;
438 /* Pending: make afi(s) an arg. */
439 for (afi = AFI_IP; afi < AFI_MAX; afi++)
440 redist_add_instance (&zclient->redist[afi][redist_default], instance);
441
442 /* Set default-information redistribute to zero. */
443 zclient->default_information = 0;
444
445 if (zclient_debug)
446 zlog_debug ("zclient_start is called");
447
448 /* zclient is disabled. */
449 if (! zclient->enable)
450 return;
451
452 if (zclient_socket_connect(zclient) < 0)
453 {
454 if (zclient_debug)
455 zlog_debug ("zclient connection fail");
456 zclient->fail++;
457 zclient_event (ZCLIENT_CONNECT, zclient);
458 return;
459 }
460
461 if (set_nonblocking(zclient->sock) < 0)
462 zlog_warn("%s: set_nonblocking(%d) failed", __func__, zclient->sock);
463
464 /* Clear fail count. */
465 zclient->fail = 0;
466 if (zclient_debug)
467 zlog_debug ("zclient connect success with socket [%d]", zclient->sock);
468
469 /* Create read thread. */
470 zclient_event (ZCLIENT_READ, zclient);
471
472 zebra_hello_send (zclient);
473
474 /* We need router-id information. */
475 zebra_message_send (zclient, ZEBRA_ROUTER_ID_ADD);
476
477 /* We need interface information. */
478 zebra_message_send (zclient, ZEBRA_INTERFACE_ADD);
479
480 zclient_event (ZCLIENT_SCHEDULE, zclient);
481}
482
0a589359 483 /*
484 * "xdr_encode"-like interface that allows daemon (client) to send
485 * a message to zebra server for a route that needs to be
486 * added/deleted to the kernel. Info about the route is specified
487 * by the caller in a struct zapi_ipv4. zapi_ipv4_read() then writes
488 * the info down the zclient socket using the stream_* functions.
489 *
490 * The corresponding read ("xdr_decode") function on the server
491 * side is zread_ipv4_add()/zread_ipv4_delete().
492 *
493 * 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
494 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
495 * | Length (2) | Command | Route Type |
496 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
497 * | ZEBRA Flags | Message Flags | Prefix length |
498 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
499 * | Destination IPv4 Prefix for route |
500 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
501 * | Nexthop count |
502 * +-+-+-+-+-+-+-+-+
503 *
504 *
505 * A number of IPv4 nexthop(s) or nexthop interface index(es) are then
506 * described, as per the Nexthop count. Each nexthop described as:
507 *
508 * +-+-+-+-+-+-+-+-+
509 * | Nexthop Type | Set to one of ZEBRA_NEXTHOP_*
510 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
511 * | IPv4 Nexthop address or Interface Index number |
512 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
513 *
514 * Alternatively, if the flags field has ZEBRA_FLAG_BLACKHOLE or
515 * ZEBRA_FLAG_REJECT is set then Nexthop count is set to 1, then _no_
516 * nexthop information is provided, and the message describes a prefix
517 * to blackhole or reject route.
518 *
c8a1cb5c
DS
519 * The original struct zapi_ipv4, zapi_ipv4_route() and zread_ipv4_*()
520 * infrastructure was built around the traditional (32-bit "gate OR
521 * ifindex") nexthop data unit. A special encoding can be used to feed
522 * onlink (64-bit "gate AND ifindex") nexthops into zapi_ipv4_route()
523 * using the same zapi_ipv4 structure. This is done by setting zapi_ipv4
524 * fields as follows:
525 * - .message |= ZAPI_MESSAGE_NEXTHOP | ZAPI_MESSAGE_ONLINK
526 * - .nexthop_num == .ifindex_num
527 * - .nexthop and .ifindex are filled with gate and ifindex parts of
528 * each compound nexthop, both in the same order
529 *
530 * zapi_ipv4_route() will produce two nexthop data units for each such
531 * interleaved 64-bit nexthop. On the zserv side of the socket it will be
532 * mapped to a singlle NEXTHOP_TYPE_IPV4_IFINDEX_OL RIB nexthop structure.
533 *
0a589359 534 * If ZAPI_MESSAGE_DISTANCE is set, the distance value is written as a 1
535 * byte value.
536 *
537 * If ZAPI_MESSAGE_METRIC is set, the metric value is written as an 8
538 * byte value.
539 *
0d9551dc
DS
540 * If ZAPI_MESSAGE_TAG is set, the tag value is written as a 2 byte value
541 *
0a589359 542 * XXX: No attention paid to alignment.
543 */
718e3744 544int
0a589359 545zapi_ipv4_route (u_char cmd, struct zclient *zclient, struct prefix_ipv4 *p,
546 struct zapi_ipv4 *api)
718e3744 547{
548 int i;
549 int psize;
550 struct stream *s;
551
552 /* Reset stream. */
553 s = zclient->obuf;
554 stream_reset (s);
c1b9800a 555
556 zclient_create_header (s, cmd);
557
558 /* Put type and nexthop. */
718e3744 559 stream_putc (s, api->type);
7c8ff89e 560 stream_putw (s, api->instance);
718e3744 561 stream_putc (s, api->flags);
562 stream_putc (s, api->message);
5a616c08 563 stream_putw (s, api->safi);
718e3744 564
718e3744 565 /* Put prefix information. */
566 psize = PSIZE (p->prefixlen);
567 stream_putc (s, p->prefixlen);
0a589359 568 stream_write (s, (u_char *) & p->prefix, psize);
718e3744 569
570 /* Nexthop, ifindex, distance and metric information. */
c8a1cb5c
DS
571 /* ZAPI_MESSAGE_ONLINK implies interleaving */
572 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_ONLINK))
718e3744 573 {
c8a1cb5c
DS
574 /* ZAPI_MESSAGE_NEXTHOP is required for proper receiving */
575 assert (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP));
576 /* 64-bit data units, interleaved between nexthop[] and ifindex[] */
577 assert (api->nexthop_num == api->ifindex_num);
578 stream_putc (s, api->nexthop_num * 2);
579 for (i = 0; i < api->nexthop_num; i++)
580 {
581 stream_putc (s, ZEBRA_NEXTHOP_IPV4_ONLINK);
582 stream_put_in_addr (s, api->nexthop[i]);
583 stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
584 stream_putl (s, api->ifindex[i]);
585 }
586 }
587 else if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
588 {
589 /* traditional 32-bit data units */
595db7f1 590 if (CHECK_FLAG (api->flags, ZEBRA_FLAG_BLACKHOLE))
591 {
592 stream_putc (s, 1);
593 stream_putc (s, ZEBRA_NEXTHOP_BLACKHOLE);
0a589359 594 /* XXX assert(api->nexthop_num == 0); */
595 /* XXX assert(api->ifindex_num == 0); */
595db7f1 596 }
597 else
598 stream_putc (s, api->nexthop_num + api->ifindex_num);
718e3744 599
600 for (i = 0; i < api->nexthop_num; i++)
595db7f1 601 {
602 stream_putc (s, ZEBRA_NEXTHOP_IPV4);
603 stream_put_in_addr (s, api->nexthop[i]);
604 }
718e3744 605 for (i = 0; i < api->ifindex_num; i++)
595db7f1 606 {
607 stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
608 stream_putl (s, api->ifindex[i]);
609 }
718e3744 610 }
611
612 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE))
613 stream_putc (s, api->distance);
614 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC))
615 stream_putl (s, api->metric);
0d9551dc
DS
616 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_TAG))
617 stream_putw (s, api->tag);
718e3744 618
619 /* Put length at the first point of the stream. */
620 stream_putw_at (s, 0, stream_get_endp (s));
621
634f9ea2 622 return zclient_send_message(zclient);
718e3744 623}
624
625#ifdef HAVE_IPV6
626int
0a589359 627zapi_ipv6_route (u_char cmd, struct zclient *zclient, struct prefix_ipv6 *p,
718e3744 628 struct zapi_ipv6 *api)
629{
630 int i;
631 int psize;
632 struct stream *s;
633
634 /* Reset stream. */
635 s = zclient->obuf;
636 stream_reset (s);
637
c1b9800a 638 zclient_create_header (s, cmd);
718e3744 639
c1b9800a 640 /* Put type and nexthop. */
718e3744 641 stream_putc (s, api->type);
7c8ff89e 642 stream_putw (s, api->instance);
718e3744 643 stream_putc (s, api->flags);
644 stream_putc (s, api->message);
c7ec179a 645 stream_putw (s, api->safi);
718e3744 646
647 /* Put prefix information. */
648 psize = PSIZE (p->prefixlen);
649 stream_putc (s, p->prefixlen);
650 stream_write (s, (u_char *)&p->prefix, psize);
651
652 /* Nexthop, ifindex, distance and metric information. */
653 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
654 {
c3c0ac83
DS
655 if (CHECK_FLAG (api->flags, ZEBRA_FLAG_BLACKHOLE))
656 {
657 stream_putc (s, 1);
658 stream_putc (s, ZEBRA_NEXTHOP_BLACKHOLE);
659 /* XXX assert(api->nexthop_num == 0); */
660 /* XXX assert(api->ifindex_num == 0); */
661 }
662 else
663 stream_putc (s, api->nexthop_num + api->ifindex_num);
718e3744 664
665 for (i = 0; i < api->nexthop_num; i++)
666 {
667 stream_putc (s, ZEBRA_NEXTHOP_IPV6);
668 stream_write (s, (u_char *)api->nexthop[i], 16);
669 }
670 for (i = 0; i < api->ifindex_num; i++)
671 {
672 stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
673 stream_putl (s, api->ifindex[i]);
674 }
675 }
676
677 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE))
678 stream_putc (s, api->distance);
679 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC))
680 stream_putl (s, api->metric);
0d9551dc
DS
681 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_TAG))
682 stream_putw (s, api->tag);
718e3744 683
684 /* Put length at the first point of the stream. */
685 stream_putw_at (s, 0, stream_get_endp (s));
686
634f9ea2 687 return zclient_send_message(zclient);
718e3744 688}
718e3744 689#endif /* HAVE_IPV6 */
690
0a589359 691/*
692 * send a ZEBRA_REDISTRIBUTE_ADD or ZEBRA_REDISTRIBUTE_DELETE
693 * for the route type (ZEBRA_ROUTE_KERNEL etc.). The zebra server will
694 * then set/unset redist[type] in the client handle (a struct zserv) for the
695 * sending client
696 */
718e3744 697int
8bb0831e 698zebra_redistribute_send (int command, struct zclient *zclient, afi_t afi, int type,
7c8ff89e 699 u_short instance)
718e3744 700{
718e3744 701 struct stream *s;
702
634f9ea2 703 s = zclient->obuf;
704 stream_reset(s);
718e3744 705
c1b9800a 706 zclient_create_header (s, command);
8bb0831e 707 stream_putc (s, afi);
718e3744 708 stream_putc (s, type);
7c8ff89e 709 stream_putw (s, instance);
c1b9800a 710
711 stream_putw_at (s, 0, stream_get_endp (s));
712
634f9ea2 713 return zclient_send_message(zclient);
718e3744 714}
715
18a6dce6 716/* Router-id update from zebra daemon. */
717void
718zebra_router_id_update_read (struct stream *s, struct prefix *rid)
719{
720 int plen;
721
722 /* Fetch interface address. */
723 rid->family = stream_getc (s);
724
725 plen = prefix_blen (rid);
726 stream_get (&rid->u.prefix, s, plen);
727 rid->prefixlen = stream_getc (s);
728}
729
718e3744 730/* Interface addition from zebra daemon. */
0a589359 731/*
732 * The format of the message sent with type ZEBRA_INTERFACE_ADD or
733 * ZEBRA_INTERFACE_DELETE from zebra to the client is:
734 * 0 1 2 3
735 * 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
736 * +-+-+-+-+-+-+-+-+
737 * | type |
738 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
739 * | ifname |
740 * | |
741 * | |
742 * | |
743 * | |
744 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
745 * | ifindex |
746 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
747 * | if_flags |
c77d4546 748 * | |
0a589359 749 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
750 * | metric |
751 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
752 * | ifmtu |
753 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
754 * | ifmtu6 |
755 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
756 * | bandwidth |
757 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
758 * | sockaddr_dl |
759 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
760 */
761
718e3744 762struct interface *
763zebra_interface_add_read (struct stream *s)
764{
765 struct interface *ifp;
02ff83c5 766 char ifname_tmp[INTERFACE_NAMSIZ];
718e3744 767
768 /* Read interface name. */
769 stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
770
a349198f 771 /* Lookup/create interface by name. */
772 ifp = if_get_by_name_len (ifname_tmp, strnlen(ifname_tmp, INTERFACE_NAMSIZ));
718e3744 773
51d4ef83 774 zebra_interface_if_set_value (s, ifp);
718e3744 775
718e3744 776 return ifp;
777}
778
0a589359 779/*
780 * Read interface up/down msg (ZEBRA_INTERFACE_UP/ZEBRA_INTERFACE_DOWN)
781 * from zebra server. The format of this message is the same as
782 * that sent for ZEBRA_INTERFACE_ADD/ZEBRA_INTERFACE_DELETE (see
783 * comments for zebra_interface_add_read), except that no sockaddr_dl
784 * is sent at the tail of the message.
785 */
718e3744 786struct interface *
787zebra_interface_state_read (struct stream *s)
788{
789 struct interface *ifp;
02ff83c5 790 char ifname_tmp[INTERFACE_NAMSIZ];
718e3744 791
792 /* Read interface name. */
793 stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
794
795 /* Lookup this by interface index. */
a349198f 796 ifp = if_lookup_by_name_len (ifname_tmp,
797 strnlen(ifname_tmp, INTERFACE_NAMSIZ));
718e3744 798
799 /* If such interface does not exist, indicate an error */
800 if (! ifp)
801 return NULL;
802
51d4ef83 803 zebra_interface_if_set_value (s, ifp);
718e3744 804
805 return ifp;
806}
807
0a589359 808/*
809 * format of message for address additon is:
810 * 0
811 * 0 1 2 3 4 5 6 7
812 * +-+-+-+-+-+-+-+-+
813 * | type | ZEBRA_INTERFACE_ADDRESS_ADD or
814 * +-+-+-+-+-+-+-+-+ ZEBRA_INTERFACE_ADDRES_DELETE
815 * | |
816 * + +
817 * | ifindex |
818 * + +
819 * | |
820 * + +
821 * | |
822 * +-+-+-+-+-+-+-+-+
823 * | ifc_flags | flags for connected address
824 * +-+-+-+-+-+-+-+-+
825 * | addr_family |
826 * +-+-+-+-+-+-+-+-+
827 * | addr... |
828 * : :
829 * | |
830 * +-+-+-+-+-+-+-+-+
831 * | addr_len | len of addr. E.g., addr_len = 4 for ipv4 addrs.
832 * +-+-+-+-+-+-+-+-+
833 * | daddr.. |
834 * : :
835 * | |
836 * +-+-+-+-+-+-+-+-+
837 *
838 */
839
18a6dce6 840void
841zebra_interface_if_set_value (struct stream *s, struct interface *ifp)
842{
843 /* Read interface's index. */
844 ifp->ifindex = stream_getl (s);
508ec910 845 ifp->status = stream_getc (s);
18a6dce6 846
847 /* Read interface's value. */
c77d4546 848 ifp->flags = stream_getq (s);
244c1cdc
DS
849 ifp->ptm_enable = stream_getc (s);
850 ifp->ptm_status = stream_getc (s);
18a6dce6 851 ifp->metric = stream_getl (s);
852 ifp->mtu = stream_getl (s);
508ec910 853 ifp->mtu6 = stream_getl (s);
18a6dce6 854 ifp->bandwidth = stream_getl (s);
51d4ef83 855#ifdef HAVE_STRUCT_SOCKADDR_DL
ca3ccd87 856 stream_get (&ifp->sdl, s, sizeof (ifp->sdl_storage));
51d4ef83
JB
857#else
858 ifp->hw_addr_len = stream_getl (s);
859 if (ifp->hw_addr_len)
860 stream_get (ifp->hw_addr, s, ifp->hw_addr_len);
861#endif /* HAVE_STRUCT_SOCKADDR_DL */
18a6dce6 862}
863
3fb9cd6e 864static int
865memconstant(const void *s, int c, size_t n)
866{
867 const u_char *p = s;
868
869 while (n-- > 0)
870 if (*p++ != c)
871 return 0;
872 return 1;
873}
874
d5a5c8f0
DS
875struct interface*
876zebra_interface_bfd_read (struct stream *s, struct prefix *p)
877{
878 unsigned int ifindex;
879 struct interface *ifp;
880 int plen;
881
882 /* Get interface index. */
883 ifindex = stream_getl (s);
884
885 /* Lookup index. */
886 ifp = if_lookup_by_index (ifindex);
887 if (ifp == NULL)
888 {
889 zlog_warn ("zebra_interface_bfd_read: "
890 "Can't find interface by ifindex: %d ", ifindex);
891 return NULL;
892 }
893
894 /* Fetch interface address. */
895 p->family = stream_getc (s);
896
897 plen = prefix_blen (p);
898 stream_get (&p->u.prefix, s, plen);
899 p->prefixlen = stream_getc (s);
900
901 return ifp;
902}
903
718e3744 904struct connected *
0a589359 905zebra_interface_address_read (int type, struct stream *s)
718e3744 906{
907 unsigned int ifindex;
908 struct interface *ifp;
909 struct connected *ifc;
0a589359 910 struct prefix p, d;
718e3744 911 int family;
912 int plen;
0a589359 913 u_char ifc_flags;
718e3744 914
0a589359 915 memset (&p, 0, sizeof(p));
916 memset (&d, 0, sizeof(d));
718e3744 917
918 /* Get interface index. */
919 ifindex = stream_getl (s);
920
921 /* Lookup index. */
922 ifp = if_lookup_by_index (ifindex);
923 if (ifp == NULL)
924 {
0a589359 925 zlog_warn ("zebra_interface_address_read(%s): "
926 "Can't find interface by ifindex: %d ",
927 (type == ZEBRA_INTERFACE_ADDRESS_ADD? "ADD" : "DELETE"),
928 ifindex);
718e3744 929 return NULL;
930 }
931
932 /* Fetch flag. */
0a589359 933 ifc_flags = stream_getc (s);
718e3744 934
935 /* Fetch interface address. */
936 family = p.family = stream_getc (s);
937
0a589359 938 plen = prefix_blen (&p);
939 stream_get (&p.u.prefix, s, plen);
718e3744 940 p.prefixlen = stream_getc (s);
941
942 /* Fetch destination address. */
0a589359 943 stream_get (&d.u.prefix, s, plen);
718e3744 944 d.family = family;
945
0a589359 946 if (type == ZEBRA_INTERFACE_ADDRESS_ADD)
947 {
3fb9cd6e 948 /* N.B. NULL destination pointers are encoded as all zeroes */
949 ifc = connected_add_by_prefix(ifp, &p,(memconstant(&d.u.prefix,0,plen) ?
950 NULL : &d));
0a589359 951 if (ifc != NULL)
e4529636
AS
952 {
953 ifc->flags = ifc_flags;
954 if (ifc->destination)
955 ifc->destination->prefixlen = ifc->address->prefixlen;
90444ca3
DL
956 else if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_PEER))
957 {
958 /* carp interfaces on OpenBSD with 0.0.0.0/0 as "peer" */
959 char buf[BUFSIZ];
960 prefix2str (ifc->address, buf, sizeof(buf));
961 zlog_warn("warning: interface %s address %s "
962 "with peer flag set, but no peer address!",
963 ifp->name, buf);
964 UNSET_FLAG(ifc->flags, ZEBRA_IFA_PEER);
965 }
e4529636 966 }
0a589359 967 }
968 else
969 {
970 assert (type == ZEBRA_INTERFACE_ADDRESS_DELETE);
971 ifc = connected_delete_by_prefix(ifp, &p);
972 }
718e3744 973
974 return ifc;
975}
0a589359 976
a80beece
DS
977/*
978 * format of message for neighbor connected address is:
979 * 0
980 * 0 1 2 3 4 5 6 7
981 * +-+-+-+-+-+-+-+-+
982 * | type | ZEBRA_INTERFACE_NBR_ADDRESS_ADD or
983 * +-+-+-+-+-+-+-+-+ ZEBRA_INTERFACE_NBR_ADDRES_DELETE
984 * | |
985 * + +
986 * | ifindex |
987 * + +
988 * | |
989 * + +
990 * | |
991 * +-+-+-+-+-+-+-+-+
992 * | addr_family |
993 * +-+-+-+-+-+-+-+-+
994 * | addr... |
995 * : :
996 * | |
997 * +-+-+-+-+-+-+-+-+
998 * | addr_len | len of addr.
999 * +-+-+-+-+-+-+-+-+
1000 */
1001struct nbr_connected *
1002zebra_interface_nbr_address_read (int type, struct stream *s)
1003{
1004 unsigned int ifindex;
1005 struct interface *ifp;
1006 struct prefix p;
1007 struct nbr_connected *ifc;
1008
1009 /* Get interface index. */
1010 ifindex = stream_getl (s);
1011
1012 /* Lookup index. */
1013 ifp = if_lookup_by_index (ifindex);
1014 if (ifp == NULL)
1015 {
1016 zlog_warn ("zebra_nbr_interface_address_read(%s): "
1017 "Can't find interface by ifindex: %d ",
1018 (type == ZEBRA_INTERFACE_NBR_ADDRESS_ADD? "ADD" : "DELETE"),
1019 ifindex);
1020 return NULL;
1021 }
1022
1023 p.family = stream_getc (s);
1024 stream_get (&p.u.prefix, s, prefix_blen (&p));
1025 p.prefixlen = stream_getc (s);
1026
1027 if (type == ZEBRA_INTERFACE_NBR_ADDRESS_ADD)
1028 {
1029 /* Currently only supporting P2P links, so any new RA source address is
1030 considered as the replacement of the previously learnt Link-Local address. */
1031 if (!(ifc = listnode_head(ifp->nbr_connected)))
1032 {
1033 ifc = nbr_connected_new ();
1034 ifc->address = prefix_new ();
1035 ifc->ifp = ifp;
1036 listnode_add (ifp->nbr_connected, ifc);
1037 }
1038
1039 prefix_copy(ifc->address, &p);
1040 }
1041 else
1042 {
1043 assert (type == ZEBRA_INTERFACE_NBR_ADDRESS_DELETE);
1044
1045 ifc = nbr_connected_check(ifp, &p);
1046 if (ifc)
1047 listnode_delete (ifp->nbr_connected, ifc);
1048 }
1049
1050 return ifc;
1051}
6b0655a2 1052
718e3744 1053/* Zebra client message read function. */
634f9ea2 1054static int
718e3744 1055zclient_read (struct thread *thread)
1056{
634f9ea2 1057 size_t already;
c1b9800a 1058 uint16_t length, command;
1059 uint8_t marker, version;
718e3744 1060 struct zclient *zclient;
1061
1062 /* Get socket to zebra. */
718e3744 1063 zclient = THREAD_ARG (thread);
1064 zclient->t_read = NULL;
1065
634f9ea2 1066 /* Read zebra header (if we don't have it already). */
1067 if ((already = stream_get_endp(zclient->ibuf)) < ZEBRA_HEADER_SIZE)
718e3744 1068 {
634f9ea2 1069 ssize_t nbyte;
1070 if (((nbyte = stream_read_try(zclient->ibuf, zclient->sock,
1071 ZEBRA_HEADER_SIZE-already)) == 0) ||
1072 (nbyte == -1))
1073 {
1074 if (zclient_debug)
1075 zlog_debug ("zclient connection closed socket [%d].", zclient->sock);
1076 return zclient_failed(zclient);
1077 }
1078 if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE-already))
1079 {
1080 /* Try again later. */
1081 zclient_event (ZCLIENT_READ, zclient);
1082 return 0;
1083 }
1084 already = ZEBRA_HEADER_SIZE;
718e3744 1085 }
1086
634f9ea2 1087 /* Reset to read from the beginning of the incoming packet. */
1088 stream_set_getp(zclient->ibuf, 0);
718e3744 1089
c1b9800a 1090 /* Fetch header values. */
718e3744 1091 length = stream_getw (zclient->ibuf);
c1b9800a 1092 marker = stream_getc (zclient->ibuf);
1093 version = stream_getc (zclient->ibuf);
1094 command = stream_getw (zclient->ibuf);
1095
1096 if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION)
1097 {
1098 zlog_err("%s: socket %d version mismatch, marker %d, version %d",
1099 __func__, zclient->sock, marker, version);
1100 return zclient_failed(zclient);
1101 }
1102
634f9ea2 1103 if (length < ZEBRA_HEADER_SIZE)
1104 {
1105 zlog_err("%s: socket %d message length %u is less than %d ",
1106 __func__, zclient->sock, length, ZEBRA_HEADER_SIZE);
1107 return zclient_failed(zclient);
1108 }
1109
718e3744 1110 /* Length check. */
634f9ea2 1111 if (length > STREAM_SIZE(zclient->ibuf))
718e3744 1112 {
634f9ea2 1113 struct stream *ns;
1114 zlog_warn("%s: message size %u exceeds buffer size %lu, expanding...",
1115 __func__, length, (u_long)STREAM_SIZE(zclient->ibuf));
1116 ns = stream_new(length);
1117 stream_copy(ns, zclient->ibuf);
718e3744 1118 stream_free (zclient->ibuf);
634f9ea2 1119 zclient->ibuf = ns;
718e3744 1120 }
718e3744 1121
1122 /* Read rest of zebra packet. */
634f9ea2 1123 if (already < length)
1124 {
1125 ssize_t nbyte;
1126 if (((nbyte = stream_read_try(zclient->ibuf, zclient->sock,
1127 length-already)) == 0) ||
1128 (nbyte == -1))
1129 {
1130 if (zclient_debug)
1131 zlog_debug("zclient connection closed socket [%d].", zclient->sock);
1132 return zclient_failed(zclient);
1133 }
1134 if (nbyte != (ssize_t)(length-already))
1135 {
1136 /* Try again later. */
1137 zclient_event (ZCLIENT_READ, zclient);
1138 return 0;
1139 }
1140 }
1141
1142 length -= ZEBRA_HEADER_SIZE;
718e3744 1143
0a589359 1144 if (zclient_debug)
8ddca704 1145 zlog_debug("zclient 0x%p command 0x%x \n", zclient, command);
0a589359 1146
718e3744 1147 switch (command)
1148 {
18a6dce6 1149 case ZEBRA_ROUTER_ID_UPDATE:
1150 if (zclient->router_id_update)
9206f9ec 1151 (*zclient->router_id_update) (command, zclient, length);
18a6dce6 1152 break;
718e3744 1153 case ZEBRA_INTERFACE_ADD:
1154 if (zclient->interface_add)
9206f9ec 1155 (*zclient->interface_add) (command, zclient, length);
718e3744 1156 break;
1157 case ZEBRA_INTERFACE_DELETE:
1158 if (zclient->interface_delete)
9206f9ec 1159 (*zclient->interface_delete) (command, zclient, length);
718e3744 1160 break;
1161 case ZEBRA_INTERFACE_ADDRESS_ADD:
1162 if (zclient->interface_address_add)
9206f9ec 1163 (*zclient->interface_address_add) (command, zclient, length);
718e3744 1164 break;
1165 case ZEBRA_INTERFACE_ADDRESS_DELETE:
1166 if (zclient->interface_address_delete)
9206f9ec 1167 (*zclient->interface_address_delete) (command, zclient, length);
718e3744 1168 break;
d5a5c8f0
DS
1169 case ZEBRA_INTERFACE_BFD_DEST_DOWN:
1170 if (zclient->interface_bfd_dest_down)
1171 (*zclient->interface_bfd_dest_down) (command, zclient, length);
1172 break;
a80beece
DS
1173 case ZEBRA_INTERFACE_NBR_ADDRESS_ADD:
1174 if (zclient->interface_nbr_address_add)
1175 (*zclient->interface_nbr_address_add) (command, zclient, length);
1176 break;
1177 case ZEBRA_INTERFACE_NBR_ADDRESS_DELETE:
1178 if (zclient->interface_nbr_address_delete)
1179 (*zclient->interface_nbr_address_delete) (command, zclient, length);
1180 break;
718e3744 1181 case ZEBRA_INTERFACE_UP:
1182 if (zclient->interface_up)
9206f9ec 1183 (*zclient->interface_up) (command, zclient, length);
718e3744 1184 break;
1185 case ZEBRA_INTERFACE_DOWN:
1186 if (zclient->interface_down)
9206f9ec 1187 (*zclient->interface_down) (command, zclient, length);
718e3744 1188 break;
1189 case ZEBRA_IPV4_ROUTE_ADD:
1190 if (zclient->ipv4_route_add)
9206f9ec 1191 (*zclient->ipv4_route_add) (command, zclient, length);
718e3744 1192 break;
1193 case ZEBRA_IPV4_ROUTE_DELETE:
1194 if (zclient->ipv4_route_delete)
9206f9ec 1195 (*zclient->ipv4_route_delete) (command, zclient, length);
718e3744 1196 break;
1197 case ZEBRA_IPV6_ROUTE_ADD:
1198 if (zclient->ipv6_route_add)
9206f9ec 1199 (*zclient->ipv6_route_add) (command, zclient, length);
718e3744 1200 break;
1201 case ZEBRA_IPV6_ROUTE_DELETE:
1202 if (zclient->ipv6_route_delete)
9206f9ec 1203 (*zclient->ipv6_route_delete) (command, zclient, length);
718e3744 1204 break;
fb018d25
DS
1205 case ZEBRA_NEXTHOP_UPDATE:
1206 if (zclient_debug)
1207 zlog_debug("zclient rcvd nexthop update\n");
1208 if (zclient->nexthop_update)
1209 (*zclient->nexthop_update) (command, zclient, length);
1210 break;
078430f6
DS
1211 case ZEBRA_IMPORT_CHECK_UPDATE:
1212 if (zclient_debug)
1213 zlog_debug("zclient rcvd import check update\n");
1214 if (zclient->import_check_update)
1215 (*zclient->import_check_update) (command, zclient, length);
1216 break;
718e3744 1217 default:
1218 break;
1219 }
1220
634f9ea2 1221 if (zclient->sock < 0)
1222 /* Connection was closed during packet processing. */
1223 return -1;
1224
718e3744 1225 /* Register read thread. */
634f9ea2 1226 stream_reset(zclient->ibuf);
718e3744 1227 zclient_event (ZCLIENT_READ, zclient);
1228
1229 return 0;
1230}
1231
1232void
8bb0831e 1233zclient_redistribute (int command, struct zclient *zclient, afi_t afi, int type,
7c8ff89e 1234 u_short instance)
718e3744 1235{
718e3744 1236
0a589359 1237 if (command == ZEBRA_REDISTRIBUTE_ADD)
1238 {
8bb0831e 1239 if (redist_check_instance(&zclient->redist[afi][type], instance))
0a589359 1240 return;
8bb0831e 1241 redist_add_instance(&zclient->redist[afi][type], instance);
0a589359 1242 }
1243 else
1244 {
8bb0831e 1245 if (!redist_check_instance(&zclient->redist[afi][type], instance))
0a589359 1246 return;
8bb0831e 1247 redist_del_instance(&zclient->redist[afi][type], instance);
0a589359 1248 }
718e3744 1249
1250 if (zclient->sock > 0)
8bb0831e 1251 zebra_redistribute_send (command, zclient, afi, type, instance);
718e3744 1252}
1253
718e3744 1254
1255void
0a589359 1256zclient_redistribute_default (int command, struct zclient *zclient)
718e3744 1257{
718e3744 1258
0a589359 1259 if (command == ZEBRA_REDISTRIBUTE_DEFAULT_ADD)
1260 {
1261 if (zclient->default_information)
1262 return;
1263 zclient->default_information = 1;
1264 }
1265 else
1266 {
1267 if (!zclient->default_information)
1268 return;
1269 zclient->default_information = 0;
1270 }
718e3744 1271
1272 if (zclient->sock > 0)
0a589359 1273 zebra_message_send (zclient, command);
718e3744 1274}
1275
718e3744 1276static void
1277zclient_event (enum event event, struct zclient *zclient)
1278{
1279 switch (event)
1280 {
1281 case ZCLIENT_SCHEDULE:
1282 if (! zclient->t_connect)
1283 zclient->t_connect =
1284 thread_add_event (master, zclient_connect, zclient, 0);
1285 break;
1286 case ZCLIENT_CONNECT:
1287 if (zclient->fail >= 10)
1288 return;
1289 if (zclient_debug)
8ddca704 1290 zlog_debug ("zclient connect schedule interval is %d",
718e3744 1291 zclient->fail < 3 ? 10 : 60);
1292 if (! zclient->t_connect)
1293 zclient->t_connect =
1294 thread_add_timer (master, zclient_connect, zclient,
1295 zclient->fail < 3 ? 10 : 60);
1296 break;
1297 case ZCLIENT_READ:
1298 zclient->t_read =
1299 thread_add_read (master, zclient_read, zclient, zclient->sock);
1300 break;
1301 }
1302}
b5114685
VT
1303
1304void
1305zclient_serv_path_set (char *path)
1306{
1307 struct stat sb;
1308
1309 /* reset */
1310 zclient_serv_path = NULL;
1311
1312 /* test if `path' is socket. don't set it otherwise. */
1313 if (stat(path, &sb) == -1)
1314 {
1315 zlog_warn ("%s: zebra socket `%s' does not exist", __func__, path);
1316 return;
1317 }
1318
1319 if ((sb.st_mode & S_IFMT) != S_IFSOCK)
1320 {
1321 zlog_warn ("%s: `%s' is not unix socket, sir", __func__, path);
1322 return;
1323 }
1324
1325 /* it seems that path is unix socket */
1326 zclient_serv_path = path;
1327}
1328