Line data Source code
1 : /* Zebra's client library.
2 : * Copyright (C) 1999 Kunihiro Ishiguro
3 : * Copyright (C) 2005 Andrew J. Schorr
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"
27 : #include "buffer.h"
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"
35 :
36 : /* Zebra client events. */
37 : enum event {ZCLIENT_SCHEDULE, ZCLIENT_READ, ZCLIENT_CONNECT};
38 :
39 : /* Prototype for event manager. */
40 : static void zclient_event (enum event, struct zclient *);
41 :
42 : extern struct thread_master *master;
43 :
44 : char *zclient_serv_path = NULL;
45 :
46 : /* This file local debug flag. */
47 : int zclient_debug = 0;
48 :
49 : /* Allocate zclient structure. */
50 : struct zclient *
51 1 : zclient_new ()
52 : {
53 : struct zclient *zclient;
54 1 : zclient = XCALLOC (MTYPE_ZCLIENT, sizeof (struct zclient));
55 :
56 1 : zclient->ibuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
57 1 : zclient->obuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
58 1 : zclient->wb = buffer_new(0);
59 :
60 1 : return zclient;
61 : }
62 :
63 : /* This function is only called when exiting, because
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.
66 :
67 : Free zclient structure. */
68 : void
69 1 : zclient_free (struct zclient *zclient)
70 : {
71 1 : if (zclient->ibuf)
72 1 : stream_free(zclient->ibuf);
73 1 : if (zclient->obuf)
74 1 : stream_free(zclient->obuf);
75 1 : if (zclient->wb)
76 1 : buffer_free(zclient->wb);
77 :
78 1 : XFREE (MTYPE_ZCLIENT, zclient);
79 1 : }
80 :
81 : /* Initialize zebra client. Argument redist_default is unwanted
82 : redistribute route type. */
83 : void
84 0 : zclient_init (struct zclient *zclient, int redist_default)
85 : {
86 : int i;
87 :
88 : /* Enable zebra client connection by default. */
89 0 : zclient->enable = 1;
90 :
91 : /* Set -1 to the default socket value. */
92 0 : zclient->sock = -1;
93 :
94 : /* Clear redistribution flags. */
95 0 : for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
96 0 : zclient->redist[i] = 0;
97 :
98 : /* Set unwanted redistribute route. bgpd does not need BGP route
99 : redistribution. */
100 0 : zclient->redist_default = redist_default;
101 0 : zclient->redist[redist_default] = 1;
102 :
103 : /* Set default-information redistribute to zero. */
104 0 : zclient->default_information = 0;
105 :
106 : /* Schedule first zclient connection. */
107 0 : if (zclient_debug)
108 0 : zlog_debug ("zclient start scheduled");
109 :
110 0 : zclient_event (ZCLIENT_SCHEDULE, zclient);
111 0 : }
112 :
113 : /* Stop zebra client services. */
114 : void
115 0 : zclient_stop (struct zclient *zclient)
116 : {
117 0 : if (zclient_debug)
118 0 : zlog_debug ("zclient stopped");
119 :
120 : /* Stop threads. */
121 0 : THREAD_OFF(zclient->t_read);
122 0 : THREAD_OFF(zclient->t_connect);
123 0 : THREAD_OFF(zclient->t_write);
124 :
125 : /* Reset streams. */
126 0 : stream_reset(zclient->ibuf);
127 0 : stream_reset(zclient->obuf);
128 :
129 : /* Empty the write buffer. */
130 0 : buffer_reset(zclient->wb);
131 :
132 : /* Close socket. */
133 0 : if (zclient->sock >= 0)
134 : {
135 0 : close (zclient->sock);
136 0 : zclient->sock = -1;
137 : }
138 0 : zclient->fail = 0;
139 0 : }
140 :
141 : void
142 0 : zclient_reset (struct zclient *zclient)
143 : {
144 0 : zclient_stop (zclient);
145 0 : zclient_init (zclient, zclient->redist_default);
146 0 : }
147 :
148 : #ifdef HAVE_TCP_ZEBRA
149 :
150 : /* Make socket to zebra daemon. Return zebra socket. */
151 : static int
152 : zclient_socket(void)
153 : {
154 : int sock;
155 : int ret;
156 : struct sockaddr_in serv;
157 :
158 : /* We should think about IPv6 connection. */
159 : sock = socket (AF_INET, SOCK_STREAM, 0);
160 : if (sock < 0)
161 : return -1;
162 :
163 : /* Make server socket. */
164 : memset (&serv, 0, sizeof (struct sockaddr_in));
165 : serv.sin_family = AF_INET;
166 : serv.sin_port = htons (ZEBRA_PORT);
167 : #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
168 : serv.sin_len = sizeof (struct sockaddr_in);
169 : #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
170 : serv.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
171 :
172 : /* Connect to zebra. */
173 : ret = connect (sock, (struct sockaddr *) &serv, sizeof (serv));
174 : if (ret < 0)
175 : {
176 : close (sock);
177 : return -1;
178 : }
179 : return sock;
180 : }
181 :
182 : #else
183 :
184 : /* For sockaddr_un. */
185 : #include <sys/un.h>
186 :
187 : static int
188 0 : zclient_socket_un (const char *path)
189 : {
190 : int ret;
191 : int sock, len;
192 : struct sockaddr_un addr;
193 :
194 0 : sock = socket (AF_UNIX, SOCK_STREAM, 0);
195 0 : if (sock < 0)
196 0 : return -1;
197 :
198 : /* Make server socket. */
199 0 : memset (&addr, 0, sizeof (struct sockaddr_un));
200 0 : addr.sun_family = AF_UNIX;
201 0 : strncpy (addr.sun_path, path, strlen (path));
202 : #ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
203 : len = addr.sun_len = SUN_LEN(&addr);
204 : #else
205 0 : len = sizeof (addr.sun_family) + strlen (addr.sun_path);
206 : #endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
207 :
208 0 : ret = connect (sock, (struct sockaddr *) &addr, len);
209 0 : if (ret < 0)
210 : {
211 0 : close (sock);
212 0 : return -1;
213 : }
214 0 : return sock;
215 : }
216 :
217 : #endif /* HAVE_TCP_ZEBRA */
218 :
219 : /**
220 : * Connect to zebra daemon.
221 : * @param zclient a pointer to zclient structure
222 : * @return socket fd just to make sure that connection established
223 : * @see zclient_init
224 : * @see zclient_new
225 : */
226 : int
227 0 : zclient_socket_connect (struct zclient *zclient)
228 : {
229 : #ifdef HAVE_TCP_ZEBRA
230 : zclient->sock = zclient_socket ();
231 : #else
232 0 : zclient->sock = zclient_socket_un (zclient_serv_path ? zclient_serv_path : ZEBRA_SERV_PATH);
233 : #endif
234 0 : return zclient->sock;
235 : }
236 :
237 : static int
238 0 : zclient_failed(struct zclient *zclient)
239 : {
240 0 : zclient->fail++;
241 0 : zclient_stop(zclient);
242 0 : zclient_event(ZCLIENT_CONNECT, zclient);
243 0 : return -1;
244 : }
245 :
246 : static int
247 0 : zclient_flush_data(struct thread *thread)
248 : {
249 0 : struct zclient *zclient = THREAD_ARG(thread);
250 :
251 0 : zclient->t_write = NULL;
252 0 : if (zclient->sock < 0)
253 0 : return -1;
254 0 : switch (buffer_flush_available(zclient->wb, zclient->sock))
255 : {
256 : case BUFFER_ERROR:
257 0 : zlog_warn("%s: buffer_flush_available failed on zclient fd %d, closing",
258 : __func__, zclient->sock);
259 0 : return zclient_failed(zclient);
260 : break;
261 : case BUFFER_PENDING:
262 0 : zclient->t_write = thread_add_write(master, zclient_flush_data,
263 : zclient, zclient->sock);
264 0 : break;
265 : case BUFFER_EMPTY:
266 0 : break;
267 : }
268 0 : return 0;
269 : }
270 :
271 : int
272 0 : zclient_send_message(struct zclient *zclient)
273 : {
274 0 : if (zclient->sock < 0)
275 0 : return -1;
276 0 : switch (buffer_write(zclient->wb, zclient->sock, STREAM_DATA(zclient->obuf),
277 : stream_get_endp(zclient->obuf)))
278 : {
279 : case BUFFER_ERROR:
280 0 : zlog_warn("%s: buffer_write failed to zclient fd %d, closing",
281 : __func__, zclient->sock);
282 0 : return zclient_failed(zclient);
283 : break;
284 : case BUFFER_EMPTY:
285 0 : THREAD_OFF(zclient->t_write);
286 0 : break;
287 : case BUFFER_PENDING:
288 0 : THREAD_WRITE_ON(master, zclient->t_write,
289 : zclient_flush_data, zclient, zclient->sock);
290 0 : break;
291 : }
292 0 : return 0;
293 : }
294 :
295 : void
296 0 : zclient_create_header (struct stream *s, uint16_t command)
297 : {
298 : /* length placeholder, caller can update */
299 0 : stream_putw (s, ZEBRA_HEADER_SIZE);
300 0 : stream_putc (s, ZEBRA_HEADER_MARKER);
301 0 : stream_putc (s, ZSERV_VERSION);
302 0 : stream_putw (s, command);
303 0 : }
304 :
305 : /* Send simple Zebra message. */
306 : static int
307 0 : zebra_message_send (struct zclient *zclient, int command)
308 : {
309 : struct stream *s;
310 :
311 : /* Get zclient output buffer. */
312 0 : s = zclient->obuf;
313 0 : stream_reset (s);
314 :
315 : /* Send very simple command only Zebra message. */
316 0 : zclient_create_header (s, command);
317 :
318 0 : return zclient_send_message(zclient);
319 : }
320 :
321 : static int
322 0 : zebra_hello_send (struct zclient *zclient)
323 : {
324 : struct stream *s;
325 :
326 0 : if (zclient->redist_default)
327 : {
328 0 : s = zclient->obuf;
329 0 : stream_reset (s);
330 :
331 0 : zclient_create_header (s, ZEBRA_HELLO);
332 0 : stream_putc (s, zclient->redist_default);
333 0 : stream_putw_at (s, 0, stream_get_endp (s));
334 0 : return zclient_send_message(zclient);
335 : }
336 :
337 0 : return 0;
338 : }
339 :
340 : /* Make connection to zebra daemon. */
341 : int
342 0 : zclient_start (struct zclient *zclient)
343 : {
344 : int i;
345 :
346 0 : if (zclient_debug)
347 0 : zlog_debug ("zclient_start is called");
348 :
349 : /* zclient is disabled. */
350 0 : if (! zclient->enable)
351 0 : return 0;
352 :
353 : /* If already connected to the zebra. */
354 0 : if (zclient->sock >= 0)
355 0 : return 0;
356 :
357 : /* Check connect thread. */
358 0 : if (zclient->t_connect)
359 0 : return 0;
360 :
361 0 : if (zclient_socket_connect(zclient) < 0)
362 : {
363 0 : if (zclient_debug)
364 0 : zlog_debug ("zclient connection fail");
365 0 : zclient->fail++;
366 0 : zclient_event (ZCLIENT_CONNECT, zclient);
367 0 : return -1;
368 : }
369 :
370 0 : if (set_nonblocking(zclient->sock) < 0)
371 0 : zlog_warn("%s: set_nonblocking(%d) failed", __func__, zclient->sock);
372 :
373 : /* Clear fail count. */
374 0 : zclient->fail = 0;
375 0 : if (zclient_debug)
376 0 : zlog_debug ("zclient connect success with socket [%d]", zclient->sock);
377 :
378 : /* Create read thread. */
379 0 : zclient_event (ZCLIENT_READ, zclient);
380 :
381 0 : zebra_hello_send (zclient);
382 :
383 : /* We need router-id information. */
384 0 : zebra_message_send (zclient, ZEBRA_ROUTER_ID_ADD);
385 :
386 : /* We need interface information. */
387 0 : zebra_message_send (zclient, ZEBRA_INTERFACE_ADD);
388 :
389 : /* Flush all redistribute request. */
390 0 : for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
391 0 : if (i != zclient->redist_default && zclient->redist[i])
392 0 : zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, i);
393 :
394 : /* If default information is needed. */
395 0 : if (zclient->default_information)
396 0 : zebra_message_send (zclient, ZEBRA_REDISTRIBUTE_DEFAULT_ADD);
397 :
398 0 : return 0;
399 : }
400 :
401 : /* This function is a wrapper function for calling zclient_start from
402 : timer or event thread. */
403 : static int
404 0 : zclient_connect (struct thread *t)
405 : {
406 : struct zclient *zclient;
407 :
408 0 : zclient = THREAD_ARG (t);
409 0 : zclient->t_connect = NULL;
410 :
411 0 : if (zclient_debug)
412 0 : zlog_debug ("zclient_connect is called");
413 :
414 0 : return zclient_start (zclient);
415 : }
416 :
417 : /*
418 : * "xdr_encode"-like interface that allows daemon (client) to send
419 : * a message to zebra server for a route that needs to be
420 : * added/deleted to the kernel. Info about the route is specified
421 : * by the caller in a struct zapi_ipv4. zapi_ipv4_read() then writes
422 : * the info down the zclient socket using the stream_* functions.
423 : *
424 : * The corresponding read ("xdr_decode") function on the server
425 : * side is zread_ipv4_add()/zread_ipv4_delete().
426 : *
427 : * 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
428 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
429 : * | Length (2) | Command | Route Type |
430 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
431 : * | ZEBRA Flags | Message Flags | Prefix length |
432 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
433 : * | Destination IPv4 Prefix for route |
434 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
435 : * | Nexthop count |
436 : * +-+-+-+-+-+-+-+-+
437 : *
438 : *
439 : * A number of IPv4 nexthop(s) or nexthop interface index(es) are then
440 : * described, as per the Nexthop count. Each nexthop described as:
441 : *
442 : * +-+-+-+-+-+-+-+-+
443 : * | Nexthop Type | Set to one of ZEBRA_NEXTHOP_*
444 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
445 : * | IPv4 Nexthop address or Interface Index number |
446 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
447 : *
448 : * Alternatively, if the flags field has ZEBRA_FLAG_BLACKHOLE or
449 : * ZEBRA_FLAG_REJECT is set then Nexthop count is set to 1, then _no_
450 : * nexthop information is provided, and the message describes a prefix
451 : * to blackhole or reject route.
452 : *
453 : * If ZAPI_MESSAGE_DISTANCE is set, the distance value is written as a 1
454 : * byte value.
455 : *
456 : * If ZAPI_MESSAGE_METRIC is set, the metric value is written as an 8
457 : * byte value.
458 : *
459 : * XXX: No attention paid to alignment.
460 : */
461 : int
462 0 : zapi_ipv4_route (u_char cmd, struct zclient *zclient, struct prefix_ipv4 *p,
463 : struct zapi_ipv4 *api)
464 : {
465 : int i;
466 : int psize;
467 : struct stream *s;
468 :
469 : /* Reset stream. */
470 0 : s = zclient->obuf;
471 0 : stream_reset (s);
472 :
473 0 : zclient_create_header (s, cmd);
474 :
475 : /* Put type and nexthop. */
476 0 : stream_putc (s, api->type);
477 0 : stream_putc (s, api->flags);
478 0 : stream_putc (s, api->message);
479 0 : stream_putw (s, api->safi);
480 :
481 : /* Put prefix information. */
482 0 : psize = PSIZE (p->prefixlen);
483 0 : stream_putc (s, p->prefixlen);
484 0 : stream_write (s, (u_char *) & p->prefix, psize);
485 :
486 : /* Nexthop, ifindex, distance and metric information. */
487 0 : if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
488 : {
489 0 : if (CHECK_FLAG (api->flags, ZEBRA_FLAG_BLACKHOLE))
490 : {
491 0 : stream_putc (s, 1);
492 0 : stream_putc (s, ZEBRA_NEXTHOP_BLACKHOLE);
493 : /* XXX assert(api->nexthop_num == 0); */
494 : /* XXX assert(api->ifindex_num == 0); */
495 : }
496 : else
497 0 : stream_putc (s, api->nexthop_num + api->ifindex_num);
498 :
499 0 : for (i = 0; i < api->nexthop_num; i++)
500 : {
501 0 : stream_putc (s, ZEBRA_NEXTHOP_IPV4);
502 0 : stream_put_in_addr (s, api->nexthop[i]);
503 : }
504 0 : for (i = 0; i < api->ifindex_num; i++)
505 : {
506 0 : stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
507 0 : stream_putl (s, api->ifindex[i]);
508 : }
509 : }
510 :
511 0 : if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE))
512 0 : stream_putc (s, api->distance);
513 0 : if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC))
514 0 : stream_putl (s, api->metric);
515 :
516 : /* Put length at the first point of the stream. */
517 0 : stream_putw_at (s, 0, stream_get_endp (s));
518 :
519 0 : return zclient_send_message(zclient);
520 : }
521 :
522 : #ifdef HAVE_IPV6
523 : int
524 0 : zapi_ipv6_route (u_char cmd, struct zclient *zclient, struct prefix_ipv6 *p,
525 : struct prefix_ipv6 *src_p, struct zapi_ipv6 *api)
526 : {
527 : int i;
528 : int psize;
529 : struct stream *s;
530 :
531 : /* either we have !SRCPFX && src_p == NULL, or SRCPFX && src_p != NULL */
532 0 : assert (!(api->message & ZAPI_MESSAGE_SRCPFX) == !src_p);
533 :
534 : /* Reset stream. */
535 0 : s = zclient->obuf;
536 0 : stream_reset (s);
537 :
538 0 : zclient_create_header (s, cmd);
539 :
540 : /* Put type and nexthop. */
541 0 : stream_putc (s, api->type);
542 0 : stream_putc (s, api->flags);
543 0 : stream_putc (s, api->message);
544 0 : stream_putw (s, api->safi);
545 :
546 : /* Put prefix information. */
547 0 : psize = PSIZE (p->prefixlen);
548 0 : stream_putc (s, p->prefixlen);
549 0 : stream_write (s, (u_char *)&p->prefix, psize);
550 :
551 0 : if (CHECK_FLAG (api->message, ZAPI_MESSAGE_SRCPFX))
552 : {
553 0 : psize = PSIZE (src_p->prefixlen);
554 0 : stream_putc (s, src_p->prefixlen);
555 0 : stream_write (s, (u_char *)&src_p->prefix, psize);
556 : }
557 :
558 : /* Nexthop, ifindex, distance and metric information. */
559 0 : if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
560 : {
561 0 : stream_putc (s, api->nexthop_num + api->ifindex_num);
562 :
563 0 : for (i = 0; i < api->nexthop_num; i++)
564 : {
565 0 : stream_putc (s, ZEBRA_NEXTHOP_IPV6);
566 0 : stream_write (s, (u_char *)api->nexthop[i], 16);
567 : }
568 0 : for (i = 0; i < api->ifindex_num; i++)
569 : {
570 0 : stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
571 0 : stream_putl (s, api->ifindex[i]);
572 : }
573 : }
574 :
575 0 : if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE))
576 0 : stream_putc (s, api->distance);
577 0 : if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC))
578 0 : stream_putl (s, api->metric);
579 :
580 : /* Put length at the first point of the stream. */
581 0 : stream_putw_at (s, 0, stream_get_endp (s));
582 :
583 0 : return zclient_send_message(zclient);
584 : }
585 : #endif /* HAVE_IPV6 */
586 :
587 : /*
588 : * send a ZEBRA_REDISTRIBUTE_ADD or ZEBRA_REDISTRIBUTE_DELETE
589 : * for the route type (ZEBRA_ROUTE_KERNEL etc.). The zebra server will
590 : * then set/unset redist[type] in the client handle (a struct zserv) for the
591 : * sending client
592 : */
593 : int
594 0 : zebra_redistribute_send (int command, struct zclient *zclient, int type)
595 : {
596 : struct stream *s;
597 :
598 0 : s = zclient->obuf;
599 0 : stream_reset(s);
600 :
601 0 : zclient_create_header (s, command);
602 0 : stream_putc (s, type);
603 :
604 0 : stream_putw_at (s, 0, stream_get_endp (s));
605 :
606 0 : return zclient_send_message(zclient);
607 : }
608 :
609 : /* Router-id update from zebra daemon. */
610 : void
611 0 : zebra_router_id_update_read (struct stream *s, struct prefix *rid)
612 : {
613 : int plen;
614 :
615 : /* Fetch interface address. */
616 0 : rid->family = stream_getc (s);
617 :
618 0 : plen = prefix_blen (rid);
619 0 : stream_get (&rid->u.prefix, s, plen);
620 0 : rid->prefixlen = stream_getc (s);
621 0 : }
622 :
623 : /* Interface addition from zebra daemon. */
624 : /*
625 : * The format of the message sent with type ZEBRA_INTERFACE_ADD or
626 : * ZEBRA_INTERFACE_DELETE from zebra to the client is:
627 : * 0 1 2 3
628 : * 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
629 : * +-+-+-+-+-+-+-+-+
630 : * | type |
631 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
632 : * | ifname |
633 : * | |
634 : * | |
635 : * | |
636 : * | |
637 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
638 : * | ifindex |
639 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
640 : * | if_flags |
641 : * | |
642 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
643 : * | metric |
644 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
645 : * | ifmtu |
646 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
647 : * | ifmtu6 |
648 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
649 : * | bandwidth |
650 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
651 : * | sockaddr_dl |
652 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
653 : */
654 :
655 : struct interface *
656 0 : zebra_interface_add_read (struct stream *s)
657 : {
658 : struct interface *ifp;
659 : char ifname_tmp[INTERFACE_NAMSIZ];
660 :
661 : /* Read interface name. */
662 0 : stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
663 :
664 : /* Lookup/create interface by name. */
665 0 : ifp = if_get_by_name_len (ifname_tmp, strnlen(ifname_tmp, INTERFACE_NAMSIZ));
666 :
667 0 : zebra_interface_if_set_value (s, ifp);
668 :
669 0 : return ifp;
670 : }
671 :
672 : /*
673 : * Read interface up/down msg (ZEBRA_INTERFACE_UP/ZEBRA_INTERFACE_DOWN)
674 : * from zebra server. The format of this message is the same as
675 : * that sent for ZEBRA_INTERFACE_ADD/ZEBRA_INTERFACE_DELETE (see
676 : * comments for zebra_interface_add_read), except that no sockaddr_dl
677 : * is sent at the tail of the message.
678 : */
679 : struct interface *
680 0 : zebra_interface_state_read (struct stream *s)
681 : {
682 : struct interface *ifp;
683 : char ifname_tmp[INTERFACE_NAMSIZ];
684 :
685 : /* Read interface name. */
686 0 : stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
687 :
688 : /* Lookup this by interface index. */
689 0 : ifp = if_lookup_by_name_len (ifname_tmp,
690 : strnlen(ifname_tmp, INTERFACE_NAMSIZ));
691 :
692 : /* If such interface does not exist, indicate an error */
693 0 : if (! ifp)
694 0 : return NULL;
695 :
696 0 : zebra_interface_if_set_value (s, ifp);
697 :
698 0 : return ifp;
699 : }
700 :
701 : /*
702 : * format of message for address additon is:
703 : * 0
704 : * 0 1 2 3 4 5 6 7
705 : * +-+-+-+-+-+-+-+-+
706 : * | type | ZEBRA_INTERFACE_ADDRESS_ADD or
707 : * +-+-+-+-+-+-+-+-+ ZEBRA_INTERFACE_ADDRES_DELETE
708 : * | |
709 : * + +
710 : * | ifindex |
711 : * + +
712 : * | |
713 : * + +
714 : * | |
715 : * +-+-+-+-+-+-+-+-+
716 : * | ifc_flags | flags for connected address
717 : * +-+-+-+-+-+-+-+-+
718 : * | addr_family |
719 : * +-+-+-+-+-+-+-+-+
720 : * | addr... |
721 : * : :
722 : * | |
723 : * +-+-+-+-+-+-+-+-+
724 : * | addr_len | len of addr. E.g., addr_len = 4 for ipv4 addrs.
725 : * +-+-+-+-+-+-+-+-+
726 : * | daddr.. |
727 : * : :
728 : * | |
729 : * +-+-+-+-+-+-+-+-+
730 : *
731 : */
732 :
733 : void
734 0 : zebra_interface_if_set_value (struct stream *s, struct interface *ifp)
735 : {
736 : /* Read interface's index. */
737 0 : ifp->ifindex = stream_getl (s);
738 0 : ifp->status = stream_getc (s);
739 :
740 : /* Read interface's value. */
741 0 : ifp->flags = stream_getq (s);
742 0 : ifp->metric = stream_getl (s);
743 0 : ifp->mtu = stream_getl (s);
744 0 : ifp->mtu6 = stream_getl (s);
745 0 : ifp->bandwidth = stream_getl (s);
746 : #ifdef HAVE_STRUCT_SOCKADDR_DL
747 : stream_get (&ifp->sdl, s, sizeof (ifp->sdl_storage));
748 : #else
749 0 : ifp->hw_addr_len = stream_getl (s);
750 0 : if (ifp->hw_addr_len)
751 0 : stream_get (ifp->hw_addr, s, ifp->hw_addr_len);
752 : #endif /* HAVE_STRUCT_SOCKADDR_DL */
753 0 : }
754 :
755 : static int
756 0 : memconstant(const void *s, int c, size_t n)
757 : {
758 0 : const u_char *p = s;
759 :
760 0 : while (n-- > 0)
761 0 : if (*p++ != c)
762 0 : return 0;
763 0 : return 1;
764 : }
765 :
766 : struct connected *
767 0 : zebra_interface_address_read (int type, struct stream *s)
768 : {
769 : unsigned int ifindex;
770 : struct interface *ifp;
771 : struct connected *ifc;
772 : struct prefix p, d;
773 : int family;
774 : int plen;
775 : u_char ifc_flags;
776 :
777 0 : memset (&p, 0, sizeof(p));
778 0 : memset (&d, 0, sizeof(d));
779 :
780 : /* Get interface index. */
781 0 : ifindex = stream_getl (s);
782 :
783 : /* Lookup index. */
784 0 : ifp = if_lookup_by_index (ifindex);
785 0 : if (ifp == NULL)
786 : {
787 0 : zlog_warn ("zebra_interface_address_read(%s): "
788 : "Can't find interface by ifindex: %d ",
789 : (type == ZEBRA_INTERFACE_ADDRESS_ADD? "ADD" : "DELETE"),
790 : ifindex);
791 0 : return NULL;
792 : }
793 :
794 : /* Fetch flag. */
795 0 : ifc_flags = stream_getc (s);
796 :
797 : /* Fetch interface address. */
798 0 : family = p.family = stream_getc (s);
799 :
800 0 : plen = prefix_blen (&p);
801 0 : stream_get (&p.u.prefix, s, plen);
802 0 : p.prefixlen = stream_getc (s);
803 :
804 : /* Fetch destination address. */
805 0 : stream_get (&d.u.prefix, s, plen);
806 0 : d.family = family;
807 :
808 0 : if (type == ZEBRA_INTERFACE_ADDRESS_ADD)
809 : {
810 : /* N.B. NULL destination pointers are encoded as all zeroes */
811 0 : ifc = connected_add_by_prefix(ifp, &p,(memconstant(&d.u.prefix,0,plen) ?
812 : NULL : &d));
813 0 : if (ifc != NULL)
814 : {
815 0 : ifc->flags = ifc_flags;
816 0 : if (ifc->destination)
817 0 : ifc->destination->prefixlen = ifc->address->prefixlen;
818 : }
819 : }
820 : else
821 : {
822 0 : assert (type == ZEBRA_INTERFACE_ADDRESS_DELETE);
823 0 : ifc = connected_delete_by_prefix(ifp, &p);
824 : }
825 :
826 0 : return ifc;
827 : }
828 :
829 :
830 : /* Zebra client message read function. */
831 : static int
832 0 : zclient_read (struct thread *thread)
833 : {
834 : size_t already;
835 : uint16_t length, command;
836 : uint8_t marker, version;
837 : struct zclient *zclient;
838 :
839 : /* Get socket to zebra. */
840 0 : zclient = THREAD_ARG (thread);
841 0 : zclient->t_read = NULL;
842 :
843 : /* Read zebra header (if we don't have it already). */
844 0 : if ((already = stream_get_endp(zclient->ibuf)) < ZEBRA_HEADER_SIZE)
845 : {
846 : ssize_t nbyte;
847 0 : if (((nbyte = stream_read_try(zclient->ibuf, zclient->sock,
848 0 : ZEBRA_HEADER_SIZE-already)) == 0) ||
849 : (nbyte == -1))
850 : {
851 0 : if (zclient_debug)
852 0 : zlog_debug ("zclient connection closed socket [%d].", zclient->sock);
853 0 : return zclient_failed(zclient);
854 : }
855 0 : if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE-already))
856 : {
857 : /* Try again later. */
858 0 : zclient_event (ZCLIENT_READ, zclient);
859 0 : return 0;
860 : }
861 0 : already = ZEBRA_HEADER_SIZE;
862 : }
863 :
864 : /* Reset to read from the beginning of the incoming packet. */
865 0 : stream_set_getp(zclient->ibuf, 0);
866 :
867 : /* Fetch header values. */
868 0 : length = stream_getw (zclient->ibuf);
869 0 : marker = stream_getc (zclient->ibuf);
870 0 : version = stream_getc (zclient->ibuf);
871 0 : command = stream_getw (zclient->ibuf);
872 :
873 0 : if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION)
874 : {
875 0 : zlog_err("%s: socket %d version mismatch, marker %d, version %d",
876 : __func__, zclient->sock, marker, version);
877 0 : return zclient_failed(zclient);
878 : }
879 :
880 0 : if (length < ZEBRA_HEADER_SIZE)
881 : {
882 0 : zlog_err("%s: socket %d message length %u is less than %d ",
883 : __func__, zclient->sock, length, ZEBRA_HEADER_SIZE);
884 0 : return zclient_failed(zclient);
885 : }
886 :
887 : /* Length check. */
888 0 : if (length > STREAM_SIZE(zclient->ibuf))
889 : {
890 : struct stream *ns;
891 0 : zlog_warn("%s: message size %u exceeds buffer size %lu, expanding...",
892 0 : __func__, length, (u_long)STREAM_SIZE(zclient->ibuf));
893 0 : ns = stream_new(length);
894 0 : stream_copy(ns, zclient->ibuf);
895 0 : stream_free (zclient->ibuf);
896 0 : zclient->ibuf = ns;
897 : }
898 :
899 : /* Read rest of zebra packet. */
900 0 : if (already < length)
901 : {
902 : ssize_t nbyte;
903 0 : if (((nbyte = stream_read_try(zclient->ibuf, zclient->sock,
904 0 : length-already)) == 0) ||
905 : (nbyte == -1))
906 : {
907 0 : if (zclient_debug)
908 0 : zlog_debug("zclient connection closed socket [%d].", zclient->sock);
909 0 : return zclient_failed(zclient);
910 : }
911 0 : if (nbyte != (ssize_t)(length-already))
912 : {
913 : /* Try again later. */
914 0 : zclient_event (ZCLIENT_READ, zclient);
915 0 : return 0;
916 : }
917 : }
918 :
919 0 : length -= ZEBRA_HEADER_SIZE;
920 :
921 0 : if (zclient_debug)
922 0 : zlog_debug("zclient 0x%p command 0x%x \n", zclient, command);
923 :
924 0 : switch (command)
925 : {
926 : case ZEBRA_ROUTER_ID_UPDATE:
927 0 : if (zclient->router_id_update)
928 0 : (*zclient->router_id_update) (command, zclient, length);
929 0 : break;
930 : case ZEBRA_INTERFACE_ADD:
931 0 : if (zclient->interface_add)
932 0 : (*zclient->interface_add) (command, zclient, length);
933 0 : break;
934 : case ZEBRA_INTERFACE_DELETE:
935 0 : if (zclient->interface_delete)
936 0 : (*zclient->interface_delete) (command, zclient, length);
937 0 : break;
938 : case ZEBRA_INTERFACE_ADDRESS_ADD:
939 0 : if (zclient->interface_address_add)
940 0 : (*zclient->interface_address_add) (command, zclient, length);
941 0 : break;
942 : case ZEBRA_INTERFACE_ADDRESS_DELETE:
943 0 : if (zclient->interface_address_delete)
944 0 : (*zclient->interface_address_delete) (command, zclient, length);
945 0 : break;
946 : case ZEBRA_INTERFACE_UP:
947 0 : if (zclient->interface_up)
948 0 : (*zclient->interface_up) (command, zclient, length);
949 0 : break;
950 : case ZEBRA_INTERFACE_DOWN:
951 0 : if (zclient->interface_down)
952 0 : (*zclient->interface_down) (command, zclient, length);
953 0 : break;
954 : case ZEBRA_IPV4_ROUTE_ADD:
955 0 : if (zclient->ipv4_route_add)
956 0 : (*zclient->ipv4_route_add) (command, zclient, length);
957 0 : break;
958 : case ZEBRA_IPV4_ROUTE_DELETE:
959 0 : if (zclient->ipv4_route_delete)
960 0 : (*zclient->ipv4_route_delete) (command, zclient, length);
961 0 : break;
962 : case ZEBRA_IPV6_ROUTE_ADD:
963 0 : if (zclient->ipv6_route_add)
964 0 : (*zclient->ipv6_route_add) (command, zclient, length);
965 0 : break;
966 : case ZEBRA_IPV6_ROUTE_DELETE:
967 0 : if (zclient->ipv6_route_delete)
968 0 : (*zclient->ipv6_route_delete) (command, zclient, length);
969 0 : break;
970 : default:
971 0 : break;
972 : }
973 :
974 0 : if (zclient->sock < 0)
975 : /* Connection was closed during packet processing. */
976 0 : return -1;
977 :
978 : /* Register read thread. */
979 0 : stream_reset(zclient->ibuf);
980 0 : zclient_event (ZCLIENT_READ, zclient);
981 :
982 0 : return 0;
983 : }
984 :
985 : void
986 0 : zclient_redistribute (int command, struct zclient *zclient, int type)
987 : {
988 :
989 0 : if (command == ZEBRA_REDISTRIBUTE_ADD)
990 : {
991 0 : if (zclient->redist[type])
992 0 : return;
993 0 : zclient->redist[type] = 1;
994 : }
995 : else
996 : {
997 0 : if (!zclient->redist[type])
998 0 : return;
999 0 : zclient->redist[type] = 0;
1000 : }
1001 :
1002 0 : if (zclient->sock > 0)
1003 0 : zebra_redistribute_send (command, zclient, type);
1004 : }
1005 :
1006 :
1007 : void
1008 0 : zclient_redistribute_default (int command, struct zclient *zclient)
1009 : {
1010 :
1011 0 : if (command == ZEBRA_REDISTRIBUTE_DEFAULT_ADD)
1012 : {
1013 0 : if (zclient->default_information)
1014 0 : return;
1015 0 : zclient->default_information = 1;
1016 : }
1017 : else
1018 : {
1019 0 : if (!zclient->default_information)
1020 0 : return;
1021 0 : zclient->default_information = 0;
1022 : }
1023 :
1024 0 : if (zclient->sock > 0)
1025 0 : zebra_message_send (zclient, command);
1026 : }
1027 :
1028 : static void
1029 0 : zclient_event (enum event event, struct zclient *zclient)
1030 : {
1031 0 : switch (event)
1032 : {
1033 : case ZCLIENT_SCHEDULE:
1034 0 : if (! zclient->t_connect)
1035 0 : zclient->t_connect =
1036 0 : thread_add_event (master, zclient_connect, zclient, 0);
1037 0 : break;
1038 : case ZCLIENT_CONNECT:
1039 0 : if (zclient->fail >= 10)
1040 0 : return;
1041 0 : if (zclient_debug)
1042 0 : zlog_debug ("zclient connect schedule interval is %d",
1043 0 : zclient->fail < 3 ? 10 : 60);
1044 0 : if (! zclient->t_connect)
1045 0 : zclient->t_connect =
1046 0 : thread_add_timer (master, zclient_connect, zclient,
1047 : zclient->fail < 3 ? 10 : 60);
1048 0 : break;
1049 : case ZCLIENT_READ:
1050 0 : zclient->t_read =
1051 0 : thread_add_read (master, zclient_read, zclient, zclient->sock);
1052 0 : break;
1053 : }
1054 : }
1055 :
1056 : void
1057 0 : zclient_serv_path_set (char *path)
1058 : {
1059 : struct stat sb;
1060 :
1061 : /* reset */
1062 0 : zclient_serv_path = NULL;
1063 :
1064 : /* test if `path' is socket. don't set it otherwise. */
1065 0 : if (stat(path, &sb) == -1)
1066 : {
1067 0 : zlog_warn ("%s: zebra socket `%s' does not exist", __func__, path);
1068 0 : return;
1069 : }
1070 :
1071 0 : if ((sb.st_mode & S_IFMT) != S_IFSOCK)
1072 : {
1073 0 : zlog_warn ("%s: `%s' is not unix socket, sir", __func__, path);
1074 0 : return;
1075 : }
1076 :
1077 : /* it seems that path is unix socket */
1078 0 : zclient_serv_path = path;
1079 : }
1080 :
|