diff options
author | sumikawa <sumikawa@FreeBSD.org> | 2004-03-05 20:58:17 +0800 |
---|---|---|
committer | sumikawa <sumikawa@FreeBSD.org> | 2004-03-05 20:58:17 +0800 |
commit | 96456b678cfd62ea464b42b45d2135b2b3943982 (patch) | |
tree | 464e02b15327867470cb28fb0d795844fae9a6da /net/zebra/files | |
parent | 958673c756b1631a182082bad814320f49f0d356 (diff) | |
download | freebsd-ports-gnome-96456b678cfd62ea464b42b45d2135b2b3943982.tar.gz freebsd-ports-gnome-96456b678cfd62ea464b42b45d2135b2b3943982.tar.zst freebsd-ports-gnome-96456b678cfd62ea464b42b45d2135b2b3943982.zip |
Upgrade to 0.94.
Diffstat (limited to 'net/zebra/files')
-rw-r--r-- | net/zebra/files/patch-ospf6d | 3427 | ||||
-rw-r--r-- | net/zebra/files/patch-ospfd_packet.c | 11 | ||||
-rw-r--r-- | net/zebra/files/patch-remote_dos | 23 |
3 files changed, 0 insertions, 3461 deletions
diff --git a/net/zebra/files/patch-ospf6d b/net/zebra/files/patch-ospf6d deleted file mode 100644 index 8dce08ba2c3e..000000000000 --- a/net/zebra/files/patch-ospf6d +++ /dev/null @@ -1,3427 +0,0 @@ -diff -x CVS -urN ospf6d.old/ChangeLog ospf6d/ChangeLog ---- ospf6d.old/ChangeLog Sat Apr 26 23:17:47 2003 -+++ ospf6d/ChangeLog Fri Apr 25 11:40:31 2003 -@@ -1,3 +1,36 @@ -+2003-04-25 Yasuhiro Ohara <yasu@sfc.wide.ad.jp> -+ -+ * ospf6_asbr.c: AS-External LSA refresh was based on the -+ prefix of the obsolete LSA. It was wrong so fixed. -+ * version: 0.9.6p -+ -+2002-11-09 Vincent Jardin <jardin@6wind.com> -+ -+ * ospf6_interface.c: update link-local address on interface creation. -+ -+2002-11-09 Yasuhiro Ohara <yasu@sfc.wide.ad.jp> -+ -+ * ospf6_asbr.c: apply MinLSInterval to AS-External-LSA origination. -+ * ospf6_lsa.c: change not to issue flooding caused by expire event -+ when the received LSA is (already) MaxAge. -+ * ospf6_spf.c: fix a bug which is that ospf6d calculates -+ wrong nexthop when failed to find Link-LSA for the neighbor. -+ * ospf6_damp.c ospf6_dbex.c ospf6_neighbor.c ospf6_spf.c: -+ some clean up -+ * version: 0.9.6o -+ -+2002-10-04 Yasuhiro Ohara <yasu@sfc.wide.ad.jp> -+ -+ * ospf6_asbr.c: bug of failing ASE lsa refresh fixed. -+ * version: 0.9.6n -+ -+2002-10-01 Yasuhiro Ohara <yasu@sfc.wide.ad.jp> -+ -+ * ospf6_asbr.c: AS-External-LSA origination function -+ is re-written. -+ * ospf6_damp.[ch]: New feature that damps flaps is added. -+ * version: 0.9.6m -+ - 2002-07-14 Yasuhiro Ohara <yasu@sfc.wide.ad.jp> - - * ospf6_spf.c: unwanted assert() in ospf6_spf_nexthop_calculation() -diff -x CVS -urN ospf6d.old/Makefile.in ospf6d/Makefile.in ---- ospf6d.old/Makefile.in Sat Apr 26 23:17:47 2003 -+++ ospf6d/Makefile.in Thu Feb 20 01:31:12 2003 -@@ -1,4 +1,4 @@ --# Makefile.in generated by automake 1.6.2 from Makefile.am. -+# Makefile.in generated by automake 1.6.3 from Makefile.am. - # @configure_input@ - - # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 -@@ -111,9 +111,9 @@ - ospf6_neighbor.c ospf6_message.c ospf6_lsa.c ospf6_spf.c \ - ospf6_route.c ospf6_zebra.c ospf6_ism.c ospf6_dbex.c \ - ospf6_lsdb.c ospf6_prefix.c ospf6_top.c ospf6_area.c ospf6_nsm.c \ -- ospf6_redistribute.c ospf6_routemap.c ospf6_proto.c \ -+ ospf6_routemap.c ospf6_proto.c \ - ospf6_hook.c ospf6_asbr.c ospf6_bintree.c ospf6_linklist.c \ -- ospf6_abr.c ospf6_intra.c -+ ospf6_abr.c ospf6_intra.c ospf6_damp.c - - - noinst_HEADERS = \ -@@ -121,9 +121,9 @@ - ospf6_message.h ospf6_neighbor.h ospf6_network.h ospf6_proto.h \ - ospf6_spf.h ospf6_route.h ospf6_types.h ospf6_zebra.h ospf6d.h \ - ospf6_ism.h ospf6_dbex.h ospf6_lsdb.h ospf6_prefix.h \ -- ospf6_top.h ospf6_nsm.h ospf6_redistribute.h ospf6_routemap.h \ -+ ospf6_top.h ospf6_nsm.h ospf6_routemap.h \ - ospf6_hook.h ospf6_asbr.h ospf6_bintree.h ospf6_linklist.h \ -- ospf6_abr.h ospf6_intra.h -+ ospf6_abr.h ospf6_intra.h ospf6_damp.h - - - ospf6d_SOURCES = \ -@@ -150,10 +150,10 @@ - ospf6_zebra.$(OBJEXT) ospf6_ism.$(OBJEXT) ospf6_dbex.$(OBJEXT) \ - ospf6_lsdb.$(OBJEXT) ospf6_prefix.$(OBJEXT) ospf6_top.$(OBJEXT) \ - ospf6_area.$(OBJEXT) ospf6_nsm.$(OBJEXT) \ -- ospf6_redistribute.$(OBJEXT) ospf6_routemap.$(OBJEXT) \ -- ospf6_proto.$(OBJEXT) ospf6_hook.$(OBJEXT) ospf6_asbr.$(OBJEXT) \ -+ ospf6_routemap.$(OBJEXT) ospf6_proto.$(OBJEXT) \ -+ ospf6_hook.$(OBJEXT) ospf6_asbr.$(OBJEXT) \ - ospf6_bintree.$(OBJEXT) ospf6_linklist.$(OBJEXT) \ -- ospf6_abr.$(OBJEXT) ospf6_intra.$(OBJEXT) -+ ospf6_abr.$(OBJEXT) ospf6_intra.$(OBJEXT) ospf6_damp.$(OBJEXT) - libospf6_a_OBJECTS = $(am_libospf6_a_OBJECTS) - sbin_PROGRAMS = ospf6d$(EXEEXT) - PROGRAMS = $(sbin_PROGRAMS) -@@ -165,10 +165,10 @@ - ospf6_zebra.$(OBJEXT) ospf6_ism.$(OBJEXT) ospf6_dbex.$(OBJEXT) \ - ospf6_lsdb.$(OBJEXT) ospf6_prefix.$(OBJEXT) ospf6_top.$(OBJEXT) \ - ospf6_area.$(OBJEXT) ospf6_nsm.$(OBJEXT) \ -- ospf6_redistribute.$(OBJEXT) ospf6_routemap.$(OBJEXT) \ -- ospf6_proto.$(OBJEXT) ospf6_hook.$(OBJEXT) ospf6_asbr.$(OBJEXT) \ -+ ospf6_routemap.$(OBJEXT) ospf6_proto.$(OBJEXT) \ -+ ospf6_hook.$(OBJEXT) ospf6_asbr.$(OBJEXT) \ - ospf6_bintree.$(OBJEXT) ospf6_linklist.$(OBJEXT) \ -- ospf6_abr.$(OBJEXT) ospf6_intra.$(OBJEXT) -+ ospf6_abr.$(OBJEXT) ospf6_intra.$(OBJEXT) ospf6_damp.$(OBJEXT) - am_ospf6d_OBJECTS = ospf6_main.$(OBJEXT) $(am__objects_1) - ospf6d_OBJECTS = $(am_ospf6d_OBJECTS) - ospf6d_DEPENDENCIES = ../lib/libzebra.a -@@ -182,8 +182,8 @@ - @AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/ospf6_abr.Po \ - @AMDEP_TRUE@ ./$(DEPDIR)/ospf6_area.Po ./$(DEPDIR)/ospf6_asbr.Po \ - @AMDEP_TRUE@ ./$(DEPDIR)/ospf6_bintree.Po \ --@AMDEP_TRUE@ ./$(DEPDIR)/ospf6_dbex.Po ./$(DEPDIR)/ospf6_dump.Po \ --@AMDEP_TRUE@ ./$(DEPDIR)/ospf6_hook.Po \ -+@AMDEP_TRUE@ ./$(DEPDIR)/ospf6_damp.Po ./$(DEPDIR)/ospf6_dbex.Po \ -+@AMDEP_TRUE@ ./$(DEPDIR)/ospf6_dump.Po ./$(DEPDIR)/ospf6_hook.Po \ - @AMDEP_TRUE@ ./$(DEPDIR)/ospf6_interface.Po \ - @AMDEP_TRUE@ ./$(DEPDIR)/ospf6_intra.Po ./$(DEPDIR)/ospf6_ism.Po \ - @AMDEP_TRUE@ ./$(DEPDIR)/ospf6_linklist.Po \ -@@ -195,7 +195,6 @@ - @AMDEP_TRUE@ ./$(DEPDIR)/ospf6_nsm.Po \ - @AMDEP_TRUE@ ./$(DEPDIR)/ospf6_prefix.Po \ - @AMDEP_TRUE@ ./$(DEPDIR)/ospf6_proto.Po \ --@AMDEP_TRUE@ ./$(DEPDIR)/ospf6_redistribute.Po \ - @AMDEP_TRUE@ ./$(DEPDIR)/ospf6_route.Po \ - @AMDEP_TRUE@ ./$(DEPDIR)/ospf6_routemap.Po \ - @AMDEP_TRUE@ ./$(DEPDIR)/ospf6_spf.Po ./$(DEPDIR)/ospf6_top.Po \ -@@ -218,7 +217,7 @@ - - .SUFFIXES: - .SUFFIXES: .c .o .obj --$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) -+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) - cd $(top_srcdir) && \ - $(AUTOMAKE) --foreign ospf6d/Makefile - Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status -@@ -238,8 +237,7 @@ - p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ - if test -f $$p \ - ; then \ -- p1=`echo "$$p1" | sed -e 's,^.*/,,'`; \ -- f=`echo $$p1|sed '$(transform);s/$$/$(EXEEXT)/'`; \ -+ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ - echo " $(INSTALL_PROGRAM_ENV) $(sbinPROGRAMS_INSTALL) $$p $(DESTDIR)$(sbindir)/$$f"; \ - $(INSTALL_PROGRAM_ENV) $(sbinPROGRAMS_INSTALL) $$p $(DESTDIR)$(sbindir)/$$f; \ - else :; fi; \ -@@ -248,8 +246,7 @@ - uninstall-sbinPROGRAMS: - @$(NORMAL_UNINSTALL) - @list='$(sbin_PROGRAMS)'; for p in $$list; do \ -- f=`echo $$p|sed 's/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ -- f=`echo "$$f" | sed -e 's,^.*/,,'`; \ -+ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ - echo " rm -f $(DESTDIR)$(sbindir)/$$f"; \ - rm -f $(DESTDIR)$(sbindir)/$$f; \ - done -@@ -270,6 +267,7 @@ - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ospf6_area.Po@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ospf6_asbr.Po@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ospf6_bintree.Po@am__quote@ -+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ospf6_damp.Po@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ospf6_dbex.Po@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ospf6_dump.Po@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ospf6_hook.Po@am__quote@ -@@ -286,7 +284,6 @@ - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ospf6_nsm.Po@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ospf6_prefix.Po@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ospf6_proto.Po@am__quote@ --@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ospf6_redistribute.Po@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ospf6_route.Po@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ospf6_routemap.Po@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ospf6_spf.Po@am__quote@ -diff -x CVS -urN ospf6d.old/ospf6_abr.c ospf6d/ospf6_abr.c ---- ospf6d.old/ospf6_abr.c Sat Apr 26 23:17:47 2003 -+++ ospf6d/ospf6_abr.c Tue Oct 1 10:28:07 2002 -@@ -42,7 +42,7 @@ - - inet_ntop (AF_INET, &router_id, router_string, sizeof (router_string)); - -- zlog_info ("ABR: Finding router %s in area %s", router_string, area->str); -+ //zlog_info ("ABR: Finding router %s in area %s", router_string, area->str); - - memset (&abr_id, 0, sizeof (abr_id)); - abr_id.family = AF_UNSPEC; -diff -x CVS -urN ospf6d.old/ospf6_area.h ospf6d/ospf6_area.h ---- ospf6d.old/ospf6_area.h Sat Apr 26 23:17:47 2003 -+++ ospf6d/ospf6_area.h Sat Nov 9 11:25:30 2002 -@@ -62,6 +62,8 @@ - void (*func) (void *, int, void *)); - - struct thread *maxage_remover; -+ -+ struct thread *thread_router_lsa; - }; - - -diff -x CVS -urN ospf6d.old/ospf6_asbr.c ospf6d/ospf6_asbr.c ---- ospf6d.old/ospf6_asbr.c Sat Apr 26 23:17:47 2003 -+++ ospf6d/ospf6_asbr.c Fri Apr 25 11:40:31 2003 -@@ -1,5 +1,5 @@ - /* -- * Copyright (C) 2001 Yasuhiro Ohara -+ * Copyright (C) 2001-2002 Yasuhiro Ohara - * - * This file is part of GNU Zebra. - * -@@ -19,108 +19,641 @@ - * Boston, MA 02111-1307, USA. - */ - --#include "ospf6d.h" -+#include <zebra.h> -+ -+#include "log.h" -+#include "memory.h" -+#include "prefix.h" -+#include "command.h" -+#include "vty.h" -+#include "routemap.h" -+#include "table.h" -+#include "plist.h" -+#include "thread.h" -+ -+#include "ospf6_prefix.h" /* xxx for ospf6_asbr.h */ -+#include "ospf6_lsa.h" /* xxx for ospf6_asbr.h */ -+#include "ospf6_route.h" /* xxx for ospf6_asbr.h, ospf6_zebra.h */ -+#include "ospf6_zebra.h" -+#include "ospf6_asbr.h" -+#include "ospf6_damp.h" -+#include "ospf6_top.h" -+#include "ospf6_lsdb.h" -+#include "ospf6_proto.h" -+ -+extern struct thread_master *master; -+ -+struct route_table *external_table; -+struct -+{ -+ char *name; -+ struct route_map *map; -+} rmap [ZEBRA_ROUTE_MAX]; -+ -+static u_int32_t link_state_id = 0; -+ -+char * -+zroute_name[] = -+{ -+ "system", "kernel", "connected", "static", -+ "rip", "ripng", "ospf", "ospf6", "bgp", "unknown" -+}; -+char * -+zroute_abname[] = -+{ -+ "X", "K", "C", "S", "R", "R", "O", "O", "B", "?" -+}; -+ -+#define ZROUTE_NAME(x) \ -+ (0 < (x) && (x) < ZEBRA_ROUTE_MAX ? \ -+ zroute_name[(x)] : zroute_name[ZEBRA_ROUTE_MAX]) -+ -+#define ZROUTE_ABNAME(x) \ -+ (0 < (x) && (x) < ZEBRA_ROUTE_MAX ? \ -+ zroute_abname[(x)] : zroute_abname[ZEBRA_ROUTE_MAX]) -+ -+/* redistribute function */ -+void -+ospf6_asbr_routemap_set (int type, char *mapname) -+{ -+ if (rmap[type].name) -+ free (rmap[type].name); -+ -+ rmap[type].name = strdup (mapname); -+ rmap[type].map = route_map_lookup_by_name (mapname); -+} -+ -+void -+ospf6_asbr_routemap_unset (int type) -+{ -+ if (rmap[type].name) -+ free (rmap[type].name); -+ rmap[type].name = NULL; -+ rmap[type].map = NULL; -+} -+ -+void -+ospf6_asbr_routemap_update () -+{ -+ int i; -+ for (i = 0; i < ZEBRA_ROUTE_MAX; i++) -+ { -+ if (rmap[i].name) -+ rmap[i].map = route_map_lookup_by_name (rmap[i].name); -+ else -+ rmap[i].map = NULL; -+ } -+} -+ -+DEFUN (ospf6_redistribute, -+ ospf6_redistribute_cmd, -+ "redistribute (static|kernel|connected|ripng|bgp)", -+ "Redistribute\n" -+ "Static route\n" -+ "Kernel route\n" -+ "Connected route\n" -+ "RIPng route\n" -+ "BGP route\n" -+ ) -+{ -+ int type = 0; -+ -+ if (strncmp (argv[0], "sta", 3) == 0) -+ type = ZEBRA_ROUTE_STATIC; -+ else if (strncmp (argv[0], "ker", 3) == 0) -+ type = ZEBRA_ROUTE_KERNEL; -+ else if (strncmp (argv[0], "con", 3) == 0) -+ type = ZEBRA_ROUTE_CONNECT; -+ else if (strncmp (argv[0], "rip", 3) == 0) -+ type = ZEBRA_ROUTE_RIPNG; -+ else if (strncmp (argv[0], "bgp", 3) == 0) -+ type = ZEBRA_ROUTE_BGP; -+ -+ ospf6_zebra_no_redistribute (type); -+ ospf6_asbr_routemap_unset (type); -+ ospf6_zebra_redistribute (type); -+ return CMD_SUCCESS; -+} -+ -+DEFUN (ospf6_redistribute_routemap, -+ ospf6_redistribute_routemap_cmd, -+ "redistribute (static|kernel|connected|ripng|bgp) route-map WORD", -+ "Redistribute\n" -+ "Static routes\n" -+ "Kernel route\n" -+ "Connected route\n" -+ "RIPng route\n" -+ "BGP route\n" -+ "Route map reference\n" -+ "Route map name\n" -+ ) -+{ -+ int type = 0; -+ -+ if (strncmp (argv[0], "sta", 3) == 0) -+ type = ZEBRA_ROUTE_STATIC; -+ else if (strncmp (argv[0], "ker", 3) == 0) -+ type = ZEBRA_ROUTE_KERNEL; -+ else if (strncmp (argv[0], "con", 3) == 0) -+ type = ZEBRA_ROUTE_CONNECT; -+ else if (strncmp (argv[0], "rip", 3) == 0) -+ type = ZEBRA_ROUTE_RIPNG; -+ else if (strncmp (argv[0], "bgp", 3) == 0) -+ type = ZEBRA_ROUTE_BGP; -+ -+ ospf6_zebra_no_redistribute (type); -+ ospf6_asbr_routemap_set (type, argv[1]); -+ ospf6_zebra_redistribute (type); -+ return CMD_SUCCESS; -+} -+ -+DEFUN (no_ospf6_redistribute, -+ no_ospf6_redistribute_cmd, -+ "no redistribute (static|kernel|connected|ripng|bgp)", -+ NO_STR -+ "Redistribute\n" -+ "Static route\n" -+ "Kernel route\n" -+ "Connected route\n" -+ "RIPng route\n" -+ "BGP route\n" -+ ) -+{ -+ int type = 0; -+ struct route_node *node; -+ struct ospf6_external_route *route; -+ struct ospf6_external_info *info, *info_next = NULL; -+ -+ if (strncmp (argv[0], "sta", 3) == 0) -+ type = ZEBRA_ROUTE_STATIC; -+ else if (strncmp (argv[0], "ker", 3) == 0) -+ type = ZEBRA_ROUTE_KERNEL; -+ else if (strncmp (argv[0], "con", 3) == 0) -+ type = ZEBRA_ROUTE_CONNECT; -+ else if (strncmp (argv[0], "rip", 3) == 0) -+ type = ZEBRA_ROUTE_RIPNG; -+ else if (strncmp (argv[0], "bgp", 3) == 0) -+ type = ZEBRA_ROUTE_BGP; -+ -+ ospf6_zebra_no_redistribute (type); -+ ospf6_asbr_routemap_unset (type); -+ -+ /* remove redistributed route */ -+ for (node = route_top (external_table); node; node = route_next (node)) -+ { -+ route = node->info; -+ if (! route) -+ continue; -+ for (info = route->info_head; info; info = info_next) -+ { -+ info_next = info->next; -+ if (info->type != type) -+ continue; -+ ospf6_asbr_route_remove (info->type, info->ifindex, -+ &route->prefix); -+ } -+ } -+ -+ return CMD_SUCCESS; -+} -+ -+ -+int -+ospf6_redistribute_config_write (struct vty *vty) -+{ -+ int i; -+ -+ for (i = 0; i < ZEBRA_ROUTE_MAX; i++) -+ { -+ if (i == ZEBRA_ROUTE_OSPF6) -+ continue; -+ -+ if (! ospf6_zebra_is_redistribute (i)) -+ continue; -+ -+ if (rmap[i].map) -+ vty_out (vty, " redistribute %s route-map %s%s", -+ ZROUTE_NAME(i), rmap[i].name, VTY_NEWLINE); -+ else -+ vty_out (vty, " redistribute %s%s", -+ ZROUTE_NAME(i), VTY_NEWLINE); -+ } -+ -+ return 0; -+} - - void --ospf6_asbr_external_lsa_update (struct ospf6_route_req *request) -+ospf6_redistribute_show_config (struct vty *vty) - { -+ int i; -+ -+ if (! ospf6_zebra_is_redistribute(ZEBRA_ROUTE_SYSTEM) && -+ ! ospf6_zebra_is_redistribute(ZEBRA_ROUTE_KERNEL) && -+ ! ospf6_zebra_is_redistribute(ZEBRA_ROUTE_STATIC) && -+ ! ospf6_zebra_is_redistribute(ZEBRA_ROUTE_RIPNG) && -+ ! ospf6_zebra_is_redistribute(ZEBRA_ROUTE_BGP)) -+ return; -+ -+ vty_out (vty, " Redistributing External Routes from,%s", VTY_NEWLINE); -+ for (i = 0; i < ZEBRA_ROUTE_MAX; i++) -+ { -+ if (i == ZEBRA_ROUTE_OSPF6) -+ continue; -+ if (! ospf6_zebra_is_redistribute (i)) -+ continue; -+ -+ if (rmap[i].map) -+ vty_out (vty, " %s with route-map %s%s", -+ ZROUTE_NAME(i), rmap[i].name, VTY_NEWLINE); -+ else -+ vty_out (vty, " %s%s", ZROUTE_NAME(i), VTY_NEWLINE); -+ } -+} -+ -+/* AS External LSA origination */ -+int -+ospf6_asbr_external_lsa_originate (struct thread *thread) -+{ -+ struct ospf6_external_info *info; - char buffer [MAXLSASIZE]; -- u_int16_t size; -- struct ospf6_lsa_as_external *external; -+ struct ospf6_lsa_as_external *e; - char *p; -- struct ospf6_route_req route; -- char pbuf[BUFSIZ]; - -- /* assert this is best path; if not, return */ -- ospf6_route_lookup (&route, &request->route.prefix, request->table); -- if (memcmp (&route.path, &request->path, sizeof (route.path))) -- return; -+ info = THREAD_ARG (thread); - -- if (IS_OSPF6_DUMP_LSA) -- zlog_info ("Update AS-External: ID: %lu", -- (u_long) ntohl (request->path.origin.id)); -+ /* clear thread */ -+ info->thread_originate = NULL; -+ -+ if (info->is_removed) -+ { -+ if (IS_OSPF6_DUMP_ASBR) -+ { -+ char pbuf[64]; -+ prefix2str (&info->route->prefix, pbuf, sizeof (pbuf)); -+ zlog_info ("ASBR: quit redistribution %s: state is down", -+ pbuf); -+ } -+ return 0; -+ } - - /* prepare buffer */ - memset (buffer, 0, sizeof (buffer)); -- size = sizeof (struct ospf6_lsa_as_external); -- external = (struct ospf6_lsa_as_external *) buffer; -- p = (char *) (external + 1); -+ e = (struct ospf6_lsa_as_external *) buffer; -+ p = (char *) (e + 1); - -- if (route.path.metric_type == 2) -- SET_FLAG (external->bits_metric, OSPF6_ASBR_BIT_E); /* type2 */ -+ if (info->metric_type == 2) -+ SET_FLAG (e->bits_metric, OSPF6_ASBR_BIT_E); /* type2 */ - else -- UNSET_FLAG (external->bits_metric, OSPF6_ASBR_BIT_E); /* type1 */ -+ UNSET_FLAG (e->bits_metric, OSPF6_ASBR_BIT_E); /* type1, default */ - - /* forwarding address */ -- if (! IN6_IS_ADDR_UNSPECIFIED (&route.nexthop.address)) -- SET_FLAG (external->bits_metric, OSPF6_ASBR_BIT_F); -+ if (! IN6_IS_ADDR_UNSPECIFIED (&info->forwarding)) -+ SET_FLAG (e->bits_metric, OSPF6_ASBR_BIT_F); - else -- UNSET_FLAG (external->bits_metric, OSPF6_ASBR_BIT_F); -+ UNSET_FLAG (e->bits_metric, OSPF6_ASBR_BIT_F); - - /* external route tag */ -- UNSET_FLAG (external->bits_metric, OSPF6_ASBR_BIT_T); -+ UNSET_FLAG (e->bits_metric, OSPF6_ASBR_BIT_T); - - /* set metric. note: related to E bit */ -- OSPF6_ASBR_METRIC_SET (external, route.path.cost); -+ OSPF6_ASBR_METRIC_SET (e, info->metric); - - /* prefixlen */ -- external->prefix.prefix_length = route.route.prefix.prefixlen; -+ e->prefix.prefix_length = info->route->prefix.prefixlen; - - /* PrefixOptions */ -- external->prefix.prefix_options = route.path.prefix_options; -+ e->prefix.prefix_options = info->prefix_options; - - /* don't use refer LS-type */ -- external->prefix.prefix_refer_lstype = htons (0); -- -- if (IS_OSPF6_DUMP_LSA) -- { -- prefix2str (&route.route.prefix, pbuf, sizeof (pbuf)); -- zlog_info (" Prefix: %s", pbuf); -- } -+ e->prefix.prefix_refer_lstype = htons (0); - - /* set Prefix */ -- memcpy (p, &route.route.prefix.u.prefix6, -- OSPF6_PREFIX_SPACE (route.route.prefix.prefixlen)); -- ospf6_prefix_apply_mask (&external->prefix); -- size += OSPF6_PREFIX_SPACE (route.route.prefix.prefixlen); -- p += OSPF6_PREFIX_SPACE (route.route.prefix.prefixlen); -+ memcpy (p, &info->route->prefix.u.prefix6, -+ OSPF6_PREFIX_SPACE (info->route->prefix.prefixlen)); -+ ospf6_prefix_apply_mask (&e->prefix); -+ p += OSPF6_PREFIX_SPACE (info->route->prefix.prefixlen); - - /* Forwarding address */ -- if (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_F)) -+ if (CHECK_FLAG (e->bits_metric, OSPF6_ASBR_BIT_F)) - { -- memcpy (p, &route.nexthop.address, sizeof (struct in6_addr)); -- size += sizeof (struct in6_addr); -+ memcpy (p, &info->forwarding, sizeof (struct in6_addr)); - p += sizeof (struct in6_addr); - } - - /* External Route Tag */ -- if (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_T)) -+ if (CHECK_FLAG (e->bits_metric, OSPF6_ASBR_BIT_T)) - { - /* xxx */ - } - - ospf6_lsa_originate (htons (OSPF6_LSA_TYPE_AS_EXTERNAL), -- route.path.origin.id, ospf6->router_id, -- (char *) external, size, ospf6); -- return; -+ htonl (info->id), ospf6->router_id, -+ (char *) buffer, p - buffer, ospf6); -+ return 0; -+} -+ -+int -+ospf6_asbr_schedule_external (void *data) -+{ -+ struct ospf6_external_info *info = data; -+ u_long elasped_time, time = 0; -+ -+ if (info->thread_originate) -+ { -+ if (IS_OSPF6_DUMP_ASBR) -+ { -+ char pbuf[64]; -+ prefix2str (&info->route->prefix, pbuf, sizeof (pbuf)); -+ zlog_info ("ASBR: schedule redistribution %s: another thread", -+ pbuf); -+ } -+ return 0; -+ } -+ -+ elasped_time = -+ ospf6_lsa_has_elasped (htons (OSPF6_LSA_TYPE_AS_EXTERNAL), -+ htonl (info->id), ospf6->router_id, ospf6); -+ if (elasped_time < OSPF6_MIN_LS_INTERVAL) -+ time = OSPF6_MIN_LS_INTERVAL - elasped_time; -+ else -+ time = 0; -+ -+ //if (IS_OSPF6_DUMP_ASBR) -+ { -+ char pbuf[64]; -+ prefix2str (&info->route->prefix, pbuf, sizeof (pbuf)); -+ zlog_info ("ASBR: schedule redistribution %s as LS-ID %ld after %lu sec", -+ pbuf, (u_long) info->id, time); -+ } -+ -+ if (time) -+ info->thread_originate = -+ thread_add_timer (master, ospf6_asbr_external_lsa_originate, info, time); -+ else -+ info->thread_originate = -+ thread_add_timer (master, ospf6_asbr_external_lsa_originate, info, 0); -+ -+ return 0; -+} -+ -+int -+ospf6_asbr_external_lsa_flush (void *data) -+{ -+ struct ospf6_lsa *lsa = data; -+ if (lsa) -+ ospf6_lsa_premature_aging (lsa); -+ return 0; -+} -+ -+int -+ospf6_asbr_external_lsa_refresh (void *data) -+{ -+ struct ospf6_lsa *lsa = data; -+ struct ospf6_lsa_as_external *e; -+ struct prefix prefix; -+ struct route_node *node; -+ struct ospf6_external_route *route = NULL; -+ struct ospf6_external_info *info = NULL; -+ struct ospf6_external_info *match = NULL; -+ -+ if (IS_OSPF6_DUMP_ASBR) -+ zlog_info ("ASBR: refresh %s", lsa->str); -+ -+ e = (struct ospf6_lsa_as_external *) (lsa->header + 1); -+ ospf6_prefix_in6_addr (&e->prefix, &prefix.u.prefix6); -+ prefix.prefixlen = e->prefix.prefix_length; -+ prefix.family = AF_INET6; -+ apply_mask_ipv6 ((struct prefix_ipv6 *) &prefix); -+ -+ for (node = route_top (external_table); node; node = route_next (node)) -+ { -+ route = node->info; -+ if (route == NULL) -+ continue; -+ -+ for (info = route->info_head; info; info = info->next) -+ { -+ if (lsa->header->id == htonl (info->id)) -+ match = info; -+ } -+ } -+ -+ if (match == NULL) -+ { -+ ospf6_lsa_premature_aging (lsa); -+ return 0; -+ } -+ -+ ospf6_asbr_schedule_external (match); -+ return 0; -+ -+#if 0 -+ node = route_node_lookup (external_table, &prefix); -+ if (! node || ! node->info) -+ { -+ char pname[64]; -+ -+ prefix2str (&prefix, pname, sizeof (pname)); -+ if (IS_OSPF6_DUMP_ASBR) -+ zlog_info ("ASBR: could not find %s: premature age", pname); -+ ospf6_lsa_premature_aging (lsa); -+ return 0; -+ } -+ -+ /* find external_info */ -+ route = node->info; -+ for (info = route->info_head; info; info = info->next) -+ { -+ if (lsa->header->id == htonl (info->id)) -+ break; -+ } -+ -+ if (info) -+ ospf6_asbr_schedule_external (info); -+ else -+ ospf6_lsa_premature_aging (lsa); -+ -+ return 0; -+#endif - } - - void --ospf6_asbr_external_route_add (struct ospf6_route_req *route) -+ospf6_asbr_route_add (int type, int ifindex, struct prefix *prefix, -+ u_int nexthop_num, struct in6_addr *nexthop) - { -- ospf6_asbr_external_lsa_update (route); -+ int ret; -+ struct route_node *node; -+ struct ospf6_external_route *route; -+ struct ospf6_external_info *info, tinfo; -+ -+ if (! ospf6_zebra_is_redistribute (type)) -+ return; -+ -+ /* apply route-map */ -+ memset (&tinfo, 0, sizeof (struct ospf6_external_info)); -+ if (rmap[type].map) -+ { -+ ret = route_map_apply (rmap[type].map, prefix, RMAP_OSPF6, &tinfo); -+ if (ret == RMAP_DENYMATCH) -+ { -+ if (IS_OSPF6_DUMP_ASBR) -+ zlog_info ("ASBR: denied by route-map %s", rmap[type].name); -+ return; -+ } -+ } -+ -+ node = route_node_get (external_table, prefix); -+ route = node->info; -+ -+ if (! route) -+ { -+ route = XMALLOC (MTYPE_OSPF6_EXTERNAL_INFO, -+ sizeof (struct ospf6_external_route)); -+ memset (route, 0, sizeof (struct ospf6_external_route)); -+ -+ memcpy (&route->prefix, prefix, sizeof (struct prefix)); -+ -+ node->info = route; -+ route->node = node; -+ } -+ -+ for (info = route->info_head; info; info = info->next) -+ { -+ if (info->type == type && info->ifindex == ifindex) -+ break; -+ } -+ -+ if (! info) -+ { -+ info = XMALLOC (MTYPE_OSPF6_EXTERNAL_INFO, -+ sizeof (struct ospf6_external_info)); -+ memset (info, 0, sizeof (struct ospf6_external_info)); -+ -+ info->route = route; -+ /* add tail */ -+ info->prev = route->info_tail; -+ if (route->info_tail) -+ route->info_tail->next = info; -+ else -+ route->info_head = info; -+ route->info_tail = info; -+ -+ info->id = link_state_id++; -+ } -+ -+ /* copy result of route-map */ -+ info->metric_type = tinfo.metric_type; -+ info->metric = tinfo.metric; -+ memcpy (&info->forwarding, &tinfo.forwarding, -+ sizeof (struct in6_addr)); -+ -+ info->type = type; -+ info->ifindex = ifindex; -+ -+ if (nexthop_num && nexthop) -+ { -+ info->nexthop_num = nexthop_num; -+ -+ if (info->nexthop) -+ XFREE (MTYPE_OSPF6_EXTERNAL_INFO, info->nexthop); -+ -+ info->nexthop = (struct in6_addr *) -+ XMALLOC (MTYPE_OSPF6_EXTERNAL_INFO, -+ nexthop_num * sizeof (struct in6_addr)); -+ memcpy (info->nexthop, nexthop, -+ nexthop_num * sizeof (struct in6_addr)); -+ } -+ -+ info->is_removed = 0; -+ -+ //if (IS_OSPF6_DUMP_ASBR) -+ { -+ char pbuf[64]; -+ struct timeval now; -+ prefix2str (&info->route->prefix, pbuf, sizeof (pbuf)); -+ gettimeofday (&now, NULL); -+ zlog_info ("ASBR: start redistributing %s as LS-ID %ld: %ld.%06ld", -+ pbuf, (u_long) info->id, now.tv_sec, now.tv_usec); -+ } -+ -+#ifdef HAVE_OSPF6_DAMP -+ ospf6_damp_event_up (OSPF6_DAMP_TYPE_ROUTE, prefix, -+ ospf6_asbr_schedule_external, info); -+#else /*HAVE_OSPF6_DAMP*/ -+ ospf6_asbr_schedule_external (info); -+#endif /*HAVE_OSPF6_DAMP*/ - } - - void --ospf6_asbr_external_route_remove (struct ospf6_route_req *route) -+ospf6_asbr_route_remove (int type, int ifindex, struct prefix *prefix) - { -+ struct route_node *node; -+ struct ospf6_external_route *route; -+ struct ospf6_external_info *info; - struct ospf6_lsa *lsa; - -- lsa = ospf6_lsdb_lookup_lsdb (htons (OSPF6_LSA_TYPE_AS_EXTERNAL), -- route->path.origin.id, -- ospf6->router_id, ospf6->lsdb); -- if (lsa) -- ospf6_lsa_premature_aging (lsa); -+ node = route_node_get (external_table, prefix); -+ route = node->info; -+ -+ if (! route) -+ return; -+ -+ for (info = route->info_head; info; info = info->next) -+ { -+ if (info->type == type && info->ifindex == ifindex) -+ break; -+ } -+ -+ if (! info) -+ return; -+ -+ //if (IS_OSPF6_DUMP_ASBR) -+ { -+ char pbuf[64]; -+ struct timeval now; -+ prefix2str (&info->route->prefix, pbuf, sizeof (pbuf)); -+ gettimeofday (&now, NULL); -+ zlog_info ("ASBR: quit redistributing %s as LS-ID %ld: %ld.%06ld", -+ pbuf, (u_long) info->id, now.tv_sec, now.tv_usec); -+ } -+ -+ if (info->thread_originate) -+ thread_cancel (info->thread_originate); -+ info->thread_originate = NULL; -+ -+ lsa = ospf6_lsdb_lookup (htons (OSPF6_LSA_TYPE_AS_EXTERNAL), -+ htonl (info->id), ospf6->router_id, ospf6); -+#ifdef HAVE_OSPF6_DAMP -+ ospf6_damp_event_down (OSPF6_DAMP_TYPE_ROUTE, &info->route->prefix, -+ ospf6_asbr_external_lsa_flush, lsa); -+#else /*HAVE_OSPF6_DAMP*/ -+ ospf6_asbr_external_lsa_flush (lsa); -+#endif /*HAVE_OSPF6_DAMP*/ -+ -+#if 1 -+ info->is_removed = 1; -+#else -+ /* remove from route */ -+ if (info->prev) -+ info->prev->next = info->next; -+ else -+ info->route->info_head = info->next; -+ if (info->next) -+ info->next->prev = info->prev; -+ else -+ info->route->info_tail = info->prev; -+ -+ /* if no info, free route */ -+ if (! info->route->info_head && ! info->route->info_tail) -+ { -+ info->route->node->info = NULL; -+ free (info->route); -+ } -+ -+ if (info->nexthop) -+ free (info->nexthop); -+ free (info); -+#endif /*0*/ - } - - void -@@ -134,22 +667,29 @@ - external = OSPF6_LSA_HEADER_END (lsa->header); - - if (IS_LSA_MAXAGE (lsa)) -- return; -+ { -+ if (IS_OSPF6_DUMP_ASBR) -+ zlog_info ("ASBR: maxage external lsa: %s seq: %lx", -+ lsa->str, (u_long)ntohl (lsa->header->seqnum)); -+ ospf6_asbr_external_lsa_remove (lsa); -+ return; -+ } - - if (IS_OSPF6_DUMP_ASBR) -- zlog_info ("ASBR: Calculate %s", lsa->str); -+ zlog_info ("ASBR: new external lsa: %s seq: %lx", -+ lsa->str, (u_long)ntohl (lsa->header->seqnum)); - - if (lsa->header->adv_router == ospf6->router_id) - { - if (IS_OSPF6_DUMP_ASBR) -- zlog_info ("ASBR: Self-originated, ignore"); -+ zlog_info ("ASBR: my external LSA, ignore"); - return; - } - - if (OSPF6_ASBR_METRIC (external) == LS_INFINITY) - { - if (IS_OSPF6_DUMP_ASBR) -- zlog_info ("ASBR: Metric is Infinity, ignore"); -+ zlog_info ("ASBR: metric is infinity, ignore"); - return; - } - -@@ -167,7 +707,7 @@ - { - char buf[64]; - inet_ntop (AF_INET, &asbr_id.adv_router, buf, sizeof (buf)); -- zlog_info ("ASBR: ASBR %s not found, ignore", buf); -+ zlog_info ("ASBR: router %s not found, ignore", buf); - } - return; - } -@@ -206,6 +746,14 @@ - { - memcpy (&request.nexthop, &asbr_entry.nexthop, - sizeof (struct ospf6_nexthop)); -+ if (IS_OSPF6_DUMP_ASBR) -+ { -+ char buf[64], nhop[64], ifname[IFNAMSIZ]; -+ prefix2str (&request.route.prefix, buf, sizeof (buf)); -+ inet_ntop (AF_INET6, &request.nexthop.address, nhop, sizeof (nhop)); -+ if_indextoname (request.nexthop.ifindex, ifname); -+ zlog_info ("ASBR: add route: %s %s%%%s", buf, nhop, ifname); -+ } - ospf6_route_add (&request, ospf6->route_table); - ospf6_route_next (&asbr_entry); - } -@@ -220,12 +768,13 @@ - struct ospf6_route_req request; - - if (IS_OSPF6_DUMP_ASBR) -- zlog_info ("ASBR: Withdraw route of %s", lsa->str); -+ zlog_info ("ASBR: withdraw external lsa: %s seq: %lx", -+ lsa->str, (u_long)ntohl (lsa->header->seqnum)); - - if (lsa->header->adv_router == ospf6->router_id) - { - if (IS_OSPF6_DUMP_ASBR) -- zlog_info ("ASBR: Self-originated, ignore"); -+ zlog_info ("ASBR: my external LSA, ignore"); - return; - } - -@@ -236,14 +785,14 @@ - memcpy (&dest.u.prefix6, (char *)(external + 1), - OSPF6_PREFIX_SPACE (dest.prefixlen)); - -- prefix2str (&dest, buf, sizeof (buf)); -- if (IS_OSPF6_DUMP_ASBR) -- zlog_info ("ASBR: route: %s", buf); -- - ospf6_route_lookup (&request, &dest, ospf6->route_table); - if (ospf6_route_end (&request)) - { -- zlog_info ("ASBR: route not found"); -+ if (IS_OSPF6_DUMP_ASBR) -+ { -+ prefix2str (&dest, buf, sizeof (buf)); -+ zlog_info ("ASBR: %s not found", buf); -+ } - return; - } - -@@ -252,7 +801,8 @@ - { - if (prefix_same (&request.route.prefix, &dest) != 1) - { -- zlog_info ("ASBR: Can't find the entry matches the origin"); -+ if (IS_OSPF6_DUMP_ASBR) -+ zlog_info ("ASBR: Can't find the entry matches the origin"); - return; - } - ospf6_route_next (&request); -@@ -264,6 +814,15 @@ - request.path.origin.adv_router == lsa->header->adv_router && - prefix_same (&request.route.prefix, &dest) == 1) - { -+ if (IS_OSPF6_DUMP_ASBR) -+ { -+ char nhop[64], ifname[IFNAMSIZ]; -+ prefix2str (&dest, buf, sizeof (buf)); -+ inet_ntop (AF_INET6, &request.nexthop.address, nhop, sizeof (nhop)); -+ if_indextoname (request.nexthop.ifindex, ifname); -+ zlog_info ("ASBR: remove route: %s %s%%%s", buf, nhop, ifname); -+ } -+ - ospf6_route_remove (&request, ospf6->route_table); - ospf6_route_next (&request); - } -@@ -303,7 +862,7 @@ - { - char buf[64]; - inet_ntop (AF_INET, &inter_router->adv_router, buf, sizeof (buf)); -- zlog_info ("ASBR: New router found: %s", buf); -+ zlog_info ("ASBR: new router found: %s", buf); - } - - if (ntohl (id) != 0 || -@@ -335,7 +894,7 @@ - { - char buf[64]; - inet_ntop (AF_INET, &inter_router->adv_router, buf, sizeof (buf)); -- zlog_info ("ASBR: Router disappearing: %s", buf); -+ zlog_info ("ASBR: router disappearing: %s", buf); - } - - if (ntohl (id) != 0 || -@@ -410,37 +969,6 @@ - return 0; - } - --int --ospf6_asbr_external_refresh (void *old) --{ -- struct ospf6_lsa *lsa = old; -- struct ospf6_route_req route, *target; -- -- assert (ospf6); -- -- if (IS_OSPF6_DUMP_ASBR) -- zlog_info ("ASBR: refresh %s", lsa->str); -- -- target = NULL; -- for (ospf6_route_head (&route, ospf6->external_table); -- ! ospf6_route_end (&route); -- ospf6_route_next (&route)) -- { -- if (route.path.origin.id == lsa->header->id) -- { -- target = &route; -- break; -- } -- } -- -- if (target) -- ospf6_asbr_external_lsa_update (target); -- else -- ospf6_lsa_premature_aging (lsa); -- -- return 0; --} -- - void - ospf6_asbr_database_hook (struct ospf6_lsa *old, struct ospf6_lsa *new) - { -@@ -459,7 +987,7 @@ - slot.type = htons (OSPF6_LSA_TYPE_AS_EXTERNAL); - slot.name = "AS-External"; - slot.func_show = ospf6_asbr_external_show; -- slot.func_refresh = ospf6_asbr_external_refresh; -+ slot.func_refresh = ospf6_asbr_external_lsa_refresh; - ospf6_lsa_slot_register (&slot); - - ospf6_lsdb_hook[OSPF6_LSA_TYPE_AS_EXTERNAL & OSPF6_LSTYPE_CODE_MASK].hook = -@@ -467,9 +995,71 @@ - } - - void -+ospf6_asbr_external_info_show (struct vty *vty, -+ struct ospf6_external_info *info) -+{ -+ char prefix_buf[64], id_buf[16]; -+ struct in_addr id; -+ -+ if (info->is_removed) -+ return; -+ -+ id.s_addr = ntohl (info->id); -+ inet_ntop (AF_INET, &id, id_buf, sizeof (id_buf)); -+ prefix2str (&info->route->prefix, prefix_buf, sizeof (prefix_buf)); -+ vty_out (vty, "%s %-32s %3d %-15s %3d %lu(type-%d)%s", -+ ZROUTE_ABNAME(info->type), prefix_buf, info->ifindex, id_buf, -+ info->nexthop_num, (u_long) info->metric, info->metric_type, -+ VTY_NEWLINE); -+} -+ -+void -+ospf6_asbr_external_route_show (struct vty *vty, -+ struct ospf6_external_route *route) -+{ -+ struct ospf6_external_info *info; -+ for (info = route->info_head; info; info = info->next) -+ ospf6_asbr_external_info_show (vty, info); -+} -+ -+DEFUN (show_ipv6_route_ospf6_external, -+ show_ipv6_route_ospf6_external_cmd, -+ "show ipv6 ospf6 route redistribute", -+ SHOW_STR -+ IP6_STR -+ ROUTE_STR -+ OSPF6_STR -+ "redistributing External information\n" -+ ) -+{ -+ struct route_node *node; -+ struct ospf6_external_route *route; -+ -+ vty_out (vty, "%s %-32s %3s %-15s %3s %s%s", -+ " ", "Prefix", "I/F", "LS-Id", "#NH", "Metric", -+ VTY_NEWLINE); -+ for (node = route_top (external_table); node; node = route_next (node)) -+ { -+ route = node->info; -+ if (route) -+ ospf6_asbr_external_route_show (vty, route); -+ } -+ return CMD_SUCCESS; -+} -+ -+void - ospf6_asbr_init () - { -+ external_table = route_table_init (); -+ link_state_id = 0; -+ - ospf6_asbr_register_as_external (); -+ -+ install_element (VIEW_NODE, &show_ipv6_route_ospf6_external_cmd); -+ install_element (ENABLE_NODE, &show_ipv6_route_ospf6_external_cmd); -+ install_element (OSPF6_NODE, &ospf6_redistribute_cmd); -+ install_element (OSPF6_NODE, &ospf6_redistribute_routemap_cmd); -+ install_element (OSPF6_NODE, &no_ospf6_redistribute_cmd); - } - - -diff -x CVS -urN ospf6d.old/ospf6_asbr.h ospf6d/ospf6_asbr.h ---- ospf6d.old/ospf6_asbr.h Sat Apr 26 23:17:47 2003 -+++ ospf6d/ospf6_asbr.h Sat Nov 9 11:25:30 2002 -@@ -22,6 +22,51 @@ - #ifndef OSPF6_ASBR_H - #define OSPF6_ASBR_H - -+#include "thread.h" -+ -+struct ospf6_external_info -+{ -+ int is_removed; -+ struct thread *thread_originate; -+ -+ struct ospf6_external_route *route; -+ -+ struct ospf6_external_info *prev; -+ struct ospf6_external_info *next; -+ -+ /* external route type */ -+ int type; -+ -+ /* external route ifindex */ -+ int ifindex; -+ -+ /* LS-ID */ -+ u_int32_t id; -+ -+ /* nexthops */ -+ u_int nexthop_num; -+ struct in6_addr *nexthop; -+ -+ u_int8_t prefix_options; -+ -+ u_int8_t metric_type; -+ u_int32_t metric; -+ struct in6_addr forwarding; -+ /* u_int32_t tag; */ -+}; -+ -+struct ospf6_external_route -+{ -+ struct route_node *node; -+ -+ /* prefix */ -+ struct prefix prefix; -+ -+ /* external information */ -+ struct ospf6_external_info *info_head; -+ struct ospf6_external_info *info_tail; -+}; -+ - /* AS-External-LSA */ - struct ospf6_lsa_as_external - { -@@ -42,8 +87,16 @@ - { (E)->bits_metric &= htonl (0xff000000); \ - (E)->bits_metric |= htonl (0x00ffffff) & htonl (C); } - --void ospf6_asbr_external_route_add (struct ospf6_route_req *route); --void ospf6_asbr_external_route_remove (struct ospf6_route_req *route); -+void ospf6_asbr_routemap_update (); -+ -+int ospf6_redistribute_config_write (struct vty *vty); -+void ospf6_redistribute_show_config (struct vty *vty); -+ -+void -+ospf6_asbr_route_add (int type, int ifindex, struct prefix *prefix, -+ u_int nexthop_num, struct in6_addr *nexthop); -+void -+ospf6_asbr_route_remove (int type, int ifindex, struct prefix *prefix); - - void ospf6_asbr_external_lsa_add (struct ospf6_lsa *lsa); - void ospf6_asbr_external_lsa_remove (struct ospf6_lsa *lsa); -diff -x CVS -urN ospf6d.old/ospf6_damp.c ospf6d/ospf6_damp.c ---- ospf6d.old/ospf6_damp.c Thu Jan 1 01:00:00 1970 -+++ ospf6d/ospf6_damp.c Sat Nov 9 11:25:30 2002 -@@ -0,0 +1,748 @@ -+/* -+ * OSPF flap dampening by Manav Bhatia -+ * Copyright (C) 2002 -+ * -+ * This file is part of GNU Zebra. -+ * -+ * GNU Zebra is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2, or (at your option) any -+ * later version. -+ * -+ * GNU Zebra is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GNU Zebra; see the file COPYING. If not, write to the Free -+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -+ * 02111-1307, USA. -+ */ -+ -+#include <zebra.h> -+#include <math.h> -+ -+#include "log.h" -+#include "prefix.h" -+#include "thread.h" -+#include "table.h" -+#include "command.h" -+#include "vty.h" -+ -+extern struct thread_master *master; -+ -+#include "ospf6_damp.h" -+ -+#ifdef HAVE_OSPF6_DAMP -+ -+#define DELTA_REUSE 10 /* Time granularity for reuse lists */ -+#define DELTA_T 5 /* Time granularity for decay arrays */ -+#define DEFAULT_HALF_LIFE 60 /* (sec) 1 min */ -+ -+#define DEFAULT_PENALTY 1000 -+#define DEFAULT_REUSE 750 -+#define DEFAULT_SUPPRESS 2000 -+ -+#define REUSE_LIST_SIZE 256 -+#define REUSE_ARRAY_SIZE 1024 -+ -+/* Global variable to access damping configuration */ -+struct ospf6_damp_config damp_config; -+struct ospf6_damp_config *dc = &damp_config; -+u_int reuse_array_offset = 0; -+struct route_table *damp_info_table[OSPF6_DAMP_TYPE_MAX]; -+struct thread *ospf6_reuse_thread = NULL; -+ -+int ospf6_damp_debug = 0; -+#define IS_OSPF6_DEBUG_DAMP (ospf6_damp_debug) -+ -+static struct ospf6_damp_info * -+ospf6_damp_lookup (u_short type, struct prefix *name) -+{ -+ struct route_node *node; -+ -+ node = route_node_lookup (damp_info_table[type], name); -+ if (node && node->info) -+ return (struct ospf6_damp_info *) node->info; -+ return NULL; -+} -+ -+static struct ospf6_damp_info * -+ospf6_damp_create (u_short type, struct prefix *name) -+{ -+ struct route_node *node; -+ struct ospf6_damp_info *di; -+ char namebuf[64]; -+ -+ di = ospf6_damp_lookup (type, name); -+ if (di) -+ return di; -+ -+ if (IS_OSPF6_DEBUG_DAMP) -+ { -+ prefix2str (name, namebuf, sizeof (namebuf)); -+ zlog_info ("DAMP: create: type: %d, name: %s", type, namebuf); -+ } -+ -+ di = (struct ospf6_damp_info *) -+ malloc (sizeof (struct ospf6_damp_info)); -+ memset (di, 0, sizeof (struct ospf6_damp_info)); -+ di->type = type; -+ prefix_copy (&di->name, name); -+ -+ node = route_node_get (damp_info_table[type], name); -+ node->info = di; -+ -+ return di; -+} -+ -+static void -+ospf6_damp_delete (u_short type, struct prefix *name) -+{ -+ struct route_node *node; -+ struct ospf6_damp_info *di; -+ char namebuf[64]; -+ -+ node = route_node_lookup (damp_info_table[type], name); -+ if (! node || ! node->info) -+ return; -+ -+ di = node->info; -+ -+ if (IS_OSPF6_DEBUG_DAMP) -+ { -+ prefix2str (&di->name, namebuf, sizeof (namebuf)); -+ zlog_info ("DAMP: delete: type: %d, name: %s", -+ di->type, namebuf); -+ } -+ -+ node->info = NULL; -+ free (di); -+} -+ -+/* compute and fill the configuration parameter */ -+void -+ospf6_damp_init_config (u_int half_life, u_int reuse, -+ u_int suppress, u_int t_hold) -+{ -+ int i; -+ double max_ratio, max_ratio1, max_ratio2; -+ -+ dc->half_life = half_life ? half_life : DEFAULT_HALF_LIFE; -+ dc->reuse = reuse ? reuse : DEFAULT_REUSE; -+ dc->suppress = suppress ? suppress : DEFAULT_SUPPRESS; -+ dc->t_hold = t_hold ? t_hold : 4 * dc->half_life; -+ -+ /* Initialize system-wide params */ -+ dc->delta_t = DELTA_T; -+ dc->delta_reuse = DELTA_REUSE; -+ dc->default_penalty = DEFAULT_PENALTY; -+ dc->reuse_index_array_size = REUSE_ARRAY_SIZE; -+ -+ /* ceiling is the maximum penalty a route may attain */ -+ /* ceiling = reuse * 2^(T-hold/half-life) */ -+ dc->ceiling = (int) -+ (dc->reuse * (pow (2, (double) dc->t_hold / dc->half_life))); -+ -+ /* Decay-array computations */ -+ /* decay_array_size = decay memory/time granularity */ -+ dc->decay_array_size = ceil ((double) dc->t_hold / dc->delta_t); -+ dc->decay_array = malloc (sizeof (double) * (dc->decay_array_size)); -+ -+ /* Each i-th element is per tick delay raised to the i-th power */ -+ dc->decay_array[0] = 1.0; -+ dc->decay_array[1] = exp ((1.0 / (dc->half_life / dc->delta_t)) * log (0.5)); -+ for (i = 2; i < dc->decay_array_size; i++) -+ dc->decay_array[i] = dc->decay_array[i - 1] * dc->decay_array[1]; -+ -+ /* Reuse-list computations (reuse queue head array ?) */ -+ dc->reuse_list_size = ceil ((double) dc->t_hold / dc->delta_reuse) + 1; -+ if (dc->reuse_list_size == 0 || dc->reuse_list_size > REUSE_LIST_SIZE) -+ dc->reuse_list_size = REUSE_LIST_SIZE; -+ dc->reuse_list_array = (struct ospf6_damp_info **) -+ malloc (dc->reuse_list_size * sizeof (struct ospf6_reuse_list *)); -+ memset (dc->reuse_list_array, 0x00, -+ dc->reuse_list_size * sizeof (struct ospf6_reuse_list *)); -+ -+ /* Reuse-array computations */ -+ dc->reuse_index_array = malloc (sizeof (int) * dc->reuse_index_array_size); -+ -+ /* -+ * This is the maximum ratio between the current value of the penalty and -+ * the reuse value which can be indexed by the reuse array. It will be -+ * limited by the ceiling or by the amount of time that the reuse list -+ * covers -+ */ -+ max_ratio1 = (double) dc->ceiling / dc->reuse; -+ max_ratio2 = exp ((double) dc->t_hold / dc->half_life) * log10 (2.0); -+ max_ratio = (max_ratio2 != 0 && max_ratio2 < max_ratio1 ? -+ max_ratio2 : max_ratio1); -+ -+ /* -+ * reuse array is just an estimator and we need something -+ * to use the full array -+ */ -+ dc->scale_factor = (double) dc->reuse_index_array_size / (max_ratio - 1); -+ -+ for (i = 0; i < dc->reuse_index_array_size; i++) -+ { -+ dc->reuse_index_array[i] = (int) -+ (((double) dc->half_life / dc->delta_reuse) * -+ log10 (1.0 / (dc->reuse * (1.0 + ((double) i / dc->scale_factor)))) -+ / log10 (0.5)); -+ } -+ -+ dc->enabled = ON; -+} -+ -+static double -+ospf6_damp_decay (time_t tdiff) -+{ -+ int index = tdiff / dc->delta_t; -+ -+ if (index >= dc->decay_array_size) -+ return 0; -+ -+ return dc->decay_array[index]; -+} -+ -+static int -+ospf6_damp_reuse_index (int penalty) -+{ -+ int index; -+ -+ index = (int) (((double) penalty / dc->reuse - 1.0) * dc->scale_factor); -+ -+ if (index >= dc->reuse_index_array_size) -+ index = dc->reuse_index_array_size - 1; -+ -+ return (dc->reuse_index_array[index] - dc->reuse_index_array[0]); -+} -+ -+static int -+ospf6_reuse_list_lookup (struct ospf6_damp_info *di) -+{ -+ struct ospf6_damp_info *info; -+ -+ for (info = dc->reuse_list_array[di->index]; info; info = info->next) -+ { -+ if (info == di) -+ return 1; -+ } -+ return 0; -+} -+ -+static void -+ospf6_reuse_list_remove (struct ospf6_damp_info *di) -+{ -+ if (di->prev) -+ di->prev->next = di->next; -+ else -+ dc->reuse_list_array[di->index] = di->next; -+ if (di->next) -+ di->next->prev = di->prev; -+ -+ di->index = -1; -+ di->prev = NULL; -+ di->next = NULL; -+} -+ -+static void -+ospf6_reuse_list_add (struct ospf6_damp_info *di) -+{ -+ /* set the index of reuse-array */ -+ di->index = (reuse_array_offset + (ospf6_damp_reuse_index (di->penalty))) -+ % dc->reuse_list_size; -+ -+ /* insert to the head of the reuse list */ -+ di->next = dc->reuse_list_array[di->index]; -+ if (di->next) -+ di->next->prev = di; -+ di->prev = NULL; -+ dc->reuse_list_array[di->index] = di; -+} -+ -+/* When we quit damping for a target, we should execute proper event -+ which have been postponed during damping */ -+static void -+ospf6_damp_stop (struct ospf6_damp_info *di) -+{ -+ time_t t_now; -+ char namebuf[64]; -+ struct timeval now; -+ -+ if (IS_OSPF6_DEBUG_DAMP) -+ { -+ t_now = time (NULL); -+ prefix2str (&di->name, namebuf, sizeof (namebuf)); -+ gettimeofday (&now, NULL); -+ zlog_info ("DAMP: %lu.%06lu stop damping: %ld: type: %d, name: %s", -+ now.tv_sec, now.tv_usec, -+ t_now, di->type, namebuf); -+ } -+ -+ /* set flag indicates that we're damping this target */ -+ di->damping = OFF; -+ -+ /* if the target's current status differ from that it should be, -+ execute the proper event to repair his status */ -+ if (di->target_status != di->event_type) -+ { -+ (*(di->event)) (di->target); -+ di->target_status = di->event_type; -+ -+ di->event = NULL; -+ di->event_type = event_none; -+ } -+} -+ -+/* ospf6_reuse_timer is called every DELTA_REUSE seconds. -+ Each route in the current reuse-list is evaluated -+ and is used or requeued */ -+int -+ospf6_damp_reuse_timer (struct thread *t) -+{ -+ struct ospf6_damp_info *di, *next; -+ time_t t_now, t_diff; -+ char namebuf[64]; -+ struct timeval now; -+ -+ /* Restart the reuse timer */ -+ ospf6_reuse_thread = -+ thread_add_timer (master, ospf6_damp_reuse_timer, NULL, dc->delta_reuse); -+ -+ t_now = time (NULL); -+ -+ /* get the damp info list head */ -+ di = dc->reuse_list_array[reuse_array_offset]; -+ dc->reuse_list_array[reuse_array_offset] = NULL; -+ -+ /* rotate the circular reuse list head array */ -+ reuse_array_offset = (reuse_array_offset + 1) % dc->reuse_list_size; -+ -+ /* for each damp info */ -+ while (di) -+ { -+ next = di->next; -+ di->next = NULL; -+ -+ /* Update penalty */ -+ t_diff = t_now - di->t_updated; -+ di->t_updated = t_now; -+ di->penalty = (int) -+ ((double) di->penalty * ospf6_damp_decay (t_diff)); -+ /* configration of ceiling may be just changed */ -+ if (di->penalty > dc->ceiling) -+ di->penalty = dc->ceiling; -+ -+ if (IS_OSPF6_DEBUG_DAMP) -+ { -+ prefix2str (&di->name, namebuf, sizeof (namebuf)); -+ gettimeofday (&now, NULL); -+ zlog_info ("DAMP: %lu.%06lu update penalty: type: %d, name: %s, penalty: %d", -+ now.tv_sec, now.tv_usec, -+ di->type, namebuf, di->penalty); -+ } -+ -+ /* If the penalty becomes under reuse, -+ call real event that we have been postponed. */ -+ if (di->penalty < dc->reuse && di->damping == ON) -+ ospf6_damp_stop (di); -+ -+ /* If the penalty becomes less than the half of the -+ reuse value, this damp info will be freed from reuse-list, -+ by assuming that it is considered to be stable enough already, -+ and there's no need to maintain flapping history for this. */ -+ if (di->penalty <= dc->reuse / 2) -+ { -+ ospf6_damp_delete (di->type, &di->name); -+ di = next; -+ continue; -+ } -+ -+ /* re-insert to the reuse-list */ -+ ospf6_reuse_list_add (di); -+ -+ di = next; -+ } -+ -+ return 0; -+} -+ -+static void -+ospf6_damp_event (damp_event_t event_type, -+ u_short type, struct prefix *name, -+ int (*event) (void *), void *target) -+{ -+ time_t t_now, t_diff; -+ struct ospf6_damp_info *di; -+ char namebuf[64]; -+ struct timeval now; -+ -+ if (dc->enabled == OFF) -+ { -+ (*event) (target); -+ return; -+ } -+ -+ di = ospf6_damp_lookup (type, name); -+ if (! di) -+ di = ospf6_damp_create (type, name); -+ -+ t_now = time (NULL); -+ -+ di->event = event; -+ di->target = target; -+ di->event_type = event_type; -+ -+ if (! ospf6_reuse_list_lookup (di)) -+ di->t_start = t_now; -+ else -+ { -+ ospf6_reuse_list_remove (di); -+ -+ t_diff = t_now - di->t_updated; -+ di->penalty = (int) (di->penalty * ospf6_damp_decay (t_diff)); -+ } -+ -+ /* penalty only on down event */ -+ if (event_type == event_down) -+ { -+ di->flap++; -+ di->penalty += dc->default_penalty; -+ } -+ -+ /* limit penalty up to ceiling */ -+ if (di->penalty > dc->ceiling) -+ di->penalty = dc->ceiling; -+ -+ if (IS_OSPF6_DEBUG_DAMP) -+ { -+ prefix2str (&di->name, namebuf, sizeof (namebuf)); -+ gettimeofday (&now, NULL); -+ zlog_info ("DAMP: %lu.%06lu update penalty: type: %d, name: %s, penalty: %d", -+ now.tv_sec, now.tv_usec, -+ di->type, namebuf, di->penalty); -+ } -+ -+ /* if penalty < reuse, stop damping here */ -+ if (di->penalty < dc->reuse && di->damping == ON) -+ { -+ if (IS_OSPF6_DEBUG_DAMP) -+ { -+ prefix2str (&di->name, namebuf, sizeof (namebuf)); -+ gettimeofday (&now, NULL); -+ zlog_info ("DAMP: %lu.%06lu stop damping: %ld: type: %d, name: %s", -+ now.tv_sec, now.tv_usec, -+ t_now, di->type, namebuf); -+ } -+ di->damping = OFF; -+ } -+ -+ /* if event == up and if penalty >= suppress , start damping here */ -+ if (di->event_type == event_up && di->penalty >= dc->suppress && -+ di->damping == OFF) -+ { -+ if (IS_OSPF6_DEBUG_DAMP) -+ { -+ prefix2str (&di->name, namebuf, sizeof (namebuf)); -+ gettimeofday (&now, NULL); -+ zlog_info ("DAMP: %lu.%06lu start damping: %ld: type: %d, name: %s", -+ now.tv_sec, now.tv_usec, -+ t_now, type, namebuf); -+ } -+ di->damping = ON; -+ } -+ -+ /* execute event if we're not damping */ -+ if (di->damping == OFF) -+ { -+ (*(di->event)) (di->target); -+ di->target_status = di->event_type; -+ } -+ -+ /* if the penalty goes beyond suppress value, start damping */ -+ if (di->penalty >= dc->suppress && di->damping == OFF) -+ { -+ if (IS_OSPF6_DEBUG_DAMP) -+ { -+ prefix2str (name, namebuf, sizeof (namebuf)); -+ gettimeofday (&now, NULL); -+ zlog_info ("DAMP: %lu.%06lu start damping: %ld: type: %d, name: %s", -+ now.tv_sec, now.tv_usec, -+ t_now, type, namebuf); -+ } -+ di->damping = ON; -+ } -+ -+ /* update last-updated-time field */ -+ di->t_updated = t_now; -+ -+ /* Insert it into the reuse list */ -+ ospf6_reuse_list_add (di); -+} -+ -+void -+ospf6_damp_event_up (u_short type, struct prefix *name, -+ int (*event) (void *), void *target) -+{ -+ struct timeval now; -+ -+ gettimeofday (&now, NULL); -+ if (IS_OSPF6_DEBUG_DAMP) -+ zlog_info ("DAMP: Up Event at %lu.%06lu", now.tv_sec, now.tv_usec); -+ -+ ospf6_damp_event (event_up, type, name, event, target); -+} -+ -+void -+ospf6_damp_event_down (u_short type, struct prefix *name, -+ int (*event) (void *), void *target) -+{ -+ struct timeval now; -+ -+ gettimeofday (&now, NULL); -+ if (IS_OSPF6_DEBUG_DAMP) -+ zlog_info ("DAMP: Down Event at %lu.%06lu", now.tv_sec, now.tv_usec); -+ -+ ospf6_damp_event (event_down, type, name, event, target); -+} -+ -+int -+ospf6_damp_debug_thread (struct thread *thread) -+{ -+ int i; -+ struct ospf6_damp_info *di; -+ char buf[256]; -+ time_t t_now; -+ struct timeval now; -+ -+ for (i = 0; i < dc->reuse_list_size; i++) -+ { -+ for (di = dc->reuse_list_array[i]; di; di = di->next) -+ { -+ t_now = time (NULL); -+ gettimeofday (&now, NULL); -+ prefix2str (&di->name, buf, sizeof (buf)); -+ zlog_info ("DAMP: %lu.%06lu %c %-32s penalty %7u", -+ now.tv_sec, now.tv_usec, -+ (di->damping == ON ? 'D' : 'A'), buf, -+ (u_int) (di->penalty * -+ ospf6_damp_decay (t_now - di->t_updated))); -+ } -+ } -+ thread_add_timer (master, ospf6_damp_debug_thread, NULL, 1); -+ return 0; -+} -+ -+DEFUN (show_ipv6_ospf6_route_flapping, -+ show_ipv6_ospf6_route_flapping_cmd, -+ "show ipv6 ospf6 route flapping", -+ SHOW_STR -+ IP6_STR -+ OSPF6_STR) -+{ -+ int i; -+ struct ospf6_damp_info *di; -+ char buf[256]; -+ time_t t_now; -+ -+ t_now = time (NULL); -+ vty_out (vty, "%c %-32s %7s%s", ' ', "Prefix", "penalty", VTY_NEWLINE); -+ -+ for (i = 0; i < dc->reuse_list_size; i++) -+ { -+ for (di = dc->reuse_list_array[i]; di; di = di->next) -+ { -+ prefix2str (&di->name, buf, sizeof (buf)); -+ vty_out (vty, "%c %-32s %7u%s", -+ (di->damping == ON ? 'D' : ' '), buf, -+ (u_int) (di->penalty * -+ ospf6_damp_decay (t_now - di->t_updated)), -+ VTY_NEWLINE); -+ } -+ } -+ -+ return CMD_SUCCESS; -+} -+ -+DEFUN (flap_damping_route, -+ flap_damping_route_cmd, -+ "flap-damping route <0-4294967295> <0-4294967295> " -+ "<0-4294967295> <0-4294967295>", -+ "enable flap dampening\n" -+ "enable route flap dampening\n" -+ "half-life in second\n" -+ "reuse value\n" -+ "suppress value\n" -+ "t-hold in second (maximum time that the target can be damped)\n" -+ ) -+{ -+ u_int half_life, reuse, suppress, t_hold; -+ -+ if (argc) -+ { -+ half_life = (u_int) strtoul (argv[0], NULL, 10); -+ reuse = (u_int) strtoul (argv[1], NULL, 10); -+ suppress = (u_int) strtoul (argv[2], NULL, 10); -+ t_hold = (u_int) strtoul (argv[3], NULL, 10); -+ } -+ else -+ { -+ half_life = (u_int) DEFAULT_HALF_LIFE; -+ reuse = (u_int) DEFAULT_REUSE; -+ suppress = (u_int) DEFAULT_SUPPRESS; -+ t_hold = (u_int) DEFAULT_HALF_LIFE * 4; -+ } -+ -+ if (reuse && suppress && reuse >= suppress) -+ { -+ vty_out (vty, "reuse value exceeded suppress value, failed%s\n", -+ VTY_NEWLINE); -+ return CMD_SUCCESS; -+ } -+ -+ if (half_life && t_hold && half_life >= t_hold) -+ { -+ vty_out (vty, "half-life exceeded t-hold, failed%s\n", VTY_NEWLINE); -+ return CMD_SUCCESS; -+ } -+ -+ ospf6_damp_init_config (half_life, reuse, suppress, t_hold); -+ -+ if (ospf6_reuse_thread == NULL) -+ ospf6_reuse_thread = -+ thread_add_timer (master, ospf6_damp_reuse_timer, NULL, dc->delta_reuse); -+ -+ return CMD_SUCCESS; -+} -+ -+DEFUN (show_ipv6_ospf6_damp_config, -+ show_ipv6_ospf6_camp_config_cmd, -+ "show ipv6 ospf6 damp config", -+ SHOW_STR -+ IP6_STR -+ OSPF6_STR -+ "Flap-dampening information\n" -+ "shows dampening configuration\n" -+ ) -+{ -+ int i; -+ -+ vty_out (vty, "%10s %10s %10s %10s%s", -+ "Half life", "Suppress", "Reuse", "T-hold", -+ VTY_NEWLINE); -+ vty_out (vty, "%10u %10u %10u %10u%s", -+ dc->half_life, dc->suppress, dc->reuse, dc->t_hold, -+ VTY_NEWLINE); -+ vty_out (vty, "%s", VTY_NEWLINE); -+ -+ vty_out (vty, "Delta-t = %u%s", dc->delta_t, VTY_NEWLINE); -+ vty_out (vty, "Delta-Reuse = %u%s", dc->delta_reuse, VTY_NEWLINE); -+ vty_out (vty, "Default-Penalty = %u%s", dc->default_penalty, VTY_NEWLINE); -+ vty_out (vty, "Ceiling = %u%s", dc->ceiling, VTY_NEWLINE); -+ vty_out (vty, "ScaleFactor = %f%s", dc->scale_factor, VTY_NEWLINE); -+ -+ vty_out (vty, "DecayArray(%d) =%s", dc->decay_array_size, VTY_NEWLINE); -+ for (i = 0; i < dc->decay_array_size; i++) -+ { -+ if (i % 10 == 0) -+ vty_out (vty, " "); -+ vty_out (vty, " %f", dc->decay_array[i]); -+ if (i % 10 == 0) -+ vty_out (vty, "%s", VTY_NEWLINE); -+ } -+ vty_out (vty, "%s", VTY_NEWLINE); -+ -+ vty_out (vty, "ReuseIndexArray(%d) =%s", -+ dc->reuse_index_array_size, VTY_NEWLINE); -+ for (i = 0; i < dc->reuse_index_array_size; i++) -+ { -+ if (i % 10 == 0) -+ vty_out (vty, " "); -+ vty_out (vty, " %d", dc->reuse_index_array[i]); -+ if (i % 10 == 0) -+ vty_out (vty, "%s", VTY_NEWLINE); -+ } -+ vty_out (vty, "%s", VTY_NEWLINE); -+ -+ return CMD_SUCCESS; -+} -+ -+void -+ospf6_damp_config_write (struct vty *vty) -+{ -+ if (dc->enabled == ON) -+ { -+ vty_out (vty, " flap-damping route %u %u %u %u%s", -+ dc->half_life, dc->reuse, dc->suppress, dc->t_hold, -+ VTY_NEWLINE); -+ } -+} -+ -+DEFUN (debug_ospf6_damp, -+ debug_ospf6_damp_cmd, -+ "debug ospf6 damp", -+ DEBUG_STR -+ OSPF6_STR -+ "Flap-dampening information\n" -+ ) -+{ -+ ospf6_damp_debug = 1; -+ return CMD_SUCCESS; -+} -+ -+DEFUN (no_debug_ospf6_damp, -+ no_debug_ospf6_damp_cmd, -+ "no debug ospf6 damp", -+ NO_STR -+ DEBUG_STR -+ OSPF6_STR -+ "Flap-dampening information\n" -+ ) -+{ -+ ospf6_damp_debug = 0; -+ return CMD_SUCCESS; -+} -+ -+DEFUN (show_debug_ospf6_damp, -+ show_debug_ospf6_damp_cmd, -+ "show debugging ospf6 damp", -+ SHOW_STR -+ DEBUG_STR -+ OSPF6_STR -+ "Flap-dampening information\n" -+ ) -+{ -+ vty_out (vty, "debugging ospf6 damp is "); -+ if (IS_OSPF6_DEBUG_DAMP) -+ vty_out (vty, "enabled."); -+ else -+ vty_out (vty, "disabled."); -+ vty_out (vty, "%s", VTY_NEWLINE); -+ return CMD_SUCCESS; -+} -+ -+void -+ospf6_damp_init () -+{ -+ int i; -+ for (i = 0; i < OSPF6_DAMP_TYPE_MAX; i++) -+ damp_info_table[i] = route_table_init (); -+ -+ install_element (VIEW_NODE, &show_ipv6_ospf6_route_flapping_cmd); -+ install_element (ENABLE_NODE, &show_ipv6_ospf6_route_flapping_cmd); -+ install_element (ENABLE_NODE, &show_ipv6_ospf6_camp_config_cmd); -+ install_element (OSPF6_NODE, &flap_damping_route_cmd); -+ -+ install_element (ENABLE_NODE, &show_debug_ospf6_damp_cmd); -+ install_element (CONFIG_NODE, &debug_ospf6_damp_cmd); -+ install_element (CONFIG_NODE, &no_debug_ospf6_damp_cmd); -+ -+ thread_add_event (master, ospf6_damp_debug_thread, NULL, 0); -+} -+ -+#endif /* HAVE_OSPF6_DAMP */ -+ -+ -diff -x CVS -urN ospf6d.old/ospf6_damp.h ospf6d/ospf6_damp.h ---- ospf6d.old/ospf6_damp.h Thu Jan 1 01:00:00 1970 -+++ ospf6d/ospf6_damp.h Tue Oct 1 00:41:10 2002 -@@ -0,0 +1,109 @@ -+/* -+ * OSPF flap dampening by Manav Bhatia -+ * Copyright (C) 2002 -+ * -+ * This file is part of GNU Zebra. -+ * -+ * GNU Zebra is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2, or (at your option) any -+ * later version. -+ * -+ * GNU Zebra is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GNU Zebra; see the file COPYING. If not, write to the Free -+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -+ * 02111-1307, USA. -+ */ -+ -+/* -+ * Flap Damping (target e.g. link/route) -+ */ -+ -+#define HAVE_OSPF6_DAMP -+ -+typedef enum -+{ -+ OFF, -+ ON, -+} onoff_t; -+ -+typedef enum -+{ -+ event_none, -+ event_up, -+ event_down, -+} damp_event_t; -+ -+/* Structure maintained per target basis */ -+struct ospf6_damp_info -+{ -+ /* identifier to decide which target */ -+ u_short type; -+ struct prefix name; -+ -+ /* do we damping this info */ -+ onoff_t damping; -+ -+ u_int penalty; -+ u_int flap; -+ time_t t_start; /* First flap (down event) time */ -+ time_t t_updated; /* Last time the penalty was updated */ -+ -+ /* index and double-link for reuse list */ -+ int index; -+ struct ospf6_damp_info *next; -+ struct ospf6_damp_info *prev; -+ -+ /* the last event that we are avoiding */ -+ int (*event) (void *target); -+ void *target; -+ damp_event_t event_type; -+ damp_event_t target_status; -+}; -+ -+#define OSPF6_DAMP_TYPE_ROUTE 0 -+#define OSPF6_DAMP_TYPE_MAX 1 -+ -+/* Global Configuration Parameters */ -+struct ospf6_damp_config -+{ -+ /* is damping enabled ? */ -+ onoff_t enabled; -+ -+ /* configurable parameters */ -+ u_int half_life; -+ u_int suppress; -+ u_int reuse; -+ u_int t_hold; /* Maximum hold down time */ -+ -+ /* Non configurable parameters */ -+ u_int delta_t; -+ u_int delta_reuse; -+ u_int default_penalty; -+ u_int ceiling; /* Max value a penalty can attain */ -+ double scale_factor; -+ -+ int decay_array_size; /* Calculated using config parameters */ -+ double *decay_array; /* Storage for decay values */ -+ -+ int reuse_index_array_size; /* Size of reuse index array */ -+ int *reuse_index_array; -+ -+ int reuse_list_size; /* Number of reuse lists */ -+ struct ospf6_damp_info **reuse_list_array; -+}; -+ -+int ospf6_damp_reuse_timer (struct thread *); -+void ospf6_damp_event_up (u_short type, struct prefix *name, -+ int (*exec_up) (void *), void *target); -+void ospf6_damp_event_down (u_short type, struct prefix *name, -+ int (*exec_down) (void *), void *target); -+ -+void ospf6_damp_config_write (struct vty *); -+void ospf6_damp_init (); -+ -diff -x CVS -urN ospf6d.old/ospf6_dbex.c ospf6d/ospf6_dbex.c ---- ospf6d.old/ospf6_dbex.c Sat Apr 26 23:17:47 2003 -+++ ospf6d/ospf6_dbex.c Sat Nov 9 11:25:30 2002 -@@ -230,12 +230,11 @@ - ismore_recent = -1; - recent_reason = "no instance"; - -+ zlog_info ("Receive LSA (header -> %p)", lsa_header); -+ - /* make lsa structure for received lsa */ - received = ospf6_lsa_create (lsa_header); - -- if (IS_OSPF6_DUMP_DBEX) -- zlog_info ("Receive %s from %s", received->str, from->str); -- - /* set LSA scope */ - if (OSPF6_LSA_IS_SCOPE_LINKLOCAL (htons (lsa_header->type))) - received->scope = from->ospf6_interface; -@@ -248,27 +247,24 @@ - cksum = ntohs (lsa_header->checksum); - if (ntohs (ospf6_lsa_checksum (lsa_header)) != cksum) - { -- zlog_warn ("DBEX: LSA cksum wrong: %s checksum %#hx should be %#hx", -- received->str, cksum, ntohs (ospf6_lsa_checksum (lsa_header))); -+ if (IS_OSPF6_DUMP_DBEX) -+ zlog_info ("DBEX: received %s from %s%%%s" -+ ": wrong checksum, drop", -+ received->str, from->str, -+ from->ospf6_interface->interface->name); - ospf6_lsa_delete (received); - return; - } - --#if 0 -- /* (2) warn if unknown */ -- if (! ospf6_lsa_is_known_type (lsa_header)) -- zlog_warn ("[%s:%s] receive LSA unknown: %#x", -- from->str, from->ospf6_interface->interface->name, -- ntohs (lsa_header->type)); --#endif /*0*/ -- - /* (3) Ebit Missmatch: AS-External-LSA */ - if (lsa_header->type == htons (OSPF6_LSA_TYPE_AS_EXTERNAL) && - ospf6_area_is_stub (from->ospf6_interface->area)) - { -- zlog_err ("DBEX: [%s:%s] receive LSA E-bit mismatch: %s", -- from->str, from->ospf6_interface->interface->name, -- received->str); -+ if (IS_OSPF6_DUMP_DBEX) -+ zlog_info ("DBEX: received %s from %s%%%s" -+ ": E-bit mismatch, drop", -+ received->str, from->str, -+ from->ospf6_interface->interface->name); - ospf6_lsa_delete (received); - return; - } -@@ -279,8 +275,10 @@ - { - /* log */ - if (IS_OSPF6_DUMP_DBEX) -- zlog_info ("Drop MaxAge LSA: no instance, no neighbor " -- "exchanging DB: %s", received->str); -+ zlog_info ("DBEX: received %s from %s%%%s" -+ ": MaxAge, no instance, no neighbor exchange, drop", -+ received->str, from->str, -+ from->ospf6_interface->interface->name); - - /* a) Acknowledge back to neighbor (13.5) */ - /* Direct Acknowledgement */ -@@ -312,18 +310,29 @@ - - /* (a) MinLSArrival check */ - gettimeofday (&now, (struct timezone *)NULL); -- if (have && now.tv_sec - have->installed.tv_sec <= OSPF6_MIN_LS_ARRIVAL) -+ if (have && SEC_TVDIFF (&now, &have->installed) < OSPF6_MIN_LS_ARRIVAL) - { -- if (IS_OSPF6_DUMP_DBEX) -- zlog_info ("DBEX: [%s:%s] received LSA too soon: %s", -- from->str, from->ospf6_interface->interface->name, -- received->str); -+ //if (IS_OSPF6_DUMP_DBEX) -+ zlog_info ("DBEX: Receive new LSA from %s: %s seq: %#x age: %d " -+ "within MinLSArrival, drop: %ld.%06ld", -+ from->str, received->str, -+ ntohl (received->header->seqnum), -+ ntohs (received->header->age), -+ now.tv_sec, now.tv_usec); - - /* this will do free this lsa */ - ospf6_lsa_delete (received); - return; /* examin next lsa */ - } - -+ //if (IS_OSPF6_DUMP_DBEX) -+ zlog_info ("DBEX: Receive new LSA from %s: %s seq: %#x age: %d: " -+ "%ld.%06ld", -+ from->str, received->str, -+ ntohl (received->header->seqnum), -+ ntohs (received->header->age), -+ now.tv_sec, now.tv_usec); -+ - /* (b) immediately flood */ - ospf6_dbex_flood (received, from); - -@@ -344,18 +353,20 @@ - acktype = ack_type (received, ismore_recent, from); - if (acktype == DIRECT_ACK) - { -+ if (IS_OSPF6_DUMP_DBEX) -+ zlog_info ("DBEX: Direct Ack to %s", from->str); - ospf6_dbex_acknowledge_direct (received, from); - } - else if (acktype == DELAYED_ACK) - { -+ if (IS_OSPF6_DUMP_DBEX) -+ zlog_info ("DBEX: Delayed Ack to %s", from->str); - ospf6_dbex_acknowledge_delayed (received, from->ospf6_interface); - } - else - { - if (IS_OSPF6_DUMP_DBEX) -- zlog_info ("DBEX: [%s:%s] don't ack %s", -- from->str, from->ospf6_interface->interface->name, -- received->str); -+ zlog_info ("DBEX: No Ack to %s", from->str); - } - - /* (f) */ -@@ -413,6 +424,9 @@ - from->retrans_list); - if (rem) - { -+ if (IS_OSPF6_DUMP_DBEX) -+ zlog_info ("DBEX: Implied Ack from %s, (remove retrans)", -+ from->str); - SET_FLAG (received->flag, OSPF6_LSA_FLAG_IMPLIEDACK); - ospf6_neighbor_retrans_remove (rem, from); - } -@@ -421,18 +435,20 @@ - acktype = ack_type (received, ismore_recent, from); - if (acktype == DIRECT_ACK) - { -+ if (IS_OSPF6_DUMP_DBEX) -+ zlog_info ("DBEX: Direct Ack to %s", from->str); - ospf6_dbex_acknowledge_direct (received, from); - } - else if (acktype == DELAYED_ACK) - { -+ if (IS_OSPF6_DUMP_DBEX) -+ zlog_info ("DBEX: Delayed Ack to %s", from->str); - ospf6_dbex_acknowledge_delayed (received, from->ospf6_interface); - } - else - { - if (IS_OSPF6_DUMP_DBEX) -- zlog_info ("DBEX: [%s:%s] will no ack %s", -- from->str, from->ospf6_interface->interface->name, -- received->str); -+ zlog_info ("DBEX: No Ack to %s", from->str); - } - ospf6_lsa_delete (received); - } -@@ -443,6 +459,9 @@ - if (! IS_LSA_MAXAGE (received) || - received->lsa_hdr->lsh_seqnum != MAX_SEQUENCE_NUMBER) - { -+ if (IS_OSPF6_DUMP_DBEX) -+ zlog_info ("DBEX: database is more recent: send back to %s", -+ from->str); - ospf6_send_lsupdate_direct (have, from); - } - ospf6_lsa_delete (received); -@@ -455,83 +474,52 @@ - struct ospf6_neighbor *from) - { - struct ospf6_interface *ospf6_interface; -- struct ospf6_neighbor *nbr; -- listnode n, m; -+ struct ospf6_lsa *have; -+ int count; - - assert (from && from->ospf6_interface); - ospf6_interface = from->ospf6_interface; - - if (CHECK_FLAG (newp->flag, OSPF6_LSA_FLAG_FLOODBACK)) -+ return NO_ACK; -+ -+ if (ismore_recent < 0) - { -+ if (ospf6_interface->state != IFS_BDR) -+ return DELAYED_ACK; -+ -+ if (ospf6_interface->dr == from->router_id) -+ return DELAYED_ACK; - return NO_ACK; - } -- else if (ismore_recent < 0 && -- ! CHECK_FLAG (newp->flag, OSPF6_LSA_FLAG_FLOODBACK)) -- { -- if (ospf6_interface->state == IFS_BDR) -- { -- if (ospf6_interface->dr == from->router_id) -- { -- return DELAYED_ACK; -- } -- else -- { -- return NO_ACK; -- } -- } -- else -- { -- return DELAYED_ACK; -- } -- } -- else if (CHECK_FLAG (newp->flag, OSPF6_LSA_FLAG_DUPLICATE) && -- CHECK_FLAG (newp->flag, OSPF6_LSA_FLAG_IMPLIEDACK)) -- { -- if (ospf6_interface->state == IFS_BDR) -- { -- if (ospf6_interface->dr == from->router_id) -- { -- return DELAYED_ACK; -- } -- else -- { -- return NO_ACK; -- } -- } -- else -- { -- return NO_ACK; -- } -- } -- else if (CHECK_FLAG (newp->flag, OSPF6_LSA_FLAG_DUPLICATE) && -- ! CHECK_FLAG (newp->flag, OSPF6_LSA_FLAG_IMPLIEDACK)) -- { -- return DIRECT_ACK; -- } -- else if (IS_LSA_MAXAGE (newp)) -+ -+ if (CHECK_FLAG (newp->flag, OSPF6_LSA_FLAG_DUPLICATE) && -+ CHECK_FLAG (newp->flag, OSPF6_LSA_FLAG_IMPLIEDACK)) - { -- if (! ospf6_lsdb_lookup (newp->header->type, newp->header->id, -- newp->header->adv_router, -- ospf6_lsa_get_scope (newp->header->type, -- from->ospf6_interface))) -- { -- for (n = listhead (from->ospf6_interface->area->if_list); -- n; nextnode (n)) -- { -- ospf6_interface = (struct ospf6_interface *) getdata (n); -- for (m = listhead (ospf6_interface->neighbor_list); -- m; nextnode (m)) -- { -- nbr = (struct ospf6_neighbor *) getdata (m); -- if (nbr->state == NBS_EXCHANGE || nbr->state == NBS_LOADING) -- { -- return NO_ACK; -- } -- } -- } -- return DIRECT_ACK; -- } -+ if (ospf6_interface->state != IFS_BDR) -+ return NO_ACK; -+ -+ if (ospf6_interface->dr == from->router_id) -+ return DELAYED_ACK; -+ -+ return NO_ACK; - } -+ -+ if (CHECK_FLAG (newp->flag, OSPF6_LSA_FLAG_DUPLICATE) && -+ ! CHECK_FLAG (newp->flag, OSPF6_LSA_FLAG_IMPLIEDACK)) -+ return DIRECT_ACK; -+ -+ have = ospf6_lsdb_lookup (newp->header->type, newp->header->id, -+ newp->header->adv_router, -+ ospf6_lsa_get_scope (newp->header->type, -+ from->ospf6_interface)); -+ -+ count = 0; -+ ospf6->foreach_nei (ospf6, &count, NBS_EXCHANGE, ospf6_count_state); -+ ospf6->foreach_nei (ospf6, &count, NBS_LOADING, ospf6_count_state); -+ -+ if (IS_LSA_MAXAGE (newp) && have == NULL && count == 0) -+ return DIRECT_ACK; - - return NO_ACK; - } -@@ -600,11 +588,13 @@ - - /* (2) */ - if (addretrans == 0) -+ return; /* examin next interface */ -+ -+ if (from && from->ospf6_interface == o6i) - { -- return; /* examin next interface */ -- } -- else if (from && from->ospf6_interface == o6i) -- { -+ if (IS_OSPF6_DUMP_DBEX) -+ zlog_info ("DBEX: flood back %s to %s", -+ lsa->str, o6i->interface->name); - /* note occurence of floodback */ - SET_FLAG (lsa->flag, OSPF6_LSA_FLAG_FLOODBACK); - } -@@ -624,7 +614,7 @@ - return; /* examin next interface */ - - if (IS_OSPF6_DUMP_DBEX) -- zlog_info (" Flood to interface %s", o6i->interface->name); -+ zlog_info ("Flood to interface %s", o6i->interface->name); - - /* (5) send LinkState Update */ - ospf6_send_lsupdate_flood (lsa, o6i); -@@ -678,14 +668,13 @@ - - lsa_header = (struct ospf6_lsa_header *) lsa->lsa_hdr; - -- if (IS_OSPF6_DUMP_DBEX) -- zlog_info ("Flood: %s", lsa->str); -- - if (OSPF6_LSA_IS_SCOPE_LINKLOCAL (ntohs (lsa_header->type))) - { - o6i = (struct ospf6_interface *) lsa->scope; - assert (o6i); - -+ if (IS_OSPF6_DUMP_DBEX) -+ zlog_info ("Flood Linklocal: %s", o6i->interface->name); - ospf6_dbex_flood_linklocal (lsa, o6i, from); - } - else if (OSPF6_LSA_IS_SCOPE_AREA (ntohs (lsa_header->type))) -@@ -693,6 +682,8 @@ - o6a = (struct ospf6_area *) lsa->scope; - assert (o6a); - -+ if (IS_OSPF6_DUMP_DBEX) -+ zlog_info ("Flood Area: %s", o6a->str); - ospf6_dbex_flood_area (lsa, o6a, from); - } - else if (OSPF6_LSA_IS_SCOPE_AS (ntohs (lsa_header->type))) -@@ -700,6 +691,8 @@ - o6 = (struct ospf6 *) lsa->scope; - assert (o6); - -+ if (IS_OSPF6_DUMP_DBEX) -+ zlog_info ("Flood AS"); - ospf6_dbex_flood_as (lsa, o6, from); - } - else -diff -x CVS -urN ospf6d.old/ospf6_interface.c ospf6d/ospf6_interface.c ---- ospf6d.old/ospf6_interface.c Sat Apr 26 23:17:47 2003 -+++ ospf6d/ospf6_interface.c Sat Nov 9 13:26:03 2002 -@@ -126,6 +126,9 @@ - - CALL_ADD_HOOK (&interface_hook, o6i); - -+ /* Get the interface's link-local if any */ -+ ospf6_interface_address_update(ifp); -+ - return o6i; - } - -diff -x CVS -urN ospf6d.old/ospf6_lsa.c ospf6d/ospf6_lsa.c ---- ospf6d.old/ospf6_lsa.c Sat Apr 26 23:17:47 2003 -+++ ospf6d/ospf6_lsa.c Sat Nov 9 11:25:30 2002 -@@ -51,7 +51,6 @@ - #include "ospf6_area.h" - #include "ospf6_interface.h" - #include "ospf6_neighbor.h" --#include "ospf6_redistribute.h" - #include "ospf6_ism.h" - #include "ospf6_nsm.h" - #include "ospf6_dbex.h" -@@ -142,8 +141,11 @@ - - lsa->birth.tv_sec = now.tv_sec - ntohs (lsa->header->age); - lsa->birth.tv_usec = now.tv_usec; -- lsa->expire = thread_add_timer (master, ospf6_lsa_expire, lsa, -- lsa->birth.tv_sec + MAXAGE - now.tv_sec); -+ if (ntohs (lsa->header->age) != MAXAGE) -+ lsa->expire = thread_add_timer (master, ospf6_lsa_expire, lsa, -+ lsa->birth.tv_sec + MAXAGE - now.tv_sec); -+ else -+ lsa->expire = NULL; - return; - } - -@@ -692,38 +694,6 @@ - ospf6_lsa_delete (lsa); - } - --/* check necessity to update LSA: -- returns 1 if it's necessary to reoriginate */ --static int --ospf6_lsa_is_really_reoriginate (struct ospf6_lsa *new) --{ -- struct ospf6_lsa *old; -- int diff; -- -- /* find previous LSA */ -- old = ospf6_lsdb_lookup (new->header->type, new->header->id, -- new->header->adv_router, new->scope); -- if (! old) -- return 1; -- -- /* Check if this is refresh */ -- if (CHECK_FLAG (old->flag, OSPF6_LSA_FLAG_REFRESH)) -- { -- zlog_warn ("LSA: reoriginate: %s: Refresh", new->str); -- return 1; -- } -- -- /* Are these contents different ? */ -- diff = ospf6_lsa_differ (new, old); -- -- if (diff) -- return 1; -- -- if (IS_OSPF6_DUMP_LSA) -- zlog_info ("LSA: Suppress updating %s", new->str); -- return 0; --} -- - void - ospf6_lsa_originate (u_int16_t type, u_int32_t id, u_int32_t adv_router, - char *data, int data_len, void *scope) -@@ -731,6 +701,7 @@ - char buffer[MAXLSASIZE]; - struct ospf6_lsa_header *lsa_header; - struct ospf6_lsa *lsa; -+ struct ospf6_lsa *old; - - assert (data_len <= sizeof (buffer) - sizeof (struct ospf6_lsa_header)); - -@@ -754,18 +725,37 @@ - - /* create LSA */ - lsa = ospf6_lsa_create ((struct ospf6_lsa_header *) buffer); -- lsa->refresh = thread_add_timer (master, ospf6_lsa_refresh, lsa, -- OSPF6_LS_REFRESH_TIME); - lsa->scope = scope; - -- if (ospf6_lsa_is_really_reoriginate (lsa)) -- { -- ospf6_dbex_remove_from_all_retrans_list (lsa); -- ospf6_dbex_flood (lsa, NULL); -- ospf6_lsdb_install (lsa); -+ /* find previous LSA */ -+ old = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id, -+ lsa->header->adv_router, lsa->scope); -+ if (old) -+ { -+ /* Check if this is neither different instance nor refresh, return */ -+ if (! CHECK_FLAG (old->flag, OSPF6_LSA_FLAG_REFRESH) && -+ ! ospf6_lsa_differ (lsa, old)) -+ { -+ if (IS_OSPF6_DUMP_LSA) -+ zlog_info ("LSA: Suppress updating %s", lsa->str); -+ ospf6_lsa_delete (lsa); -+ return; -+ } - } -- else -- ospf6_lsa_delete (lsa); -+ -+ lsa->refresh = thread_add_timer (master, ospf6_lsa_refresh, lsa, -+ OSPF6_LS_REFRESH_TIME); -+ gettimeofday (&lsa->originated, NULL); -+ -+ //if (IS_OSPF6_DUMP_LSA) -+ zlog_info ("LSA: originate %s seq: %#x age: %hu %ld.%06ld", -+ lsa->str, ntohl (lsa->header->seqnum), -+ ospf6_lsa_age_current (lsa), -+ lsa->originated.tv_sec, lsa->originated.tv_usec); -+ -+ ospf6_dbex_remove_from_all_retrans_list (lsa); -+ ospf6_dbex_flood (lsa, NULL); -+ ospf6_lsdb_install (lsa); - } - - -@@ -1130,14 +1120,32 @@ - return 0; - } - --void --ospf6_lsa_router_update (u_int32_t area_id) -+u_long -+ospf6_lsa_has_elasped (u_int16_t type, u_int32_t id, -+ u_int32_t adv_router, void *scope) -+{ -+ struct ospf6_lsa *old; -+ struct timeval now; -+ -+ if (adv_router != ospf6->router_id) -+ zlog_info ("LSA: Router-ID changed ?"); -+ -+ old = ospf6_lsdb_lookup (type, id, adv_router, scope); -+ if (! old) -+ return OSPF6_LSA_MAXAGE; -+ -+ gettimeofday (&now, NULL); -+ return ((u_long) SEC_TVDIFF (&now, &old->originated)); -+} -+ -+int -+ospf6_lsa_originate_router (struct thread *thread) - { - char buffer [MAXLSASIZE]; - u_int16_t size; -- struct ospf6_lsa *old; - struct ospf6_area *o6a; - int count; -+ u_int32_t area_id; - - struct ospf6_router_lsa *router_lsa; - struct ospf6_router_lsd *router_lsd; -@@ -1145,22 +1153,22 @@ - struct ospf6_interface *o6i; - struct ospf6_neighbor *o6n = NULL; - -+ area_id = (u_int32_t) THREAD_ARG (thread); -+ - o6a = ospf6_area_lookup (area_id, ospf6); - if (! o6a) - { - inet_ntop (AF_INET, &area_id, buffer, sizeof (buffer)); - if (IS_OSPF6_DUMP_LSA) -- zlog_warn ("Update Router-LSA: No such area: %s", buffer); -- return; -+ zlog_info ("LSA: Update Router-LSA: No such area: %s", buffer); -+ return 0; - } - -- if (IS_OSPF6_DUMP_LSA) -- zlog_info ("Update Router-LSA: for Area %s", o6a->str); -+ /* clear thread */ -+ o6a->thread_router_lsa = NULL; - -- /* find previous LSA */ -- /* xxx, there may be multiple Router-LSAs */ -- old = ospf6_lsdb_lookup (htons (OSPF6_LSA_TYPE_ROUTER), -- htonl (0), o6a->ospf6->router_id, o6a); -+ if (IS_OSPF6_DUMP_LSA) -+ zlog_info ("LSA: originate Router-LSA for Area %s", o6a->str); - - size = sizeof (struct ospf6_router_lsa); - memset (buffer, 0, sizeof (buffer)); -@@ -1277,6 +1285,42 @@ - ospf6_lsa_originate (htons (OSPF6_LSA_TYPE_ROUTER), - htonl (0), o6a->ospf6->router_id, - (char *) router_lsa, size, o6a); -+ return 0; -+} -+ -+void -+ospf6_lsa_schedule_router (struct ospf6_area *area) -+{ -+ u_long elasped_time, time = 0; -+ -+ if (area->thread_router_lsa) -+ { -+ if (IS_OSPF6_DUMP_LSA) -+ zlog_info ("LSA: schedule: Router-LSA for Area %s: another thread", -+ area->str); -+ return; -+ } -+ -+ elasped_time = -+ ospf6_lsa_has_elasped (htons (OSPF6_LSA_TYPE_ROUTER), htonl (0), -+ area->ospf6->router_id, area); -+ if (elasped_time < OSPF6_MIN_LS_INTERVAL) -+ time = (u_long) (OSPF6_MIN_LS_INTERVAL - elasped_time); -+ else -+ time = 0; -+ -+ if (IS_OSPF6_DUMP_LSA) -+ zlog_info ("LSA: schedule: Router-LSA for Area %s after %lu sec", -+ area->str, time); -+ -+ if (time) -+ area->thread_router_lsa = -+ thread_add_timer (master, ospf6_lsa_originate_router, -+ (void *) area->area_id, time); -+ else -+ area->thread_router_lsa = -+ thread_add_event (master, ospf6_lsa_originate_router, -+ (void *) area->area_id, 0); - } - - int -@@ -1284,7 +1328,7 @@ - { - struct ospf6_neighbor *o6n = neighbor; - if (o6n->ospf6_interface->area) -- ospf6_lsa_router_update (o6n->ospf6_interface->area->area_id); -+ ospf6_lsa_schedule_router (o6n->ospf6_interface->area); - return 0; - } - -@@ -1293,7 +1337,7 @@ - { - struct ospf6_interface *o6i = interface; - if (o6i->area) -- ospf6_lsa_router_update (o6i->area->area_id); -+ ospf6_lsa_schedule_router (o6i->area); - return 0; - } - -@@ -1301,7 +1345,7 @@ - ospf6_lsa_router_hook_area (void *area) - { - struct ospf6_area *o6a = area; -- ospf6_lsa_router_update (o6a->area_id); -+ ospf6_lsa_schedule_router (o6a); - return 0; - } - -@@ -1315,7 +1359,7 @@ - for (node = listhead (o6->area_list); node; nextnode (node)) - { - o6a = getdata (node); -- ospf6_lsa_router_update (o6a->area_id); -+ ospf6_lsa_schedule_router (o6a); - } - return 0; - } -@@ -1327,7 +1371,7 @@ - struct ospf6_area *o6a; - - o6a = lsa->scope; -- ospf6_lsa_router_update (o6a->area_id); -+ ospf6_lsa_schedule_router (o6a); - return 0; - } - -diff -x CVS -urN ospf6d.old/ospf6_lsa.h ospf6d/ospf6_lsa.h ---- ospf6d.old/ospf6_lsa.h Sat Apr 26 23:17:47 2003 -+++ ospf6d/ospf6_lsa.h Sat Nov 9 11:25:30 2002 -@@ -25,6 +25,13 @@ - - #include "ospf6_hook.h" - -+#define ONESECOND_USEC 1000000 -+#define USEC_TVDIFF(tv2,tv1) \ -+ (((tv2)->tv_sec - (tv1)->tv_sec) * ONESECOND_USEC \ -+ + ((tv2)->tv_usec - (tv1)->tv_usec)) -+#define SEC_TVDIFF(tv2,tv1) \ -+ (USEC_TVDIFF((tv2),(tv1)) / ONESECOND_USEC) -+ - /* LSA definition */ - - #define MAXLSASIZE 1024 -@@ -211,6 +218,7 @@ - unsigned char flag; /* to decide ack type and refresh */ - struct timeval birth; /* tv_sec when LS age 0 */ - struct timeval installed; /* installed time */ -+ struct timeval originated; /* installed time */ - struct thread *expire; - struct thread *refresh; /* For self-originated LSA */ - u_int32_t from; /* from which neighbor */ -@@ -397,22 +405,22 @@ - - u_short ospf6_lsa_checksum (struct ospf6_lsa_header *); - --void ospf6_lsa_update_router (u_int32_t area_id); - void ospf6_lsa_update_network (char *ifname); - void ospf6_lsa_update_link (char *ifname); - void ospf6_lsa_update_as_external (u_int32_t ls_id); - void ospf6_lsa_update_intra_prefix_transit (char *ifname); - void ospf6_lsa_update_intra_prefix_stub (u_int32_t area_id); - --void ospf6_lsa_reoriginate (struct ospf6_lsa *); --void --ospf6_lsa_originate (u_int16_t, u_int32_t, u_int32_t, char *, int, void *); -- - u_int16_t ospf6_lsa_get_scope_type (u_int16_t); - int ospf6_lsa_is_known_type (struct ospf6_lsa_header *lsa_header); - - char *ospf6_lsa_type_string (u_int16_t type, char *buf, int bufsize); - char *ospf6_lsa_router_bits_string (u_char router_bits, char *buf, int size); -+ -+u_long -+ospf6_lsa_has_elasped (u_int16_t, u_int32_t, u_int32_t, void *); -+void -+ospf6_lsa_originate (u_int16_t, u_int32_t, u_int32_t, char *, int, void *); - - #endif /* OSPF6_LSA_H */ - -diff -x CVS -urN ospf6d.old/ospf6_message.c ospf6d/ospf6_message.c ---- ospf6d.old/ospf6_message.c Sat Apr 26 23:17:47 2003 -+++ ospf6d/ospf6_message.c Sat Nov 9 11:25:30 2002 -@@ -1108,14 +1108,14 @@ - if (!o6n) - { - if (IS_OSPF6_DUMP_LSACK) -- zlog_info (" neighbor not found, reject"); -+ zlog_info ("LSACK: neighbor not found, reject"); - return; - } - - if (memcmp (src, &o6n->hisaddr, sizeof (struct in6_addr))) - { -- if (IS_OSPF6_DUMP_MESSAGE (ospf6_header->type)) -- zlog_info ("From Secondary I/F of the neighbor: ignore"); -+ if (IS_OSPF6_DUMP_LSACK) -+ zlog_info ("LSACK: From Secondary I/F of the neighbor: ignore"); - return; - } - -@@ -1123,7 +1123,7 @@ - if (o6n->state < NBS_EXCHANGE) - { - if (IS_OSPF6_DUMP_LSACK) -- zlog_info (" neighbor state less than Exchange, reject"); -+ zlog_info ("LSACK: neighbor state less than Exchange, reject"); - return; - } - -@@ -1141,7 +1141,7 @@ - if (!copy) - { - if (IS_OSPF6_DUMP_LSACK) -- zlog_info ("no database copy, ignore"); -+ zlog_info ("LSACK: no database copy, ignore"); - continue; - } - -@@ -1152,7 +1152,7 @@ - if (rem == NULL) - { - if (IS_OSPF6_DUMP_LSACK) -- zlog_info ("not on %s's retranslist, ignore", o6n->str); -+ zlog_info ("LSACK: not on %s's retranslist, ignore", o6n->str); - continue; - } - -@@ -1167,7 +1167,13 @@ - { - /* Log the questionable acknowledgement, - and examine the next one. */ -- zlog_warn ("LSAck: questionable acknowledge: LSAs differ"); -+ zlog_info ("LSACK: questionable acknowledge: %s", copy->str); -+ zlog_info ("LSACK: received: seq: %#x age: %hu", -+ ntohl (lsa->header->seqnum), -+ ntohs (lsa->header->age)); -+ zlog_info ("LSACK: instance: seq: %#x age: %hu", -+ ntohl (copy->header->seqnum), -+ ospf6_lsa_age_current (copy)); - } - - /* release temporary LSA from Ack message */ -@@ -1242,6 +1248,22 @@ - return; - } - -+ /* message type check */ -+ type = (ospf6_header->type >= OSPF6_MESSAGE_TYPE_MAX ? -+ OSPF6_MESSAGE_TYPE_UNKNOWN : ospf6_header->type); -+ -+ /* log */ -+ if (IS_OSPF6_DUMP_MESSAGE (type)) -+ { -+ char srcname[64], dstname[64]; -+ inet_ntop (AF_INET6, dst, dstname, sizeof (dstname)); -+ inet_ntop (AF_INET6, src, srcname, sizeof (srcname)); -+ zlog_info ("Receive %s on %s", -+ ospf6_message_type_string[type], o6i->interface->name); -+ zlog_info (" %s -> %s", srcname, dstname); -+ ospf6_message_log (message); -+ } -+ - /* router id check */ - router_id = ospf6_header->router_id; - if (ospf6_header->router_id == o6i->area->ospf6->router_id) -@@ -1252,10 +1274,6 @@ - return; - } - -- /* message type check */ -- type = (ospf6_header->type >= OSPF6_MESSAGE_TYPE_MAX ? -- OSPF6_MESSAGE_TYPE_UNKNOWN : ospf6_header->type); -- - /* octet statistics relies on some asumption: - on ethernet, no IPv6 Extention header, etc */ - #define OSPF6_IP6_HEADER_SIZE 40 -@@ -1280,12 +1298,14 @@ - struct ospf6_header ospf6_header; - char buffer[OSPF6_MESSAGE_RECEIVE_BUFSIZE]; - struct ospf6_interface *o6i; -- char srcname[64], dstname[64]; - unsigned char type; - - /* get socket */ - sockfd = THREAD_FD (thread); - -+ /* add next read thread */ -+ thread_add_read (master, ospf6_receive, NULL, sockfd); -+ - /* initialize */ - OSPF6_MESSAGE_CLEAR (message); - memset (&ospf6_header, 0, sizeof (struct ospf6_header)); -@@ -1302,22 +1322,10 @@ - o6i = ospf6_interface_lookup_by_index (ifindex); - if (!o6i || !o6i->area) - { -- zlog_warn ("*** received interface ospf6 disabled"); -- thread_add_read (master, ospf6_receive, NULL, sockfd); -+ //zlog_warn ("*** received interface ospf6 disabled"); - return 0; - } - -- /* log */ -- if (IS_OSPF6_DUMP_MESSAGE (type)) -- { -- inet_ntop (AF_INET6, &dst, dstname, sizeof (dstname)); -- inet_ntop (AF_INET6, &src, srcname, sizeof (srcname)); -- zlog_info ("Receive %s on %s", -- ospf6_message_type_string[type], o6i->interface->name); -- zlog_info (" %s -> %s", srcname, dstname); -- ospf6_message_log (message); -- } -- - /* if not passive, process message */ - if (! CHECK_FLAG (o6i->flag, OSPF6_INTERFACE_FLAG_PASSIVE)) - ospf6_message_process (message, &src, &dst, o6i); -@@ -1325,9 +1333,6 @@ - zlog_info ("Ignore message on passive interface %s", - o6i->interface->name); - -- /* add next read thread */ -- thread_add_read (master, ospf6_receive, NULL, sockfd); -- - return 0; - } - -@@ -1828,6 +1833,9 @@ - return 0; - lsupdate.lsupdate_num = htonl (lsupdate.lsupdate_num); - -+ if (IS_OSPF6_DUMP_LSUPDATE) -+ zlog_info ("MESSAGE: retrsnsmit LSUpdate to %s", o6n->str); -+ - /* statistics */ - o6n->ospf6_stat_retrans_lsupdate++; - -@@ -1915,6 +1923,9 @@ - - o6i = THREAD_ARG (thread); - assert (o6i); -+ -+ if (IS_OSPF6_DUMP_LSACK) -+ zlog_info ("LSACK: Delayed LSAck for %s\n", o6i->interface->name); - - o6i->thread_send_lsack_delayed = (struct thread *) NULL; - -diff -x CVS -urN ospf6d.old/ospf6_neighbor.c ospf6d/ospf6_neighbor.c ---- ospf6d.old/ospf6_neighbor.c Sat Apr 26 23:17:47 2003 -+++ ospf6d/ospf6_neighbor.c Sat Nov 9 11:25:30 2002 -@@ -179,6 +179,13 @@ - } - - ospf6_lsdb_remove (lsa, nei->retrans_list); -+ -+ if (nei->retrans_list->count == 0) -+ { -+ if (nei->send_update) -+ thread_cancel (nei->send_update); -+ nei->send_update = NULL; -+ } - } - - void -diff -x CVS -urN ospf6d.old/ospf6_network.c ospf6d/ospf6_network.c ---- ospf6d.old/ospf6_network.c Sat Apr 26 23:17:47 2003 -+++ ospf6d/ospf6_network.c Tue Oct 1 10:28:08 2002 -@@ -255,8 +255,10 @@ - &mreq6, sizeof (mreq6)) < 0) - zlog_warn ("Network: Leave AllSPFRouters on ifindex %d Failed: %s", - ifindex, strerror (errno)); -+#if 0 - else - zlog_info ("Network: Leave AllSPFRouters on ifindex %d", ifindex); -+#endif - } - - void -@@ -273,8 +275,10 @@ - &mreq6, sizeof (mreq6)) < 0) - zlog_warn ("Network: Join AllDRouters on ifindex %d Failed: %s", - ifindex, strerror (errno)); -+#if 0 - else - zlog_info ("Network: Join AllDRouters on ifindex %d", ifindex); -+#endif - } - - void -@@ -290,8 +294,10 @@ - if (setsockopt (ospf6_sock, IPPROTO_IPV6, IPV6_LEAVE_GROUP, - &mreq6, sizeof (mreq6)) < 0) - zlog_warn ("Network: Leave AllDRouters on ifindex %d Failed", ifindex); -+#if 0 - else - zlog_info ("Network: Leave AllDRouters on ifindex %d", ifindex); -+#endif - } - - /* setsockopt ReUseAddr to on */ -diff -x CVS -urN ospf6d.old/ospf6_route.h ospf6d/ospf6_route.h ---- ospf6d.old/ospf6_route.h Sat Apr 26 23:17:47 2003 -+++ ospf6d/ospf6_route.h Tue Oct 1 00:41:10 2002 -@@ -186,6 +186,9 @@ - void ospf6_route_table_freeze (struct ospf6_route_table *); - void ospf6_route_table_thaw (struct ospf6_route_table *); - -+void ospf6_route_log_request (char *what, char *where, -+ struct ospf6_route_req *request); -+ - void - ospf6_route_hook_register (void (*add) (struct ospf6_route_req *), - void (*change) (struct ospf6_route_req *), -diff -x CVS -urN ospf6d.old/ospf6_routemap.c ospf6d/ospf6_routemap.c ---- ospf6d.old/ospf6_routemap.c Sat Apr 26 23:17:47 2003 -+++ ospf6d/ospf6_routemap.c Tue Oct 1 00:41:10 2002 -@@ -22,9 +22,6 @@ - - #include <zebra.h> - --#if 1 --#include "ospf6d.h" --#else - #include "log.h" - #include "memory.h" - #include "linklist.h" -@@ -32,11 +29,13 @@ - #include "command.h" - #include "vty.h" - #include "routemap.h" -+#include "table.h" - #include "plist.h" - --#include "ospf6_top.h" --#include "ospf6_redistribute.h" --#endif -+#include "ospf6_route.h" -+#include "ospf6_prefix.h" -+#include "ospf6_lsa.h" -+#include "ospf6_asbr.h" - - route_map_result_t - ospf6_routemap_rule_match_address_prefixlist (void *rule, -@@ -70,7 +69,8 @@ - XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); - } - --struct route_map_rule_cmd ospf6_routemap_rule_match_address_prefixlist_cmd = -+struct route_map_rule_cmd -+ospf6_routemap_rule_match_address_prefixlist_cmd = - { - "ipv6 address prefix-list", - ospf6_routemap_rule_match_address_prefixlist, -@@ -83,15 +83,15 @@ - route_map_object_t type, void *object) - { - char *metric_type = rule; -- struct ospf6_route_req *route = object; -+ struct ospf6_external_info *info = object; - - if (type != RMAP_OSPF6) - return RMAP_OKAY; - - if (strcmp (metric_type, "type-2") == 0) -- route->path.metric_type = 2; -+ info->metric_type = 2; - else -- route->path.metric_type = 1; -+ info->metric_type = 1; - - return RMAP_OKAY; - } -@@ -108,7 +108,8 @@ - XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); - } - --struct route_map_rule_cmd ospf6_routemap_rule_set_metric_type_cmd = -+struct route_map_rule_cmd -+ospf6_routemap_rule_set_metric_type_cmd = - { - "metric-type", - ospf6_routemap_rule_set_metric_type, -@@ -121,14 +122,12 @@ - route_map_object_t type, void *object) - { - char *metric = rule; -- struct ospf6_route_req *route = object; -+ struct ospf6_external_info *info = object; - - if (type != RMAP_OSPF6) - return RMAP_OKAY; - -- route->path.cost = atoi (metric); -- route->path.cost_e2 = atoi (metric); -- -+ info->metric = atoi (metric); - return RMAP_OKAY; - } - -@@ -144,7 +143,8 @@ - XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); - } - --struct route_map_rule_cmd ospf6_routemap_rule_set_metric_cmd = -+struct route_map_rule_cmd -+ospf6_routemap_rule_set_metric_cmd = - { - "metric", - ospf6_routemap_rule_set_metric, -@@ -157,14 +157,14 @@ - route_map_object_t type, void *object) - { - char *forwarding = rule; -- struct ospf6_route_req *route = object; -+ struct ospf6_external_info *info = object; - - if (type != RMAP_OSPF6) - return RMAP_OKAY; - -- if (inet_pton (AF_INET6, forwarding, &route->nexthop.address) != 1) -+ if (inet_pton (AF_INET6, forwarding, &info->forwarding) != 1) - { -- memset (&route->nexthop.address, 0, sizeof (struct in6_addr)); -+ memset (&info->forwarding, 0, sizeof (struct in6_addr)); - return RMAP_ERROR; - } - -@@ -183,7 +183,8 @@ - XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); - } - --struct route_map_rule_cmd ospf6_routemap_rule_set_forwarding_cmd = -+struct route_map_rule_cmd -+ospf6_routemap_rule_set_forwarding_cmd = - { - "forwarding-address", - ospf6_routemap_rule_set_forwarding, -@@ -331,8 +332,8 @@ - { - route_map_init (); - route_map_init_vty (); -- route_map_add_hook (ospf6_redistribute_routemap_update); -- route_map_delete_hook (ospf6_redistribute_routemap_update); -+ route_map_add_hook (ospf6_asbr_routemap_update); -+ route_map_delete_hook (ospf6_asbr_routemap_update); - - route_map_install_match (&ospf6_routemap_rule_match_address_prefixlist_cmd); - route_map_install_set (&ospf6_routemap_rule_set_metric_type_cmd); -diff -x CVS -urN ospf6d.old/ospf6_spf.c ospf6d/ospf6_spf.c ---- ospf6d.old/ospf6_spf.c Sat Apr 26 23:17:47 2003 -+++ ospf6d/ospf6_spf.c Sat Nov 9 11:25:30 2002 -@@ -281,7 +281,7 @@ - static struct in6_addr * - ospf6_spf_get_ipaddr (u_int32_t id, u_int32_t adv_router, u_int32_t ifindex) - { -- char buf[64]; -+ char buf[64], nhbuf[64]; - struct ospf6_interface *o6i; - struct ospf6_neighbor *o6n; - struct ospf6_lsa *lsa; -@@ -303,26 +303,30 @@ - lsa = node.lsa; - - /* return Linklocal Address field if the Link-LSA exists */ -- if (lsa) -+ if (lsa && lsa->header->adv_router == adv_router) - { - struct ospf6_link_lsa *link_lsa; - link_lsa = (struct ospf6_link_lsa *) (lsa->header + 1); - return &link_lsa->llsa_linklocal; - } - -- zlog_warn ("SPF: Can't find Link-LSA for %s, " -- "use source address from his packet", -+ zlog_warn ("SPF: Can't find Link-LSA for %s", - inet_ntop (AF_INET, &adv_router, buf, sizeof (buf))); - - o6n = ospf6_neighbor_lookup (adv_router, o6i); - if (! o6n) - { - inet_ntop (AF_INET, &adv_router, buf, sizeof (buf)); -- zlog_err ("SPF: Can't find neighbor %s in %s", -+ zlog_err ("SPF: Can't find neighbor %s in %s, " -+ "unable to find his linklocal address", - buf, o6i->interface->name); - return (struct in6_addr *) NULL; - } - -+ zlog_warn ("SPF: use packet's source address for %s's nexthop: %s", -+ inet_ntop (AF_INET, &adv_router, buf, sizeof (buf)), -+ inet_ntop (AF_INET6, &o6n->hisaddr, nhbuf, sizeof (nhbuf))); -+ - return &o6n->hisaddr; - } - -@@ -478,18 +482,22 @@ - inet_ntop (AF_INET, &adv_router, buf_router, sizeof (buf_router)); - inet_ntop (AF_INET, &id, buf_id, sizeof (buf_id)); - -- if (type == htons (OSPF6_LSA_TYPE_ROUTER)) -- zlog_err ("SPF: Can't find LSA for W (%s *): not found", -- buf_router); -- else -- zlog_err ("SPF: Can't find LSA for W (%s %s): not found", -- buf_router, buf_id); -+ if (IS_OSPF6_DUMP_SPF) -+ { -+ if (type == htons (OSPF6_LSA_TYPE_ROUTER)) -+ zlog_info ("SPF: Can't find LSA for W (%s *): not found", -+ buf_router); -+ else -+ zlog_info ("SPF: Can't find LSA for W (%s %s): not found", -+ buf_router, buf_id); -+ } - return (struct ospf6_vertex *) NULL; - } - - if (IS_LSA_MAXAGE (lsa)) - { -- zlog_err ("SPF: Associated LSA for W is MaxAge: %s", lsa->str); -+ if (IS_OSPF6_DUMP_SPF) -+ zlog_info ("SPF: Associated LSA for W is MaxAge: %s", lsa->str); - return (struct ospf6_vertex *) NULL; - } - -@@ -504,8 +512,9 @@ - } - if (! backreference) - { -- zlog_err ("SPF: Back reference failed: V: %s, W: %s", -- V->lsa->str, lsa->str); -+ if (IS_OSPF6_DUMP_SPF) -+ zlog_info ("SPF: Back reference failed: V: %s, W: %s", -+ V->lsa->str, lsa->str); - return (struct ospf6_vertex *) NULL; - } - -diff -x CVS -urN ospf6d.old/ospf6_top.c ospf6d/ospf6_top.c ---- ospf6d.old/ospf6_top.c Sat Apr 26 23:17:47 2003 -+++ ospf6d/ospf6_top.c Tue Oct 1 00:51:40 2002 -@@ -43,7 +43,6 @@ - #include "ospf6_area.h" - #include "ospf6_top.h" - --#include "ospf6_redistribute.h" - #include "ospf6_route.h" - #include "ospf6_zebra.h" - -@@ -152,7 +151,7 @@ - vty_out (vty, " Supports only single TOS(TOS0) routes%s", VTY_NEWLINE); - - /* Redistribute config */ -- ospf6_redistribute_show_config (vty, ospf6); -+ ospf6_redistribute_show_config (vty); - - /* LSAs */ - vty_out (vty, " Number of AS scoped LSAs is %u%s", -@@ -250,9 +249,6 @@ - - o6->lsdb = ospf6_lsdb_create (); - -- /* route table init */ -- ospf6_redistribute_init (o6); -- - o6->foreach_area = ospf6_top_foreach_area; - o6->foreach_if = ospf6_top_foreach_interface; - o6->foreach_nei = ospf6_top_foreach_neighbor; -@@ -264,12 +260,14 @@ - ospf6_top_topology_remove, - o6->topology_table); - -+#if 0 - snprintf (namebuf, sizeof (namebuf), "External table"); - o6->external_table = ospf6_route_table_create (namebuf); - ospf6_route_hook_register (ospf6_asbr_external_route_add, - ospf6_asbr_external_route_add, - ospf6_asbr_external_route_remove, - o6->external_table); -+#endif /*0*/ - - snprintf (namebuf, sizeof (namebuf), "Top route table"); - o6->route_table = ospf6_route_table_create (namebuf); -diff -x CVS -urN ospf6d.old/ospf6_zebra.c ospf6d/ospf6_zebra.c ---- ospf6d.old/ospf6_zebra.c Sat Apr 26 23:17:47 2003 -+++ ospf6d/ospf6_zebra.c Wed Oct 2 17:16:56 2002 -@@ -22,7 +22,7 @@ - #include "ospf6d.h" - - #include "ospf6_interface.h" --#include "ospf6_redistribute.h" -+#include "ospf6_asbr.h" - - #include "ospf6_linklist.h" - -@@ -202,13 +202,14 @@ - struct stream *s; - struct zapi_ipv6 api; - unsigned long ifindex; -- struct in6_addr nexthop; - struct prefix_ipv6 p; -+ struct in6_addr *nexthop; - char prefixstr[128], nexthopstr[128]; - - s = zclient->ibuf; - ifindex = 0; -- memset (&nexthop, 0, sizeof (struct in6_addr)); -+ nexthop = NULL; -+ memset (&api, 0, sizeof (api)); - - /* Type, flags, message. */ - api.type = stream_getc (s); -@@ -225,7 +226,9 @@ - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP)) - { - api.nexthop_num = stream_getc (s); -- stream_get (&nexthop, s, 16); -+ nexthop = (struct in6_addr *) -+ malloc (api.nexthop_num * sizeof (struct in6_addr)); -+ stream_get (nexthop, s, api.nexthop_num * sizeof (struct in6_addr)); - } - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX)) - { -@@ -256,11 +259,15 @@ - zebra_route_name [api.type], prefixstr, - nexthopstr, ifindex); - } -- -+ - if (command == ZEBRA_IPV6_ROUTE_ADD) -- ospf6_redistribute_route_add (api.type, ifindex, &p); -+ ospf6_asbr_route_add (api.type, ifindex, (struct prefix *) &p, -+ api.nexthop_num, nexthop); - else -- ospf6_redistribute_route_remove (api.type, ifindex, &p); -+ ospf6_asbr_route_remove (api.type, ifindex, (struct prefix *) &p); -+ -+ if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP)) -+ free (nexthop); - - return 0; - } -@@ -448,10 +455,6 @@ - - if (IS_OSPF6_DUMP_ZEBRA) - zlog_info ("ZEBRA: found alternative path to add"); -- -- linklist_remove (nexthop, nexthop_list); -- XFREE (MTYPE_OSPF6_OTHER, nexthop); -- assert (nexthop_list->count == 0); - - memcpy (&seconde_path, &route.path, sizeof (struct ospf6_path)); - type = ADD; -diff -x CVS -urN ospf6d.old/ospf6d.c ospf6d/ospf6d.c ---- ospf6d.old/ospf6d.c Sat Apr 26 23:17:47 2003 -+++ ospf6d/ospf6d.c Mon Mar 24 17:45:16 2003 -@@ -21,6 +21,8 @@ - - #include "ospf6d.h" - -+#include "ospf6_damp.h" -+ - /* global ospf6d variable */ - int ospf6_sock; - list iflist; -@@ -536,8 +538,8 @@ - return CMD_SUCCESS; - } - --DEFUN (area_range, -- area_range_cmd, -+DEFUN (ospf6_area_range, -+ ospf6_area_range_cmd, - "area A.B.C.D range X:X::X:X/M", - "OSPFv3 area parameters\n" - "OSPFv3 area ID in IPv4 address format\n" -@@ -689,6 +691,7 @@ - vty_out (vty, " router-id %s%s", buf, VTY_NEWLINE); - - ospf6_redistribute_config_write (vty); -+ ospf6_damp_config_write (vty); - - for (j = listhead (ospf6->area_list); j; nextnode (j)) - { -@@ -745,7 +748,7 @@ - install_element (OSPF6_NODE, &no_interface_area_cmd); - install_element (OSPF6_NODE, &passive_interface_cmd); - install_element (OSPF6_NODE, &no_passive_interface_cmd); -- install_element (OSPF6_NODE, &area_range_cmd); -+ install_element (OSPF6_NODE, &ospf6_area_range_cmd); - - /* Make empty list of top list. */ - if_init (); -@@ -757,6 +760,10 @@ - prefix_list_init (); - - ospf6_dump_init (); -+ -+#ifdef HAVE_OSPF6_DAMP -+ ospf6_damp_init (); -+#endif /*HAVE_OSPF6_DAMP*/ - - ospf6_hook_init (); - ospf6_lsa_init (); -diff -x CVS -urN ospf6d.old/ospf6d.h ospf6d/ospf6d.h ---- ospf6d.old/ospf6d.h Sat Apr 26 23:17:47 2003 -+++ ospf6d/ospf6d.h Fri Apr 25 11:40:31 2003 -@@ -59,7 +59,6 @@ - #include "ospf6_neighbor.h" - #include "ospf6_ism.h" - #include "ospf6_nsm.h" --#include "ospf6_redistribute.h" - #include "ospf6_route.h" - #include "ospf6_dbex.h" - #include "ospf6_network.h" -@@ -74,7 +73,7 @@ - #define HASHVAL 64 - #define MAXIOVLIST 1024 - --#define OSPF6_DAEMON_VERSION "0.9.6l" -+#define OSPF6_DAEMON_VERSION "0.9.6p" - - #define AF_LINKSTATE 0xff - diff --git a/net/zebra/files/patch-ospfd_packet.c b/net/zebra/files/patch-ospfd_packet.c deleted file mode 100644 index cb3872872064..000000000000 --- a/net/zebra/files/patch-ospfd_packet.c +++ /dev/null @@ -1,11 +0,0 @@ ---- ospfd/ospf_packet.c.orig Thu Jul 4 05:06:41 2002 -+++ ospfd/ospf_packet.c Fri Mar 28 00:05:26 2003 -@@ -276,7 +276,7 @@ - - /* check crypto seqnum. */ - nbr = ospf_nbr_lookup_by_routerid (oi->nbrs, &ospfh->router_id); -- if (nbr && ntohl(nbr->crypt_seqnum) >= ntohl(ospfh->u.crypt.crypt_seqnum)) -+ if (nbr && ntohl(nbr->crypt_seqnum) > ntohl(ospfh->u.crypt.crypt_seqnum)) - return 0; - - /* Generate a digest for the ospf packet - their digest + our digest. */ diff --git a/net/zebra/files/patch-remote_dos b/net/zebra/files/patch-remote_dos deleted file mode 100644 index ad34a751beea..000000000000 --- a/net/zebra/files/patch-remote_dos +++ /dev/null @@ -1,23 +0,0 @@ ---- lib/vty.c.orig Sun Aug 18 15:49:50 2002 -+++ lib/vty.c Thu Nov 20 22:17:46 2003 -@@ -1138,13 +1138,16 @@ - break; - case SE: - { -- char *buffer = (char *)vty->sb_buffer->head->data; -- int length = vty->sb_buffer->length; -+ char *buffer; -+ int length; - -- if (buffer == NULL) -+ if (!vty->iac_sb_in_progress) - return 0; - -- if (!vty->iac_sb_in_progress) -+ buffer = (char *)vty->sb_buffer->head->data; -+ length = vty->sb_buffer->length; -+ -+ if (buffer == NULL) - return 0; - - if (buffer[0] == '\0') |