Line data Source code
1 : /* Zebra daemon server routine.
2 : * Copyright (C) 1997, 98, 99 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 it
7 : * under the terms of the GNU General Public License as published by the
8 : * Free Software Foundation; either version 2, or (at your option) any
9 : * 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,
19 : * Boston, MA 02111-1307, USA.
20 : */
21 :
22 : #include <zebra.h>
23 :
24 : #include "prefix.h"
25 : #include "command.h"
26 : #include "if.h"
27 : #include "thread.h"
28 : #include "stream.h"
29 : #include "memory.h"
30 : #include "table.h"
31 : #include "rib.h"
32 : #include "network.h"
33 : #include "sockunion.h"
34 : #include "log.h"
35 : #include "zclient.h"
36 : #include "privs.h"
37 : #include "network.h"
38 : #include "buffer.h"
39 :
40 : #include "zebra/zserv.h"
41 : #include "zebra/router-id.h"
42 : #include "zebra/redistribute.h"
43 : #include "zebra/debug.h"
44 : #include "zebra/ipforward.h"
45 :
46 : /* Event list of zebra. */
47 : enum event { ZEBRA_SERV, ZEBRA_READ, ZEBRA_WRITE };
48 :
49 : extern struct zebra_t zebrad;
50 :
51 : static void zebra_event (enum event event, int sock, struct zserv *client);
52 :
53 : extern struct zebra_privs_t zserv_privs;
54 :
55 : static void zebra_client_close (struct zserv *client);
56 :
57 : static int
58 0 : zserv_delayed_close(struct thread *thread)
59 : {
60 0 : struct zserv *client = THREAD_ARG(thread);
61 :
62 0 : client->t_suicide = NULL;
63 0 : zebra_client_close(client);
64 0 : return 0;
65 : }
66 :
67 : /* When client connects, it sends hello message
68 : * with promise to send zebra routes of specific type.
69 : * Zebra stores a socket fd of the client into
70 : * this array. And use it to clean up routes that
71 : * client didn't remove for some reasons after closing
72 : * connection.
73 : */
74 : static int route_type_oaths[ZEBRA_ROUTE_MAX];
75 :
76 : static int
77 0 : zserv_flush_data(struct thread *thread)
78 : {
79 0 : struct zserv *client = THREAD_ARG(thread);
80 :
81 0 : client->t_write = NULL;
82 0 : if (client->t_suicide)
83 : {
84 0 : zebra_client_close(client);
85 0 : return -1;
86 : }
87 0 : switch (buffer_flush_available(client->wb, client->sock))
88 : {
89 : case BUFFER_ERROR:
90 0 : zlog_warn("%s: buffer_flush_available failed on zserv client fd %d, "
91 : "closing", __func__, client->sock);
92 0 : zebra_client_close(client);
93 0 : break;
94 : case BUFFER_PENDING:
95 0 : client->t_write = thread_add_write(zebrad.master, zserv_flush_data,
96 : client, client->sock);
97 0 : break;
98 : case BUFFER_EMPTY:
99 0 : break;
100 : }
101 0 : return 0;
102 : }
103 :
104 : static int
105 0 : zebra_server_send_message(struct zserv *client)
106 : {
107 0 : if (client->t_suicide)
108 0 : return -1;
109 0 : switch (buffer_write(client->wb, client->sock, STREAM_DATA(client->obuf),
110 : stream_get_endp(client->obuf)))
111 : {
112 : case BUFFER_ERROR:
113 0 : zlog_warn("%s: buffer_write failed to zserv client fd %d, closing",
114 : __func__, client->sock);
115 : /* Schedule a delayed close since many of the functions that call this
116 : one do not check the return code. They do not allow for the
117 : possibility that an I/O error may have caused the client to be
118 : deleted. */
119 0 : client->t_suicide = thread_add_event(zebrad.master, zserv_delayed_close,
120 : client, 0);
121 0 : return -1;
122 : case BUFFER_EMPTY:
123 0 : THREAD_OFF(client->t_write);
124 0 : break;
125 : case BUFFER_PENDING:
126 0 : THREAD_WRITE_ON(zebrad.master, client->t_write,
127 : zserv_flush_data, client, client->sock);
128 0 : break;
129 : }
130 0 : return 0;
131 : }
132 :
133 : static void
134 0 : zserv_create_header (struct stream *s, uint16_t cmd)
135 : {
136 : /* length placeholder, caller can update */
137 0 : stream_putw (s, ZEBRA_HEADER_SIZE);
138 0 : stream_putc (s, ZEBRA_HEADER_MARKER);
139 0 : stream_putc (s, ZSERV_VERSION);
140 0 : stream_putw (s, cmd);
141 0 : }
142 :
143 : static void
144 0 : zserv_encode_interface (struct stream *s, struct interface *ifp)
145 : {
146 : /* Interface information. */
147 0 : stream_put (s, ifp->name, INTERFACE_NAMSIZ);
148 0 : stream_putl (s, ifp->ifindex);
149 0 : stream_putc (s, ifp->status);
150 0 : stream_putq (s, ifp->flags);
151 0 : stream_putl (s, ifp->metric);
152 0 : stream_putl (s, ifp->mtu);
153 0 : stream_putl (s, ifp->mtu6);
154 0 : stream_putl (s, ifp->bandwidth);
155 : #ifdef HAVE_STRUCT_SOCKADDR_DL
156 : stream_put (s, &ifp->sdl, sizeof (ifp->sdl_storage));
157 : #else
158 0 : stream_putl (s, ifp->hw_addr_len);
159 0 : if (ifp->hw_addr_len)
160 0 : stream_put (s, ifp->hw_addr, ifp->hw_addr_len);
161 : #endif /* HAVE_STRUCT_SOCKADDR_DL */
162 :
163 : /* Write packet size. */
164 0 : stream_putw_at (s, 0, stream_get_endp (s));
165 0 : }
166 :
167 : /* Interface is added. Send ZEBRA_INTERFACE_ADD to client. */
168 : /*
169 : * This function is called in the following situations:
170 : * - in response to a 3-byte ZEBRA_INTERFACE_ADD request
171 : * from the client.
172 : * - at startup, when zebra figures out the available interfaces
173 : * - when an interface is added (where support for
174 : * RTM_IFANNOUNCE or AF_NETLINK sockets is available), or when
175 : * an interface is marked IFF_UP (i.e., an RTM_IFINFO message is
176 : * received)
177 : */
178 : int
179 0 : zsend_interface_add (struct zserv *client, struct interface *ifp)
180 : {
181 : struct stream *s;
182 :
183 : /* Check this client need interface information. */
184 0 : if (! client->ifinfo)
185 0 : return 0;
186 :
187 0 : s = client->obuf;
188 0 : stream_reset (s);
189 :
190 0 : zserv_create_header (s, ZEBRA_INTERFACE_ADD);
191 0 : zserv_encode_interface (s, ifp);
192 :
193 0 : return zebra_server_send_message(client);
194 : }
195 :
196 : /* Interface deletion from zebra daemon. */
197 : int
198 0 : zsend_interface_delete (struct zserv *client, struct interface *ifp)
199 : {
200 : struct stream *s;
201 :
202 : /* Check this client need interface information. */
203 0 : if (! client->ifinfo)
204 0 : return 0;
205 :
206 0 : s = client->obuf;
207 0 : stream_reset (s);
208 :
209 0 : zserv_create_header (s, ZEBRA_INTERFACE_DELETE);
210 0 : zserv_encode_interface (s, ifp);
211 :
212 0 : return zebra_server_send_message (client);
213 : }
214 :
215 : /* Interface address is added/deleted. Send ZEBRA_INTERFACE_ADDRESS_ADD or
216 : * ZEBRA_INTERFACE_ADDRESS_DELETE to the client.
217 : *
218 : * A ZEBRA_INTERFACE_ADDRESS_ADD is sent in the following situations:
219 : * - in response to a 3-byte ZEBRA_INTERFACE_ADD request
220 : * from the client, after the ZEBRA_INTERFACE_ADD has been
221 : * sent from zebra to the client
222 : * - redistribute new address info to all clients in the following situations
223 : * - at startup, when zebra figures out the available interfaces
224 : * - when an interface is added (where support for
225 : * RTM_IFANNOUNCE or AF_NETLINK sockets is available), or when
226 : * an interface is marked IFF_UP (i.e., an RTM_IFINFO message is
227 : * received)
228 : * - for the vty commands "ip address A.B.C.D/M [<secondary>|<label LINE>]"
229 : * and "no bandwidth <1-10000000>", "ipv6 address X:X::X:X/M"
230 : * - when an RTM_NEWADDR message is received from the kernel,
231 : *
232 : * The call tree that triggers ZEBRA_INTERFACE_ADDRESS_DELETE:
233 : *
234 : * zsend_interface_address(DELETE)
235 : * ^
236 : * |
237 : * zebra_interface_address_delete_update
238 : * ^ ^ ^
239 : * | | if_delete_update
240 : * | |
241 : * ip_address_uninstall connected_delete_ipv4
242 : * [ipv6_addresss_uninstall] [connected_delete_ipv6]
243 : * ^ ^
244 : * | |
245 : * | RTM_NEWADDR on routing/netlink socket
246 : * |
247 : * vty commands:
248 : * "no ip address A.B.C.D/M [label LINE]"
249 : * "no ip address A.B.C.D/M secondary"
250 : * ["no ipv6 address X:X::X:X/M"]
251 : *
252 : */
253 : int
254 0 : zsend_interface_address (int cmd, struct zserv *client,
255 : struct interface *ifp, struct connected *ifc)
256 : {
257 : int blen;
258 : struct stream *s;
259 : struct prefix *p;
260 :
261 : /* Check this client need interface information. */
262 0 : if (! client->ifinfo)
263 0 : return 0;
264 :
265 0 : s = client->obuf;
266 0 : stream_reset (s);
267 :
268 0 : zserv_create_header (s, cmd);
269 0 : stream_putl (s, ifp->ifindex);
270 :
271 : /* Interface address flag. */
272 0 : stream_putc (s, ifc->flags);
273 :
274 : /* Prefix information. */
275 0 : p = ifc->address;
276 0 : stream_putc (s, p->family);
277 0 : blen = prefix_blen (p);
278 0 : stream_put (s, &p->u.prefix, blen);
279 :
280 : /*
281 : * XXX gnu version does not send prefixlen for ZEBRA_INTERFACE_ADDRESS_DELETE
282 : * but zebra_interface_address_delete_read() in the gnu version
283 : * expects to find it
284 : */
285 0 : stream_putc (s, p->prefixlen);
286 :
287 : /* Destination. */
288 0 : p = ifc->destination;
289 0 : if (p)
290 0 : stream_put (s, &p->u.prefix, blen);
291 : else
292 0 : stream_put (s, NULL, blen);
293 :
294 : /* Write packet size. */
295 0 : stream_putw_at (s, 0, stream_get_endp (s));
296 :
297 0 : return zebra_server_send_message(client);
298 : }
299 :
300 : /*
301 : * The cmd passed to zsend_interface_update may be ZEBRA_INTERFACE_UP or
302 : * ZEBRA_INTERFACE_DOWN.
303 : *
304 : * The ZEBRA_INTERFACE_UP message is sent from the zebra server to
305 : * the clients in one of 2 situations:
306 : * - an if_up is detected e.g., as a result of an RTM_IFINFO message
307 : * - a vty command modifying the bandwidth of an interface is received.
308 : * The ZEBRA_INTERFACE_DOWN message is sent when an if_down is detected.
309 : */
310 : int
311 0 : zsend_interface_update (int cmd, struct zserv *client, struct interface *ifp)
312 : {
313 : struct stream *s;
314 :
315 : /* Check this client need interface information. */
316 0 : if (! client->ifinfo)
317 0 : return 0;
318 :
319 0 : s = client->obuf;
320 0 : stream_reset (s);
321 :
322 0 : zserv_create_header (s, cmd);
323 0 : zserv_encode_interface (s, ifp);
324 :
325 0 : return zebra_server_send_message(client);
326 : }
327 :
328 : /*
329 : * The zebra server sends the clients a ZEBRA_IPV4_ROUTE_ADD or a
330 : * ZEBRA_IPV6_ROUTE_ADD via zsend_route_multipath in the following
331 : * situations:
332 : * - when the client starts up, and requests default information
333 : * by sending a ZEBRA_REDISTRIBUTE_DEFAULT_ADD to the zebra server, in the
334 : * - case of rip, ripngd, ospfd and ospf6d, when the client sends a
335 : * ZEBRA_REDISTRIBUTE_ADD as a result of the "redistribute" vty cmd,
336 : * - when the zebra server redistributes routes after it updates its rib
337 : *
338 : * The zebra server sends clients a ZEBRA_IPV4_ROUTE_DELETE or a
339 : * ZEBRA_IPV6_ROUTE_DELETE via zsend_route_multipath when:
340 : * - a "ip route" or "ipv6 route" vty command is issued, a prefix is
341 : * - deleted from zebra's rib, and this info
342 : * has to be redistributed to the clients
343 : *
344 : * XXX The ZEBRA_IPV*_ROUTE_ADD message is also sent by the client to the
345 : * zebra server when the client wants to tell the zebra server to add a
346 : * route to the kernel (zapi_ipv4_add etc. ). Since it's essentially the
347 : * same message being sent back and forth, this function and
348 : * zapi_ipv{4,6}_{add, delete} should be re-written to avoid code
349 : * duplication.
350 : */
351 : int
352 0 : zsend_route_multipath (int cmd, struct zserv *client, struct prefix *p,
353 : struct prefix *src_p, struct rib *rib)
354 : {
355 : int psize;
356 : struct stream *s;
357 : struct nexthop *nexthop;
358 0 : unsigned long nhnummark = 0, messmark = 0;
359 0 : int nhnum = 0;
360 0 : u_char zapi_flags = 0;
361 :
362 0 : s = client->obuf;
363 0 : stream_reset (s);
364 :
365 0 : zserv_create_header (s, cmd);
366 :
367 : /* Put type and nexthop. */
368 0 : stream_putc (s, rib->type);
369 0 : stream_putc (s, rib->flags);
370 :
371 : /* marker for message flags field */
372 0 : messmark = stream_get_endp (s);
373 0 : stream_putc (s, 0);
374 :
375 : /* Prefix. */
376 0 : psize = PSIZE (p->prefixlen);
377 0 : stream_putc (s, p->prefixlen);
378 0 : stream_write (s, (u_char *) & p->u.prefix, psize);
379 :
380 0 : if (src_p)
381 : {
382 0 : SET_FLAG (zapi_flags, ZAPI_MESSAGE_SRCPFX);
383 0 : psize = PSIZE (src_p->prefixlen);
384 0 : stream_putc (s, src_p->prefixlen);
385 0 : stream_write (s, (u_char *) & src_p->u.prefix, psize);
386 : }
387 :
388 : /*
389 : * XXX The message format sent by zebra below does not match the format
390 : * of the corresponding message expected by the zebra server
391 : * itself (e.g., see zread_ipv4_add). The nexthop_num is not set correctly,
392 : * (is there a bug on the client side if more than one segment is sent?)
393 : * nexthop ZEBRA_NEXTHOP_IPV4 is never set, ZEBRA_NEXTHOP_IFINDEX
394 : * is hard-coded.
395 : */
396 : /* Nexthop */
397 :
398 0 : for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
399 : {
400 0 : if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)
401 0 : || nexthop_has_fib_child(nexthop))
402 : {
403 0 : SET_FLAG (zapi_flags, ZAPI_MESSAGE_NEXTHOP);
404 0 : SET_FLAG (zapi_flags, ZAPI_MESSAGE_IFINDEX);
405 :
406 0 : if (nhnummark == 0)
407 : {
408 0 : nhnummark = stream_get_endp (s);
409 0 : stream_putc (s, 1); /* placeholder */
410 : }
411 :
412 0 : nhnum++;
413 :
414 0 : switch(nexthop->type)
415 : {
416 : case NEXTHOP_TYPE_IPV4:
417 : case NEXTHOP_TYPE_IPV4_IFINDEX:
418 0 : stream_put_in_addr (s, &nexthop->gate.ipv4);
419 0 : break;
420 : #ifdef HAVE_IPV6
421 : case NEXTHOP_TYPE_IPV6:
422 : case NEXTHOP_TYPE_IPV6_IFINDEX:
423 : case NEXTHOP_TYPE_IPV6_IFNAME:
424 0 : stream_write (s, (u_char *) &nexthop->gate.ipv6, 16);
425 0 : break;
426 : #endif
427 : default:
428 0 : if (cmd == ZEBRA_IPV4_ROUTE_ADD
429 0 : || cmd == ZEBRA_IPV4_ROUTE_DELETE)
430 0 : {
431 : struct in_addr empty;
432 0 : memset (&empty, 0, sizeof (struct in_addr));
433 0 : stream_write (s, (u_char *) &empty, IPV4_MAX_BYTELEN);
434 : }
435 : else
436 : {
437 : struct in6_addr empty;
438 0 : memset (&empty, 0, sizeof (struct in6_addr));
439 0 : stream_write (s, (u_char *) &empty, IPV6_MAX_BYTELEN);
440 : }
441 : }
442 :
443 : /* Interface index. */
444 0 : stream_putc (s, 1);
445 0 : stream_putl (s, nexthop->ifindex);
446 :
447 0 : break;
448 : }
449 : }
450 :
451 : /* Metric */
452 0 : if (cmd == ZEBRA_IPV4_ROUTE_ADD || cmd == ZEBRA_IPV6_ROUTE_ADD)
453 : {
454 0 : SET_FLAG (zapi_flags, ZAPI_MESSAGE_DISTANCE);
455 0 : stream_putc (s, rib->distance);
456 0 : SET_FLAG (zapi_flags, ZAPI_MESSAGE_METRIC);
457 0 : stream_putl (s, rib->metric);
458 : }
459 :
460 : /* write real message flags value */
461 0 : stream_putc_at (s, messmark, zapi_flags);
462 :
463 : /* Write next-hop number */
464 0 : if (nhnummark)
465 0 : stream_putc_at (s, nhnummark, nhnum);
466 :
467 : /* Write packet size. */
468 0 : stream_putw_at (s, 0, stream_get_endp (s));
469 :
470 0 : return zebra_server_send_message(client);
471 : }
472 :
473 : #ifdef HAVE_IPV6
474 : static int
475 0 : zsend_ipv6_nexthop_lookup (struct zserv *client, struct in6_addr *addr)
476 : {
477 : struct stream *s;
478 : struct rib *rib;
479 : unsigned long nump;
480 : u_char num;
481 : struct nexthop *nexthop;
482 :
483 : /* Lookup nexthop. */
484 0 : rib = rib_match_ipv6 (addr);
485 :
486 : /* Get output stream. */
487 0 : s = client->obuf;
488 0 : stream_reset (s);
489 :
490 : /* Fill in result. */
491 0 : zserv_create_header (s, ZEBRA_IPV6_NEXTHOP_LOOKUP);
492 0 : stream_put (s, &addr, 16);
493 :
494 0 : if (rib)
495 : {
496 0 : stream_putl (s, rib->metric);
497 0 : num = 0;
498 0 : nump = stream_get_endp(s);
499 0 : stream_putc (s, 0);
500 : /* Only non-recursive routes are elegible to resolve nexthop we
501 : * are looking up. Therefore, we will just iterate over the top
502 : * chain of nexthops. */
503 0 : for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
504 0 : if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
505 : {
506 0 : stream_putc (s, nexthop->type);
507 0 : switch (nexthop->type)
508 : {
509 : case ZEBRA_NEXTHOP_IPV6:
510 0 : stream_put (s, &nexthop->gate.ipv6, 16);
511 0 : break;
512 : case ZEBRA_NEXTHOP_IPV6_IFINDEX:
513 : case ZEBRA_NEXTHOP_IPV6_IFNAME:
514 0 : stream_put (s, &nexthop->gate.ipv6, 16);
515 0 : stream_putl (s, nexthop->ifindex);
516 0 : break;
517 : case ZEBRA_NEXTHOP_IFINDEX:
518 : case ZEBRA_NEXTHOP_IFNAME:
519 0 : stream_putl (s, nexthop->ifindex);
520 0 : break;
521 : default:
522 : /* do nothing */
523 0 : break;
524 : }
525 0 : num++;
526 : }
527 0 : stream_putc_at (s, nump, num);
528 : }
529 : else
530 : {
531 0 : stream_putl (s, 0);
532 0 : stream_putc (s, 0);
533 : }
534 :
535 0 : stream_putw_at (s, 0, stream_get_endp (s));
536 :
537 0 : return zebra_server_send_message(client);
538 : }
539 : #endif /* HAVE_IPV6 */
540 :
541 : static int
542 0 : zsend_ipv4_nexthop_lookup (struct zserv *client, struct in_addr addr)
543 : {
544 : struct stream *s;
545 : struct rib *rib;
546 : unsigned long nump;
547 : u_char num;
548 : struct nexthop *nexthop;
549 :
550 : /* Lookup nexthop. */
551 0 : rib = rib_match_ipv4 (addr);
552 :
553 : /* Get output stream. */
554 0 : s = client->obuf;
555 0 : stream_reset (s);
556 :
557 : /* Fill in result. */
558 0 : zserv_create_header (s, ZEBRA_IPV4_NEXTHOP_LOOKUP);
559 0 : stream_put_in_addr (s, &addr);
560 :
561 0 : if (rib)
562 : {
563 0 : if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
564 0 : zlog_debug("%s: Matching rib entry found.", __func__);
565 0 : stream_putl (s, rib->metric);
566 0 : num = 0;
567 0 : nump = stream_get_endp(s);
568 0 : stream_putc (s, 0);
569 : /* Only non-recursive routes are elegible to resolve the nexthop we
570 : * are looking up. Therefore, we will just iterate over the top
571 : * chain of nexthops. */
572 0 : for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
573 0 : if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
574 : {
575 0 : stream_putc (s, nexthop->type);
576 0 : switch (nexthop->type)
577 : {
578 : case ZEBRA_NEXTHOP_IPV4:
579 0 : stream_put_in_addr (s, &nexthop->gate.ipv4);
580 0 : break;
581 : case ZEBRA_NEXTHOP_IPV4_IFINDEX:
582 0 : stream_put_in_addr (s, &nexthop->gate.ipv4);
583 0 : stream_putl (s, nexthop->ifindex);
584 0 : break;
585 : case ZEBRA_NEXTHOP_IFINDEX:
586 : case ZEBRA_NEXTHOP_IFNAME:
587 0 : stream_putl (s, nexthop->ifindex);
588 0 : break;
589 : default:
590 : /* do nothing */
591 0 : break;
592 : }
593 0 : num++;
594 : }
595 0 : stream_putc_at (s, nump, num);
596 : }
597 : else
598 : {
599 0 : if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
600 0 : zlog_debug("%s: No matching rib entry found.", __func__);
601 0 : stream_putl (s, 0);
602 0 : stream_putc (s, 0);
603 : }
604 :
605 0 : stream_putw_at (s, 0, stream_get_endp (s));
606 :
607 0 : return zebra_server_send_message(client);
608 : }
609 :
610 : static int
611 0 : zsend_ipv4_import_lookup (struct zserv *client, struct prefix_ipv4 *p)
612 : {
613 : struct stream *s;
614 : struct rib *rib;
615 : unsigned long nump;
616 : u_char num;
617 : struct nexthop *nexthop;
618 :
619 : /* Lookup nexthop. */
620 0 : rib = rib_lookup_ipv4 (p);
621 :
622 : /* Get output stream. */
623 0 : s = client->obuf;
624 0 : stream_reset (s);
625 :
626 : /* Fill in result. */
627 0 : zserv_create_header (s, ZEBRA_IPV4_IMPORT_LOOKUP);
628 0 : stream_put_in_addr (s, &p->prefix);
629 :
630 0 : if (rib)
631 : {
632 0 : stream_putl (s, rib->metric);
633 0 : num = 0;
634 0 : nump = stream_get_endp(s);
635 0 : stream_putc (s, 0);
636 0 : for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
637 0 : if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)
638 0 : || nexthop_has_fib_child(nexthop))
639 : {
640 0 : stream_putc (s, nexthop->type);
641 0 : switch (nexthop->type)
642 : {
643 : case ZEBRA_NEXTHOP_IPV4:
644 0 : stream_put_in_addr (s, &nexthop->gate.ipv4);
645 0 : break;
646 : case ZEBRA_NEXTHOP_IPV4_IFINDEX:
647 0 : stream_put_in_addr (s, &nexthop->gate.ipv4);
648 0 : stream_putl (s, nexthop->ifindex);
649 0 : break;
650 : case ZEBRA_NEXTHOP_IFINDEX:
651 : case ZEBRA_NEXTHOP_IFNAME:
652 0 : stream_putl (s, nexthop->ifindex);
653 0 : break;
654 : default:
655 : /* do nothing */
656 0 : break;
657 : }
658 0 : num++;
659 : }
660 0 : stream_putc_at (s, nump, num);
661 : }
662 : else
663 : {
664 0 : stream_putl (s, 0);
665 0 : stream_putc (s, 0);
666 : }
667 :
668 0 : stream_putw_at (s, 0, stream_get_endp (s));
669 :
670 0 : return zebra_server_send_message(client);
671 : }
672 :
673 : /* Router-id is updated. Send ZEBRA_ROUTER_ID_ADD to client. */
674 : int
675 0 : zsend_router_id_update (struct zserv *client, struct prefix *p)
676 : {
677 : struct stream *s;
678 : int blen;
679 :
680 : /* Check this client need interface information. */
681 0 : if (!client->ridinfo)
682 0 : return 0;
683 :
684 0 : s = client->obuf;
685 0 : stream_reset (s);
686 :
687 : /* Message type. */
688 0 : zserv_create_header (s, ZEBRA_ROUTER_ID_UPDATE);
689 :
690 : /* Prefix information. */
691 0 : stream_putc (s, p->family);
692 0 : blen = prefix_blen (p);
693 0 : stream_put (s, &p->u.prefix, blen);
694 0 : stream_putc (s, p->prefixlen);
695 :
696 : /* Write packet size. */
697 0 : stream_putw_at (s, 0, stream_get_endp (s));
698 :
699 0 : return zebra_server_send_message(client);
700 : }
701 :
702 : /* Register zebra server interface information. Send current all
703 : interface and address information. */
704 : static int
705 0 : zread_interface_add (struct zserv *client, u_short length)
706 : {
707 : struct listnode *ifnode, *ifnnode;
708 : struct listnode *cnode, *cnnode;
709 : struct interface *ifp;
710 : struct connected *c;
711 :
712 : /* Interface information is needed. */
713 0 : client->ifinfo = 1;
714 :
715 0 : for (ALL_LIST_ELEMENTS (iflist, ifnode, ifnnode, ifp))
716 : {
717 : /* Skip pseudo interface. */
718 0 : if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
719 0 : continue;
720 :
721 0 : if (zsend_interface_add (client, ifp) < 0)
722 0 : return -1;
723 :
724 0 : for (ALL_LIST_ELEMENTS (ifp->connected, cnode, cnnode, c))
725 : {
726 0 : if (CHECK_FLAG (c->conf, ZEBRA_IFC_REAL) &&
727 0 : (zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_ADD, client,
728 : ifp, c) < 0))
729 0 : return -1;
730 : }
731 : }
732 0 : return 0;
733 : }
734 :
735 : /* Unregister zebra server interface information. */
736 : static int
737 0 : zread_interface_delete (struct zserv *client, u_short length)
738 : {
739 0 : client->ifinfo = 0;
740 0 : return 0;
741 : }
742 :
743 : /* This function support multiple nexthop. */
744 : /*
745 : * Parse the ZEBRA_IPV4_ROUTE_ADD sent from client. Update rib and
746 : * add kernel route.
747 : */
748 : static int
749 60 : zread_ipv4_add (struct zserv *client, u_short length)
750 : {
751 : int i;
752 : struct rib *rib;
753 : struct prefix_ipv4 p;
754 : u_char message;
755 : struct in_addr nexthop;
756 : u_char nexthop_num;
757 : u_char nexthop_type;
758 : struct stream *s;
759 : unsigned int ifindex;
760 : u_char ifname_len;
761 : safi_t safi;
762 :
763 :
764 : /* Get input stream. */
765 60 : s = client->ibuf;
766 :
767 : /* Allocate new rib. */
768 60 : rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
769 :
770 : /* Type, flags, message. */
771 60 : rib->type = stream_getc (s);
772 60 : rib->flags = stream_getc (s);
773 60 : message = stream_getc (s);
774 60 : safi = stream_getw (s);
775 60 : rib->uptime = time (NULL);
776 :
777 : /* IPv4 prefix. */
778 60 : memset (&p, 0, sizeof (struct prefix_ipv4));
779 60 : p.family = AF_INET;
780 60 : p.prefixlen = stream_getc (s);
781 60 : stream_get (&p.prefix, s, PSIZE (p.prefixlen));
782 :
783 : /* Nexthop parse. */
784 60 : if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP))
785 : {
786 60 : nexthop_num = stream_getc (s);
787 :
788 259 : for (i = 0; i < nexthop_num; i++)
789 : {
790 199 : nexthop_type = stream_getc (s);
791 :
792 199 : switch (nexthop_type)
793 : {
794 : case ZEBRA_NEXTHOP_IFINDEX:
795 22 : ifindex = stream_getl (s);
796 22 : nexthop_ifindex_add (rib, ifindex);
797 22 : break;
798 : case ZEBRA_NEXTHOP_IFNAME:
799 0 : ifname_len = stream_getc (s);
800 0 : stream_forward_getp (s, ifname_len);
801 0 : break;
802 : case ZEBRA_NEXTHOP_IPV4:
803 168 : nexthop.s_addr = stream_get_ipv4 (s);
804 168 : nexthop_ipv4_add (rib, &nexthop, NULL);
805 168 : break;
806 : case ZEBRA_NEXTHOP_IPV4_IFINDEX:
807 9 : nexthop.s_addr = stream_get_ipv4 (s);
808 9 : ifindex = stream_getl (s);
809 9 : nexthop_ipv4_ifindex_add (rib, &nexthop, NULL, ifindex);
810 9 : break;
811 : case ZEBRA_NEXTHOP_IPV6:
812 0 : stream_forward_getp (s, IPV6_MAX_BYTELEN);
813 0 : break;
814 : case ZEBRA_NEXTHOP_BLACKHOLE:
815 0 : nexthop_blackhole_add (rib);
816 0 : break;
817 : }
818 : }
819 : }
820 :
821 : /* Distance. */
822 60 : if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
823 0 : rib->distance = stream_getc (s);
824 :
825 : /* Metric. */
826 60 : if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
827 0 : rib->metric = stream_getl (s);
828 :
829 : /* Table */
830 60 : rib->table=zebrad.rtm_table_default;
831 60 : rib_add_ipv4_multipath (&p, rib, safi);
832 60 : return 0;
833 : }
834 :
835 : /* Zebra server IPv4 prefix delete function. */
836 : static int
837 33 : zread_ipv4_delete (struct zserv *client, u_short length)
838 : {
839 : int i;
840 : struct stream *s;
841 : struct zapi_ipv4 api;
842 : struct in_addr nexthop, *nexthop_p;
843 : unsigned long ifindex;
844 : struct prefix_ipv4 p;
845 : u_char nexthop_num;
846 : u_char nexthop_type;
847 : u_char ifname_len;
848 :
849 33 : s = client->ibuf;
850 33 : ifindex = 0;
851 33 : nexthop.s_addr = 0;
852 33 : nexthop_p = NULL;
853 :
854 : /* Type, flags, message. */
855 33 : api.type = stream_getc (s);
856 33 : api.flags = stream_getc (s);
857 33 : api.message = stream_getc (s);
858 33 : api.safi = stream_getw (s);
859 :
860 : /* IPv4 prefix. */
861 33 : memset (&p, 0, sizeof (struct prefix_ipv4));
862 33 : p.family = AF_INET;
863 33 : p.prefixlen = stream_getc (s);
864 33 : stream_get (&p.prefix, s, PSIZE (p.prefixlen));
865 :
866 : /* Nexthop, ifindex, distance, metric. */
867 33 : if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
868 : {
869 33 : nexthop_num = stream_getc (s);
870 :
871 199 : for (i = 0; i < nexthop_num; i++)
872 : {
873 166 : nexthop_type = stream_getc (s);
874 :
875 166 : switch (nexthop_type)
876 : {
877 : case ZEBRA_NEXTHOP_IFINDEX:
878 8 : ifindex = stream_getl (s);
879 8 : break;
880 : case ZEBRA_NEXTHOP_IFNAME:
881 0 : ifname_len = stream_getc (s);
882 0 : stream_forward_getp (s, ifname_len);
883 0 : break;
884 : case ZEBRA_NEXTHOP_IPV4:
885 153 : nexthop.s_addr = stream_get_ipv4 (s);
886 153 : nexthop_p = &nexthop;
887 153 : break;
888 : case ZEBRA_NEXTHOP_IPV4_IFINDEX:
889 5 : nexthop.s_addr = stream_get_ipv4 (s);
890 5 : nexthop_p = &nexthop;
891 5 : ifindex = stream_getl (s);
892 5 : break;
893 : case ZEBRA_NEXTHOP_IPV6:
894 0 : stream_forward_getp (s, IPV6_MAX_BYTELEN);
895 0 : break;
896 : }
897 : }
898 : }
899 :
900 : /* Distance. */
901 33 : if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
902 0 : api.distance = stream_getc (s);
903 : else
904 33 : api.distance = 0;
905 :
906 : /* Metric. */
907 33 : if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
908 0 : api.metric = stream_getl (s);
909 : else
910 33 : api.metric = 0;
911 :
912 66 : rib_delete_ipv4 (api.type, api.flags, &p, nexthop_p, ifindex,
913 66 : client->rtm_table, api.safi);
914 33 : return 0;
915 : }
916 :
917 : /* Nexthop lookup for IPv4. */
918 : static int
919 0 : zread_ipv4_nexthop_lookup (struct zserv *client, u_short length)
920 : {
921 : struct in_addr addr;
922 : char buf[BUFSIZ];
923 :
924 0 : addr.s_addr = stream_get_ipv4 (client->ibuf);
925 0 : if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
926 0 : zlog_debug("%s: looking up %s", __func__,
927 : inet_ntop (AF_INET, &addr, buf, BUFSIZ));
928 0 : return zsend_ipv4_nexthop_lookup (client, addr);
929 : }
930 :
931 : /* Nexthop lookup for IPv4. */
932 : static int
933 0 : zread_ipv4_import_lookup (struct zserv *client, u_short length)
934 : {
935 : struct prefix_ipv4 p;
936 :
937 0 : p.family = AF_INET;
938 0 : p.prefixlen = stream_getc (client->ibuf);
939 0 : p.prefix.s_addr = stream_get_ipv4 (client->ibuf);
940 :
941 0 : return zsend_ipv4_import_lookup (client, &p);
942 : }
943 :
944 : #ifdef HAVE_IPV6
945 : /* Zebra server IPv6 prefix add function. */
946 : static int
947 28 : zread_ipv6_add (struct zserv *client, u_short length)
948 : {
949 : int i;
950 : struct stream *s;
951 : struct zapi_ipv6 api;
952 : struct in6_addr nexthop;
953 : unsigned long ifindex;
954 : struct prefix_ipv6 p, src_p, *src_pp;
955 :
956 28 : s = client->ibuf;
957 28 : ifindex = 0;
958 28 : memset (&nexthop, 0, sizeof (struct in6_addr));
959 :
960 : /* Type, flags, message. */
961 28 : api.type = stream_getc (s);
962 28 : api.flags = stream_getc (s);
963 28 : api.message = stream_getc (s);
964 28 : api.safi = stream_getw (s);
965 :
966 : /* IPv4 prefix. */
967 28 : memset (&p, 0, sizeof (struct prefix_ipv6));
968 28 : p.family = AF_INET6;
969 28 : p.prefixlen = stream_getc (s);
970 28 : stream_get (&p.prefix, s, PSIZE (p.prefixlen));
971 :
972 28 : if (CHECK_FLAG (api.message, ZAPI_MESSAGE_SRCPFX))
973 : {
974 6 : memset (&src_p, 0, sizeof (struct prefix_ipv6));
975 6 : src_p.family = AF_INET6;
976 6 : src_p.prefixlen = stream_getc (s);
977 6 : stream_get (&src_p.prefix, s, PSIZE (src_p.prefixlen));
978 6 : src_pp = &src_p;
979 : }
980 : else
981 22 : src_pp = NULL;
982 :
983 : /* Nexthop, ifindex, distance, metric. */
984 28 : if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
985 : {
986 : u_char nexthop_type;
987 :
988 28 : api.nexthop_num = stream_getc (s);
989 64 : for (i = 0; i < api.nexthop_num; i++)
990 : {
991 36 : nexthop_type = stream_getc (s);
992 :
993 36 : switch (nexthop_type)
994 : {
995 : case ZEBRA_NEXTHOP_IPV6:
996 22 : stream_get (&nexthop, s, 16);
997 22 : break;
998 : case ZEBRA_NEXTHOP_IFINDEX:
999 14 : ifindex = stream_getl (s);
1000 14 : break;
1001 : }
1002 : }
1003 : }
1004 :
1005 28 : if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
1006 0 : api.distance = stream_getc (s);
1007 : else
1008 28 : api.distance = 0;
1009 :
1010 28 : if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
1011 0 : api.metric = stream_getl (s);
1012 : else
1013 28 : api.metric = 0;
1014 :
1015 28 : if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
1016 12 : rib_add_ipv6 (api.type, api.flags, &p, src_pp, NULL, ifindex, zebrad.rtm_table_default, api.metric,
1017 12 : api.distance, api.safi);
1018 : else
1019 44 : rib_add_ipv6 (api.type, api.flags, &p, src_pp, &nexthop, ifindex, zebrad.rtm_table_default, api.metric,
1020 44 : api.distance, api.safi);
1021 28 : return 0;
1022 : }
1023 :
1024 : /* Zebra server IPv6 prefix delete function. */
1025 : static int
1026 14 : zread_ipv6_delete (struct zserv *client, u_short length)
1027 : {
1028 : int i;
1029 : struct stream *s;
1030 : struct zapi_ipv6 api;
1031 : struct in6_addr nexthop;
1032 : unsigned long ifindex;
1033 : struct prefix_ipv6 p, src_p, *src_pp;
1034 :
1035 14 : s = client->ibuf;
1036 14 : ifindex = 0;
1037 14 : memset (&nexthop, 0, sizeof (struct in6_addr));
1038 :
1039 : /* Type, flags, message. */
1040 14 : api.type = stream_getc (s);
1041 14 : api.flags = stream_getc (s);
1042 14 : api.message = stream_getc (s);
1043 14 : api.safi = stream_getw (s);
1044 :
1045 : /* IPv4 prefix. */
1046 14 : memset (&p, 0, sizeof (struct prefix_ipv6));
1047 14 : p.family = AF_INET6;
1048 14 : p.prefixlen = stream_getc (s);
1049 14 : stream_get (&p.prefix, s, PSIZE (p.prefixlen));
1050 :
1051 14 : if (CHECK_FLAG (api.message, ZAPI_MESSAGE_SRCPFX))
1052 : {
1053 5 : memset (&src_p, 0, sizeof (struct prefix_ipv6));
1054 5 : src_p.family = AF_INET6;
1055 5 : src_p.prefixlen = stream_getc (s);
1056 5 : stream_get (&src_p.prefix, s, PSIZE (src_p.prefixlen));
1057 5 : src_pp = &src_p;
1058 : }
1059 : else
1060 9 : src_pp = NULL;
1061 :
1062 : /* Nexthop, ifindex, distance, metric. */
1063 14 : if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
1064 : {
1065 : u_char nexthop_type;
1066 :
1067 14 : api.nexthop_num = stream_getc (s);
1068 32 : for (i = 0; i < api.nexthop_num; i++)
1069 : {
1070 18 : nexthop_type = stream_getc (s);
1071 :
1072 18 : switch (nexthop_type)
1073 : {
1074 : case ZEBRA_NEXTHOP_IPV6:
1075 12 : stream_get (&nexthop, s, 16);
1076 12 : break;
1077 : case ZEBRA_NEXTHOP_IFINDEX:
1078 6 : ifindex = stream_getl (s);
1079 6 : break;
1080 : }
1081 : }
1082 : }
1083 :
1084 14 : if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
1085 0 : api.distance = stream_getc (s);
1086 : else
1087 14 : api.distance = 0;
1088 14 : if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
1089 0 : api.metric = stream_getl (s);
1090 : else
1091 14 : api.metric = 0;
1092 :
1093 14 : if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
1094 2 : rib_delete_ipv6 (api.type, api.flags, &p, src_pp, NULL, ifindex, client->rtm_table, api.safi);
1095 : else
1096 12 : rib_delete_ipv6 (api.type, api.flags, &p, src_pp, &nexthop, ifindex, client->rtm_table, api.safi);
1097 14 : return 0;
1098 : }
1099 :
1100 : static int
1101 0 : zread_ipv6_nexthop_lookup (struct zserv *client, u_short length)
1102 : {
1103 : struct in6_addr addr;
1104 : char buf[BUFSIZ];
1105 :
1106 0 : stream_get (&addr, client->ibuf, 16);
1107 0 : if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
1108 0 : zlog_debug("%s: looking up %s", __func__,
1109 : inet_ntop (AF_INET6, &addr, buf, BUFSIZ));
1110 :
1111 0 : return zsend_ipv6_nexthop_lookup (client, &addr);
1112 : }
1113 : #endif /* HAVE_IPV6 */
1114 :
1115 : /* Register zebra server router-id information. Send current router-id */
1116 : static int
1117 0 : zread_router_id_add (struct zserv *client, u_short length)
1118 : {
1119 : struct prefix p;
1120 :
1121 : /* Router-id information is needed. */
1122 0 : client->ridinfo = 1;
1123 :
1124 0 : router_id_get (&p);
1125 :
1126 0 : return zsend_router_id_update (client,&p);
1127 : }
1128 :
1129 : /* Unregister zebra server router-id information. */
1130 : static int
1131 0 : zread_router_id_delete (struct zserv *client, u_short length)
1132 : {
1133 0 : client->ridinfo = 0;
1134 0 : return 0;
1135 : }
1136 :
1137 : /* Tie up route-type and client->sock */
1138 : static void
1139 52 : zread_hello (struct zserv *client)
1140 : {
1141 : /* type of protocol (lib/zebra.h) */
1142 : u_char proto;
1143 52 : proto = stream_getc (client->ibuf);
1144 :
1145 : /* accept only dynamic routing protocols */
1146 52 : if ((proto < ZEBRA_ROUTE_MAX)
1147 52 : && (proto > ZEBRA_ROUTE_STATIC))
1148 : {
1149 52 : zlog_notice ("client %d says hello and bids fair to announce only %s routes",
1150 : client->sock, zebra_route_string(proto));
1151 :
1152 : /* if route-type was binded by other client */
1153 52 : if (route_type_oaths[proto])
1154 0 : zlog_warn ("sender of %s routes changed %c->%c",
1155 : zebra_route_string(proto), route_type_oaths[proto],
1156 : client->sock);
1157 :
1158 52 : route_type_oaths[proto] = client->sock;
1159 : }
1160 52 : }
1161 :
1162 : /* If client sent routes of specific type, zebra removes it
1163 : * and returns number of deleted routes.
1164 : */
1165 : static void
1166 43 : zebra_score_rib (int client_sock)
1167 : {
1168 : int i;
1169 :
1170 150 : for (i = ZEBRA_ROUTE_RIP; i < ZEBRA_ROUTE_MAX; i++)
1171 150 : if (client_sock == route_type_oaths[i])
1172 : {
1173 43 : zlog_notice ("client %d disconnected. %lu %s routes removed from the rib",
1174 : client_sock, rib_score_proto (i), zebra_route_string (i));
1175 43 : route_type_oaths[i] = 0;
1176 43 : break;
1177 : }
1178 43 : }
1179 :
1180 : /* Close zebra client. */
1181 : static void
1182 43 : zebra_client_close (struct zserv *client)
1183 : {
1184 : /* Close file descriptor. */
1185 43 : if (client->sock)
1186 : {
1187 43 : close (client->sock);
1188 43 : zebra_score_rib (client->sock);
1189 43 : client->sock = -1;
1190 : }
1191 :
1192 : /* Free stream buffers. */
1193 43 : if (client->ibuf)
1194 43 : stream_free (client->ibuf);
1195 43 : if (client->obuf)
1196 43 : stream_free (client->obuf);
1197 43 : if (client->wb)
1198 43 : buffer_free(client->wb);
1199 :
1200 : /* Release threads. */
1201 43 : if (client->t_read)
1202 0 : thread_cancel (client->t_read);
1203 43 : if (client->t_write)
1204 0 : thread_cancel (client->t_write);
1205 43 : if (client->t_suicide)
1206 0 : thread_cancel (client->t_suicide);
1207 :
1208 : /* Free client structure. */
1209 43 : listnode_delete (zebrad.client_list, client);
1210 43 : XFREE (0, client);
1211 43 : }
1212 :
1213 : /* Make new client. */
1214 : static void
1215 52 : zebra_client_create (int sock)
1216 : {
1217 : struct zserv *client;
1218 :
1219 52 : client = XCALLOC (0, sizeof (struct zserv));
1220 :
1221 : /* Make client input/output buffer. */
1222 52 : client->sock = sock;
1223 52 : client->ibuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
1224 52 : client->obuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
1225 52 : client->wb = buffer_new(0);
1226 :
1227 : /* Set table number. */
1228 52 : client->rtm_table = zebrad.rtm_table_default;
1229 :
1230 : /* Add this client to linked list. */
1231 52 : listnode_add (zebrad.client_list, client);
1232 :
1233 : /* Make new read thread. */
1234 52 : zebra_event (ZEBRA_READ, sock, client);
1235 52 : }
1236 :
1237 : /* Handler of zebra service request. */
1238 : static int
1239 230 : zebra_client_read (struct thread *thread)
1240 : {
1241 : int sock;
1242 : struct zserv *client;
1243 : size_t already;
1244 : uint16_t length, command;
1245 : uint8_t marker, version;
1246 :
1247 : /* Get thread data. Reset reading thread because I'm running. */
1248 230 : sock = THREAD_FD (thread);
1249 230 : client = THREAD_ARG (thread);
1250 230 : client->t_read = NULL;
1251 :
1252 230 : if (client->t_suicide)
1253 : {
1254 0 : zebra_client_close(client);
1255 0 : return -1;
1256 : }
1257 :
1258 : /* Read length and command (if we don't have it already). */
1259 230 : if ((already = stream_get_endp(client->ibuf)) < ZEBRA_HEADER_SIZE)
1260 : {
1261 : ssize_t nbyte;
1262 230 : if (((nbyte = stream_read_try (client->ibuf, sock,
1263 187 : ZEBRA_HEADER_SIZE-already)) == 0) ||
1264 : (nbyte == -1))
1265 : {
1266 43 : if (IS_ZEBRA_DEBUG_EVENT)
1267 43 : zlog_debug ("connection closed socket [%d]", sock);
1268 43 : zebra_client_close (client);
1269 43 : return -1;
1270 : }
1271 187 : if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE-already))
1272 : {
1273 : /* Try again later. */
1274 0 : zebra_event (ZEBRA_READ, sock, client);
1275 0 : return 0;
1276 : }
1277 187 : already = ZEBRA_HEADER_SIZE;
1278 : }
1279 :
1280 : /* Reset to read from the beginning of the incoming packet. */
1281 187 : stream_set_getp(client->ibuf, 0);
1282 :
1283 : /* Fetch header values */
1284 187 : length = stream_getw (client->ibuf);
1285 187 : marker = stream_getc (client->ibuf);
1286 187 : version = stream_getc (client->ibuf);
1287 187 : command = stream_getw (client->ibuf);
1288 :
1289 187 : if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION)
1290 : {
1291 0 : zlog_err("%s: socket %d version mismatch, marker %d, version %d",
1292 : __func__, sock, marker, version);
1293 0 : zebra_client_close (client);
1294 0 : return -1;
1295 : }
1296 187 : if (length < ZEBRA_HEADER_SIZE)
1297 : {
1298 0 : zlog_warn("%s: socket %d message length %u is less than header size %d",
1299 : __func__, sock, length, ZEBRA_HEADER_SIZE);
1300 0 : zebra_client_close (client);
1301 0 : return -1;
1302 : }
1303 187 : if (length > STREAM_SIZE(client->ibuf))
1304 : {
1305 0 : zlog_warn("%s: socket %d message length %u exceeds buffer size %lu",
1306 0 : __func__, sock, length, (u_long)STREAM_SIZE(client->ibuf));
1307 0 : zebra_client_close (client);
1308 0 : return -1;
1309 : }
1310 :
1311 : /* Read rest of data. */
1312 187 : if (already < length)
1313 : {
1314 : ssize_t nbyte;
1315 187 : if (((nbyte = stream_read_try (client->ibuf, sock,
1316 187 : length-already)) == 0) ||
1317 : (nbyte == -1))
1318 : {
1319 0 : if (IS_ZEBRA_DEBUG_EVENT)
1320 0 : zlog_debug ("connection closed [%d] when reading zebra data", sock);
1321 0 : zebra_client_close (client);
1322 0 : return -1;
1323 : }
1324 187 : if (nbyte != (ssize_t)(length-already))
1325 : {
1326 : /* Try again later. */
1327 0 : zebra_event (ZEBRA_READ, sock, client);
1328 0 : return 0;
1329 : }
1330 : }
1331 :
1332 187 : length -= ZEBRA_HEADER_SIZE;
1333 :
1334 : /* Debug packet information. */
1335 187 : if (IS_ZEBRA_DEBUG_EVENT)
1336 187 : zlog_debug ("zebra message comes from socket [%d]", sock);
1337 :
1338 187 : if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
1339 187 : zlog_debug ("zebra message received [%s] %d",
1340 : zserv_command_string (command), length);
1341 :
1342 187 : switch (command)
1343 : {
1344 : case ZEBRA_ROUTER_ID_ADD:
1345 0 : zread_router_id_add (client, length);
1346 0 : break;
1347 : case ZEBRA_ROUTER_ID_DELETE:
1348 0 : zread_router_id_delete (client, length);
1349 0 : break;
1350 : case ZEBRA_INTERFACE_ADD:
1351 0 : zread_interface_add (client, length);
1352 0 : break;
1353 : case ZEBRA_INTERFACE_DELETE:
1354 0 : zread_interface_delete (client, length);
1355 0 : break;
1356 : case ZEBRA_IPV4_ROUTE_ADD:
1357 60 : zread_ipv4_add (client, length);
1358 60 : break;
1359 : case ZEBRA_IPV4_ROUTE_DELETE:
1360 33 : zread_ipv4_delete (client, length);
1361 33 : break;
1362 : #ifdef HAVE_IPV6
1363 : case ZEBRA_IPV6_ROUTE_ADD:
1364 28 : zread_ipv6_add (client, length);
1365 28 : break;
1366 : case ZEBRA_IPV6_ROUTE_DELETE:
1367 14 : zread_ipv6_delete (client, length);
1368 14 : break;
1369 : #endif /* HAVE_IPV6 */
1370 : case ZEBRA_REDISTRIBUTE_ADD:
1371 0 : zebra_redistribute_add (command, client, length);
1372 0 : break;
1373 : case ZEBRA_REDISTRIBUTE_DELETE:
1374 0 : zebra_redistribute_delete (command, client, length);
1375 0 : break;
1376 : case ZEBRA_REDISTRIBUTE_DEFAULT_ADD:
1377 0 : zebra_redistribute_default_add (command, client, length);
1378 0 : break;
1379 : case ZEBRA_REDISTRIBUTE_DEFAULT_DELETE:
1380 0 : zebra_redistribute_default_delete (command, client, length);
1381 0 : break;
1382 : case ZEBRA_IPV4_NEXTHOP_LOOKUP:
1383 0 : zread_ipv4_nexthop_lookup (client, length);
1384 0 : break;
1385 : #ifdef HAVE_IPV6
1386 : case ZEBRA_IPV6_NEXTHOP_LOOKUP:
1387 0 : zread_ipv6_nexthop_lookup (client, length);
1388 0 : break;
1389 : #endif /* HAVE_IPV6 */
1390 : case ZEBRA_IPV4_IMPORT_LOOKUP:
1391 0 : zread_ipv4_import_lookup (client, length);
1392 0 : break;
1393 : case ZEBRA_HELLO:
1394 52 : zread_hello (client);
1395 52 : break;
1396 : default:
1397 0 : zlog_info ("Zebra received unknown command %d", command);
1398 0 : break;
1399 : }
1400 :
1401 187 : if (client->t_suicide)
1402 : {
1403 : /* No need to wait for thread callback, just kill immediately. */
1404 0 : zebra_client_close(client);
1405 0 : return -1;
1406 : }
1407 :
1408 187 : stream_reset (client->ibuf);
1409 187 : zebra_event (ZEBRA_READ, sock, client);
1410 187 : return 0;
1411 : }
1412 :
1413 :
1414 : /* Accept code of zebra server socket. */
1415 : static int
1416 52 : zebra_accept (struct thread *thread)
1417 : {
1418 : int accept_sock;
1419 : int client_sock;
1420 : struct sockaddr_in client;
1421 : socklen_t len;
1422 :
1423 52 : accept_sock = THREAD_FD (thread);
1424 :
1425 : /* Reregister myself. */
1426 52 : zebra_event (ZEBRA_SERV, accept_sock, NULL);
1427 :
1428 52 : len = sizeof (struct sockaddr_in);
1429 52 : client_sock = accept (accept_sock, (struct sockaddr *) &client, &len);
1430 :
1431 52 : if (client_sock < 0)
1432 : {
1433 0 : zlog_warn ("Can't accept zebra socket: %s", safe_strerror (errno));
1434 0 : return -1;
1435 : }
1436 :
1437 : /* Make client socket non-blocking. */
1438 52 : set_nonblocking(client_sock);
1439 :
1440 : /* Create new zebra client. */
1441 52 : zebra_client_create (client_sock);
1442 :
1443 52 : return 0;
1444 : }
1445 :
1446 : #ifdef HAVE_TCP_ZEBRA
1447 : /* Make zebra's server socket. */
1448 : static void
1449 : zebra_serv ()
1450 : {
1451 : int ret;
1452 : int accept_sock;
1453 : struct sockaddr_in addr;
1454 :
1455 : accept_sock = socket (AF_INET, SOCK_STREAM, 0);
1456 :
1457 : if (accept_sock < 0)
1458 : {
1459 : zlog_warn ("Can't create zserv stream socket: %s",
1460 : safe_strerror (errno));
1461 : zlog_warn ("zebra can't provice full functionality due to above error");
1462 : return;
1463 : }
1464 :
1465 : memset (&route_type_oaths, 0, sizeof (route_type_oaths));
1466 : memset (&addr, 0, sizeof (struct sockaddr_in));
1467 : addr.sin_family = AF_INET;
1468 : addr.sin_port = htons (ZEBRA_PORT);
1469 : #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1470 : addr.sin_len = sizeof (struct sockaddr_in);
1471 : #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1472 : addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
1473 :
1474 : sockopt_reuseaddr (accept_sock);
1475 : sockopt_reuseport (accept_sock);
1476 :
1477 : if ( zserv_privs.change(ZPRIVS_RAISE) )
1478 : zlog (NULL, LOG_ERR, "Can't raise privileges");
1479 :
1480 : ret = bind (accept_sock, (struct sockaddr *)&addr,
1481 : sizeof (struct sockaddr_in));
1482 : if (ret < 0)
1483 : {
1484 : zlog_warn ("Can't bind to stream socket: %s",
1485 : safe_strerror (errno));
1486 : zlog_warn ("zebra can't provice full functionality due to above error");
1487 : close (accept_sock); /* Avoid sd leak. */
1488 : return;
1489 : }
1490 :
1491 : if ( zserv_privs.change(ZPRIVS_LOWER) )
1492 : zlog (NULL, LOG_ERR, "Can't lower privileges");
1493 :
1494 : ret = listen (accept_sock, 1);
1495 : if (ret < 0)
1496 : {
1497 : zlog_warn ("Can't listen to stream socket: %s",
1498 : safe_strerror (errno));
1499 : zlog_warn ("zebra can't provice full functionality due to above error");
1500 : close (accept_sock); /* Avoid sd leak. */
1501 : return;
1502 : }
1503 :
1504 : zebra_event (ZEBRA_SERV, accept_sock, NULL);
1505 : }
1506 : #endif /* HAVE_TCP_ZEBRA */
1507 :
1508 : /* For sockaddr_un. */
1509 : #include <sys/un.h>
1510 :
1511 : /* zebra server UNIX domain socket. */
1512 : static void
1513 45 : zebra_serv_un (const char *path)
1514 : {
1515 : int ret;
1516 : int sock, len;
1517 : struct sockaddr_un serv;
1518 : mode_t old_mask;
1519 :
1520 : /* First of all, unlink existing socket */
1521 45 : unlink (path);
1522 :
1523 : /* Set umask */
1524 45 : old_mask = umask (0077);
1525 :
1526 : /* Make UNIX domain socket. */
1527 45 : sock = socket (AF_UNIX, SOCK_STREAM, 0);
1528 45 : if (sock < 0)
1529 : {
1530 0 : zlog_warn ("Can't create zserv unix socket: %s",
1531 0 : safe_strerror (errno));
1532 0 : zlog_warn ("zebra can't provide full functionality due to above error");
1533 0 : return;
1534 : }
1535 :
1536 45 : memset (&route_type_oaths, 0, sizeof (route_type_oaths));
1537 :
1538 : /* Make server socket. */
1539 45 : memset (&serv, 0, sizeof (struct sockaddr_un));
1540 45 : serv.sun_family = AF_UNIX;
1541 45 : strncpy (serv.sun_path, path, strlen (path));
1542 : #ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
1543 : len = serv.sun_len = SUN_LEN(&serv);
1544 : #else
1545 45 : len = sizeof (serv.sun_family) + strlen (serv.sun_path);
1546 : #endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
1547 :
1548 45 : ret = bind (sock, (struct sockaddr *) &serv, len);
1549 45 : if (ret < 0)
1550 : {
1551 0 : zlog_warn ("Can't bind to unix socket %s: %s",
1552 0 : path, safe_strerror (errno));
1553 0 : zlog_warn ("zebra can't provide full functionality due to above error");
1554 0 : close (sock);
1555 0 : return;
1556 : }
1557 :
1558 45 : ret = listen (sock, 5);
1559 45 : if (ret < 0)
1560 : {
1561 0 : zlog_warn ("Can't listen to unix socket %s: %s",
1562 0 : path, safe_strerror (errno));
1563 0 : zlog_warn ("zebra can't provide full functionality due to above error");
1564 0 : close (sock);
1565 0 : return;
1566 : }
1567 :
1568 45 : umask (old_mask);
1569 :
1570 45 : zebra_event (ZEBRA_SERV, sock, NULL);
1571 : }
1572 :
1573 :
1574 : static void
1575 336 : zebra_event (enum event event, int sock, struct zserv *client)
1576 : {
1577 336 : switch (event)
1578 : {
1579 : case ZEBRA_SERV:
1580 97 : thread_add_read (zebrad.master, zebra_accept, client, sock);
1581 97 : break;
1582 : case ZEBRA_READ:
1583 239 : client->t_read =
1584 239 : thread_add_read (zebrad.master, zebra_client_read, client, sock);
1585 239 : break;
1586 : case ZEBRA_WRITE:
1587 : /**/
1588 0 : break;
1589 : }
1590 336 : }
1591 :
1592 : /* Display default rtm_table for all clients. */
1593 0 : DEFUN (show_table,
1594 : show_table_cmd,
1595 : "show table",
1596 : SHOW_STR
1597 : "default routing table to use for all clients\n")
1598 : {
1599 0 : vty_out (vty, "table %d%s", zebrad.rtm_table_default,
1600 0 : VTY_NEWLINE);
1601 0 : return CMD_SUCCESS;
1602 : }
1603 :
1604 0 : DEFUN (config_table,
1605 : config_table_cmd,
1606 : "table TABLENO",
1607 : "Configure target kernel routing table\n"
1608 : "TABLE integer\n")
1609 : {
1610 0 : zebrad.rtm_table_default = strtol (argv[0], (char**)0, 10);
1611 0 : return CMD_SUCCESS;
1612 : }
1613 :
1614 0 : DEFUN (ip_forwarding,
1615 : ip_forwarding_cmd,
1616 : "ip forwarding",
1617 : IP_STR
1618 : "Turn on IP forwarding")
1619 : {
1620 : int ret;
1621 :
1622 0 : ret = ipforward ();
1623 0 : if (ret == 0)
1624 0 : ret = ipforward_on ();
1625 :
1626 0 : if (ret == 0)
1627 : {
1628 0 : vty_out (vty, "Can't turn on IP forwarding%s", VTY_NEWLINE);
1629 0 : return CMD_WARNING;
1630 : }
1631 :
1632 0 : return CMD_SUCCESS;
1633 : }
1634 :
1635 0 : DEFUN (no_ip_forwarding,
1636 : no_ip_forwarding_cmd,
1637 : "no ip forwarding",
1638 : NO_STR
1639 : IP_STR
1640 : "Turn off IP forwarding")
1641 : {
1642 : int ret;
1643 :
1644 0 : ret = ipforward ();
1645 0 : if (ret != 0)
1646 0 : ret = ipforward_off ();
1647 :
1648 0 : if (ret != 0)
1649 : {
1650 0 : vty_out (vty, "Can't turn off IP forwarding%s", VTY_NEWLINE);
1651 0 : return CMD_WARNING;
1652 : }
1653 :
1654 0 : return CMD_SUCCESS;
1655 : }
1656 :
1657 : /* This command is for debugging purpose. */
1658 0 : DEFUN (show_zebra_client,
1659 : show_zebra_client_cmd,
1660 : "show zebra client",
1661 : SHOW_STR
1662 : "Zebra information"
1663 : "Client information")
1664 : {
1665 : struct listnode *node;
1666 : struct zserv *client;
1667 :
1668 0 : for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
1669 0 : vty_out (vty, "Client fd %d%s", client->sock, VTY_NEWLINE);
1670 :
1671 0 : return CMD_SUCCESS;
1672 : }
1673 :
1674 : /* Table configuration write function. */
1675 : static int
1676 0 : config_write_table (struct vty *vty)
1677 : {
1678 0 : if (zebrad.rtm_table_default)
1679 0 : vty_out (vty, "table %d%s", zebrad.rtm_table_default,
1680 0 : VTY_NEWLINE);
1681 0 : return 0;
1682 : }
1683 :
1684 : /* table node for routing tables. */
1685 : static struct cmd_node table_node =
1686 : {
1687 : TABLE_NODE,
1688 : "", /* This node has no interface. */
1689 : 1
1690 : };
1691 :
1692 : /* Only display ip forwarding is enabled or not. */
1693 0 : DEFUN (show_ip_forwarding,
1694 : show_ip_forwarding_cmd,
1695 : "show ip forwarding",
1696 : SHOW_STR
1697 : IP_STR
1698 : "IP forwarding status\n")
1699 : {
1700 : int ret;
1701 :
1702 0 : ret = ipforward ();
1703 :
1704 0 : if (ret == 0)
1705 0 : vty_out (vty, "IP forwarding is off%s", VTY_NEWLINE);
1706 : else
1707 0 : vty_out (vty, "IP forwarding is on%s", VTY_NEWLINE);
1708 0 : return CMD_SUCCESS;
1709 : }
1710 :
1711 : #ifdef HAVE_IPV6
1712 : /* Only display ipv6 forwarding is enabled or not. */
1713 0 : DEFUN (show_ipv6_forwarding,
1714 : show_ipv6_forwarding_cmd,
1715 : "show ipv6 forwarding",
1716 : SHOW_STR
1717 : "IPv6 information\n"
1718 : "Forwarding status\n")
1719 : {
1720 : int ret;
1721 :
1722 0 : ret = ipforward_ipv6 ();
1723 :
1724 0 : switch (ret)
1725 : {
1726 : case -1:
1727 0 : vty_out (vty, "ipv6 forwarding is unknown%s", VTY_NEWLINE);
1728 0 : break;
1729 : case 0:
1730 0 : vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE);
1731 0 : break;
1732 : case 1:
1733 0 : vty_out (vty, "ipv6 forwarding is %s%s", "on", VTY_NEWLINE);
1734 0 : break;
1735 : default:
1736 0 : vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE);
1737 0 : break;
1738 : }
1739 0 : return CMD_SUCCESS;
1740 : }
1741 :
1742 0 : DEFUN (ipv6_forwarding,
1743 : ipv6_forwarding_cmd,
1744 : "ipv6 forwarding",
1745 : IPV6_STR
1746 : "Turn on IPv6 forwarding")
1747 : {
1748 : int ret;
1749 :
1750 0 : ret = ipforward_ipv6 ();
1751 0 : if (ret == 0)
1752 0 : ret = ipforward_ipv6_on ();
1753 :
1754 0 : if (ret == 0)
1755 : {
1756 0 : vty_out (vty, "Can't turn on IPv6 forwarding%s", VTY_NEWLINE);
1757 0 : return CMD_WARNING;
1758 : }
1759 :
1760 0 : return CMD_SUCCESS;
1761 : }
1762 :
1763 0 : DEFUN (no_ipv6_forwarding,
1764 : no_ipv6_forwarding_cmd,
1765 : "no ipv6 forwarding",
1766 : NO_STR
1767 : IPV6_STR
1768 : "Turn off IPv6 forwarding")
1769 : {
1770 : int ret;
1771 :
1772 0 : ret = ipforward_ipv6 ();
1773 0 : if (ret != 0)
1774 0 : ret = ipforward_ipv6_off ();
1775 :
1776 0 : if (ret != 0)
1777 : {
1778 0 : vty_out (vty, "Can't turn off IPv6 forwarding%s", VTY_NEWLINE);
1779 0 : return CMD_WARNING;
1780 : }
1781 :
1782 0 : return CMD_SUCCESS;
1783 : }
1784 :
1785 : #endif /* HAVE_IPV6 */
1786 :
1787 : /* IPForwarding configuration write function. */
1788 : static int
1789 0 : config_write_forwarding (struct vty *vty)
1790 : {
1791 : /* FIXME: Find better place for that. */
1792 0 : router_id_write (vty);
1793 :
1794 0 : if (ipforward ())
1795 0 : vty_out (vty, "ip forwarding%s", VTY_NEWLINE);
1796 : #ifdef HAVE_IPV6
1797 0 : if (ipforward_ipv6 ())
1798 0 : vty_out (vty, "ipv6 forwarding%s", VTY_NEWLINE);
1799 : #endif /* HAVE_IPV6 */
1800 0 : vty_out (vty, "!%s", VTY_NEWLINE);
1801 0 : return 0;
1802 : }
1803 :
1804 : /* table node for routing tables. */
1805 : static struct cmd_node forwarding_node =
1806 : {
1807 : FORWARDING_NODE,
1808 : "", /* This node has no interface. */
1809 : 1
1810 : };
1811 :
1812 :
1813 : /* Initialisation of zebra and installation of commands. */
1814 : void
1815 45 : zebra_init (void)
1816 : {
1817 : /* Client list init. */
1818 45 : zebrad.client_list = list_new ();
1819 :
1820 : /* Install configuration write function. */
1821 45 : install_node (&table_node, config_write_table);
1822 45 : install_node (&forwarding_node, config_write_forwarding);
1823 :
1824 45 : install_element (VIEW_NODE, &show_ip_forwarding_cmd);
1825 45 : install_element (ENABLE_NODE, &show_ip_forwarding_cmd);
1826 45 : install_element (CONFIG_NODE, &ip_forwarding_cmd);
1827 45 : install_element (CONFIG_NODE, &no_ip_forwarding_cmd);
1828 45 : install_element (ENABLE_NODE, &show_zebra_client_cmd);
1829 :
1830 : #ifdef HAVE_NETLINK
1831 45 : install_element (VIEW_NODE, &show_table_cmd);
1832 45 : install_element (ENABLE_NODE, &show_table_cmd);
1833 45 : install_element (CONFIG_NODE, &config_table_cmd);
1834 : #endif /* HAVE_NETLINK */
1835 :
1836 : #ifdef HAVE_IPV6
1837 45 : install_element (VIEW_NODE, &show_ipv6_forwarding_cmd);
1838 45 : install_element (ENABLE_NODE, &show_ipv6_forwarding_cmd);
1839 45 : install_element (CONFIG_NODE, &ipv6_forwarding_cmd);
1840 45 : install_element (CONFIG_NODE, &no_ipv6_forwarding_cmd);
1841 : #endif /* HAVE_IPV6 */
1842 :
1843 : /* Route-map */
1844 45 : zebra_route_map_init ();
1845 45 : }
1846 :
1847 : /* Make zebra server socket, wiping any existing one (see bug #403). */
1848 : void
1849 45 : zebra_zserv_socket_init (char *path)
1850 : {
1851 : #ifdef HAVE_TCP_ZEBRA
1852 : zebra_serv ();
1853 : #else
1854 45 : zebra_serv_un (path ? path : ZEBRA_SERV_PATH);
1855 : #endif /* HAVE_TCP_ZEBRA */
1856 45 : }
|