]> git.proxmox.com Git - mirror_frr.git/blame - lib/zclient.c
- From Andrew Schorr, fixup logrotate to use correct path to killall
[mirror_frr.git] / lib / zclient.c
CommitLineData
718e3744 1/* Zebra's client library.
2 * Copyright (C) 1999 Kunihiro Ishiguro
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published
8 * by the Free Software Foundation; either version 2, or (at your
9 * option) any later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Zebra; see the file COPYING. If not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
19 * MA 02111-1307, USA.
20 */
21
22#include <zebra.h>
23
24#include "prefix.h"
25#include "stream.h"
26#include "network.h"
27#include "if.h"
28#include "log.h"
29#include "thread.h"
30#include "zclient.h"
31#include "memory.h"
32#include "table.h"
33
34#include "zebra/rib.h"
35#include "zebra/zserv.h"
36\f
37/* Zebra client events. */
38enum event {ZCLIENT_SCHEDULE, ZCLIENT_READ, ZCLIENT_CONNECT};
39
40/* Prototype for event manager. */
41static void zclient_event (enum event, struct zclient *);
42
43/* This file local debug flag. */
44int zclient_debug = 0;
45\f
46/* Allocate zclient structure. */
47struct zclient *
48zclient_new ()
49{
50 struct zclient *zclient;
51 zclient = XMALLOC (MTYPE_ZCLIENT, sizeof (struct zclient));
52 memset (zclient, 0, sizeof (struct zclient));
53
54 zclient->ibuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
55 zclient->obuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
56
57 return zclient;
58}
59
60/* Free zclient structure. */
61void
62zclient_free (struct zclient *zclient)
63{
64 XFREE (MTYPE_ZCLIENT, zclient);
65}
66
67/* Initialize zebra client. Argument redist_default is unwanted
68 redistribute route type. */
69void
70zclient_init (struct zclient *zclient, int redist_default)
71{
72 int i;
73
74 /* Enable zebra client connection by default. */
75 zclient->enable = 1;
76
77 /* Set -1 to the default socket value. */
78 zclient->sock = -1;
79
80 /* Clear redistribution flags. */
81 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
82 zclient->redist[i] = 0;
83
84 /* Set unwanted redistribute route. bgpd does not need BGP route
85 redistribution. */
86 zclient->redist_default = redist_default;
87 zclient->redist[redist_default] = 1;
88
89 /* Set default-information redistribute to zero. */
90 zclient->default_information = 0;
91
92 /* Schedule first zclient connection. */
93 if (zclient_debug)
94 zlog_info ("zclient start scheduled");
95
96 zclient_event (ZCLIENT_SCHEDULE, zclient);
97}
98
99/* Stop zebra client services. */
100void
101zclient_stop (struct zclient *zclient)
102{
103 if (zclient_debug)
104 zlog_info ("zclient stopped");
105
106 /* Stop threads. */
107 if (zclient->t_read)
108 {
109 thread_cancel (zclient->t_read);
110 zclient->t_read = NULL;
111 }
112 if (zclient->t_connect)
113 {
114 thread_cancel (zclient->t_connect);
115 zclient->t_connect = NULL;
116 }
117
118 /* Close socket. */
119 if (zclient->sock >= 0)
120 {
121 close (zclient->sock);
122 zclient->sock = -1;
123 }
124 zclient->fail = 0;
125}
126
127void
128zclient_reset (struct zclient *zclient)
129{
130 zclient_stop (zclient);
131 zclient_init (zclient, zclient->redist_default);
132}
133
134/* Make socket to zebra daemon. Return zebra socket. */
135int
136zclient_socket ()
137{
138 int sock;
139 int ret;
140 struct sockaddr_in serv;
141
142 /* We should think about IPv6 connection. */
143 sock = socket (AF_INET, SOCK_STREAM, 0);
144 if (sock < 0)
145 return -1;
146
147 /* Make server socket. */
148 memset (&serv, 0, sizeof (struct sockaddr_in));
149 serv.sin_family = AF_INET;
150 serv.sin_port = htons (ZEBRA_PORT);
151#ifdef HAVE_SIN_LEN
152 serv.sin_len = sizeof (struct sockaddr_in);
153#endif /* HAVE_SIN_LEN */
154 serv.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
155
156 /* Connect to zebra. */
157 ret = connect (sock, (struct sockaddr *) &serv, sizeof (serv));
158 if (ret < 0)
159 {
160 close (sock);
161 return -1;
162 }
163 return sock;
164}
165
166/* For sockaddr_un. */
167#include <sys/un.h>
168
169int
8c328f11 170zclient_socket_un (const char *path)
718e3744 171{
172 int ret;
173 int sock, len;
174 struct sockaddr_un addr;
175
176 sock = socket (AF_UNIX, SOCK_STREAM, 0);
177 if (sock < 0)
178 return -1;
179
180 /* Make server socket. */
181 memset (&addr, 0, sizeof (struct sockaddr_un));
182 addr.sun_family = AF_UNIX;
183 strncpy (addr.sun_path, path, strlen (path));
184#ifdef HAVE_SUN_LEN
185 len = addr.sun_len = SUN_LEN(&addr);
186#else
187 len = sizeof (addr.sun_family) + strlen (addr.sun_path);
188#endif /* HAVE_SUN_LEN */
189
190 ret = connect (sock, (struct sockaddr *) &addr, len);
191 if (ret < 0)
192 {
193 close (sock);
194 return -1;
195 }
196 return sock;
197}
198
199/* Send simple Zebra message. */
200int
201zebra_message_send (struct zclient *zclient, int command)
202{
203 struct stream *s;
204
205 /* Get zclient output buffer. */
206 s = zclient->obuf;
207 stream_reset (s);
208
209 /* Send very simple command only Zebra message. */
210 stream_putw (s, 3);
211 stream_putc (s, command);
212
213 return writen (zclient->sock, s->data, 3);
214}
215
216/* Make connection to zebra daemon. */
217int
218zclient_start (struct zclient *zclient)
219{
220 int i;
221
222 if (zclient_debug)
223 zlog_info ("zclient_start is called");
224
225 /* zclient is disabled. */
226 if (! zclient->enable)
227 return 0;
228
229 /* If already connected to the zebra. */
230 if (zclient->sock >= 0)
231 return 0;
232
233 /* Check connect thread. */
234 if (zclient->t_connect)
235 return 0;
236
237 /* Make socket. */
238#ifdef HAVE_TCP_ZEBRA
239 zclient->sock = zclient_socket ();
240#else
241 zclient->sock = zclient_socket_un (ZEBRA_SERV_PATH);
242#endif /* HAVE_TCP_ZEBRA */
243 if (zclient->sock < 0)
244 {
245 if (zclient_debug)
246 zlog_info ("zclient connection fail");
247 zclient->fail++;
248 zclient_event (ZCLIENT_CONNECT, zclient);
249 return -1;
250 }
251
252 /* Clear fail count. */
253 zclient->fail = 0;
254 if (zclient_debug)
255 zlog_info ("zclient connect success with socket [%d]", zclient->sock);
256
257 /* Create read thread. */
258 zclient_event (ZCLIENT_READ, zclient);
259
260 /* We need interface information. */
261 zebra_message_send (zclient, ZEBRA_INTERFACE_ADD);
262
18a6dce6 263 /* We need router-id information. */
264 zebra_message_send (zclient, ZEBRA_ROUTER_ID_ADD);
265
718e3744 266 /* Flush all redistribute request. */
267 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
268 if (i != zclient->redist_default && zclient->redist[i])
269 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient->sock, i);
270
271 /* If default information is needed. */
272 if (zclient->default_information)
273 zebra_message_send (zclient, ZEBRA_REDISTRIBUTE_DEFAULT_ADD);
274
275 return 0;
276}
277
278/* This function is a wrapper function for calling zclient_start from
279 timer or event thread. */
280int
281zclient_connect (struct thread *t)
282{
283 struct zclient *zclient;
284
285 zclient = THREAD_ARG (t);
286 zclient->t_connect = NULL;
287
288 if (zclient_debug)
289 zlog_info ("zclient_connect is called");
290
291 return zclient_start (zclient);
292}
293\f
0a589359 294 /*
295 * "xdr_encode"-like interface that allows daemon (client) to send
296 * a message to zebra server for a route that needs to be
297 * added/deleted to the kernel. Info about the route is specified
298 * by the caller in a struct zapi_ipv4. zapi_ipv4_read() then writes
299 * the info down the zclient socket using the stream_* functions.
300 *
301 * The corresponding read ("xdr_decode") function on the server
302 * side is zread_ipv4_add()/zread_ipv4_delete().
303 *
304 * 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
305 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
306 * | Length (2) | Command | Route Type |
307 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
308 * | ZEBRA Flags | Message Flags | Prefix length |
309 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
310 * | Destination IPv4 Prefix for route |
311 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
312 * | Nexthop count |
313 * +-+-+-+-+-+-+-+-+
314 *
315 *
316 * A number of IPv4 nexthop(s) or nexthop interface index(es) are then
317 * described, as per the Nexthop count. Each nexthop described as:
318 *
319 * +-+-+-+-+-+-+-+-+
320 * | Nexthop Type | Set to one of ZEBRA_NEXTHOP_*
321 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
322 * | IPv4 Nexthop address or Interface Index number |
323 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
324 *
325 * Alternatively, if the flags field has ZEBRA_FLAG_BLACKHOLE or
326 * ZEBRA_FLAG_REJECT is set then Nexthop count is set to 1, then _no_
327 * nexthop information is provided, and the message describes a prefix
328 * to blackhole or reject route.
329 *
330 * If ZAPI_MESSAGE_DISTANCE is set, the distance value is written as a 1
331 * byte value.
332 *
333 * If ZAPI_MESSAGE_METRIC is set, the metric value is written as an 8
334 * byte value.
335 *
336 * XXX: No attention paid to alignment.
337 */
718e3744 338int
0a589359 339zapi_ipv4_route (u_char cmd, struct zclient *zclient, struct prefix_ipv4 *p,
340 struct zapi_ipv4 *api)
718e3744 341{
342 int i;
343 int psize;
344 struct stream *s;
345
346 /* Reset stream. */
347 s = zclient->obuf;
348 stream_reset (s);
349
350 /* Length place holder. */
351 stream_putw (s, 0);
352
353 /* Put command, type and nexthop. */
0a589359 354 stream_putc (s, cmd);
718e3744 355 stream_putc (s, api->type);
356 stream_putc (s, api->flags);
357 stream_putc (s, api->message);
718e3744 358
718e3744 359 /* Put prefix information. */
360 psize = PSIZE (p->prefixlen);
361 stream_putc (s, p->prefixlen);
0a589359 362 stream_write (s, (u_char *) & p->prefix, psize);
718e3744 363
364 /* Nexthop, ifindex, distance and metric information. */
365 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
366 {
595db7f1 367 if (CHECK_FLAG (api->flags, ZEBRA_FLAG_BLACKHOLE))
368 {
369 stream_putc (s, 1);
370 stream_putc (s, ZEBRA_NEXTHOP_BLACKHOLE);
0a589359 371 /* XXX assert(api->nexthop_num == 0); */
372 /* XXX assert(api->ifindex_num == 0); */
595db7f1 373 }
374 else
375 stream_putc (s, api->nexthop_num + api->ifindex_num);
718e3744 376
377 for (i = 0; i < api->nexthop_num; i++)
595db7f1 378 {
379 stream_putc (s, ZEBRA_NEXTHOP_IPV4);
380 stream_put_in_addr (s, api->nexthop[i]);
381 }
718e3744 382 for (i = 0; i < api->ifindex_num; i++)
595db7f1 383 {
384 stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
385 stream_putl (s, api->ifindex[i]);
386 }
718e3744 387 }
388
389 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE))
390 stream_putc (s, api->distance);
391 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC))
392 stream_putl (s, api->metric);
393
394 /* Put length at the first point of the stream. */
395 stream_putw_at (s, 0, stream_get_endp (s));
396
397 return writen (zclient->sock, s->data, stream_get_endp (s));
398}
399
400#ifdef HAVE_IPV6
401int
0a589359 402zapi_ipv6_route (u_char cmd, struct zclient *zclient, struct prefix_ipv6 *p,
718e3744 403 struct zapi_ipv6 *api)
404{
405 int i;
406 int psize;
407 struct stream *s;
408
409 /* Reset stream. */
410 s = zclient->obuf;
411 stream_reset (s);
412
413 /* Length place holder. */
414 stream_putw (s, 0);
415
416 /* Put command, type and nexthop. */
0a589359 417 stream_putc (s, cmd);
718e3744 418 stream_putc (s, api->type);
419 stream_putc (s, api->flags);
420 stream_putc (s, api->message);
421
422 /* Put prefix information. */
423 psize = PSIZE (p->prefixlen);
424 stream_putc (s, p->prefixlen);
425 stream_write (s, (u_char *)&p->prefix, psize);
426
427 /* Nexthop, ifindex, distance and metric information. */
428 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
429 {
430 stream_putc (s, api->nexthop_num + api->ifindex_num);
431
432 for (i = 0; i < api->nexthop_num; i++)
433 {
434 stream_putc (s, ZEBRA_NEXTHOP_IPV6);
435 stream_write (s, (u_char *)api->nexthop[i], 16);
436 }
437 for (i = 0; i < api->ifindex_num; i++)
438 {
439 stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
440 stream_putl (s, api->ifindex[i]);
441 }
442 }
443
444 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE))
445 stream_putc (s, api->distance);
446 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC))
447 stream_putl (s, api->metric);
448
449 /* Put length at the first point of the stream. */
450 stream_putw_at (s, 0, stream_get_endp (s));
451
452 return writen (zclient->sock, s->data, stream_get_endp (s));
453}
718e3744 454#endif /* HAVE_IPV6 */
455
0a589359 456/*
457 * send a ZEBRA_REDISTRIBUTE_ADD or ZEBRA_REDISTRIBUTE_DELETE
458 * for the route type (ZEBRA_ROUTE_KERNEL etc.). The zebra server will
459 * then set/unset redist[type] in the client handle (a struct zserv) for the
460 * sending client
461 */
718e3744 462int
463zebra_redistribute_send (int command, int sock, int type)
464{
465 int ret;
466 struct stream *s;
467
468 s = stream_new (ZEBRA_MAX_PACKET_SIZ);
469
470 /* Total length of the messages. */
471 stream_putw (s, 4);
472
473 stream_putc (s, command);
474 stream_putc (s, type);
475
476 ret = writen (sock, s->data, 4);
477
478 stream_free (s);
479
480 return ret;
481}
482
18a6dce6 483/* Router-id update from zebra daemon. */
484void
485zebra_router_id_update_read (struct stream *s, struct prefix *rid)
486{
487 int plen;
488
489 /* Fetch interface address. */
490 rid->family = stream_getc (s);
491
492 plen = prefix_blen (rid);
493 stream_get (&rid->u.prefix, s, plen);
494 rid->prefixlen = stream_getc (s);
495}
496
718e3744 497/* Interface addition from zebra daemon. */
0a589359 498/*
499 * The format of the message sent with type ZEBRA_INTERFACE_ADD or
500 * ZEBRA_INTERFACE_DELETE from zebra to the client is:
501 * 0 1 2 3
502 * 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
503 * +-+-+-+-+-+-+-+-+
504 * | type |
505 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
506 * | ifname |
507 * | |
508 * | |
509 * | |
510 * | |
511 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
512 * | ifindex |
513 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
514 * | if_flags |
515 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
516 * | metric |
517 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
518 * | ifmtu |
519 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
520 * | ifmtu6 |
521 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
522 * | bandwidth |
523 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
524 * | sockaddr_dl |
525 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
526 */
527
718e3744 528struct interface *
529zebra_interface_add_read (struct stream *s)
530{
531 struct interface *ifp;
02ff83c5 532 char ifname_tmp[INTERFACE_NAMSIZ];
718e3744 533
534 /* Read interface name. */
535 stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
536
537 /* Lookup this by interface name. */
538 ifp = if_lookup_by_name (ifname_tmp);
539
540 /* If such interface does not exist, make new one. */
541 if (! ifp)
106d2fd5 542 ifp = if_create (ifname_tmp, INTERFACE_NAMSIZ);
718e3744 543
544 /* Read interface's index. */
545 ifp->ifindex = stream_getl (s);
546
547 /* Read interface's value. */
2e3b2e47 548 ifp->status = stream_getc (s);
718e3744 549 ifp->flags = stream_getl (s);
550 ifp->metric = stream_getl (s);
551 ifp->mtu = stream_getl (s);
0a589359 552 ifp->mtu6 = stream_getl (s);
718e3744 553 ifp->bandwidth = stream_getl (s);
554#ifdef HAVE_SOCKADDR_DL
555 stream_get (&ifp->sdl, s, sizeof (ifp->sdl));
556#else
557 ifp->hw_addr_len = stream_getl (s);
558 if (ifp->hw_addr_len)
559 stream_get (ifp->hw_addr, s, ifp->hw_addr_len);
560#endif /* HAVE_SOCKADDR_DL */
561
562 return ifp;
563}
564
0a589359 565/*
566 * Read interface up/down msg (ZEBRA_INTERFACE_UP/ZEBRA_INTERFACE_DOWN)
567 * from zebra server. The format of this message is the same as
568 * that sent for ZEBRA_INTERFACE_ADD/ZEBRA_INTERFACE_DELETE (see
569 * comments for zebra_interface_add_read), except that no sockaddr_dl
570 * is sent at the tail of the message.
571 */
718e3744 572struct interface *
573zebra_interface_state_read (struct stream *s)
574{
575 struct interface *ifp;
02ff83c5 576 char ifname_tmp[INTERFACE_NAMSIZ];
718e3744 577
578 /* Read interface name. */
579 stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
580
581 /* Lookup this by interface index. */
582 ifp = if_lookup_by_name (ifname_tmp);
583
584 /* If such interface does not exist, indicate an error */
585 if (! ifp)
586 return NULL;
587
588 /* Read interface's index. */
589 ifp->ifindex = stream_getl (s);
590
591 /* Read interface's value. */
2e3b2e47 592 ifp->status = stream_getc (s);
718e3744 593 ifp->flags = stream_getl (s);
594 ifp->metric = stream_getl (s);
595 ifp->mtu = stream_getl (s);
0a589359 596 ifp->mtu6 = stream_getl (s);
718e3744 597 ifp->bandwidth = stream_getl (s);
598
599 return ifp;
600}
601
0a589359 602/*
603 * format of message for address additon is:
604 * 0
605 * 0 1 2 3 4 5 6 7
606 * +-+-+-+-+-+-+-+-+
607 * | type | ZEBRA_INTERFACE_ADDRESS_ADD or
608 * +-+-+-+-+-+-+-+-+ ZEBRA_INTERFACE_ADDRES_DELETE
609 * | |
610 * + +
611 * | ifindex |
612 * + +
613 * | |
614 * + +
615 * | |
616 * +-+-+-+-+-+-+-+-+
617 * | ifc_flags | flags for connected address
618 * +-+-+-+-+-+-+-+-+
619 * | addr_family |
620 * +-+-+-+-+-+-+-+-+
621 * | addr... |
622 * : :
623 * | |
624 * +-+-+-+-+-+-+-+-+
625 * | addr_len | len of addr. E.g., addr_len = 4 for ipv4 addrs.
626 * +-+-+-+-+-+-+-+-+
627 * | daddr.. |
628 * : :
629 * | |
630 * +-+-+-+-+-+-+-+-+
631 *
632 */
633
18a6dce6 634void
635zebra_interface_if_set_value (struct stream *s, struct interface *ifp)
636{
637 /* Read interface's index. */
638 ifp->ifindex = stream_getl (s);
639
640 /* Read interface's value. */
641 ifp->flags = stream_getl (s);
642 ifp->metric = stream_getl (s);
643 ifp->mtu = stream_getl (s);
644 ifp->bandwidth = stream_getl (s);
645}
646
718e3744 647struct connected *
0a589359 648zebra_interface_address_read (int type, struct stream *s)
718e3744 649{
650 unsigned int ifindex;
651 struct interface *ifp;
652 struct connected *ifc;
0a589359 653 struct prefix p, d;
718e3744 654 int family;
655 int plen;
0a589359 656 u_char ifc_flags;
718e3744 657
0a589359 658 memset (&p, 0, sizeof(p));
659 memset (&d, 0, sizeof(d));
718e3744 660
661 /* Get interface index. */
662 ifindex = stream_getl (s);
663
664 /* Lookup index. */
665 ifp = if_lookup_by_index (ifindex);
666 if (ifp == NULL)
667 {
0a589359 668 zlog_warn ("zebra_interface_address_read(%s): "
669 "Can't find interface by ifindex: %d ",
670 (type == ZEBRA_INTERFACE_ADDRESS_ADD? "ADD" : "DELETE"),
671 ifindex);
718e3744 672 return NULL;
673 }
674
675 /* Fetch flag. */
0a589359 676 ifc_flags = stream_getc (s);
718e3744 677
678 /* Fetch interface address. */
679 family = p.family = stream_getc (s);
680
0a589359 681 plen = prefix_blen (&p);
682 stream_get (&p.u.prefix, s, plen);
718e3744 683 p.prefixlen = stream_getc (s);
684
685 /* Fetch destination address. */
0a589359 686 stream_get (&d.u.prefix, s, plen);
718e3744 687 d.family = family;
688
0a589359 689 if (type == ZEBRA_INTERFACE_ADDRESS_ADD)
690 {
691 ifc = connected_add_by_prefix(ifp, &p, &d);
692 if (ifc != NULL)
693 ifc->flags = ifc_flags;
694 }
695 else
696 {
697 assert (type == ZEBRA_INTERFACE_ADDRESS_DELETE);
698 ifc = connected_delete_by_prefix(ifp, &p);
699 }
718e3744 700
701 return ifc;
702}
0a589359 703
718e3744 704\f
705/* Zebra client message read function. */
706int
707zclient_read (struct thread *thread)
708{
709 int ret;
710 int nbytes;
711 int sock;
712 zebra_size_t length;
713 zebra_command_t command;
714 struct zclient *zclient;
715
716 /* Get socket to zebra. */
717 sock = THREAD_FD (thread);
718 zclient = THREAD_ARG (thread);
719 zclient->t_read = NULL;
720
721 /* Clear input buffer. */
722 stream_reset (zclient->ibuf);
723
724 /* Read zebra header. */
725 nbytes = stream_read (zclient->ibuf, sock, ZEBRA_HEADER_SIZE);
726
727 /* zebra socket is closed. */
728 if (nbytes == 0)
729 {
730 if (zclient_debug)
0a589359 731 zlog_info ("zclient connection closed socket [%d].", sock);
718e3744 732 zclient->fail++;
733 zclient_stop (zclient);
734 zclient_event (ZCLIENT_CONNECT, zclient);
735 return -1;
736 }
737
738 /* zebra read error. */
739 if (nbytes < 0 || nbytes != ZEBRA_HEADER_SIZE)
740 {
741 if (zclient_debug)
0a589359 742 zlog_info ("Can't read all packet (length %d).", nbytes);
718e3744 743 zclient->fail++;
744 zclient_stop (zclient);
745 zclient_event (ZCLIENT_CONNECT, zclient);
746 return -1;
747 }
748
749 /* Fetch length and command. */
750 length = stream_getw (zclient->ibuf);
751 command = stream_getc (zclient->ibuf);
752
753 /* Length check. */
754 if (length >= zclient->ibuf->size)
755 {
756 stream_free (zclient->ibuf);
757 zclient->ibuf = stream_new (length + 1);
758 }
759 length -= ZEBRA_HEADER_SIZE;
760
761 /* Read rest of zebra packet. */
762 nbytes = stream_read (zclient->ibuf, sock, length);
763 if (nbytes != length)
764 {
765 if (zclient_debug)
766 zlog_info ("zclient connection closed socket [%d].", sock);
767 zclient->fail++;
768 zclient_stop (zclient);
769 zclient_event (ZCLIENT_CONNECT, zclient);
770 return -1;
771 }
772
0a589359 773 if (zclient_debug)
774 zlog_info("zclient 0x%p command 0x%x \n", zclient, command);
775
718e3744 776 switch (command)
777 {
18a6dce6 778 case ZEBRA_ROUTER_ID_UPDATE:
779 if (zclient->router_id_update)
780 ret = (*zclient->router_id_update) (command, zclient, length);
781 break;
718e3744 782 case ZEBRA_INTERFACE_ADD:
783 if (zclient->interface_add)
784 ret = (*zclient->interface_add) (command, zclient, length);
785 break;
786 case ZEBRA_INTERFACE_DELETE:
787 if (zclient->interface_delete)
788 ret = (*zclient->interface_delete) (command, zclient, length);
789 break;
790 case ZEBRA_INTERFACE_ADDRESS_ADD:
791 if (zclient->interface_address_add)
792 ret = (*zclient->interface_address_add) (command, zclient, length);
793 break;
794 case ZEBRA_INTERFACE_ADDRESS_DELETE:
795 if (zclient->interface_address_delete)
796 ret = (*zclient->interface_address_delete) (command, zclient, length);
797 break;
798 case ZEBRA_INTERFACE_UP:
799 if (zclient->interface_up)
800 ret = (*zclient->interface_up) (command, zclient, length);
801 break;
802 case ZEBRA_INTERFACE_DOWN:
803 if (zclient->interface_down)
804 ret = (*zclient->interface_down) (command, zclient, length);
805 break;
806 case ZEBRA_IPV4_ROUTE_ADD:
807 if (zclient->ipv4_route_add)
808 ret = (*zclient->ipv4_route_add) (command, zclient, length);
809 break;
810 case ZEBRA_IPV4_ROUTE_DELETE:
811 if (zclient->ipv4_route_delete)
812 ret = (*zclient->ipv4_route_delete) (command, zclient, length);
813 break;
814 case ZEBRA_IPV6_ROUTE_ADD:
815 if (zclient->ipv6_route_add)
816 ret = (*zclient->ipv6_route_add) (command, zclient, length);
817 break;
818 case ZEBRA_IPV6_ROUTE_DELETE:
819 if (zclient->ipv6_route_delete)
820 ret = (*zclient->ipv6_route_delete) (command, zclient, length);
821 break;
822 default:
823 break;
824 }
825
826 /* Register read thread. */
827 zclient_event (ZCLIENT_READ, zclient);
828
829 return 0;
830}
831
832void
0a589359 833zclient_redistribute (int command, struct zclient *zclient, int type)
718e3744 834{
718e3744 835
0a589359 836 if (command == ZEBRA_REDISTRIBUTE_ADD)
837 {
838 if (zclient->redist[type])
839 return;
840 zclient->redist[type] = 1;
841 }
842 else
843 {
844 if (!zclient->redist[type])
845 return;
846 zclient->redist[type] = 0;
847 }
718e3744 848
849 if (zclient->sock > 0)
0a589359 850 zebra_redistribute_send (command, zclient->sock, type);
718e3744 851}
852
718e3744 853
854void
0a589359 855zclient_redistribute_default (int command, struct zclient *zclient)
718e3744 856{
718e3744 857
0a589359 858 if (command == ZEBRA_REDISTRIBUTE_DEFAULT_ADD)
859 {
860 if (zclient->default_information)
861 return;
862 zclient->default_information = 1;
863 }
864 else
865 {
866 if (!zclient->default_information)
867 return;
868 zclient->default_information = 0;
869 }
718e3744 870
871 if (zclient->sock > 0)
0a589359 872 zebra_message_send (zclient, command);
718e3744 873}
874
718e3744 875\f
876extern struct thread_master *master;
877
878static void
879zclient_event (enum event event, struct zclient *zclient)
880{
881 switch (event)
882 {
883 case ZCLIENT_SCHEDULE:
884 if (! zclient->t_connect)
885 zclient->t_connect =
886 thread_add_event (master, zclient_connect, zclient, 0);
887 break;
888 case ZCLIENT_CONNECT:
889 if (zclient->fail >= 10)
890 return;
891 if (zclient_debug)
892 zlog_info ("zclient connect schedule interval is %d",
893 zclient->fail < 3 ? 10 : 60);
894 if (! zclient->t_connect)
895 zclient->t_connect =
896 thread_add_timer (master, zclient_connect, zclient,
897 zclient->fail < 3 ? 10 : 60);
898 break;
899 case ZCLIENT_READ:
900 zclient->t_read =
901 thread_add_read (master, zclient_read, zclient, zclient->sock);
902 break;
903 }
904}