1/*
2 * Zebra connect library for OSPFd
3 * Copyright (C) 1997, 98, 99, 2000 Kunihiro Ishiguro, Toshiaki Takada
4 *
5 * This file is part of GNU Zebra.
6 *
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
11 *
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Zebra; see the file COPYING.  If not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
21 */
22
23#include <zebra.h>
24
25#include "thread.h"
26#include "command.h"
27#include "network.h"
28#include "prefix.h"
29#include "routemap.h"
30#include "table.h"
31#include "stream.h"
32#include "memory.h"
33#include "zclient.h"
34#include "filter.h"
35#include "log.h"
36
37#include "ospfd/ospfd.h"
38#include "ospfd/ospf_interface.h"
39#include "ospfd/ospf_ism.h"
40#include "ospfd/ospf_asbr.h"
41#include "ospfd/ospf_asbr.h"
42#include "ospfd/ospf_abr.h"
43#include "ospfd/ospf_lsa.h"
44#include "ospfd/ospf_dump.h"
45#include "ospfd/ospf_route.h"
46#include "ospfd/ospf_zebra.h"
47#ifdef HAVE_SNMP
48#include "ospfd/ospf_snmp.h"
49#endif /* HAVE_SNMP */
50
51/* Zebra structure to hold current status. */
52struct zclient *zclient = NULL;
53
54/* For registering threads. */
55extern struct thread_master *master;
56
57/* Inteface addition message from zebra. */
58int
59ospf_interface_add (int command, struct zclient *zclient, zebra_size_t length)
60{
61  struct interface *ifp;
62
63  ifp = zebra_interface_add_read (zclient->ibuf);
64
65  if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
66    zlog_info ("Zebra: interface add %s index %d flags %ld metric %d mtu %d",
67	       ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
68
69  if (!OSPF_IF_PARAM_CONFIGURED (IF_DEF_PARAMS (ifp), type))
70    {
71      SET_IF_PARAM (IF_DEF_PARAMS (ifp), type);
72      IF_DEF_PARAMS (ifp)->type = OSPF_IFTYPE_BROADCAST;
73
74      if (if_is_broadcast (ifp))
75	IF_DEF_PARAMS (ifp)->type = OSPF_IFTYPE_BROADCAST;
76      else if (if_is_pointopoint (ifp))
77	IF_DEF_PARAMS (ifp)->type = OSPF_IFTYPE_POINTOPOINT;
78      else if (if_is_loopback (ifp))
79	IF_DEF_PARAMS (ifp)->type = OSPF_IFTYPE_LOOPBACK;
80    }
81
82  ospf_if_update ();
83
84#ifdef HAVE_SNMP
85  ospf_snmp_if_update (ifp);
86#endif /* HAVE_SNMP */
87
88  return 0;
89}
90
91int
92ospf_interface_delete (int command, struct zclient *zclient,
93		       zebra_size_t length)
94{
95  struct interface *ifp;
96  struct stream *s;
97  struct route_node *rn;
98
99  s = zclient->ibuf;
100  /* zebra_interface_state_read() updates interface structure in iflist */
101  ifp = zebra_interface_state_read (s);
102
103  if (ifp == NULL)
104    return 0;
105
106  if (if_is_up (ifp))
107    zlog_warn ("Zebra: got delete of %s, but interface is still up",
108	       ifp->name);
109
110  if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
111    zlog_info ("Zebra: interface delete %s index %d flags %ld metric %d mtu %d",
112	       ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
113
114#ifdef HAVE_SNMP
115  ospf_snmp_if_delete (ifp);
116#endif /* HAVE_SNMP */
117
118  for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
119    if (rn->info)
120      ospf_if_free ((struct ospf_interface *) rn->info);
121
122  for (rn = route_top (IF_OIFS_PARAMS (ifp)); rn; rn = route_next (rn))
123    if (rn->info)
124      ospf_del_if_params (rn->info);
125
126  if_delete (ifp);
127
128  return 0;
129}
130
131struct interface *
132zebra_interface_if_lookup (struct stream *s)
133{
134  struct interface *ifp;
135  u_char ifname_tmp[INTERFACE_NAMSIZ];
136
137  /* Read interface name. */
138  stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
139
140  /* Lookup this by interface index. */
141  ifp = if_lookup_by_name (ifname_tmp);
142
143  /* If such interface does not exist, indicate an error */
144  if (!ifp)
145    return NULL;
146
147  return ifp;
148}
149
150void
151zebra_interface_if_set_value (struct stream *s, struct interface *ifp)
152{
153  /* Read interface's index. */
154  ifp->ifindex = stream_getl (s);
155
156  /* Read interface's value. */
157  ifp->flags = stream_getl (s);
158  ifp->metric = stream_getl (s);
159  ifp->mtu = stream_getl (s);
160  ifp->bandwidth = stream_getl (s);
161}
162
163int
164ospf_interface_state_up (int command, struct zclient *zclient,
165			 zebra_size_t length)
166{
167  struct interface *ifp;
168  struct interface if_tmp;
169  struct ospf_interface *oi;
170  struct route_node *rn;
171
172  ifp = zebra_interface_if_lookup (zclient->ibuf);
173
174  if (ifp == NULL)
175    return 0;
176
177  /* Interface is already up. */
178  if (if_is_up (ifp))
179    {
180      /* Temporarily keep ifp values. */
181      memcpy (&if_tmp, ifp, sizeof (struct interface));
182
183      zebra_interface_if_set_value (zclient->ibuf, ifp);
184
185      if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
186	zlog_info ("Zebra: Interface[%s] state update.", ifp->name);
187
188      if (if_tmp.bandwidth != ifp->bandwidth)
189	{
190	  if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
191	    zlog_info ("Zebra: Interface[%s] bandwidth change %d -> %d.",
192		       ifp->name, if_tmp.bandwidth, ifp->bandwidth);
193
194	  ospf_if_recalculate_output_cost (ifp);
195	}
196      return 0;
197    }
198
199  zebra_interface_if_set_value (zclient->ibuf, ifp);
200
201  if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
202    zlog_info ("Zebra: Interface[%s] state change to up.", ifp->name);
203
204  for (rn = route_top (IF_OIFS (ifp));rn; rn = route_next (rn))
205    {
206      if ( (oi = rn->info) == NULL)
207	continue;
208
209      ospf_if_up (oi);
210    }
211
212  return 0;
213}
214
215int
216ospf_interface_state_down (int command, struct zclient *zclient,
217			   zebra_size_t length)
218{
219  struct interface *ifp;
220  struct ospf_interface *oi;
221  struct route_node *node;
222
223  ifp = zebra_interface_state_read (zclient->ibuf);
224
225  if (ifp == NULL)
226    return 0;
227
228  if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
229    zlog_info ("Zebra: Interface[%s] state change to down.", ifp->name);
230
231  for (node = route_top (IF_OIFS (ifp));node; node = route_next (node))
232    {
233      if ( (oi = node->info) == NULL)
234	continue;
235      ospf_if_down (oi);
236    }
237
238  return 0;
239}
240
241int
242ospf_interface_address_add (int command, struct zclient *zclient,
243			    zebra_size_t length)
244{
245  struct connected *c;
246
247  c = zebra_interface_address_add_read (zclient->ibuf);
248
249  if (c == NULL)
250    return 0;
251
252#if 0
253  if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
254    {
255      struct prefix *p;
256
257      p = c->address;
258      if (p->family == AF_INET)
259	zlog_info (" connected address %s/%d",
260		   inet_atop (p->u.prefix4), p->prefixlen);
261    }
262#endif
263
264  ospf_if_update ();
265
266#ifdef HAVE_SNMP
267  ospf_snmp_if_update (c->ifp);
268#endif /* HAVE_SNMP */
269
270  return 0;
271}
272
273int
274ospf_interface_address_delete (int command, struct zclient *zclient,
275			       zebra_size_t length)
276{
277  struct connected *c;
278  struct interface *ifp;
279  struct ospf_interface *oi;
280  struct route_node *rn;
281  struct prefix p;
282
283  c = zebra_interface_address_delete_read (zclient->ibuf);
284
285  if (c == NULL)
286    return 0;
287
288  ifp = c->ifp;
289  p = *c->address;
290  p.prefixlen = IPV4_MAX_PREFIXLEN;
291
292  rn = route_node_lookup (IF_OIFS (ifp), &p);
293  if (! rn)
294    return 0;
295
296  assert (rn->info);
297  oi = rn->info;
298
299  /* Call interface hook functions to clean up */
300  ospf_if_free (oi);
301
302#ifdef HAVE_SNMP
303  ospf_snmp_if_update (c->ifp);
304#endif /* HAVE_SNMP */
305
306  connected_free (c);
307
308  ospf_if_update();
309
310  return 0;
311}
312
313void
314ospf_zebra_add (struct prefix_ipv4 *p, struct ospf_route *or)
315{
316  u_char message;
317  u_char distance;
318  u_char flags;
319  int psize;
320  struct stream *s;
321  struct ospf_path *path;
322  listnode node;
323
324  if (zclient->redist[ZEBRA_ROUTE_OSPF])
325    {
326      message = 0;
327      flags = 0;
328
329      /* OSPF pass nexthop and metric */
330      SET_FLAG (message, ZAPI_MESSAGE_NEXTHOP);
331      SET_FLAG (message, ZAPI_MESSAGE_METRIC);
332
333      /* Distance value. */
334      distance = ospf_distance_apply (p, or);
335      if (distance)
336	SET_FLAG (message, ZAPI_MESSAGE_DISTANCE);
337
338      /* Make packet. */
339      s = zclient->obuf;
340      stream_reset (s);
341
342      /* Length place holder. */
343      stream_putw (s, 0);
344
345      /* Put command, type, flags, message. */
346      stream_putc (s, ZEBRA_IPV4_ROUTE_ADD);
347      stream_putc (s, ZEBRA_ROUTE_OSPF);
348      stream_putc (s, flags);
349      stream_putc (s, message);
350
351      /* Put prefix information. */
352      psize = PSIZE (p->prefixlen);
353      stream_putc (s, p->prefixlen);
354      stream_write (s, (u_char *)&p->prefix, psize);
355
356      /* Nexthop count. */
357      stream_putc (s, or->path->count);
358
359      /* Nexthop, ifindex, distance and metric information. */
360      for (node = listhead (or->path); node; nextnode (node))
361	{
362	  path = getdata (node);
363
364	  if (path->nexthop.s_addr != INADDR_ANY)
365	    {
366	      stream_putc (s, ZEBRA_NEXTHOP_IPV4);
367	      stream_put_in_addr (s, &path->nexthop);
368	    }
369	  else
370	    {
371	      stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
372	      if (path->oi)
373		stream_putl (s, path->oi->ifp->ifindex);
374	      else
375		stream_putl (s, 0);
376	    }
377	}
378
379      if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
380	stream_putc (s, distance);
381      if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
382	{
383	  if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL)
384	    stream_putl (s, or->cost + or->u.ext.type2_cost);
385	  else if (or->path_type == OSPF_PATH_TYPE2_EXTERNAL)
386	    stream_putl (s, or->u.ext.type2_cost);
387	  else
388	    stream_putl (s, or->cost);
389	}
390
391      stream_putw_at (s, 0, stream_get_endp (s));
392
393      writen (zclient->sock, s->data, stream_get_endp (s));
394
395#if 0
396      if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
397	{
398	  char *nexthop_str;
399
400	  nexthop_str = strdup (inet_ntoa (*nexthop));
401	  zlog_info ("Zebra: Route add %s/%d nexthop %s metric %d",
402		     inet_ntoa (p->prefix), p->prefixlen, nexthop_str,
403		     metric);
404	  free (nexthop_str);
405	}
406#endif /* 0 */
407    }
408}
409
410void
411ospf_zebra_delete (struct prefix_ipv4 *p, struct ospf_route *or)
412{
413  struct zapi_ipv4 api;
414
415  if (zclient->redist[ZEBRA_ROUTE_OSPF])
416    {
417      api.type = ZEBRA_ROUTE_OSPF;
418      api.flags = 0;
419      api.message = 0;
420      zapi_ipv4_delete (zclient, p, &api);
421
422#if 0
423      if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
424	{
425	  char *nexthop_str;
426
427	  nexthop_str = strdup (inet_ntoa (*nexthop));
428	  zlog_info ("Zebra: Route delete %s/%d nexthop %s",
429		     inet_ntoa (p->prefix), p->prefixlen, nexthop_str);
430	  free (nexthop_str);
431	}
432#endif /* 0 */
433    }
434}
435
436void
437ospf_zebra_add_discard (struct prefix_ipv4 *p)
438{
439  struct in_addr lo_addr;
440  struct in_addr *nexthop;
441  struct zapi_ipv4 api;
442
443  lo_addr.s_addr = htonl (INADDR_LOOPBACK);
444  nexthop = &lo_addr;
445
446  if (zclient->redist[ZEBRA_ROUTE_OSPF])
447    {
448      api.type = ZEBRA_ROUTE_OSPF;
449      api.flags = ZEBRA_FLAG_BLACKHOLE;
450      api.message = 0;
451      SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
452      api.nexthop_num = 1;
453      api.nexthop = &nexthop;
454      api.ifindex_num = 0;
455
456      zapi_ipv4_add (zclient, p, &api);
457    }
458}
459
460void
461ospf_zebra_delete_discard (struct prefix_ipv4 *p)
462{
463  struct in_addr lo_addr;
464  struct in_addr *nexthop;
465  struct zapi_ipv4 api;
466
467  lo_addr.s_addr = htonl (INADDR_LOOPBACK);
468  nexthop = &lo_addr;
469
470  if (zclient->redist[ZEBRA_ROUTE_OSPF])
471    {
472      api.type = ZEBRA_ROUTE_OSPF;
473      api.flags = ZEBRA_FLAG_BLACKHOLE;
474      api.message = 0;
475      SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
476      api.nexthop_num = 1;
477      api.nexthop = &nexthop;
478      api.ifindex_num = 0;
479
480      zapi_ipv4_delete (zclient, p, &api);
481    }
482}
483
484int
485ospf_is_type_redistributed (int type)
486{
487  return (DEFAULT_ROUTE_TYPE (type)) ?
488    zclient->default_information : zclient->redist[type];
489}
490
491int
492ospf_redistribute_set (int type, int mtype, int mvalue)
493{
494  int force = 0;
495
496  if (ospf_is_type_redistributed (type))
497    {
498      if (mtype != ospf_top->dmetric[type].type)
499	{
500	  ospf_top->dmetric[type].type = mtype;
501	  force = LSA_REFRESH_FORCE;
502	}
503      if (mvalue != ospf_top->dmetric[type].value)
504	{
505	  ospf_top->dmetric[type].value = mvalue;
506	  force = LSA_REFRESH_FORCE;
507	}
508
509      ospf_external_lsa_refresh_type (type, force);
510
511      if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
512	zlog_info ("Redistribute[%s]: Refresh  Type[%d], Metric[%d]",
513		   LOOKUP (ospf_redistributed_proto, type),
514		   metric_type (type), metric_value (type));
515
516      return CMD_SUCCESS;
517    }
518
519  ospf_top->dmetric[type].type = mtype;
520  ospf_top->dmetric[type].value = mvalue;
521
522  zclient_redistribute_set (zclient, type);
523
524  if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
525    zlog_info ("Redistribute[%s]: Start  Type[%d], Metric[%d]",
526	       LOOKUP (ospf_redistributed_proto, type),
527	       metric_type (type), metric_value (type));
528
529  ospf_asbr_status_update (++ospf_top->redistribute);
530
531  return CMD_SUCCESS;
532}
533
534int
535ospf_redistribute_unset (int type)
536{
537  if (type == zclient->redist_default)
538    return CMD_SUCCESS;
539
540  if (! ospf_is_type_redistributed (type))
541    return CMD_SUCCESS;
542
543  zclient_redistribute_unset (zclient, type);
544
545  if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
546    zlog_info ("Redistribute[%s]: Stop",
547	       LOOKUP (ospf_redistributed_proto, type));
548
549  ospf_top->dmetric[type].type = -1;
550  ospf_top->dmetric[type].value = -1;
551
552  /* Remove the routes from OSPF table. */
553  ospf_redistribute_withdraw (type);
554
555  ospf_asbr_status_update (--ospf_top->redistribute);
556
557  return CMD_SUCCESS;
558}
559
560int
561ospf_redistribute_default_set (int originate, int mtype, int mvalue)
562{
563  int force = 0;
564  if (ospf_is_type_redistributed (DEFAULT_ROUTE))
565    {
566      if (mtype != ospf_top->dmetric[DEFAULT_ROUTE].type)
567	{
568	  ospf_top->dmetric[DEFAULT_ROUTE].type = mtype;
569	  force = 1;
570	}
571      if (mvalue != ospf_top->dmetric[DEFAULT_ROUTE].value)
572	{
573	  force = 1;
574	  ospf_top->dmetric[DEFAULT_ROUTE].value = mvalue;
575	}
576
577      ospf_external_lsa_refresh_default ();
578
579      if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
580	zlog_info ("Redistribute[%s]: Refresh  Type[%d], Metric[%d]",
581		   LOOKUP (ospf_redistributed_proto, DEFAULT_ROUTE),
582		   metric_type (DEFAULT_ROUTE),
583		   metric_value (DEFAULT_ROUTE));
584      return CMD_SUCCESS;
585    }
586
587  ospf_top->default_originate = originate;
588  ospf_top->dmetric[DEFAULT_ROUTE].type = mtype;
589  ospf_top->dmetric[DEFAULT_ROUTE].value = mvalue;
590
591  zclient_redistribute_default_set (zclient);
592
593  if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
594    zlog_info ("Redistribute[DEFAULT]: Start  Type[%d], Metric[%d]",
595	       metric_type (DEFAULT_ROUTE), metric_value (DEFAULT_ROUTE));
596
597
598  if (ospf_top->router_id.s_addr == 0)
599    ospf_top->external_origin |= (1 << DEFAULT_ROUTE);
600  else
601    thread_add_timer (master, ospf_default_originate_timer,
602		      &ospf_top->default_originate, 1);
603
604  ospf_asbr_status_update (++ospf_top->redistribute);
605
606  return CMD_SUCCESS;
607}
608
609int
610ospf_redistribute_default_unset ()
611{
612  if (!ospf_is_type_redistributed (DEFAULT_ROUTE))
613    return CMD_SUCCESS;
614
615  ospf_top->default_originate = DEFAULT_ORIGINATE_NONE;
616  ospf_top->dmetric[DEFAULT_ROUTE].type = -1;
617  ospf_top->dmetric[DEFAULT_ROUTE].value = -1;
618
619  zclient_redistribute_default_unset (zclient);
620
621  if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
622    zlog_info ("Redistribute[DEFAULT]: Stop");
623
624  ospf_asbr_status_update (--ospf_top->redistribute);
625
626  return CMD_SUCCESS;
627}
628
629int
630ospf_external_lsa_originate_check (struct external_info *ei)
631{
632  /* If prefix is multicast, then do not originate LSA. */
633  if (IN_MULTICAST (htonl (ei->p.prefix.s_addr)))
634    {
635      zlog_info ("LSA[Type5:%s]: Not originate AS-external-LSA, "
636		 "Prefix belongs multicast", inet_ntoa (ei->p.prefix));
637      return 0;
638    }
639
640  /* Take care of default-originate. */
641  if (is_prefix_default (&ei->p))
642    if (ospf_top->default_originate == DEFAULT_ORIGINATE_NONE)
643      {
644	zlog_info ("LSA[Type5:0.0.0.0]: Not originate AS-exntenal-LSA "
645		   "for default");
646	return 0;
647      }
648
649  return 1;
650}
651
652/* If connected prefix is OSPF enable interface, then do not announce. */
653int
654ospf_distribute_check_connected (struct external_info *ei)
655{
656  struct route_node *rn;
657
658  for (rn = route_top (ospf_top->networks); rn; rn = route_next (rn))
659    if (rn->info != NULL)
660      if (prefix_match (&rn->p, (struct prefix *)&ei->p))
661	return 0;
662
663  return 1;
664}
665
666/* return 1 if external LSA must be originated, 0 otherwise */
667int
668ospf_redistribute_check (struct external_info *ei, int *changed)
669{
670  struct route_map_set_values save_values;
671  struct prefix_ipv4 *p = &ei->p;
672  u_char type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
673
674  if (changed)
675    *changed = 0;
676
677  if (!ospf_external_lsa_originate_check (ei))
678    return 0;
679
680  /* Take care connected route. */
681  if (type == ZEBRA_ROUTE_CONNECT && !ospf_distribute_check_connected (ei))
682    return 0;
683
684  if (!DEFAULT_ROUTE_TYPE (type) && DISTRIBUTE_NAME (type))
685    /* distirbute-list exists, but access-list may not? */
686    if (DISTRIBUTE_LIST (type))
687      if (access_list_apply (DISTRIBUTE_LIST (type), p) == FILTER_DENY)
688	{
689	  if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
690	    zlog_info ("Redistribute[%s]: %s/%d filtered by ditribute-list.",
691		       LOOKUP (ospf_redistributed_proto, type),
692		       inet_ntoa (p->prefix), p->prefixlen);
693	  return 0;
694	}
695
696  save_values = ei->route_map_set;
697  ospf_reset_route_map_set_values (&ei->route_map_set);
698
699  /* apply route-map if needed */
700  if (ROUTEMAP_NAME (type))
701    {
702      int ret;
703
704      ret = route_map_apply (ROUTEMAP (type), (struct prefix *)p,
705			     RMAP_OSPF, ei);
706
707      if (ret == RMAP_DENYMATCH)
708	{
709	  ei->route_map_set = save_values;
710	  if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
711	    zlog_info ("Redistribute[%s]: %s/%d filtered by route-map.",
712		       LOOKUP (ospf_redistributed_proto, type),
713		       inet_ntoa (p->prefix), p->prefixlen);
714	  return 0;
715	}
716
717      /* check if 'route-map set' changed something */
718      if (changed)
719	*changed = !ospf_route_map_set_compare (&ei->route_map_set,
720						&save_values);
721    }
722
723  return 1;
724}
725
726/* OSPF route-map set for redistribution */
727void
728ospf_routemap_set (int type, char *name)
729{
730  if (ROUTEMAP_NAME (type))
731    free (ROUTEMAP_NAME (type));
732
733  ROUTEMAP_NAME (type) = strdup (name);
734  ROUTEMAP (type) = route_map_lookup_by_name (name);
735}
736
737void
738ospf_routemap_unset (int type)
739{
740  if (ROUTEMAP_NAME (type))
741    free (ROUTEMAP_NAME (type));
742
743  ROUTEMAP_NAME (type) = NULL;
744  ROUTEMAP (type) = NULL;
745}
746
747/* Zebra route add and delete treatment. */
748int
749ospf_zebra_read_ipv4 (int command, struct zclient *zclient,
750		      zebra_size_t length)
751{
752  struct stream *s;
753  struct zapi_ipv4 api;
754  unsigned long ifindex;
755  struct in_addr nexthop;
756  struct prefix_ipv4 p;
757  struct external_info *ei;
758
759  s = zclient->ibuf;
760  ifindex = 0;
761  nexthop.s_addr = 0;
762
763  /* Type, flags, message. */
764  api.type = stream_getc (s);
765  api.flags = stream_getc (s);
766  api.message = stream_getc (s);
767
768  /* IPv4 prefix. */
769  memset (&p, 0, sizeof (struct prefix_ipv4));
770  p.family = AF_INET;
771  p.prefixlen = stream_getc (s);
772  stream_get (&p.prefix, s, PSIZE (p.prefixlen));
773
774  /* Nexthop, ifindex, distance, metric. */
775  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
776    {
777      api.nexthop_num = stream_getc (s);
778      nexthop.s_addr = stream_get_ipv4 (s);
779    }
780  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
781    {
782      api.ifindex_num = stream_getc (s);
783      ifindex = stream_getl (s);
784    }
785  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
786    api.distance = stream_getc (s);
787  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
788    api.metric = stream_getl (s);
789
790  if (command == ZEBRA_IPV4_ROUTE_ADD)
791    {
792      ei = ospf_external_info_add (api.type, p, ifindex, nexthop);
793
794      if (ospf_top->router_id.s_addr == 0)
795	/* Set flags to generate AS-external-LSA originate event
796	   for each redistributed protocols later. */
797	ospf_top->external_origin |= (1 << api.type);
798      else
799	{
800	  if (ei)
801	    {
802	      if (is_prefix_default (&p))
803		ospf_external_lsa_refresh_default ();
804	      else
805		{
806		  struct ospf_lsa *current;
807
808		  current = ospf_external_info_find_lsa (&ei->p);
809		  if (!current)
810		    ospf_external_lsa_originate (ei);
811		  else if (IS_LSA_MAXAGE (current))
812		    ospf_external_lsa_refresh (current, ei, LSA_REFRESH_FORCE);
813		  else
814		    zlog_warn ("ospf_zebra_read_ipv4() : %s already exists",
815			       inet_ntoa (p.prefix));
816		}
817	    }
818	}
819    }
820  else /* if (command == ZEBRA_IPV4_ROUTE_DELETE) */
821    {
822      ospf_external_info_delete (api.type, p);
823      if ( !is_prefix_default (&p))
824	ospf_external_lsa_flush (api.type, &p, ifindex, nexthop);
825      else
826	ospf_external_lsa_refresh_default ();
827    }
828
829  return 0;
830}
831
832
833int
834ospf_distribute_list_out_set (int type, char *name)
835{
836  /* Lookup access-list for distribute-list. */
837  DISTRIBUTE_LIST (type) = access_list_lookup (AFI_IP, name);
838
839  /* Clear previous distribute-name. */
840  if (DISTRIBUTE_NAME (type))
841    free (DISTRIBUTE_NAME (type));
842
843  /* Set distribute-name. */
844  DISTRIBUTE_NAME (type) = strdup (name);
845
846  /* If access-list have been set, schedule update timer. */
847  if (DISTRIBUTE_LIST (type))
848    ospf_distribute_list_update (type);
849
850  return CMD_SUCCESS;
851}
852
853int
854ospf_distribute_list_out_unset (int type, char *name)
855{
856  /* Schedule update timer. */
857  if (DISTRIBUTE_LIST (type))
858    ospf_distribute_list_update (type);
859
860  /* Unset distribute-list. */
861  DISTRIBUTE_LIST (type) = NULL;
862
863  /* Clear distribute-name. */
864  if (DISTRIBUTE_NAME (type))
865    free (DISTRIBUTE_NAME (type));
866
867  DISTRIBUTE_NAME (type) = NULL;
868
869  return CMD_SUCCESS;
870}
871
872/* distribute-list update timer. */
873int
874ospf_distribute_list_update_timer (struct thread *thread)
875{
876  struct route_node *rn;
877  struct external_info *ei;
878  struct route_table *rt;
879  struct ospf_lsa *lsa;
880  u_char type;
881
882  type = (int) THREAD_ARG (thread);
883  rt = EXTERNAL_INFO (type);
884
885  ospf_top->t_distribute_update = NULL;
886
887  zlog_info ("Zebra[Redistribute]: distribute-list update timer fired!");
888
889  /* foreach all external info. */
890  if (rt)
891    for (rn = route_top (rt); rn; rn = route_next (rn))
892      if ((ei = rn->info) != NULL)
893	{
894	  if (is_prefix_default (&ei->p))
895	    ospf_external_lsa_refresh_default ();
896	  else if ((lsa = ospf_external_info_find_lsa (&ei->p)))
897	    ospf_external_lsa_refresh (lsa, ei, LSA_REFRESH_IF_CHANGED);
898	  else
899	    ospf_external_lsa_originate (ei);
900	}
901  return 0;
902}
903
904#define OSPF_DISTRIBUTE_UPDATE_DELAY 5
905
906/* Update distribute-list and set timer to apply access-list. */
907void
908ospf_distribute_list_update (int type)
909{
910  struct route_table *rt;
911
912  zlog_info ("ospf_distribute_list_update(): start");
913
914  /* External info does not exist. */
915  if (!(rt = EXTERNAL_INFO (type)))
916    return;
917
918  /* If exists previously invoked thread, then cancel it. */
919  if (ospf_top->t_distribute_update)
920    OSPF_TIMER_OFF (ospf_top->t_distribute_update);
921
922  /* Set timer. */
923  ospf_top->t_distribute_update =
924    thread_add_timer (master, ospf_distribute_list_update_timer,
925		      (void *) type, OSPF_DISTRIBUTE_UPDATE_DELAY);
926
927  zlog_info ("ospf_distribute_list_update(): stop");
928}
929
930/* If access-list is updated, apply some check. */
931void
932ospf_filter_update (struct access_list *access)
933{
934  int type;
935  int abr_inv = 0;
936  struct ospf_area *area;
937  listnode node;
938
939  /* If OSPF instatnce does not exist, return right now. */
940  if (!ospf_top)
941    return;
942
943
944  /* Update distribute-list, and apply filter. */
945  for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
946    {
947      if (ROUTEMAP (type) != NULL)
948	{
949	  /* if route-map is not NULL it may be using this access list */
950	  ospf_distribute_list_update (type);
951	  continue;
952	}
953
954
955      if (DISTRIBUTE_NAME (type))
956	{
957	  /* Keep old access-list for distribute-list. */
958	  struct access_list *old = DISTRIBUTE_LIST (type);
959
960	  /* Update access-list for distribute-list. */
961	  DISTRIBUTE_LIST (type) =
962	    access_list_lookup (AFI_IP, DISTRIBUTE_NAME (type));
963
964	  /* No update for this distribute type. */
965	  if (old == NULL && DISTRIBUTE_LIST (type) == NULL)
966	    continue;
967
968	  /* Schedule distribute-list update timer. */
969	  if (DISTRIBUTE_LIST (type) == NULL ||
970	      strcmp (DISTRIBUTE_NAME (type), access->name) == 0)
971	    ospf_distribute_list_update (type);
972	}
973    }
974
975  /* Update Area access-list. */
976  for (node = listhead (ospf_top->areas); node; nextnode (node))
977    if ((area = getdata (node)) != NULL)
978      {
979	if (EXPORT_NAME (area))
980	  {
981	    EXPORT_LIST (area) = NULL;
982	    abr_inv++;
983	  }
984
985	if (IMPORT_NAME (area))
986	  {
987	    IMPORT_LIST (area) = NULL;
988	    abr_inv++;
989	  }
990      }
991
992  /* Schedule ABR tasks -- this will be changed -- takada. */
993  if (OSPF_IS_ABR && abr_inv)
994    ospf_schedule_abr_task ();
995}
996
997
998struct ospf_distance *
999ospf_distance_new ()
1000{
1001  struct ospf_distance *new;
1002  new = XMALLOC (MTYPE_OSPF_DISTANCE, sizeof (struct ospf_distance));
1003  memset (new, 0, sizeof (struct ospf_distance));
1004  return new;
1005}
1006
1007void
1008ospf_distance_free (struct ospf_distance *odistance)
1009{
1010  XFREE (MTYPE_OSPF_DISTANCE, odistance);
1011}
1012
1013int
1014ospf_distance_set (struct vty *vty, char *distance_str, char *ip_str,
1015		   char *access_list_str)
1016{
1017  int ret;
1018  struct prefix_ipv4 p;
1019  u_char distance;
1020  struct route_node *rn;
1021  struct ospf_distance *odistance;
1022
1023  ret = str2prefix_ipv4 (ip_str, &p);
1024  if (ret == 0)
1025    {
1026      vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
1027      return CMD_WARNING;
1028    }
1029
1030  distance = atoi (distance_str);
1031
1032  /* Get OSPF distance node. */
1033  rn = route_node_get (ospf_top->distance_table, (struct prefix *) &p);
1034  if (rn->info)
1035    {
1036      odistance = rn->info;
1037      route_unlock_node (rn);
1038    }
1039  else
1040    {
1041      odistance = ospf_distance_new ();
1042      rn->info = odistance;
1043    }
1044
1045  /* Set distance value. */
1046  odistance->distance = distance;
1047
1048  /* Reset access-list configuration. */
1049  if (odistance->access_list)
1050    {
1051      free (odistance->access_list);
1052      odistance->access_list = NULL;
1053    }
1054  if (access_list_str)
1055    odistance->access_list = strdup (access_list_str);
1056
1057  return CMD_SUCCESS;
1058}
1059
1060int
1061ospf_distance_unset (struct vty *vty, char *distance_str, char *ip_str,
1062		     char *access_list_str)
1063{
1064  int ret;
1065  struct prefix_ipv4 p;
1066  u_char distance;
1067  struct route_node *rn;
1068  struct ospf_distance *odistance;
1069
1070  ret = str2prefix_ipv4 (ip_str, &p);
1071  if (ret == 0)
1072    {
1073      vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
1074      return CMD_WARNING;
1075    }
1076
1077  distance = atoi (distance_str);
1078
1079  rn = route_node_lookup (ospf_top->distance_table, (struct prefix *)&p);
1080  if (! rn)
1081    {
1082      vty_out (vty, "Can't find specified prefix%s", VTY_NEWLINE);
1083      return CMD_WARNING;
1084    }
1085
1086  odistance = rn->info;
1087
1088  if (odistance->access_list)
1089    free (odistance->access_list);
1090  ospf_distance_free (odistance);
1091
1092  rn->info = NULL;
1093  route_unlock_node (rn);
1094  route_unlock_node (rn);
1095
1096  return CMD_SUCCESS;
1097}
1098
1099void
1100ospf_distance_reset ()
1101{
1102  struct route_node *rn;
1103  struct ospf_distance *odistance;
1104
1105  for (rn = route_top (ospf_top->distance_table); rn; rn = route_next (rn))
1106    if ((odistance = rn->info) != NULL)
1107      {
1108	if (odistance->access_list)
1109	  free (odistance->access_list);
1110	ospf_distance_free (odistance);
1111	rn->info = NULL;
1112	route_unlock_node (rn);
1113      }
1114}
1115
1116u_char
1117ospf_distance_apply (struct prefix_ipv4 *p, struct ospf_route *or)
1118{
1119#if 0
1120  struct route_node *rn;
1121  struct ospf_distance *odistance;
1122  struct access_list *alist;
1123  struct prefix_ipv4 q;
1124
1125  memset (&q, 0, sizeof (struct prefix_ipv4));
1126  q.family = AF_INET;
1127  /* q.prefix =  */
1128  q.prefixlen = IPV4_MAX_BITLEN;
1129#endif /* 0 */
1130
1131  if (! ospf_top)
1132    return 0;
1133
1134#if 0
1135  rn = route_node_match (ospf_top->distance_table, (struct prefix *) &q);
1136  if (rn)
1137    {
1138      odistance = rn->info;
1139      route_unlock_node (rn);
1140
1141      if (odistance->access_list)
1142	{
1143	  alist = access_list_lookup (AFI_IP, odistance->access_list);
1144	  if (alist == NULL)
1145	    return 0;
1146	  if (access_list_apply (alist, (struct prefix *) p) == FILTER_DENY)
1147	    return 0;
1148
1149	  return odistance->distance;
1150	}
1151      else
1152	return odistance->distance;
1153    }
1154#endif /* 0 */
1155
1156  if (ospf_top->distance_intra)
1157    if (or->path_type == OSPF_PATH_INTRA_AREA)
1158      return ospf_top->distance_intra;
1159
1160  if (ospf_top->distance_inter)
1161    if (or->path_type == OSPF_PATH_INTER_AREA)
1162      return ospf_top->distance_inter;
1163
1164  if (ospf_top->distance_external)
1165    if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL
1166	|| or->path_type == OSPF_PATH_TYPE2_EXTERNAL)
1167      return ospf_top->distance_external;
1168
1169  if (ospf_top->distance_all)
1170    return ospf_top->distance_all;
1171
1172  return 0;
1173}
1174
1175void
1176ospf_zebra_init ()
1177{
1178  /* Allocate zebra structure. */
1179  zclient = zclient_new ();
1180  zclient_init (zclient, ZEBRA_ROUTE_OSPF);
1181  zclient->interface_add = ospf_interface_add;
1182  zclient->interface_delete = ospf_interface_delete;
1183  zclient->interface_up = ospf_interface_state_up;
1184  zclient->interface_down = ospf_interface_state_down;
1185  zclient->interface_address_add = ospf_interface_address_add;
1186  zclient->interface_address_delete = ospf_interface_address_delete;
1187  zclient->ipv4_route_add = ospf_zebra_read_ipv4;
1188  zclient->ipv4_route_delete = ospf_zebra_read_ipv4;
1189
1190  access_list_add_hook (ospf_filter_update);
1191  access_list_delete_hook (ospf_filter_update);
1192}
1193