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