3427 lines
101 KiB
Text
3427 lines
101 KiB
Text
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
|
||
|