blob: efcad57f644a6eaebdbc6938bb11ec40385f13d6 [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
ajsa3491982005-04-02 22:50:38 +0000537 /* Lookup/create interface by name. */
538 ifp = if_get_by_name_len (ifname_tmp, strnlen(ifname_tmp, INTERFACE_NAMSIZ));
paul718e3742002-12-13 20:15:29 +0000539
540 /* Read interface's index. */
541 ifp->ifindex = stream_getl (s);
542
543 /* Read interface's value. */
paul2e3b2e42002-12-13 21:03:13 +0000544 ifp->status = stream_getc (s);
paul718e3742002-12-13 20:15:29 +0000545 ifp->flags = stream_getl (s);
546 ifp->metric = stream_getl (s);
547 ifp->mtu = stream_getl (s);
paul0a589352004-05-08 11:48:26 +0000548 ifp->mtu6 = stream_getl (s);
paul718e3742002-12-13 20:15:29 +0000549 ifp->bandwidth = stream_getl (s);
550#ifdef HAVE_SOCKADDR_DL
551 stream_get (&ifp->sdl, s, sizeof (ifp->sdl));
552#else
553 ifp->hw_addr_len = stream_getl (s);
554 if (ifp->hw_addr_len)
555 stream_get (ifp->hw_addr, s, ifp->hw_addr_len);
556#endif /* HAVE_SOCKADDR_DL */
557
558 return ifp;
559}
560
paul0a589352004-05-08 11:48:26 +0000561/*
562 * Read interface up/down msg (ZEBRA_INTERFACE_UP/ZEBRA_INTERFACE_DOWN)
563 * from zebra server. The format of this message is the same as
564 * that sent for ZEBRA_INTERFACE_ADD/ZEBRA_INTERFACE_DELETE (see
565 * comments for zebra_interface_add_read), except that no sockaddr_dl
566 * is sent at the tail of the message.
567 */
paul718e3742002-12-13 20:15:29 +0000568struct interface *
569zebra_interface_state_read (struct stream *s)
570{
571 struct interface *ifp;
paul02ff83c2004-06-11 11:27:03 +0000572 char ifname_tmp[INTERFACE_NAMSIZ];
paul718e3742002-12-13 20:15:29 +0000573
574 /* Read interface name. */
575 stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
576
577 /* Lookup this by interface index. */
ajsa3491982005-04-02 22:50:38 +0000578 ifp = if_lookup_by_name_len (ifname_tmp,
579 strnlen(ifname_tmp, INTERFACE_NAMSIZ));
paul718e3742002-12-13 20:15:29 +0000580
581 /* If such interface does not exist, indicate an error */
582 if (! ifp)
583 return NULL;
584
585 /* Read interface's index. */
586 ifp->ifindex = stream_getl (s);
587
588 /* Read interface's value. */
paul2e3b2e42002-12-13 21:03:13 +0000589 ifp->status = stream_getc (s);
paul718e3742002-12-13 20:15:29 +0000590 ifp->flags = stream_getl (s);
591 ifp->metric = stream_getl (s);
592 ifp->mtu = stream_getl (s);
paul0a589352004-05-08 11:48:26 +0000593 ifp->mtu6 = stream_getl (s);
paul718e3742002-12-13 20:15:29 +0000594 ifp->bandwidth = stream_getl (s);
595
596 return ifp;
597}
598
paul0a589352004-05-08 11:48:26 +0000599/*
600 * format of message for address additon is:
601 * 0
602 * 0 1 2 3 4 5 6 7
603 * +-+-+-+-+-+-+-+-+
604 * | type | ZEBRA_INTERFACE_ADDRESS_ADD or
605 * +-+-+-+-+-+-+-+-+ ZEBRA_INTERFACE_ADDRES_DELETE
606 * | |
607 * + +
608 * | ifindex |
609 * + +
610 * | |
611 * + +
612 * | |
613 * +-+-+-+-+-+-+-+-+
614 * | ifc_flags | flags for connected address
615 * +-+-+-+-+-+-+-+-+
616 * | addr_family |
617 * +-+-+-+-+-+-+-+-+
618 * | addr... |
619 * : :
620 * | |
621 * +-+-+-+-+-+-+-+-+
622 * | addr_len | len of addr. E.g., addr_len = 4 for ipv4 addrs.
623 * +-+-+-+-+-+-+-+-+
624 * | daddr.. |
625 * : :
626 * | |
627 * +-+-+-+-+-+-+-+-+
628 *
629 */
630
hasso18a6dce2004-10-03 18:18:34 +0000631void
632zebra_interface_if_set_value (struct stream *s, struct interface *ifp)
633{
634 /* Read interface's index. */
635 ifp->ifindex = stream_getl (s);
hasso508ec912004-10-23 14:26:49 +0000636 ifp->status = stream_getc (s);
hasso18a6dce2004-10-03 18:18:34 +0000637
638 /* Read interface's value. */
639 ifp->flags = stream_getl (s);
640 ifp->metric = stream_getl (s);
641 ifp->mtu = stream_getl (s);
hasso508ec912004-10-23 14:26:49 +0000642 ifp->mtu6 = stream_getl (s);
hasso18a6dce2004-10-03 18:18:34 +0000643 ifp->bandwidth = stream_getl (s);
644}
645
hasso3fb9cd62004-10-19 19:44:43 +0000646static int
647memconstant(const void *s, int c, size_t n)
648{
649 const u_char *p = s;
650
651 while (n-- > 0)
652 if (*p++ != c)
653 return 0;
654 return 1;
655}
656
paul718e3742002-12-13 20:15:29 +0000657struct connected *
paul0a589352004-05-08 11:48:26 +0000658zebra_interface_address_read (int type, struct stream *s)
paul718e3742002-12-13 20:15:29 +0000659{
660 unsigned int ifindex;
661 struct interface *ifp;
662 struct connected *ifc;
paul0a589352004-05-08 11:48:26 +0000663 struct prefix p, d;
paul718e3742002-12-13 20:15:29 +0000664 int family;
665 int plen;
paul0a589352004-05-08 11:48:26 +0000666 u_char ifc_flags;
667
668 memset (&p, 0, sizeof(p));
669 memset (&d, 0, sizeof(d));
paul718e3742002-12-13 20:15:29 +0000670
671 /* Get interface index. */
672 ifindex = stream_getl (s);
673
674 /* Lookup index. */
675 ifp = if_lookup_by_index (ifindex);
676 if (ifp == NULL)
677 {
paul0a589352004-05-08 11:48:26 +0000678 zlog_warn ("zebra_interface_address_read(%s): "
679 "Can't find interface by ifindex: %d ",
680 (type == ZEBRA_INTERFACE_ADDRESS_ADD? "ADD" : "DELETE"),
681 ifindex);
paul718e3742002-12-13 20:15:29 +0000682 return NULL;
683 }
684
685 /* Fetch flag. */
paul0a589352004-05-08 11:48:26 +0000686 ifc_flags = stream_getc (s);
paul718e3742002-12-13 20:15:29 +0000687
688 /* Fetch interface address. */
689 family = p.family = stream_getc (s);
690
paul0a589352004-05-08 11:48:26 +0000691 plen = prefix_blen (&p);
692 stream_get (&p.u.prefix, s, plen);
paul718e3742002-12-13 20:15:29 +0000693 p.prefixlen = stream_getc (s);
694
695 /* Fetch destination address. */
paul0a589352004-05-08 11:48:26 +0000696 stream_get (&d.u.prefix, s, plen);
paul718e3742002-12-13 20:15:29 +0000697 d.family = family;
698
paul0a589352004-05-08 11:48:26 +0000699 if (type == ZEBRA_INTERFACE_ADDRESS_ADD)
700 {
hasso3fb9cd62004-10-19 19:44:43 +0000701 /* N.B. NULL destination pointers are encoded as all zeroes */
702 ifc = connected_add_by_prefix(ifp, &p,(memconstant(&d.u.prefix,0,plen) ?
703 NULL : &d));
paul0a589352004-05-08 11:48:26 +0000704 if (ifc != NULL)
705 ifc->flags = ifc_flags;
706 }
707 else
708 {
709 assert (type == ZEBRA_INTERFACE_ADDRESS_DELETE);
710 ifc = connected_delete_by_prefix(ifp, &p);
711 }
paul718e3742002-12-13 20:15:29 +0000712
713 return ifc;
714}
paul0a589352004-05-08 11:48:26 +0000715
paul718e3742002-12-13 20:15:29 +0000716
717/* Zebra client message read function. */
718int
719zclient_read (struct thread *thread)
720{
721 int ret;
722 int nbytes;
723 int sock;
724 zebra_size_t length;
725 zebra_command_t command;
726 struct zclient *zclient;
727
728 /* Get socket to zebra. */
729 sock = THREAD_FD (thread);
730 zclient = THREAD_ARG (thread);
731 zclient->t_read = NULL;
732
733 /* Clear input buffer. */
734 stream_reset (zclient->ibuf);
735
736 /* Read zebra header. */
737 nbytes = stream_read (zclient->ibuf, sock, ZEBRA_HEADER_SIZE);
738
739 /* zebra socket is closed. */
740 if (nbytes == 0)
741 {
742 if (zclient_debug)
ajs8ddca702004-12-07 18:53:52 +0000743 zlog_debug ("zclient connection closed socket [%d].", sock);
paul718e3742002-12-13 20:15:29 +0000744 zclient->fail++;
745 zclient_stop (zclient);
746 zclient_event (ZCLIENT_CONNECT, zclient);
747 return -1;
748 }
749
750 /* zebra read error. */
751 if (nbytes < 0 || nbytes != ZEBRA_HEADER_SIZE)
752 {
753 if (zclient_debug)
ajs8ddca702004-12-07 18:53:52 +0000754 zlog_debug ("Can't read all packet (length %d).", nbytes);
paul718e3742002-12-13 20:15:29 +0000755 zclient->fail++;
756 zclient_stop (zclient);
757 zclient_event (ZCLIENT_CONNECT, zclient);
758 return -1;
759 }
760
761 /* Fetch length and command. */
762 length = stream_getw (zclient->ibuf);
763 command = stream_getc (zclient->ibuf);
764
765 /* Length check. */
766 if (length >= zclient->ibuf->size)
767 {
768 stream_free (zclient->ibuf);
769 zclient->ibuf = stream_new (length + 1);
770 }
771 length -= ZEBRA_HEADER_SIZE;
772
773 /* Read rest of zebra packet. */
774 nbytes = stream_read (zclient->ibuf, sock, length);
775 if (nbytes != length)
776 {
777 if (zclient_debug)
ajs8ddca702004-12-07 18:53:52 +0000778 zlog_debug ("zclient connection closed socket [%d].", sock);
paul718e3742002-12-13 20:15:29 +0000779 zclient->fail++;
780 zclient_stop (zclient);
781 zclient_event (ZCLIENT_CONNECT, zclient);
782 return -1;
783 }
784
paul0a589352004-05-08 11:48:26 +0000785 if (zclient_debug)
ajs8ddca702004-12-07 18:53:52 +0000786 zlog_debug("zclient 0x%p command 0x%x \n", zclient, command);
paul0a589352004-05-08 11:48:26 +0000787
paul718e3742002-12-13 20:15:29 +0000788 switch (command)
789 {
hasso18a6dce2004-10-03 18:18:34 +0000790 case ZEBRA_ROUTER_ID_UPDATE:
791 if (zclient->router_id_update)
792 ret = (*zclient->router_id_update) (command, zclient, length);
793 break;
paul718e3742002-12-13 20:15:29 +0000794 case ZEBRA_INTERFACE_ADD:
795 if (zclient->interface_add)
796 ret = (*zclient->interface_add) (command, zclient, length);
797 break;
798 case ZEBRA_INTERFACE_DELETE:
799 if (zclient->interface_delete)
800 ret = (*zclient->interface_delete) (command, zclient, length);
801 break;
802 case ZEBRA_INTERFACE_ADDRESS_ADD:
803 if (zclient->interface_address_add)
804 ret = (*zclient->interface_address_add) (command, zclient, length);
805 break;
806 case ZEBRA_INTERFACE_ADDRESS_DELETE:
807 if (zclient->interface_address_delete)
808 ret = (*zclient->interface_address_delete) (command, zclient, length);
809 break;
810 case ZEBRA_INTERFACE_UP:
811 if (zclient->interface_up)
812 ret = (*zclient->interface_up) (command, zclient, length);
813 break;
814 case ZEBRA_INTERFACE_DOWN:
815 if (zclient->interface_down)
816 ret = (*zclient->interface_down) (command, zclient, length);
817 break;
818 case ZEBRA_IPV4_ROUTE_ADD:
819 if (zclient->ipv4_route_add)
820 ret = (*zclient->ipv4_route_add) (command, zclient, length);
821 break;
822 case ZEBRA_IPV4_ROUTE_DELETE:
823 if (zclient->ipv4_route_delete)
824 ret = (*zclient->ipv4_route_delete) (command, zclient, length);
825 break;
826 case ZEBRA_IPV6_ROUTE_ADD:
827 if (zclient->ipv6_route_add)
828 ret = (*zclient->ipv6_route_add) (command, zclient, length);
829 break;
830 case ZEBRA_IPV6_ROUTE_DELETE:
831 if (zclient->ipv6_route_delete)
832 ret = (*zclient->ipv6_route_delete) (command, zclient, length);
833 break;
834 default:
835 break;
836 }
837
838 /* Register read thread. */
839 zclient_event (ZCLIENT_READ, zclient);
840
841 return 0;
842}
843
844void
paul0a589352004-05-08 11:48:26 +0000845zclient_redistribute (int command, struct zclient *zclient, int type)
paul718e3742002-12-13 20:15:29 +0000846{
paul718e3742002-12-13 20:15:29 +0000847
paul0a589352004-05-08 11:48:26 +0000848 if (command == ZEBRA_REDISTRIBUTE_ADD)
849 {
850 if (zclient->redist[type])
851 return;
852 zclient->redist[type] = 1;
853 }
854 else
855 {
856 if (!zclient->redist[type])
857 return;
858 zclient->redist[type] = 0;
859 }
paul718e3742002-12-13 20:15:29 +0000860
861 if (zclient->sock > 0)
paul0a589352004-05-08 11:48:26 +0000862 zebra_redistribute_send (command, zclient->sock, type);
paul718e3742002-12-13 20:15:29 +0000863}
864
paul0a589352004-05-08 11:48:26 +0000865
paul718e3742002-12-13 20:15:29 +0000866void
paul0a589352004-05-08 11:48:26 +0000867zclient_redistribute_default (int command, struct zclient *zclient)
paul718e3742002-12-13 20:15:29 +0000868{
paul718e3742002-12-13 20:15:29 +0000869
paul0a589352004-05-08 11:48:26 +0000870 if (command == ZEBRA_REDISTRIBUTE_DEFAULT_ADD)
871 {
872 if (zclient->default_information)
873 return;
874 zclient->default_information = 1;
875 }
876 else
877 {
878 if (!zclient->default_information)
879 return;
880 zclient->default_information = 0;
881 }
paul718e3742002-12-13 20:15:29 +0000882
883 if (zclient->sock > 0)
paul0a589352004-05-08 11:48:26 +0000884 zebra_message_send (zclient, command);
paul718e3742002-12-13 20:15:29 +0000885}
886
paul718e3742002-12-13 20:15:29 +0000887
888extern struct thread_master *master;
889
890static void
891zclient_event (enum event event, struct zclient *zclient)
892{
893 switch (event)
894 {
895 case ZCLIENT_SCHEDULE:
896 if (! zclient->t_connect)
897 zclient->t_connect =
898 thread_add_event (master, zclient_connect, zclient, 0);
899 break;
900 case ZCLIENT_CONNECT:
901 if (zclient->fail >= 10)
902 return;
903 if (zclient_debug)
ajs8ddca702004-12-07 18:53:52 +0000904 zlog_debug ("zclient connect schedule interval is %d",
paul718e3742002-12-13 20:15:29 +0000905 zclient->fail < 3 ? 10 : 60);
906 if (! zclient->t_connect)
907 zclient->t_connect =
908 thread_add_timer (master, zclient_connect, zclient,
909 zclient->fail < 3 ? 10 : 60);
910 break;
911 case ZCLIENT_READ:
912 zclient->t_read =
913 thread_add_read (master, zclient_read, zclient, zclient->sock);
914 break;
915 }
916}