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