blob: 453e6cdd2d434a67e34f8dd8abd50f43911457b4 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* 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
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
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)
ajs8ddca702004-12-07 18:53:52 +000094 zlog_debug ("zclient start scheduled");
paul718e3742002-12-13 20:15:29 +000095
96 zclient_event (ZCLIENT_SCHEDULE, zclient);
97}
98
99/* Stop zebra client services. */
100void
101zclient_stop (struct zclient *zclient)
102{
103 if (zclient_debug)
ajs8ddca702004-12-07 18:53:52 +0000104 zlog_debug ("zclient stopped");
paul718e3742002-12-13 20:15:29 +0000105
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
hasso8c328f12004-10-05 21:01:23 +0000170zclient_socket_un (const char *path)
paul718e3742002-12-13 20:15:29 +0000171{
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)
ajs8ddca702004-12-07 18:53:52 +0000223 zlog_debug ("zclient_start is called");
paul718e3742002-12-13 20:15:29 +0000224
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)
ajs8ddca702004-12-07 18:53:52 +0000246 zlog_debug ("zclient connection fail");
paul718e3742002-12-13 20:15:29 +0000247 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)
ajs8ddca702004-12-07 18:53:52 +0000255 zlog_debug ("zclient connect success with socket [%d]", zclient->sock);
paul718e3742002-12-13 20:15:29 +0000256
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
hasso18a6dce2004-10-03 18:18:34 +0000263 /* We need router-id information. */
264 zebra_message_send (zclient, ZEBRA_ROUTER_ID_ADD);
265
paul718e3742002-12-13 20:15:29 +0000266 /* 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)
ajs8ddca702004-12-07 18:53:52 +0000289 zlog_debug ("zclient_connect is called");
paul718e3742002-12-13 20:15:29 +0000290
291 return zclient_start (zclient);
292}
293
paul0a589352004-05-08 11:48:26 +0000294 /*
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 */
paul718e3742002-12-13 20:15:29 +0000338int
paul0a589352004-05-08 11:48:26 +0000339zapi_ipv4_route (u_char cmd, struct zclient *zclient, struct prefix_ipv4 *p,
340 struct zapi_ipv4 *api)
paul718e3742002-12-13 20:15:29 +0000341{
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. */
paul0a589352004-05-08 11:48:26 +0000354 stream_putc (s, cmd);
paul718e3742002-12-13 20:15:29 +0000355 stream_putc (s, api->type);
356 stream_putc (s, api->flags);
357 stream_putc (s, api->message);
paul0a589352004-05-08 11:48:26 +0000358
paul718e3742002-12-13 20:15:29 +0000359 /* Put prefix information. */
360 psize = PSIZE (p->prefixlen);
361 stream_putc (s, p->prefixlen);
paul0a589352004-05-08 11:48:26 +0000362 stream_write (s, (u_char *) & p->prefix, psize);
paul718e3742002-12-13 20:15:29 +0000363
364 /* Nexthop, ifindex, distance and metric information. */
365 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
366 {
paul595db7f2003-05-25 21:35:06 +0000367 if (CHECK_FLAG (api->flags, ZEBRA_FLAG_BLACKHOLE))
368 {
369 stream_putc (s, 1);
370 stream_putc (s, ZEBRA_NEXTHOP_BLACKHOLE);
paul0a589352004-05-08 11:48:26 +0000371 /* XXX assert(api->nexthop_num == 0); */
372 /* XXX assert(api->ifindex_num == 0); */
paul595db7f2003-05-25 21:35:06 +0000373 }
374 else
375 stream_putc (s, api->nexthop_num + api->ifindex_num);
paul718e3742002-12-13 20:15:29 +0000376
377 for (i = 0; i < api->nexthop_num; i++)
paul595db7f2003-05-25 21:35:06 +0000378 {
379 stream_putc (s, ZEBRA_NEXTHOP_IPV4);
380 stream_put_in_addr (s, api->nexthop[i]);
381 }
paul718e3742002-12-13 20:15:29 +0000382 for (i = 0; i < api->ifindex_num; i++)
paul595db7f2003-05-25 21:35:06 +0000383 {
384 stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
385 stream_putl (s, api->ifindex[i]);
386 }
paul718e3742002-12-13 20:15:29 +0000387 }
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
paul0a589352004-05-08 11:48:26 +0000402zapi_ipv6_route (u_char cmd, struct zclient *zclient, struct prefix_ipv6 *p,
paul718e3742002-12-13 20:15:29 +0000403 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. */
paul0a589352004-05-08 11:48:26 +0000417 stream_putc (s, cmd);
paul718e3742002-12-13 20:15:29 +0000418 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}
paul718e3742002-12-13 20:15:29 +0000454#endif /* HAVE_IPV6 */
455
paul0a589352004-05-08 11:48:26 +0000456/*
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 */
paul718e3742002-12-13 20:15:29 +0000462int
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
hasso18a6dce2004-10-03 18:18:34 +0000483/* 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
paul718e3742002-12-13 20:15:29 +0000497/* Interface addition from zebra daemon. */
paul0a589352004-05-08 11:48:26 +0000498/*
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
paul718e3742002-12-13 20:15:29 +0000528struct interface *
529zebra_interface_add_read (struct stream *s)
530{
531 struct interface *ifp;
paul02ff83c2004-06-11 11:27:03 +0000532 char ifname_tmp[INTERFACE_NAMSIZ];
paul718e3742002-12-13 20:15:29 +0000533
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)
paul106d2fd2003-08-01 00:24:13 +0000542 ifp = if_create (ifname_tmp, INTERFACE_NAMSIZ);
paul718e3742002-12-13 20:15:29 +0000543
544 /* Read interface's index. */
545 ifp->ifindex = stream_getl (s);
546
547 /* Read interface's value. */
paul2e3b2e42002-12-13 21:03:13 +0000548 ifp->status = stream_getc (s);
paul718e3742002-12-13 20:15:29 +0000549 ifp->flags = stream_getl (s);
550 ifp->metric = stream_getl (s);
551 ifp->mtu = stream_getl (s);
paul0a589352004-05-08 11:48:26 +0000552 ifp->mtu6 = stream_getl (s);
paul718e3742002-12-13 20:15:29 +0000553 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
paul0a589352004-05-08 11:48:26 +0000565/*
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 */
paul718e3742002-12-13 20:15:29 +0000572struct interface *
573zebra_interface_state_read (struct stream *s)
574{
575 struct interface *ifp;
paul02ff83c2004-06-11 11:27:03 +0000576 char ifname_tmp[INTERFACE_NAMSIZ];
paul718e3742002-12-13 20:15:29 +0000577
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. */
paul2e3b2e42002-12-13 21:03:13 +0000592 ifp->status = stream_getc (s);
paul718e3742002-12-13 20:15:29 +0000593 ifp->flags = stream_getl (s);
594 ifp->metric = stream_getl (s);
595 ifp->mtu = stream_getl (s);
paul0a589352004-05-08 11:48:26 +0000596 ifp->mtu6 = stream_getl (s);
paul718e3742002-12-13 20:15:29 +0000597 ifp->bandwidth = stream_getl (s);
598
599 return ifp;
600}
601
paul0a589352004-05-08 11:48:26 +0000602/*
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
hasso18a6dce2004-10-03 18:18:34 +0000634void
635zebra_interface_if_set_value (struct stream *s, struct interface *ifp)
636{
637 /* Read interface's index. */
638 ifp->ifindex = stream_getl (s);
hasso508ec912004-10-23 14:26:49 +0000639 ifp->status = stream_getc (s);
hasso18a6dce2004-10-03 18:18:34 +0000640
641 /* Read interface's value. */
642 ifp->flags = stream_getl (s);
643 ifp->metric = stream_getl (s);
644 ifp->mtu = stream_getl (s);
hasso508ec912004-10-23 14:26:49 +0000645 ifp->mtu6 = stream_getl (s);
hasso18a6dce2004-10-03 18:18:34 +0000646 ifp->bandwidth = stream_getl (s);
647}
648
hasso3fb9cd62004-10-19 19:44:43 +0000649static int
650memconstant(const void *s, int c, size_t n)
651{
652 const u_char *p = s;
653
654 while (n-- > 0)
655 if (*p++ != c)
656 return 0;
657 return 1;
658}
659
paul718e3742002-12-13 20:15:29 +0000660struct connected *
paul0a589352004-05-08 11:48:26 +0000661zebra_interface_address_read (int type, struct stream *s)
paul718e3742002-12-13 20:15:29 +0000662{
663 unsigned int ifindex;
664 struct interface *ifp;
665 struct connected *ifc;
paul0a589352004-05-08 11:48:26 +0000666 struct prefix p, d;
paul718e3742002-12-13 20:15:29 +0000667 int family;
668 int plen;
paul0a589352004-05-08 11:48:26 +0000669 u_char ifc_flags;
670
671 memset (&p, 0, sizeof(p));
672 memset (&d, 0, sizeof(d));
paul718e3742002-12-13 20:15:29 +0000673
674 /* Get interface index. */
675 ifindex = stream_getl (s);
676
677 /* Lookup index. */
678 ifp = if_lookup_by_index (ifindex);
679 if (ifp == NULL)
680 {
paul0a589352004-05-08 11:48:26 +0000681 zlog_warn ("zebra_interface_address_read(%s): "
682 "Can't find interface by ifindex: %d ",
683 (type == ZEBRA_INTERFACE_ADDRESS_ADD? "ADD" : "DELETE"),
684 ifindex);
paul718e3742002-12-13 20:15:29 +0000685 return NULL;
686 }
687
688 /* Fetch flag. */
paul0a589352004-05-08 11:48:26 +0000689 ifc_flags = stream_getc (s);
paul718e3742002-12-13 20:15:29 +0000690
691 /* Fetch interface address. */
692 family = p.family = stream_getc (s);
693
paul0a589352004-05-08 11:48:26 +0000694 plen = prefix_blen (&p);
695 stream_get (&p.u.prefix, s, plen);
paul718e3742002-12-13 20:15:29 +0000696 p.prefixlen = stream_getc (s);
697
698 /* Fetch destination address. */
paul0a589352004-05-08 11:48:26 +0000699 stream_get (&d.u.prefix, s, plen);
paul718e3742002-12-13 20:15:29 +0000700 d.family = family;
701
paul0a589352004-05-08 11:48:26 +0000702 if (type == ZEBRA_INTERFACE_ADDRESS_ADD)
703 {
hasso3fb9cd62004-10-19 19:44:43 +0000704 /* N.B. NULL destination pointers are encoded as all zeroes */
705 ifc = connected_add_by_prefix(ifp, &p,(memconstant(&d.u.prefix,0,plen) ?
706 NULL : &d));
paul0a589352004-05-08 11:48:26 +0000707 if (ifc != NULL)
708 ifc->flags = ifc_flags;
709 }
710 else
711 {
712 assert (type == ZEBRA_INTERFACE_ADDRESS_DELETE);
713 ifc = connected_delete_by_prefix(ifp, &p);
714 }
paul718e3742002-12-13 20:15:29 +0000715
716 return ifc;
717}
paul0a589352004-05-08 11:48:26 +0000718
paul718e3742002-12-13 20:15:29 +0000719
720/* Zebra client message read function. */
721int
722zclient_read (struct thread *thread)
723{
724 int ret;
725 int nbytes;
726 int sock;
727 zebra_size_t length;
728 zebra_command_t command;
729 struct zclient *zclient;
730
731 /* Get socket to zebra. */
732 sock = THREAD_FD (thread);
733 zclient = THREAD_ARG (thread);
734 zclient->t_read = NULL;
735
736 /* Clear input buffer. */
737 stream_reset (zclient->ibuf);
738
739 /* Read zebra header. */
740 nbytes = stream_read (zclient->ibuf, sock, ZEBRA_HEADER_SIZE);
741
742 /* zebra socket is closed. */
743 if (nbytes == 0)
744 {
745 if (zclient_debug)
ajs8ddca702004-12-07 18:53:52 +0000746 zlog_debug ("zclient connection closed socket [%d].", sock);
paul718e3742002-12-13 20:15:29 +0000747 zclient->fail++;
748 zclient_stop (zclient);
749 zclient_event (ZCLIENT_CONNECT, zclient);
750 return -1;
751 }
752
753 /* zebra read error. */
754 if (nbytes < 0 || nbytes != ZEBRA_HEADER_SIZE)
755 {
756 if (zclient_debug)
ajs8ddca702004-12-07 18:53:52 +0000757 zlog_debug ("Can't read all packet (length %d).", nbytes);
paul718e3742002-12-13 20:15:29 +0000758 zclient->fail++;
759 zclient_stop (zclient);
760 zclient_event (ZCLIENT_CONNECT, zclient);
761 return -1;
762 }
763
764 /* Fetch length and command. */
765 length = stream_getw (zclient->ibuf);
766 command = stream_getc (zclient->ibuf);
767
768 /* Length check. */
769 if (length >= zclient->ibuf->size)
770 {
771 stream_free (zclient->ibuf);
772 zclient->ibuf = stream_new (length + 1);
773 }
774 length -= ZEBRA_HEADER_SIZE;
775
776 /* Read rest of zebra packet. */
777 nbytes = stream_read (zclient->ibuf, sock, length);
778 if (nbytes != length)
779 {
780 if (zclient_debug)
ajs8ddca702004-12-07 18:53:52 +0000781 zlog_debug ("zclient connection closed socket [%d].", sock);
paul718e3742002-12-13 20:15:29 +0000782 zclient->fail++;
783 zclient_stop (zclient);
784 zclient_event (ZCLIENT_CONNECT, zclient);
785 return -1;
786 }
787
paul0a589352004-05-08 11:48:26 +0000788 if (zclient_debug)
ajs8ddca702004-12-07 18:53:52 +0000789 zlog_debug("zclient 0x%p command 0x%x \n", zclient, command);
paul0a589352004-05-08 11:48:26 +0000790
paul718e3742002-12-13 20:15:29 +0000791 switch (command)
792 {
hasso18a6dce2004-10-03 18:18:34 +0000793 case ZEBRA_ROUTER_ID_UPDATE:
794 if (zclient->router_id_update)
795 ret = (*zclient->router_id_update) (command, zclient, length);
796 break;
paul718e3742002-12-13 20:15:29 +0000797 case ZEBRA_INTERFACE_ADD:
798 if (zclient->interface_add)
799 ret = (*zclient->interface_add) (command, zclient, length);
800 break;
801 case ZEBRA_INTERFACE_DELETE:
802 if (zclient->interface_delete)
803 ret = (*zclient->interface_delete) (command, zclient, length);
804 break;
805 case ZEBRA_INTERFACE_ADDRESS_ADD:
806 if (zclient->interface_address_add)
807 ret = (*zclient->interface_address_add) (command, zclient, length);
808 break;
809 case ZEBRA_INTERFACE_ADDRESS_DELETE:
810 if (zclient->interface_address_delete)
811 ret = (*zclient->interface_address_delete) (command, zclient, length);
812 break;
813 case ZEBRA_INTERFACE_UP:
814 if (zclient->interface_up)
815 ret = (*zclient->interface_up) (command, zclient, length);
816 break;
817 case ZEBRA_INTERFACE_DOWN:
818 if (zclient->interface_down)
819 ret = (*zclient->interface_down) (command, zclient, length);
820 break;
821 case ZEBRA_IPV4_ROUTE_ADD:
822 if (zclient->ipv4_route_add)
823 ret = (*zclient->ipv4_route_add) (command, zclient, length);
824 break;
825 case ZEBRA_IPV4_ROUTE_DELETE:
826 if (zclient->ipv4_route_delete)
827 ret = (*zclient->ipv4_route_delete) (command, zclient, length);
828 break;
829 case ZEBRA_IPV6_ROUTE_ADD:
830 if (zclient->ipv6_route_add)
831 ret = (*zclient->ipv6_route_add) (command, zclient, length);
832 break;
833 case ZEBRA_IPV6_ROUTE_DELETE:
834 if (zclient->ipv6_route_delete)
835 ret = (*zclient->ipv6_route_delete) (command, zclient, length);
836 break;
837 default:
838 break;
839 }
840
841 /* Register read thread. */
842 zclient_event (ZCLIENT_READ, zclient);
843
844 return 0;
845}
846
847void
paul0a589352004-05-08 11:48:26 +0000848zclient_redistribute (int command, struct zclient *zclient, int type)
paul718e3742002-12-13 20:15:29 +0000849{
paul718e3742002-12-13 20:15:29 +0000850
paul0a589352004-05-08 11:48:26 +0000851 if (command == ZEBRA_REDISTRIBUTE_ADD)
852 {
853 if (zclient->redist[type])
854 return;
855 zclient->redist[type] = 1;
856 }
857 else
858 {
859 if (!zclient->redist[type])
860 return;
861 zclient->redist[type] = 0;
862 }
paul718e3742002-12-13 20:15:29 +0000863
864 if (zclient->sock > 0)
paul0a589352004-05-08 11:48:26 +0000865 zebra_redistribute_send (command, zclient->sock, type);
paul718e3742002-12-13 20:15:29 +0000866}
867
paul0a589352004-05-08 11:48:26 +0000868
paul718e3742002-12-13 20:15:29 +0000869void
paul0a589352004-05-08 11:48:26 +0000870zclient_redistribute_default (int command, struct zclient *zclient)
paul718e3742002-12-13 20:15:29 +0000871{
paul718e3742002-12-13 20:15:29 +0000872
paul0a589352004-05-08 11:48:26 +0000873 if (command == ZEBRA_REDISTRIBUTE_DEFAULT_ADD)
874 {
875 if (zclient->default_information)
876 return;
877 zclient->default_information = 1;
878 }
879 else
880 {
881 if (!zclient->default_information)
882 return;
883 zclient->default_information = 0;
884 }
paul718e3742002-12-13 20:15:29 +0000885
886 if (zclient->sock > 0)
paul0a589352004-05-08 11:48:26 +0000887 zebra_message_send (zclient, command);
paul718e3742002-12-13 20:15:29 +0000888}
889
paul718e3742002-12-13 20:15:29 +0000890
891extern struct thread_master *master;
892
893static void
894zclient_event (enum event event, struct zclient *zclient)
895{
896 switch (event)
897 {
898 case ZCLIENT_SCHEDULE:
899 if (! zclient->t_connect)
900 zclient->t_connect =
901 thread_add_event (master, zclient_connect, zclient, 0);
902 break;
903 case ZCLIENT_CONNECT:
904 if (zclient->fail >= 10)
905 return;
906 if (zclient_debug)
ajs8ddca702004-12-07 18:53:52 +0000907 zlog_debug ("zclient connect schedule interval is %d",
paul718e3742002-12-13 20:15:29 +0000908 zclient->fail < 3 ? 10 : 60);
909 if (! zclient->t_connect)
910 zclient->t_connect =
911 thread_add_timer (master, zclient_connect, zclient,
912 zclient->fail < 3 ? 10 : 60);
913 break;
914 case ZCLIENT_READ:
915 zclient->t_read =
916 thread_add_read (master, zclient_read, zclient, zclient->sock);
917 break;
918 }
919}