Initial revision

This commit is contained in:
jardin 2003-12-23 08:09:43 +00:00
parent 3dbf99698a
commit eb5d44eb8d
76 changed files with 45393 additions and 0 deletions

3
isisd/AUTHORS Normal file
View File

@ -0,0 +1,3 @@
Sampo Saaristo <sambo@cs.tut.fi>
Ofer Wald <ofersf@islands.co.il>
Hannes Gredler <hannes@gredler.at>

339
isisd/COPYING Normal file
View File

@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
675 Mass Ave, Cambridge, MA 02139, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
Appendix: How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
This program 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 of the License, or
(at your option) any later version.
This program 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 this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

69
isisd/ChangeLog Normal file
View File

@ -0,0 +1,69 @@
Version 0.0.7 to 0.0.8
======================
o A bug in handling of other ISs fragments fixed
o hello interval now specified in *seconds*
o replaced the adj->ipv[46]_addr tables with linked lists
Version 0.0.6 to 0.0.7 (Oct 29 2002)
======================
o changed to zebra-0.93b
o fixed a seg in SPF
o handling/generation of LSP fragments
o domain/area/circuit password
Version 0.0.5 to 0.0.6 (Jul 4 2002)
======================
o lots of changes to SPF
- runs the SPF for IPv4 and IPv6 separately
- a number of bugs fixed
- simplified the implementation
- "7.2.7 Removal of excess paths" implemented
o ported to freebsd (tested in 4.5-STABLE and 4.6-STABLE)
o moved to zebra-0.93-pre2
o "show isis topology" command added
o "show (ip|ipv6) route isis commands added to zebra
o a number of fixes and additions (e.g. checksum calculation and DIS state
change event) by BeomSeok Gwak added
Version 0.0.4 to 0.0.5 (Apr 26 2002)
======================
o changed to zebra-0.93-pre1
o number of memory leaks + small bugs fixed
o a bug related to processing of neigbors when installing routes fixed
Version 0.0.3 to 0.0.4 (Feb 27 2002)
======================
o initial version of SPT algorithm
o installing routes though zebrad
o isis debug commands
o work on IS-IS events (e.g. circuit state change)
Version 0.0.2 to 0.0.3 (Jan 17 2002)
======================
o LSP handling improved
o generation of pseudonode LSPs
o DR election enhanced
o support for p2p interfaces
o support for topology simulation
o more detailed output for show commands
Version 0.0.1 to 0.0.2 (Dec 13 2001)
======================
o circuit state machine (isis_csm.[ch]) added
o lot of work on LSP generation
o ISO checksum
o uses DGRAM sockets instead of RAW
o gets IP(v6) addresses from zebra
o debug can be controlled with "debug isis" command
o read support for TE tlvs
o work started on p2p interfaces
o work started on isis events

18
isisd/INSTALL-0.0.4 Normal file
View File

@ -0,0 +1,18 @@
ISISd package for zebra 0.92a installation instructions:
1. grab the zebra 0.92a package from www.zebra.org
2. unpack the package using tar -zxvf zebra-0.92a.tar.gz
3. enter the zebra-092a directory
4. copy the contents of the isisd package into the zebra dir
5. enter the isisd/modified directory
6. use the README file and copy the files to the appropriate zebra dirs
(the simplest way to do so would be 'source README')
7. enter the main zebra directory and issue 'automake','autoconf' and
'autoheader'. if using automake version 1.5 and up use the '-i' option.
8. run './configure --enable-isisd' (you may use other zebra config commands)
9. run 'make'
10. find your self something entertaining to do for the next couple of minutes
11. you can issue 'make install' or simply work from the isisd directory
for any problems, contact the developers at the sourceforge site
http://www.sf.net/projects/isisd

55
isisd/Makefile.am Normal file
View File

@ -0,0 +1,55 @@
## Process this file with automake to produce Makefile.in.
# INCLUDES = @INCLUDES@ -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -Itopology
INCLUDES = @INCLUDES@ -I.. -I$(top_srcdir) -I$(top_srcdir)/lib
DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
INSTALL_SDATA=@INSTALL@ -m 600
LIBS = @LIBS@
noinst_LIBRARIES = libisis.a
sbin_PROGRAMS = isisd
libisis_a_SOURCES = \
isis_adjacency.c isis_lsp.c dict.c isis_circuit.c isis_pdu.c \
isis_tlv.c isisd.c isis_misc.c isis_network.c isis_zebra.c isis_dr.c \
isis_flags.c isis_dynhn.c iso_checksum.c isis_csm.c isis_events.c \
isis_spf.c isis_route.c isis_routemap.c
noinst_HEADERS = \
isisd.h isis_pdu.h isis_tlv.h isis_adjacency.h isis_constants.h \
isis_lsp.h dict.h isis_circuit.h isis_misc.h isis_network.h \
isis_zebra.h isis_dr.h isis_flags.h isis_dynhn.h isis_common.h \
iso_checksum.h isis_csm.h isis_events.h isis_spf.h isis_route.h
isisd_SOURCES = \
isis_main.c $(libisis_a_SOURCES)
isisd_LDADD = ../lib/libzebra.a
sysconf_DATA = isisd.conf.sample
EXTRA_DIST = $(sysconf_DATA)
install-sysconfDATA: $(sysconf_DATA)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(sysconfdir)
@list='$(sysconf_DATA)'; for p in $$list; do \
if test -f $(srcdir)/$$p; then \
echo " $(INSTALL_SDATA) $(srcdir)/$$p $(DESTDIR)$(sysconfdir)/$$p"; \
$(INSTALL_SDATA) $(srcdir)/$$p $(DESTDIR)$(sysconfdir)/$$p; \
else if test -f $$p; then \
echo " $(INSTALL_SDATA) $$p $(DESTDIR)$(sysconfdir)/$$p"; \
$(INSTALL_SDATA) $$p $(DESTDIR)$(sysconfdir)/$$p; \
fi; fi; \
done
depend:
@$(CPP) -MM $(INCLUDES) $(LDFLAGS) *.c
## File dependency.
isis_adjacency.o : isis_adjacency.c ../lib/version.h ../lib/log.h \
../isisd/isis_adjacency.h
isis_pdu.o : isis_pdu.c ../lib/log.h ../isisd/isisd.h \
../isisd/isis_constants.h ../isisd/isis_adjacency.h \
../isisd/isis_pdu.h
isis_circuit.o : isis_circuit.c ../isisd/isis_circuit.h

463
isisd/Makefile.in Normal file
View File

@ -0,0 +1,463 @@
# Makefile.in generated by automake 1.6.2 from Makefile.am.
# @configure_input@
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
# Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
SHELL = @SHELL@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
sbindir = @sbindir@
libexecdir = @libexecdir@
datadir = @datadir@
sysconfdir = @sysconfdir@
sharedstatedir = @sharedstatedir@
localstatedir = @localstatedir@
libdir = @libdir@
infodir = @infodir@
mandir = @mandir@
includedir = @includedir@
oldincludedir = /usr/include
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
ACLOCAL = @ACLOCAL@
AUTOCONF = @AUTOCONF@
AUTOMAKE = @AUTOMAKE@
AUTOHEADER = @AUTOHEADER@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_HEADER = $(INSTALL_DATA)
transform = @program_transform_name@
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
host_alias = @host_alias@
host_triplet = @host@
EXEEXT = @EXEEXT@
OBJEXT = @OBJEXT@
PATH_SEPARATOR = @PATH_SEPARATOR@
AMTAR = @AMTAR@
AR = @AR@
AWK = @AWK@
BGPD = @BGPD@
CC = @CC@
CPP = @CPP@
CURSES = @CURSES@
DEPDIR = @DEPDIR@
IF_METHOD = @IF_METHOD@
IF_PROC = @IF_PROC@
# INCLUDES = @INCLUDES@ -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -Itopology
INCLUDES = @INCLUDES@ -I.. -I$(top_srcdir) -I$(top_srcdir)/lib
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
IPFORWARD = @IPFORWARD@
ISISD = @ISISD@
KERNEL_METHOD = @KERNEL_METHOD@
LIBPAM = @LIBPAM@
LIB_IPV6 = @LIB_IPV6@
LIB_REGEX = @LIB_REGEX@
MULTIPATH_NUM = @MULTIPATH_NUM@
OSPF6D = @OSPF6D@
OSPFD = @OSPFD@
OTHER_METHOD = @OTHER_METHOD@
PACKAGE = @PACKAGE@
RANLIB = @RANLIB@
RIPD = @RIPD@
RIPNGD = @RIPNGD@
RTREAD_METHOD = @RTREAD_METHOD@
RT_METHOD = @RT_METHOD@
STRIP = @STRIP@
VERSION = @VERSION@
VTYSH = @VTYSH@
ZEBRA = @ZEBRA@
am__include = @am__include@
am__quote = @am__quote@
install_sh = @install_sh@
DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
INSTALL_SDATA = @INSTALL@ -m 600
LIBS = @LIBS@
noinst_LIBRARIES = libisis.a
sbin_PROGRAMS = isisd
libisis_a_SOURCES = \
isis_adjacency.c isis_lsp.c dict.c isis_circuit.c isis_pdu.c \
isis_tlv.c isisd.c isis_misc.c isis_network.c isis_zebra.c isis_dr.c \
isis_flags.c isis_dynhn.c iso_checksum.c isis_csm.c isis_events.c \
isis_spf.c isis_route.c isis_routemap.c
noinst_HEADERS = \
isisd.h isis_pdu.h isis_tlv.h isis_adjacency.h isis_constants.h \
isis_lsp.h dict.h isis_circuit.h isis_misc.h isis_network.h \
isis_zebra.h isis_dr.h isis_flags.h isis_dynhn.h isis_common.h \
iso_checksum.h isis_csm.h isis_events.h isis_spf.h isis_route.h
isisd_SOURCES = \
isis_main.c $(libisis_a_SOURCES)
isisd_LDADD = ../lib/libzebra.a
sysconf_DATA = isisd.conf.sample
EXTRA_DIST = $(sysconf_DATA)
subdir = isisd
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
LIBRARIES = $(noinst_LIBRARIES)
libisis_a_AR = $(AR) cru
libisis_a_LIBADD =
am_libisis_a_OBJECTS = isis_adjacency.$(OBJEXT) isis_lsp.$(OBJEXT) \
dict.$(OBJEXT) isis_circuit.$(OBJEXT) isis_pdu.$(OBJEXT) \
isis_tlv.$(OBJEXT) isisd.$(OBJEXT) isis_misc.$(OBJEXT) \
isis_network.$(OBJEXT) isis_zebra.$(OBJEXT) isis_dr.$(OBJEXT) \
isis_flags.$(OBJEXT) isis_dynhn.$(OBJEXT) \
iso_checksum.$(OBJEXT) isis_csm.$(OBJEXT) isis_events.$(OBJEXT) \
isis_spf.$(OBJEXT) isis_route.$(OBJEXT) isis_routemap.$(OBJEXT)
libisis_a_OBJECTS = $(am_libisis_a_OBJECTS)
sbin_PROGRAMS = isisd$(EXEEXT)
PROGRAMS = $(sbin_PROGRAMS)
am__objects_1 = isis_adjacency.$(OBJEXT) isis_lsp.$(OBJEXT) \
dict.$(OBJEXT) isis_circuit.$(OBJEXT) isis_pdu.$(OBJEXT) \
isis_tlv.$(OBJEXT) isisd.$(OBJEXT) isis_misc.$(OBJEXT) \
isis_network.$(OBJEXT) isis_zebra.$(OBJEXT) isis_dr.$(OBJEXT) \
isis_flags.$(OBJEXT) isis_dynhn.$(OBJEXT) \
iso_checksum.$(OBJEXT) isis_csm.$(OBJEXT) isis_events.$(OBJEXT) \
isis_spf.$(OBJEXT) isis_route.$(OBJEXT) isis_routemap.$(OBJEXT)
am_isisd_OBJECTS = isis_main.$(OBJEXT) $(am__objects_1)
isisd_OBJECTS = $(am_isisd_OBJECTS)
isisd_DEPENDENCIES = ../lib/libzebra.a
isisd_LDFLAGS =
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/dict.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/isis_adjacency.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/isis_circuit.Po ./$(DEPDIR)/isis_csm.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/isis_dr.Po ./$(DEPDIR)/isis_dynhn.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/isis_events.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/isis_flags.Po ./$(DEPDIR)/isis_lsp.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/isis_main.Po ./$(DEPDIR)/isis_misc.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/isis_network.Po ./$(DEPDIR)/isis_pdu.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/isis_route.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/isis_routemap.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/isis_spf.Po ./$(DEPDIR)/isis_tlv.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/isis_zebra.Po ./$(DEPDIR)/isisd.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/iso_checksum.Po
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
CFLAGS = @CFLAGS@
DIST_SOURCES = $(libisis_a_SOURCES) $(isisd_SOURCES)
DATA = $(sysconf_DATA)
HEADERS = $(noinst_HEADERS)
DIST_COMMON = README $(noinst_HEADERS) AUTHORS COPYING ChangeLog \
Makefile.am Makefile.in TODO
SOURCES = $(libisis_a_SOURCES) $(isisd_SOURCES)
all: all-am
.SUFFIXES:
.SUFFIXES: .c .o .obj
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu isisd/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
clean-noinstLIBRARIES:
-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
libisis.a: $(libisis_a_OBJECTS) $(libisis_a_DEPENDENCIES)
-rm -f libisis.a
$(libisis_a_AR) libisis.a $(libisis_a_OBJECTS) $(libisis_a_LIBADD)
$(RANLIB) libisis.a
sbinPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
install-sbinPROGRAMS: $(sbin_PROGRAMS)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(sbindir)
@list='$(sbin_PROGRAMS)'; for p in $$list; do \
p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
if test -f $$p \
; then \
p1=`echo "$$p1" | sed -e 's,^.*/,,'`; \
f=`echo $$p1|sed '$(transform);s/$$/$(EXEEXT)/'`; \
echo " $(INSTALL_PROGRAM_ENV) $(sbinPROGRAMS_INSTALL) $$p $(DESTDIR)$(sbindir)/$$f"; \
$(INSTALL_PROGRAM_ENV) $(sbinPROGRAMS_INSTALL) $$p $(DESTDIR)$(sbindir)/$$f; \
else :; fi; \
done
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,^.*/,,'`; \
echo " rm -f $(DESTDIR)$(sbindir)/$$f"; \
rm -f $(DESTDIR)$(sbindir)/$$f; \
done
clean-sbinPROGRAMS:
-test -z "$(sbin_PROGRAMS)" || rm -f $(sbin_PROGRAMS)
isisd$(EXEEXT): $(isisd_OBJECTS) $(isisd_DEPENDENCIES)
@rm -f isisd$(EXEEXT)
$(LINK) $(isisd_LDFLAGS) $(isisd_OBJECTS) $(isisd_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT) core *.core
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dict.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isis_adjacency.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isis_circuit.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isis_csm.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isis_dr.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isis_dynhn.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isis_events.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isis_flags.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isis_lsp.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isis_main.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isis_misc.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isis_network.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isis_pdu.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isis_route.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isis_routemap.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isis_spf.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isis_tlv.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isis_zebra.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isisd.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iso_checksum.Po@am__quote@
distclean-depend:
-rm -rf ./$(DEPDIR)
.c.o:
@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
$(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$<
.c.obj:
@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
$(COMPILE) -c `cygpath -w $<`
CCDEPMODE = @CCDEPMODE@
uninstall-info-am:
sysconfDATA_INSTALL = $(INSTALL_DATA)
uninstall-sysconfDATA:
@$(NORMAL_UNINSTALL)
@list='$(sysconf_DATA)'; for p in $$list; do \
f="`echo $$p | sed -e 's|^.*/||'`"; \
echo " rm -f $(DESTDIR)$(sysconfdir)/$$f"; \
rm -f $(DESTDIR)$(sysconfdir)/$$f; \
done
ETAGS = etags
ETAGSFLAGS =
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$tags$$unique" \
|| $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
top_distdir = ..
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
distdir: $(DISTFILES)
@list='$(DISTFILES)'; for file in $$list; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkinstalldirs) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LIBRARIES) $(PROGRAMS) $(DATA) $(HEADERS)
installdirs:
$(mkinstalldirs) $(DESTDIR)$(sbindir) $(DESTDIR)$(sysconfdir)
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-noinstLIBRARIES clean-sbinPROGRAMS \
mostlyclean-am
distclean: distclean-am
distclean-am: clean-am distclean-compile distclean-depend \
distclean-generic distclean-tags
dvi: dvi-am
dvi-am:
info: info-am
info-am:
install-data-am:
install-exec-am: install-sbinPROGRAMS install-sysconfDATA
install-info: install-info-am
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic
uninstall-am: uninstall-info-am uninstall-sbinPROGRAMS \
uninstall-sysconfDATA
.PHONY: GTAGS all all-am check check-am clean clean-generic \
clean-noinstLIBRARIES clean-sbinPROGRAMS distclean \
distclean-compile distclean-depend distclean-generic \
distclean-tags distdir dvi dvi-am info info-am install \
install-am install-data install-data-am install-exec \
install-exec-am install-info install-info-am install-man \
install-sbinPROGRAMS install-strip install-sysconfDATA \
installcheck installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic tags uninstall uninstall-am \
uninstall-info-am uninstall-sbinPROGRAMS uninstall-sysconfDATA
install-sysconfDATA: $(sysconf_DATA)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(sysconfdir)
@list='$(sysconf_DATA)'; for p in $$list; do \
if test -f $(srcdir)/$$p; then \
echo " $(INSTALL_SDATA) $(srcdir)/$$p $(DESTDIR)$(sysconfdir)/$$p"; \
$(INSTALL_SDATA) $(srcdir)/$$p $(DESTDIR)$(sysconfdir)/$$p; \
else if test -f $$p; then \
echo " $(INSTALL_SDATA) $$p $(DESTDIR)$(sysconfdir)/$$p"; \
$(INSTALL_SDATA) $$p $(DESTDIR)$(sysconfdir)/$$p; \
fi; fi; \
done
depend:
@$(CPP) -MM $(INCLUDES) $(LDFLAGS) *.c
isis_adjacency.o : isis_adjacency.c ../lib/version.h ../lib/log.h \
../isisd/isis_adjacency.h
isis_pdu.o : isis_pdu.c ../lib/log.h ../isisd/isisd.h \
../isisd/isis_constants.h ../isisd/isis_adjacency.h \
../isisd/isis_pdu.h
isis_circuit.o : isis_circuit.c ../isisd/isis_circuit.h
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

20
isisd/README Normal file
View File

@ -0,0 +1,20 @@
Modified files in the ZEBRA-0.92a package.
../configure.in
../Makefile.am
../acconfig.h
../lib/log.h
../lib/memory.h
../lib/vty.c
- case ISIS_NODE:
../lib/command.c
- case ISIS_NODE:
../lib/command.h
- ISIS_NODE, /* IS-IS protocol mode */
- str #definitions
Constraints
o Maximum number of interfaces 255

10
isisd/TODO Normal file
View File

@ -0,0 +1,10 @@
Things in the TODO list for the near future
o select nearest L2 when running SPF for L1
o remove the routes when holding time for nexthop expires
o redist
o autosummary
Not so urgent:
o Mesh groups

1496
isisd/dict.c Normal file

File diff suppressed because it is too large Load Diff

144
isisd/dict.h Normal file
View File

@ -0,0 +1,144 @@
/*
* Dictionary Abstract Data Type
* Copyright (C) 1997 Kaz Kylheku <kaz@ashi.footprints.net>
*
* Free Software License:
*
* All rights are reserved by the author, with the following exceptions:
* Permission is granted to freely reproduce and distribute this software,
* possibly in exchange for a fee, provided that this copyright notice appears
* intact. Permission is also granted to adapt this software to produce
* derivative works, as long as the modified versions carry this copyright
* notice and additional notices stating that the work has been modified.
* This source code may be translated into executable form and incorporated
* into proprietary software; there is no requirement for such software to
* contain a copyright notice related to this source.
*
* $Id: dict.h,v 1.1 2003/12/23 08:09:48 jardin Exp $
* $Name: $
*/
#ifndef DICT_H
#define DICT_H
#include <limits.h>
#ifdef KAZLIB_SIDEEFFECT_DEBUG
#include "sfx.h"
#endif
/*
* Blurb for inclusion into C++ translation units
*/
#ifdef __cplusplus
extern "C" {
#endif
typedef unsigned long dictcount_t;
#define DICTCOUNT_T_MAX ULONG_MAX
/*
* The dictionary is implemented as a red-black tree
*/
typedef enum { dnode_red, dnode_black } dnode_color_t;
typedef struct dnode_t {
#if defined(DICT_IMPLEMENTATION) || !defined(KAZLIB_OPAQUE_DEBUG)
struct dnode_t *dict_left;
struct dnode_t *dict_right;
struct dnode_t *dict_parent;
dnode_color_t dict_color;
const void *dict_key;
void *dict_data;
#else
int dict_dummy;
#endif
} dnode_t;
typedef int (*dict_comp_t)(const void *, const void *);
typedef dnode_t *(*dnode_alloc_t)(void *);
typedef void (*dnode_free_t)(dnode_t *, void *);
typedef struct dict_t {
#if defined(DICT_IMPLEMENTATION) || !defined(KAZLIB_OPAQUE_DEBUG)
dnode_t dict_nilnode;
dictcount_t dict_nodecount;
dictcount_t dict_maxcount;
dict_comp_t dict_compare;
dnode_alloc_t dict_allocnode;
dnode_free_t dict_freenode;
void *dict_context;
int dict_dupes;
#else
int dict_dummmy;
#endif
} dict_t;
typedef void (*dnode_process_t)(dict_t *, dnode_t *, void *);
typedef struct dict_load_t {
#if defined(DICT_IMPLEMENTATION) || !defined(KAZLIB_OPAQUE_DEBUG)
dict_t *dict_dictptr;
dnode_t dict_nilnode;
#else
int dict_dummmy;
#endif
} dict_load_t;
extern dict_t *dict_create(dictcount_t, dict_comp_t);
extern void dict_set_allocator(dict_t *, dnode_alloc_t, dnode_free_t, void *);
extern void dict_destroy(dict_t *);
extern void dict_free_nodes(dict_t *);
extern void dict_free(dict_t *);
extern dict_t *dict_init(dict_t *, dictcount_t, dict_comp_t);
extern void dict_init_like(dict_t *, const dict_t *);
extern int dict_verify(dict_t *);
extern int dict_similar(const dict_t *, const dict_t *);
extern dnode_t *dict_lookup(dict_t *, const void *);
extern dnode_t *dict_lower_bound(dict_t *, const void *);
extern dnode_t *dict_upper_bound(dict_t *, const void *);
extern void dict_insert(dict_t *, dnode_t *, const void *);
extern dnode_t *dict_delete(dict_t *, dnode_t *);
extern int dict_alloc_insert(dict_t *, const void *, void *);
extern void dict_delete_free(dict_t *, dnode_t *);
extern dnode_t *dict_first(dict_t *);
extern dnode_t *dict_last(dict_t *);
extern dnode_t *dict_next(dict_t *, dnode_t *);
extern dnode_t *dict_prev(dict_t *, dnode_t *);
extern dictcount_t dict_count(dict_t *);
extern int dict_isempty(dict_t *);
extern int dict_isfull(dict_t *);
extern int dict_contains(dict_t *, dnode_t *);
extern void dict_allow_dupes(dict_t *);
extern int dnode_is_in_a_dict(dnode_t *);
extern dnode_t *dnode_create(void *);
extern dnode_t *dnode_init(dnode_t *, void *);
extern void dnode_destroy(dnode_t *);
extern void *dnode_get(dnode_t *);
extern const void *dnode_getkey(dnode_t *);
extern void dnode_put(dnode_t *, void *);
extern void dict_process(dict_t *, void *, dnode_process_t);
extern void dict_load_begin(dict_load_t *, dict_t *);
extern void dict_load_next(dict_load_t *, dnode_t *, const void *);
extern void dict_load_end(dict_load_t *);
extern void dict_merge(dict_t *, dict_t *);
#if defined(DICT_IMPLEMENTATION) || !defined(KAZLIB_OPAQUE_DEBUG)
#ifdef KAZLIB_SIDEEFFECT_DEBUG
#define dict_isfull(D) (SFX_CHECK(D)->dict_nodecount == (D)->dict_maxcount)
#else
#define dict_isfull(D) ((D)->dict_nodecount == (D)->dict_maxcount)
#endif
#define dict_count(D) ((D)->dict_nodecount)
#define dict_isempty(D) ((D)->dict_nodecount == 0)
#define dnode_get(N) ((N)->dict_data)
#define dnode_getkey(N) ((N)->dict_key)
#define dnode_put(N, X) ((N)->dict_data = (X))
#endif
#ifdef __cplusplus
}
#endif
#endif

547
isisd/include-netbsd/clnp.h Normal file
View File

@ -0,0 +1,547 @@
/* $NetBSD: clnp.h,v 1.13 2001/08/20 12:00:54 wiz Exp $ */
/*-
* Copyright (c) 1991, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)clnp.h 8.2 (Berkeley) 4/16/94
*/
/***********************************************************
Copyright IBM Corporation 1987
All Rights Reserved
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the name of IBM not be
used in advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
SOFTWARE.
******************************************************************/
/*
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
*/
/* should be config option but cpp breaks with too many #defines */
#define DECBIT
/*
* Return true if the mbuf is a cluster mbuf
*/
#define IS_CLUSTER(m) ((m)->m_flags & M_EXT)
/*
* Move the halfword into the two characters
*/
#define HTOC(msb, lsb, hword)\
(msb) = (u_char)((hword) >> 8);\
(lsb) = (u_char)((hword) & 0xff)
/*
* Move the two charcters into the halfword
*/
#define CTOH(msb, lsb, hword)\
(hword) = ((msb) << 8) | (lsb)
/*
* Return true if the checksum has been set - ie. the checksum is
* not zero
*/
#define CKSUM_REQUIRED(clnp)\
(((clnp)->cnf_cksum_msb != 0) || ((clnp)->cnf_cksum_lsb != 0))
/*
* Fixed part of clnp header
*/
struct clnp_fixed {
u_char cnf_proto_id; /* network layer protocol identifier */
u_char cnf_hdr_len; /* length indicator (octets) */
u_char cnf_vers; /* version/protocol identifier
* extension */
u_char cnf_ttl;/* lifetime (500 milliseconds) */
u_char cnf_type; /* type code */
/* Includes err_ok, more_segs, and seg_ok */
u_char cnf_seglen_msb; /* pdu segment length (octets) high
* byte */
u_char cnf_seglen_lsb; /* pdu segment length (octets) low
* byte */
u_char cnf_cksum_msb; /* checksum high byte */
u_char cnf_cksum_lsb; /* checksum low byte */
} __attribute__((packed));
#define CNF_TYPE 0x1f
#define CNF_ERR_OK 0x20
#define CNF_MORE_SEGS 0x40
#define CNF_SEG_OK 0x80
#define CLNP_CKSUM_OFF 0x07 /* offset of checksum */
#define clnl_fixed clnp_fixed
/*
* Segmentation part of clnp header
*/
struct clnp_segment {
u_short cng_id; /* data unit identifier */
u_short cng_off;/* segment offset */
u_short cng_tot_len; /* total length */
};
/*
* Clnp fragment reassembly structures:
*
* All packets undergoing reassembly are linked together in
* clnp_fragl structures. Each clnp_fragl structure contains a
* pointer to the original clnp packet header, as well as a
* list of packet fragments. Each packet fragment
* is headed by a clnp_frag structure. This structure contains the
* offset of the first and last byte of the fragment, as well as
* a pointer to the data (an mbuf chain) of the fragment.
*/
/*
* NOTE:
* The clnp_frag structure is stored in an mbuf immedately
* preceding the fragment data. Since there are words in
* this struct, it must be word aligned.
*
* NOTE:
* All the fragment code assumes that the entire clnp header is
* contained in the first mbuf.
*/
struct clnp_frag {
u_int cfr_first; /* offset of first byte of this frag */
u_int cfr_last; /* offset of last byte of this frag */
u_int cfr_bytes; /* bytes to shave to get to data */
struct mbuf *cfr_data; /* ptr to data for this frag */
struct clnp_frag *cfr_next; /* next fragment in list */
};
struct clnp_fragl {
struct iso_addr cfl_src;/* source of the pkt */
struct iso_addr cfl_dst;/* destination of the pkt */
u_short cfl_id; /* id of the pkt */
u_char cfl_ttl;/* current ttl of pkt */
u_short cfl_last; /* offset of last byte of packet */
struct mbuf *cfl_orighdr; /* ptr to original header */
struct clnp_frag *cfl_frags; /* linked list of fragments for pkt */
struct clnp_fragl *cfl_next; /* next pkt being reassembled */
};
/*
* The following structure is used to index into an options section
* of a clnp datagram. These values can be used without worry that
* offset or length fields are invalid or too big, etc. That is,
* the consistancy of the options will be guaranteed before this
* structure is filled in. Any pointer (field ending in p) is
* actually the offset from the beginning of the mbuf the option
* is contained in. A value of NULL for any pointer
* means that the option is not present. The length any option
* does not include the option code or option length fields.
*/
struct clnp_optidx {
u_short cni_securep; /* ptr to start of security option */
char cni_secure_len; /* length of entire security option */
u_short cni_srcrt_s; /* offset of start of src rt option */
u_short cni_srcrt_len; /* length of entire src rt option */
u_short cni_recrtp; /* ptr to beginning of recrt option */
char cni_recrt_len; /* length of entire recrt option */
char cni_priorp; /* ptr to priority option */
u_short cni_qos_formatp; /* ptr to format of qos
* option */
char cni_qos_len; /* length of entire qos option */
u_char cni_er_reason; /* reason from ER pdu option */
/* ESIS options */
u_short cni_esct; /* value from ISH ESCT option */
u_short cni_netmaskp; /* ptr to beginning of netmask option */
char cni_netmask_len; /* length of entire netmask
* option */
u_short cni_snpamaskp; /* ptr to start of snpamask option */
char cni_snpamask_len; /* length of entire snpamask
* option */
};
#define ER_INVALREAS 0xff /* code for invalid ER pdu discard reason */
/* given an mbuf and addr of option, return offset from data of mbuf */
#define CLNP_OPTTOOFF(m, opt) ((u_short) (opt - mtod(m, caddr_t)))
/* given an mbuf and offset of option, return address of option */
#define CLNP_OFFTOOPT(m, off) ((caddr_t) (mtod(m, caddr_t) + off))
/* return true iff src route is valid */
#define CLNPSRCRT_VALID(oidx) ((oidx) && (oidx->cni_srcrt_s))
/* return the offset field of the src rt */
#define CLNPSRCRT_OFF(oidx, options)\
(*((u_char *)(CLNP_OFFTOOPT(options, oidx->cni_srcrt_s) + 1)))
/* return the type field of the src rt */
#define CLNPSRCRT_TYPE(oidx, options)\
((u_char)(*(CLNP_OFFTOOPT(options, oidx->cni_srcrt_s))))
/* return the length of the current address */
#define CLNPSRCRT_CLEN(oidx, options)\
((u_char)(*(CLNP_OFFTOOPT(options, oidx->cni_srcrt_s) + CLNPSRCRT_OFF(oidx, options) - 1)))
/* return the address of the current address */
#define CLNPSRCRT_CADDR(oidx, options)\
((caddr_t)(CLNP_OFFTOOPT(options, oidx->cni_srcrt_s) + CLNPSRCRT_OFF(oidx, options)))
/*
* return true if the src route has run out of routes this is true if the
* offset of next route is greater than the end of the rt
*/
#define CLNPSRCRT_TERM(oidx, options)\
(CLNPSRCRT_OFF(oidx, options) > oidx->cni_srcrt_len)
/*
* Options a user can set/get
*/
#define CLNPOPT_FLAGS 0x01 /* flags: seg permitted, no er xmit, etc */
#define CLNPOPT_OPTS 0x02 /* datagram options */
/*
* Values for particular datagram options
*/
#define CLNPOVAL_PAD 0xcc /* padding */
#define CLNPOVAL_SECURE 0xc5 /* security */
#define CLNPOVAL_SRCRT 0xc8 /* source routing */
#define CLNPOVAL_RECRT 0xcb /* record route */
#define CLNPOVAL_QOS 0xc3 /* quality of service */
#define CLNPOVAL_PRIOR 0xcd /* priority */
#define CLNPOVAL_ERREAS 0xc1 /* ER PDU ONLY: reason for discard */
#define CLNPOVAL_SRCSPEC 0x40 /* source address specific */
#define CLNPOVAL_DSTSPEC 0x80 /* destination address specific */
#define CLNPOVAL_GLOBAL 0xc0 /* globally unique */
/* Globally Unique QOS */
#define CLNPOVAL_SEQUENCING 0x10 /* sequencing preferred */
#define CLNPOVAL_CONGESTED 0x08 /* congestion experienced */
#define CLNPOVAL_LOWDELAY 0x04 /* low transit delay */
#define CLNPOVAL_PARTRT 0x00 /* partial source routing */
#define CLNPOVAL_COMPRT 0x01 /* complete source routing */
/*
* Clnp flags used in a control block flags field.
* NOTE: these must be out of the range of bits defined in ../net/raw_cb.h
*/
#define CLNP_NO_SEG 0x010 /* segmentation not permitted */
#define CLNP_NO_ER 0x020 /* do not generate ERs */
#define CLNP_SEND_RAW 0x080 /* send pkt as RAW DT not TP DT */
#define CLNP_NO_CKSUM 0x100 /* don't use clnp checksum */
#define CLNP_ECHO 0x200 /* send echo request */
#define CLNP_NOCACHE 0x400 /* don't store cache information */
#define CLNP_ECHOR 0x800 /* send echo reply */
/* valid clnp flags */
#define CLNP_VFLAGS \
(CLNP_SEND_RAW|CLNP_NO_SEG|CLNP_NO_ER|CLNP_NO_CKSUM|\
CLNP_ECHO|CLNP_NOCACHE|CLNP_ECHOR)
/*
* Constants used by clnp
*/
#define CLNP_HDR_MIN (sizeof (struct clnp_fixed))
#define CLNP_HDR_MAX (254)
#define CLNP_TTL_UNITS 2 /* 500 milliseconds */
#define CLNP_TTL 15*CLNP_TTL_UNITS /* time to live (seconds) */
#define ISO8473_V1 0x01
/*
* Clnp packet types
* In order to test raw clnp and tp/clnp simultaneously, a third type of
* packet has been defined: CLNP_RAW. This is done so that the input
* routine can switch to the correct input routine (rclnp_input or
* tpclnp_input) based on the type field. If clnp had a higher level
* protocol field, this would not be necessary.
*/
#define CLNP_DT 0x1C /* normal data */
#define CLNP_ER 0x01 /* error report */
#define CLNP_RAW 0x1D /* debug only */
#define CLNP_EC 0x1E /* echo packet */
#define CLNP_ECR 0x1F /* echo reply */
/*
* ER pdu error codes
*/
#define GEN_NOREAS 0x00 /* reason not specified */
#define GEN_PROTOERR 0x01 /* protocol procedure error */
#define GEN_BADCSUM 0x02 /* incorrect checksum */
#define GEN_CONGEST 0x03 /* pdu discarded due to congestion */
#define GEN_HDRSYNTAX 0x04 /* header syntax error */
#define GEN_SEGNEEDED 0x05 /* need segmentation but not allowed */
#define GEN_INCOMPLETE 0x06 /* incomplete pdu received */
#define GEN_DUPOPT 0x07 /* duplicate option */
/* address errors */
#define ADDR_DESTUNREACH 0x80 /* destination address unreachable */
#define ADDR_DESTUNKNOWN 0x81 /* destination address unknown */
/* source routing */
#define SRCRT_UNSPECERR 0x90 /* unspecified src rt error */
#define SRCRT_SYNTAX 0x91 /* syntax error in src rt field */
#define SRCRT_UNKNOWNADDR 0x92 /* unknown addr in src rt field */
#define SRCRT_BADPATH 0x93 /* path not acceptable */
/* lifetime */
#define TTL_EXPTRANSIT 0xa0 /* lifetime expired during transit */
#define TTL_EXPREASS 0xa1 /* lifetime expired during reassembly */
/* pdu discarded */
#define DISC_UNSUPPOPT 0xb0 /* unsupported option not specified? */
#define DISC_UNSUPPVERS 0xb1 /* unsupported protocol version */
#define DISC_UNSUPPSECURE 0xb2 /* unsupported security option */
#define DISC_UNSUPPSRCRT 0xb3 /* unsupported src rt option */
#define DISC_UNSUPPRECRT 0xb4 /* unsupported rec rt option */
/* reassembly */
#define REASS_INTERFERE 0xc0 /* reassembly interference */
#define CLNP_ERRORS 22
#ifdef CLNP_ER_CODES
u_char clnp_er_codes[CLNP_ERRORS] = {
GEN_NOREAS, GEN_PROTOERR, GEN_BADCSUM, GEN_CONGEST,
GEN_HDRSYNTAX, GEN_SEGNEEDED, GEN_INCOMPLETE, GEN_DUPOPT,
ADDR_DESTUNREACH, ADDR_DESTUNKNOWN,
SRCRT_UNSPECERR, SRCRT_SYNTAX, SRCRT_UNKNOWNADDR, SRCRT_BADPATH,
TTL_EXPTRANSIT, TTL_EXPREASS,
DISC_UNSUPPOPT, DISC_UNSUPPVERS, DISC_UNSUPPSECURE,
DISC_UNSUPPSRCRT, DISC_UNSUPPRECRT, REASS_INTERFERE
};
#endif
#ifdef TROLL
#define TR_DUPEND 0x01 /* duplicate end of fragment */
#define TR_DUPPKT 0x02 /* duplicate entire packet */
#define TR_DROPPKT 0x04 /* drop packet on output */
#define TR_TRIM 0x08 /* trim bytes from packet */
#define TR_CHANGE 0x10 /* change bytes in packet */
#define TR_MTU 0x20 /* delta to change device mtu */
#define TR_CHUCK 0x40 /* drop packet in rclnp_input */
#define TR_BLAST 0x80 /* force rclnp_output to blast many
* packet */
#define TR_RAWLOOP 0x100 /* make if_loop call clnpintr
* directly */
struct troll {
int tr_ops; /* operations to perform */
float tr_dup_size; /* % to duplicate */
float tr_dup_freq; /* frequency to duplicate packets */
float tr_drop_freq; /* frequence to drop packets */
int tr_mtu_adj; /* delta to adjust if mtu */
int tr_blast_cnt; /* # of pkts to blast out */
};
#define SN_OUTPUT(clcp, m)\
troll_output(clcp->clc_ifp, m, clcp->clc_firsthop, clcp->clc_rt)
#define SN_MTU(ifp, rt) (((rt && rt->rt_rmx.rmx_mtu) ?\
rt->rt_rmx.rmx_mtu : clnp_badmtu(ifp, rt, __LINE__, __FILE__))\
- trollctl.tr_mtu_adj)
#ifdef _KERNEL
extern float troll_random;
#endif
#else /* NO TROLL */
#define SN_OUTPUT(clcp, m)\
(*clcp->clc_ifp->if_output)(clcp->clc_ifp, m, clcp->clc_firsthop, \
clcp->clc_rt)
#define SN_MTU(ifp, rt) (((rt && rt->rt_rmx.rmx_mtu) ?\
rt->rt_rmx.rmx_mtu : clnp_badmtu(ifp, rt, __LINE__, __FILE__)))
#endif /* TROLL */
/*
* Macro to remove an address from a clnp header
*/
#define CLNP_EXTRACT_ADDR(isoa, hoff, hend)\
{\
isoa.isoa_len = (u_char)*hoff;\
if ((((++hoff) + isoa.isoa_len) > hend) ||\
(isoa.isoa_len > 20) || (isoa.isoa_len == 0)) {\
hoff = (caddr_t)0;\
} else {\
(void) bcopy(hoff, (caddr_t)isoa.isoa_genaddr, \
isoa.isoa_len);\
hoff += isoa.isoa_len;\
}\
}
/*
* Macro to insert an address into a clnp header
*/
#define CLNP_INSERT_ADDR(hoff, isoa)\
*hoff++ = (isoa).isoa_len;\
(void) bcopy((caddr_t)((isoa).isoa_genaddr), hoff, (isoa).isoa_len);\
hoff += (isoa).isoa_len;
/*
* Clnp hdr cache. Whenever a clnp packet is sent, a copy of the
* header is made and kept in this cache. In addition to a copy of
* the cached clnp hdr, the cache contains
* information necessary to determine whether the new packet
* to send requires a new header to be built.
*/
struct clnp_cache {
/* these fields are used to check the validity of the cache */
struct iso_addr clc_dst;/* destination of packet */
struct mbuf *clc_options; /* ptr to options mbuf */
int clc_flags; /* flags passed to clnp_output */
/* these fields are state that clnp_output requires to finish the pkt */
int clc_segoff; /* offset of seg part of header */
struct rtentry *clc_rt; /* ptr to rtentry (points into the route
* structure) */
struct sockaddr *clc_firsthop; /* first hop of packet */
struct ifnet *clc_ifp;/* ptr to interface structure */
struct iso_ifaddr
*clc_ifa;/* ptr to interface address */
struct mbuf *clc_hdr;/* cached pkt hdr (finally)! */
};
#ifdef _KERNEL
struct iso_addr;
struct sockaddr_iso;
struct mbuf;
struct clnp_segment;
struct sockaddr;
struct rt_entry;
struct clnp_fragl;
struct clnp_optidx;
struct isopcb;
struct snpa_hdr;
struct iso_ifaddr;
struct route_iso;
/* clnp_debug.c */
char *clnp_hexp __P((char *, int, char *));
char *clnp_iso_addrp __P((struct iso_addr *));
char *clnp_saddr_isop __P((struct sockaddr_iso *));
/* clnp_er.c */
void clnp_er_input __P((struct mbuf *, struct iso_addr *, u_int));
void clnp_discard __P((struct mbuf *, u_int));
void clnp_emit_er __P((struct mbuf *, u_int));
int clnp_er_index __P((u_int));
int clnp_fragment __P((struct ifnet *, struct mbuf *, struct sockaddr *,
int, int, int, struct rtentry *));
struct mbuf *clnp_reass __P((struct mbuf *, struct iso_addr *,
struct iso_addr *, struct clnp_segment *));
int clnp_newpkt __P((struct mbuf *, struct iso_addr *, struct iso_addr *,
struct clnp_segment *));
void clnp_insert_frag __P((struct clnp_fragl *, struct mbuf *,
struct clnp_segment *));
struct mbuf *clnp_comp_pdu __P((struct clnp_fragl *));
#ifdef TROLL
float troll_random __P((void));
int troll_output __P((struct ifnet *, struct mbuf *, struct sockaddr *,
struct rtentry *));
#endif
/* clnp_input.c */
void clnp_init __P((void));
void clnlintr __P((void));
void clnp_input __P((struct mbuf *, ...));
/* clnp_options.c */
void clnp_update_srcrt __P((struct mbuf *, struct clnp_optidx *));
void clnp_dooptions __P((struct mbuf *, struct clnp_optidx *, struct ifnet *,
struct iso_addr *));
int clnp_set_opts __P((struct mbuf **, struct mbuf **));
int clnp_opt_sanity __P((struct mbuf *, caddr_t, int, struct clnp_optidx *));
/* clnp_output.c */
int clnp_output __P((struct mbuf *, ...));
void clnp_ctloutput __P((void));
/* clnp_raw.c */
void rclnp_input __P((struct mbuf *, ...));
int rclnp_output __P((struct mbuf *, ...));
int rclnp_ctloutput __P((int, struct socket *, int, int, struct mbuf **));
int clnp_usrreq __P((struct socket *, int, struct mbuf *, struct mbuf *,
struct mbuf *, struct proc *));
/* clnp_subr.c */
struct mbuf *clnp_data_ck __P((struct mbuf *, int));
caddr_t clnp_extract_addr __P((caddr_t, int, struct iso_addr *,
struct iso_addr *));
int clnp_ours __P((struct iso_addr *));
void clnp_forward __P((struct mbuf *, int, struct iso_addr *,
struct clnp_optidx *, int, struct snpa_hdr *));
caddr_t clnp_insert_addr __P((caddr_t, struct iso_addr *, struct iso_addr *));
int clnp_route __P((struct iso_addr *, struct route_iso *, int,
struct sockaddr **, struct iso_ifaddr **));
int clnp_srcroute __P((struct mbuf *, struct clnp_optidx *, struct route_iso *,
struct sockaddr **, struct iso_ifaddr **,
struct iso_addr *));
int clnp_echoreply __P((struct mbuf *, int, struct sockaddr_iso *,
struct sockaddr_iso *, struct clnp_optidx *));
int clnp_badmtu __P((struct ifnet *, struct rtentry *, int, char *));
void clnp_ypocb __P((caddr_t, caddr_t, u_int));
/* clnp_timer.c */
struct clnp_fragl *clnp_freefrags __P((struct clnp_fragl *));
void clnp_slowtimo __P((void));
void clnp_drain __P((void));
#ifdef TROLL
struct troll trollctl;
#endif /* TROLL */
#endif /* _KERNEL */

146
isisd/include-netbsd/esis.h Normal file
View File

@ -0,0 +1,146 @@
/* $NetBSD: esis.h,v 1.11 1997/11/03 15:01:19 is Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)esis.h 8.1 (Berkeley) 6/10/93
*/
/***********************************************************
Copyright IBM Corporation 1987
All Rights Reserved
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the name of IBM not be
used in advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
SOFTWARE.
******************************************************************/
/*
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
*/
#include <machine/endian.h>
#define SNPAC_AGE 60 /* seconds */
#define ESIS_CONFIG 60 /* seconds */
#define ESIS_HT (ESIS_CONFIG * 2)
/*
* Fixed part of an ESIS header
*/
struct esis_fixed {
u_char esis_proto_id; /* network layer protocol identifier */
u_char esis_hdr_len; /* length indicator (octets) */
u_char esis_vers; /* version/protocol identifier
* extension */
u_char esis_res1; /* reserved */
u_char esis_type; /* type code */
/* technically, type should be &='d 0x1f */
#define ESIS_ESH 0x02 /* End System Hello */
#define ESIS_ISH 0x04 /* Intermediate System Hello */
#define ESIS_RD 0x06 /* Redirect */
u_char esis_ht_msb; /* holding time (seconds) high byte */
u_char esis_ht_lsb; /* holding time (seconds) low byte */
u_char esis_cksum_msb; /* checksum high byte */
u_char esis_cksum_lsb; /* checksum low byte */
} __attribute__((packed));
/*
* Values for ESIS datagram options
*/
#define ESISOVAL_NETMASK 0xe1 /* address mask option, RD PDU only */
#define ESISOVAL_SNPAMASK 0xe2 /* snpa mask option, RD PDU only */
#define ESISOVAL_ESCT 0xc6 /* end system conf. timer, ISH PDU
* only */
#define ESIS_CKSUM_OFF 0x07
#define ESIS_CKSUM_REQUIRED(pdu)\
((pdu->esis_cksum_msb != 0) || (pdu->esis_cksum_lsb != 0))
#define ESIS_VERSION 1
struct esis_stat {
u_short es_nomem; /* insufficient memory to send hello */
u_short es_badcsum; /* incorrect checksum */
u_short es_badvers; /* incorrect version number */
u_short es_badtype; /* unknown pdu type field */
u_short es_toosmall; /* packet too small */
u_short es_eshsent; /* ESH sent */
u_short es_eshrcvd; /* ESH rcvd */
u_short es_ishsent; /* ISH sent */
u_short es_ishrcvd; /* ISH rcvd */
u_short es_rdsent; /* RD sent */
u_short es_rdrcvd; /* RD rcvd */
};
#ifdef _KERNEL
struct esis_stat esis_stat;
struct socket;
struct mbuf;
struct snpa_hdr;
struct clnp_optidx;
struct iso_addr;
struct rtentry;
struct sockaddr_dl;
void esis_init __P((void));
int esis_usrreq __P((struct socket *, int, struct mbuf *, struct mbuf *,
struct mbuf *, struct proc *));
void esis_input __P((struct mbuf *, ...));
void esis_rdoutput __P((struct snpa_hdr *, struct mbuf *, struct clnp_optidx *,
struct iso_addr *, struct rtentry *));
int esis_insert_addr __P((caddr_t *, int *, struct iso_addr *, struct mbuf *,
int));
void esis_eshinput __P((struct mbuf *, struct snpa_hdr *));
void esis_ishinput __P((struct mbuf *, struct snpa_hdr *));
void esis_rdinput __P((struct mbuf *, struct snpa_hdr *));
void esis_config __P((void *));
void esis_shoutput __P((struct ifnet *, int, int, caddr_t, int,
struct iso_addr *));
void isis_input __P((struct mbuf *, ...));
int isis_output __P((struct mbuf *, ...));
void *esis_ctlinput __P((int, struct sockaddr *, void *));
#endif /* _KERNEL */

208
isisd/include-netbsd/iso.h Normal file
View File

@ -0,0 +1,208 @@
/* $NetBSD: iso.h,v 1.13 2000/07/28 12:13:34 kleink Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)iso.h 8.1 (Berkeley) 6/10/93
*/
/***********************************************************
Copyright IBM Corporation 1987
All Rights Reserved
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the name of IBM not be
used in advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
SOFTWARE.
******************************************************************/
/*
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
*/
#ifndef _NETISO_ISO_H_
#define _NETISO_ISO_H_
#if 0
#include <sys/ansi.h>
#endif
#if 0
#ifndef sa_family_t
typedef __sa_family_t sa_family_t;
#define sa_family_t __sa_family_t
#endif
#endif
/*
* Return true if this is a multicast address
* This assumes that the bit transmission is lsb first. This
* assumption is valid for 802.3 but not 802.5. There is a
* kludge to get around this for 802.5 -- see if_lan.c
* where subnetwork header is setup.
*/
#define IS_MULTICAST(snpa)\
((snpa)[0] & 0x01)
/*
* Protocols
*/
#define ISOPROTO_TCP 6 /* IETF experiment */
#define ISOPROTO_UDP 17 /* IETF experiment */
#define ISOPROTO_TP0 25 /* connection oriented transport protocol */
#define ISOPROTO_TP1 26 /* not implemented */
#define ISOPROTO_TP2 27 /* not implemented */
#define ISOPROTO_TP3 28 /* not implemented */
#define ISOPROTO_TP4 29 /* connection oriented transport protocol */
#define ISOPROTO_TP ISOPROTO_TP4 /* tp-4 with negotiation */
#define ISOPROTO_CLTP 30 /* connectionless transport (not yet impl.) */
#define ISOPROTO_CLNP 31 /* connectionless internetworking protocol */
#define ISOPROTO_X25 32 /* cons */
#define ISOPROTO_INACT_NL 33 /* inactive network layer! */
#define ISOPROTO_ESIS 34 /* ES-IS protocol */
#define ISOPROTO_INTRAISIS 35 /* IS-IS protocol */
#define ISOPROTO_IDRP 36 /* Interdomain Routing Protocol */
#define ISOPROTO_RAW 255 /* raw clnp */
#define ISOPROTO_MAX 256
#define ISO_PORT_RESERVED 1024
#define ISO_PORT_USERRESERVED 5000
/*
* Port/socket numbers: standard network functions
* NOT PRESENTLY USED
*/
#define ISO_PORT_MAINT 501
#define ISO_PORT_ECHO 507
#define ISO_PORT_DISCARD 509
#define ISO_PORT_SYSTAT 511
#define ISO_PORT_NETSTAT 515
/*
* Port/socket numbers: non-standard application functions
*/
#define ISO_PORT_LOGIN 513
/*
* Port/socket numbers: public use
*/
#define ISO_PORT_PUBLIC 1024 /* high bit set --> public */
/*
* Network layer protocol identifiers
*/
#define ISO8473_CLNP 0x81
#define ISO9542_ESIS 0x82
#define ISO9542X25_ESIS 0x8a
#define ISO10589_ISIS 0x83
#define ISO8878A_CONS 0x84
#define ISO10747_IDRP 0x85
#ifndef IN_CLASSA_NET
#include <netinet/in.h>
#endif /* IN_CLASSA_NET */
/*
* The following looks like a sockaddr to facilitate using tree lookup
* routines
*/
struct iso_addr {
u_char isoa_len; /* length (in bytes) */
char isoa_genaddr[20]; /* general opaque address */
};
struct sockaddr_iso {
u_char siso_len; /* length */
sa_family_t siso_family; /* family */
u_char siso_plen; /* presentation selector length */
u_char siso_slen; /* session selector length */
u_char siso_tlen; /* transport selector length */
struct iso_addr siso_addr; /* network address */
u_char siso_pad[6]; /* space for gosip v2 sels */
/* makes struct 32 bytes long */
};
#define siso_nlen siso_addr.isoa_len
#define siso_data siso_addr.isoa_genaddr
#define TSEL(s) ((caddr_t)((s)->siso_data + (s)->siso_nlen))
#define SAME_ISOADDR(a, b) \
(bcmp((a)->siso_data, (b)->siso_data, (unsigned)(a)->siso_nlen)==0)
#define SAME_ISOIFADDR(a, b) (bcmp((a)->siso_data, (b)->siso_data, \
(unsigned)((b)->siso_nlen - (b)->siso_tlen)) == 0)
/*
* The following are specific values for siso->siso_data[0],
* otherwise known as the AFI:
*/
#define AFI_37 0x37 /* bcd of "37" */
#define AFI_OSINET 0x47 /* bcd of "47" */
#define AFI_RFC986 0x47 /* bcd of "47" */
#define AFI_SNA 0x00 /* SubNetwork Address; invalid really... */
#ifdef _KERNEL
extern struct domain isodomain;
extern struct protosw isosw[];
#define satosiso(sa) ((struct sockaddr_iso *)(sa))
#define sisotosa(siso) ((struct sockaddr *)(siso))
#else
/* user utilities definitions from the iso library */
#include <sys/cdefs.h>
__BEGIN_DECLS
struct iso_addr *iso_addr __P((const char *));
char *iso_ntoa __P((const struct iso_addr *));
/* THESE DON'T EXIST YET */
struct hostent *iso_gethostbyname __P((const char *));
struct hostent *iso_gethostbyaddr __P((const char *, int, int));
__END_DECLS
#endif /* _KERNEL */
#endif /* _NETISO_ISO_H_ */

508
isisd/isis_adjacency.c Normal file
View File

@ -0,0 +1,508 @@
/*
* IS-IS Rout(e)ing protocol - isis_adjacency.c
* handling of IS-IS adjacencies
*
* Copyright (C) 2001,2002 Sampo Saaristo
* Tampere University of Technology
* Institute of Communications Engineering
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public Licenseas published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <stdio.h>
#include <limits.h>
#include <string.h>
#include <zebra.h>
#include <net/ethernet.h>
#include "log.h"
#include "memory.h"
#include "hash.h"
#include "vty.h"
#include "linklist.h"
#include "thread.h"
#include "if.h"
#include "stream.h"
#include "isisd/dict.h"
#include "isisd/include-netbsd/iso.h"
#include "isisd/isis_constants.h"
#include "isisd/isis_common.h"
#include "isisd/isisd.h"
#include "isisd/isis_circuit.h"
#include "isisd/isis_adjacency.h"
#include "isisd/isis_misc.h"
#include "isisd/isis_dr.h"
#include "isisd/isis_dynhn.h"
#include "isisd/isis_pdu.h"
extern struct isis *isis;
struct isis_adjacency *
adj_alloc (u_char *id)
{
struct isis_adjacency *adj;
adj = XMALLOC (MTYPE_ISIS_ADJACENCY, sizeof (struct isis_adjacency));
memset (adj, 0, sizeof (struct isis_adjacency));
memcpy (adj->sysid, id, ISIS_SYS_ID_LEN);
return adj;
}
struct isis_adjacency *
isis_new_adj (u_char *id, u_char *snpa, int level,
struct isis_circuit *circuit)
{
struct isis_adjacency *adj;
int i;
adj = adj_alloc (id); /* P2P kludge */
if (adj == NULL){
zlog_err ("Out of memory!");
return NULL;
}
memcpy (adj->snpa, snpa, 6);
adj->circuit = circuit;
adj->level = level;
adj->flaps = 0;
adj->last_flap = time (NULL);
if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
listnode_add (circuit->u.bc.adjdb[level-1], adj);
adj->dischanges[level - 1] = 0;
for (i = 0; i < DIS_RECORDS; i++) /* clear N DIS state change records */
{
adj->dis_record[(i * ISIS_LEVELS) + level - 1].dis
= ISIS_UNKNOWN_DIS;
adj->dis_record[(i * ISIS_LEVELS) + level - 1].last_dis_change
= time (NULL);
}
}
return adj;
}
struct isis_adjacency *
isis_adj_lookup (u_char *sysid, struct list *adjdb)
{
struct isis_adjacency *adj;
struct listnode *node;
for (node = listhead (adjdb); node; nextnode (node)) {
adj = getdata (node);
if (memcmp (adj->sysid, sysid, ISIS_SYS_ID_LEN) == 0)
return adj;
}
return NULL;
}
struct isis_adjacency *
isis_adj_lookup_snpa (u_char *ssnpa, struct list *adjdb)
{
struct listnode *node;
struct isis_adjacency *adj;
for (node = listhead (adjdb); node; nextnode (node)) {
adj = getdata (node);
if (memcmp (adj->snpa, ssnpa, ETH_ALEN) == 0)
return adj;
}
return NULL;
}
/*
* When we recieve a NULL list, we will know its p2p
*/
void
isis_delete_adj (struct isis_adjacency *adj, struct list *adjdb)
{
struct isis_adjacency *adj2;
struct listnode *node;
if (adjdb) {
for (node = listhead (adjdb); node; nextnode (node)) {
adj2 = getdata (node);
if (adj2 == adj)
break;
}
listnode_delete (adjdb, node);
}
if (adj->ipv4_addrs)
list_delete (adj->ipv4_addrs);
#ifdef HAVE_IPV6
if (adj->ipv6_addrs)
list_delete (adj->ipv6_addrs);
#endif
if (adj) {
XFREE (MTYPE_ISIS_ADJACENCY,adj);
} else {
zlog_info ("tried to delete a non-existent adjacency");
}
return;
}
void
isis_adj_state_change (struct isis_adjacency *adj, enum isis_adj_state state,
char *reason)
{
int old_state;
int level = adj->level;
struct isis_circuit *circuit;
old_state = adj->adj_state;
adj->adj_state = state;
circuit = adj->circuit;
if (isis->debugs & DEBUG_ADJ_PACKETS) {
zlog_info ("ISIS-Adj (%s): Adjacency state change %d->%d: %s",
circuit->area->area_tag,
old_state,
state,
reason ? reason : "unspecified");
}
if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
if (state == ISIS_ADJ_UP)
circuit->upadjcount[level-1]++;
if (state == ISIS_ADJ_DOWN) {
isis_delete_adj (adj, adj->circuit->u.bc.adjdb[level - 1]);
circuit->upadjcount[level-1]--;
}
list_delete_all_node (circuit->u.bc.lan_neighs[level - 1]);
isis_adj_build_neigh_list (circuit->u.bc.adjdb[level - 1],
circuit->u.bc.lan_neighs[level - 1]);
} else if (state == ISIS_ADJ_UP) { /* p2p interface */
if (adj->sys_type == ISIS_SYSTYPE_UNKNOWN)
send_hello (circuit, 1);
/* update counter & timers for debugging purposes */
adj->last_flap = time(NULL);
adj->flaps++;
/* 7.3.17 - going up on P2P -> send CSNP */
/* FIXME: yup, I know its wrong... but i will do it! (for now) */
send_csnp (circuit,1);
send_csnp (circuit,2);
} else if (state == ISIS_ADJ_DOWN) { /* p2p interface */
adj->circuit->u.p2p.neighbor = NULL;
isis_delete_adj (adj, NULL);
}
return;
}
void
isis_adj_print (struct isis_adjacency *adj)
{
struct isis_dynhn *dyn;
struct listnode *node;
struct in_addr *ipv4_addr;
#ifdef HAVE_IPV6
struct in6_addr *ipv6_addr;
u_char ip6 [INET6_ADDRSTRLEN];
#endif /* HAVE_IPV6 */
if(!adj)
return;
dyn = dynhn_find_by_id (adj->sysid);
if (dyn)
zlog_info ("%s", dyn->name.name);
zlog_info ("SystemId %20s SNPA %s, level %d\nHolding Time %d",
adj->sysid ? sysid_print (adj->sysid) : "unknown" ,
snpa_print (adj->snpa),
adj->level, adj->hold_time);
if (adj->ipv4_addrs && listcount (adj->ipv4_addrs) > 0) {
zlog_info ("IPv4 Addresses:");
for (node = listhead (adj->ipv4_addrs); node; nextnode (node)) {
ipv4_addr = getdata (node);
zlog_info ("%s", inet_ntoa(*ipv4_addr));
}
}
#ifdef HAVE_IPV6
if (adj->ipv6_addrs && listcount (adj->ipv6_addrs) > 0) {
zlog_info ("IPv6 Addresses:");
for (node = listhead (adj->ipv6_addrs); node; nextnode (node)) {
ipv6_addr = getdata (node);
inet_ntop (AF_INET6, ipv6_addr, ip6, INET6_ADDRSTRLEN);
zlog_info ("%s", ip6);
}
}
#endif /* HAVE_IPV6 */
zlog_info ("Speaks: %s", nlpid2string(&adj->nlpids));
return;
}
int
isis_adj_expire (struct thread *thread)
{
struct isis_adjacency *adj;
int level;
/*
* Get the adjacency
*/
adj = THREAD_ARG (thread);
assert (adj);
level = adj->level;
/* trigger the adj expire event */
isis_adj_state_change (adj, ISIS_ADJ_DOWN, "holding time expired");
return 0;
}
const char *
adj_state2string (int state)
{
switch (state) {
case ISIS_ADJ_INITIALIZING:
return "Initializing";
case ISIS_ADJ_UP:
return "Up";
case ISIS_ADJ_DOWN:
return "Down";
default:
return "Unknown";
}
return NULL; /* not reached */
}
/*
* show clns/isis neighbor (detail)
*/
void
isis_adj_print_vty2 (struct isis_adjacency *adj, struct vty *vty, char detail)
{
#ifdef HAVE_IPV6
struct in6_addr *ipv6_addr;
u_char ip6 [INET6_ADDRSTRLEN];
#endif /* HAVE_IPV6 */
struct in_addr *ip_addr;
time_t now;
struct isis_dynhn *dyn;
int level;
struct listnode *node;
dyn = dynhn_find_by_id (adj->sysid);
if (dyn)
vty_out (vty, " %-20s", dyn->name.name);
else if (adj->sysid){
vty_out (vty, " %-20s", sysid_print (adj->sysid));
} else {
vty_out (vty, " unknown ");
}
if (detail == ISIS_UI_LEVEL_BRIEF) {
if (adj->circuit)
vty_out (vty, "%-12s",adj->circuit->interface->name);
else
vty_out (vty, "NULL circuit!");
vty_out (vty, "%-3u", adj->level); /* level */
vty_out (vty, "%-13s", adj_state2string (adj->adj_state));
now = time (NULL);
vty_out (vty, "%-9lu", adj->last_upd + adj->hold_time - now);
vty_out (vty, "%-10s", snpa_print (adj->snpa));
vty_out (vty, "%s", VTY_NEWLINE);
}
if (detail == ISIS_UI_LEVEL_DETAIL) {
level = adj->level;
if (adj->circuit)
vty_out (vty, "%s Interface: %s",
VTY_NEWLINE,
adj->circuit->interface->name); /* interface name */
else
vty_out (vty, "NULL circuit!%s", VTY_NEWLINE);
vty_out (vty, ", Level: %u", adj->level); /* level */
vty_out (vty, ", State: %s", adj_state2string (adj->adj_state));
now = time (NULL);
vty_out (vty, ", Expires in %s",
time2string (adj->last_upd + adj->hold_time - now));
vty_out (vty, "%s Adjacency flaps: %u",
VTY_NEWLINE,
adj->flaps);
vty_out (vty, ", Last: %s ago", time2string(now - adj->last_flap));
vty_out (vty, "%s Circuit type: %s",
VTY_NEWLINE,
circuit_t2string(adj->circuit_t));
vty_out (vty, ", Speaks: %s", nlpid2string(&adj->nlpids));
vty_out (vty, "%s SNPA: %s",
VTY_NEWLINE,
snpa_print (adj->snpa));
dyn = dynhn_find_by_id (adj->lanid);
if (dyn)
vty_out (vty, ", LAN id: %s.%02x",
dyn->name.name,
adj->lanid[ISIS_SYS_ID_LEN]);
else
vty_out (vty, ", LAN id: %s.%02x",
sysid_print (adj->lanid),
adj->lanid[ISIS_SYS_ID_LEN]);
vty_out (vty, "%s Priority: %u",
VTY_NEWLINE,
adj->prio[adj->level-1]);
vty_out (vty, ", %s, DIS flaps: %u, Last: %s ago%s",
isis_disflag2string(adj->dis_record[ISIS_LEVELS+level-1].dis),
adj->dischanges[level-1],
time2string (now -
(adj->dis_record[ISIS_LEVELS + level - 1].last_dis_change)),
VTY_NEWLINE);
if (adj->ipv4_addrs && listcount (adj->ipv4_addrs) > 0) {
vty_out (vty, " IPv4 Addresses:%s", VTY_NEWLINE);
for (node = listhead (adj->ipv4_addrs);node; nextnode (node)) {
ip_addr = getdata (node);
vty_out (vty, " %s%s", inet_ntoa(*ip_addr), VTY_NEWLINE);
}
}
#ifdef HAVE_IPV6
if (adj->ipv6_addrs && listcount (adj->ipv6_addrs) > 0) {
vty_out (vty, " IPv6 Addresses:%s", VTY_NEWLINE);
for (node = listhead (adj->ipv6_addrs); node; nextnode (node)) {
ipv6_addr = getdata (node);
inet_ntop (AF_INET6, ipv6_addr, ip6, INET6_ADDRSTRLEN);
vty_out (vty, " %s%s", ip6, VTY_NEWLINE);
}
}
#endif /* HAVE_IPV6 */
vty_out (vty, "%s", VTY_NEWLINE);
}
return;
}
void
isis_adj_print_vty (struct isis_adjacency *adj, struct vty *vty) {
isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_BRIEF);
}
void
isis_adj_print_vty_detail (struct isis_adjacency *adj, struct vty *vty) {
isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_DETAIL);
}
void
isis_adj_print_vty_extensive (struct isis_adjacency *adj, struct vty *vty) {
isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_EXTENSIVE);
}
void
isis_adj_p2p_print_vty (struct isis_adjacency *adj, struct vty *vty)
{
isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_BRIEF);
}
void
isis_adj_p2p_print_vty_detail (struct isis_adjacency *adj, struct vty *vty)
{
isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_DETAIL);
}
void
isis_adj_p2p_print_vty_extensive (struct isis_adjacency *adj, struct vty *vty)
{
isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_EXTENSIVE);
}
void
isis_adjdb_iterate (struct list *adjdb, void (*func)(struct isis_adjacency*,
void *), void *arg)
{
struct listnode *node;
struct isis_adjacency *adj;
for (node = listhead (adjdb); node; nextnode (node)) {
adj = getdata (node);
(*func)(adj, arg);
}
}
void
isis_adj_build_neigh_list (struct list *adjdb, struct list *list)
{
struct isis_adjacency *adj;
struct listnode *node;
if (!list) {
zlog_warn ("isis_adj_build_neigh_list(): NULL list");
return;
}
for (node = listhead (adjdb); node; nextnode (node)) {
adj = getdata (node);
if (!adj) {
zlog_warn ("isis_adj_build_neigh_list(): NULL adj");
return;
}
if ((adj->adj_state == ISIS_ADJ_UP ||
adj->adj_state == ISIS_ADJ_INITIALIZING))
listnode_add (list, adj->snpa);
}
return;
}
void
isis_adj_build_up_list (struct list *adjdb, struct list *list)
{
struct isis_adjacency *adj;
struct listnode *node;
if (!list) {
zlog_warn ("isis_adj_build_up_list(): NULL list");
return;
}
for (node = listhead (adjdb); node; nextnode (node)) {
adj = getdata (node);
if (!adj) {
zlog_warn ("isis_adj_build_up_list(): NULL adj");
return;
}
if (adj->adj_state == ISIS_ADJ_UP)
listnode_add (list, adj);
}
return;
}

126
isisd/isis_adjacency.h Normal file
View File

@ -0,0 +1,126 @@
/*
* IS-IS Rout(e)ing protocol - isis_adjacency.h
* IS-IS adjacency handling
*
* Copyright (C) 2001,2002 Sampo Saaristo
* Tampere University of Technology
* Institute of Communications Engineering
*
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public Licenseas published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _ZEBRA_ISIS_ADJACENCY_H
#define _ZEBRA_ISIS_ADJACENCY_H
enum isis_adj_usage
{
ISIS_ADJ_NONE,
ISIS_ADJ_LEVEL1,
ISIS_ADJ_LEVEL2,
ISIS_ADJ_LEVEL1AND2
};
enum isis_system_type
{
ISIS_SYSTYPE_UNKNOWN,
ISIS_SYSTYPE_ES,
ISIS_SYSTYPE_IS,
ISIS_SYSTYPE_L1_IS,
ISIS_SYSTYPE_L2_IS
};
enum isis_adj_state
{
ISIS_ADJ_INITIALIZING,
ISIS_ADJ_UP,
ISIS_ADJ_DOWN
};
/*
* we use the following codes to give an indication _why_
* a specific adjacency is up or down
*/
enum isis_adj_updown_reason
{
ISIS_ADJ_REASON_SEENSELF,
ISIS_ADJ_REASON_AREA_MISMATCH,
ISIS_ADJ_REASON_HOLDTIMER_EXPIRED,
ISIS_ADJ_REASON_AUTH_FAILED,
ISIS_ADJ_REASON_CHECKSUM_FAILED
};
#define DIS_RECORDS 8 /* keep the last 8 DIS state changes on record */
struct isis_dis_record {
int dis; /* is our neighbor the DIS ? */ time_t last_dis_change; /* timestamp for last dis change */
};
struct isis_adjacency{
u_char snpa[ETH_ALEN]; /* NeighbourSNPAAddress */
u_char sysid[ISIS_SYS_ID_LEN]; /* neighbourSystemIdentifier */
u_char lanid[ISIS_SYS_ID_LEN+1]; /* LAN id on bcast circuits */
int dischanges[ISIS_LEVELS]; /* how many DIS changes ?*/
/* an array of N levels for M records */
struct isis_dis_record dis_record[DIS_RECORDS * ISIS_LEVELS];
enum isis_adj_state adj_state; /* adjacencyState */
enum isis_adj_usage adj_usage; /* adjacencyUsage */
struct list *area_addrs; /* areaAdressesOfNeighbour */
struct nlpids nlpids; /* protocols spoken ... */
struct list *ipv4_addrs;
#ifdef HAVE_IPV6
struct list *ipv6_addrs;
#endif /* HAVE_IPV6 */
u_char prio[ISIS_LEVELS]; /* priorityOfNeighbour for DIS*/
int circuit_t; /* from hello PDU hdr */
int level; /* level (1 or 2) */
enum isis_system_type sys_type; /* neighbourSystemType */
u_int16_t hold_time; /* entryRemainingTime */
u_int32_t last_upd;
u_int32_t last_flap; /* last time the adj flapped */
int flaps; /* number of adjacency flaps */
struct thread *t_expire; /* expire after hold_time */
struct isis_circuit *circuit; /* back pointer */
};
struct isis_adjacency *isis_adj_lookup (u_char *sysid, struct list *adjdb);
struct isis_adjacency *isis_adj_lookup_snpa (u_char *ssnpa,
struct list *adjdb);
struct isis_adjacency *isis_new_adj (u_char *id, u_char *snpa, int level,
struct isis_circuit *circuit);
void isis_delete_adj (struct isis_adjacency *adj, struct list *adjdb);
void isis_adj_state_change (struct isis_adjacency *adj,
enum isis_adj_state state, char *reason);
void isis_adj_print (struct isis_adjacency *adj);
int isis_adj_expire (struct thread *thread);
void isis_adj_print_vty (struct isis_adjacency *adj, struct vty *vty);
void isis_adj_print_vty_detail (struct isis_adjacency *adj, struct vty *vty);
void isis_adj_print_vty_extensive (struct isis_adjacency *adj,
struct vty *vty);
void isis_adj_p2p_print_vty (struct isis_adjacency *adj, struct vty *vty);
void isis_adj_p2p_print_vty_detail (struct isis_adjacency *adj,
struct vty *vty);
void isis_adj_p2p_print_vty_extensive (struct isis_adjacency *adj,
struct vty *vty);
void isis_adj_build_neigh_list (struct list *adjdb, struct list *list);
void isis_adj_build_up_list (struct list *adjdb, struct list *list);
void isis_adjdb_iterate (struct list *adjdb,
void (*func)(struct isis_adjacency*,
void *), void *arg);
#endif /* ISIS_ADJACENCY_H */

2200
isisd/isis_circuit.c Normal file

File diff suppressed because it is too large Load Diff

158
isisd/isis_circuit.h Normal file
View File

@ -0,0 +1,158 @@
/*
* IS-IS Rout(e)ing protocol - isis_circuit.h
*
* Copyright (C) 2001,2002 Sampo Saaristo
* Tampere University of Technology
* Institute of Communications Engineering
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public Licenseas published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef ISIS_CIRCUIT_H
#define ISIS_CIRCUIT_H
#define CIRCUIT_MAX 255
struct password {
struct password *next;
int len;
u_char *pass;
};
struct metric {
u_char metric_default;
u_char metric_error;
u_char metric_expense;
u_char metric_delay;
};
struct isis_bcast_info {
u_char snpa [ETH_ALEN]; /* SNPA of this circuit */
char run_dr_elect[2]; /* Should we run dr election ? */
struct thread *t_run_dr[2]; /* DR election thread */
struct thread *t_send_lan_hello[2]; /* send LAN IIHs in this thread */
struct list *adjdb[2]; /* adjacency dbs */
struct list *lan_neighs[2]; /* list of lx neigh snpa */
char is_dr[2]; /* Are we level x DR ? */
u_char l1_desig_is[ISIS_SYS_ID_LEN + 1]; /* level-1 DR */
u_char l2_desig_is[ISIS_SYS_ID_LEN + 1]; /* level-2 DR */
struct thread *t_refresh_pseudo_lsp[2]; /* refresh pseudo-node LSPs */
int pad_hellos; /* add padding to Hello PDUs ? */
u_char priority[2]; /* l1/2 IS Priority */
};
struct isis_p2p_info {
struct isis_adjacency *neighbor;
struct thread *t_send_p2p_hello; /* send P2P IIHs in this thread */
};
struct isis_circuit {
int state;
u_char circuit_id; /* l1/l2 p2p/bcast CircuitID */
struct isis_area *area; /* back pointer to the area */
struct interface *interface; /* interface info from z */
int fd; /* IS-IS l1/2 socket */
struct nlpids nlpids;
/*
* Threads
*/
struct thread *t_read;
struct thread *t_send_csnp[2];
struct thread *t_send_psnp[2];
struct list *lsp_queue; /* LSPs to be txed (both levels) */
/* there is no real point in two streams, just for programming kicker */
int (* rx) (struct isis_circuit *circuit, u_char *ssnpa);
struct stream *rcv_stream; /* Stream for receiving */
int (* tx) (struct isis_circuit *circuit, int level);
struct stream *snd_stream; /* Stream for sending */
int idx; /* idx in S[RM|SN] flags */
#define CIRCUIT_T_BROADCAST 0
#define CIRCUIT_T_P2P 1
#define CIRCUIT_T_STATIC_IN 2
#define CIRCUIT_T_STATIC_OUT 3
#define CIRCUIT_T_DA 4
int circ_type; /* type of the physical interface */
union {
struct isis_bcast_info bc;
struct isis_p2p_info p2p;
} u;
char ext_domain; /* externalDomain (boolean) */
/*
* Configurables
*/
struct isis_passwd passwd; /* Circuit rx/tx password */
long lsp_interval;
int manual_l2_only; /* manualL2OnlyMode (boolean) */
int circuit_is_type; /* circuit is type == level of circuit
* diffrenciated from circuit type (media) */
u_int32_t hello_interval[2]; /* l1HelloInterval in msecs */
u_int16_t hello_multiplier[2]; /* l1HelloMultiplier */
u_int16_t csnp_interval[2]; /* level-1 csnp-interval in seconds */
u_int16_t psnp_interval[2]; /* level-1 psnp-interval in seconds */
struct metric metrics[2]; /* l1XxxMetric */
struct password *c_rx_passwds; /* circuitReceivePasswords */
struct password *c_tc_passwd; /* circuitTransmitPassword */
int ip_router; /* Route IP ? */
struct list *ip_addrs; /* our IP addresses */
#ifdef HAVE_IPV6
int ipv6_router; /* Route IPv6 ? */
struct list *ipv6_link; /* our link local IPv6 addresses */
struct list *ipv6_non_link; /* our non-link local IPv6 addresses */
#endif /* HAVE_IPV6 */
/*
* RFC 2973 IS-IS Mesh Groups
*/
#define MESH_INACTIVE 0
#define MESH_BLOCKED 1
#define MESH_SET 2
int mesh_enabled; /* meshGroupEnabled */
u_int16_t mesh_group; /* meshGroup */
u_int16_t upadjcount[2];
/*
* Counters as in 10589--11.2.5.9
*/
u_int32_t adj_state_changes; /* changesInAdjacencyState */
u_int32_t init_failures; /* intialisationFailures */
u_int32_t ctrl_pdus_rxed; /* controlPDUsReceived */
u_int32_t ctrl_pdus_txed; /* controlPDUsSent */
u_int32_t desig_changes[2]; /* lanLxDesignatedIntermediateSystemChanges*/
u_int32_t rej_adjacencies; /* rejectedAdjacencies */
};
void isis_circuit_init (void);
struct isis_circuit *isis_circuit_new (void);
struct isis_circuit *circuit_lookup_by_ifp (struct interface *ifp,
struct list *list);
struct isis_circuit *circuit_scan_by_ifp (struct interface *ifp);
void isis_circuit_del (struct isis_circuit *circuit);
void isis_circuit_configure (struct isis_circuit *circuit,
struct isis_area *area);
void isis_circuit_up (struct isis_circuit *circuit);
void isis_circuit_deconfigure (struct isis_circuit *circuit,
struct isis_area *area);
int isis_circuit_destroy (struct isis_circuit *circuit);
void isis_circuit_if_add (struct isis_circuit *circuit,
struct interface *ifp);
void isis_circuit_if_del (struct isis_circuit *circuit);
void circuit_update_nlpids (struct isis_circuit *circuit);
void isis_circuit_update_params (struct isis_circuit *circuit,
struct interface *ifp);
void isis_circuit_add_addr (struct isis_circuit *circuit,
struct connected *conn);
void isis_circuit_del_addr (struct isis_circuit *circuit,
struct connected *conn);
#endif /* _ZEBRA_ISIS_CIRCUIT_H */

65
isisd/isis_common.h Normal file
View File

@ -0,0 +1,65 @@
/*
* IS-IS Rout(e)ing protocol - isis_common.h
* some common data structures
*
* Copyright (C) 2001,2002 Sampo Saaristo
* Tampere University of Technology
* Institute of Communications Engineering
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public Licenseas published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
* Area Address
*/
struct area_addr {
u_char addr_len;
u_char area_addr[20];
};
struct isis_passwd {
u_char len;
#define ISIS_PASSWD_TYPE_UNUSED 0
#define ISIS_PASSWD_TYPE_CLEARTXT 1
#define ISIS_PASSWD_TYPE_PRIVATE 255
u_char type;
u_char passwd[255];
};
/*
* (Dynamic) Hostname
* one struct for cache list
* one struct for LSP TLV
*/
struct hostname {
u_char namelen;
u_char name[255];
};
/*
* Supported Protocol IDs
*/
struct nlpids {
u_char count;
u_char nlpids[4]; /* FIXME: enough ? */
};
/*
* Flags structure for SSN and SRM flags
*/
struct flags {
int maxindex;
struct list *free_idcs;
};

151
isisd/isis_constants.h Normal file
View File

@ -0,0 +1,151 @@
/*
* IS-IS Rout(e)ing protocol - isis_constants.h
*
* Copyright (C) 2001,2002 Sampo Saaristo
* Tampere University of Technology
* Institute of Communications Engineering
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public Licenseas published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef ISIS_CONSTANTS_H
#define ISIS_CONSTANTS_H
/*
* Architectural constant values from p. 35 of ISO/IEC 10589
*/
#define MAX_LINK_METRIC 63
#define MAX_PATH_METRIC 1023
#define ISO_SAP 0xFE
#define INTRADOMAIN_ROUTEING_SELECTOR 0
#define SEQUENCE_MODULUS 4294967296
#define RECEIVE_LSP_BUFFER_SIZE 1492
/*
* implementation specific jitter values
*/
#define IIH_JITTER 25 /* % */
#define MAX_AGE_JITTER 5 /* % */
#define MAX_LSP_GEN_JITTER 5 /* % */
#define CSNP_JITTER 10 /* % */
#define PSNP_JITTER 10 /* % */
#define RANDOM_SPREAD 100000.0
/*
* Default values
* ISO - 10589
* Section 7.3.21 - Parameters
*/
#define MAX_AGE 1200
#define ZERO_AGE_LIFETIME 60
#define MAX_LSP_GEN_INTERVAL 900
#define MIN_LSP_GEN_INTERVAL 30
#define MIN_LSP_TRANS_INTERVAL 5
#define ISIS_MIN_LSP_LIFETIME 380
#define CSNP_INTERVAL 10
#define PSNP_INTERVAL 2
#define ISIS_MAX_PATH_SPLITS 3
#define ISIS_LEVELS 2
#define ISIS_LEVEL1 1
#define ISIS_LEVEL2 2
#define HELLO_INTERVAL 1
#define HELLO_MINIMAL HELLO_INTERVAL
#define HELLO_MULTIPLIER 3
#define DEFAULT_PRIORITY 64
/* different vendors implement different values 5-10 on average */
#define LSP_GEN_INTERVAL_DEFAULT 10
#define LSP_INTERVAL 33 /* msecs */
#define DEFAULT_CIRCUIT_METRICS 10
#define METRICS_UNSUPPORTED 0x80
#define PERIODIC_SPF_INTERVAL 60 /* at the top of my head */
#define MINIMUM_SPF_INTERVAL 5 /* .. same here */
/*
* NLPID values
*/
#define NLPID_IP 204
#define NLPID_IPV6 142
/*
* Return values for functions
*/
#define ISIS_OK 0
#define ISIS_WARNING 1
#define ISIS_ERROR 2
#define ISIS_CRITICAL 3
/*
* IS-IS Circuit Types
*/
#define IS_LEVEL_1 1
#define IS_LEVEL_2 2
#define IS_LEVEL_1_AND_2 3
#define SNPA_ADDRSTRLEN 18
#define ISIS_SYS_ID_LEN 6
#define SYSID_STRLEN 24
/*
* LSP bit masks
*/
#define LSPBIT_P 0x80
#define LSPBIT_ATT 0x78
#define LSPBIT_OL 0x04
#define LSPBIT_IST 0x03
/*
* LSP bit masking macros
* taken from tcpdumps
* print-isoclns.c
*/
#define ISIS_MASK_LSP_OL_BIT(x) ((x)&0x4)
#define ISIS_MASK_LSP_IS_L1_BIT(x) ((x)&0x1)
#define ISIS_MASK_LSP_IS_L2_BIT(x) ((x)&0x2)
#define ISIS_MASK_LSP_PARTITION_BIT(x) ((x)&0x80)
#define ISIS_MASK_LSP_ATT_BITS(x) ((x)&0x78)
#define ISIS_MASK_LSP_ATT_ERROR_BIT(x) ((x)&0x40)
#define ISIS_MASK_LSP_ATT_EXPENSE_BIT(x) ((x)&0x20)
#define ISIS_MASK_LSP_ATT_DELAY_BIT(x) ((x)&0x10)
#define ISIS_MASK_LSP_ATT_DEFAULT_BIT(x) ((x)&0x8)
#define LLC_LEN 3
/* we need to be aware of the fact we are using ISO sized
* packets, using isomtu = mtu - LLC_LEN
*/
#define ISO_MTU(C) \
(C->circ_type==CIRCUIT_T_BROADCAST) ? \
(C->interface->mtu - LLC_LEN) : (C->interface->mtu)
#ifndef ETH_ALEN
#define ETH_ALEN 6
#endif
#endif /* ISIS_CONSTANTS_H */

186
isisd/isis_csm.c Normal file
View File

@ -0,0 +1,186 @@
/*
* IS-IS Rout(e)ing protocol - isis_csm.c
* IS-IS circuit state machine
* Copyright (C) 2001,2002 Sampo Saaristo
* Tampere University of Technology
* Institute of Communications Engineering
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public Licenseas published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <zebra.h>
#include <net/ethernet.h>
#include "log.h"
#include "memory.h"
#include "if.h"
#include "linklist.h"
#include "command.h"
#include "thread.h"
#include "hash.h"
#include "prefix.h"
#include "stream.h"
#include "isisd/dict.h"
#include "isisd/include-netbsd/iso.h"
#include "isisd/isis_constants.h"
#include "isisd/isis_common.h"
#include "isisd/isis_circuit.h"
#include "isisd/isis_tlv.h"
#include "isisd/isis_lsp.h"
#include "isisd/isis_pdu.h"
#include "isisd/isis_network.h"
#include "isisd/isis_misc.h"
#include "isisd/isis_constants.h"
#include "isisd/isis_adjacency.h"
#include "isisd/isis_dr.h"
#include "isisd/isis_flags.h"
#include "isisd/isisd.h"
#include "isisd/isis_csm.h"
#include "isisd/isis_events.h"
extern struct isis *isis;
static char *csm_statestr[] =
{
"C_STATE_NA",
"C_STATE_INIT",
"C_STATE_CONF",
"C_STATE_UP"
};
#define STATE2STR(S) csm_statestr[S]
static char *csm_eventstr[] =
{
"NO_STATE",
"ISIS_ENABLE",
"IF_UP_FROM_Z",
"ISIS_DISABLE",
"IF_DOWN_FROM_Z",
};
#define EVENT2STR(E) csm_eventstr[E]
struct isis_circuit*
isis_csm_state_change (int event, struct isis_circuit *circuit,
void *arg)
{
int old_state;
old_state = circuit ? circuit->state : C_STATE_NA;
zlog_info ("CSM_EVENT: %s", EVENT2STR(event));
switch (old_state) {
case C_STATE_NA:
if (circuit)
zlog_warn ("Non-null circuit while state C_STATE_NA");
switch (event) {
case ISIS_ENABLE:
circuit = isis_circuit_new ();
isis_circuit_configure (circuit, (struct isis_area *)arg);
circuit->state = C_STATE_CONF;
break;
case IF_UP_FROM_Z:
circuit = isis_circuit_new ();
isis_circuit_if_add (circuit, (struct interface *)arg);
listnode_add (isis->init_circ_list, circuit);
circuit->state = C_STATE_INIT;
break;
case ISIS_DISABLE:
zlog_warn ("circuit already disabled");
case IF_DOWN_FROM_Z:
zlog_warn ("circuit already disconnected");
break;
}
break;
case C_STATE_INIT:
switch (event) {
case ISIS_ENABLE:
isis_circuit_configure (circuit, (struct isis_area *)arg);
isis_circuit_up (circuit);
circuit->state = C_STATE_UP;
isis_event_circuit_state_change (circuit, 1);
listnode_delete (isis->init_circ_list, circuit);
break;
case IF_UP_FROM_Z:
zlog_warn ("circuit already connected");
break;
case ISIS_DISABLE:
zlog_warn ("circuit already disabled");
break;
case IF_DOWN_FROM_Z:
isis_circuit_if_del (circuit);
listnode_delete (isis->init_circ_list, circuit);
isis_circuit_del (circuit);
break;
}
break;
case C_STATE_CONF:
switch (event) {
case ISIS_ENABLE:
zlog_warn ("circuit already enabled");
break;
case IF_UP_FROM_Z:
isis_circuit_if_add (circuit, (struct interface *)arg);
isis_circuit_up (circuit);
circuit->state = C_STATE_UP;
isis_event_circuit_state_change (circuit, 1);
break;
case ISIS_DISABLE:
isis_circuit_deconfigure (circuit, (struct isis_area *)arg);
isis_circuit_del (circuit);
break;
case IF_DOWN_FROM_Z:
zlog_warn ("circuit already disconnected");
break;
}
break;
case C_STATE_UP:
switch (event) {
case ISIS_ENABLE:
zlog_warn ("circuit already configured");
break;
case IF_UP_FROM_Z:
zlog_warn ("circuit already connected");
break;
case ISIS_DISABLE:
isis_circuit_deconfigure (circuit, (struct isis_area *)arg);
listnode_add (isis->init_circ_list, circuit);
circuit->state = C_STATE_INIT;
isis_event_circuit_state_change (circuit, 0);
break;
case IF_DOWN_FROM_Z:
isis_circuit_if_del (circuit);
circuit->state = C_STATE_CONF;
isis_event_circuit_state_change (circuit, 0);
break;
}
break;
default:
zlog_warn ("Invalid circuit state %d", old_state);
}
zlog_info ("CSM_STATE_CHANGE: %s -> %s ", STATE2STR (old_state),
circuit ? STATE2STR (circuit->state) : STATE2STR (C_STATE_NA));
return circuit;
}

47
isisd/isis_csm.h Normal file
View File

@ -0,0 +1,47 @@
/*
* IS-IS Rout(e)ing protocol - isis_csm.h
* IS-IS circuit state machine
*
* Copyright (C) 2001,2002 Sampo Saaristo
* Tampere University of Technology
* Institute of Communications Engineering
*
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public Licenseas published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _ZEBRA_ISIS_CSM_H
#define _ZEBRA_ISIS_CSM_H
/*
* Circuit states
*/
#define C_STATE_NA 0
#define C_STATE_INIT 1 /* Connected to interface */
#define C_STATE_CONF 2 /* Configured for ISIS */
#define C_STATE_UP 3 /* CONN | CONF */
/*
* Circuit events
*/
#define ISIS_ENABLE 1
#define IF_UP_FROM_Z 2
#define ISIS_DISABLE 3
#define IF_DOWN_FROM_Z 4
struct isis_circuit *isis_csm_state_change (int event,
struct isis_circuit *circuit,
void *arg);
#endif /* _ZEBRA_ISIS_CSM_H */

373
isisd/isis_dr.c Normal file
View File

@ -0,0 +1,373 @@
/*
* IS-IS Rout(e)ing protocol - isis_dr.c
* IS-IS designated router related routines
*
* Copyright (C) 2001,2002 Sampo Saaristo
* Tampere University of Technology
* Institute of Communications Engineering
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public Licenseas published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <zebra.h>
#include <net/ethernet.h>
#include "log.h"
#include "hash.h"
#include "thread.h"
#include "linklist.h"
#include "vty.h"
#include "stream.h"
#include "if.h"
#include "isisd/dict.h"
#include "isisd/isis_constants.h"
#include "isisd/isis_common.h"
#include "isisd/isis_misc.h"
#include "isisd/isis_flags.h"
#include "isisd/isis_circuit.h"
#include "isisd/isisd.h"
#include "isisd/isis_adjacency.h"
#include "isisd/isis_constants.h"
#include "isisd/isis_pdu.h"
#include "isisd/isis_tlv.h"
#include "isisd/isis_lsp.h"
#include "isisd/isis_dr.h"
#include "isisd/isis_events.h"
extern struct isis *isis;
extern struct thread_master *master;
char *
isis_disflag2string (int disflag) {
switch (disflag) {
case ISIS_IS_NOT_DIS:
return "is not DIS";
case ISIS_IS_DIS:
return "is DIS";
case ISIS_WAS_DIS:
return "was DIS";
default:
return "unknown DIS state";
}
return NULL; /* not reached */
}
int
isis_run_dr_l1 (struct thread *thread)
{
struct isis_circuit *circuit;
circuit = THREAD_ARG (thread);
assert (circuit);
if (circuit->u.bc.run_dr_elect[0])
zlog_warn ("isis_run_dr(): run_dr_elect already set for l1");
circuit->u.bc.run_dr_elect[0] = 1;
return ISIS_OK;
}
int
isis_run_dr_l2 (struct thread *thread)
{
struct isis_circuit *circuit;
circuit = THREAD_ARG (thread);
assert (circuit);
if (circuit->u.bc.run_dr_elect[1])
zlog_warn ("isis_run_dr(): run_dr_elect already set for l2");
circuit->u.bc.run_dr_elect[1] = 1;
return ISIS_OK;
}
int
isis_check_dr_change (struct isis_adjacency *adj, int level)
{
int i;
if ( adj->dis_record[level-1].dis !=
adj->dis_record[(1*ISIS_LEVELS) + level - 1].dis)
/* was there a DIS state transition ? */
{
adj->dischanges[level-1]++;
/* ok rotate the history list through */
for (i = DIS_RECORDS - 1; i > 0; i--)
{
adj->dis_record[(i * ISIS_LEVELS) + level - 1].dis =
adj->dis_record[((i-1) * ISIS_LEVELS) + level - 1].dis;
adj->dis_record[(i * ISIS_LEVELS) + level - 1].last_dis_change =
adj->dis_record[((i-1) * ISIS_LEVELS) + level - 1].last_dis_change;
}
}
return ISIS_OK;
}
int
isis_dr_elect (struct isis_circuit *circuit, int level)
{
struct list *adjdb;
struct listnode *node;
struct isis_adjacency *adj, *adj_dr = NULL;
struct list *list = list_new ();
u_char own_prio;
int biggest_prio = -1;
int cmp_res, retval = ISIS_OK;
own_prio = circuit->u.bc.priority[level - 1];
adjdb = circuit->u.bc.adjdb[level - 1];
if (!adjdb) {
zlog_warn ("isis_dr_elect() adjdb == NULL");
retval = ISIS_WARNING;
list_delete (list);
goto out;
}
isis_adj_build_up_list (adjdb, list);
/*
* Loop the adjacencies and find the one with the biggest priority
*/
for (node = listhead (list); node; nextnode (node)) {
adj = getdata (node);
/* clear flag for show output */
adj->dis_record[level-1].dis = ISIS_IS_NOT_DIS;
adj->dis_record[level-1].last_dis_change = time (NULL);
if (adj->prio[level-1] > biggest_prio) {
biggest_prio = adj->prio[level-1];
adj_dr = adj;
} else if (adj->prio[level-1] == biggest_prio) {
/*
* Comparison of MACs breaks a tie
*/
if (adj_dr) {
cmp_res = memcmp (adj_dr->snpa, adj->snpa, ETH_ALEN);
if (cmp_res < 0) {
adj_dr = adj;
}
if (cmp_res == 0)
zlog_warn ("isis_dr_elect(): multiple adjacencies with same SNPA");
} else {
adj_dr = adj;
}
}
}
if (!adj_dr) {
/*
* Could not find the DR - means we are alone and thus the DR
*/
if ( !circuit->u.bc.is_dr[level - 1]) {
list_delete (list);
list = NULL;
return isis_dr_commence (circuit, level);
}
goto out;
}
/*
* Now we have the DR adjacency, compare it to self
*/
if (adj_dr->prio[level-1] < own_prio || (adj_dr->prio[level-1] == own_prio &&
memcmp (adj_dr->snpa, circuit->u.bc.snpa,
ETH_ALEN) < 0)) {
if (!circuit->u.bc.is_dr[level - 1]) {
/*
* We are the DR -> commence
*/
list_delete (list);
return isis_dr_commence (circuit, level);
}
} else {
/* ok we have found the DIS - lets mark the adjacency */
/* set flag for show output */
adj_dr->dis_record[level - 1].dis = ISIS_IS_DIS;
adj_dr->dis_record[level - 1].last_dis_change = time(NULL);
/* now loop through a second time to check if there has been a DIS change
* if yes rotate the history log
*/
for (node = listhead (list); node; nextnode (node)) {
adj = getdata (node);
isis_check_dr_change(adj, level);
}
/*
* We are not DR - if we were -> resign
*/
if (circuit->u.bc.is_dr[level - 1]) {
list_delete (list);
return isis_dr_resign (circuit, level);
}
}
out:
if (list)
list_delete (list);
return retval;
}
int
isis_dr_resign (struct isis_circuit *circuit, int level)
{
u_char id[ISIS_SYS_ID_LEN + 2];
zlog_info ("isis_dr_resign l%d", level);
circuit->u.bc.is_dr[level - 1] = 0;
circuit->u.bc.run_dr_elect[level - 1] = 0;
if (circuit->u.bc.t_run_dr[level - 1]) {
thread_cancel (circuit->u.bc.t_run_dr[level - 1]);
circuit->u.bc.t_run_dr[level - 1] = NULL;
}
if (circuit->u.bc.t_refresh_pseudo_lsp[level - 1]) {
thread_cancel (circuit->u.bc.t_refresh_pseudo_lsp[level - 1]);
circuit->u.bc.t_refresh_pseudo_lsp[level - 1] = NULL;
}
memcpy (id, isis->sysid, ISIS_SYS_ID_LEN);
LSP_PSEUDO_ID(id) = circuit->circuit_id;
LSP_FRAGMENT(id) = 0;
lsp_purge_dr (id, circuit, level);
if (level == 1) {
memset (circuit->u.bc.l1_desig_is, 0, ISIS_SYS_ID_LEN + 1);
if (circuit->t_send_csnp[0])
thread_cancel (circuit->t_send_csnp[0]);
circuit->u.bc.t_run_dr[0] =
thread_add_timer (master, isis_run_dr_l1, circuit,
2 * circuit->hello_interval[1]);
circuit->t_send_psnp[0] =
thread_add_timer (master,
send_l1_psnp,
circuit,
isis_jitter (circuit->psnp_interval[level - 1],
PSNP_JITTER));
} else {
memset (circuit->u.bc.l2_desig_is, 0, ISIS_SYS_ID_LEN + 1);
if (circuit->t_send_csnp[0])
thread_cancel (circuit->t_send_csnp[0]);
circuit->u.bc.t_run_dr[1] =
thread_add_timer (master, isis_run_dr_l2, circuit,
2 * circuit->hello_interval[1]);
circuit->t_send_psnp[1] =
thread_add_timer (master,
send_l2_psnp,
circuit,
isis_jitter (circuit->psnp_interval[level - 1],
PSNP_JITTER));
}
thread_add_event (master, isis_event_dis_status_change, circuit, 0);
return ISIS_OK;
}
int
isis_dr_commence (struct isis_circuit *circuit, int level)
{
u_char old_dr[ISIS_SYS_ID_LEN + 2];
zlog_info ("isis_dr_commence l%d", level);
/* Lets keep a pause in DR election */
circuit->u.bc.run_dr_elect[level - 1] = 0;
if (level == 1)
circuit->u.bc.t_run_dr[0] =
thread_add_timer (master, isis_run_dr_l1, circuit,
2 * circuit->hello_multiplier[0] *
circuit->hello_interval[0]);
else
circuit->u.bc.t_run_dr[1] =
thread_add_timer (master, isis_run_dr_l2, circuit,
2 * circuit->hello_multiplier[1] *
circuit->hello_interval[1]);
circuit->u.bc.is_dr[level - 1] = 1;
if (level == 1) {
memcpy (old_dr, circuit->u.bc.l1_desig_is, ISIS_SYS_ID_LEN + 1);
LSP_FRAGMENT (old_dr) = 0;
if (LSP_PSEUDO_ID(old_dr)) {
/* there was a dr elected, purge its LSPs from the db */
lsp_purge_dr (old_dr, circuit, level);
}
memcpy (circuit->u.bc.l1_desig_is, isis->sysid, ISIS_SYS_ID_LEN);
*(circuit->u.bc.l1_desig_is + ISIS_SYS_ID_LEN) = circuit->circuit_id;
assert (circuit->circuit_id); /* must be non-zero */
/* if (circuit->t_send_l1_psnp)
thread_cancel (circuit->t_send_l1_psnp); */
lsp_l1_pseudo_generate (circuit);
circuit->u.bc.t_run_dr[0] =
thread_add_timer (master, isis_run_dr_l1, circuit,
2 * circuit->hello_interval[0]);
circuit->t_send_csnp[0] = thread_add_timer (master,
send_l1_csnp,
circuit,
isis_jitter
(circuit->csnp_interval[level-1],
CSNP_JITTER));
} else {
memcpy (old_dr, circuit->u.bc.l2_desig_is, ISIS_SYS_ID_LEN + 1);
LSP_FRAGMENT (old_dr) = 0;
if (LSP_PSEUDO_ID(old_dr)) {
/* there was a dr elected, purge its LSPs from the db */
lsp_purge_dr (old_dr, circuit, level);
}
memcpy (circuit->u.bc.l2_desig_is, isis->sysid, ISIS_SYS_ID_LEN);
*(circuit->u.bc.l2_desig_is + ISIS_SYS_ID_LEN) = circuit->circuit_id;
assert (circuit->circuit_id); /* must be non-zero */
/* if (circuit->t_send_l1_psnp)
thread_cancel (circuit->t_send_l1_psnp); */
lsp_l2_pseudo_generate (circuit);
circuit->u.bc.t_run_dr[1] =
thread_add_timer (master, isis_run_dr_l2, circuit,
2 * circuit->hello_interval[1]);
circuit->t_send_csnp[1] =
thread_add_timer (master,
send_l2_csnp,
circuit,
isis_jitter (circuit->csnp_interval[level-1],
CSNP_JITTER));
}
thread_add_event (master, isis_event_dis_status_change, circuit, 0);
return ISIS_OK;
}

42
isisd/isis_dr.h Normal file
View File

@ -0,0 +1,42 @@
/*
* IS-IS Rout(e)ing protocol - isis_dr.h
* IS-IS designated router related routines
*
* Copyright (C) 2001,2002 Sampo Saaristo
* Tampere University of Technology
* Institute of Communications Engineering
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public Licenseas published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _ZEBRA_ISIS_DR_H
#define _ZEBRA_ISIS_DR_H
int isis_run_dr_l1 (struct thread *thread);
int isis_run_dr_l2 (struct thread *thread);
int isis_dr_elect (struct isis_circuit *circuit, int level);
int isis_dr_resign (struct isis_circuit *circuit, int level);
int isis_dr_commence (struct isis_circuit *circuit, int level);
char *isis_disflag2string (int disflag);
enum isis_dis_state {
ISIS_IS_NOT_DIS,
ISIS_IS_DIS,
ISIS_WAS_DIS,
ISIS_UNKNOWN_DIS
};
#endif /* _ZEBRA_ISIS_DR_H */

124
isisd/isis_dynhn.c Normal file
View File

@ -0,0 +1,124 @@
/*
* IS-IS Rout(e)ing protocol - isis_dynhn.c
* Dynamic hostname cache
* Copyright (C) 2001,2002 Sampo Saaristo
* Tampere University of Technology
* Institute of Communications Engineering
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public Licenseas published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <time.h>
#include <zebra.h>
#include <net/ethernet.h>
#include "vty.h"
#include "linklist.h"
#include "memory.h"
#include "log.h"
#include "stream.h"
#include "command.h"
#include "if.h"
#include "isisd/dict.h"
#include "isisd/isis_constants.h"
#include "isisd/isis_common.h"
#include "isisd/isis_flags.h"
#include "isisd/isis_circuit.h"
#include "isisd/isisd.h"
#include "isisd/isis_dynhn.h"
#include "isisd/isis_misc.h"
#include "isisd/isis_constants.h"
extern struct isis *isis;
extern struct host host;
struct list *dyn_cache = NULL;
void
dyn_cache_init (void)
{
dyn_cache = list_new ();
return;
}
struct isis_dynhn *dynhn_find_by_id (u_char * id)
{
struct listnode *node = NULL;
struct isis_dynhn *dyn = NULL;
for (node = listhead (dyn_cache); node; nextnode (node)) {
dyn = getdata (node);
if (memcmp (dyn->id, id, ISIS_SYS_ID_LEN) == 0)
return dyn;
}
return NULL;
}
void
isis_dynhn_insert (u_char *id, struct hostname *hostname, int level)
{
struct isis_dynhn *dyn;
dyn = dynhn_find_by_id (id);
if (dyn) {
memcpy (&dyn->name, hostname, hostname->namelen + 1);
memcpy (dyn->id, id, ISIS_SYS_ID_LEN);
dyn->refresh = time (NULL);
return;
}
dyn = XMALLOC (MTYPE_ISIS_DYNHN, sizeof (struct isis_dynhn));
if (!dyn) {
zlog_warn ("isis_dynhn_insert(): out of memory!");
return;
}
memset (dyn,0,sizeof(struct isis_dynhn));
/* we also copy the length */
memcpy (&dyn->name, hostname, hostname->namelen + 1);
memcpy (dyn->id, id, ISIS_SYS_ID_LEN);
dyn->refresh = time (NULL);
dyn->level = level;
listnode_add (dyn_cache, dyn);
return;
}
/*
* Level System ID Dynamic Hostname (notag)
* 2 0000.0000.0001 foo-gw
* 2 0000.0000.0002 bar-gw
* * 0000.0000.0004 this-gw
*/
void dynhn_print_all (struct vty *vty)
{
struct listnode *node;
struct isis_dynhn *dyn;
vty_out (vty, "Level System ID Dynamic Hostname%s", VTY_NEWLINE);
for (node = listhead (dyn_cache); node; nextnode (node)) {
dyn = getdata (node);
vty_out (vty, "%-7d", dyn->level);
vty_out (vty, "%-15s%-15s%s", sysid_print (dyn->id), dyn->name.name,
VTY_NEWLINE);
}
vty_out (vty, " * %s %s%s", sysid_print (isis->sysid), host.name,
VTY_NEWLINE);
return;
}

42
isisd/isis_dynhn.h Normal file
View File

@ -0,0 +1,42 @@
/*
* IS-IS Rout(e)ing protocol - isis_dynhn.h
* Dynamic hostname cache
*
* Copyright (C) 2001,2002 Sampo Saaristo
* Tampere University of Technology
* Institute of Communications Engineering
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public Licenseas published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _ZEBRA_ISIS_DYNHN_H
#define _ZEBRA_ISIS_DYNHN_H
struct isis_dynhn {
u_char id[ISIS_SYS_ID_LEN];
struct hostname name;
time_t refresh;
int level;
};
void dyn_cache_init (void);
void isis_dynhn_insert (u_char *id, struct hostname *hostname, int level);
struct isis_dynhn *dynhn_find_by_id (u_char * id);
void dynhn_print_all (struct vty *vty);
#endif /* _ZEBRA_ISIS_DYNHN_H */

336
isisd/isis_events.c Normal file
View File

@ -0,0 +1,336 @@
/*
* IS-IS Rout(e)ing protocol - isis_events.h
*
* Copyright (C) 2001,2002 Sampo Saaristo
* Tampere University of Technology
* Institute of Communications Engineering
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public Licenseas published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <zebra.h>
#include <net/ethernet.h>
#include "log.h"
#include "memory.h"
#include "if.h"
#include "linklist.h"
#include "command.h"
#include "thread.h"
#include "hash.h"
#include "prefix.h"
#include "stream.h"
#include "isisd/dict.h"
#include "isisd/include-netbsd/iso.h"
#include "isisd/isis_constants.h"
#include "isisd/isis_common.h"
#include "isisd/isis_circuit.h"
#include "isisd/isis_tlv.h"
#include "isisd/isis_lsp.h"
#include "isisd/isis_pdu.h"
#include "isisd/isis_network.h"
#include "isisd/isis_misc.h"
#include "isisd/isis_constants.h"
#include "isisd/isis_adjacency.h"
#include "isisd/isis_dr.h"
#include "isisd/isis_flags.h"
#include "isisd/isisd.h"
#include "isisd/isis_csm.h"
#include "isisd/isis_events.h"
#include "isisd/isis_spf.h"
extern struct thread_master *master;
extern struct isis *isis;
/* debug isis-spf spf-events
4w4d: ISIS-Spf (tlt): L2 SPF needed, new adjacency, from 0x609229F4
4w4d: ISIS-Spf (tlt): L2, 0000.0000.0042.01-00 TLV contents changed, code 0x2
4w4d: ISIS-Spf (tlt): L2, new LSP 0 DEAD.BEEF.0043.00-00
4w5d: ISIS-Spf (tlt): L1 SPF needed, periodic SPF, from 0x6091C844
4w5d: ISIS-Spf (tlt): L2 SPF needed, periodic SPF, from 0x6091C844
*/
void
isis_event_circuit_state_change (struct isis_circuit *circuit, int up)
{
struct isis_area *area;
area = circuit->area;
assert (area);
area->circuit_state_changes++;
if (isis->debugs & DEBUG_EVENTS)
zlog_info ("ISIS-Evt (%s) circuit %s", circuit->area->area_tag,
up ? "up" : "down");
/*
* Regenerate LSPs this affects
*/
lsp_regenerate_schedule (area);
return;
}
void
isis_event_system_type_change (struct isis_area *area, int newtype)
{
struct listnode *node;
struct isis_circuit *circuit;
if (isis->debugs & DEBUG_EVENTS)
zlog_info ("ISIS-Evt (%s) system type change %s -> %s", area->area_tag,
circuit_t2string (area->is_type), circuit_t2string (newtype));
if (area->is_type == newtype)
return; /* No change */
switch (area->is_type) {
case IS_LEVEL_1:
if (area->lspdb[1] == NULL)
area->lspdb[1] = lsp_db_init ();
lsp_l2_generate (area);
break;
case IS_LEVEL_1_AND_2:
if (newtype == IS_LEVEL_1) {
lsp_db_destroy (area->lspdb[1]);
}
else {
lsp_db_destroy (area->lspdb[0]);
}
break;
case IS_LEVEL_2:
if (area->lspdb[0] == NULL)
area->lspdb[0] = lsp_db_init ();
lsp_l1_generate (area);
break;
default:
break;
}
area->is_type = newtype;
for (node = listhead (area->circuit_list); node; nextnode (node)) {
circuit = getdata (node);
isis_event_circuit_type_change (circuit, newtype);
}
spftree_area_init (area);
lsp_regenerate_schedule (area);
return;
}
void
isis_event_area_addr_change (struct isis_area *area)
{
}
void
circuit_commence_level (struct isis_circuit *circuit, int level)
{
uint32_t interval;
if (level == 1) {
circuit->t_send_psnp[0] = thread_add_timer (master, send_l1_psnp,
circuit,
isis_jitter
(circuit->psnp_interval[0],
PSNP_JITTER));
if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
interval = circuit->hello_multiplier[0] * (circuit->hello_interval[0]);
circuit->u.bc.t_run_dr[0] = thread_add_timer (master, isis_run_dr_l1,
circuit, interval);
circuit->u.bc.t_send_lan_hello[0] =
thread_add_timer (master,
send_lan_l1_hello,
circuit,
isis_jitter
(circuit->hello_interval[0], IIH_JITTER));
circuit->u.bc.lan_neighs[0] = list_new ();
}
} else {
circuit->t_send_psnp[1] = thread_add_timer (master, send_l2_psnp,
circuit,
isis_jitter
(circuit->psnp_interval[1],
PSNP_JITTER));
if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
interval = circuit->hello_multiplier[1] * (circuit->hello_interval[1]);
circuit->u.bc.t_run_dr[1] = thread_add_timer (master, isis_run_dr_l2,
circuit, interval);
circuit->u.bc.t_send_lan_hello[1] =
thread_add_timer (master,
send_lan_l2_hello,
circuit,
isis_jitter
(circuit->hello_interval[1], IIH_JITTER));
circuit->u.bc.lan_neighs[1] = list_new ();
}
}
return;
}
void
circuit_resign_level (struct isis_circuit *circuit, int level)
{
int idx = level - 1;
if (circuit->t_send_csnp[idx])
thread_cancel (circuit->t_send_csnp[idx]);
circuit->t_send_csnp[idx] = NULL;
if (circuit->t_send_psnp[idx])
thread_cancel (circuit->t_send_psnp[idx]);
circuit->t_send_psnp[level - 1] = NULL;
if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
if (circuit->u.bc.t_send_lan_hello[idx])
thread_cancel (circuit->u.bc.t_send_lan_hello[idx]);
circuit->u.bc.t_send_lan_hello[idx] = NULL;
if (circuit->u.bc.t_run_dr[idx])
thread_cancel (circuit->u.bc.t_run_dr[idx]);
circuit->u.bc.t_run_dr[idx] = NULL;
circuit->u.bc.run_dr_elect[idx] = 0;
}
return;
}
void
isis_event_circuit_type_change (struct isis_circuit *circuit, int newtype)
{
if (isis->debugs & DEBUG_EVENTS)
zlog_info ("ISIS-Evt (%s) circuit type change %s -> %s",
circuit->area->area_tag,
circuit_t2string (circuit->circuit_is_type),
circuit_t2string (newtype));
if (circuit->circuit_is_type == newtype)
return; /* No change */
if (!(newtype & circuit->area->is_type)) {
zlog_err ("ISIS-Evt (%s) circuit type change - invalid level %s because"
" area is %s", circuit->area->area_tag,
circuit_t2string (newtype),
circuit_t2string (circuit->area->is_type));
return;
}
switch (circuit->circuit_is_type) {
case IS_LEVEL_1:
if (newtype == IS_LEVEL_2)
circuit_resign_level (circuit, 1);
circuit_commence_level (circuit, 2);
break;
case IS_LEVEL_1_AND_2:
if (newtype == IS_LEVEL_1)
circuit_resign_level (circuit, 2);
else
circuit_resign_level (circuit, 1);
break;
case IS_LEVEL_2:
if (newtype == IS_LEVEL_1)
circuit_resign_level (circuit, 2);
circuit_commence_level (circuit, 1);
break;
default:
break;
}
circuit->circuit_is_type = newtype;
lsp_regenerate_schedule (circuit->area);
return;
}
/* 04/18/2002 by Gwak. */
/**************************************************************************
*
* EVENTS for LSP generation
*
* 1) an Adajacency or Circuit Up/Down event
* 2) a chnage in Circuit metric
* 3) a change in Reachable Address metric
* 4) a change in manualAreaAddresses
* 5) a change in systemID
* 6) a change in DIS status
* 7) a chnage in the waiting status
*
* ***********************************************************************
*
* current support event
*
* 1) Adjacency Up/Down event
* 6) a change in DIS status
*
* ***********************************************************************/
void
isis_event_adjacency_state_change (struct isis_adjacency *adj, int newstate)
{
/* adjacency state change event.
* - the only proto-type was supported */
/* invalid arguments */
if ( !adj || !adj->circuit || !adj->circuit->area ) return;
zlog_info ("ISIS-Evt (%s) Adjacency State change",
adj->circuit->area->area_tag );
/* LSP generation again */
lsp_regenerate_schedule (adj->circuit->area);
return;
}
/* events supporting code */
int
isis_event_dis_status_change (struct thread *thread)
{
struct isis_circuit *circuit;
circuit = THREAD_ARG (thread);
/* invalid arguments */
if (!circuit || !circuit->area) return 0;
zlog_info ("ISIS-Evt (%s) DIS status change", circuit->area->area_tag);
/* LSP generation again */
lsp_regenerate_schedule (circuit->area);
return 0;
}
void
isis_event_auth_failure (char *area_tag, char *error_string, char *sysid)
{
zlog_info ("ISIS-Evt (%s) Authentication failure %s from %s",
area_tag, error_string, sysid_print (sysid));
return;
}

54
isisd/isis_events.h Normal file
View File

@ -0,0 +1,54 @@
/*
* IS-IS Rout(e)ing protocol - isis_events.h
*
* Copyright (C) 2001,2002 Sampo Saaristo
* Tampere University of Technology
* Institute of Communications Engineering
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public Licenseas published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _ZEBRA_ISIS_EVENTS_H
#define _ZEBRA_ISIS_EVENTS_H
/*
* Events related to area
*/
void isis_event_system_type_change (struct isis_area *area, int newtype);
void isis_event_area_addr_change (struct isis_area *area);
/*
* Events related to circuit
*/
void isis_event_circuit_state_change (struct isis_circuit *circuit, int state);
void isis_event_circuit_type_change (struct isis_circuit *circuit,
int newtype);
/*
* Events related to adjacencies
*/
void isis_event_adjacency_state_change(struct isis_adjacency *adj,
int newstate);
int isis_event_dis_status_change (struct thread *thread);
/*
* Error events
*/
#define AUTH_ERROR_TYPE_LSP 3
#define AUTH_ERROR_TYPE_SNP 2
#define AUTH_ERROR_TYPE_HELLO 1
void isis_event_auth_failure (char *area_tag, char *error_string, char *sysid);
#endif /* _ZEBRA_ISIS_EVENTS_H */

71
isisd/isis_flags.c Normal file
View File

@ -0,0 +1,71 @@
/*
* IS-IS Rout(e)ing protocol - isis_flags.c
* Routines for manipulation of SSN and SRM flags
*
* Copyright (C) 2001,2002 Sampo Saaristo
* Tampere University of Technology
* Institute of Communications Engineering
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public Licenseas published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <zebra.h>
#include "log.h"
#include "linklist.h"
#include "isisd/isis_constants.h"
#include "isisd/isis_common.h"
#include "isisd/isis_flags.h"
int
flags_get_index (struct flags *flags)
{
struct listnode *node;
int index;
if (flags->free_idcs == NULL || flags->free_idcs->count == 0) {
flags->maxindex++;
index = flags->maxindex;
} else {
node = listhead (flags->free_idcs);
index = (int) getdata (node);
listnode_delete (flags->free_idcs, (void *)index);
}
return index;
}
void
flags_free_index (struct flags *flags, int index)
{
if (flags->free_idcs == NULL) {
flags->free_idcs = list_new ();
}
listnode_add (flags->free_idcs, (void *)index);
return;
}
int
flags_any_set (u_int32_t *flags)
{
u_int32_t zero[ISIS_MAX_CIRCUITS];
memset (zero, 0x00, ISIS_MAX_CIRCUITS*4);
return bcmp(flags, zero, ISIS_MAX_CIRCUITS*4);
}

58
isisd/isis_flags.h Normal file
View File

@ -0,0 +1,58 @@
/*
* IS-IS Rout(e)ing protocol - isis_flags.h
* Routines for manipulation of SSN and SRM flags
*
* Copyright (C) 2001,2002 Sampo Saaristo
* Tampere University of Technology
* Institute of Communications Engineering
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public Licenseas published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _ZEBRA_ISIS_FLAGS_H
#define _ZEBRA_ISIS_FLAGS_H
/* The grand plan is to support 1024 circuits so we have 32*32 bit flags
* the support will be achived using the newest drafts */
#define ISIS_MAX_CIRCUITS 32 /* = 1024 */ /*FIXME:defined in lsp.h as well*/
struct flags *new_flags (int size);
int flags_get_index (struct flags *flags);
void flags_free_index (struct flags *flags, int index);
int flags_any_set (u_int32_t *flags);
#define ISIS_SET_FLAG(F,C) \
F[C->idx>>5] |= (1<<(C->idx & 0x1F));
#define ISIS_CLEAR_FLAG(F,C) \
F[C->idx>>5] &= ~(1<<(C->idx & 0x1F));
#define ISIS_CHECK_FLAG(F, C) F[(C)->idx>>5] & (1<<(C->idx & 0x1F))
/* sets all u_32int_t flags to 1 */
#define ISIS_FLAGS_SET_ALL(FLAGS) \
memset(FLAGS,0xFF,ISIS_MAX_CIRCUITS*4);
#define ISIS_FLAGS_CLEAR_ALL(FLAGS) \
memset(FLAGS,0x00,ISIS_MAX_CIRCUITS*4);
#endif /* _ZEBRA_ISIS_FLAGS_H */

2419
isisd/isis_lsp.c Normal file

File diff suppressed because it is too large Load Diff

132
isisd/isis_lsp.h Normal file
View File

@ -0,0 +1,132 @@
/*
* IS-IS Rout(e)ing protocol - isis_lsp.h
* LSP processing
*
* Copyright (C) 2001,2002 Sampo Saaristo
* Tampere University of Technology
* Institute of Communications Engineering
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public Licenseas published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _ZEBRA_ISIS_LSP_H
#define _ZEBRA_ISIS_LSP_H
/* The grand plan is to support 1024 circuits so we have 32*32 bit flags
* the support will be achived using the newest drafts */
#define ISIS_MAX_CIRCUITS 32 /* = 1024 */ /*FIXME:defined in flags.h as well*/
/* Structure for isis_lsp, this structure will only support the fixed
* System ID (Currently 6) (atleast for now). In order to support more
* We will have to split the header into two parts, and for readability
* sake it should better be avoided */
struct isis_lsp
{
struct isis_fixed_hdr *isis_header; /* normally equals pdu */
struct isis_link_state_hdr *lsp_header; /* pdu + isis_header_len */
struct stream *pdu; /* full pdu lsp */
union {
struct list *frags;
struct isis_lsp *zero_lsp;
} lspu;
u_int32_t SRMflags[ISIS_MAX_CIRCUITS];
u_int32_t SSNflags[ISIS_MAX_CIRCUITS];
u_int32_t rexmit_queue[ISIS_MAX_CIRCUITS];
int level; /* L1 or L2? */
int purged; /* have purged this one */
int scheduled; /* scheduled for sending */
time_t installed;
time_t last_generated;
time_t last_sent;
int own_lsp;
#ifdef TOPOLOGY_GENERATE
int from_topology;
struct thread *t_lsp_top_ref;
#endif
/* used for 60 second counting when rem_lifetime is zero */
int age_out;
struct isis_adjacency *adj;
struct tlvs tlv_data; /* Simplifies TLV access */
};
dict_t *lsp_db_init (void);
void lsp_db_destroy (dict_t *lspdb);
int lsp_tick (struct thread *thread);
int lsp_l1_generate (struct isis_area *area);
int lsp_l2_generate (struct isis_area *area);
int lsp_refresh_l1 (struct thread *thread);
int lsp_refresh_l2 (struct thread *thread);
int lsp_regenerate_schedule (struct isis_area *area);
int lsp_l1_pseudo_generate (struct isis_circuit *circuit);
int lsp_l2_pseudo_generate (struct isis_circuit *circuit);
int lsp_l1_refresh_pseudo (struct thread *thread);
int lsp_l2_refresh_pseudo (struct thread *thread);
int isis_lsp_authinfo_check (struct stream *stream, struct isis_area *area,
int pdulen, struct isis_passwd *passwd);
struct isis_lsp *lsp_new (u_char *lsp_id, u_int16_t rem_lifetime,
u_int32_t seq_num, u_int8_t lsp_bits,
u_int16_t checksum, int level);
struct isis_lsp *lsp_new_from_stream_ptr (struct stream *stream,
u_int16_t pdu_len,
struct isis_lsp *lsp0,
struct isis_area *area);
void lsp_insert (struct isis_lsp *lsp, dict_t *lspdb);
struct isis_lsp *lsp_search (u_char *id, dict_t *lspdb);
void lsp_build_list (u_char *start_id, u_char *stop_id,
struct list *list, dict_t *lspdb);
void lsp_build_list_nonzero_ht (u_char *start_id, u_char *stop_id,
struct list *list, dict_t *lspdb);
void lsp_build_list_ssn (struct isis_circuit *circuit, struct list *list,
dict_t *lspdb);
void lsp_search_and_destroy (u_char *id, dict_t *lspdb);
void lsp_purge_dr (u_char *id, struct isis_circuit *circuit, int level);
void lsp_purge_non_exist (struct isis_link_state_hdr *lsp_hdr,
struct isis_area *area);
#define LSP_EQUAL 1
#define LSP_NEWER 2
#define LSP_OLDER 3
#define LSP_PSEUDO_ID(I) ((u_char)(I)[ISIS_SYS_ID_LEN])
#define LSP_FRAGMENT(I) ((u_char)(I)[ISIS_SYS_ID_LEN + 1])
#define OWNLSPID(I) \
memcpy ((I), isis->sysid, ISIS_SYS_ID_LEN);\
(I)[ISIS_SYS_ID_LEN] = 0;\
(I)[ISIS_SYS_ID_LEN + 1] = 0
int lsp_id_cmp (u_char *id1, u_char *id2);
int lsp_compare (char *areatag, struct isis_lsp *lsp, u_int32_t seq_num,
u_int16_t checksum, u_int16_t rem_lifetime);
void lsp_update (struct isis_lsp *lsp, struct isis_link_state_hdr *lsp_hdr,
struct stream *stream, struct isis_area *area);
void lsp_inc_seqnum (struct isis_lsp *lsp, u_int32_t seq_num);
int lsp_print_all (struct vty *vty, dict_t *lspdb, char detail, char dynhost);
char *lsp_bits2string (u_char *);
/* staticly assigned vars for printing purposes */
char lsp_bits_string[200]; /* FIXME: enough ? */
#ifdef TOPOLOGY_GENERATE
void generate_topology_lsps (struct isis_area *area);
void remove_topology_lsps (struct isis_area *area);
void build_topology_lsp_data (struct isis_lsp *lsp,
struct isis_area *area, int lsp_top_num);
#endif /* TOPOLOGY_GENERATE */
#endif /* ISIS_LSP */

330
isisd/isis_main.c Normal file
View File

@ -0,0 +1,330 @@
/*
* IS-IS Rout(e)ing protocol - isis_main.c
*
* Copyright (C) 2001,2002 Sampo Saaristo
* Tampere University of Technology
* Institute of Communications Engineering
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public Licenseas published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <stdio.h>
#include <zebra.h>
#include <net/ethernet.h>
#include "getopt.h"
#include "thread.h"
#include "log.h"
#include "version.h"
#include "command.h"
#include "vty.h"
#include "memory.h"
#include "stream.h"
#include "if.h"
#include "isisd/dict.h"
#include "include-netbsd/iso.h"
#include "isisd/isis_constants.h"
#include "isisd/isis_common.h"
#include "isisd/isis_flags.h"
#include "isisd/isis_circuit.h"
#include "isisd/isisd.h"
#include "isisd/isis_dynhn.h"
/* Default configuration file name */
#define ISISD_DEFAULT_CONFIG "isisd.conf"
/* Default vty port */
#define ISISD_VTY_PORT 2607
/* isisd options */
struct option longopts[] =
{
{ "daemon", no_argument, NULL, 'd'},
{ "config_file", required_argument, NULL, 'f'},
{ "vty_port", required_argument, NULL, 'P'},
{ "version", no_argument, NULL, 'v'},
{ "help", no_argument, NULL, 'h'},
{ 0 }
};
/* Configuration file and directory. */
char config_current[] = ISISD_DEFAULT_CONFIG;
char config_default[] = SYSCONFDIR ISISD_DEFAULT_CONFIG;
char *config_file = NULL;
/* isisd program name. */
char *progname;
int daemon_mode = 0;
/* Master of threads. */
struct thread_master *master;
/* for reload */
char _cwd[64];
char _progpath[64];
int _argc;
char **_argv;
char **_envp;
/* Help information display. */
static void
usage (int status)
{
if (status != 0)
fprintf (stderr, "Try `%s --help' for more information.\n", progname);
else
{
printf ("Usage : %s [OPTION...]\n\n\
Daemon which manages IS-IS routing\n\n\
-d, --daemon Runs in daemon mode\n\
-f, --config_file Set configuration file name\n\
-P, --vty_port Set vty's port number\n\
-v, --version Print program version\n\
-h, --help Display this help and exit\n\
\n\
Report bugs to sambo@cs.tut.fi\n", progname);
}
exit (status);
}
void
reload ()
{
zlog_info ("Reload");
/* FIXME: Clean up func call here */
vty_finish ();
execve (_progpath, _argv, _envp);
}
void
terminate (int i)
{
exit (i);
}
/*
* Signal handlers
*/
void
sighup (int sig)
{
zlog_info ("SIGHUP received");
reload ();
return;
}
void
sigint (int sig)
{
zlog_info ("SIGINT received");
terminate (0);
return;
}
void
sigterm (int sig)
{
zlog_info ("SIGTERM received");
terminate (0);
}
void
sigusr1 (int sig)
{
zlog_info ("SIGUSR1 received");
zlog_rotate (NULL);
}
/*
* Signal wrapper.
*/
RETSIGTYPE *
signal_set (int signo, void (*func)(int))
{
int ret;
struct sigaction sig;
struct sigaction osig;
sig.sa_handler = func;
sigemptyset (&sig.sa_mask);
sig.sa_flags = 0;
#ifdef SA_RESTART
sig.sa_flags |= SA_RESTART;
#endif /* SA_RESTART */
ret = sigaction (signo, &sig, &osig);
if (ret < 0)
return (SIG_ERR);
else
return (osig.sa_handler);
}
void
signal_init ()
{
signal_set (SIGHUP, sighup);
signal_set (SIGINT, sigint);
signal_set (SIGTERM, sigterm);
signal_set (SIGPIPE, SIG_IGN);
#ifdef SIGTSTP
signal_set (SIGTSTP, SIG_IGN);
#endif
#ifdef SIGTTIN
signal_set (SIGTTIN, SIG_IGN);
#endif
#ifdef SIGTTOU
signal_set (SIGTTOU, SIG_IGN);
#endif
signal_set (SIGUSR1, sigusr1);
}
/*
* Main routine of isisd. Parse arguments and handle IS-IS state machine.
*/
int
main (int argc, char **argv, char **envp)
{
char *p;
int opt, vty_port = ISISD_VTY_PORT;
struct thread thread;
char *config_file = NULL;
char *vty_addr = NULL;
/* Get the programname without the preceding path. */
progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
zlog_default = openzlog (progname, ZLOG_NOLOG, ZLOG_ISIS,
LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
/* for reload */
_argc = argc;
_argv = argv;
_envp = envp;
getcwd (_cwd, sizeof (_cwd));
if (*argv[0] == '.')
snprintf (_progpath, sizeof (_progpath), "%s/%s", _cwd, _argv[0]);
else
snprintf (_progpath, sizeof (_progpath), "%s", argv[0]);
/* Command line argument treatment. */
while (1)
{
opt = getopt_long (argc, argv, "df:hAp:P:v", longopts, 0);
if (opt == EOF)
break;
switch (opt)
{
case 0:
break;
case 'd':
daemon_mode = 1;
break;
case 'f':
config_file = optarg;
break;
case 'A':
vty_addr = optarg;
break;
case 'P':
vty_port = atoi (optarg);
break;
case 'v':
printf("ISISd version %s\n", ISISD_VERSION);
printf("Copyright (c) 2001-2002 Sampo Saaristo,"
" Ofer Wald and Hannes Gredler\n");
print_version ("Zebra");
exit (0);
break;
case 'h':
usage (0);
break;
default:
usage (1);
break;
}
}
/* thread master */
master = thread_master_create ();
/* random seed from time */
srand(time(NULL));
/*
* initializations
*/
signal_init ();
cmd_init (1);
vty_init ();
memory_init ();
isis_init ();
dyn_cache_init ();
sort_node ();
/* parse config file */
/* this is needed three times! because we have interfaces before the areas */
vty_read_config (config_file, config_current, config_default);
#if 0
vty_read_config (config_file, config_current, config_default);
vty_read_config (config_file, config_current, config_default);
#endif
/* demonize */
if (daemon_mode)
daemon (0, 0);
/* Problems with the build env ?*/
#ifndef PATH_ISISD_PID
#define PATH_ISISD_PID "/var/run/isisd.pid"
#endif
/* Process ID file creation. */
pid_output (PATH_ISISD_PID);
/* Make isis vty socket. */
vty_serv_sock (vty_addr, vty_port ? vty_port : ISISD_VTY_PORT,
ISIS_VTYSH_PATH);
/* Print banner. */
zlog_info ("ISISd %s starting: vty@%d", ZEBRA_VERSION, vty_port);
#ifdef HAVE_IPV6
zlog_info ("IPv6 enabled");
#endif
/* Start finite state machine. */
while (thread_fetch (master, &thread))
thread_call (&thread);
/* Not reached. */
exit (0);
}

438
isisd/isis_misc.c Normal file
View File

@ -0,0 +1,438 @@
/*
* IS-IS Rout(e)ing protocol - isis_misc.h
* Miscellanous routines
*
* Copyright (C) 2001,2002 Sampo Saaristo
* Tampere University of Technology
* Institute of Communications Engineering
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public Licenseas published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <ctype.h>
#include <zebra.h>
#include <net/ethernet.h>
#include "stream.h"
#include "vty.h"
#include "hash.h"
#include "if.h"
#include "isisd/dict.h"
#include "isisd/isis_constants.h"
#include "isisd/isis_common.h"
#include "isisd/isis_circuit.h"
#include "isisd/isisd.h"
#include "isisd/isis_misc.h"
#include "isisd/isis_tlv.h"
#include "isisd/isis_lsp.h"
#include "isisd/isis_constants.h"
#include "isisd/isis_adjacency.h"
/*
* This converts the isonet to its printable format
*/
char * isonet_print (u_char *from, int len) {
int i = 0;
char *pos = isonet;
if(!from)
return "unknown";
while (i < len) {
if (i & 1) {
sprintf ( pos, "%02x", *(from + i));
pos += 2;
} else {
if (i == 0) { /* if the area addr is just one byte, eg. 47. */
sprintf ( pos, "%02x", *(from + i));
pos += 2;
} else {
sprintf ( pos, "%02x.", *(from + i));
pos += 3;
}
}
i++;
}
*(pos) = '\0';
return isonet;
}
/*
* Returns 0 on error, length of buff on ok
* extract dot from the dotted str, and insert all the number in a buff
*/
int
dotformat2buff (u_char *buff, u_char *dotted)
{
int dotlen, len = 0;
u_char *pos = dotted;
u_char number[3];
int nextdotpos = 2;
number[2] = '\0';
dotlen = strlen(dotted);
if (dotlen > 50) {
/* this can't be an iso net, its too long */
return 0;
}
while ( (pos - dotted) < dotlen && len < 20 ) {
if (*pos == '.') {
/* we expect the . at 2, and than every 5 */
if ((pos - dotted) != nextdotpos) {
len = 0;
break;
}
nextdotpos += 5;
pos++;
continue;
}
/* we must have at least two chars left here */
if (dotlen - (pos - dotted) < 2) {
len = 0;
break;
}
if ((isxdigit((int)*pos)) && (isxdigit((int)*(pos+1)))){
memcpy (number, pos ,2);
pos+=2;
} else {
len = 0;
break;
}
*(buff + len) = (char)strtol(number, NULL, 16);
len++;
}
return len;
}
/*
* conversion of XXXX.XXXX.XXXX to memory
*/
int
sysid2buff (u_char *buff, u_char *dotted)
{
int len = 0;
u_char *pos = dotted;
u_char number[3];
number[2] = '\0';
// surely not a sysid_string if not 14 length
if (strlen(dotted) != 14) {
return 0;
}
while ( len < ISIS_SYS_ID_LEN ) {
if (*pos == '.') {
/* the . is not positioned correctly */
if (((pos - dotted) !=4) && ((pos - dotted) != 9)) {
len = 0;
break;
}
pos++;
continue;
}
if ((isxdigit((int)*pos)) && (isxdigit((int)*(pos+1)))){
memcpy (number, pos ,2);
pos+=2;
} else {
len = 0;
break;
}
*(buff + len) = (char)strtol(number, NULL, 16);
len++;
}
return len;
}
/*
* converts the nlpids struct (filled by TLV #129)
* into a string
*/
char *
nlpid2string (struct nlpids *nlpids) {
char *pos = nlpidstring;
int i;
for (i=0;i<nlpids->count;i++) {
switch (nlpids->nlpids[i]) {
case NLPID_IP:
pos += sprintf (pos, "IPv4");
break;
case NLPID_IPV6:
pos += sprintf (pos, "IPv6");
break;
default:
pos += sprintf (pos, "unknown");
break;
}
if (nlpids->count-i>1)
pos += sprintf (pos, ", ");
}
*(pos) = '\0';
return nlpidstring;
}
/*
* supports the given af ?
*/
int
speaks (struct nlpids *nlpids, int family)
{
int i, speaks = 0;
if (nlpids == (struct nlpids*)NULL)
return speaks;
for (i = 0;i < nlpids->count; i++) {
if (family == AF_INET && nlpids->nlpids[i] == NLPID_IP)
speaks = 1;
if (family == AF_INET6 && nlpids->nlpids[i] == NLPID_IPV6)
speaks = 1;
}
return speaks;
}
/*
* Returns 0 on error, IS-IS Circuit Type on ok
*/
int
string2circuit_t (u_char *str)
{
if (!str)
return 0;
if (!strcmp(str,"level-1"))
return IS_LEVEL_1;
if (!strcmp(str,"level-2-only") || !strcmp(str,"level-2"))
return IS_LEVEL_2;
if (!strcmp(str,"level-1-2"))
return IS_LEVEL_1_AND_2;
return 0;
}
const char *
circuit_t2string (int circuit_t)
{
switch (circuit_t) {
case IS_LEVEL_1:
return "L1";
case IS_LEVEL_2:
return "L2";
case IS_LEVEL_1_AND_2:
return "L1L2";
default:
return "??";
}
return NULL; /* not reached */
}
const char *
syst2string (int type)
{
switch (type) {
case ISIS_SYSTYPE_ES:
return "ES";
case ISIS_SYSTYPE_IS:
return "IS";
case ISIS_SYSTYPE_L1_IS:
return "1";
case ISIS_SYSTYPE_L2_IS:
return "2";
default:
return "??";
}
return NULL; /* not reached */
}
/*
* Print functions - we print to static vars
*/
char *
snpa_print (u_char *from)
{
int i = 0;
u_char *pos = snpa;
if(!from)
return "unknown";
while (i < ETH_ALEN - 1) {
if (i & 1) {
sprintf ( pos, "%02x.", *(from + i));
pos += 3;
} else {
sprintf ( pos, "%02x", *(from + i));
pos += 2;
}
i++;
}
sprintf (pos, "%02x", *(from + (ISIS_SYS_ID_LEN - 1)));
pos += 2;
*(pos) = '\0';
return snpa;
}
char *
sysid_print (u_char *from)
{
int i = 0;
char *pos = sysid;
if(!from)
return "unknown";
while (i < ISIS_SYS_ID_LEN - 1) {
if (i & 1) {
sprintf ( pos, "%02x.", *(from + i));
pos += 3;
} else {
sprintf ( pos, "%02x", *(from + i));
pos += 2;
}
i++;
}
sprintf (pos, "%02x", *(from + (ISIS_SYS_ID_LEN - 1)));
pos += 2;
*(pos) = '\0';
return sysid;
}
char *
rawlspid_print (u_char *from)
{
char *pos = lspid;
if(!from)
return "unknown";
memcpy(pos, sysid_print(from), 15);
pos += 14;
sprintf (pos, ".%02x", LSP_PSEUDO_ID(from));
pos += 3;
sprintf (pos, "-%02x", LSP_FRAGMENT(from));
pos += 3;
*(pos) = '\0';
return lspid;
}
char *
time2string (u_int32_t time) {
char *pos = datestring;
u_int32_t rest;
if (time==0)
return "-";
if(time/SECS_PER_YEAR)
pos += sprintf (pos, "%uY",time/SECS_PER_YEAR);
rest=time%SECS_PER_YEAR;
if(rest/SECS_PER_MONTH)
pos += sprintf (pos, "%uM",rest/SECS_PER_MONTH);
rest=rest%SECS_PER_MONTH;
if(rest/SECS_PER_WEEK)
pos += sprintf (pos, "%uw",rest/SECS_PER_WEEK);
rest=rest%SECS_PER_WEEK;
if(rest/SECS_PER_DAY)
pos += sprintf (pos, "%ud",rest/SECS_PER_DAY);
rest=rest%SECS_PER_DAY;
if(rest/SECS_PER_HOUR)
pos += sprintf (pos, "%uh",rest/SECS_PER_HOUR);
rest=rest%SECS_PER_HOUR;
if(rest/SECS_PER_MINUTE)
pos += sprintf (pos, "%um",rest/SECS_PER_MINUTE);
rest=rest%SECS_PER_MINUTE;
if(rest)
pos += sprintf (pos, "%us",rest);
*(pos) = 0;
return datestring;
}
/*
* routine to decrement a timer by a random
* number
*
* first argument is the timer and the second is
* the jitter
*/
unsigned long
isis_jitter (unsigned long timer, unsigned long jitter)
{
int j,k;
if (jitter>=100)
return timer;
if (timer == 1)
return timer;
/*
* randomizing just the percent value provides
* no good random numbers - hence the spread
* to RANDOM_SPREAD (100000), which is ok as
* most IS-IS timers are no longer than 16 bit
*/
j = 1 + (int) ((RANDOM_SPREAD * rand()) / (RAND_MAX + 1.0 ));
k = timer - (timer * (100 - jitter))/100;
timer = timer - (k * j / RANDOM_SPREAD);
return timer;
}
struct in_addr
newprefix2inaddr (u_char *prefix_start, u_char prefix_masklen)
{
memset(&new_prefix, 0, sizeof (new_prefix));
memcpy(&new_prefix, prefix_start, (prefix_masklen & 0x3F) ?
((((prefix_masklen & 0x3F)-1)>>3)+1) : 0);
return new_prefix;
}

94
isisd/isis_misc.h Normal file
View File

@ -0,0 +1,94 @@
/*
* IS-IS Rout(e)ing protocol - isis_misc.h
* Miscellanous routines
*
* Copyright (C) 2001,2002 Sampo Saaristo
* Tampere University of Technology
* Institute of Communications Engineering
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public Licenseas published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _ZEBRA_ISIS_MISC_H
#define _ZEBRA_ISIS_MISC_H
int dotformat2buff (u_char *, u_char *);
int string2circuit_t (u_char *);
const char *circuit_t2string (int);
const char *syst2string (int);
struct in_addr newprefix2inaddr (u_char *prefix_start, u_char prefix_masklen);
/*
* Converting input to memory stored format
* return value of 0 indicates wrong input
*/
int dotformat2buff (u_char *, u_char *);
int sysid2buff (u_char *, u_char *);
/*
* Printing functions
*/
char *isonet_print (u_char *, int len);
char *sysid_print (u_char *);
char *snpa_print (u_char *);
char *rawlspid_print (u_char *);
char *time2string (u_int32_t);
/* typedef struct nlpids nlpids; */
char *nlpid2string (struct nlpids *);
/*
* misc functions
*/
int speaks (struct nlpids *nlpids, int family);
unsigned long isis_jitter (unsigned long timer, unsigned long jitter);
/*
* macros
*/
#define GETSYSID(A,L) (A->area_addr + (A->addr_len - (L + 1)))
/* staticly assigned vars for printing purposes */
struct in_addr new_prefix;
/* len of xxxx.xxxx.xxxx + place for #0 termination */
char sysid[15];
/* len of xxxx.xxxx.xxxx + place for #0 termination */
char snpa[15];
/* len of xx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xx */
char isonet[51];
/* + place for #0 termination */
/* len of xxxx.xxxx.xxxx.xx.xx + place for #0 termination */
char lspid[21];
/* len of xxYxxMxWxdxxhxxmxxs + place for #0 termination */
char datestring[20];
char nlpidstring[30];
/* used for calculating nice string representation instead of plain seconds */
#define SECS_PER_MINUTE 60
#define SECS_PER_HOUR 3600
#define SECS_PER_DAY 86400
#define SECS_PER_WEEK 604800
#define SECS_PER_MONTH 2628000
#define SECS_PER_YEAR 31536000
enum {
ISIS_UI_LEVEL_BRIEF,
ISIS_UI_LEVEL_DETAIL,
ISIS_UI_LEVEL_EXTENSIVE,
};
#endif

622
isisd/isis_network.c Normal file
View File

@ -0,0 +1,622 @@
/*
* IS-IS Rout(e)ing protocol - isis_network.c
*
* Copyright (C) 2001,2002 Sampo Saaristo
* Tampere University of Technology
* Institute of Communications Engineering
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public Licenseas published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <zebra.h>
#include <net/ethernet.h> /* the L2 protocols */
#include "log.h"
#include "stream.h"
#include "if.h"
#include "isisd/dict.h"
#include "isisd/include-netbsd/iso.h"
#include "isisd/isis_constants.h"
#include "isisd/isis_common.h"
#include "isisd/isis_circuit.h"
#include "isisd/isis_flags.h"
#include "isisd/isisd.h"
#include "isisd/isis_constants.h"
#include "isisd/isis_circuit.h"
#include "isisd/isis_network.h"
/*
* On linux we can use the packet(7) sockets, in other OSs we have to do with
* Berkley Packet Filter (BPF). Please tell me if you can think of a better
* way...
*/
#ifdef GNU_LINUX
#include <netpacket/packet.h>
#else
#include <sys/time.h>
#include <sys/ioctl.h>
#include <net/bpf.h>
struct bpf_insn llcfilter[] = {
BPF_STMT(BPF_LD+BPF_B+BPF_ABS, ETHER_HDR_LEN), /* check first byte */
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ISO_SAP, 0, 5),
BPF_STMT(BPF_LD+BPF_B+BPF_ABS, ETHER_HDR_LEN+1),
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ISO_SAP, 0, 3), /* check second byte */
BPF_STMT(BPF_LD+BPF_B+BPF_ABS, ETHER_HDR_LEN+2),
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x03, 0, 1), /* check third byte */
BPF_STMT(BPF_RET+BPF_K, (u_int)-1),
BPF_STMT(BPF_RET+BPF_K, 0)
};
int readblen = 0;
u_char *readbuff = NULL;
#endif /* GNU_LINUX */
/*
* Table 9 - Architectural constans for use with ISO 8802 subnetworks
* ISO 10589 - 8.4.8
*/
u_char ALL_L1_ISS[6] = {0x01, 0x80, 0xC2, 0x00, 0x00, 0x14};
u_char ALL_L2_ISS[6] = {0x01, 0x80, 0xC2, 0x00, 0x00, 0x15};
u_char ALL_ISS[6] = {0x09, 0x00, 0x2B, 0x00, 0x00, 0x05};
u_char ALL_ESS[6] = {0x09, 0x00, 0x2B, 0x00, 0x00, 0x04};
#ifdef GNU_LINUX
static char discard_buff[8192];
#endif
static char sock_buff[8192];
/*
* if level is 0 we are joining p2p multicast
* FIXME: and the p2p multicast being ???
*/
#ifdef GNU_LINUX
int
isis_multicast_join (int fd, int registerto, int if_num)
{
struct packet_mreq mreq;
memset(&mreq, 0, sizeof(mreq));
mreq.mr_ifindex = if_num;
if (registerto) {
mreq.mr_type = PACKET_MR_MULTICAST;
mreq.mr_alen = ETH_ALEN;
if (registerto == 1)
memcpy (&mreq.mr_address, ALL_L1_ISS, ETH_ALEN);
else if (registerto == 2)
memcpy (&mreq.mr_address, ALL_L2_ISS, ETH_ALEN);
else if (registerto == 3)
memcpy (&mreq.mr_address, ALL_ISS, ETH_ALEN);
else
memcpy (&mreq.mr_address, ALL_ESS, ETH_ALEN);
} else {
mreq.mr_type = PACKET_MR_ALLMULTI;
}
#ifdef EXTREME_DEBUG
zlog_info ("isis_multicast_join(): fd=%d, reg_to=%d, if_num=%d, "
"address = %02x:%02x:%02x:%02x:%02x:%02x",
fd, registerto, if_num, mreq.mr_address[0], mreq.mr_address[1],
mreq.mr_address[2], mreq.mr_address[3],mreq.mr_address[4],
mreq.mr_address[5]);
#endif /* EXTREME_DEBUG */
if (setsockopt (fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq,
sizeof (struct packet_mreq))) {
zlog_warn ("isis_multicast_join(): setsockopt(): %s", strerror (errno));
return ISIS_WARNING;
}
return ISIS_OK;
}
int
open_packet_socket (struct isis_circuit *circuit)
{
struct sockaddr_ll s_addr;
int fd, retval = ISIS_OK;
fd = socket (PF_PACKET, SOCK_DGRAM, htons (ETH_P_ALL));
if (fd < 0) {
zlog_warn ("open_packet_socket(): socket() failed %s", strerror (errno));
return ISIS_WARNING;
}
/*
* Bind to the physical interface
*/
memset(&s_addr, 0, sizeof (struct sockaddr_ll));
s_addr.sll_family = AF_PACKET;
s_addr.sll_protocol = htons (ETH_P_ALL);
s_addr.sll_ifindex = circuit->interface->ifindex;
if (bind (fd, (struct sockaddr*) (&s_addr),
sizeof(struct sockaddr_ll)) < 0) {
zlog_warn ("open_packet_socket(): bind() failed: %s", strerror(errno));
return ISIS_WARNING;
}
circuit->fd = fd;
if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
/*
* Join to multicast groups
* according to
* 8.4.2 - Broadcast subnetwork IIH PDUs
* FIXME: is there a case only one will fail??
*/
if (circuit->circuit_is_type & IS_LEVEL_1) {
/* joining ALL_L1_ISS */
retval = isis_multicast_join (circuit->fd, 1,
circuit->interface->ifindex);
/* joining ALL_ISS */
retval = isis_multicast_join (circuit->fd, 3,
circuit->interface->ifindex);
}
if (circuit->circuit_is_type & IS_LEVEL_2)
/* joining ALL_L2_ISS */
retval = isis_multicast_join (circuit->fd, 2,
circuit->interface->ifindex);
} else {
retval = isis_multicast_join (circuit->fd, 0, circuit->interface->ifindex);
}
return retval;
}
#else
int
open_bpf_dev (struct isis_circuit *circuit)
{
int i = 0, fd;
char bpfdev[128];
struct ifreq ifr;
u_int16_t blen;
int true = 1, false = 0;
struct timeval timeout;
struct bpf_program bpf_prog;
do {
(void)snprintf(bpfdev, sizeof(bpfdev), "/dev/bpf%d", i++);
fd = open(bpfdev, O_RDWR);
} while (fd < 0 && errno == EBUSY);
if (fd < 0) {
zlog_warn ("open_bpf_dev(): failed to create bpf socket: %s",
strerror (errno));
return ISIS_WARNING;
}
zlog_info ("Opened BPF device %s", bpfdev);
memcpy (ifr.ifr_name, circuit->interface->name, sizeof(ifr.ifr_name));
if (ioctl (fd, BIOCSETIF, (caddr_t)&ifr) < 0 ) {
zlog_warn ("open_bpf_dev(): failed to bind to interface: %s",
strerror (errno));
return ISIS_WARNING;
}
if (ioctl (fd, BIOCGBLEN, (caddr_t)&blen) < 0) {
zlog_warn ("failed to get BPF buffer len");
blen = circuit->interface->mtu;
}
readblen = blen;
if (readbuff == NULL)
readbuff = malloc (blen);
zlog_info ("BPF buffer len = %u", blen);
/* BPF(4): reads return immediately upon packet reception.
* Otherwise, a read will block until either the kernel
* buffer becomes full or a timeout occurs.
*/
if (ioctl (fd, BIOCIMMEDIATE, (caddr_t)&true) < 0) {
zlog_warn ("failed to set BPF dev to immediate mode");
}
/*
* We want to see only incoming packets
*/
if (ioctl (fd, BIOCSSEESENT, (caddr_t)&false) < 0) {
zlog_warn ("failed to set BPF dev to incoming only mode");
}
/*
* ...but all of them
*/
if (ioctl (fd, BIOCPROMISC, (caddr_t)&true) < 0) {
zlog_warn ("failed to set BPF dev to promiscuous mode");
}
/*
* If the buffer length is smaller than our mtu, lets try to increase it
*/
if (blen < circuit->interface->mtu) {
if (ioctl (fd, BIOCSBLEN, &circuit->interface->mtu) < 0) {
zlog_warn ("failed to set BPF buffer len (%u to %u)", blen,
circuit->interface->mtu);
}
}
/*
* Set a timeout parameter - hope this helps select()
*/
timeout.tv_sec = 600;
timeout.tv_usec = 0;
if (ioctl (fd, BIOCSRTIMEOUT, (caddr_t)&timeout) < 0) {
zlog_warn ("failed to set BPF device timeout");
}
/*
* And set the filter
*/
memset (&bpf_prog, 0, sizeof (struct bpf_program));
bpf_prog.bf_len = 8;
bpf_prog.bf_insns = &(llcfilter[0]);
if (ioctl (fd, BIOCSETF, (caddr_t)&bpf_prog) < 0) {
zlog_warn ("open_bpf_dev(): failed to install filter: %s",
strerror (errno));
return ISIS_WARNING;
}
assert (fd > 0);
circuit->fd = fd;
return ISIS_OK;
}
#endif /* GNU_LINUX */
/*
* Create the socket and set the tx/rx funcs
*/
int
isis_sock_init (struct isis_circuit *circuit)
{
int retval = ISIS_OK;
#ifdef GNU_LINUX
retval = open_packet_socket (circuit);
#else
retval = open_bpf_dev (circuit);
#endif
if (retval == ISIS_OK) {
if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
circuit->tx = isis_send_pdu_bcast;
circuit->rx = isis_recv_pdu_bcast;
}
else if (circuit->circ_type == CIRCUIT_T_P2P) {
circuit->tx = isis_send_pdu_p2p;
circuit->rx = isis_recv_pdu_p2p;
}
else {
zlog_warn ("isis_sock_init(): unknown circuit type");
retval = ISIS_WARNING;
}
}
return retval;
}
static inline int
llc_check (u_char *llc)
{
if(*llc != ISO_SAP || *(llc + 1) != ISO_SAP || *(llc +2) != 3)
return 0;
return 1;
}
#ifdef GNU_LINUX
int
isis_recv_pdu_bcast (struct isis_circuit *circuit, u_char *ssnpa)
{
int bytesread, addr_len;
struct sockaddr_ll s_addr;
u_char llc[LLC_LEN];
addr_len = sizeof (s_addr);
memset (&s_addr, 0, sizeof (struct sockaddr_ll));
bytesread = recvfrom (circuit->fd, (void *)&llc,
LLC_LEN, MSG_PEEK,
(struct sockaddr *)&s_addr, &addr_len);
if (bytesread < 0) {
zlog_warn ("isis_recv_packet_bcast(): fd %d, recvfrom (): %s",
circuit->fd, strerror (errno));
zlog_warn ("circuit is %s", circuit->interface->name);
zlog_warn ("circuit fd %d", circuit->fd);
zlog_warn ("bytesread %d", bytesread);
/* get rid of the packet */
bytesread = read (circuit->fd, discard_buff, sizeof (discard_buff));
return ISIS_WARNING;
}
/*
* Filtering by llc field, discard packets sent by this host (other circuit)
*/
if (!llc_check (llc) || s_addr.sll_pkttype == PACKET_OUTGOING) {
/* Read the packet into discard buff */
bytesread = read (circuit->fd, discard_buff, sizeof (discard_buff));
if (bytesread < 0)
zlog_warn ("isis_recv_pdu_bcast(): read() failed");
return ISIS_WARNING;
}
/* on lan we have to read to the static buff first */
bytesread = recvfrom (circuit->fd, sock_buff, circuit->interface->mtu, 0,
(struct sockaddr *)&s_addr, &addr_len);
/* then we lose the LLC */
memcpy (STREAM_DATA (circuit->rcv_stream),
sock_buff + LLC_LEN, bytesread - LLC_LEN);
circuit->rcv_stream->putp = bytesread - LLC_LEN;
circuit->rcv_stream->endp = bytesread - LLC_LEN;
memcpy (ssnpa, &s_addr.sll_addr, s_addr.sll_halen);
return ISIS_OK;
}
int
isis_recv_pdu_p2p (struct isis_circuit *circuit, u_char *ssnpa)
{
int bytesread, addr_len;
struct sockaddr_ll s_addr;
memset (&s_addr, 0, sizeof (struct sockaddr_ll));
addr_len = sizeof (s_addr);
/* we can read directly to the stream */
bytesread = recvfrom (circuit->fd, STREAM_DATA (circuit->rcv_stream),
circuit->interface->mtu, 0,
(struct sockaddr *)&s_addr, &addr_len);
if(s_addr.sll_pkttype == PACKET_OUTGOING) {
/* Read the packet into discard buff */
bytesread = read (circuit->fd, discard_buff, sizeof (discard_buff));
if (bytesread < 0)
zlog_warn ("isis_recv_pdu_p2p(): read() failed");
return ISIS_WARNING;
}
circuit->rcv_stream->putp = bytesread;
circuit->rcv_stream->endp = bytesread;
/* If we don't have protocol type 0x00FE which is
* ISO over GRE we exit with pain :)
*/
if (ntohs(s_addr.sll_protocol) != 0x00FE) {
zlog_warn ("isis_recv_pdu_p2p(): protocol mismatch(): %X",
ntohs(s_addr.sll_protocol));
return ISIS_WARNING;
}
memcpy (ssnpa, &s_addr.sll_addr, s_addr.sll_halen);
return ISIS_OK;
}
int
isis_send_pdu_bcast (struct isis_circuit *circuit, int level)
{
/* we need to do the LLC in here because of P2P circuits, which will
* not need it
*/
int written = 1;
struct sockaddr_ll sa;
stream_set_getp (circuit->snd_stream, 0);
memset (&sa, 0, sizeof (struct sockaddr_ll));
sa.sll_family = AF_PACKET;
sa.sll_protocol = htons (stream_get_endp(circuit->snd_stream)+LLC_LEN);
sa.sll_ifindex = circuit->interface->ifindex;
sa.sll_halen = ETH_ALEN;
if (level == 1)
memcpy (&sa.sll_addr, ALL_L1_ISS, ETH_ALEN);
else
memcpy (&sa.sll_addr, ALL_L2_ISS, ETH_ALEN);
/* on a broadcast circuit */
/* first we put the LLC in */
sock_buff[0] = 0xFE;
sock_buff[1] = 0xFE;
sock_buff[2] = 0x03;
/* then we copy the data */
memcpy (sock_buff + LLC_LEN, circuit->snd_stream->data,
stream_get_endp (circuit->snd_stream));
/* now we can send this */
written = sendto (circuit->fd, sock_buff,
circuit->snd_stream->putp + LLC_LEN, 0,
(struct sockaddr *)&sa, sizeof (struct sockaddr_ll));
return ISIS_OK;
}
int
isis_send_pdu_p2p (struct isis_circuit *circuit, int level)
{
int written = 1;
struct sockaddr_ll sa;
stream_set_getp (circuit->snd_stream, 0);
memset (&sa, 0, sizeof (struct sockaddr_ll));
sa.sll_family = AF_PACKET;
sa.sll_protocol = htons (stream_get_endp(circuit->snd_stream)+LLC_LEN);
sa.sll_ifindex = circuit->interface->ifindex;
sa.sll_halen = ETH_ALEN;
if (level == 1)
memcpy (&sa.sll_addr, ALL_L1_ISS, ETH_ALEN);
else
memcpy (&sa.sll_addr, ALL_L2_ISS, ETH_ALEN);
/* lets try correcting the protocol */
sa.sll_protocol = htons(0x00FE);
written = sendto (circuit->fd, circuit->snd_stream->data,
circuit->snd_stream->putp, 0, (struct sockaddr *)&sa,
sizeof (struct sockaddr_ll));
return ISIS_OK;
}
#else
int
isis_recv_pdu_bcast (struct isis_circuit *circuit, u_char *ssnpa)
{
int bytesread = 0, bytestoread, offset, one = 1;
struct bpf_hdr *bpf_hdr;
assert (circuit->fd > 0);
if (ioctl (circuit->fd, FIONREAD, (caddr_t)&bytestoread) < 0 ) {
zlog_warn ("ioctl() FIONREAD failed: %s", strerror (errno));
}
if (bytestoread) {
bytesread = read (circuit->fd, readbuff, readblen);
}
if (bytesread < 0) {
zlog_warn ("isis_recv_pdu_bcast(): read() failed: %s", strerror (errno));
return ISIS_WARNING;
}
if (bytesread == 0)
return ISIS_WARNING;
bpf_hdr = (struct bpf_hdr*)readbuff;
assert (bpf_hdr->bh_caplen == bpf_hdr->bh_datalen);
offset = bpf_hdr->bh_hdrlen + LLC_LEN + ETHER_HDR_LEN;
/* then we lose the BPF, LLC and ethernet headers */
memcpy (STREAM_DATA (circuit->rcv_stream),
readbuff + offset,
bpf_hdr->bh_caplen - LLC_LEN - ETHER_HDR_LEN);
circuit->rcv_stream->putp = bpf_hdr->bh_caplen - LLC_LEN - ETHER_HDR_LEN;
circuit->rcv_stream->endp = bpf_hdr->bh_caplen - LLC_LEN - ETHER_HDR_LEN;
circuit->rcv_stream->getp = 0;
memcpy (ssnpa, readbuff + bpf_hdr->bh_hdrlen + ETHER_ADDR_LEN,
ETHER_ADDR_LEN);
if (ioctl (circuit->fd, BIOCFLUSH, &one) < 0)
zlog_warn ("Flushing failed: %s", strerror (errno));
return ISIS_OK;
}
int
isis_recv_pdu_p2p (struct isis_circuit *circuit, u_char *ssnpa)
{
int bytesread;
bytesread = read (circuit->fd, STREAM_DATA(circuit->rcv_stream),
circuit->interface->mtu);
if (bytesread < 0) {
zlog_warn ("isis_recv_pdu_p2p(): read () failed: %s", strerror (errno));
return ISIS_WARNING;
}
circuit->rcv_stream->putp = bytesread;
circuit->rcv_stream->endp = bytesread;
return ISIS_OK;
}
int
isis_send_pdu_bcast (struct isis_circuit *circuit, int level)
{
struct ether_header *eth;
int written;
stream_set_getp (circuit->snd_stream, 0);
/*
* First the eth header
*/
eth = (struct ether_header *)sock_buff;
if (level == 1)
memcpy (eth->ether_dhost, ALL_L1_ISS, ETHER_ADDR_LEN);
else
memcpy (eth->ether_dhost, ALL_L2_ISS, ETHER_ADDR_LEN);
memcpy (eth->ether_shost, circuit->u.bc.snpa, ETHER_ADDR_LEN);
eth->ether_type = htons (stream_get_endp (circuit->snd_stream) + LLC_LEN);
/*
* Then the LLC
*/
sock_buff[ETHER_HDR_LEN] = ISO_SAP;
sock_buff[ETHER_HDR_LEN + 1] = ISO_SAP;
sock_buff[ETHER_HDR_LEN + 2] = 0x03;
/* then we copy the data */
memcpy (sock_buff + (LLC_LEN + ETHER_HDR_LEN), circuit->snd_stream->data,
stream_get_endp (circuit->snd_stream));
/* now we can send this */
written = write (circuit->fd, sock_buff,
circuit->snd_stream->putp + LLC_LEN + ETHER_HDR_LEN);
return ISIS_OK;
}
int
isis_send_pdu_p2p (struct isis_circuit *circuit, int level)
{
return ISIS_OK;
}
#endif /* GNU_LINUX */

37
isisd/isis_network.h Normal file
View File

@ -0,0 +1,37 @@
/*
* IS-IS Rout(e)ing protocol - isis_network.h
*
* Copyright (C) 2001,2002 Sampo Saaristo
* Tampere University of Technology
* Institute of Communications Engineering
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public Licenseas published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _ZEBRA_ISIS_NETWORK_H
#define _ZEBRA_ISIS_NETWORK_H
extern u_char ALL_L1_ISYSTEMS[];
extern u_char ALL_L2_ISYSTEMS[];
int isis_sock_init (struct isis_circuit *circuit);
int isis_recv_pdu_bcast (struct isis_circuit *circuit, u_char *ssnpa);
int isis_recv_pdu_p2p (struct isis_circuit *circuit, u_char *ssnpa);
int isis_send_pdu_bcast (struct isis_circuit *circuit, int level);
int isis_send_pdu_p2p (struct isis_circuit *circuit, int level);
#endif /* _ZEBRA_ISIS_NETWORK_H */

2478
isisd/isis_pdu.c Normal file

File diff suppressed because it is too large Load Diff

257
isisd/isis_pdu.h Normal file
View File

@ -0,0 +1,257 @@
/*
* IS-IS Rout(e)ing protocol - isis_pdu.h
* PDU processing
*
* Copyright (C) 2001,2002 Sampo Saaristo
* Tampere University of Technology
* Institute of Communications Engineering
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public Licenseas published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _ZEBRA_ISIS_PDU_H
#define _ZEBRA_ISIS_PDU_H
/*
* ISO 9542 - 7.5,7.6
*
* ES to IS Fixed Header
* +-------+-------+-------+-------+-------+-------+-------+-------+
* | Intradomain Routeing Protocol Discriminator |
* +-------+-------+-------+-------+-------+-------+-------+-------+
* | Length Indicator |
* +-------+-------+-------+-------+-------+-------+-------+-------+
* | Version/Protocol ID extension |
* +-------+-------+-------+-------+-------+-------+-------+-------+
* | Reserved = 0 |
* +-------+-------+-------+-------+-------+-------+-------+-------+
* | 0 | 0 | 0 | PDU Type |
* +-------+-------+-------+-------+-------+-------+-------+-------+
* | Holding Time | 2
* +-------+-------+-------+-------+-------+-------+-------+-------+
* | Checksum | 2
* +-------+-------+-------+-------+-------+-------+-------+-------+
*/
struct esis_fixed_hdr
{
u_char idrp;
u_char length;
u_char version;
u_char id_len;
u_char pdu_type;
u_int16_t holdtime;
u_int16_t checksum;
} __attribute__((packed));
#define ESIS_FIXED_HDR_LEN 9
#define ESH_PDU 2
#define ISH_PDU 4
#define RD_PDU 5
/*
* IS to IS Fixed Header
* +-------+-------+-------+-------+-------+-------+-------+-------+
* | Intradomain Routeing Protocol Discriminator |
* +-------+-------+-------+-------+-------+-------+-------+-------+
* | Length Indicator |
* +-------+-------+-------+-------+-------+-------+-------+-------+
* | Version/Protocol ID extension |
* +-------+-------+-------+-------+-------+-------+-------+-------+
* | R | R | R | PDU Type |
* +-------+-------+-------+-------+-------+-------+-------+-------+
* | Version |
* +-------+-------+-------+-------+-------+-------+-------+-------+
* | Reserved |
* +-------+-------+-------+-------+-------+-------+-------+-------+
* | Maximum Area Addresses |
* +-------+-------+-------+-------+-------+-------+-------+-------+
*/
struct isis_fixed_hdr
{
u_char idrp;
u_char length;
u_char version1;
u_char id_len;
u_char pdu_type;
u_char version2;
u_char reserved;
u_char max_area_addrs;
};
#define ISIS_FIXED_HDR_LEN 8
/*
* IS-IS PDU types.
*/
#define L1_LAN_HELLO 15
#define L2_LAN_HELLO 16
/*
* L1 and L2 LAN IS to IS Hello PDU header
* +-------+-------+-------+-------+-------+-------+-------+-------+
* | Reserved | Circuit Type | 1
* +-------+-------+-------+-------+-------+-------+-------+-------+
* + Source ID + id_len
* +-------+-------+-------+-------+-------+-------+-------+-------+
* | Holding Time | 2
* +-------+-------+-------+-------+-------+-------+-------+-------+
* | PDU Lenght | 2
* +-------+-------+-------+-------+-------+-------+-------+-------+
* | R | Priority | 1
* +-------+-------+-------+-------+-------+-------+-------+-------+
* | LAN ID | id_len + 1
* +-------+-------+-------+-------+-------+-------+-------+-------+
*/
struct isis_lan_hello_hdr {
u_char circuit_t;
u_char source_id[ISIS_SYS_ID_LEN];
u_int16_t hold_time;
u_int16_t pdu_len;
u_char prio;
u_char lan_id[ISIS_SYS_ID_LEN + 1];
} __attribute__((packed));
#define ISIS_LANHELLO_HDRLEN 19
#define P2P_HELLO 17
/*
* Point-to-point IS to IS hello PDU header
* +-------+-------+-------+-------+-------+-------+-------+-------+
* | Reserved | Circuit Type | 1
* +-------+-------+-------+-------+-------+-------+-------+-------+
* + Source ID + id_len
* +-------+-------+-------+-------+-------+-------+-------+-------+
* + Holding Time + 2
* +-------+-------+-------+-------+-------+-------+-------+-------+
* + PDU Lenght + 2
* +-------+-------+-------+-------+-------+-------+-------+-------+
* | Local Circuit ID | 1
* +-------+-------+-------+-------+-------+-------+-------+-------+
*/
struct isis_p2p_hello_hdr {
u_char circuit_t;
u_char source_id[ISIS_SYS_ID_LEN];
u_int16_t hold_time;
u_int16_t pdu_len;
u_char local_id;
} __attribute__((packed));
#define ISIS_P2PHELLO_HDRLEN 12
#define L1_LINK_STATE 18
#define L2_LINK_STATE 20
/*
* L1 and L2 IS to IS link state PDU header
* +-------+-------+-------+-------+-------+-------+-------+-------+
* + PDU Length + 2
* +-------+-------+-------+-------+-------+-------+-------+-------+
* + Remaining Lifetime + 2
* +-------+-------+-------+-------+-------+-------+-------+-------+
* | LSP ID | id_len + 2
* +-------+-------+-------+-------+-------+-------+-------+-------+
* + Sequence Number + 4
* +-------+-------+-------+-------+-------+-------+-------+-------+
* + Checksum + 2
* +-------+-------+-------+-------+-------+-------+-------+-------+
* | P | ATT |LSPDBOL| ISTYPE |
* +-------+-------+-------+-------+-------+-------+-------+-------+
*/
struct isis_link_state_hdr {
u_int16_t pdu_len;
u_int16_t rem_lifetime;
u_char lsp_id[ISIS_SYS_ID_LEN + 2];
u_int32_t seq_num;
u_int16_t checksum;
u_int8_t lsp_bits;
} __attribute__((packed));
#define ISIS_LSP_HDR_LEN 19
#define L1_COMPLETE_SEQ_NUM 24
#define L2_COMPLETE_SEQ_NUM 25
/*
* L1 and L2 IS to IS complete sequence numbers PDU header
* +-------+-------+-------+-------+-------+-------+-------+-------+
* + PDU Lenght + 2
* +-------+-------+-------+-------+-------+-------+-------+-------+
* + Source ID + id_len + 1
* +-------+-------+-------+-------+-------+-------+-------+-------+
* + Start LSP ID + id_len + 2
* +-------+-------+-------+-------+-------+-------+-------+-------+
* + End LSP ID + id_len + 2
* +-------+-------+-------+-------+-------+-------+-------+-------+
*/
struct isis_complete_seqnum_hdr {
u_int16_t pdu_len;
u_char source_id[ISIS_SYS_ID_LEN + 1];
u_char start_lsp_id[ISIS_SYS_ID_LEN + 2];
u_char stop_lsp_id[ISIS_SYS_ID_LEN + 2];
};
#define ISIS_CSNP_HDRLEN 25
#define L1_PARTIAL_SEQ_NUM 26
#define L2_PARTIAL_SEQ_NUM 27
/*
* L1 and L2 IS to IS partial sequence numbers PDU header
* +-------+-------+-------+-------+-------+-------+-------+-------+
* + PDU Length + 2
* +-------+-------+-------+-------+-------+-------+-------+-------+
* + Source ID + id_len + 1
* +---------------------------------------------------------------+
*/
struct isis_partial_seqnum_hdr {
u_int16_t pdu_len;
u_char source_id[ISIS_SYS_ID_LEN + 1];
};
#define ISIS_PSNP_HDRLEN 9
/*
* Function for receiving IS-IS PDUs
*/
int isis_receive (struct thread *thread);
/*
* calling arguments for snp_process ()
*/
#define ISIS_SNP_PSNP_FLAG 0
#define ISIS_SNP_CSNP_FLAG 1
/*
* Sending functions
*/
int send_lan_l1_hello (struct thread *thread);
int send_lan_l2_hello (struct thread *thread);
int send_p2p_hello (struct thread *thread);
int send_csnp (struct isis_circuit *circuit, int level);
int send_l1_csnp (struct thread *thread);
int send_l2_csnp (struct thread *thread);
int send_l1_psnp (struct thread *thread);
int send_l2_psnp (struct thread *thread);
int send_lsp (struct thread *thread);
int ack_lsp (struct isis_link_state_hdr *hdr,
struct isis_circuit *circuit, int level);
void fill_fixed_hdr (struct isis_fixed_hdr *hdr, u_char pdu_type);
int send_hello (struct isis_circuit *circuit, int level);
int authentication_check (struct isis_passwd *one,
struct isis_passwd *theother);
#endif /* _ZEBRA_ISIS_PDU_H */

615
isisd/isis_route.c Normal file
View File

@ -0,0 +1,615 @@
/*
* IS-IS Rout(e)ing protocol - isis_route.c
* Copyright (C) 2001,2002 Sampo Saaristo
* Tampere University of Technology
* Institute of Communications Engineering
*
* based on ../ospf6d/ospf6_route.[ch]
* by Yasuhiro Ohara
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public Licenseas published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <stdlib.h>
#include <stdio.h>
#include <zebra.h>
#include <net/ethernet.h>
#include "thread.h"
#include "linklist.h"
#include "vty.h"
#include "log.h"
#include "memory.h"
#include "prefix.h"
#include "hash.h"
#include "if.h"
#include "table.h"
#include "isis_constants.h"
#include "isis_common.h"
#include "dict.h"
#include "isisd.h"
#include "isis_misc.h"
#include "isis_adjacency.h"
#include "isis_circuit.h"
#include "isis_tlv.h"
#include "isis_pdu.h"
#include "isis_lsp.h"
#include "isis_spf.h"
#include "isis_route.h"
#include "isis_zebra.h"
extern struct isis *isis;
extern struct thread_master *master;
struct isis_nexthop *
isis_nexthop_create (struct in_addr *ip, unsigned int ifindex)
{
struct listnode *node;
struct isis_nexthop *nexthop;
for (node = listhead (isis->nexthops); node; nextnode (node)) {
nexthop = getdata (node);
if (nexthop->ifindex != ifindex)
continue;
if (ip && memcmp (&nexthop->ip, ip, sizeof (struct in_addr)) != 0)
continue;
nexthop->lock++;
return nexthop;
}
nexthop = XMALLOC (MTYPE_ISIS_NEXTHOP, sizeof (struct isis_nexthop));
if (!nexthop) {
zlog_err ("ISIS-Rte: isis_nexthop_create: out of memory!");
}
memset (nexthop, 0, sizeof (struct isis_nexthop));
nexthop->ifindex = ifindex;
memcpy (&nexthop->ip, ip, sizeof (struct in_addr));
listnode_add (isis->nexthops, nexthop);
nexthop->lock++;
return nexthop;
}
void
isis_nexthop_delete (struct isis_nexthop *nexthop)
{
nexthop->lock--;
if (nexthop->lock == 0) {
listnode_delete (isis->nexthops, nexthop);
XFREE (MTYPE_ISIS_NEXTHOP, nexthop);
}
return;
}
int
nexthoplookup (struct list *nexthops, struct in_addr *ip,
unsigned int ifindex)
{
struct listnode *node;
struct isis_nexthop *nh;
for (node = listhead (nexthops); node; nextnode (node)) {
nh = getdata (node);
if (!(memcmp (ip, &nh->ip, sizeof (struct in_addr))) &&
ifindex == nh->ifindex)
return 1;
}
return 0;
}
void
nexthop_print (struct isis_nexthop *nh)
{
u_char buf[BUFSIZ];
inet_ntop (AF_INET, &nh->ip, buf, BUFSIZ);
zlog_info (" %s %u", buf, nh->ifindex);
}
void
nexthops_print (struct list *nhs)
{
struct listnode *node;
for (node = listhead(nhs); node; nextnode (node))
nexthop_print (getdata (node));
}
#ifdef HAVE_IPV6
struct isis_nexthop6 *
isis_nexthop6_new (struct in6_addr *ip6, unsigned int ifindex)
{
struct isis_nexthop6 *nexthop6;
nexthop6 = XMALLOC (MTYPE_ISIS_NEXTHOP6, sizeof (struct isis_nexthop6));
if (!nexthop6) {
zlog_err ("ISIS-Rte: isis_nexthop_create6: out of memory!");
}
memset (nexthop6, 0, sizeof (struct isis_nexthop6));
nexthop6->ifindex = ifindex;
memcpy (&nexthop6->ip6, ip6, sizeof (struct in6_addr));
nexthop6->lock++;
return nexthop6;
}
struct isis_nexthop6 *
isis_nexthop6_create (struct in6_addr *ip6, unsigned int ifindex)
{
struct listnode *node;
struct isis_nexthop6 *nexthop6;
for (node = listhead (isis->nexthops6); node; nextnode (node)) {
nexthop6 = getdata (node);
if (nexthop6->ifindex != ifindex)
continue;
if (ip6 && memcmp (&nexthop6->ip6, ip6, sizeof (struct in6_addr)) != 0)
continue;
nexthop6->lock++;
return nexthop6;
}
nexthop6 = isis_nexthop6_new (ip6, ifindex);
return nexthop6;
}
void
isis_nexthop6_delete (struct isis_nexthop6 *nexthop6)
{
nexthop6->lock--;
if (nexthop6->lock == 0) {
listnode_delete (isis->nexthops6, nexthop6);
XFREE (MTYPE_ISIS_NEXTHOP6, nexthop6);
}
return;
}
int
nexthop6lookup (struct list *nexthops6, struct in6_addr *ip6,
unsigned int ifindex)
{
struct listnode *node;
struct isis_nexthop6 *nh6;
for (node = listhead (nexthops6); node; nextnode (node)) {
nh6 = getdata (node);
if (!(memcmp (ip6, &nh6->ip6, sizeof (struct in6_addr))) &&
ifindex == nh6->ifindex)
return 1;
}
return 0;
}
void
nexthop6_print (struct isis_nexthop6 *nh6)
{
u_char buf[BUFSIZ];
inet_ntop (AF_INET6, &nh6->ip6, buf, BUFSIZ);
zlog_info (" %s %u", buf, nh6->ifindex);
}
void
nexthops6_print (struct list *nhs6)
{
struct listnode *node;
for (node = listhead(nhs6); node; nextnode (node))
nexthop6_print (getdata (node));
}
#endif /* HAVE_IPV6 */
void
adjinfo2nexthop (struct list *nexthops, struct isis_adjacency *adj)
{
struct isis_nexthop *nh;
struct listnode *node;
struct in_addr *ipv4_addr;
if (adj->ipv4_addrs == NULL)
return;
for (node = listhead (adj->ipv4_addrs); node; nextnode (node)) {
ipv4_addr = getdata (node);
if (!nexthoplookup (nexthops, ipv4_addr,
adj->circuit->interface->ifindex)) {
nh = isis_nexthop_create (ipv4_addr,
adj->circuit->interface->ifindex);
listnode_add (nexthops, nh);
}
}
}
#ifdef HAVE_IPV6
void
adjinfo2nexthop6 (struct list *nexthops6, struct isis_adjacency *adj)
{
struct listnode *node;
struct in6_addr *ipv6_addr;
struct isis_nexthop6 *nh6;
if (!adj->ipv6_addrs)
return;
for (node = listhead (adj->ipv6_addrs); node; nextnode (node)) {
ipv6_addr = getdata (node);
if (!nexthop6lookup (nexthops6, ipv6_addr,
adj->circuit->interface->ifindex)) {
nh6 = isis_nexthop6_create (ipv6_addr,
adj->circuit->interface->ifindex);
listnode_add (nexthops6, nh6);
}
}
}
#endif /* HAVE_IPV6 */
struct isis_route_info *
isis_route_info_new (uint32_t cost, uint32_t depth, u_char family,
struct list *adjacencies)
{
struct isis_route_info *rinfo;
struct isis_adjacency *adj;
struct listnode *node;
rinfo = XMALLOC (MTYPE_ISIS_ROUTE_INFO, sizeof (struct isis_route_info));
if (!rinfo) {
zlog_err ("ISIS-Rte: isis_route_info_new: out of memory!");
return NULL;
}
memset (rinfo, 0, sizeof (struct isis_route_info));
if (family == AF_INET) {
rinfo->nexthops = list_new ();
for (node = listhead (adjacencies); node; nextnode (node)) {
adj = getdata (node);
adjinfo2nexthop (rinfo->nexthops, adj);
}
}
#ifdef HAVE_IPV6
if (family == AF_INET6) {
rinfo->nexthops6 = list_new ();
for (node = listhead (adjacencies); node; nextnode (node)) {
adj =getdata (node);
adjinfo2nexthop6 (rinfo->nexthops6, adj);
}
}
#endif /* HAVE_IPV6 */
rinfo->cost = cost;
rinfo->depth = depth;
return rinfo;
}
void
isis_route_info_delete (struct isis_route_info *route_info)
{
if (route_info->nexthops) {
route_info->nexthops->del = (void *)isis_nexthop_delete;
list_delete (route_info->nexthops);
}
#ifdef HAVE_IPV6
if (route_info->nexthops6) {
route_info->nexthops6->del = (void *)isis_nexthop6_delete;
list_delete (route_info->nexthops6);
}
#endif /* HAVE_IPV6 */
XFREE (MTYPE_ISIS_ROUTE_INFO, route_info);
}
int
isis_route_info_same_attrib (struct isis_route_info *new,
struct isis_route_info *old)
{
if (new->cost != old->cost)
return 0;
if (new->depth != old->depth)
return 0;
return 1;
}
int
isis_route_info_same (struct isis_route_info *new, struct isis_route_info *old,
u_char family)
{
struct listnode *node;
struct isis_nexthop *nexthop;
#ifdef HAVE_IPV6
struct isis_nexthop6 *nexthop6;
#endif /* HAVE_IPV6 */
if (!isis_route_info_same_attrib (new, old))
return 0;
if (family == AF_INET) {
for (node = listhead (new->nexthops); node; nextnode (node)) {
nexthop = (struct isis_nexthop *) getdata (node);
if (nexthoplookup (old->nexthops, &nexthop->ip, nexthop->ifindex) == 0)
return 0;
}
for (node = listhead (old->nexthops); node; nextnode (node)) {
nexthop = (struct isis_nexthop *) getdata (node);
if (nexthoplookup (new->nexthops, &nexthop->ip, nexthop->ifindex) == 0)
return 0;
}
}
#ifdef HAVE_IPV6
else if (family == AF_INET6) {
for (node = listhead (new->nexthops6); node; nextnode (node)) {
nexthop6 = (struct isis_nexthop6 *) getdata (node);
if (nexthop6lookup (old->nexthops6, &nexthop6->ip6,
nexthop6->ifindex) == 0)
return 0;
}
for (node = listhead (old->nexthops6); node; nextnode (node)) {
nexthop6 = (struct isis_nexthop6 *) getdata (node);
if (nexthop6lookup (new->nexthops6, &nexthop6->ip6,
nexthop6->ifindex) == 0)
return 0;
}
}
#endif /* HAVE_IPV6 */
return 1;
}
void
isis_nexthops_merge (struct list *new, struct list *old)
{
struct listnode *node;
struct isis_nexthop *nexthop;
for (node = listhead (new); node; nextnode (node)) {
nexthop = (struct isis_nexthop *) getdata (node);
if (nexthoplookup (old, &nexthop->ip, nexthop->ifindex))
continue;
listnode_add (old, nexthop);
nexthop->lock++;
}
}
#ifdef HAVE_IPV6
void
isis_nexthops6_merge (struct list *new, struct list *old)
{
struct listnode *node;
struct isis_nexthop6 *nexthop6;
for (node = listhead (new); node; nextnode (node)) {
nexthop6 = (struct isis_nexthop6 *) getdata (node);
if (nexthop6lookup (old, &nexthop6->ip6, nexthop6->ifindex))
continue;
listnode_add (old, nexthop6);
nexthop6->lock++;
}
}
#endif /* HAVE_IPV6 */
void
isis_route_info_merge (struct isis_route_info *new,
struct isis_route_info *old, u_char family)
{
if (family == AF_INET)
isis_nexthops_merge (new->nexthops, old->nexthops);
#ifdef HAVE_IPV6
else if (family == AF_INET6)
isis_nexthops6_merge (new->nexthops6, old->nexthops6);
#endif /* HAVE_IPV6 */
return;
}
int
isis_route_info_prefer_new (struct isis_route_info *new,
struct isis_route_info *old)
{
if (!CHECK_FLAG (old->flag, ISIS_ROUTE_FLAG_ACTIVE))
return 1;
if (new->cost < old->cost)
return 1;
return 0;
}
struct isis_route_info *
isis_route_create (struct prefix *prefix, u_int32_t cost, u_int32_t depth,
struct list *adjacencies, struct isis_area *area)
{
struct route_node *route_node;
struct isis_route_info *rinfo_new, *rinfo_old, *route_info = NULL;
u_char buff[BUFSIZ];
u_char family;
family = prefix->family;
/* for debugs */
prefix2str (prefix, buff, BUFSIZ);
rinfo_new = isis_route_info_new (cost, depth, family, adjacencies);
if (!rinfo_new) {
zlog_err ("ISIS-Rte (%s): isis_route_create: out of memory!",
area->area_tag);
return NULL;
}
if (family == AF_INET)
route_node = route_node_get (area->route_table, prefix);
#ifdef HAVE_IPV6
else if (family == AF_INET6)
route_node = route_node_get (area->route_table6, prefix);
#endif /* HAVE_IPV6 */
else
return NULL;
rinfo_old = route_node->info;
if (!rinfo_old) {
if (isis->debugs & DEBUG_RTE_EVENTS)
zlog_info ("ISIS-Rte (%s) route created: %s", area->area_tag, buff);
SET_FLAG(rinfo_new->flag, ISIS_ROUTE_FLAG_ACTIVE);
route_node->info = rinfo_new;
return rinfo_new;
}
if (isis->debugs & DEBUG_RTE_EVENTS)
zlog_info ("ISIS-Rte (%s) route already exists: %s", area->area_tag, buff);
if (isis_route_info_same (rinfo_new, rinfo_old, family)) {
if (isis->debugs & DEBUG_RTE_EVENTS)
zlog_info ("ISIS-Rte (%s) route unchanged: %s", area->area_tag, buff);
isis_route_info_delete (rinfo_new);
route_info = rinfo_old;
} else if (isis_route_info_same_attrib (rinfo_new, rinfo_old)) {
/* merge the nexthop lists */
if (isis->debugs & DEBUG_RTE_EVENTS)
zlog_info ("ISIS-Rte (%s) route changed (same attribs): %s",
area->area_tag, buff);
#ifdef EXTREME_DEBUG
zlog_info ("Old nexthops");
nexthops6_print (rinfo_old->nexthops6);
zlog_info ("New nexthops");
nexthops6_print (rinfo_new->nexthops6);
#endif /* EXTREME_DEBUG */
isis_route_info_merge (rinfo_new, rinfo_old, family);
isis_route_info_delete (rinfo_new);
route_info = rinfo_old;
} else {
if (isis_route_info_prefer_new (rinfo_new, rinfo_old)) {
if (isis->debugs & DEBUG_RTE_EVENTS)
zlog_info ("ISIS-Rte (%s) route changed: %s", area->area_tag, buff);
isis_route_info_delete (rinfo_old);
route_info = rinfo_new;
} else {
if (isis->debugs & DEBUG_RTE_EVENTS)
zlog_info ("ISIS-Rte (%s) route rejected: %s", area->area_tag, buff);
isis_route_info_delete (rinfo_new);
route_info = rinfo_old;
}
}
SET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ACTIVE);
route_node->info = route_info;
return route_info;
}
void
isis_route_delete (struct prefix *prefix, struct route_table *table)
{
struct route_node *rode;
struct isis_route_info *rinfo;
char buff[BUFSIZ];
/* for log */
prefix2str (prefix, buff, BUFSIZ);
rode = route_node_get (table, prefix);
rinfo = rode->info;
if (rinfo == NULL) {
if (isis->debugs & DEBUG_RTE_EVENTS)
zlog_info ("ISIS-Rte: tried to delete non-existant route %s", buff);
return;
}
if (CHECK_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC)) {
UNSET_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ACTIVE);
if (isis->debugs & DEBUG_RTE_EVENTS)
zlog_info ("ISIS-Rte: route delete %s", buff);
isis_zebra_route_update (prefix, rinfo);
}
isis_route_info_delete (rinfo);
rode->info = NULL;
return;
}
int
isis_route_validate (struct thread *thread)
{
struct isis_area *area;
struct route_table *table;
struct route_node *rode;
struct isis_route_info *rinfo;
u_char buff[BUFSIZ];
#ifdef HAVE_IPV6
int v6done = 0;
#endif
area = THREAD_ARG (thread);
table = area->route_table;
#ifdef HAVE_IPV6
again:
#endif
for (rode = route_top (table); rode; rode = route_next (rode)) {
if (rode->info == NULL)
continue;
rinfo = rode->info;
if (isis->debugs & DEBUG_RTE_EVENTS) {
prefix2str (&rode->p, buff, BUFSIZ);
zlog_info ("ISIS-Rte (%s): route validate: %s %s %s",
area->area_tag,
(CHECK_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC) ?
"sync'ed": "nosync"),
(CHECK_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ACTIVE) ?
"active": "inactive"), buff);
}
isis_zebra_route_update (&rode->p, rinfo);
if (!CHECK_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ACTIVE))
isis_route_delete (&rode->p, area->route_table);
}
#ifdef HAVE_IPV6
if (v6done)
return ISIS_OK;
table = area->route_table6;
v6done = 1;
goto again;
#endif
return ISIS_OK;
}

61
isisd/isis_route.h Normal file
View File

@ -0,0 +1,61 @@
/*
* IS-IS Rout(e)ing protocol - isis_route.h
*
* Copyright (C) 2001,2002 Sampo Saaristo
* Tampere University of Technology
* Institute of Communications Engineering
*
* based on ../ospf6d/ospf6_route.[ch]
* by Yasuhiro Ohara
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public Licenseas published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _ZEBRA_ISIS_ROUTE_H
#define _ZEBRA_ISIS_ROUTE_H
#ifdef HAVE_IPV6
struct isis_nexthop6 {
unsigned int ifindex;
struct in6_addr ip6;
unsigned int lock;
};
#endif /* HAVE_IPV6 */
struct isis_nexthop {
unsigned int ifindex;
struct in_addr ip;
unsigned int lock;
};
struct isis_route_info {
#define ISIS_ROUTE_FLAG_ZEBRA_SYNC 0x01
#define ISIS_ROUTE_FLAG_ACTIVE 0x02
u_char flag;
u_int32_t cost;
u_int32_t depth;
struct list *nexthops;
#ifdef HAVE_IPV6
struct list *nexthops6;
#endif /* HAVE_IPV6 */
};
struct isis_route_info *isis_route_create (struct prefix *prefix,
u_int32_t cost, u_int32_t depth,
struct list *adjacencies,
struct isis_area *area);
int isis_route_validate (struct thread *thread);
#endif /* _ZEBRA_ISIS_ROUTE_H */

100
isisd/isis_routemap.c Normal file
View File

@ -0,0 +1,100 @@
/*
* IS-IS Rout(e)ing protocol - isis_routemap.c
*
* Copyright (C) 2001,2002 Sampo Saaristo
* Tampere University of Technology
* Institute of Communications Engineering
*
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public Licenseas published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <stdlib.h>
#include <stdio.h>
#include <zebra.h>
#include <net/ethernet.h>
#include "thread.h"
#include "linklist.h"
#include "vty.h"
#include "log.h"
#include "memory.h"
#include "prefix.h"
#include "hash.h"
#include "if.h"
#include "table.h"
#include "routemap.h"
#include "isis_constants.h"
#include "isis_common.h"
#include "dict.h"
#include "isisd.h"
#include "isis_misc.h"
#include "isis_adjacency.h"
#include "isis_circuit.h"
#include "isis_tlv.h"
#include "isis_pdu.h"
#include "isis_lsp.h"
#include "isis_spf.h"
#include "isis_route.h"
#include "isis_zebra.h"
extern struct isis *isis;
void
isis_route_map_upd()
{
int i = 0;
if (!isis)
return;
for (i = 0; i <= ZEBRA_ROUTE_MAX; i++) {
if (isis->rmap[i].name)
isis->rmap[i].map = isis->rmap[i].map =
route_map_lookup_by_name (isis->rmap[i].name);
else
isis->rmap[i].map = NULL;
}
/* FIXME: do the address family sub-mode AF_INET6 here ? */
}
void
isis_route_map_event(route_map_event_t event, char *name)
{
int type;
if (!isis)
return;
for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
if (isis->rmap[type].name && isis->rmap[type].map &&
!strcmp (isis->rmap[type].name, name)) {
isis_distribute_list_update (type);
}
}
}
void
isis_route_map_init (void)
{
route_map_init ();
route_map_init_vty ();
route_map_add_hook (isis_route_map_upd);
route_map_delete_hook (isis_route_map_upd);
route_map_event_hook (isis_route_map_event);
}

1293
isisd/isis_spf.c Normal file

File diff suppressed because it is too large Load Diff

85
isisd/isis_spf.h Normal file
View File

@ -0,0 +1,85 @@
/*
* IS-IS Rout(e)ing protocol - isis_spf.h
* IS-IS Shortest Path First algorithm
*
* Copyright (C) 2001,2002 Sampo Saaristo
* Tampere University of Technology
* Institute of Communications Engineering
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public Licenseas published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _ZEBRA_ISIS_SPF_H
#define _ZEBRA_ISIS_SPF_H
enum vertextype {
VTYPE_PSEUDO_IS = 1,
VTYPE_NONPSEUDO_IS,
VTYPE_ES,
VTYPE_IPREACH_INTERNAL,
VTYPE_IPREACH_EXTERNAL
#ifdef HAVE_IPV6
,
VTYPE_IP6REACH_INTERNAL,
VTYPE_IP6REACH_EXTERNAL
#endif /* HAVE_IPV6 */
};
/*
* Triple <N, d(N), {Adj(N)}>
*/
struct isis_vertex
{
enum vertextype type;
union {
u_char id [ISIS_SYS_ID_LEN + 1];
struct prefix prefix;
} N;
struct isis_lsp *lsp;
u_int32_t d_N; /* d(N) Distance from this IS */
u_int16_t depth; /* The depth in the imaginary tree */
struct list *Adj_N; /* {Adj(N)} */
};
struct isis_spftree
{
struct thread *t_spf_periodic; /* periodic spf threads */
time_t lastrun; /* for scheduling */
int pending; /* already scheduled */
struct list *paths; /* the SPT */
struct list *tents; /* TENT */
u_int32_t timerun; /* statistics */
};
void spftree_area_init (struct isis_area *area);
int isis_spf_schedule (struct isis_area *area, int level);
void isis_spf_cmds_init (void);
#ifdef HAVE_IPV6
int isis_spf_schedule6 (struct isis_area *area, int level);
#endif
#endif /* _ZEBRA_ISIS_SPF_H */

1014
isisd/isis_tlv.c Normal file

File diff suppressed because it is too large Load Diff

268
isisd/isis_tlv.h Normal file
View File

@ -0,0 +1,268 @@
/*
* IS-IS Rout(e)ing protocol - isis_tlv.h
* IS-IS TLV related routines
*
* Copyright (C) 2001,2002 Sampo Saaristo
* Tampere University of Technology
* Institute of Communications Engineering
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public Licenseas published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _ZEBRA_ISIS_TLV_H
#define _ZEBRA_ISIS_TLV_H
/*
* Structures found in TLV's.
* this header is fully complient with
* draft-ietf-isis-wg-tlv-codepoints-02.txt
1. TLV Codepoints reserved
____________________________________________________
Name Value IIH LSP SNP Status
____________________________________________________
Area Addresses 1 y y n ISO 10589
IIS Neighbors 2 n y n ISO 10589
ES Neighbors 3 n y n ISO 10589
Part. DIS 4 n y n ISO 10589
Prefix Neighbors 5 n y n ISO 10589
IIS Neighbors 6 y n n ISO 10589
Padding 8 y n n ISO 10589
LSP Entries 9 n n y ISO 10589
Authentication 10 y y y ISO 10589
Opt. Checksum 12 y n y IETF-draft
LSPBufferSize 14 n y n ISO 10589 Rev 2 Draft
TE IIS Neigh. 22 n y n IETF-draft
DECnet Phase IV 42 y n n DEC (ancient)
IP Int. Reach 128 n y n RFC 1195
Prot. Supported 129 y y n RFC 1195
IP Ext. Address 130 n y n RFC 1195
IDRPI 131 n y y RFC 1195
IP Intf. Address 132 y y n RFC 1195
Illegal 133 n n n RFC 1195 (not used)
Router ID 134 n y n IETF-draft
TE IP. Reach 135 n y n IETF-draft
Dynamic Name 137 n y n RFC 2763
Nortel Proprietary 176 n y n
Nortel Proprietary 177 n y n
Restart TLV 211 y n n IETF-draft
MT-ISN 222 n y n IETF-draft
M-Topologies 229 y y n IETF-draft
IPv6 Intf. Addr. 232 y y n IETF-draft
MT IP. Reach 235 n y n IETF-draft
IPv6 IP. Reach 236 n y n IETF-draft
MT IPv6 IP. Reach 237 n y n IETF-draft
P2P Adjacency State 240 y n n IETF-draft
*/
#define AREA_ADDRESSES 1
#define IS_NEIGHBOURS 2
#define ES_NEIGHBOURS 3
#define PARTITION_DESIG_LEVEL2_IS 4
#define PREFIX_NEIGHBOURS 5
#define LAN_NEIGHBOURS 6
#define PADDING 8
#define LSP_ENTRIES 9
#define AUTH_INFO 10
#define CHECKSUM 12
#define TE_IS_NEIGHBOURS 22
#define IPV4_INT_REACHABILITY 128
#define IPV4_EXT_REACHABILITY 130
#define PROTOCOLS_SUPPORTED 129
#define IDRP_INFO 131
#define IPV4_ADDR 132
#define TE_ROUTER_ID 134
#define TE_IPV4_REACHABILITY 135
#define DYNAMIC_HOSTNAME 137
#define IPV6_REACHABILITY 236
#define IPV6_ADDR 232
#define WAY3_HELLO 240
#define IS_NEIGHBOURS_LEN (ISIS_SYS_ID_LEN + 5)
#define LAN_NEIGHBOURS_LEN 6
#define LSP_ENTRIES_LEN (10 + ISIS_SYS_ID_LEN) /* FIXME: should be entry */
#define IPV4_REACH_LEN 12
#define IPV6_REACH_LEN 22
/* struct for neighbor */
struct is_neigh{
struct metric metrics;
u_char neigh_id[ISIS_SYS_ID_LEN + 1];
};
/* struct for te is neighbor */
struct te_is_neigh{
u_char neigh_id[ISIS_SYS_ID_LEN + 1];
u_char te_metric[3];
u_char sub_tlvs_length;
};
/* struct for es neighbors */
struct es_neigh{
struct metric metrics;
/* approximate position of first, we use the
* length ((uchar*)metric-1) to know all */
u_char first_es_neigh[ISIS_SYS_ID_LEN];
};
struct partition_desig_level2_is{
struct list *isis_system_ids;
};
/* struct for lan neighbors */
struct lan_neigh{
u_char LAN_addr[6];
};
/* struct for LSP entry */
struct lsp_entry {
u_int16_t rem_lifetime;
u_char lsp_id[ISIS_SYS_ID_LEN + 2];
u_int32_t seq_num;
u_int16_t checksum;
} __attribute__((packed));
/* struct for checksum */
struct checksum {
u_int16_t checksum;
};
/* ipv4 reachability */
struct ipv4_reachability {
struct metric metrics;
struct in_addr prefix;
struct in_addr mask;
};
/* te router id */
struct te_router_id {
struct in_addr id;
};
/* te ipv4 reachability */
struct te_ipv4_reachability {
u_int32_t te_metric;
u_char control;
u_char prefix_start; /* since this is variable length by nature it only */
}; /* points to an approximate location */
struct idrp_info {
u_char len;
u_char *value;
};
#ifdef HAVE_IPV6
struct ipv6_reachability {
u_int32_t metric;
u_char control_info;
u_char prefix_len;
u_char prefix[16];
};
#endif /* HAVE_IPV6 */
/* bits in control_info */
#define CTRL_INFO_DIRECTION 0x80
#define DIRECTION_UP 0
#define DIRECTION_DOWN 1
#define CTRL_INFO_DISTRIBUTION 0x40
#define DISTRIBUTION_INTERNAL 0
#define DISTRIBUTION_EXTERNAL 1
#define CTRL_INFO_SUBTLVS 0x20
/*
* Pointer to each tlv type, filled by parse_tlvs()
*/
struct tlvs {
struct list *area_addrs;
struct list *is_neighs;
struct list *te_is_neighs;
struct list *es_neighs;
struct list *lsp_entries;
struct list *prefix_neighs;
struct list *lan_neighs;
struct checksum *checksum;
struct nlpids *nlpids;
struct list *ipv4_addrs;
struct list *ipv4_int_reachs;
struct list *ipv4_ext_reachs;
struct list *te_ipv4_reachs;
struct hostname *hostname;
struct te_router_id *router_id;
#ifdef HAVE_IPV6
struct list *ipv6_addrs;
struct list *ipv6_reachs;
#endif
struct isis_passwd auth_info;
};
/*
* Own definitions - used to bitmask found and expected
*/
#define TLVFLAG_AREA_ADDRS (1<<0)
#define TLVFLAG_IS_NEIGHS (1<<1)
#define TLVFLAG_ES_NEIGHS (1<<2)
#define TLVFLAG_PARTITION_DESIG_LEVEL2_IS (1<<3)
#define TLVFLAG_PREFIX_NEIGHS (1<<4)
#define TLVFLAG_LAN_NEIGHS (1<<5)
#define TLVFLAG_LSP_ENTRIES (1<<6)
#define TLVFLAG_PADDING (1<<7)
#define TLVFLAG_AUTH_INFO (1<<8)
#define TLVFLAG_IPV4_INT_REACHABILITY (1<<9)
#define TLVFLAG_NLPID (1<<10)
#define TLVFLAG_IPV4_EXT_REACHABILITY (1<<11)
#define TLVFLAG_IPV4_ADDR (1<<12)
#define TLVFLAG_DYN_HOSTNAME (1<<13)
#define TLVFLAG_IPV6_ADDR (1<<14)
#define TLVFLAG_IPV6_REACHABILITY (1<<15)
#define TLVFLAG_TE_IS_NEIGHS (1<<16)
#define TLVFLAG_TE_IPV4_REACHABILITY (1<<17)
#define TLVFLAG_3WAY_HELLO (1<<18)
#define TLVFLAG_TE_ROUTER_ID (1<<19)
#define TLVFLAG_CHECKSUM (1<<20)
void init_tlvs (struct tlvs *tlvs, uint32_t expected);
void free_tlvs (struct tlvs *tlvs);
int parse_tlvs (char *areatag, u_char *stream, int size, u_int32_t *expected,
u_int32_t *found, struct tlvs *tlvs);
void free_tlv (void *val);
int tlv_add_area_addrs (struct list *area_addrs, struct stream *stream);
int tlv_add_is_neighs (struct list *is_neighs, struct stream *stream);
int tlv_add_lan_neighs (struct list *lan_neighs, struct stream *stream);
int tlv_add_nlpid (struct nlpids *nlpids, struct stream *stream);
int tlv_add_checksum (struct checksum *checksum,
struct stream *stream);
int tlv_add_authinfo (char auth_type, char authlen, char *auth_value,
struct stream *stream);
int tlv_add_ip_addrs (struct list *ip_addrs, struct stream *stream);
int tlv_add_dynamic_hostname (struct hostname *hostname,struct stream *stream);
int tlv_add_lsp_entries (struct list *lsps, struct stream *stream);
int tlv_add_ipv4_reachs (struct list *ipv4_reachs, struct stream *stream);
#ifdef HAVE_IPV6
int tlv_add_ipv6_addrs (struct list *ipv6_addrs, struct stream *stream);
int tlv_add_ipv6_reachs (struct list *ipv6_reachs, struct stream *stream);
#endif /* HAVE_IPV6 */
int tlv_add_padding (struct stream *stream);
#endif /* _ZEBRA_ISIS_TLV_H */

592
isisd/isis_zebra.c Normal file
View File

@ -0,0 +1,592 @@
/*
* IS-IS Rout(e)ing protocol - isis_zebra.c
*
* Copyright (C) 2001,2002 Sampo Saaristo
* Tampere University of Technology
* Institute of Communications Engineering
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public Licenseas published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <zebra.h>
#include <net/ethernet.h>
#include "thread.h"
#include "command.h"
#include "memory.h"
#include "log.h"
#include "if.h"
#include "network.h"
#include "prefix.h"
#include "zclient.h"
#include "stream.h"
#include "linklist.h"
#include "isisd/isis_constants.h"
#include "isisd/isis_common.h"
#include "isisd/isis_circuit.h"
#include "isisd/isis_csm.h"
#include "isisd/isis_route.h"
#include "isisd/isis_zebra.h"
struct zclient *zclient = NULL;
extern struct thread_master *master;
int
isis_zebra_if_add (int command, struct zclient *zclient, zebra_size_t length)
{
struct interface *ifp;
ifp = zebra_interface_add_read (zclient->ibuf);
zlog_info ("Zebra I/F add: %s index %d flags %ld metric %d mtu %d",
ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
if (if_is_up (ifp))
isis_csm_state_change (IF_UP_FROM_Z, circuit_scan_by_ifp (ifp), ifp);
return 0;
}
int
isis_zebra_if_del (int command, struct zclient *zclient, zebra_size_t length)
{
struct interface *ifp;
struct stream *s;
s = zclient->ibuf;
ifp = zebra_interface_state_read (s);
if (!ifp)
return 0;
if (if_is_up (ifp))
zlog_warn ("Zebra: got delete of %s, but interface is still up",
ifp->name);
zlog_info ("Zebra I/F delete: %s index %d flags %ld metric %d mtu %d",
ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
if_delete (ifp);
isis_csm_state_change (IF_DOWN_FROM_Z, circuit_scan_by_ifp (ifp), ifp);
return 0;
}
struct interface *
zebra_interface_if_lookup (struct stream *s)
{
struct interface *ifp;
u_char ifname_tmp[INTERFACE_NAMSIZ];
/* Read interface name. */
stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
/* Lookup this by interface index. */
ifp = if_lookup_by_name (ifname_tmp);
/* If such interface does not exist, indicate an error */
if (!ifp)
return NULL;
return ifp;
}
void
zebra_interface_if_set_value (struct stream *s, struct interface *ifp)
{
/* Read interface's index. */
ifp->ifindex = stream_getl (s);
/* Read interface's value. */
ifp->flags = stream_getl (s);
ifp->metric = stream_getl (s);
ifp->mtu = stream_getl (s);
ifp->bandwidth = stream_getl (s);
}
int
isis_zebra_if_state_up (int command, struct zclient *zclient,
zebra_size_t length)
{
struct interface *ifp;
ifp = zebra_interface_if_lookup (zclient->ibuf);
if (!ifp)
return 0;
if (if_is_up (ifp)) {
zebra_interface_if_set_value (zclient->ibuf, ifp);
isis_circuit_update_params (circuit_scan_by_ifp (ifp), ifp);
return 0;
}
zebra_interface_if_set_value (zclient->ibuf, ifp);
isis_csm_state_change (IF_UP_FROM_Z, circuit_scan_by_ifp (ifp), ifp);
return 0;
}
int
isis_zebra_if_state_down (int command, struct zclient *zclient,
zebra_size_t length)
{
struct interface *ifp;
ifp = zebra_interface_if_lookup (zclient->ibuf);
if (ifp == NULL)
return 0;
if (if_is_up (ifp)) {
zebra_interface_if_set_value (zclient->ibuf, ifp);
isis_csm_state_change (IF_DOWN_FROM_Z, circuit_scan_by_ifp (ifp), ifp);
}
return 0;
}
int
isis_zebra_if_address_add (int command, struct zclient *zclient,
zebra_size_t length)
{
struct connected *c;
struct prefix *p;
u_char buf[BUFSIZ];
c = zebra_interface_address_add_read (zclient->ibuf);
if (c == NULL)
return 0;
p = c->address;
prefix2str (p, buf, BUFSIZ);
#ifdef EXTREME_DEBUG
if (p->family == AF_INET)
zlog_info ("connected IP address %s", buf);
#ifdef HAVE_IPV6
if (p->family == AF_INET6)
zlog_info ("connected IPv6 address %s", buf);
#endif /* HAVE_IPV6 */
#endif /* EXTREME_DEBUG */
isis_circuit_add_addr (circuit_scan_by_ifp (c->ifp), c);
return 0;
}
int
isis_zebra_if_address_del (int command, struct zclient *client,
zebra_size_t length)
{
struct connected *c;
struct interface *ifp;
c = zebra_interface_address_delete_read (zclient->ibuf);
if (c == NULL)
return 0;
ifp = c->ifp;
connected_free (c);
isis_circuit_del_addr (circuit_scan_by_ifp (ifp), c);
return 0;
}
void
isis_zebra_route_add_ipv4 (struct prefix *prefix,
struct isis_route_info *route_info)
{
u_char message, flags;
int psize;
struct stream *stream;
struct isis_nexthop *nexthop;
struct listnode *node;
if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC))
return;
if (zclient->redist[ZEBRA_ROUTE_ISIS]) {
message = 0;
flags = 0;
SET_FLAG (message, ZAPI_MESSAGE_NEXTHOP);
SET_FLAG (message, ZAPI_MESSAGE_METRIC);
SET_FLAG (message, ZAPI_MESSAGE_DISTANCE);
stream = zclient->obuf;
stream_reset (stream);
/* Length place holder. */
stream_putw (stream, 0);
/* command */
stream_putc (stream, ZEBRA_IPV4_ROUTE_ADD);
/* type */
stream_putc (stream, ZEBRA_ROUTE_ISIS);
/* flags */
stream_putc (stream, flags);
/* message */
stream_putc (stream, message);
/* prefix information */
psize = PSIZE (prefix->prefixlen);
stream_putc (stream, prefix->prefixlen);
stream_write (stream, (u_char *)&prefix->u.prefix4, psize);
stream_putc (stream, listcount (route_info->nexthops));
/* Nexthop, ifindex, distance and metric information */
for (node = listhead (route_info->nexthops); node; nextnode (node)) {
nexthop = getdata (node);
/* FIXME: can it be ? */
if (nexthop->ip.s_addr != INADDR_ANY) {
stream_putc (stream, ZEBRA_NEXTHOP_IPV4);
stream_put_in_addr (stream, &nexthop->ip);
} else {
stream_putc (stream, ZEBRA_NEXTHOP_IFINDEX);
stream_putl (stream, nexthop->ifindex);
}
}
if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
stream_putc (stream, route_info->depth);
if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
stream_putl (stream, route_info->cost);
stream_putw_at (stream, 0, stream_get_endp (stream));
writen (zclient->sock, stream->data, stream_get_endp (stream));
}
}
void
isis_zebra_route_del_ipv4 (struct prefix *prefix,
struct isis_route_info *route_info)
{
struct zapi_ipv4 api;
struct prefix_ipv4 prefix4;
if (zclient->redist[ZEBRA_ROUTE_ISIS]) {
api.type = ZEBRA_ROUTE_ISIS;
api.flags = 0;
api.message = 0;
prefix4.family = AF_INET;
prefix4.prefixlen = prefix->prefixlen;
prefix4.prefix = prefix->u.prefix4;
zapi_ipv4_delete (zclient, &prefix4, &api);
}
return;
}
#ifdef HAVE_IPV6
void
isis_zebra_route_add_ipv6 (struct prefix *prefix,
struct isis_route_info *route_info)
{
struct zapi_ipv6 api;
struct in6_addr **nexthop_list;
unsigned int *ifindex_list;
struct isis_nexthop6 *nexthop6;
int i, size;
struct listnode *node;
struct prefix_ipv6 prefix6;
if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC))
return;
api.type = ZEBRA_ROUTE_ISIS;
api.flags = 0;
api.message = 0;
SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
api.metric = route_info->cost;
#if 0
SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
api.distance = route_info->depth;
#endif
api.nexthop_num = listcount (route_info->nexthops6);
api.ifindex_num = listcount (route_info->nexthops6);
/* allocate memory for nexthop_list */
size = sizeof (struct isis_nexthop6 *) * listcount (route_info->nexthops6);
nexthop_list = (struct in6_addr **) XMALLOC (MTYPE_ISIS_TMP, size);
if (!nexthop_list) {
zlog_err ("isis_zebra_add_route_ipv6: out of memory!");
return;
}
/* allocate memory for ifindex_list */
size = sizeof (unsigned int) * listcount (route_info->nexthops6);
ifindex_list = (unsigned int *) XMALLOC (MTYPE_ISIS_TMP, size);
if (!ifindex_list) {
zlog_err ("isis_zebra_add_route_ipv6: out of memory!");
XFREE (MTYPE_ISIS_TMP, nexthop_list);
return;
}
/* for each nexthop */
i = 0;
for (node = listhead (route_info->nexthops6); node; nextnode (node)) {
nexthop6 = getdata (node);
if (!IN6_IS_ADDR_LINKLOCAL (&nexthop6->ip6) &&
!IN6_IS_ADDR_UNSPECIFIED (&nexthop6->ip6)) {
api.nexthop_num--;
api.ifindex_num--;
continue;
}
nexthop_list[i] = &nexthop6->ip6;
ifindex_list[i] = nexthop6->ifindex;
i++;
}
api.nexthop = nexthop_list;
api.ifindex = ifindex_list;
if (api.nexthop_num && api.ifindex_num) {
prefix6.family = AF_INET6;
prefix6.prefixlen = prefix->prefixlen;
memcpy (&prefix6.prefix, &prefix->u.prefix6, sizeof (struct in6_addr));
zapi_ipv6_add (zclient, &prefix6, &api);
SET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC);
}
XFREE (MTYPE_ISIS_TMP, nexthop_list);
XFREE (MTYPE_ISIS_TMP, ifindex_list);
return;
}
void
isis_zebra_route_del_ipv6 (struct prefix *prefix,
struct isis_route_info *route_info)
{
struct zapi_ipv6 api;
struct in6_addr **nexthop_list;
unsigned int *ifindex_list;
struct isis_nexthop6 *nexthop6;
int i, size;
struct listnode *node;
struct prefix_ipv6 prefix6;
if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC))
return;
api.type = ZEBRA_ROUTE_ISIS;
api.flags = 0;
api.message = 0;
SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
api.nexthop_num = listcount (route_info->nexthops6);
api.ifindex_num = listcount (route_info->nexthops6);
/* allocate memory for nexthop_list */
size = sizeof (struct isis_nexthop6 *) * listcount (route_info->nexthops6);
nexthop_list = (struct in6_addr **) XMALLOC (MTYPE_ISIS_TMP, size);
if (!nexthop_list) {
zlog_err ("isis_zebra_route_del_ipv6: out of memory!");
return;
}
/* allocate memory for ifindex_list */
size = sizeof (unsigned int) * listcount (route_info->nexthops6);
ifindex_list = (unsigned int *) XMALLOC (MTYPE_ISIS_TMP, size);
if (!ifindex_list) {
zlog_err ("isis_zebra_route_del_ipv6: out of memory!");
XFREE (MTYPE_ISIS_TMP, nexthop_list);
return;
}
/* for each nexthop */
i = 0;
for (node = listhead (route_info->nexthops6); node; nextnode (node)) {
nexthop6 = getdata (node);
if (!IN6_IS_ADDR_LINKLOCAL (&nexthop6->ip6) &&
!IN6_IS_ADDR_UNSPECIFIED (&nexthop6->ip6)) {
api.nexthop_num--;
api.ifindex_num--;
continue;
}
nexthop_list[i] = &nexthop6->ip6;
ifindex_list[i] = nexthop6->ifindex;
i++;
}
api.nexthop = nexthop_list;
api.ifindex = ifindex_list;
if (api.nexthop_num && api.ifindex_num) {
prefix6.family = AF_INET6;
prefix6.prefixlen = prefix->prefixlen;
memcpy (&prefix6.prefix, &prefix->u.prefix6, sizeof (struct in6_addr));
zapi_ipv6_delete (zclient, &prefix6, &api);
UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC);
}
XFREE (MTYPE_ISIS_TMP, nexthop_list);
XFREE (MTYPE_ISIS_TMP, ifindex_list);
}
#endif /* HAVE_IPV6 */
void
isis_zebra_route_update (struct prefix *prefix,
struct isis_route_info *route_info)
{
if (zclient->sock < 0)
return;
if (!zclient->redist[ZEBRA_ROUTE_ISIS])
return;
if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ACTIVE)) {
if (prefix->family == AF_INET)
isis_zebra_route_add_ipv4 (prefix, route_info);
#ifdef HAVE_IPV6
else if (prefix->family == AF_INET6)
isis_zebra_route_add_ipv6 (prefix, route_info);
#endif /* HAVE_IPV6 */
} else {
if (prefix->family == AF_INET)
isis_zebra_route_del_ipv4 (prefix, route_info);
#ifdef HAVE_IPV6
else if (prefix->family == AF_INET6)
isis_zebra_route_del_ipv6 (prefix, route_info);
#endif /* HAVE_IPV6 */
}
return;
}
int
isis_zebra_read_ipv4 (int command, struct zclient *zclient,
zebra_size_t length)
{
struct stream *stream;
struct zapi_ipv4 api;
struct prefix_ipv4 p;
unsigned long ifindex;
struct in_addr nexthop;
stream = zclient->ibuf;
memset (&p, 0, sizeof (struct prefix_ipv4));
ifindex = 0;
api.type = stream_getc (stream);
api.flags = stream_getc (stream);
api.message = stream_getc (stream);
p.family = AF_INET;
p.prefixlen = stream_getc (stream);
stream_get (&p.prefix, stream, PSIZE (p.prefixlen));
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP)) {
api.nexthop_num = stream_getc (stream);
nexthop.s_addr = stream_get_ipv4 (stream);
}
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX)) {
api.ifindex_num = stream_getc (stream);
ifindex = stream_getl (stream);
}
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
api.distance = stream_getc (stream);
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
api.metric = stream_getl (stream);
else
api.metric = 0;
if (command == ZEBRA_IPV4_ROUTE_ADD) {
zlog_info ("IPv4 Route add from Z");
}
return 0;
}
int
isis_zebra_read_ipv6 (int command, struct zclient *zclient,
zebra_size_t length)
{
return 0;
}
#define ISIS_TYPE_IS_REDISTRIBUTED(T) \
T == ZEBRA_ROUTE_MAX ? zclient->default_information : zclient->redist[type]
int
isis_distribute_list_update (int routetype)
{
return 0;
}
int
isis_redistribute_default_set(int routetype, int metric_type, int metric_value)
{
return 0;
}
void
isis_zebra_init ()
{
zclient = zclient_new ();
zclient_init (zclient, ZEBRA_ROUTE_ISIS);
zclient->interface_add = isis_zebra_if_add;
zclient->interface_delete = isis_zebra_if_del;
zclient->interface_up = isis_zebra_if_state_up;
zclient->interface_down = isis_zebra_if_state_down;
zclient->interface_address_add = isis_zebra_if_address_add;
zclient->interface_address_delete = isis_zebra_if_address_del;
zclient->ipv4_route_add = isis_zebra_read_ipv4;
zclient->ipv4_route_delete = isis_zebra_read_ipv4;
#ifdef HAVE_IPV6
zclient->ipv6_route_add = isis_zebra_read_ipv6;
zclient->ipv6_route_delete = isis_zebra_read_ipv6;
#endif /* HAVE_IPV6 */
return;
}
void
isis_zebra_finish ()
{
zclient_stop (zclient);
zclient_free (zclient);
zclient = (struct zclient *) NULL;
return;
}

33
isisd/isis_zebra.h Normal file
View File

@ -0,0 +1,33 @@
/*
* IS-IS Rout(e)ing protocol - isis_zebra.h
*
* Copyright (C) 2001,2002 Sampo Saaristo
* Tampere University of Technology
* Institute of Communications Engineering
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public Licenseas published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _ZEBRA_ISIS_ZEBRA_H
#define _ZEBRA_ISIS_ZEBRA_H
extern struct zclient *zclient;
void isis_zebra_init (void);
void isis_zebra_finish (void);
void isis_zebra_route_update (struct prefix *prefix,
struct isis_route_info *route_info);
int isis_distribute_list_update (int routetype);
#endif /* _ZEBRA_ISIS_ZEBRA_H */

1989
isisd/isisd.c Normal file

File diff suppressed because it is too large Load Diff

39
isisd/isisd.conf.sample Normal file
View File

@ -0,0 +1,39 @@
! -*- isis -*-
!
! ISISd sample configuration file
!
!
!
hostname isisd
password foo
enable password foo
!log stdout
log file /tmp/isisd.log
!
!
!
router isis DEAD
net 47.0023.0000.0003.0300.0100.0102.0304.0506.00
! is-type level-1
! -- set the lifetime either for level-1, level-2 or both
! lsp-lifetime level-1 65535
! lsp-lifetime level-2 65535
! lsp-lifetime 65535
interface eth0
ip router isis DEAD
ip address 10.101.43.194
isis hello-interval 10000
! isis lsp-interval 1000
! -- optional
! isis circuit-type level-1
! isis password lallaa level-1
! isis metric 1 level-1
! isis csnp-interval 5 level-1
! isis retransmit-interval 10
! isis retransmit-throttle-interval
! isis hello-multiplier 2 level-1
!
!

147
isisd/isisd.h Normal file
View File

@ -0,0 +1,147 @@
/*
* IS-IS Rout(e)ing protocol - isisd.h
*
* Copyright (C) 2001,2002 Sampo Saaristo
* Tampere University of Technology
* Institute of Communications Engineering
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public Licenseas published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef ISISD_H
#define ISISD_H
#define ISISD_VERSION "0.0.7"
#define ISIS_VTYSH_PATH "/tmp/.isisd"
/* uncomment if you are a developer in bug hunt */
/* #define EXTREME_DEBUG */
/* #define EXTREME_TLV_DEBUG */
/* If you want topology stuff compiled in */
/* #define TOPOLOGY_GENERATE */
struct rmap{
char *name;
struct route_map *map;
};
struct isis
{
u_long process_id;
int sysid_set;
u_char sysid[ISIS_SYS_ID_LEN]; /* SystemID for this IS */
struct list *area_list; /* list of IS-IS areas */
struct list *init_circ_list;
struct list *nexthops; /* IPv4 next hops from this IS */
#ifdef HAVE_IPV6
struct list *nexthops6; /* IPv6 next hops from this IS */
#endif /* HAVE_IPV6 */
u_char max_area_addrs; /* maximumAreaAdresses */
struct area_addr *man_area_addrs; /* manualAreaAddresses */
u_int32_t debugs; /* bitmap for debug */
time_t uptime; /* when did we start */
/* Redistributed external information. */
struct route_table *external_info[ZEBRA_ROUTE_MAX + 1];
/* Redistribute metric info. */
struct {
int type; /* Internal or External */
int value; /* metric value */
} dmetric [ZEBRA_ROUTE_MAX + 1];
struct {
char *name;
struct route_map *map;
} rmap [ZEBRA_ROUTE_MAX + 1];
#ifdef HAVE_IPV6
struct {
struct {
char *name;
struct route_map *map;
} rmap [ZEBRA_ROUTE_MAX + 1];
} inet6_afmode;
#endif
};
struct isis_area
{
struct isis *isis; /* back pointer */
dict_t *lspdb[ISIS_LEVELS]; /* link-state dbs */
struct isis_spftree *spftree[ISIS_LEVELS]; /* The v4 SPTs */
struct route_table *route_table; /* IPv4 routes */
#ifdef HAVE_IPV6
struct isis_spftree *spftree6[ISIS_LEVELS]; /* The v4 SPTs */
struct route_table *route_table6; /* IPv6 routes */
#endif
int min_bcast_mtu;
struct list *circuit_list; /* IS-IS circuits */
struct flags flags;
struct thread *t_tick; /* LSP walker */
struct thread *t_remove_aged;
int lsp_regenerate_pending[ISIS_LEVELS];
struct thread *t_lsp_refresh[ISIS_LEVELS];
/*
* Configurables
*/
struct isis_passwd area_passwd;
struct isis_passwd domain_passwd;
/* do we support dynamic hostnames? */
char dynhostname;
/* do we support new style metrics? */
char newmetric;
/* identifies the routing instance */
char *area_tag;
/* area addresses for this area */
struct list *area_addrs;
u_int16_t max_lsp_lifetime[ISIS_LEVELS];
char is_type; /* level-1 level-1-2 or level-2-only */
u_int16_t lsp_refresh[ISIS_LEVELS];
/* minimum time allowed before lsp retransmission */
u_int16_t lsp_gen_interval[ISIS_LEVELS];
/* min interval between between consequtive SPFs */
u_int16_t min_spf_interval[ISIS_LEVELS];
/* the percentage of LSP mtu size used, before generating a new frag */
int lsp_frag_threshold;
int ip_circuits;
#ifdef HAVE_IPV6
int ipv6_circuits;
#endif /* HAVE_IPV6 */
/* Counters */
u_int32_t circuit_state_changes;
#ifdef TOPOLOGY_GENERATE
struct list *topology;
char topology_baseis[ISIS_SYS_ID_LEN]; /* is for the first is emulated */
char top_params[200]; /* FIXME: what is reasonable? */
#endif /* TOPOLOGY_GENERATE */
};
void isis_init(void);
struct isis_area *isis_area_lookup (char *);
#define DEBUG_ADJ_PACKETS (1<<0)
#define DEBUG_CHECKSUM_ERRORS (1<<1)
#define DEBUG_LOCAL_UPDATES (1<<2)
#define DEBUG_PROTOCOL_ERRORS (1<<3)
#define DEBUG_SNP_PACKETS (1<<4)
#define DEBUG_UPDATE_PACKETS (1<<5)
#define DEBUG_SPF_EVENTS (1<<6)
#define DEBUG_SPF_STATS (1<<7)
#define DEBUG_SPF_TRIGGERS (1<<8)
#define DEBUG_RTE_EVENTS (1<<9)
#define DEBUG_EVENTS (1<<10)
#endif /* ISISD_H */

192
isisd/iso_checksum.c Normal file
View File

@ -0,0 +1,192 @@
/*
* IS-IS Rout(e)ing protocol - iso_checksum.c
* ISO checksum related routines
*
* Copyright (C) 2001,2002 Sampo Saaristo
* Tampere University of Technology
* Institute of Communications Engineering
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public Licenseas published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <zebra.h>
#include "iso_checksum.h"
/*
* Calculations of the OSI checksum.
* ISO/IEC 8473 defines the sum as
*
* L
* sum a (mod 255) = 0
* 1 i
*
* L
* sum (L-i+1)a (mod 255) = 0
* 1 i
*
*/
/*
* Verifies that the checksum is correct.
* Return 0 on correct and 1 on invalid checksum.
* Based on Annex C.4 of ISO/IEC 8473
* FIXME: Check for overflow
*/
int
iso_csum_verify (u_char *buffer, int len, uint16_t *csum)
{
u_int8_t *p;
u_int32_t c0;
u_int32_t c1;
u_int16_t checksum;
int i;
p = buffer;
checksum = 0;
c0 = *csum & 0xff00;
c1 = *csum & 0x00ff;
/*
* If both are zero return correct
*/
if (c0 == 0 && c1 == 0)
return 0;
/*
* If either, but not both are zero return incorrect
*/
if (c0 == 0 || c1 == 0)
return 1;
/*
* Otherwise initialize to zero and calculate...
*/
c0 = 0;
c1 = 0;
for (i = 0; i < len; i++) {
c0 = c0 + *(p++);
c1 += c0;
}
c0 = c0 % 255;
c1 = c1 % 255;
if ( c0 == 0 && c1 == 0)
return 0;
return 1;
}
/*
* Creates the checksum. *csum points to the position of the checksum in the
* PDU.
* Based on Annex C.4 of ISO/IEC 8473
* we will not overflow until about length of 6000,
* which is the answer to (255+255n)*n/2 > 2^32
* so if we have a length of over 5000 we will return zero (for now)
*/
#define FIXED_CODE
u_int16_t
iso_csum_create (u_char *buffer, int len, u_int16_t n)
{
u_int8_t *p;
int x;
int y;
u_int32_t mul;
u_int32_t c0;
u_int32_t c1;
u_int16_t checksum;
u_int16_t *csum;
int i;
checksum = 0;
/*
* Zero the csum in the packet.
*/
csum = (u_int16_t*)(buffer + n);
*(csum) = checksum;
/* for the limitation of our implementation */
if (len > 5000) {
return 0;
}
p = buffer;
c0 = 0;
c1 = 0;
for (i = 0; i < len; i++) {
c0 = c0 + *(p++);
c1 += c0;
}
c0 = c0 % 255;
c1 = c1 % 255;
mul = (len - n)*(c0);
#ifdef FIXED_CODE
x = mul - c0 - c1;
y = c1 - mul - 1;
if ( y >= 0 ) y++;
if ( x < 0 ) x--;
x %= 255;
y %= 255;
if (x == 0) x = 255;
if (y == 0) y = 255;
x &= 0x00FF;
checksum = ((y << 8) | x);
#else
x = mul - c0 - c1;
x %= 255;
y = c1 - mul - 1;
y %= 255;
if (x == 0) x = 255;
if (y == 0) y = 255;
checksum = ((y << 8) | x);
#endif
/*
* Now we write this to the packet
*/
*(csum) = checksum;
/* return the checksum for user usage */
return checksum;
}
int
iso_csum_modify (u_char *buffer, int len, uint16_t *csum)
{
return 0;
}

29
isisd/iso_checksum.h Normal file
View File

@ -0,0 +1,29 @@
/*
* IS-IS Rout(e)ing protocol - iso_checksum.c
* ISO checksum related routines
*
* Copyright (C) 2001,2002 Sampo Saaristo
* Tampere University of Technology
* Institute of Communications Engineering
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public Licenseas published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _ZEBRA_ISO_CSUM_H
#define _ZEBRA_ISO_CSUM_H
int iso_csum_verify (u_char *buffer, int len, uint16_t *csum);
u_int16_t iso_csum_create (u_char *buffer, int len, u_int16_t n);
#endif /* _ZEBRA_ISO_CSUM_H */

View File

@ -0,0 +1,17 @@
## Process this file with automake to produce Makefile.in.
SUBDIRS = lib @ZEBRA@ @BGPD@ @RIPD@ @RIPNGD@ @OSPFD@ @OSPF6D@ @ISISD@ \
@VTYSH@ doc
EXTRA_DIST = aclocal.m4 SERVICES TODO REPORTING-BUGS vtysh/Makefile.in \
vtysh/Makefile.am update-autotools
dist-hook:
mkdir $(distdir)/tools
cp -p $(srcdir)/tools/*.pl $(distdir)/tools
cp -p $(srcdir)/tools/*.el $(distdir)/tools
cp -p $(srcdir)/tools/*.cgi $(distdir)/tools
mkdir $(distdir)/init
mkdir $(distdir)/init/redhat
cp -p $(srcdir)/init/redhat/*.init $(distdir)/init/redhat
cp -p $(srcdir)/init/redhat/zebra.* $(distdir)/init/redhat

462
isisd/modified/Makefile.in Normal file
View File

@ -0,0 +1,462 @@
# Makefile.in generated by automake 1.6.2 from Makefile.am.
# @configure_input@
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
# Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
SHELL = @SHELL@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
sbindir = @sbindir@
libexecdir = @libexecdir@
datadir = @datadir@
sysconfdir = @sysconfdir@
sharedstatedir = @sharedstatedir@
localstatedir = @localstatedir@
libdir = @libdir@
infodir = @infodir@
mandir = @mandir@
includedir = @includedir@
oldincludedir = /usr/include
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = .
ACLOCAL = @ACLOCAL@
AUTOCONF = @AUTOCONF@
AUTOMAKE = @AUTOMAKE@
AUTOHEADER = @AUTOHEADER@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_HEADER = $(INSTALL_DATA)
transform = @program_transform_name@
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
host_alias = @host_alias@
host_triplet = @host@
EXEEXT = @EXEEXT@
OBJEXT = @OBJEXT@
PATH_SEPARATOR = @PATH_SEPARATOR@
AMTAR = @AMTAR@
AR = @AR@
AWK = @AWK@
BGPD = @BGPD@
CC = @CC@
CPP = @CPP@
CURSES = @CURSES@
DEPDIR = @DEPDIR@
IF_METHOD = @IF_METHOD@
IF_PROC = @IF_PROC@
INCLUDES = @INCLUDES@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
IPFORWARD = @IPFORWARD@
ISISD = @ISISD@
KERNEL_METHOD = @KERNEL_METHOD@
LIBPAM = @LIBPAM@
LIB_IPV6 = @LIB_IPV6@
LIB_REGEX = @LIB_REGEX@
MULTIPATH_NUM = @MULTIPATH_NUM@
OSPF6D = @OSPF6D@
OSPFD = @OSPFD@
OTHER_METHOD = @OTHER_METHOD@
PACKAGE = @PACKAGE@
RANLIB = @RANLIB@
RIPD = @RIPD@
RIPNGD = @RIPNGD@
RTREAD_METHOD = @RTREAD_METHOD@
RT_METHOD = @RT_METHOD@
STRIP = @STRIP@
VERSION = @VERSION@
VTYSH = @VTYSH@
ZEBRA = @ZEBRA@
am__include = @am__include@
am__quote = @am__quote@
install_sh = @install_sh@
SUBDIRS = lib @ZEBRA@ @BGPD@ @RIPD@ @RIPNGD@ @OSPFD@ @OSPF6D@ @ISISD@ \
@VTYSH@ doc
EXTRA_DIST = aclocal.m4 SERVICES TODO REPORTING-BUGS vtysh/Makefile.in \
vtysh/Makefile.am update-autotools
subdir = .
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = config.h
CONFIG_CLEAN_FILES =
DIST_SOURCES =
RECURSIVE_TARGETS = info-recursive dvi-recursive install-info-recursive \
uninstall-info-recursive all-recursive install-data-recursive \
install-exec-recursive installdirs-recursive install-recursive \
uninstall-recursive check-recursive installcheck-recursive
DIST_COMMON = README AUTHORS COPYING COPYING.LIB ChangeLog INSTALL \
Makefile.am Makefile.in NEWS TODO acconfig.h aclocal.m4 \
config.guess config.h.in config.sub configure configure.in \
depcomp install-sh missing mkinstalldirs
DIST_SUBDIRS = $(SUBDIRS)
all: config.h
$(MAKE) $(AM_MAKEFLAGS) all-recursive
.SUFFIXES:
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && \
$(AUTOMAKE) --foreign Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)
$(top_builddir)/config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
$(SHELL) ./config.status --recheck
$(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
cd $(srcdir) && $(AUTOCONF)
$(ACLOCAL_M4): configure.in
cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
config.h: stamp-h1
@if test ! -f $@; then \
rm -f stamp-h1; \
$(MAKE) stamp-h1; \
else :; fi
stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
@rm -f stamp-h1
cd $(top_builddir) && $(SHELL) ./config.status config.h
$(srcdir)/config.h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4) $(top_srcdir)/acconfig.h
cd $(top_srcdir) && $(AUTOHEADER)
touch $(srcdir)/config.h.in
distclean-hdr:
-rm -f config.h stamp-h1
uninstall-info-am:
# This directory's subdirectories are mostly independent; you can cd
# into them and run `make' without going through this Makefile.
# To change the values of `make' variables: instead of editing Makefiles,
# (1) if the variable is set in `config.status', edit `config.status'
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
$(RECURSIVE_TARGETS):
@set fnord $$MAKEFLAGS; amf=$$2; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
mostlyclean-recursive clean-recursive distclean-recursive \
maintainer-clean-recursive:
@set fnord $$MAKEFLAGS; amf=$$2; \
dot_seen=no; \
case "$@" in \
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
*) list='$(SUBDIRS)' ;; \
esac; \
rev=''; for subdir in $$list; do \
if test "$$subdir" = "."; then :; else \
rev="$$subdir $$rev"; \
fi; \
done; \
rev="$$rev ."; \
target=`echo $@ | sed s/-recursive//`; \
for subdir in $$rev; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done && test -z "$$fail"
tags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
done
ETAGS = etags
ETAGSFLAGS =
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
fi; \
done; \
list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$tags$$unique" \
|| $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
top_distdir = .
distdir = $(PACKAGE)-$(VERSION)
am__remove_distdir = \
{ test ! -d $(distdir) \
|| { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \
&& rm -fr $(distdir); }; }
GZIP_ENV = --best
distcleancheck_listfiles = find . -type f -print
distdir: $(DISTFILES)
$(am__remove_distdir)
mkdir $(distdir)
$(mkinstalldirs) $(distdir)/vtysh
@list='$(DISTFILES)'; for file in $$list; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkinstalldirs) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -d $(distdir)/$$subdir \
|| mkdir $(distdir)/$$subdir \
|| exit 1; \
(cd $$subdir && \
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$(top_distdir)" \
distdir=../$(distdir)/$$subdir \
distdir) \
|| exit 1; \
fi; \
done
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="${top_distdir}" distdir="$(distdir)" \
dist-hook
-find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
! -type d ! -perm -400 -exec chmod a+r {} \; -o \
! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \
|| chmod -R a+r $(distdir)
dist-gzip: distdir
$(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
$(am__remove_distdir)
dist dist-all: distdir
$(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
$(am__remove_distdir)
# This target untars the dist file and tries a VPATH configuration. Then
# it guarantees that the distribution is self-contained by making another
# tarfile.
distcheck: dist
$(am__remove_distdir)
GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(AMTAR) xf -
chmod -R a-w $(distdir); chmod a+w $(distdir)
mkdir $(distdir)/=build
mkdir $(distdir)/=inst
chmod a-w $(distdir)
dc_install_base=`$(am__cd) $(distdir)/=inst && pwd` \
&& cd $(distdir)/=build \
&& ../configure --srcdir=.. --prefix=$$dc_install_base \
$(DISTCHECK_CONFIGURE_FLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
&& $(MAKE) $(AM_MAKEFLAGS) check \
&& $(MAKE) $(AM_MAKEFLAGS) install \
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
&& $(MAKE) $(AM_MAKEFLAGS) uninstall \
&& (test `find $$dc_install_base -type f -print | wc -l` -le 1 \
|| { echo "ERROR: files left after uninstall:" ; \
find $$dc_install_base -type f -print ; \
exit 1; } >&2 ) \
&& $(MAKE) $(AM_MAKEFLAGS) dist-gzip \
&& rm -f $(distdir).tar.gz \
&& $(MAKE) $(AM_MAKEFLAGS) distcleancheck
$(am__remove_distdir)
@echo "$(distdir).tar.gz is ready for distribution" | \
sed 'h;s/./=/g;p;x;p;x'
distcleancheck: distclean
if test '$(srcdir)' = . ; then \
echo "ERROR: distcleancheck can only run from a VPATH build" ; \
exit 1 ; \
fi
test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
|| { echo "ERROR: files left after distclean:" ; \
$(distcleancheck_listfiles) ; \
exit 1; } >&2
check-am: all-am
check: check-recursive
all-am: Makefile config.h
installdirs: installdirs-recursive
installdirs-am:
install: install-recursive
install-exec: install-exec-recursive
install-data: install-data-recursive
uninstall: uninstall-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-recursive
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-recursive
clean-am: clean-generic mostlyclean-am
distclean: distclean-recursive
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
distclean-am: clean-am distclean-generic distclean-hdr distclean-tags
dvi: dvi-recursive
dvi-am:
info: info-recursive
info-am:
install-data-am:
install-exec-am:
install-info: install-info-recursive
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-recursive
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -rf autom4te.cache
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-recursive
mostlyclean-am: mostlyclean-generic
uninstall-am: uninstall-info-am
uninstall-info: uninstall-info-recursive
.PHONY: $(RECURSIVE_TARGETS) GTAGS all all-am check check-am clean \
clean-generic clean-recursive dist dist-all dist-gzip distcheck \
distclean distclean-generic distclean-hdr distclean-recursive \
distclean-tags distcleancheck distdir dvi dvi-am dvi-recursive \
info info-am info-recursive install install-am install-data \
install-data-am install-data-recursive install-exec \
install-exec-am install-exec-recursive install-info \
install-info-am install-info-recursive install-man \
install-recursive install-strip installcheck installcheck-am \
installdirs installdirs-am installdirs-recursive \
maintainer-clean maintainer-clean-generic \
maintainer-clean-recursive mostlyclean mostlyclean-generic \
mostlyclean-recursive tags tags-recursive uninstall \
uninstall-am uninstall-info-am uninstall-info-recursive \
uninstall-recursive
dist-hook:
mkdir $(distdir)/tools
cp -p $(srcdir)/tools/*.pl $(distdir)/tools
cp -p $(srcdir)/tools/*.el $(distdir)/tools
cp -p $(srcdir)/tools/*.cgi $(distdir)/tools
mkdir $(distdir)/init
mkdir $(distdir)/init/redhat
cp -p $(srcdir)/init/redhat/*.init $(distdir)/init/redhat
cp -p $(srcdir)/init/redhat/zebra.* $(distdir)/init/redhat
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

4
isisd/modified/README Normal file
View File

@ -0,0 +1,4 @@
cp config.h.in acconfig.h configure.in Makefile.am Makefile.in configure ../../
cp command.h command.c memory.c memory.h log.h log.c vty.c ../../lib/
cp thread.h thread.c zebra.h ../../lib
cp rib.c ../../zebra/

162
isisd/modified/acconfig.h Normal file
View File

@ -0,0 +1,162 @@
/* accconfig.h -- `autoheader' will generate config.h.in for zebra.
Copyright (C) 1998, 1999 Kunihiro Ishiguro <kunihiro@zebra.org> */
/* Version of GNU Zebra */
#undef VERSION
/* Solaris on x86. */
#undef SOLARIS_X86
/* Package name of GNU Zebra */
#undef PACKAGE
/* Define if host is GNU/Linux */
#undef GNU_LINUX
/* Define if you have the AF_ROUTE socket. */
#undef HAVE_AF_ROUTE
/* Define if you have the inet_aton function. */
#undef HAVE_INET_ATON
/* Define if you have the inet_ntop function. */
#undef HAVE_INET_NTOP
/* Define if you have the inet_pton function. */
#undef HAVE_INET_PTON
/* Define if you have the setproctitle function. */
#undef HAVE_SETPROCTITLE
/* Define if you have ipv6 stack. */
#undef HAVE_IPV6
/* Define if you wish to support ipv6 router advertisment. */
/* #undef HAVE_RTADV */
/* whether system has GNU regex */
#undef HAVE_GNU_REGEX
/* whether system has SNMP library */
#undef HAVE_SNMP
/* whether sockaddr has a sa_len field */
#undef HAVE_SA_LEN
/* whether sockaddr_in has a sin_len field */
#undef HAVE_SIN_LEN
/* whether sockaddr_un has a sun_len field */
#undef HAVE_SUN_LEN
/* whether sockaddr_in6 has a sin6_scope_id field */
#undef HAVE_SIN6_SCOPE_ID
/* Define if there is socklen_t. */
#undef HAVE_SOCKLEN_T
/* Define if there is sockaddr_dl structure. */
#undef HAVE_SOCKADDR_DL
/* Define if there is ifaliasreq structure. */
#undef HAVE_IFALIASREQ
/* Define if there is in6_aliasreq structure. */
#undef HAVE_IN6_ALIASREQ
/* Define if there is rt_addrinfo structure. */
#undef HAVE_RT_ADDRINFO
/* Define if there is in_pktinfo structure. */
#undef HAVE_INPKTINFO
/* Define if you have the getrusage function. */
#undef HAVE_RUSAGE
/* Define if /proc/net/dev exists. */
#undef HAVE_PROC_NET_DEV
/* Define if /proc/net/if_inet6 exists. */
#undef HAVE_PROC_NET_IF_INET6
/* Define if NET_RT_IFLIST exists in sys/socket.h. */
#undef HAVE_NET_RT_IFLIST
/* Define if you have INRIA ipv6 stack. */
#undef INRIA_IPV6
/* Define if you have KAME project ipv6 stack. */
#undef KAME
/* Define if you have Linux ipv6 stack. */
#undef LINUX_IPV6
/* Define if you have NRL ipv6 stack. */
#undef NRL
/* Define if you have BSDI NRL IPv6 stack. */
#undef BSDI_NRL
/* Define if one-vty option is specified. */
#undef VTYSH
/* Define if interface aliases don't have distinct indeces */
#undef HAVE_BROKEN_ALIASES
/* Define if disable-bgp-announce option is specified. */
#undef DISABLE_BGP_ANNOUNCE
/* PAM support */
#undef USE_PAM
/* TCP/IP communication between zebra and protocol daemon. */
#undef HAVE_TCP_ZEBRA
/* The OSPF NSSA option (RFC1587). */
#undef HAVE_NSSA
/* The OSPF Opaque LSA option (RFC2370). */
#undef HAVE_OPAQUE_LSA
/* Traffic Engineering Extension to OSPF
(draft-katz-yeung-ospf-traffic-06.txt). */
#undef HAVE_OSPF_TE
/* Linux netlink. */
#undef HAVE_NETLINK
/* PATHS */
#undef PATH_ZEBRA_PID
#undef PATH_RIPD_PID
#undef PATH_RIPNGD_PID
#undef PATH_BGPD_PID
#undef PATH_OSPFD_PID
#undef PATH_OSPF6D_PID
#undef PATH_ISISD_PID
/* Define if Solaris */
#undef SUNOS_5
/* Define if FreeBSD 3.2 */
#undef FREEBSD_32
/* Define if OpenBSD */
#undef OPEN_BSD
#ifdef HAVE_IPV6
#ifdef KAME
#ifndef INET6
#define INET6
#endif /* INET6 */
#endif /* KAME */
#endif /* HAVE_IPV6 */
#ifdef SUNOS_5
typedef unsigned int u_int32_t;
typedef unsigned short u_int16_t;
typedef unsigned short u_int8_t;
#endif /* SUNOS_5 */
#ifndef HAVE_SOCKLEN_T
typedef int socklen_t;
#endif /* HAVE_SOCKLEN_T */

2983
isisd/modified/command.c Normal file

File diff suppressed because it is too large Load Diff

311
isisd/modified/command.h Normal file
View File

@ -0,0 +1,311 @@
/*
* Zebra configuration command interface routine
* Copyright (C) 1997, 98 Kunihiro Ishiguro
*
* 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.
*/
#ifndef _ZEBRA_COMMAND_H
#define _ZEBRA_COMMAND_H
#include "vector.h"
#include "vty.h"
/* Host configuration variable */
struct host
{
/* Host name of this router. */
char *name;
/* Password for vty interface. */
char *password;
char *password_encrypt;
/* Enable password */
char *enable;
char *enable_encrypt;
/* System wide terminal lines. */
int lines;
/* Log filename. */
char *logfile;
/* Log stdout. */
u_char log_stdout;
/* Log syslog. */
u_char log_syslog;
/* config file name of this host */
char *config;
/* Flags for services */
int advanced;
int encrypt;
/* Banner configuration. */
char *motd;
};
/* There are some command levels which called from command node. */
enum node_type
{
AUTH_NODE, /* Authentication mode of vty interface. */
VIEW_NODE, /* View node. Default mode of vty interface. */
AUTH_ENABLE_NODE, /* Authentication mode for change enable. */
ENABLE_NODE, /* Enable node. */
CONFIG_NODE, /* Config node. Default mode of config file. */
DEBUG_NODE, /* Debug node. */
AAA_NODE, /* AAA node. */
KEYCHAIN_NODE, /* Key-chain node. */
KEYCHAIN_KEY_NODE, /* Key-chain key node. */
INTERFACE_NODE, /* Interface mode node. */
ZEBRA_NODE, /* zebra connection node. */
TABLE_NODE, /* rtm_table selection node. */
RIP_NODE, /* RIP protocol mode node. */
RIPNG_NODE, /* RIPng protocol mode node. */
BGP_NODE, /* BGP protocol mode which includes BGP4+ */
BGP_VPNV4_NODE, /* BGP MPLS-VPN PE exchange. */
BGP_IPV4_NODE, /* BGP IPv4 unicast address family. */
BGP_IPV4M_NODE, /* BGP IPv4 multicast address family. */
BGP_IPV6_NODE, /* BGP IPv6 address family */
OSPF_NODE, /* OSPF protocol mode */
OSPF6_NODE, /* OSPF protocol for IPv6 mode */
ISIS_NODE, /* IS-IS protocol mode */
MASC_NODE, /* MASC for multicast. */
IRDP_NODE, /* ICMP Router Discovery Protocol mode. */
IP_NODE, /* Static ip route node. */
ACCESS_NODE, /* Access list node. */
PREFIX_NODE, /* Prefix list node. */
ACCESS_IPV6_NODE, /* Access list node. */
PREFIX_IPV6_NODE, /* Prefix list node. */
AS_LIST_NODE, /* AS list node. */
COMMUNITY_LIST_NODE, /* Community list node. */
RMAP_NODE, /* Route map node. */
SMUX_NODE, /* SNMP configuration node. */
DUMP_NODE, /* Packet dump node. */
FORWARDING_NODE, /* IP forwarding node. */
VTY_NODE /* Vty node. */
};
/* Node which has some commands and prompt string and configuration
function pointer . */
struct cmd_node
{
/* Node index. */
enum node_type node;
/* Prompt character at vty interface. */
char *prompt;
/* Is this node's configuration goes to vtysh ? */
int vtysh;
/* Node's configuration write function */
int (*func) (struct vty *);
/* Vector of this node's command list. */
vector cmd_vector;
};
/* Structure of command element. */
struct cmd_element
{
char *string; /* Command specification by string. */
int (*func) (struct cmd_element *, struct vty *, int, char **);
char *doc; /* Documentation of this command. */
int daemon; /* Daemon to which this command belong. */
vector strvec; /* Pointing out each description vector. */
int cmdsize; /* Command index count. */
char *config; /* Configuration string */
vector subconfig; /* Sub configuration string */
};
/* Command description structure. */
struct desc
{
char *cmd; /* Command string. */
char *str; /* Command's description. */
};
/* Return value of the commands. */
#define CMD_SUCCESS 0
#define CMD_WARNING 1
#define CMD_ERR_NO_MATCH 2
#define CMD_ERR_AMBIGUOUS 3
#define CMD_ERR_INCOMPLETE 4
#define CMD_ERR_EXEED_ARGC_MAX 5
#define CMD_ERR_NOTHING_TODO 6
#define CMD_COMPLETE_FULL_MATCH 7
#define CMD_COMPLETE_MATCH 8
#define CMD_COMPLETE_LIST_MATCH 9
#define CMD_SUCCESS_DAEMON 10
/* Argc max counts. */
#define CMD_ARGC_MAX 25
/* Turn off these macros when uisng cpp with extract.pl */
#ifndef VTYSH_EXTRACT_PL
/* DEFUN for vty command interafce. Little bit hacky ;-). */
#define DEFUN(funcname, cmdname, cmdstr, helpstr) \
int funcname (struct cmd_element *, struct vty *, int, char **); \
struct cmd_element cmdname = \
{ \
cmdstr, \
funcname, \
helpstr \
}; \
int funcname \
(struct cmd_element *self, struct vty *vty, int argc, char **argv)
/* DEFUN_NOSH for commands that vtysh should ignore */
#define DEFUN_NOSH(funcname, cmdname, cmdstr, helpstr) \
DEFUN(funcname, cmdname, cmdstr, helpstr)
/* DEFSH for vtysh. */
#define DEFSH(daemon, cmdname, cmdstr, helpstr) \
struct cmd_element cmdname = \
{ \
cmdstr, \
NULL, \
helpstr, \
daemon \
}; \
/* DEFUN + DEFSH */
#define DEFUNSH(daemon, funcname, cmdname, cmdstr, helpstr) \
int funcname (struct cmd_element *, struct vty *, int, char **); \
struct cmd_element cmdname = \
{ \
cmdstr, \
funcname, \
helpstr, \
daemon \
}; \
int funcname \
(struct cmd_element *self, struct vty *vty, int argc, char **argv)
/* ALIAS macro which define existing command's alias. */
#define ALIAS(funcname, cmdname, cmdstr, helpstr) \
struct cmd_element cmdname = \
{ \
cmdstr, \
funcname, \
helpstr \
};
#endif /* VTYSH_EXTRACT_PL */
/* Some macroes */
#define CMD_OPTION(S) ((S[0]) == '[')
#define CMD_VARIABLE(S) (((S[0]) >= 'A' && (S[0]) <= 'Z') || ((S[0]) == '<'))
#define CMD_VARARG(S) ((S[0]) == '.')
#define CMD_RANGE(S) ((S[0] == '<'))
#define CMD_IPV4(S) ((strcmp ((S), "A.B.C.D") == 0))
#define CMD_IPV4_PREFIX(S) ((strcmp ((S), "A.B.C.D/M") == 0))
#define CMD_IPV6(S) ((strcmp ((S), "X:X::X:X") == 0))
#define CMD_IPV6_PREFIX(S) ((strcmp ((S), "X:X::X:X/M") == 0))
/* Common descriptions. */
#define SHOW_STR "Show running system information\n"
#define IP_STR "IP information\n"
#define IPV6_STR "IPv6 information\n"
#define NO_STR "Negate a command or set its defaults\n"
#define CLEAR_STR "Reset functions\n"
#define RIP_STR "RIP information\n"
#define BGP_STR "BGP information\n"
#define OSPF_STR "OSPF information\n"
#define NEIGHBOR_STR "Specify neighbor router\n"
#define DEBUG_STR "Debugging functions (see also 'undebug')\n"
#define UNDEBUG_STR "Disable debugging functions (see also 'debug')\n"
#define ROUTER_STR "Enable a routing process\n"
#define AS_STR "AS number\n"
#define MBGP_STR "MBGP information\n"
#define MATCH_STR "Match values from routing table\n"
#define SET_STR "Set values in destination routing protocol\n"
#define OUT_STR "Filter outgoing routing updates\n"
#define IN_STR "Filter incoming routing updates\n"
#define V4NOTATION_STR "specify by IPv4 address notation(e.g. 0.0.0.0)\n"
#define OSPF6_NUMBER_STR "Specify by number\n"
#define INTERFACE_STR "Interface infomation\n"
#define IFNAME_STR "Interface name(e.g. ep0)\n"
#define IP6_STR "IPv6 Information\n"
#define OSPF6_STR "Open Shortest Path First (OSPF) for IPv6\n"
#define OSPF6_ROUTER_STR "Enable a routing process\n"
#define OSPF6_INSTANCE_STR "<1-65535> Instance ID\n"
#define SECONDS_STR "<1-65535> Seconds\n"
#define ROUTE_STR "Routing Table\n"
#define PREFIX_LIST_STR "Build a prefix list\n"
#define OSPF6_DUMP_TYPE_LIST \
"(neighbor|interface|area|lsa|zebra|config|dbex|spf|route|lsdb|redistribute|hook|asbr|prefix|abr)"
#define ISIS_STR "IS-IS information\n"
#define AREA_TAG_STR "[area tag]\n"
#define CONF_BACKUP_EXT ".sav"
/* IPv4 only machine should not accept IPv6 address for peer's IP
address. So we replace VTY command string like below. */
#ifdef HAVE_IPV6
#define NEIGHBOR_CMD "neighbor (A.B.C.D|X:X::X:X) "
#define NO_NEIGHBOR_CMD "no neighbor (A.B.C.D|X:X::X:X) "
#define NEIGHBOR_ADDR_STR "Neighbor address\nIPv6 address\n"
#define NEIGHBOR_CMD2 "neighbor (A.B.C.D|X:X::X:X|WORD) "
#define NO_NEIGHBOR_CMD2 "no neighbor (A.B.C.D|X:X::X:X|WORD) "
#define NEIGHBOR_ADDR_STR2 "Neighbor address\nNeighbor IPv6 address\nNeighbor tag\n"
#else
#define NEIGHBOR_CMD "neighbor A.B.C.D "
#define NO_NEIGHBOR_CMD "no neighbor A.B.C.D "
#define NEIGHBOR_ADDR_STR "Neighbor address\n"
#define NEIGHBOR_CMD2 "neighbor (A.B.C.D|WORD) "
#define NO_NEIGHBOR_CMD2 "no neighbor (A.B.C.D|WORD) "
#define NEIGHBOR_ADDR_STR2 "Neighbor address\nNeighbor tag\n"
#endif /* HAVE_IPV6 */
/* Prototypes. */
void install_node (struct cmd_node *, int (*) (struct vty *));
void install_default (enum node_type);
void install_element (enum node_type, struct cmd_element *);
void sort_node ();
char *argv_concat (char **, int, int);
vector cmd_make_strvec (char *);
void cmd_free_strvec (vector);
vector cmd_describe_command ();
char **cmd_complete_command ();
char *cmd_prompt (enum node_type);
int config_from_file (struct vty *, FILE *);
int cmd_execute_command (vector, struct vty *, struct cmd_element **);
int cmd_execute_command_strict (vector, struct vty *, struct cmd_element **);
void config_replace_string (struct cmd_element *, char *, ...);
void cmd_init (int);
/* Export typical functions. */
extern struct cmd_element config_end_cmd;
extern struct cmd_element config_exit_cmd;
extern struct cmd_element config_quit_cmd;
extern struct cmd_element config_help_cmd;
extern struct cmd_element config_list_cmd;
int config_exit (struct cmd_element *, struct vty *, int, char **);
int config_help (struct cmd_element *, struct vty *, int, char **);
char *host_config_file ();
void host_config_set (char *);
#endif /* _ZEBRA_COMMAND_H */

368
isisd/modified/config.h.in Normal file
View File

@ -0,0 +1,368 @@
/* config.h.in. Generated from configure.in by autoheader. */
/* accconfig.h -- `autoheader' will generate config.h.in for zebra.
Copyright (C) 1998, 1999 Kunihiro Ishiguro <kunihiro@zebra.org> */
/* Version of GNU Zebra */
#undef VERSION
/* Solaris on x86. */
#undef SOLARIS_X86
/* Package name of GNU Zebra */
#undef PACKAGE
/* Define if host is GNU/Linux */
#undef GNU_LINUX
/* Define if you have the AF_ROUTE socket. */
#undef HAVE_AF_ROUTE
/* Define if you have the inet_aton function. */
#undef HAVE_INET_ATON
/* Define if you have the inet_ntop function. */
#undef HAVE_INET_NTOP
/* Define if you have the inet_pton function. */
#undef HAVE_INET_PTON
/* Define if you have the setproctitle function. */
#undef HAVE_SETPROCTITLE
/* Define if you have ipv6 stack. */
#undef HAVE_IPV6
/* Define if you wish to support ipv6 router advertisment. */
/* #undef HAVE_RTADV */
/* whether system has GNU regex */
#undef HAVE_GNU_REGEX
/* whether system has SNMP library */
#undef HAVE_SNMP
/* whether sockaddr has a sa_len field */
#undef HAVE_SA_LEN
/* whether sockaddr_in has a sin_len field */
#undef HAVE_SIN_LEN
/* whether sockaddr_un has a sun_len field */
#undef HAVE_SUN_LEN
/* whether sockaddr_in6 has a sin6_scope_id field */
#undef HAVE_SIN6_SCOPE_ID
/* Define if there is socklen_t. */
#undef HAVE_SOCKLEN_T
/* Define if there is sockaddr_dl structure. */
#undef HAVE_SOCKADDR_DL
/* Define if there is ifaliasreq structure. */
#undef HAVE_IFALIASREQ
/* Define if there is in6_aliasreq structure. */
#undef HAVE_IN6_ALIASREQ
/* Define if there is rt_addrinfo structure. */
#undef HAVE_RT_ADDRINFO
/* Define if there is in_pktinfo structure. */
#undef HAVE_INPKTINFO
/* Define if you have the getrusage function. */
#undef HAVE_RUSAGE
/* Define if /proc/net/dev exists. */
#undef HAVE_PROC_NET_DEV
/* Define if /proc/net/if_inet6 exists. */
#undef HAVE_PROC_NET_IF_INET6
/* Define if NET_RT_IFLIST exists in sys/socket.h. */
#undef HAVE_NET_RT_IFLIST
/* Define if you have INRIA ipv6 stack. */
#undef INRIA_IPV6
/* Define if you have KAME project ipv6 stack. */
#undef KAME
/* Define if you have Linux ipv6 stack. */
#undef LINUX_IPV6
/* Define if you have NRL ipv6 stack. */
#undef NRL
/* Define if you have BSDI NRL IPv6 stack. */
#undef BSDI_NRL
/* Define if one-vty option is specified. */
#undef VTYSH
/* Define if interface aliases don't have distinct indeces */
#undef HAVE_BROKEN_ALIASES
/* Define if disable-bgp-announce option is specified. */
#undef DISABLE_BGP_ANNOUNCE
/* PAM support */
#undef USE_PAM
/* TCP/IP communication between zebra and protocol daemon. */
#undef HAVE_TCP_ZEBRA
/* The OSPF NSSA option (RFC1587). */
#undef HAVE_NSSA
/* The OSPF Opaque LSA option (RFC2370). */
#undef HAVE_OPAQUE_LSA
/* Traffic Engineering Extension to OSPF
(draft-katz-yeung-ospf-traffic-06.txt). */
#undef HAVE_OSPF_TE
/* Linux netlink. */
#undef HAVE_NETLINK
/* PATHS */
#undef PATH_ZEBRA_PID
#undef PATH_RIPD_PID
#undef PATH_RIPNGD_PID
#undef PATH_BGPD_PID
#undef PATH_OSPFD_PID
#undef PATH_OSPF6D_PID
#undef PATH_ISISD_PID
/* Define if Solaris */
#undef SUNOS_5
/* Define if FreeBSD 3.2 */
#undef FREEBSD_32
/* Define if OpenBSD */
#undef OPEN_BSD
#ifdef HAVE_IPV6
#ifdef KAME
#ifndef INET6
#define INET6
#endif /* INET6 */
#endif /* KAME */
#endif /* HAVE_IPV6 */
#ifdef SUNOS_5
typedef unsigned int u_int32_t;
typedef unsigned short u_int16_t;
typedef unsigned short u_int8_t;
#endif /* SUNOS_5 */
#ifndef HAVE_SOCKLEN_T
typedef int socklen_t;
#endif /* HAVE_SOCKLEN_T */
/* Define to 1 if you have the <asm/types.h> header file. */
#undef HAVE_ASM_TYPES_H
/* Define to 1 if you have the `bcopy' function. */
#undef HAVE_BCOPY
/* Define to 1 if you have the `bzero' function. */
#undef HAVE_BZERO
/* Define to 1 if you have the `daemon' function. */
#undef HAVE_DAEMON
/* Define to 1 if you have the `getaddrinfo' function. */
#undef HAVE_GETADDRINFO
/* Define to 1 if you have the `getifaddrs' function. */
#undef HAVE_GETIFADDRS
/* Define to 1 if you have the `if_indextoname' function. */
#undef HAVE_IF_INDEXTONAME
/* Define to 1 if you have the `if_nametoindex' function. */
#undef HAVE_IF_NAMETOINDEX
/* Define to 1 if you have the `inet_aton' function. */
#undef HAVE_INET_ATON
/* Define to 1 if you have the <inet/nd.h> header file. */
#undef HAVE_INET_ND_H
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the <kvm.h> header file. */
#undef HAVE_KVM_H
/* Define to 1 if you have the `crypt' library (-lcrypt). */
#undef HAVE_LIBCRYPT
/* Define to 1 if you have the `kvm' library (-lkvm). */
#undef HAVE_LIBKVM
/* Define to 1 if you have the `m' library (-lm). */
#undef HAVE_LIBM
/* Define to 1 if you have the `ncurses' library (-lncurses). */
#undef HAVE_LIBNCURSES
/* Define to 1 if you have the `nsl' library (-lnsl). */
#undef HAVE_LIBNSL
/* Define to 1 if you have the `readline' library (-lreadline). */
#undef HAVE_LIBREADLINE
/* Define to 1 if you have the `resolv' library (-lresolv). */
#undef HAVE_LIBRESOLV
/* Define to 1 if you have the `socket' library (-lsocket). */
#undef HAVE_LIBSOCKET
/* Define to 1 if you have the `tinfo' library (-ltinfo). */
#undef HAVE_LIBTINFO
/* Define to 1 if you have the <libutil.h> header file. */
#undef HAVE_LIBUTIL_H
/* Define to 1 if you have the `xnet' library (-lxnet). */
#undef HAVE_LIBXNET
/* Define to 1 if you have the <linux/version.h> header file. */
#undef HAVE_LINUX_VERSION_H
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the <netdb.h> header file. */
#undef HAVE_NETDB_H
/* Define to 1 if you have the <netinet6/nd6.h> header file. */
#undef HAVE_NETINET6_ND6_H
/* Define to 1 if you have the <netinet/icmp6.h> header file. */
#undef HAVE_NETINET_ICMP6_H
/* Define to 1 if you have the <netinet/in6.h> header file. */
#undef HAVE_NETINET_IN6_H
/* Define to 1 if you have the <netinet/in6_var.h> header file. */
#undef HAVE_NETINET_IN6_VAR_H
/* Define to 1 if you have the <netinet/in.h> header file. */
#undef HAVE_NETINET_IN_H
/* Define to 1 if you have the <netinet/in_var.h> header file. */
#undef HAVE_NETINET_IN_VAR_H
/* Define to 1 if you have the <net/if_dl.h> header file. */
#undef HAVE_NET_IF_DL_H
/* Define to 1 if you have the <net/if_var.h> header file. */
#undef HAVE_NET_IF_VAR_H
/* Define to 1 if you have the <net/netopt.h> header file. */
#undef HAVE_NET_NETOPT_H
/* Define to 1 if you have the `setproctitle' function. */
#undef HAVE_SETPROCTITLE
/* Define to 1 if you have the `snprintf' function. */
#undef HAVE_SNPRINTF
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the `strerror' function. */
#undef HAVE_STRERROR
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the `strlcat' function. */
#undef HAVE_STRLCAT
/* Define to 1 if you have the `strlcpy' function. */
#undef HAVE_STRLCPY
/* Define to 1 if you have the <stropts.h> header file. */
#undef HAVE_STROPTS_H
/* Define to 1 if you have the <sys/conf.h> header file. */
#undef HAVE_SYS_CONF_H
/* Define to 1 if you have the <sys/ksym.h> header file. */
#undef HAVE_SYS_KSYM_H
/* Define to 1 if you have the <sys/select.h> header file. */
#undef HAVE_SYS_SELECT_H
/* Define to 1 if you have the <sys/sockio.h> header file. */
#undef HAVE_SYS_SOCKIO_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/sysctl.h> header file. */
#undef HAVE_SYS_SYSCTL_H
/* Define to 1 if you have the <sys/times.h> header file. */
#undef HAVE_SYS_TIMES_H
/* Define to 1 if you have the <sys/time.h> header file. */
#undef HAVE_SYS_TIME_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to 1 if you have the `vsnprintf' function. */
#undef HAVE_VSNPRINTF
/* Name of package */
#undef PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Define as the return type of signal handlers (`int' or `void'). */
#undef RETSIGTYPE
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Version number of package */
#undef VERSION
/* Define to 1 if on AIX 3.
System headers sometimes define this.
We just want to avoid a redefinition error message. */
#ifndef _ALL_SOURCE
# undef _ALL_SOURCE
#endif
/* Define to empty if `const' does not conform to ANSI C. */
#undef const

8277
isisd/modified/configure vendored Executable file

File diff suppressed because it is too large Load Diff

882
isisd/modified/configure.in Executable file
View File

@ -0,0 +1,882 @@
##
## Configure template file for Zebra.
## autoconf will generate configure script.
##
## Copyright (c) 1996, 97, 98, 99, 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
##
AC_PREREQ(2.13)
AC_INIT(lib/zebra.h)
AM_INIT_AUTOMAKE(zebra, 0.93)
AM_CONFIG_HEADER(config.h)
dnl -----------------------------------
dnl Get hostname and other information.
dnl -----------------------------------
AC_CANONICAL_HOST
dnl ------------
dnl Check CFLAGS
dnl ------------
AC_ARG_WITH(cflags,
[ --with-cflags Set CFLAGS for use in compilation.])
if test "x$with_cflags" != "x" ; then
CFLAGS="$with_cflags" ; cflags_specified=yes ;
elif test -n "$CFLAGS" ; then
cflags_specified=yes ;
fi
dnl --------
dnl Check CC
dnl --------
AC_PROG_CC
dnl -----------------------------------------
dnl If CLFAGS doesn\'t exist set default value
dnl -----------------------------------------
if test "x$cflags_specified" = "x" ; then
CFLAGS="$CFLAGS -Wall"
fi
dnl --------------
dnl Check programs
dnl --------------
AC_PROG_CPP
AC_PROG_INSTALL
AC_PROG_MAKE_SET
AC_CHECK_TOOL(AR, ar)
AC_CHECK_TOOL(RANLIB, ranlib, :)
dnl ---------
dnl AIX check
dnl ---------
AC_AIX
dnl ----------------------
dnl Packages configuration
dnl ----------------------
AC_ARG_ENABLE(vtysh,
[ --enable-vtysh, Make integrated VTY version of zebra])
AC_ARG_ENABLE(ipv6,
[ --disable-ipv6 turn off IPv6 related features and daemons])
AC_ARG_ENABLE(zebra,
[ --disable-zebra do not build zebra daemon])
AC_ARG_ENABLE(bgpd,
[ --disable-bgpd do not build bgpd])
AC_ARG_ENABLE(ripd,
[ --disable-ripd do not build ripd])
AC_ARG_ENABLE(ripngd,
[ --disable-ripngd do not build ripngd])
AC_ARG_ENABLE(ospfd,
[ --disable-ospfd do not build ospfd])
AC_ARG_ENABLE(ospf6d,
[ --disable-ospf6d do not build ospf6d])
AC_ARG_ENABLE(isisd,
[ --disable-isisd do not build isisd])
AC_ARG_ENABLE(bgp-announce,
[ --disable-bgp-announce, turn off BGP route announcement])
AC_ARG_ENABLE(netlink,
[ --enable-netlink force to use Linux netlink interface])
AC_ARG_ENABLE(broken-aliases,
[ --enable-broken-aliases enable aliases as distinct interfaces for Linux 2.2.X])
AC_ARG_ENABLE(snmp,
[ --enable-snmp enable SNMP support])
AC_ARG_WITH(libpam,
[ --with-libpam use libpam for PAM support in vtysh])
AC_ARG_ENABLE(tcpsock,
[ --enable-tcp-zebra enable TCP/IP socket connection between zebra and protocol daemon])
dnl Temporary option until OSPF NSSA implementation complete
AC_ARG_ENABLE(nssa,
[ --enable-nssa enable OSPF NSSA option])
AC_ARG_ENABLE(opaque-lsa,
[ --enable-opaque-lsa enable OSPF Opaque-LSA support (RFC2370)])
AC_ARG_ENABLE(ospf-te,
[ --enable-ospf-te enable Traffic Engineering Extension to OSPF])
AC_ARG_ENABLE(multipath,
[ --enable-multipath=ARG enable multipath function, ARG must be digit])
dnl AC_ARG_ENABLE(rtadv,
dnl [ --enable-rtadv enable IPV6 router advertisment option])
if test "${enable_broken_aliases}" = "yes"; then
if test "${enable_netlink}" = "yes"
then
echo "Sorry, you can't use netlink with broken aliases"
exit 1
fi
AC_DEFINE(HAVE_BROKEN_ALIASES)
enable_netlink=no
fi
if test "${enable_tcp_zebra}" = "yes"; then
AC_DEFINE(HAVE_TCP_ZEBRA)
fi
if test "${enable_nssa}" = "yes"; then
AC_DEFINE(HAVE_NSSA)
fi
if test "${enable_opaque_lsa}" = "yes"; then
AC_DEFINE(HAVE_OPAQUE_LSA)
fi
if test "${enable_ospf_te}" = "yes"; then
AC_DEFINE(HAVE_OPAQUE_LSA)
AC_DEFINE(HAVE_OSPF_TE)
fi
dnl if test "${enable_rtadv}" = "yes"; then
dnl AC_DEFINE(HAVE_RTADV)
dnl fi
changequote(, )dnl
MULTIPATH_NUM=1
case "${enable_multipath}" in
[0-9]|[1-9][0-9])
MULTIPATH_NUM="${enable_multipath}"
;;
"")
;;
*)
echo "Please specify digit to --enable-multipath ARG."
exit 1
;;
esac
changequote([, ])dnl
AC_SUBST(MULTIPATH_NUM)
dnl -------------------
dnl Check header files.
dnl -------------------
AC_STDC_HEADERS
AC_CHECK_HEADERS(string.h stropts.h sys/conf.h sys/ksym.h sys/time.h sys/times.h sys/select.h sys/sysctl.h sys/sockio.h sys/types.h net/if_dl.h net/if_var.h linux/version.h kvm.h netdb.h netinet/in.h net/netopt.h netinet/in_var.h netinet/in6_var.h netinet/in6.h inet/nd.h asm/types.h netinet/icmp6.h netinet6/nd6.h libutil.h)
dnl check some types
AC_C_CONST
dnl AC_TYPE_PID_T
AC_TYPE_SIGNAL
dnl Some systems (Solaris 2.x) require libnsl (Network Services Library)
case "$host" in
*-sunos5.6* | *-solaris2.6*)
opsys=sol2-6
AC_DEFINE(SUNOS_5)
AC_CHECK_LIB(xnet, main)
CURSES=-lcurses
;;
*-sunos5* | *-solaris2*)
AC_DEFINE(SUNOS_5)
AC_CHECK_LIB(socket, main)
AC_CHECK_LIB(nsl, main)
CURSES=-lcurses
;;
*-linux-*)
opsys=gnu-linux
AC_DEFINE(GNU_LINUX)
;;
*-nec-sysv4*)
AC_CHECK_LIB(nsl, gethostbyname)
AC_CHECK_LIB(socket, socket)
;;
*-freebsd3.2)
AC_DEFINE(FREEBSD_32)
;;
*-openbsd*)
opsys=openbsd
AC_DEFINE(OPEN_BSD)
;;
*-bsdi*)
opsys=bsdi
OTHER_METHOD="mtu_kvm.o"
AC_CHECK_LIB(kvm, main)
;;
esac
case "${host_cpu}-${host_os}" in
i?86-solaris*)
AC_DEFINE(SOLARIS_X86)
;;
esac
dnl ---------------------
dnl Integrated VTY option
dnl ---------------------
case "${enable_vtysh}" in
"yes") VTYSH="vtysh";
AC_DEFINE(VTYSH)
AC_CHECK_LIB(tinfo, tputs, , AC_CHECK_LIB(ncurses, tputs))
AC_CHECK_LIB(readline, main)
if test $ac_cv_lib_readline_main = no; then
AC_MSG_ERROR([vtysh needs libreadline but was not found on your system.])
fi
AC_CHECK_HEADER(readline/history.h)
if test $ac_cv_header_readline_history_h = no;then
AC_MSG_ERROR([readline is too old to have readline/history.h, please update to the latest readline library.])
fi
;;
"no" ) VTYSH="";;
* ) ;;
esac
dnl ----------
dnl PAM module
dnl ----------
if test "$with_libpam" = "yes"; then
dnl took this test from proftpd's configure.in and suited to our needs
dnl -------------------------------------------------------------------------
dnl
dnl This next check looks funky due to a linker problem with some versions
dnl of the PAM library. Prior to 0.72 release, the Linux PAM shared library
dnl omitted requiring libdl linking information. PAM-0.72 or better ships
dnl with RedHat 6.2 and Debian 2.2 or better.
AC_CHECK_LIB(pam, pam_start,
[AC_CHECK_LIB(pam, misc_conv,
[AC_DEFINE(USE_PAM)
LIBPAM="-lpam"],
[AC_DEFINE(USE_PAM)
LIBPAM="-lpam -lpam_misc"]
)
],
[AC_CHECK_LIB(pam, pam_end,
[AC_CHECK_LIB(pam, misc_conv,
[AC_DEFINE(USE_PAM)
LIBPAM="-lpam -ldl"],
[AC_DEFINE(USE_PAM)
LIBPAM="-lpam -ldl -lpam_misc"]
)
],AC_MSG_WARN([*** pam support will not be built ***]),
[-ldl])
]
)
fi
AC_SUBST(LIBPAM)
dnl -------------------------------
dnl Endian-ness check
dnl -------------------------------
AC_DEFUN(ZEBRA_AC_C_BIGENDIAN,
[AC_CACHE_CHECK(whether byte ordering is bigendian, ac_cv_c_bigendian,
[ac_cv_c_bigendian=unknown
# See if sys/param.h defines the BYTE_ORDER macro.
AC_TRY_COMPILE([#include <sys/types.h>
#include <sys/param.h>], [
#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
bogus endian macros
#endif], [# It does; now see whether it defined to BIG_ENDIAN or not.
AC_TRY_COMPILE([#include <sys/types.h>
#include <sys/param.h>], [
#if BYTE_ORDER != BIG_ENDIAN
not big endian
#endif], ac_cv_c_bigendian=yes, ac_cv_c_bigendian=no)])
if test $ac_cv_c_bigendian = unknown; then
AC_TRY_RUN([main () {
/* Are we little or big endian? From Harbison&Steele. */
union
{
long l;
char c[sizeof (long)];
} u;
u.l = 1;
exit (u.c[sizeof (long) - 1] == 1);
}], ac_cv_c_bigendian=no, ac_cv_c_bigendian=yes, ac_cv_c_bigendian=no)
fi])
if test $ac_cv_c_bigendian = yes; then
AC_DEFINE(WORDS_BIGENDIAN,1,Big endian words)
fi
])
dnl -------------------------------
dnl check the size in byte of the C
dnl -------------------------------
dnl AC_CHECK_SIZEOF(char)
dnl AC_CHECK_SIZEOF(int)
dnl AC_CHECK_SIZEOF(short)
dnl AC_CHECK_SIZEOF(long)
dnl ----------------------------
dnl check existance of functions
dnl ----------------------------
AC_CHECK_FUNCS(bcopy bzero strerror inet_aton daemon snprintf vsnprintf strlcat strlcpy if_nametoindex if_indextoname getifaddrs)
AC_CHECK_FUNCS(setproctitle, ,[AC_CHECK_LIB(util, setproctitle, [LIBS="$LIBS -lutil"; AC_DEFINE(HAVE_SETPROCTITLE)])])
dnl ------------------------------------
dnl Determine routing get and set method
dnl ------------------------------------
AC_MSG_CHECKING(zebra between kernel interface method)
if test x"$opsys" = x"gnu-linux"; then
if test "${enable_netlink}" = "yes";then
AC_MSG_RESULT(netlink)
RT_METHOD=rt_netlink.o
AC_DEFINE(HAVE_NETLINK)
netlink=yes
elif test "${enable_netlink}" = "no"; then
AC_MSG_RESULT(ioctl)
RT_METHOD=rt_ioctl.o
netlink=no
else
AC_EGREP_CPP(yes,
[#include <linux/autoconf.h>
#include <linux/version.h>
#if LINUX_VERSION_CODE > 131328 /* 2.1.0 or later */
#ifdef CONFIG_RTNETLINK
yes
#endif
#endif
#if LINUX_VERSION_CODE > 132112 /* 2.4.17 or later */
yes
#endif
],
[AC_MSG_RESULT(netlink)
RT_METHOD=rt_netlink.o
AC_DEFINE(HAVE_NETLINK)
netlink=yes],
[AC_MSG_RESULT(ioctl)
RT_METHOD=rt_ioctl.o])
fi
else
if test "$opsys" = "sol2-6";then
AC_MSG_RESULT(solaris)
KERNEL_METHOD="kernel_socket.o"
RT_METHOD="rt_socket.o"
else
AC_TRY_RUN([#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
main ()
{
int ac_sock;
ac_sock = socket (AF_ROUTE, SOCK_RAW, 0);
if (ac_sock < 0 && errno == EINVAL)
exit (1);
exit (0);
}],
[AC_DEFINE(HAVE_AF_ROUTE)
KERNEL_METHOD=kernel_socket.o
RT_METHOD=rt_socket.o
AC_MSG_RESULT(socket)],
[RT_METHOD=rt_ioctl.o
AC_MSG_RESULT(ioctl)],
[KERNEL_METHOD=kernel_socket.o
RT_METHOD=rt_socket.o
AC_MSG_RESULT(socket)])
fi
fi
AC_SUBST(RT_METHOD)
AC_SUBST(KERNEL_METHOD)
AC_SUBST(OTHER_METHOD)
dnl ------------------------------
dnl check kernel route read method
dnl ------------------------------
AC_CACHE_CHECK(route read method check, zebra_rtread,
[if test "$netlink" = yes; then
RTREAD_METHOD="rtread_netlink.o"
zebra_rtread="netlink"
else
for zebra_rtread in /proc/net/route /dev/ip /dev/null;
do
test x`ls $zebra_rtread 2>/dev/null` = x"$zebra_rtread" && break
done
case $zebra_rtread in
"/proc/net/route") RTREAD_METHOD="rtread_proc.o"
zebra_rtread="proc";;
"/dev/ip") RTREAD_METHOD="rtread_getmsg.o"
zebra_rtread="getmsg";;
*) RTREAD_METHOD="rtread_sysctl.o"
zebra_rtread="sysctl";;
esac
fi])
AC_SUBST(RTREAD_METHOD)
dnl -----------------------------
dnl check interface lookup method
dnl -----------------------------
AC_MSG_CHECKING(interface looking up method)
if test "$netlink" = yes; then
AC_MSG_RESULT(netlink)
IF_METHOD=if_netlink.o
else
if test "$opsys" = "sol2-6";then
AC_MSG_RESULT(solaris)
IF_METHOD=if_ioctl.o
elif test "$opsys" = "openbsd";then
AC_MSG_RESULT(openbsd)
IF_METHOD=if_ioctl.o
elif grep NET_RT_IFLIST /usr/include/sys/socket.h >/dev/null 2>&1; then
AC_MSG_RESULT(sysctl)
IF_METHOD=if_sysctl.o
AC_DEFINE(HAVE_NET_RT_IFLIST)
else
AC_MSG_RESULT(ioctl)
IF_METHOD=if_ioctl.o
fi
fi
AC_SUBST(IF_METHOD)
dnl -----------------------
dnl check proc file system.
dnl -----------------------
if test -r /proc/net/dev; then
AC_DEFINE(HAVE_PROC_NET_DEV)
IF_PROC=if_proc.o
fi
if test -r /proc/net/if_inet6; then
AC_DEFINE(HAVE_PROC_NET_IF_INET6)
IF_PROC=if_proc.o
fi
AC_SUBST(IF_PROC)
dnl -----------------------------
dnl check ipforward detect method
dnl -----------------------------
AC_CACHE_CHECK(ipforward method check, zebra_ipforward_path,
[for zebra_ipforward_path in /proc/net/snmp /dev/ip /dev/null;
do
test x`ls $zebra_ipforward_path 2>/dev/null` = x"$zebra_ipforward_path" && break
done
case $zebra_ipforward_path in
"/proc/net/snmp") IPFORWARD=ipforward_proc.o
zebra_ipforward_path="proc";;
"/dev/ip")
case "$host" in
*-nec-sysv4*) IPFORWARD=ipforward_ews.o
zebra_ipforward_path="ews";;
*) IPFORWARD=ipforward_solaris.o
zebra_ipforward_path="solaris";;
esac;;
*) IPFORWARD=ipforward_sysctl.o
zebra_ipforward_path="sysctl";;
esac])
AC_SUBST(IPFORWARD)
AC_CHECK_FUNCS(getaddrinfo, [have_getaddrinfo=yes], [have_getaddrinfo=no])
dnl ----------
dnl IPv6 check
dnl ----------
AC_MSG_CHECKING(whether does this OS have IPv6 stack)
if test "${enable_ipv6}" = "no"; then
AC_MSG_RESULT(disabled)
else
dnl ----------
dnl INRIA IPv6
dnl ----------
if grep IPV6_INRIA_VERSION /usr/include/netinet/in.h >/dev/null 2>&1; then
zebra_cv_ipv6=yes
AC_DEFINE(HAVE_IPV6)
AC_DEFINE(INRIA_IPV6)
RIPNGD="ripngd"
OSPF6D="ospf6d"
LIB_IPV6=""
AC_MSG_RESULT(INRIA IPv6)
fi
dnl ---------
dnl KAME IPv6
dnl ---------
if grep WIDE /usr/include/netinet6/in6.h >/dev/null 2>&1; then
zebra_cv_ipv6=yes
AC_DEFINE(HAVE_IPV6)
AC_DEFINE(KAME)
RIPNGD="ripngd"
OSPF6D="ospf6d"
if test -d /usr/local/v6/lib -a -f /usr/local/v6/lib/libinet6.a; then
LIB_IPV6="-L/usr/local/v6/lib -linet6"
fi
AC_MSG_RESULT(KAME)
fi
dnl ---------
dnl NRL check
dnl ---------
if grep NRL /usr/include/netinet6/in6.h >/dev/null 2>&1; then
zebra_cv_ipv6=yes
AC_DEFINE(HAVE_IPV6)
AC_DEFINE(NRL)
RIPNGD="ripngd"
OSPF6D="ospf6d"
if test x"$opsys" = x"bsdi";then
AC_DEFINE(BSDI_NRL)
AC_MSG_RESULT(BSDI_NRL)
else
AC_MSG_RESULT(NRL)
fi
fi
dnl ----------
dnl Linux IPv6
dnl ----------
if test "${enable_ipv6}" = "yes"; then
AC_EGREP_CPP(yes, [
#include <linux/version.h>
/* 2.1.128 or later */
#if LINUX_VERSION_CODE >= 0x020180
yes
#endif],
[zebra_cv_ipv6=yes; zebra_cv_linux_ipv6=yes;AC_MSG_RESULT(Linux IPv6)])
else
if test x`ls /proc/net/ipv6_route 2>/dev/null` = x"/proc/net/ipv6_route"
then
zebra_cv_ipv6=yes
zebra_cv_linux_ipv6=yes
AC_MSG_RESULT(Linux IPv6)
fi
fi
if test "$zebra_cv_linux_ipv6" = "yes";then
AC_DEFINE(HAVE_IPV6)
AC_MSG_CHECKING(for GNU libc 2.1)
AC_EGREP_CPP(yes, [
#include <features.h>
#if __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1
yes
#endif], [glibc=yes; AC_MSG_RESULT(yes)], AC_MSG_RESULT(no))
AC_DEFINE(LINUX_IPV6)
RIPNGD="ripngd"
OSPF6D="ospf6d"
if test "$glibc" != "yes"; then
INCLUDES="-I/usr/inet6/include"
if test x`ls /usr/inet6/lib/libinet6.a 2>/dev/null` != x;then
LIB_IPV6="-L/usr/inet6/lib -linet6"
fi
fi
fi
dnl -----------------------
dnl Set IPv6 related values
dnl -----------------------
LIBS="$LIB_IPV6 $LIBS"
AC_SUBST(LIB_IPV6)
if test x"$RIPNGD" = x""; then
AC_MSG_RESULT(IPv4 only)
fi
fi
dnl --------------------
dnl Daemon disable check
dnl --------------------
if test "${enable_zebra}" = "no";then
ZEBRA=""
else
ZEBRA="zebra"
fi
if test "${enable_bgpd}" = "no";then
BGPD=""
else
BGPD="bgpd"
fi
if test "${enable_ripd}" = "no";then
RIPD=""
else
RIPD="ripd"
fi
if test "${enable_ospfd}" = "no";then
OSPFD=""
else
OSPFD="ospfd"
fi
case "${enable_ripngd}" in
"yes") RIPNGD="ripngd";;
"no" ) RIPNGD="";;
* ) ;;
esac
case "${enable_ospf6d}" in
"yes") OSPF6D="ospf6d";;
"no" ) OSPF6D="";;
* ) ;;
esac
case "${enable_isisd}" in
"yes") ISISD="isisd";;
"no" ) ISISD="";;
* ) ;;
esac
if test "${enable_bgp_announce}" = "no";then
AC_DEFINE(DISABLE_BGP_ANNOUNCE)
fi
AC_SUBST(ZEBRA)
AC_SUBST(BGPD)
AC_SUBST(RIPD)
AC_SUBST(RIPNGD)
AC_SUBST(OSPFD)
AC_SUBST(OSPF6D)
AC_SUBST(ISISD)
AC_SUBST(VTYSH)
AC_SUBST(INCLUDES)
AC_SUBST(CURSES)
AC_CHECK_LIB(c, inet_ntop, [AC_DEFINE(HAVE_INET_NTOP)])
AC_CHECK_LIB(c, inet_pton, [AC_DEFINE(HAVE_INET_PTON)])
AC_CHECK_LIB(crypt, crypt)
AC_CHECK_LIB(resolv, res_init)
AC_CHECK_LIB(m, main)
dnl ---------------------------------------------------
dnl BSD/OS 4.1 define inet_XtoY function as __inet_XtoY
dnl ---------------------------------------------------
AC_CHECK_FUNC(__inet_ntop, AC_DEFINE(HAVE_INET_NTOP))
AC_CHECK_FUNC(__inet_pton, AC_DEFINE(HAVE_INET_PTON))
AC_CHECK_FUNC(__inet_aton, AC_DEFINE(HAVE_INET_ATON))
dnl ---------------------------
dnl check system has GNU regexp
dnl ---------------------------
dnl AC_MSG_CHECKING(whether system has GNU regex)
AC_CHECK_LIB(c, regexec,
[AC_DEFINE(HAVE_GNU_REGEX)
LIB_REGEX=""],
[LIB_REGEX="regex.o"])
AC_SUBST(LIB_REGEX)
dnl AC_MSG_CHECKING(whether system has GNU regex)
dnl if grep RE_NO_GNU_OPS /usr/include/regex.h >/dev/null 2>&1; then
dnl AC_MSG_RESULT(yes)
dnl AC_DEFINE(HAVE_GNU_REGEX)
dnl LIB_REGEX=""
dnl else
dnl AC_MSG_RESULT(no)
dnl LIB_REGEX="regex.o"
dnl fi
dnl AC_SUBST(LIB_REGEX)
dnl ------------------
dnl check SNMP library
dnl ------------------
if test "${enable_snmp}" = "yes";then
dnl AC_CHECK_LIB(snmp, asn_parse_int, HAVE_SNMP=yes)
old_libs="${LIBS}"
LIBS="-L/usr/local/lib"
unset ac_cv_lib_snmp_asn_parse_int
AC_CHECK_LIB(snmp, asn_parse_int, HAVE_SNMP=yes, )
if test "${HAVE_SNMP}" = ""; then
unset ac_cv_lib_snmp_asn_parse_int
AC_CHECK_LIB(crypto, main, [NEED_CRYPTO=yes ], )
if test "${NEED_CRYPTO}" = ""; then
AC_CHECK_LIB(snmp, asn_parse_int, [HAVE_SNMP=yes; NEED_CRYPTO=yes ],)
else
AC_CHECK_LIB(snmp, asn_parse_int, [HAVE_SNMP=yes; NEED_CRYPTO=yes;LIBS="$LIBS -lcrypto" ],,"-lcrypto")
fi
fi
LIBS="${old_libs}"
if test "${HAVE_SNMP}" = ""; then
old_libs="${LIBS}"
LIBS="-L/usr/local/lib"
AC_CHECK_LIB(snmp, asn_parse_int, HAVE_SNMP=yes)
LIBS="${old_libs}"
fi
if test "${HAVE_SNMP}" = "yes"; then
for ac_snmp in /usr/include/ucd-snmp/asn1.h /usr/local/include/ucd-snmp/asn1.h /dev/null
do
test -f "${ac_snmp}" && break
done
case ${ac_snmp} in
/usr/include/ucd-snmp/*)
AC_DEFINE(HAVE_SNMP)
CFLAGS="${CFLAGS} -I/usr/include/ucd-snmp"
LIBS="${LIBS} -lsnmp"
;;
/usr/local/include/ucd-snmp/*)
AC_DEFINE(HAVE_SNMP)
CFLAGS="${CFLAGS} -I/usr/local/include/ucd-snmp"
LIBS="${LIBS} -L/usr/local/lib -lsnmp"
;;
esac
if test "${NEED_CRYPTO}" = "yes"; then
LIBS="${LIBS} -lcrypto"
fi
fi
fi
dnl ----------------------------
dnl check sa_len of sockaddr
dnl ----------------------------
AC_MSG_CHECKING(whether struct sockaddr has a sa_len field)
AC_TRY_COMPILE([#include <sys/types.h>
#include <sys/socket.h>
],[static struct sockaddr ac_i;int ac_j = sizeof (ac_i.sa_len);],
[AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_SA_LEN)],
AC_MSG_RESULT(no))
dnl ----------------------------
dnl check sin_len of sockaddr_in
dnl ----------------------------
AC_MSG_CHECKING(whether struct sockaddr_in has a sin_len field)
AC_TRY_COMPILE([#include <sys/types.h>
#include <netinet/in.h>
],[static struct sockaddr_in ac_i;int ac_j = sizeof (ac_i.sin_len);],
[AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_SIN_LEN)],
AC_MSG_RESULT(no))
dnl ----------------------------
dnl check sun_len of sockaddr_un
dnl ----------------------------
AC_MSG_CHECKING(whether struct sockaddr_un has a sun_len field)
AC_TRY_COMPILE([#include <sys/types.h>
#include <sys/un.h>
],[static struct sockaddr_un ac_i;int ac_j = sizeof (ac_i.sun_len);],
[AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_SUN_LEN)],
AC_MSG_RESULT(no))
dnl -----------------------------------
dnl check sin6_scope_id of sockaddr_in6
dnl -----------------------------------
if test "$zebra_cv_ipv6" = yes; then
AC_MSG_CHECKING(whether struct sockaddr_in6 has a sin6_scope_id field)
AC_TRY_COMPILE([#include <sys/types.h>
#include <netinet/in.h>
],[static struct sockaddr_in6 ac_i;int ac_j = sizeof (ac_i.sin6_scope_id);],
[AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_SIN6_SCOPE_ID)],
AC_MSG_RESULT(no))
fi
dnl ----------------------------
dnl check socklen_t exist or not
dnl ----------------------------
AC_MSG_CHECKING(whther socklen_t is defined)
AC_TRY_COMPILE([#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
],[socklen_t ac_x;],
[AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_SOCKLEN_T)],
AC_MSG_RESULT(no))
dnl ------------------------
dnl check struct sockaddr_dl
dnl ------------------------
AC_MSG_CHECKING(whether struct sockaddr_dl exist)
AC_EGREP_HEADER(sockaddr_dl,
net/if_dl.h,
[AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_SOCKADDR_DL)],
AC_MSG_RESULT(no))
dnl --------------------------
dnl check structure ifaliasreq
dnl --------------------------
AC_MSG_CHECKING(whether struct ifaliasreq exist)
AC_EGREP_HEADER(ifaliasreq,
net/if.h,
[AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_IFALIASREQ)],
AC_MSG_RESULT(no))
dnl ----------------------------
dnl check structure in6_aliasreq
dnl ----------------------------
AC_MSG_CHECKING(whether struct if6_aliasreq exist)
AC_EGREP_HEADER(in6_aliasreq,
netinet6/in6_var.h,
[AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_IN6_ALIASREQ)],
AC_MSG_RESULT(no))
dnl ---------------------------
dnl check structure rt_addrinfo
dnl ---------------------------
AC_MSG_CHECKING(whether struct rt_addrinfo exist)
AC_EGREP_HEADER(rt_addrinfo,
net/route.h,
[AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_RT_ADDRINFO)],
AC_MSG_RESULT(no))
dnl --------------------------
dnl check structure in_pktinfo
dnl --------------------------
AC_MSG_CHECKING(whether struct in_pktinfo exist)
AC_TRY_COMPILE([#include <netinet/in.h>
],[struct in_pktinfo ac_x;],
[AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_INPKTINFO)],
AC_MSG_RESULT(no))
dnl --------------------------------------
dnl checking for getrusage struct and call
dnl --------------------------------------
AC_MSG_CHECKING(whether getrusage is available)
AC_TRY_COMPILE([#include <sys/resource.h>
],[struct rusage ac_x; getrusage (RUSAGE_SELF, &ac_x);],
[AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_RUSAGE)],
AC_MSG_RESULT(no))
dnl -------------
dnl check version
dnl -------------
file="${srcdir}/lib/version.h"
VERSION=`sed -ne 's/^#.*ZEBRA_VERSION.*\"\([^\"]*\)\"$/\1/p' $file`
AC_SUBST(VERSION)
dnl ------------------------------
dnl set paths for process id files
dnl ------------------------------
AC_CACHE_CHECK(pid file directory,ac_piddir,
[for ZEBRA_PID_DIR in /var/run dnl
/var/adm dnl
/etc dnl
/dev/null;
do
test -d $ZEBRA_PID_DIR && break
done
ac_piddir=$ZEBRA_PID_DIR
if test $ZEBRA_PID_DIR = "/dev/null"; then
echo "PID DIRECTORY NOT FOUND!"
fi])
AC_DEFINE_UNQUOTED(PATH_ZEBRA_PID, "$ac_piddir/zebra.pid")
AC_DEFINE_UNQUOTED(PATH_RIPD_PID, "$ac_piddir/ripd.pid")
AC_DEFINE_UNQUOTED(PATH_RIPNGD_PID, "$ac_piddir/ripngd.pid")
AC_DEFINE_UNQUOTED(PATH_BGPD_PID, "$ac_piddir/bgpd.pid")
AC_DEFINE_UNQUOTED(PATH_OSPFD_PID, "$ac_piddir/ospfd.pid")
AC_DEFINE_UNQUOTED(PATH_OSPF6D_PID, "$ac_piddir/ospf6d.pid")
AC_DEFINE_UNQUOTED(PATH_ISISD_PID, "$ac_piddir/isisd.pid")
dnl ---------------------------
dnl Check htonl works correctly
dnl ---------------------------
AC_MSG_CHECKING(for working htonl)
AC_CACHE_VAL(ac_cv_htonl_works, [
AC_TRY_LINK([#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif],
[htonl (0);],
ac_cv_htonl_works=yes,
ac_cv_htonl_works=no)])
AC_MSG_RESULT($ac_cv_htonl_works)
AC_OUTPUT(Makefile lib/Makefile zebra/Makefile ripd/Makefile ripngd/Makefile bgpd/Makefile ospfd/Makefile ospf6d/Makefile isisd/Makefile vtysh/Makefile doc/Makefile)
echo "
zebra configuration
-------------------
zebra version : ${VERSION}
host operationg system : ${host_os}
source code location : ${srcdir}
compiler : ${CC}
compiler flags : ${CFLAGS}
directory for pid files : ${ac_piddir}
"

484
isisd/modified/log.c Normal file
View File

@ -0,0 +1,484 @@
/* Logging of zebra
* Copyright (C) 1997, 1998, 1999 Kunihiro Ishiguro
*
* 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 "log.h"
#include "memory.h"
#include "command.h"
struct zlog *zlog_default = NULL;
const char *zlog_proto_names[] =
{
"NONE",
"DEFAULT",
"ZEBRA",
"RIP",
"BGP",
"OSPF",
"RIPNG",
"OSPF6",
"ISIS",
"MASC",
NULL,
};
const char *zlog_priority[] =
{
"emergencies",
"alerts",
"critical",
"errors",
"warnings",
"notifications",
"informational",
"debugging",
NULL,
};
/* For time string format. */
#define TIME_BUF 27
/* Utility routine for current time printing. */
static void
time_print (FILE *fp)
{
int ret;
char buf [TIME_BUF];
time_t clock;
struct tm *tm;
time (&clock);
tm = localtime (&clock);
ret = strftime (buf, TIME_BUF, "%Y/%m/%d %H:%M:%S", tm);
if (ret == 0) {
zlog_warn ("strftime error");
}
fprintf (fp, "%s ", buf);
}
/* va_list version of zlog. */
void
vzlog (struct zlog *zl, int priority, const char *format, va_list *args)
{
/* If zlog is not specified, use default one. */
if (zl == NULL)
zl = zlog_default;
/* When zlog_default is also NULL, use stderr for logging. */
if (zl == NULL)
{
time_print (stderr);
fprintf (stderr, "%s: ", "unknown");
vfprintf (stderr, format, args[ZLOG_NOLOG_INDEX]);
fprintf (stderr, "\n");
fflush (stderr);
/* In this case we return at here. */
return;
}
/* only log this information if it has not been masked out */
if ( priority > zl->maskpri )
return ;
/* Syslog output */
if (zl->flags & ZLOG_SYSLOG)
vsyslog (priority, format, args[ZLOG_SYSLOG_INDEX]);
/* File output. */
if (zl->flags & ZLOG_FILE)
{
time_print (zl->fp);
if (zl->record_priority) fprintf (zl->fp, "%s: ", zlog_priority[priority]);
fprintf (zl->fp, "%s: ", zlog_proto_names[zl->protocol]);
vfprintf (zl->fp, format, args[ZLOG_FILE_INDEX]);
fprintf (zl->fp, "\n");
fflush (zl->fp);
}
/* stdout output. */
if (zl->flags & ZLOG_STDOUT)
{
time_print (stdout);
if (zl->record_priority) fprintf (stdout, "%s: ", zlog_priority[priority]);
fprintf (stdout, "%s: ", zlog_proto_names[zl->protocol]);
vfprintf (stdout, format, args[ZLOG_STDOUT_INDEX]);
fprintf (stdout, "\n");
fflush (stdout);
}
/* stderr output. */
if (zl->flags & ZLOG_STDERR)
{
time_print (stderr);
if (zl->record_priority) fprintf (stderr, "%s: ", zlog_priority[priority]);
fprintf (stderr, "%s: ", zlog_proto_names[zl->protocol]);
vfprintf (stderr, format, args[ZLOG_STDERR_INDEX]);
fprintf (stderr, "\n");
fflush (stderr);
}
/* Terminal monitor. */
vty_log (zlog_proto_names[zl->protocol], format, args[ZLOG_NOLOG_INDEX]);
}
void
zlog (struct zlog *zl, int priority, const char *format, ...)
{
va_list args[ZLOG_MAX_INDEX];
int index;
for (index = 0; index < ZLOG_MAX_INDEX; index++)
va_start(args[index], format);
vzlog (zl, priority, format, args);
for (index = 0; index < ZLOG_MAX_INDEX; index++)
va_end (args[index]);
}
void
zlog_err (const char *format, ...)
{
va_list args[ZLOG_MAX_INDEX];
int index;
for (index = 0; index < ZLOG_MAX_INDEX; index++)
va_start(args[index], format);
vzlog (NULL, LOG_ERR, format, args);
for (index = 0; index < ZLOG_MAX_INDEX; index++)
va_end (args[index]);
}
void
zlog_warn (const char *format, ...)
{
va_list args[ZLOG_MAX_INDEX];
int index;
for (index = 0; index < ZLOG_MAX_INDEX; index++)
va_start(args[index], format);
vzlog (NULL, LOG_WARNING, format, args);
for (index = 0; index < ZLOG_MAX_INDEX; index++)
va_end (args[index]);
}
void
zlog_info (const char *format, ...)
{
va_list args[ZLOG_MAX_INDEX];
int index;
for (index = 0; index < ZLOG_MAX_INDEX; index++)
va_start(args[index], format);
vzlog (NULL, LOG_INFO, format, args);
for (index = 0; index < ZLOG_MAX_INDEX; index++)
va_end (args[index]);
}
void
zlog_notice (const char *format, ...)
{
va_list args[ZLOG_MAX_INDEX];
int index;
for (index = 0; index < ZLOG_MAX_INDEX; index++)
va_start(args[index], format);
vzlog (NULL, LOG_NOTICE, format, args);
for (index = 0; index < ZLOG_MAX_INDEX; index++)
va_end (args[index]);
}
void
zlog_debug (const char *format, ...)
{
va_list args[ZLOG_MAX_INDEX];
int index;
for (index = 0; index < ZLOG_MAX_INDEX; index++)
va_start(args[index], format);
vzlog (NULL, LOG_DEBUG, format, args);
for (index = 0; index < ZLOG_MAX_INDEX; index++)
va_end (args[index]);
}
void
plog_err (struct zlog *zl, const char *format, ...)
{
va_list args[ZLOG_MAX_INDEX];
int index;
for (index = 0; index < ZLOG_MAX_INDEX; index++)
va_start(args[index], format);
vzlog (zl, LOG_ERR, format, args);
for (index = 0; index < ZLOG_MAX_INDEX; index++)
va_end (args[index]);
}
void
plog_warn (struct zlog *zl, const char *format, ...)
{
va_list args[ZLOG_MAX_INDEX];
int index;
for (index = 0; index < ZLOG_MAX_INDEX; index++)
va_start(args[index], format);
vzlog (zl, LOG_WARNING, format, args);
for (index = 0; index < ZLOG_MAX_INDEX; index++)
va_end (args[index]);
}
void
plog_info (struct zlog *zl, const char *format, ...)
{
va_list args[ZLOG_MAX_INDEX];
int index;
for (index = 0; index < ZLOG_MAX_INDEX; index++)
va_start(args[index], format);
vzlog (zl, LOG_INFO, format, args);
for (index = 0; index < ZLOG_MAX_INDEX; index++)
va_end (args[index]);
}
void
plog_notice (struct zlog *zl, const char *format, ...)
{
va_list args[ZLOG_MAX_INDEX];
int index;
for (index = 0; index < ZLOG_MAX_INDEX; index++)
va_start(args[index], format);
vzlog (zl, LOG_NOTICE, format, args);
for (index = 0; index < ZLOG_MAX_INDEX; index++)
va_end (args[index]);
}
void
plog_debug (struct zlog *zl, const char *format, ...)
{
va_list args[ZLOG_MAX_INDEX];
int index;
for (index = 0; index < ZLOG_MAX_INDEX; index++)
va_start(args[index], format);
vzlog (zl, LOG_DEBUG, format, args);
for (index = 0; index < ZLOG_MAX_INDEX; index++)
va_end (args[index]);
}
/* Open log stream */
struct zlog *
openzlog (const char *progname, int flags, zlog_proto_t protocol,
int syslog_flags, int syslog_facility)
{
struct zlog *zl;
zl = XMALLOC(MTYPE_ZLOG, sizeof (struct zlog));
memset (zl, 0, sizeof (struct zlog));
zl->ident = progname;
zl->flags = flags;
zl->protocol = protocol;
zl->facility = syslog_facility;
zl->maskpri = LOG_DEBUG;
zl->record_priority = 0;
openlog (progname, syslog_flags, zl->facility);
return zl;
}
void
closezlog (struct zlog *zl)
{
closelog();
fclose (zl->fp);
XFREE (MTYPE_ZLOG, zl);
}
/* Called from command.c. */
void
zlog_set_flag (struct zlog *zl, int flags)
{
if (zl == NULL)
zl = zlog_default;
zl->flags |= flags;
}
void
zlog_reset_flag (struct zlog *zl, int flags)
{
if (zl == NULL)
zl = zlog_default;
zl->flags &= ~flags;
}
int
zlog_set_file (struct zlog *zl, int flags, char *filename)
{
FILE *fp;
/* There is opend file. */
zlog_reset_file (zl);
/* Set default zl. */
if (zl == NULL)
zl = zlog_default;
/* Open file. */
fp = fopen (filename, "a");
if (fp == NULL)
return 0;
/* Set flags. */
zl->filename = strdup (filename);
zl->flags |= ZLOG_FILE;
zl->fp = fp;
return 1;
}
/* Reset opend file. */
int
zlog_reset_file (struct zlog *zl)
{
if (zl == NULL)
zl = zlog_default;
zl->flags &= ~ZLOG_FILE;
if (zl->fp)
fclose (zl->fp);
zl->fp = NULL;
if (zl->filename)
free (zl->filename);
zl->filename = NULL;
return 1;
}
/* Reopen log file. */
int
zlog_rotate (struct zlog *zl)
{
FILE *fp;
if (zl == NULL)
zl = zlog_default;
if (zl->fp)
fclose (zl->fp);
zl->fp = NULL;
if (zl->filename)
{
fp = fopen (zl->filename, "a");
if (fp == NULL)
return -1;
zl->fp = fp;
}
return 1;
}
static char *zlog_cwd = NULL;
void
zlog_save_cwd ()
{
char *cwd;
cwd = getcwd (NULL, MAXPATHLEN);
zlog_cwd = XMALLOC (MTYPE_TMP, strlen (cwd) + 1);
strcpy (zlog_cwd, cwd);
}
char *
zlog_get_cwd ()
{
return zlog_cwd;
}
void
zlog_free_cwd ()
{
if (zlog_cwd)
XFREE (MTYPE_TMP, zlog_cwd);
}
/* Message lookup function. */
char *
lookup (struct message *mes, int key)
{
struct message *pnt;
for (pnt = mes; pnt->key != 0; pnt++)
if (pnt->key == key)
return pnt->str;
return "";
}
/* Very old hacky version of message lookup function. Still partly
used in bgpd and ospfd. */
char *
mes_lookup (struct message *meslist, int max, int index)
{
if (index < 0 || index >= max)
{
zlog_err ("message index out of bound: %d", max);
return NULL;
}
return meslist[index].str;
}

129
isisd/modified/log.h Normal file
View File

@ -0,0 +1,129 @@
/* Zebra logging funcions.
* Copyright (C) 1997, 1998, 1999 Kunihiro Ishiguro
*
* 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.
*/
#ifndef _ZEBRA_LOG_H
#define _ZEBRA_LOG_H
#include <syslog.h>
#define ZLOG_NOLOG 0x00
#define ZLOG_FILE 0x01
#define ZLOG_SYSLOG 0x02
#define ZLOG_STDOUT 0x04
#define ZLOG_STDERR 0x08
#define ZLOG_NOLOG_INDEX 0
#define ZLOG_FILE_INDEX 1
#define ZLOG_SYSLOG_INDEX 2
#define ZLOG_STDOUT_INDEX 3
#define ZLOG_STDERR_INDEX 4
#define ZLOG_MAX_INDEX 5
typedef enum
{
ZLOG_NONE,
ZLOG_DEFAULT,
ZLOG_ZEBRA,
ZLOG_RIP,
ZLOG_BGP,
ZLOG_OSPF,
ZLOG_RIPNG,
ZLOG_OSPF6,
ZLOG_ISIS,
ZLOG_MASC
} zlog_proto_t;
struct zlog
{
const char *ident;
zlog_proto_t protocol;
int flags;
FILE *fp;
char *filename;
int syslog;
int stat;
int connected;
int maskpri; /* as per syslog setlogmask */
int priority; /* as per syslog priority */
int facility; /* as per syslog facility */
int record_priority;
};
/* Message structure. */
struct message
{
int key;
char *str;
};
/* Default logging strucutre. */
extern struct zlog *zlog_default;
/* Open zlog function */
struct zlog *openzlog (const char *, int, zlog_proto_t, int, int);
/* Close zlog function. */
void closezlog (struct zlog *zl);
/* GCC have printf type attribute check. */
#ifdef __GNUC__
#define PRINTF_ATTRIBUTE(a,b) __attribute__ ((__format__ (__printf__, a, b)))
#else
#define PRINTF_ATTRIBUTE(a,b)
#endif /* __GNUC__ */
/* Generic function for zlog. */
void zlog (struct zlog *zl, int priority, const char *format, ...) PRINTF_ATTRIBUTE(3, 4);
/* Handy zlog functions. */
void zlog_err (const char *format, ...) PRINTF_ATTRIBUTE(1, 2);
void zlog_warn (const char *format, ...) PRINTF_ATTRIBUTE(1, 2);
void zlog_info (const char *format, ...) PRINTF_ATTRIBUTE(1, 2);
void zlog_notice (const char *format, ...) PRINTF_ATTRIBUTE(1, 2);
void zlog_debug (const char *format, ...) PRINTF_ATTRIBUTE(1, 2);
/* For bgpd's peer oriented log. */
void plog_err (struct zlog *, const char *format, ...);
void plog_warn (struct zlog *, const char *format, ...);
void plog_info (struct zlog *, const char *format, ...);
void plog_notice (struct zlog *, const char *format, ...);
void plog_debug (struct zlog *, const char *format, ...);
/* Set zlog flags. */
void zlog_set_flag (struct zlog *zl, int flags);
void zlog_reset_flag (struct zlog *zl, int flags);
/* Set zlog filename. */
int zlog_set_file (struct zlog *zl, int flags, char *filename);
int zlog_reset_file (struct zlog *zl);
/* Rotate log. */
int zlog_rotate ();
/* For hackey massage lookup and check */
#define LOOKUP(x, y) mes_lookup(x, x ## _max, y)
char *lookup (struct message *, int);
char *mes_lookup (struct message *meslist, int max, int index);
extern const char *zlog_priority[];
#endif /* _ZEBRA_LOG_H */

527
isisd/modified/memory.c Normal file
View File

@ -0,0 +1,527 @@
/*
* Memory management routine
* Copyright (C) 1998 Kunihiro Ishiguro
*
* 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 "log.h"
#include "memory.h"
void alloc_inc (int);
void alloc_dec (int);
struct message mstr [] =
{
{ MTYPE_THREAD, "thread" },
{ MTYPE_THREAD_MASTER, "thread_master" },
{ MTYPE_VECTOR, "vector" },
{ MTYPE_VECTOR_INDEX, "vector_index" },
{ MTYPE_IF, "interface" },
{ 0, NULL },
};
/* Fatal memory allocation error occured. */
static void
zerror (const char *fname, int type, size_t size)
{
fprintf (stderr, "%s : can't allocate memory for `%s' size %d\n",
fname, lookup (mstr, type), (int) size);
exit (1);
}
/* Memory allocation. */
void *
zmalloc (int type, size_t size)
{
void *memory;
memory = malloc (size);
if (memory == NULL)
zerror ("malloc", type, size);
alloc_inc (type);
return memory;
}
/* Memory allocation with num * size with cleared. */
void *
zcalloc (int type, size_t size)
{
void *memory;
memory = calloc (1, size);
if (memory == NULL)
zerror ("calloc", type, size);
alloc_inc (type);
return memory;
}
/* Memory reallocation. */
void *
zrealloc (int type, void *ptr, size_t size)
{
void *memory;
memory = realloc (ptr, size);
if (memory == NULL)
zerror ("realloc", type, size);
return memory;
}
/* Memory free. */
void
zfree (int type, void *ptr)
{
alloc_dec (type);
free (ptr);
}
/* String duplication. */
char *
zstrdup (int type, char *str)
{
void *dup;
dup = strdup (str);
if (dup == NULL)
zerror ("strdup", type, strlen (str));
alloc_inc (type);
return dup;
}
#ifdef MEMORY_LOG
struct
{
char *name;
unsigned long alloc;
unsigned long t_malloc;
unsigned long c_malloc;
unsigned long t_calloc;
unsigned long c_calloc;
unsigned long t_realloc;
unsigned long t_free;
unsigned long c_strdup;
} mstat [MTYPE_MAX];
void
mtype_log (char *func, void *memory, const char *file, int line, int type)
{
zlog_info ("%s: %s %p %s %d", func, lookup (mstr, type), memory, file, line);
}
void *
mtype_zmalloc (const char *file, int line, int type, size_t size)
{
void *memory;
mstat[type].c_malloc++;
mstat[type].t_malloc++;
memory = zmalloc (type, size);
mtype_log ("zmalloc", memory, file, line, type);
return memory;
}
void *
mtype_zcalloc (const char *file, int line, int type, size_t size)
{
void *memory;
mstat[type].c_calloc++;
mstat[type].t_calloc++;
memory = zcalloc (type, size);
mtype_log ("xcalloc", memory, file, line, type);
return memory;
}
void *
mtype_zrealloc (const char *file, int line, int type, void *ptr, size_t size)
{
void *memory;
/* Realloc need before allocated pointer. */
mstat[type].t_realloc++;
memory = zrealloc (type, ptr, size);
mtype_log ("xrealloc", memory, file, line, type);
return memory;
}
/* Important function. */
void
mtype_zfree (const char *file, int line, int type, void *ptr)
{
mstat[type].t_free++;
mtype_log ("xfree", ptr, file, line, type);
zfree (type, ptr);
}
char *
mtype_zstrdup (const char *file, int line, int type, char *str)
{
char *memory;
mstat[type].c_strdup++;
memory = zstrdup (type, str);
mtype_log ("xstrdup", memory, file, line, type);
return memory;
}
#else
struct
{
char *name;
unsigned long alloc;
} mstat [MTYPE_MAX];
#endif /* MTPYE_LOG */
/* Increment allocation counter. */
void
alloc_inc (int type)
{
mstat[type].alloc++;
}
/* Decrement allocation counter. */
void
alloc_dec (int type)
{
mstat[type].alloc--;
}
/* Looking up memory status from vty interface. */
#include "vector.h"
#include "vty.h"
#include "command.h"
/* For pretty printng of memory allocate information. */
struct memory_list
{
int index;
char *format;
};
struct memory_list memory_list_lib[] =
{
{ MTYPE_TMP, "Temporary memory" },
{ MTYPE_ROUTE_TABLE, "Route table " },
{ MTYPE_ROUTE_NODE, "Route node " },
{ MTYPE_RIB, "RIB " },
{ MTYPE_NEXTHOP, "Nexthop " },
{ MTYPE_LINK_LIST, "Link List " },
{ MTYPE_LINK_NODE, "Link Node " },
{ MTYPE_HASH, "Hash " },
{ MTYPE_HASH_BACKET, "Hash Bucket " },
{ MTYPE_ACCESS_LIST, "Access List " },
{ MTYPE_ACCESS_LIST_STR, "Access List Str " },
{ MTYPE_ACCESS_FILTER, "Access Filter " },
{ MTYPE_PREFIX_LIST, "Prefix List " },
{ MTYPE_PREFIX_LIST_STR, "Prefix List Str " },
{ MTYPE_PREFIX_LIST_ENTRY, "Prefix List Entry "},
{ MTYPE_ROUTE_MAP, "Route map " },
{ MTYPE_ROUTE_MAP_NAME, "Route map name " },
{ MTYPE_ROUTE_MAP_INDEX, "Route map index " },
{ MTYPE_ROUTE_MAP_RULE, "Route map rule " },
{ MTYPE_ROUTE_MAP_RULE_STR, "Route map rule str" },
{ MTYPE_DESC, "Command desc " },
{ MTYPE_BUFFER, "Buffer " },
{ MTYPE_BUFFER_DATA, "Buffer data " },
{ MTYPE_STREAM, "Stream " },
{ MTYPE_KEYCHAIN, "Key chain " },
{ MTYPE_KEY, "Key " },
{ MTYPE_VTY, "VTY " },
{ -1, NULL }
};
struct memory_list memory_list_bgp[] =
{
{ MTYPE_BGP_PEER, "BGP peer" },
{ MTYPE_ATTR, "BGP attribute" },
{ MTYPE_AS_PATH, "BGP aspath" },
{ MTYPE_AS_SEG, "BGP aspath seg" },
{ MTYPE_AS_STR, "BGP aspath str" },
{ 0, NULL },
{ MTYPE_BGP_TABLE, "BGP table" },
{ MTYPE_BGP_NODE, "BGP node" },
{ MTYPE_BGP_ADVERTISE_ATTR, "BGP adv attr" },
{ MTYPE_BGP_ADVERTISE, "BGP adv" },
{ MTYPE_BGP_ADJ_IN, "BGP adj in" },
{ MTYPE_BGP_ADJ_OUT, "BGP adj out" },
{ 0, NULL },
{ MTYPE_AS_LIST, "BGP AS list" },
{ MTYPE_AS_FILTER, "BGP AS filter" },
{ MTYPE_AS_FILTER_STR, "BGP AS filter str" },
{ 0, NULL },
{ MTYPE_COMMUNITY, "community" },
{ MTYPE_COMMUNITY_VAL, "community val" },
{ MTYPE_COMMUNITY_STR, "community str" },
{ 0, NULL },
{ MTYPE_ECOMMUNITY, "extcommunity" },
{ MTYPE_ECOMMUNITY_VAL, "extcommunity val" },
{ MTYPE_ECOMMUNITY_STR, "extcommunity str" },
{ 0, NULL },
{ MTYPE_COMMUNITY_LIST, "community-list" },
{ MTYPE_COMMUNITY_LIST_NAME, "community-list name" },
{ MTYPE_COMMUNITY_LIST_ENTRY, "community-list entry" },
{ MTYPE_COMMUNITY_LIST_CONFIG, "community-list config" },
{ 0, NULL },
{ MTYPE_CLUSTER, "Cluster list" },
{ MTYPE_CLUSTER_VAL, "Cluster list val" },
{ 0, NULL },
{ MTYPE_TRANSIT, "BGP transit attr" },
{ MTYPE_TRANSIT_VAL, "BGP transit val" },
{ 0, NULL },
{ MTYPE_BGP_DISTANCE, "BGP distance" },
{ MTYPE_BGP_NEXTHOP_CACHE, "BGP nexthop" },
{ MTYPE_BGP_CONFED_LIST, "BGP confed list" },
{ MTYPE_PEER_UPDATE_SOURCE, "peer update if" },
{ MTYPE_BGP_DAMP_INFO, "Dampening info" },
{ MTYPE_BGP_REGEXP, "BGP regexp" },
{ -1, NULL }
};
struct memory_list memory_list_rip[] =
{
{ MTYPE_RIP, "RIP structure " },
{ MTYPE_RIP_INFO, "RIP route info " },
{ MTYPE_RIP_INTERFACE, "RIP interface " },
{ MTYPE_RIP_PEER, "RIP peer " },
{ MTYPE_RIP_OFFSET_LIST, "RIP offset list " },
{ MTYPE_RIP_DISTANCE, "RIP distance " },
{ -1, NULL }
};
struct memory_list memory_list_ospf[] =
{
{ MTYPE_OSPF_TOP, "OSPF top " },
{ MTYPE_OSPF_AREA, "OSPF area " },
{ MTYPE_OSPF_AREA_RANGE, "OSPF area range " },
{ MTYPE_OSPF_NETWORK, "OSPF network " },
#ifdef NBMA_ENABLE
{ MTYPE_OSPF_NEIGHBOR_STATIC,"OSPF static nbr " },
#endif /* NBMA_ENABLE */
{ MTYPE_OSPF_IF, "OSPF interface " },
{ MTYPE_OSPF_NEIGHBOR, "OSPF neighbor " },
{ MTYPE_OSPF_ROUTE, "OSPF route " },
{ MTYPE_OSPF_TMP, "OSPF tmp mem " },
{ MTYPE_OSPF_LSA, "OSPF LSA " },
{ MTYPE_OSPF_LSA_DATA, "OSPF LSA data " },
{ MTYPE_OSPF_LSDB, "OSPF LSDB " },
{ MTYPE_OSPF_PACKET, "OSPF packet " },
{ MTYPE_OSPF_FIFO, "OSPF FIFO queue " },
{ MTYPE_OSPF_VERTEX, "OSPF vertex " },
{ MTYPE_OSPF_NEXTHOP, "OSPF nexthop " },
{ MTYPE_OSPF_PATH, "OSPF path " },
{ MTYPE_OSPF_VL_DATA, "OSPF VL data " },
{ MTYPE_OSPF_CRYPT_KEY, "OSPF crypt key " },
{ MTYPE_OSPF_EXTERNAL_INFO, "OSPF ext. info " },
{ MTYPE_OSPF_DISTANCE, "OSPF distance " },
{ MTYPE_OSPF_IF_INFO, "OSPF if info " },
{ MTYPE_OSPF_IF_PARAMS, "OSPF if params " },
{ -1, NULL },
};
struct memory_list memory_list_ospf6[] =
{
{ MTYPE_OSPF6_TOP, "OSPF6 top " },
{ MTYPE_OSPF6_AREA, "OSPF6 area " },
{ MTYPE_OSPF6_IF, "OSPF6 interface " },
{ MTYPE_OSPF6_NEIGHBOR, "OSPF6 neighbor " },
{ MTYPE_OSPF6_ROUTE, "OSPF6 route " },
{ MTYPE_OSPF6_PREFIX, "OSPF6 prefix " },
{ MTYPE_OSPF6_MESSAGE, "OSPF6 message " },
{ MTYPE_OSPF6_LSA, "OSPF6 LSA " },
{ MTYPE_OSPF6_LSA_SUMMARY, "OSPF6 LSA summary " },
{ MTYPE_OSPF6_LSDB, "OSPF6 LSA database" },
{ MTYPE_OSPF6_VERTEX, "OSPF6 vertex " },
{ MTYPE_OSPF6_SPFTREE, "OSPF6 SPF tree " },
{ MTYPE_OSPF6_NEXTHOP, "OSPF6 nexthop " },
{ MTYPE_OSPF6_EXTERNAL_INFO,"OSPF6 ext. info " },
{ MTYPE_OSPF6_OTHER, "OSPF6 other " },
{ -1, NULL },
};
struct memory_list memory_list_isis[] =
{
{ MTYPE_ISIS, "ISIS : %ld\r\n" },
{ MTYPE_ISIS_TMP, "ISIS TMP : %ld\r\n" },
{ MTYPE_ISIS_CIRCUIT, "ISIS circuit : %ld\r\n" },
{ MTYPE_ISIS_LSP, "ISIS LSP : %ld\r\n" },
{ MTYPE_ISIS_ADJACENCY, "ISIS adjacency : %ld\r\n" },
{ MTYPE_ISIS_AREA, "ISIS area : %ld\r\n" },
{ MTYPE_ISIS_AREA_ADDR, "ISIS area address: %ld\r\n" },
{ MTYPE_ISIS_TLV, "ISIS TLV : %ld\r\n" },
{ MTYPE_ISIS_DYNHN, "ISIS dyn hostname: %ld\r\n" },
{ MTYPE_ISIS_SPFTREE, "ISIS SPFtree : %ld\r\n" },
{ MTYPE_ISIS_VERTEX, "ISIS vertex : %ld\r\n" },
{ MTYPE_ISIS_ROUTE_INFO, "ISIS route info : %ld\r\n" },
{ MTYPE_ISIS_NEXTHOP, "ISIS nexthop : %ld\r\n" },
{ MTYPE_ISIS_NEXTHOP6, "ISIS nexthop6 : %ld\r\n" },
{ -1, NULL },
};
struct memory_list memory_list_separator[] =
{
{ 0, NULL},
{-1, NULL}
};
void
show_memory_vty (struct vty *vty, struct memory_list *list)
{
struct memory_list *m;
for (m = list; m->index >= 0; m++)
if (m->index == 0)
vty_out (vty, "-----------------------------\r\n");
else
vty_out (vty, "%-22s: %5ld\r\n", m->format, mstat[m->index].alloc);
}
DEFUN (show_memory_all,
show_memory_all_cmd,
"show memory all",
"Show running system information\n"
"Memory statistics\n"
"All memory statistics\n")
{
show_memory_vty (vty, memory_list_lib);
show_memory_vty (vty, memory_list_separator);
show_memory_vty (vty, memory_list_rip);
show_memory_vty (vty, memory_list_separator);
show_memory_vty (vty, memory_list_ospf);
show_memory_vty (vty, memory_list_separator);
show_memory_vty (vty, memory_list_ospf6);
show_memory_vty (vty, memory_list_separator);
show_memory_vty (vty, memory_list_bgp);
return CMD_SUCCESS;
}
ALIAS (show_memory_all,
show_memory_cmd,
"show memory",
"Show running system information\n"
"Memory statistics\n")
DEFUN (show_memory_lib,
show_memory_lib_cmd,
"show memory lib",
SHOW_STR
"Memory statistics\n"
"Library memory\n")
{
show_memory_vty (vty, memory_list_lib);
return CMD_SUCCESS;
}
DEFUN (show_memory_rip,
show_memory_rip_cmd,
"show memory rip",
SHOW_STR
"Memory statistics\n"
"RIP memory\n")
{
show_memory_vty (vty, memory_list_rip);
return CMD_SUCCESS;
}
DEFUN (show_memory_bgp,
show_memory_bgp_cmd,
"show memory bgp",
SHOW_STR
"Memory statistics\n"
"BGP memory\n")
{
show_memory_vty (vty, memory_list_bgp);
return CMD_SUCCESS;
}
DEFUN (show_memory_ospf,
show_memory_ospf_cmd,
"show memory ospf",
SHOW_STR
"Memory statistics\n"
"OSPF memory\n")
{
show_memory_vty (vty, memory_list_ospf);
return CMD_SUCCESS;
}
DEFUN (show_memory_ospf6,
show_memory_ospf6_cmd,
"show memory ospf6",
SHOW_STR
"Memory statistics\n"
"OSPF6 memory\n")
{
show_memory_vty (vty, memory_list_ospf6);
return CMD_SUCCESS;
}
DEFUN (show_memory_isis,
show_memory_isis_cmd,
"show memory isis",
SHOW_STR
"Memory statistics\n"
"ISIS memory\n")
{
show_memory_vty (vty, memory_list_isis);
return CMD_SUCCESS;
}
void
memory_init ()
{
install_element (VIEW_NODE, &show_memory_cmd);
install_element (VIEW_NODE, &show_memory_all_cmd);
install_element (VIEW_NODE, &show_memory_lib_cmd);
install_element (VIEW_NODE, &show_memory_rip_cmd);
install_element (VIEW_NODE, &show_memory_bgp_cmd);
install_element (VIEW_NODE, &show_memory_ospf_cmd);
install_element (VIEW_NODE, &show_memory_ospf6_cmd);
install_element (VIEW_NODE, &show_memory_isis_cmd);
install_element (ENABLE_NODE, &show_memory_cmd);
install_element (ENABLE_NODE, &show_memory_all_cmd);
install_element (ENABLE_NODE, &show_memory_lib_cmd);
install_element (ENABLE_NODE, &show_memory_rip_cmd);
install_element (ENABLE_NODE, &show_memory_bgp_cmd);
install_element (ENABLE_NODE, &show_memory_ospf_cmd);
install_element (ENABLE_NODE, &show_memory_ospf6_cmd);
install_element (ENABLE_NODE, &show_memory_isis_cmd);
}

257
isisd/modified/memory.h Normal file
View File

@ -0,0 +1,257 @@
/* Memory management routine
Copyright (C) 1998 Kunihiro Ishiguro
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. */
#ifndef _ZEBRA_MEMORY_H
#define _ZEBRA_MEMORY_H
/* #define MEMORY_LOG */
/* For tagging memory, below is the type of the memory. */
enum
{
MTYPE_TMP = 1,
MTYPE_STRVEC,
MTYPE_VECTOR,
MTYPE_VECTOR_INDEX,
MTYPE_LINK_LIST,
MTYPE_LINK_NODE,
MTYPE_THREAD,
MTYPE_THREAD_MASTER,
MTYPE_VTY,
MTYPE_VTY_HIST,
MTYPE_VTY_OUT_BUF,
MTYPE_IF,
MTYPE_CONNECTED,
MTYPE_AS_SEG,
MTYPE_AS_STR,
MTYPE_AS_PATH,
MTYPE_CLUSTER,
MTYPE_CLUSTER_VAL,
MTYPE_ATTR,
MTYPE_TRANSIT,
MTYPE_TRANSIT_VAL,
MTYPE_BUFFER,
MTYPE_BUFFER_DATA,
MTYPE_STREAM,
MTYPE_STREAM_DATA,
MTYPE_STREAM_FIFO,
MTYPE_PREFIX,
MTYPE_PREFIX_IPV4,
MTYPE_PREFIX_IPV6,
MTYPE_HASH,
MTYPE_HASH_INDEX,
MTYPE_HASH_BACKET,
MTYPE_RIPNG_ROUTE,
MTYPE_RIPNG_AGGREGATE,
MTYPE_ROUTE_TABLE,
MTYPE_ROUTE_NODE,
MTYPE_ACCESS_LIST,
MTYPE_ACCESS_LIST_STR,
MTYPE_ACCESS_FILTER,
MTYPE_PREFIX_LIST,
MTYPE_PREFIX_LIST_STR,
MTYPE_PREFIX_LIST_ENTRY,
MTYPE_ROUTE_MAP,
MTYPE_ROUTE_MAP_NAME,
MTYPE_ROUTE_MAP_INDEX,
MTYPE_ROUTE_MAP_RULE,
MTYPE_ROUTE_MAP_RULE_STR,
MTYPE_ROUTE_MAP_COMPILED,
MTYPE_RIB,
MTYPE_DISTRIBUTE,
MTYPE_ZLOG,
MTYPE_ZCLIENT,
MTYPE_NEXTHOP,
MTYPE_RTADV_PREFIX,
MTYPE_IF_RMAP,
MTYPE_SOCKUNION,
MTYPE_STATIC_IPV4,
MTYPE_STATIC_IPV6,
MTYPE_DESC,
MTYPE_OSPF_TOP,
MTYPE_OSPF_AREA,
MTYPE_OSPF_AREA_RANGE,
MTYPE_OSPF_NETWORK,
MTYPE_OSPF_NEIGHBOR_STATIC,
MTYPE_OSPF_IF,
MTYPE_OSPF_NEIGHBOR,
MTYPE_OSPF_ROUTE,
MTYPE_OSPF_TMP,
MTYPE_OSPF_LSA,
MTYPE_OSPF_LSA_DATA,
MTYPE_OSPF_LSDB,
MTYPE_OSPF_PACKET,
MTYPE_OSPF_FIFO,
MTYPE_OSPF_VERTEX,
MTYPE_OSPF_NEXTHOP,
MTYPE_OSPF_PATH,
MTYPE_OSPF_VL_DATA,
MTYPE_OSPF_CRYPT_KEY,
MTYPE_OSPF_EXTERNAL_INFO,
MTYPE_OSPF_MESSAGE,
MTYPE_OSPF_DISTANCE,
MTYPE_OSPF_IF_INFO,
MTYPE_OSPF_IF_PARAMS,
MTYPE_OSPF6_TOP,
MTYPE_OSPF6_AREA,
MTYPE_OSPF6_IF,
MTYPE_OSPF6_NEIGHBOR,
MTYPE_OSPF6_ROUTE,
MTYPE_OSPF6_PREFIX,
MTYPE_OSPF6_MESSAGE,
MTYPE_OSPF6_LSA,
MTYPE_OSPF6_LSA_SUMMARY,
MTYPE_OSPF6_LSDB,
MTYPE_OSPF6_VERTEX,
MTYPE_OSPF6_SPFTREE,
MTYPE_OSPF6_NEXTHOP,
MTYPE_OSPF6_EXTERNAL_INFO,
MTYPE_OSPF6_OTHER,
MTYPE_ISIS,
MTYPE_ISIS_TMP,
MTYPE_ISIS_CIRCUIT,
MTYPE_ISIS_LSP,
MTYPE_ISIS_ADJACENCY,
MTYPE_ISIS_AREA,
MTYPE_ISIS_AREA_ADDR,
MTYPE_ISIS_TLV,
MTYPE_ISIS_DYNHN,
MTYPE_ISIS_SPFTREE,
MTYPE_ISIS_VERTEX,
MTYPE_ISIS_ROUTE_INFO,
MTYPE_ISIS_NEXTHOP,
MTYPE_ISIS_NEXTHOP6,
MTYPE_BGP,
MTYPE_BGP_PEER,
MTYPE_PEER_GROUP,
MTYPE_PEER_DESC,
MTYPE_PEER_UPDATE_SOURCE,
MTYPE_BGP_STATIC,
MTYPE_BGP_AGGREGATE,
MTYPE_BGP_CONFED_LIST,
MTYPE_BGP_NEXTHOP_CACHE,
MTYPE_BGP_DAMP_INFO,
MTYPE_BGP_DAMP_ARRAY,
MTYPE_BGP_ANNOUNCE,
MTYPE_BGP_ATTR_QUEUE,
MTYPE_BGP_ROUTE_QUEUE,
MTYPE_BGP_DISTANCE,
MTYPE_BGP_ROUTE,
MTYPE_BGP_TABLE,
MTYPE_BGP_NODE,
MTYPE_BGP_ADVERTISE_ATTR,
MTYPE_BGP_ADVERTISE,
MTYPE_BGP_ADJ_IN,
MTYPE_BGP_ADJ_OUT,
MTYPE_BGP_REGEXP,
MTYPE_AS_FILTER,
MTYPE_AS_FILTER_STR,
MTYPE_AS_LIST,
MTYPE_COMMUNITY,
MTYPE_COMMUNITY_VAL,
MTYPE_COMMUNITY_STR,
MTYPE_ECOMMUNITY,
MTYPE_ECOMMUNITY_VAL,
MTYPE_ECOMMUNITY_STR,
/* community-list and extcommunity-list. */
MTYPE_COMMUNITY_LIST_HANDLER,
MTYPE_COMMUNITY_LIST,
MTYPE_COMMUNITY_LIST_NAME,
MTYPE_COMMUNITY_LIST_ENTRY,
MTYPE_COMMUNITY_LIST_CONFIG,
MTYPE_RIP,
MTYPE_RIP_INTERFACE,
MTYPE_RIP_DISTANCE,
MTYPE_RIP_OFFSET_LIST,
MTYPE_RIP_INFO,
MTYPE_RIP_PEER,
MTYPE_KEYCHAIN,
MTYPE_KEY,
MTYPE_VTYSH_CONFIG,
MTYPE_VTYSH_CONFIG_LINE,
MTYPE_MAX
};
#ifdef MEMORY_LOG
#define XMALLOC(mtype, size) \
mtype_zmalloc (__FILE__, __LINE__, (mtype), (size))
#define XCALLOC(mtype, size) \
mtype_zcalloc (__FILE__, __LINE__, (mtype), (size))
#define XREALLOC(mtype, ptr, size) \
mtype_zrealloc (__FILE__, __LINE__, (mtype), (ptr), (size))
#define XFREE(mtype, ptr) \
mtype_zfree (__FILE__, __LINE__, (mtype), (ptr))
#define XSTRDUP(mtype, str) \
mtype_zstrdup (__FILE__, __LINE__, (mtype), (str))
#else
#define XMALLOC(mtype, size) zmalloc ((mtype), (size))
#define XCALLOC(mtype, size) zcalloc ((mtype), (size))
#define XREALLOC(mtype, ptr, size) zrealloc ((mtype), (ptr), (size))
#define XFREE(mtype, ptr) zfree ((mtype), (ptr))
#define XSTRDUP(mtype, str) zstrdup ((mtype), (str))
#endif /* MEMORY_LOG */
/* Prototypes of memory function. */
void *zmalloc (int type, size_t size);
void *zcalloc (int type, size_t size);
void *zrealloc (int type, void *ptr, size_t size);
void zfree (int type, void *ptr);
char *zstrdup (int type, char *str);
void *mtype_zmalloc (const char *file,
int line,
int type,
size_t size);
void *mtype_zcalloc (const char *file,
int line,
int type,
size_t num,
size_t size);
void *mtype_zrealloc (const char *file,
int line,
int type,
void *ptr,
size_t size);
void mtype_zfree (const char *file,
int line,
int type,
void *ptr);
char *mtype_zstrdup (const char *file,
int line,
int type,
char *str);
void memory_init ();
#endif /* _ZEBRA_MEMORY_H */

3321
isisd/modified/rib.c Normal file

File diff suppressed because it is too large Load Diff

713
isisd/modified/thread.c Normal file
View File

@ -0,0 +1,713 @@
/* Thread management routine
* Copyright (C) 1998, 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
*
* 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.
*/
/* #define DEBUG */
#include <zebra.h>
#include "thread.h"
#include "memory.h"
#include "log.h"
/* Struct timeval's tv_usec one second value. */
#define TIMER_SECOND_MICRO 1000000L
struct timeval
timeval_adjust (struct timeval a)
{
while (a.tv_usec >= TIMER_SECOND_MICRO)
{
a.tv_usec -= TIMER_SECOND_MICRO;
a.tv_sec++;
}
while (a.tv_usec < 0)
{
a.tv_usec += TIMER_SECOND_MICRO;
a.tv_sec--;
}
if (a.tv_sec < 0)
{
a.tv_sec = 0;
a.tv_usec = 10;
}
if (a.tv_sec > TIMER_SECOND_MICRO)
a.tv_sec = TIMER_SECOND_MICRO;
return a;
}
static struct timeval
timeval_subtract (struct timeval a, struct timeval b)
{
struct timeval ret;
ret.tv_usec = a.tv_usec - b.tv_usec;
ret.tv_sec = a.tv_sec - b.tv_sec;
return timeval_adjust (ret);
}
static int
timeval_cmp (struct timeval a, struct timeval b)
{
return (a.tv_sec == b.tv_sec
? a.tv_usec - b.tv_usec : a.tv_sec - b.tv_sec);
}
static unsigned long
timeval_elapsed (struct timeval a, struct timeval b)
{
return (((a.tv_sec - b.tv_sec) * TIMER_SECOND_MICRO)
+ (a.tv_usec - b.tv_usec));
}
/* List allocation and head/tail print out. */
static void
thread_list_debug (struct thread_list *list)
{
printf ("count [%d] head [%p] tail [%p]\n",
list->count, list->head, list->tail);
}
/* Debug print for thread_master. */
void
thread_master_debug (struct thread_master *m)
{
printf ("-----------\n");
printf ("readlist : ");
thread_list_debug (&m->read);
printf ("writelist : ");
thread_list_debug (&m->write);
printf ("timerlist : ");
thread_list_debug (&m->timer);
printf ("eventlist : ");
thread_list_debug (&m->event);
printf ("unuselist : ");
thread_list_debug (&m->unuse);
printf ("total alloc: [%ld]\n", m->alloc);
printf ("-----------\n");
}
/* Allocate new thread master. */
struct thread_master *
thread_master_create ()
{
return (struct thread_master *) XCALLOC (MTYPE_THREAD_MASTER,
sizeof (struct thread_master));
}
/* Add a new thread to the list. */
static void
thread_list_add (struct thread_list *list, struct thread *thread)
{
thread->next = NULL;
thread->prev = list->tail;
if (list->tail)
list->tail->next = thread;
else
list->head = thread;
list->tail = thread;
list->count++;
}
/* Add a new thread just before the point. */
static void
thread_list_add_before (struct thread_list *list,
struct thread *point,
struct thread *thread)
{
thread->next = point;
thread->prev = point->prev;
if (point->prev)
point->prev->next = thread;
else
list->head = thread;
point->prev = thread;
list->count++;
}
/* Delete a thread from the list. */
static struct thread *
thread_list_delete (struct thread_list *list, struct thread *thread)
{
if (thread->next)
thread->next->prev = thread->prev;
else
list->tail = thread->prev;
if (thread->prev)
thread->prev->next = thread->next;
else
list->head = thread->next;
thread->next = thread->prev = NULL;
list->count--;
return thread;
}
/* Move thread to unuse list. */
static void
thread_add_unuse (struct thread_master *m, struct thread *thread)
{
assert (m != NULL);
assert (thread->next == NULL);
assert (thread->prev == NULL);
assert (thread->type == THREAD_UNUSED);
thread_list_add (&m->unuse, thread);
}
/* Free all unused thread. */
static void
thread_list_free (struct thread_master *m, struct thread_list *list)
{
struct thread *t;
struct thread *next;
for (t = list->head; t; t = next)
{
next = t->next;
XFREE (MTYPE_THREAD, t);
list->count--;
m->alloc--;
}
}
/* Stop thread scheduler. */
void
thread_master_free (struct thread_master *m)
{
thread_list_free (m, &m->read);
thread_list_free (m, &m->write);
thread_list_free (m, &m->timer);
thread_list_free (m, &m->event);
thread_list_free (m, &m->ready);
thread_list_free (m, &m->unuse);
XFREE (MTYPE_THREAD_MASTER, m);
}
/* Delete top of the list and return it. */
static struct thread *
thread_trim_head (struct thread_list *list)
{
if (list->head)
return thread_list_delete (list, list->head);
return NULL;
}
/* Thread list is empty or not. */
int
thread_empty (struct thread_list *list)
{
return list->head ? 0 : 1;
}
/* Return remain time in second. */
unsigned long
thread_timer_remain_second (struct thread *thread)
{
struct timeval timer_now;
gettimeofday (&timer_now, NULL);
if (thread->u.sands.tv_sec - timer_now.tv_sec > 0)
return thread->u.sands.tv_sec - timer_now.tv_sec;
else
return 0;
}
/* Get new thread. */
static struct thread *
thread_get (struct thread_master *m, u_char type,
int (*func) (struct thread *), void *arg)
{
struct thread *thread;
if (m->unuse.head)
thread = thread_trim_head (&m->unuse);
else
{
thread = XCALLOC (MTYPE_THREAD, sizeof (struct thread));
m->alloc++;
}
thread->type = type;
thread->master = m;
thread->func = func;
thread->arg = arg;
return thread;
}
/* Add new read thread. */
struct thread *
thread_add_read (struct thread_master *m,
int (*func) (struct thread *), void *arg, int fd)
{
struct thread *thread;
assert (m != NULL);
if (FD_ISSET (fd, &m->readfd))
{
zlog (NULL, LOG_WARNING, "There is already read fd [%d]", fd);
return NULL;
}
thread = thread_get (m, THREAD_READ, func, arg);
FD_SET (fd, &m->readfd);
thread->u.fd = fd;
thread_list_add (&m->read, thread);
return thread;
}
/* Add new write thread. */
struct thread *
thread_add_write (struct thread_master *m,
int (*func) (struct thread *), void *arg, int fd)
{
struct thread *thread;
assert (m != NULL);
if (FD_ISSET (fd, &m->writefd))
{
zlog (NULL, LOG_WARNING, "There is already write fd [%d]", fd);
return NULL;
}
thread = thread_get (m, THREAD_WRITE, func, arg);
FD_SET (fd, &m->writefd);
thread->u.fd = fd;
thread_list_add (&m->write, thread);
return thread;
}
/* Add timer event thread. */
struct thread *
thread_add_timer (struct thread_master *m,
int (*func) (struct thread *), void *arg, long timer)
{
struct timeval timer_now;
struct thread *thread;
#ifndef TIMER_NO_SORT
struct thread *tt;
#endif /* TIMER_NO_SORT */
assert (m != NULL);
thread = thread_get (m, THREAD_TIMER, func, arg);
/* Do we need jitter here? */
gettimeofday (&timer_now, NULL);
timer_now.tv_sec += timer;
thread->u.sands = timer_now;
/* Sort by timeval. */
#ifdef TIMER_NO_SORT
thread_list_add (&m->timer, thread);
#else
for (tt = m->timer.head; tt; tt = tt->next)
if (timeval_cmp (thread->u.sands, tt->u.sands) <= 0)
break;
if (tt)
thread_list_add_before (&m->timer, tt, thread);
else
thread_list_add (&m->timer, thread);
#endif /* TIMER_NO_SORT */
return thread;
}
/* Add timer event thread with "millisecond" resolution */
struct thread *
thread_add_timer_msec (struct thread_master *m,
int (*func)(struct thread *),
void *arg, long timer)
{
struct timeval timer_now;
struct thread *thread;
#ifndef TIMER_NO_SORT
struct thread *tt;
#endif /* TIMER_NO_SORT */
assert (m != NULL);
thread = thread_get (m, THREAD_TIMER, func, arg);
timer = 1000*timer; /* milli -> micro */
gettimeofday (&timer_now, NULL);
timer_now.tv_sec += timer / TIMER_SECOND_MICRO;
timer_now.tv_usec += (timer % TIMER_SECOND_MICRO);
thread->u.sands = timer_now;
/* Sort by timeval. */
#ifdef TIMER_NO_SORT
thread_list_add (&m->timer, thread);
#else
for (tt = m->timer.head; tt; tt = tt->next)
if (timeval_cmp (thread->u.sands, tt->u.sands) <= 0)
break;
if (tt)
thread_list_add_before (&m->timer, tt, thread);
else
thread_list_add (&m->timer, thread);
#endif /* TIMER_NO_SORT */
return thread;
}
/* Add simple event thread. */
struct thread *
thread_add_event (struct thread_master *m,
int (*func) (struct thread *), void *arg, int val)
{
struct thread *thread;
assert (m != NULL);
thread = thread_get (m, THREAD_EVENT, func, arg);
thread->u.val = val;
thread_list_add (&m->event, thread);
return thread;
}
/* Cancel thread from scheduler. */
void
thread_cancel (struct thread *thread)
{
switch (thread->type)
{
case THREAD_READ:
assert (FD_ISSET (thread->u.fd, &thread->master->readfd));
FD_CLR (thread->u.fd, &thread->master->readfd);
thread_list_delete (&thread->master->read, thread);
break;
case THREAD_WRITE:
assert (FD_ISSET (thread->u.fd, &thread->master->writefd));
FD_CLR (thread->u.fd, &thread->master->writefd);
thread_list_delete (&thread->master->write, thread);
break;
case THREAD_TIMER:
thread_list_delete (&thread->master->timer, thread);
break;
case THREAD_EVENT:
thread_list_delete (&thread->master->event, thread);
break;
case THREAD_READY:
thread_list_delete (&thread->master->ready, thread);
break;
case THREAD_UNUSED:
thread_list_delete (&thread->master->unuse, thread);
break;
default:
break;
}
thread->type = THREAD_UNUSED;
thread_add_unuse (thread->master, thread);
}
/* Delete all events which has argument value arg. */
void
thread_cancel_event (struct thread_master *m, void *arg)
{
struct thread *thread;
thread = m->event.head;
while (thread)
{
struct thread *t;
t = thread;
thread = t->next;
if (t->arg == arg)
{
thread_list_delete (&m->event, t);
t->type = THREAD_UNUSED;
thread_add_unuse (m, t);
}
}
}
#ifdef TIMER_NO_SORT
struct timeval *
thread_timer_wait (struct thread_master *m, struct timeval *timer_val)
{
struct timeval timer_now;
struct timeval timer_min;
struct timeval *timer_wait;
gettimeofday (&timer_now, NULL);
timer_wait = NULL;
for (thread = m->timer.head; thread; thread = thread->next)
{
if (! timer_wait)
timer_wait = &thread->u.sands;
else if (timeval_cmp (thread->u.sands, *timer_wait) < 0)
timer_wait = &thread->u.sands;
}
if (m->timer.head)
{
timer_min = *timer_wait;
timer_min = timeval_subtract (timer_min, timer_now);
if (timer_min.tv_sec < 0)
{
timer_min.tv_sec = 0;
timer_min.tv_usec = 10;
}
timer_wait = &timer_min;
}
else
timer_wait = NULL;
if (timer_wait)
{
*timer_val = timer_wait;
return timer_val;
}
return NULL;
}
#else /* ! TIMER_NO_SORT */
struct timeval *
thread_timer_wait (struct thread_master *m, struct timeval *timer_val)
{
struct timeval timer_now;
struct timeval timer_min;
if (m->timer.head)
{
gettimeofday (&timer_now, NULL);
timer_min = m->timer.head->u.sands;
timer_min = timeval_subtract (timer_min, timer_now);
if (timer_min.tv_sec < 0)
{
timer_min.tv_sec = 0;
timer_min.tv_usec = 10;
}
*timer_val = timer_min;
return timer_val;
}
return NULL;
}
#endif /* TIMER_NO_SORT */
struct thread *
thread_run (struct thread_master *m, struct thread *thread,
struct thread *fetch)
{
*fetch = *thread;
thread->type = THREAD_UNUSED;
thread_add_unuse (m, thread);
return fetch;
}
int
thread_process_fd (struct thread_master *m, struct thread_list *list,
fd_set *fdset, fd_set *mfdset)
{
struct thread *thread;
struct thread *next;
int ready = 0;
for (thread = list->head; thread; thread = next)
{
next = thread->next;
if (FD_ISSET (THREAD_FD (thread), fdset))
{
assert (FD_ISSET (THREAD_FD (thread), mfdset));
FD_CLR(THREAD_FD (thread), mfdset);
thread_list_delete (list, thread);
thread_list_add (&m->ready, thread);
thread->type = THREAD_READY;
ready++;
}
}
return ready;
}
/* Fetch next ready thread. */
struct thread *
thread_fetch (struct thread_master *m, struct thread *fetch)
{
int num;
int ready;
struct thread *thread;
fd_set readfd;
fd_set writefd;
fd_set exceptfd;
struct timeval timer_now;
struct timeval timer_val;
struct timeval *timer_wait;
struct timeval timer_nowait;
timer_nowait.tv_sec = 0;
timer_nowait.tv_usec = 0;
while (1)
{
/* Normal event is the highest priority. */
if ((thread = thread_trim_head (&m->event)) != NULL)
return thread_run (m, thread, fetch);
/* Execute timer. */
gettimeofday (&timer_now, NULL);
for (thread = m->timer.head; thread; thread = thread->next)
if (timeval_cmp (timer_now, thread->u.sands) >= 0)
{
thread_list_delete (&m->timer, thread);
return thread_run (m, thread, fetch);
}
/* If there are any ready threads, process top of them. */
if ((thread = thread_trim_head (&m->ready)) != NULL)
return thread_run (m, thread, fetch);
/* Structure copy. */
readfd = m->readfd;
writefd = m->writefd;
exceptfd = m->exceptfd;
/* Calculate select wait timer. */
timer_wait = thread_timer_wait (m, &timer_val);
num = select (FD_SETSIZE, &readfd, &writefd, &exceptfd, timer_wait);
if (num == 0)
continue;
if (num < 0)
{
if (errno == EINTR)
continue;
zlog_warn ("select() error: %s", strerror (errno));
return NULL;
}
/* Normal priority read thead. */
ready = thread_process_fd (m, &m->read, &readfd, &m->readfd);
/* Write thead. */
ready = thread_process_fd (m, &m->write, &writefd, &m->writefd);
if ((thread = thread_trim_head (&m->ready)) != NULL)
return thread_run (m, thread, fetch);
}
}
static unsigned long
thread_consumed_time (RUSAGE_T *now, RUSAGE_T *start)
{
unsigned long thread_time;
#ifdef HAVE_RUSAGE
/* This is 'user + sys' time. */
thread_time = timeval_elapsed (now->ru_utime, start->ru_utime);
thread_time += timeval_elapsed (now->ru_stime, start->ru_stime);
#else
/* When rusage is not available, simple elapsed time is used. */
thread_time = timeval_elapsed (*now, *start);
#endif /* HAVE_RUSAGE */
return thread_time;
}
/* We should aim to yield after THREAD_YIELD_TIME_SLOT
milliseconds. */
int
thread_should_yield (struct thread *thread)
{
RUSAGE_T ru;
GETRUSAGE (&ru);
if (thread_consumed_time (&ru, &thread->ru) > THREAD_YIELD_TIME_SLOT)
return 1;
else
return 0;
}
/* We check thread consumed time. If the system has getrusage, we'll
use that to get indepth stats on the performance of the thread. If
not - we'll use gettimeofday for some guestimation. */
void
thread_call (struct thread *thread)
{
unsigned long thread_time;
RUSAGE_T ru;
GETRUSAGE (&thread->ru);
(*thread->func) (thread);
GETRUSAGE (&ru);
thread_time = thread_consumed_time (&ru, &thread->ru);
#ifdef THREAD_CONSUMED_TIME_CHECK
if (thread_time > 200000L)
{
/*
* We have a CPU Hog on our hands.
* Whinge about it now, so we're aware this is yet another task
* to fix.
*/
zlog_err ("CPU HOG task %lx ran for %ldms",
/* FIXME: report the name of the function somehow */
(unsigned long) thread->func,
thread_time / 1000L);
}
#endif /* THREAD_CONSUMED_TIME_CHECK */
}
/* Execute thread */
struct thread *
thread_execute (struct thread_master *m,
int (*func)(struct thread *),
void *arg,
int val)
{
struct thread dummy;
memset (&dummy, 0, sizeof (struct thread));
dummy.type = THREAD_EVENT;
dummy.master = NULL;
dummy.func = func;
dummy.arg = arg;
dummy.u.val = val;
thread_call (&dummy);
return NULL;
}

141
isisd/modified/thread.h Normal file
View File

@ -0,0 +1,141 @@
/* Thread management routine header.
* Copyright (C) 1998 Kunihiro Ishiguro
*
* 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.
*/
#ifndef _ZEBRA_THREAD_H
#define _ZEBRA_THREAD_H
#ifdef HAVE_RUSAGE
#define RUSAGE_T struct rusage
#define GETRUSAGE(X) getrusage (RUSAGE_SELF, X);
#else
#define RUSAGE_T struct timeval
#define GETRUSAGE(X) gettimeofday (X, NULL);
#endif /* HAVE_RUSAGE */
/* Linked list of thread. */
struct thread_list
{
struct thread *head;
struct thread *tail;
int count;
};
/* Master of the theads. */
struct thread_master
{
struct thread_list read;
struct thread_list write;
struct thread_list timer;
struct thread_list event;
struct thread_list ready;
struct thread_list unuse;
fd_set readfd;
fd_set writefd;
fd_set exceptfd;
unsigned long alloc;
};
/* Thread itself. */
struct thread
{
unsigned char type; /* thread type */
struct thread *next; /* next pointer of the thread */
struct thread *prev; /* previous pointer of the thread */
struct thread_master *master; /* pointer to the struct thread_master. */
int (*func) (struct thread *); /* event function */
void *arg; /* event argument */
union {
int val; /* second argument of the event. */
int fd; /* file descriptor in case of read/write. */
struct timeval sands; /* rest of time sands value. */
} u;
RUSAGE_T ru; /* Indepth usage info. */
};
/* Thread types. */
#define THREAD_READ 0
#define THREAD_WRITE 1
#define THREAD_TIMER 2
#define THREAD_EVENT 3
#define THREAD_READY 4
#define THREAD_UNUSED 5
/* Thread yield time. */
#define THREAD_YIELD_TIME_SLOT 100 * 1000L /* 100ms */
/* Macros. */
#define THREAD_ARG(X) ((X)->arg)
#define THREAD_FD(X) ((X)->u.fd)
#define THREAD_VAL(X) ((X)->u.val)
#define THREAD_READ_ON(master,thread,func,arg,sock) \
do { \
if (! thread) \
thread = thread_add_read (master, func, arg, sock); \
} while (0)
#define THREAD_WRITE_ON(master,thread,func,arg,sock) \
do { \
if (! thread) \
thread = thread_add_write (master, func, arg, sock); \
} while (0)
#define THREAD_TIMER_ON(master,thread,func,arg,time) \
do { \
if (! thread) \
thread = thread_add_timer (master, func, arg, time); \
} while (0)
#define THREAD_OFF(thread) \
do { \
if (thread) \
{ \
thread_cancel (thread); \
thread = NULL; \
} \
} while (0)
#define THREAD_READ_OFF(thread) THREAD_OFF(thread)
#define THREAD_WRITE_OFF(thread) THREAD_OFF(thread)
#define THREAD_TIMER_OFF(thread) THREAD_OFF(thread)
/* Prototypes. */
struct thread_master *thread_master_create ();
struct thread *thread_add_read (struct thread_master *,
int (*)(struct thread *), void *, int);
struct thread *thread_add_write (struct thread_master *,
int (*)(struct thread *), void *, int);
struct thread *thread_add_timer (struct thread_master *,
int (*)(struct thread *), void *, long);
struct thread *thread_add_timer_msec (struct thread_master *,
int (*)(struct thread *), void *, long);
struct thread *thread_add_event (struct thread_master *,
int (*)(struct thread *), void *, int );
void thread_cancel (struct thread *);
void thread_cancel_event (struct thread_master *, void *);
struct thread *thread_fetch (struct thread_master *, struct thread *);
struct thread *thread_execute (struct thread_master *,
int (*)(struct thread *), void *, int);
void thread_call (struct thread *);
unsigned long thread_timer_remain_second (struct thread *);
#endif /* _ZEBRA_THREAD_H */

2786
isisd/modified/vty.c Normal file

File diff suppressed because it is too large Load Diff

313
isisd/modified/zebra.h Normal file
View File

@ -0,0 +1,313 @@
/* Zebra common header.
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Kunihiro Ishiguro
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. */
#ifndef _ZEBRA_H
#define _ZEBRA_H
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */
#ifdef SUNOS_5
#define _XPG4_2
#define __EXTENSIONS__
#endif /* SUNOS_5 */
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <string.h>
#ifdef HAVE_STROPTS_H
#include <stropts.h>
#endif /* HAVE_STROPTS_H */
#include <sys/fcntl.h>
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif /* HAVE_SYS_SELECT_H */
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/param.h>
#ifdef HAVE_SYS_SYSCTL_H
#include <sys/sysctl.h>
#endif /* HAVE_SYS_SYSCTL_H */
#include <sys/ioctl.h>
#ifdef HAVE_SYS_CONF_H
#include <sys/conf.h>
#endif /* HAVE_SYS_CONF_H */
#ifdef HAVE_SYS_KSYM_H
#include <sys/ksym.h>
#endif /* HAVE_SYS_KSYM_H */
#include <syslog.h>
#include <time.h>
#include <sys/uio.h>
#include <sys/utsname.h>
#ifdef HAVE_RUSAGE
#include <sys/resource.h>
#endif /* HAVE_RUSAGE */
/* machine dependent includes */
#ifdef SUNOS_5
#include <limits.h>
#include <strings.h>
#endif /* SUNOS_5 */
/* machine dependent includes */
#ifdef HAVE_LINUX_VERSION_H
#include <linux/version.h>
#endif /* HAVE_LINUX_VERSION_H */
#ifdef HAVE_ASM_TYPES_H
#include <asm/types.h>
#endif /* HAVE_ASM_TYPES_H */
/* misc include group */
#include <stdarg.h>
#include <assert.h>
/* network include group */
#include <sys/socket.h>
#ifdef HAVE_SYS_SOCKIO_H
#include <sys/sockio.h>
#endif /* HAVE_SYS_SOCKIO_H */
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif /* HAVE_NETINET_IN_H */
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#ifdef HAVE_NET_NETOPT_H
#include <net/netopt.h>
#endif /* HAVE_NET_NETOPT_H */
#include <net/if.h>
#ifdef HAVE_NET_IF_DL_H
#include <net/if_dl.h>
#endif /* HAVE_NET_IF_DL_H */
#ifdef HAVE_NET_IF_VAR_H
#include <net/if_var.h>
#endif /* HAVE_NET_IF_VAR_H */
#include <net/route.h>
#ifdef HAVE_NETLINK
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#else
#define RT_TABLE_MAIN 0
#endif /* HAVE_NETLINK */
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif /* HAVE_NETDB_H */
#include <arpa/inet.h>
#include <arpa/telnet.h>
#ifdef HAVE_INET_ND_H
#include <inet/nd.h>
#endif /* HAVE_INET_ND_H */
#ifdef HAVE_NETINET_IN_VAR_H
#include <netinet/in_var.h>
#endif /* HAVE_NETINET_IN_VAR_H */
#ifdef HAVE_NETINET_IN6_VAR_H
#include <netinet/in6_var.h>
#endif /* HAVE_NETINET_IN6_VAR_H */
#ifdef HAVE_NETINET6_IN_H
#include <netinet6/in.h>
#endif /* HAVE_NETINET6_IN_H */
#ifdef HAVE_NETINET6_IP6_H
#include <netinet6/ip6.h>
#endif /* HAVE_NETINET6_IP6_H */
#ifdef HAVE_NETINET_ICMP6_H
#include <netinet/icmp6.h>
#endif /* HAVE_NETINET_ICMP6_H */
#ifdef HAVE_NETINET6_ND6_H
#include <netinet6/nd6.h>
#endif /* HAVE_NETINET6_ND6_H */
#ifdef HAVE_LIBUTIL_H
#include <libutil.h>
#endif /* HAVE_LIBUTIL_H */
#ifdef BSDI_NRL
#ifdef HAVE_NETINET6_IN6_H
#include <netinet6/in6.h>
#endif /* HAVE_NETINET6_IN6_H */
#ifdef NRL
#include <netinet6/in6.h>
#endif /* NRL */
#define IN6_ARE_ADDR_EQUAL IN6_IS_ADDR_EQUAL
/* BSD/OS 4.0 has lost belows defines, it should appear at
/usr/include/sys/socket.h. */
#define CMSG_ALIGN(n) (((n) + 3) & ~3)
#define CMSG_SPACE(l) (CMSG_ALIGN(sizeof(struct cmsghdr)) + CMSG_ALIGN(l))
#define CMSG_LEN(l) (CMSG_ALIGN(sizeof(struct cmsghdr)) + (l))
#endif /* BSDI_NRL */
/* The definition of struct in_pktinfo is missing in old version of
GLIBC 2.1 (Redhat 6.1). */
#if defined (GNU_LINUX) && ! defined (HAVE_INPKTINFO)
struct in_pktinfo
{
int ipi_ifindex;
struct in_addr ipi_spec_dst;
struct in_addr ipi_addr;
};
#endif
/* For old definition. */
#ifndef IN6_ARE_ADDR_EQUAL
#define IN6_ARE_ADDR_EQUAL IN6_IS_ADDR_EQUAL
#endif /* IN6_ARE_ADDR_EQUAL */
/* Zebra message types. */
#define ZEBRA_INTERFACE_ADD 1
#define ZEBRA_INTERFACE_DELETE 2
#define ZEBRA_INTERFACE_ADDRESS_ADD 3
#define ZEBRA_INTERFACE_ADDRESS_DELETE 4
#define ZEBRA_INTERFACE_UP 5
#define ZEBRA_INTERFACE_DOWN 6
#define ZEBRA_IPV4_ROUTE_ADD 7
#define ZEBRA_IPV4_ROUTE_DELETE 8
#define ZEBRA_IPV6_ROUTE_ADD 9
#define ZEBRA_IPV6_ROUTE_DELETE 10
#define ZEBRA_REDISTRIBUTE_ADD 11
#define ZEBRA_REDISTRIBUTE_DELETE 12
#define ZEBRA_REDISTRIBUTE_DEFAULT_ADD 13
#define ZEBRA_REDISTRIBUTE_DEFAULT_DELETE 14
#define ZEBRA_IPV4_NEXTHOP_LOOKUP 15
#define ZEBRA_IPV6_NEXTHOP_LOOKUP 16
#define ZEBRA_IPV4_IMPORT_LOOKUP 17
#define ZEBRA_IPV6_IMPORT_LOOKUP 18
#define ZEBRA_MESSAGE_MAX 19
/* Zebra route's types. */
#define ZEBRA_ROUTE_SYSTEM 0
#define ZEBRA_ROUTE_KERNEL 1
#define ZEBRA_ROUTE_CONNECT 2
#define ZEBRA_ROUTE_STATIC 3
#define ZEBRA_ROUTE_RIP 4
#define ZEBRA_ROUTE_RIPNG 5
#define ZEBRA_ROUTE_OSPF 6
#define ZEBRA_ROUTE_OSPF6 7
#define ZEBRA_ROUTE_ISIS 8
#define ZEBRA_ROUTE_BGP 9
#define ZEBRA_ROUTE_MAX 10
/* Zebra's family types. */
#define ZEBRA_FAMILY_IPV4 1
#define ZEBRA_FAMILY_IPV6 2
#define ZEBRA_FAMILY_MAX 3
/* Error codes of zebra. */
#define ZEBRA_ERR_RTEXIST -1
#define ZEBRA_ERR_RTUNREACH -2
#define ZEBRA_ERR_EPERM -3
#define ZEBRA_ERR_RTNOEXIST -4
/* Zebra message flags */
#define ZEBRA_FLAG_INTERNAL 0x01
#define ZEBRA_FLAG_SELFROUTE 0x02
#define ZEBRA_FLAG_BLACKHOLE 0x04
#define ZEBRA_FLAG_IBGP 0x08
#define ZEBRA_FLAG_SELECTED 0x10
#define ZEBRA_FLAG_CHANGED 0x20
#define ZEBRA_FLAG_STATIC 0x40
/* Zebra nexthop flags. */
#define ZEBRA_NEXTHOP_IFINDEX 1
#define ZEBRA_NEXTHOP_IFNAME 2
#define ZEBRA_NEXTHOP_IPV4 3
#define ZEBRA_NEXTHOP_IPV4_IFINDEX 4
#define ZEBRA_NEXTHOP_IPV4_IFNAME 5
#define ZEBRA_NEXTHOP_IPV6 6
#define ZEBRA_NEXTHOP_IPV6_IFINDEX 7
#define ZEBRA_NEXTHOP_IPV6_IFNAME 8
#ifndef INADDR_LOOPBACK
#define INADDR_LOOPBACK 0x7f000001 /* Internet address 127.0.0.1. */
#endif
/* Address family numbers from RFC1700. */
#define AFI_IP 1
#define AFI_IP6 2
#define AFI_MAX 3
/* Subsequent Address Family Identifier. */
#define SAFI_UNICAST 1
#define SAFI_MULTICAST 2
#define SAFI_UNICAST_MULTICAST 3
#define SAFI_MPLS_VPN 4
#define SAFI_MAX 5
/* Filter direction. */
#define FILTER_IN 0
#define FILTER_OUT 1
#define FILTER_MAX 2
/* Default Administrative Distance of each protocol. */
#define ZEBRA_KERNEL_DISTANCE_DEFAULT 0
#define ZEBRA_CONNECT_DISTANCE_DEFAULT 0
#define ZEBRA_STATIC_DISTANCE_DEFAULT 1
#define ZEBRA_RIP_DISTANCE_DEFAULT 120
#define ZEBRA_RIPNG_DISTANCE_DEFAULT 120
#define ZEBRA_OSPF_DISTANCE_DEFAULT 110
#define ZEBRA_OSPF6_DISTANCE_DEFAULT 110
#define ZEBRA_ISIS_DISTANCE_DEFAULT 115
#define ZEBRA_IBGP_DISTANCE_DEFAULT 200
#define ZEBRA_EBGP_DISTANCE_DEFAULT 20
/* Flag manipulation macros. */
#define CHECK_FLAG(V,F) ((V) & (F))
#define SET_FLAG(V,F) (V) = (V) | (F)
#define UNSET_FLAG(V,F) (V) = (V) & ~(F)
/* AFI and SAFI type. */
typedef u_int16_t afi_t;
typedef u_char safi_t;
/* Zebra types. */
typedef u_int16_t zebra_size_t;
typedef u_int8_t zebra_command_t;
#endif /* _ZEBRA_H */

View File

@ -0,0 +1,23 @@
## Process this file with automake to produce Makefile.in.
INCLUDES = @INCLUDES@ -I.. -I$(top_srcdir) -I$(top_srcdir)/lib
DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
noinst_LIBRARIES = libtopology.a
libtopology_a_SOURCES = \
spgrid.c
libtopology_a_DEPENDENCIES = @LIB_REGEX@
libtopology_a_LIBADD = @LIB_REGEX@ ../../lib/libzebra.a
noinst_HEADERS = \
spgrid.h
EXTRA_DIST = regex.c regex-gnu.h
depend:
@$(CPP) -MM $(INCLUDES) $(LDFLAGS) *.c
## File dependency.

154
isisd/topology/random.c Normal file
View File

@ -0,0 +1,154 @@
/*********************************************************************/
/* */
/* current processor time in seconds */
/* difference between two calls is processor time spent by your code */
/* needs: <sys/types.h>, <sys/times.h> */
/* depends on compiler and OS */
/* */
/*********************************************************************/
#include <sys/types.h>
#include <sys/times.h>
float timer()
{ struct tms hold;
times(&hold);
return (float)(hold.tms_utime) / 60.0;
}
/*********************************************************************/
/* */
/* Family of random number generators */
/* */
/* Initialisation: */
/* void init_rand ( seed ); */
/* long seed - any positive number */
/* if seed<=0 init_rand takes time */
/* from timer instead of seed */
/* */
/* Whole number uniformly distributed on [0,n): */
/* long nrand (n); */
/* long n */
/* */
/* Real number uniformly distributed on [0,1] */
/* double rand01(); */
/* */
/* Real number with Gauss(0,1) disitribution: */
/* double randg01(); */
/* */
/* Algorithm: */
/* x(n+1) = (x(n) * 5^13) mod 2^31 */
/* */
/*********************************************************************/
unsigned long internal_seed;
void init_rand ( init_seed )
long init_seed;
{ internal_seed = ( init_seed > 0 )
? (unsigned long) init_seed
: (unsigned long) timer();
/* only odd numbers are acceptable */
if ( internal_seed % 2 == 0 ) internal_seed --;
}
/*********************************************************************/
/* */
/* Internal function irand may depend on OS and compiler */
/* */
/* irand assumption: */
/* unsigned long i,j; */
/* if i*j > max(unsigned long) */
/* 1. No overflow interruption */
/* 2. i*j = i*j mod max(unsigned long) */
/* */
/* This assumption is true for a lot of computers. */
/* If your computer fails: */
/* rename: irand <---> xrand */
/* */
/*********************************************************************/
#define A 1220703125
#define B 2147483647
#define BF 2147483647.
static long irand ()
{ internal_seed = ( internal_seed * A ) & B;
return (long) internal_seed ;
}
/*********************************************************************/
/* */
/* computer independent variant of irand */
/* */
/*********************************************************************/
#define T15 32768
#define T16 65536
#define A1 37252
#define A2 29589
static long xrand()
{ unsigned long is1, is2;
is1 = internal_seed / T15;
is2 = internal_seed % T15;
internal_seed = ( (((is2 * A1) + (is1 * A2))% T16 )* T15 + (is2 * A2) ) & B;
return (long) ( internal_seed ) ;
}
/*********************************************************************/
double rand01()
{ return (double) irand() / BF ;
}
/*********************************************************************/
#define NK 12
double randg01()
{ int i;
double sum = 0;
for ( i = 0; i < NK; i++ ) sum += rand01();
return sum - 6.;
/* if NK != 12 then you must return (12/NK)*sum - (NK/2) */
}
#undef NK
/*********************************************************************/
long nrand ( n )
long n;
{ return (long) ( rand01() * (double) n );
}
/*********************************************************************/
#undef A
#undef A1
#undef A2
#undef B
#undef BF
#undef T15
#undef T16

483
isisd/topology/spacyc.c Normal file
View File

@ -0,0 +1,483 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <values.h>
#include "random.c"
#define DASH '-'
#define VERY_FAR 100000000
/* generator of acyclic random networks for the shortest paths problem;
extended DIMACS format for output */
main ( argc, argv )
int argc;
char* argv[];
{
char args[30];
long n,
n0,
source,
i,
i0,
j,
dij;
long m,
m0,
mc,
k;
long *p,
p_t,
l,
lx;
long seed,
seed1,
seed2;
int ext=0;
FILE *fout;
/* variables for lengths generating */
/* initialized by default values */
int l_f = 0, ll_f = 0, lm_f = 0, ln_f = 0, ls_f = 0;
long ll = 10000, /* upper bound of the interval */
lm = 0; /* lower bound of the interval */
double ln = 0, /* l += ln * |i-j| */
ls = 0; /* l += ls * |i-j|^2 */
/* variables for connecting path(s) */
int c_f = 0, cl_f = 0, ch_f = 0, c_rand = 1;
long cl = 1; /* length of path arc */
long ch; /* number of arcs in the path
n - by default */
/* variables for artifical source */
int s_f = 0, sl_f = 0, sm_f = 0;
long sl = VERY_FAR, /* upper bound of artifical arc */
sm, /* lower bound of artifical arc */
s;
/* variables for potentials */
int p_f = 0, pl_f = 0, pm_f = 0, pn_f = 0, ps_f = 0,
pa_f = 0, pap_f = 0, pac_f = 0;
long pl, /* upper bound of the interval */
pm; /* lower bound of the interval */
double pn = 0, /* l += ln * |i-j| */
ps = 0, /* l += ls * |i-j|^2 */
pap = 0, /* part of nodes with alternative dustribution */
pac = -1; /* multiplier for alternative distribution */
int np; /* number of parameter parsing now */
#define PRINT_ARC( i, j, length )\
{\
l = length;\
if ( p_f ) l += ( p[i] - p[j] );\
printf ("a %8ld %8ld %12ld\n", i, j, l );\
}
/* parsing parameters */
if ( argc < 2 ) goto usage;
np = 0;
strcpy ( args, argv[1] );
if ( ( args[0] == DASH ) && ( args[1] == 'h')
)
goto help;
if ( argc < 4 ) goto usage;
/* first parameter - number of nodes */
np = 1;
if ( ( n = atoi ( argv[1] ) ) < 2 ) goto usage;
/* second parameter - number of arcs */
np = 2;
if ( ( m = atoi ( argv[2] ) ) < n ) goto usage;
/* third parameter - seed */
np=3;
if ( ( seed = atoi ( argv[3] ) ) <= 0 ) goto usage;
/* other parameters */
for ( np = 4; np < argc; np ++ )
{
strcpy ( args, argv[np] );
if ( args[0] != DASH ) goto usage;
switch ( args[1] )
{
case 'l' : /* an interval for arc length */
l_f = 1;
switch ( args[2] )
{
case 'l': /* length of the interval */
ll_f = 1;
ll = (long) atof ( &args[3] );
break;
case 'm': /* minimal bound */
lm_f = 1;
lm = (long ) atof ( &args[3] );
break;
case 'n': /* additional length: l*|i-j| */
ln_f = 1;
ln = atof ( &args[3] );
break;
case 's': /* additional length: l*|i-j|^2 */
ls_f = 1;
ls = atof ( &args[3] );
break;
default: /* unknown switch value */
goto usage;
}
break;
case 'c' : /* connecting path(s) */
c_f = 1;
switch ( args[2] )
{
case 'l': /* length of path arc */
c_rand = 0; /* fixed arc length */
cl_f = 1;
cl = (long) atof ( &args[3] );
break;
case 'h': /* number of arcs in connecting path */
ch_f = 1;
ch = (long) atof ( &args[3] );
if ( ch < 1 || ch > n ) goto usage;
break;
default: /* unknown switch value */
goto usage;
}
break;
case 's' : /* additional source */
s_f = 1;
if ( strlen ( args ) > 2 )
{
switch ( args[2] )
{
case 'l': /* upper bound of art. arc */
sl_f = 1;
sl = (long) atof ( &args[3] );
break;
case 'm': /* lower bound of art. arc */
sm_f = 1;
sm = (long) atof ( &args[3] );
break;
default: /* unknown switch value */
goto usage;
}
}
break;
case 'p' : /* potentials */
p_f = 1;
if ( strlen ( args ) > 2 )
{
switch ( args[2] )
{
case 'l': /* length of the interval */
pl_f = 1;
pl = (long) atof ( &args[3] );
break;
case 'm': /* minimal bound */
pm_f = 1;
pm = (long ) atof ( &args[3] );
break;
case 'n': /* additional length: l*|i-j| */
pn_f = 1;
pn = atof ( &args[3] );
break;
case 's': /* additional length: l*|i-j|^2 */
ps_f = 1;
ps = atof ( &args[3] );
break;
case 'a': /* bipolar distribution */
pa_f = 1;
switch ( args[3] )
{
case 'p': /* % of alternative potentials */
pap_f = 1;
pap = atof ( &args[4] );
if ( pap < 0 ) pap = 0;
if ( pap > 100 ) pap = 100;
pap /= 100;
break;
case 'c': /* multiplier */
pac_f = 1;
pac = atof ( &args[4] );
break;
default: /* unknown switch value */
goto usage;
}
break;
default: /* unknown switch value */
goto usage;
}
}
break;
default : /* unknoun case */
goto usage;
}
}
/* ----- ajusting parameters ----- */
n0 = n; m0 = m;
/* length parameters */
if ( ll < lm ) { lx = ll; ll = lm; lm = lx; }
/* potential parameters */
if ( p_f )
{
if ( ! pl_f ) pl = ll;
if ( ! pm_f ) pm = lm;
if ( pl < pm ) { lx = pl; pl = pm; pm = lx; }
}
/* path(s) parameters */
if ( ! ch_f ) ch = n - 1;
mc = n - 1;
/* artifical source parameters */
if ( s_f )
{ m0 += n; n0 ++ ;
if ( ! sm_f ) sm = sl;
if ( sl < sm ) { lx = sl; sl = sm; sm = lx; }
}
/*----- printing title -----*/
printf ("c acyclic network for shortest paths problem\n");
printf ("c extended DIMACS format\nc\n" );
/* name of the problem */
printf ("t ac_%ld_%ld_%ld_", n, m, seed );
if ( l_f )
printf ("%c", 'l');
if ( c_f )
printf ("%c", 'c');
if ( s_f )
printf ("%c", 's');
if ( p_f )
printf ("%c", 'p');
printf ("\nc\n");
/* printing additional information */
if ( l_f )
printf ("c length -> min: %ld max: %ld k1: %.2f k2: %.2f\n",
lm, ll, ln, ls );
if ( c_f )
printf ("c path(s) -> number of arcs: %ld arc length: %ld\n",
ch, cl );
if ( s_f )
printf ("c length of arcs from artifical source -> min: %ld max: %ld\n",
sm, sl );
if ( p_f )
{
printf ("c potentials -> min: %ld max: %ld k1: %.2f k2: %.2f\n",
pm, pl, pn, ps );
if ( pa_f )
printf ("c potentials -> part of alternative distribution: %.2f k: %.2f\n",
pap, pac );
}
printf ("c\n" );
printf ("p sp %8ld %8ld\nc\n", n0, m0 );
source = ( s_f ) ? n0 : 1;
printf ("n %8ld\nc\n", source );
if ( p_f ) /* generating potentials */
{
seed1 = 2*seed + 1;
p = (long*) calloc ( n+2, sizeof (long) );
init_rand ( seed1);
pl = pl - pm + 1;
for ( i = 0; i <= n; i ++ )
{
p_t = pm + nrand ( pl );
if ( pn_f ) p_t += (long) ( i * pn );
if ( ps_f ) p_t += (long) ( i * ( i * ps ));
if ( pap_f )
if ( rand01() < pap )
p_t = (long) ( p_t * pac );
p[i] = p_t;
}
p[n+1] = 0;
}
if ( s_f ) /* additional arcs from artifical source */
{
seed2 = 3*seed + 1;
init_rand ( seed2 );
sl = sl - sm + 1;
for ( i = n; i > 1; i -- )
{
s = sm + nrand ( sl );
PRINT_ARC ( n0, i, s )
}
PRINT_ARC ( n0, 1, 0 )
}
/* initialize random number generator */
init_rand ( seed );
ll = ll - lm + 1;
/* generating connecting path(s) */
for ( i = 1; i < n; i ++ )
{
if ( ( (i-1) % ch ) != 0 )
i0 = i;
else
i0 = 1;
if (c_rand)
cl = lm + nrand(ll);
PRINT_ARC ( i0, i+1, cl )
}
/* generating random arcs */
for ( k = 1; k <= m - mc; k ++ )
{
i = 1 + nrand ( n );
do
j = 1 + nrand ( n );
while ( j == i );
if ( i > j )
{ i0 = i; i = j; j = i0; }
dij = j - i;
l = lm + nrand ( ll );
if ( ln_f ) l += (long) ( dij * ln );
if ( ls_f ) l += (long) ( dij * ( dij * ls ) );
PRINT_ARC ( i, j, l );
}
/* all is done */
exit (ext);
/* ----- wrong usage ----- */
usage:
fprintf ( stderr,
"\nusage: %s n m seed [ -ll#i -lm#i -cl#i -p -pl#i -pm#i ... ]\n\
help: %s -h\n\n", argv[0], argv[0] );
if ( np > 0 )
fprintf ( stderr, "error in parameter # %d\n\n", np );
exit (4);
/* ---- help ---- */
help:
if ( args[2] == 'h') goto hhelp;
fprintf ( stderr,
"\n'%s' - acyclic network generator for shortest paths problem.\n\
Generates problems in extended DIMACS format.\n\
\n\
%s n m seed [ -ll#i -lm#i -cl#i -p -pl#i -pm#i ... ]\n\
%s -hh\n\
\n\
#i - integer number #f - real number\n\
\n\
-ll#i - #i is the upper bound on arc lengths (default 10000)\n\
-lm#i - #i is the lower bound on arc lengths (default 0)\n\
-cl#i - #i is length of arcs in connecting path(s) (default random)\n\
-p - generate potentials \n\
-pl#i - #i is the upper bound on potentials (default ll)\n\
-pm#i - #i is the lower bound on potentials (default lm)\n\
\n\
-hh - extended help \n\n",
argv[0], argv[0], argv[0] );
exit (0);
/* --------- sophisticated help ------------ */
hhelp:
if ( argc < 3 )
fout = stderr;
else
fout = fopen ( argv[2], "w" );
if ( fout == NULL )
{ fprintf ( stderr, "\nCan't open file '%s' for writing help\n\n", argv[2] );
exit ( 2 );
}
fprintf (fout,
"\n'%s' - acyclic network generator for shortest paths problem.\n\
Generates problems in extended DIMACS format.\n\
\n\
%s n m seed [ -ll#i -lm#i -ln#f -ls#f\n\
-p -pl#i -pm#i -pn#f -ps#f -pap#i -pac#f\n\
-cl#i -ch#i\n\
-s -sl#i -sm#i\n\
]\n\
%s -hh file_name\n\
\n\
#i - integer number #f - real number\n\
\n\
Arc length parameters:\n\
-ll#i - #i is the upper bound on arc lengths (default 10000)\n\
-lm#i - #i is the lower bound on arc lengths (default 0)\n\
-ln#f - multipliy l(i, j) by #f * |i-j| (default 0)\n\
-ls#f - multipliy l(i, j) by #f * |i-j|^2 (default 0)\n\
\n\
Potential parameters:\n\
-p - generate potentials \n\
-pl#i - #i is the upper bound on potentials (default ll)\n\
-pm#i - #i is the lower bound on potentials (default lm)\n\
-pn#f - multiply p(i) by #f * i (default 0)\n\
-ps#f - multiply p(i) by #f * i^2 (default 0)\n\
-pap#i - percentage of alternative potential nodes (default 0)\n\
-pac#f - if i is alternative, multiply p(i) by #f (default -1)\n\
\n\
Connecting path(s) parameters:\n\
-cl#i - #i is length of arcs in connecting path(s) (default random)\n\
-ch#i - #i is length of connecting path(s) (default n-1)\n\
\n\
Artificial source parameters:\n\
-s - generate artificial source with default connecting arc lengths\n\
-sl#i - #i is the upper bound on art. arc lengths (default 100000000)\n\
-sm#i - #i is the lower bound on art. arc lengths (default sl)\n\
\n\
-hh file_name - save this help in the file 'file_name'\n\n",
argv[0], argv[0], argv[0] );
exit (0);
}

729
isisd/topology/spgrid.c Normal file
View File

@ -0,0 +1,729 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <values.h>
#include "random.c"
#include <zebra.h>
#include "thread.h"
#include "vty.h"
#include "log.h"
#include "linklist.h"
#include "spgrid.h"
#define DASH '-'
#define VERY_FAR 100000000
#define DOUBLE_CYCLE 0
#define CYCLE 1
#define PATH 2
#define NO 0
#define YES 1
#define NODE( x, y ) (x*Y + y + 1)
char *graph_type[] = {
"double cycle",
"cycle",
"path"
};
struct arc *arc;
char args[30];
long X, /* horizontal size of grid */
Y; /* vertical size of grid */
long x,
y,
y1, y2, yp,
dl, dx, xn, yn, count,
*mess;
double n;
long n0,
source,
i,
i0,
j,
dij;
double m;
long m0,
mc,
k;
long *p,
p_t,
l,
lx;
long seed,
seed1,
seed2;
int ext=0;
/* initialized by default values */
/* variables for generating one layer */
/* variables for generating spanning graph */
int c_f = 0, cw_f = 0, cm_f = 0, cl_f = 0;
int cw = DOUBLE_CYCLE; /* type of spanning graph */
long cm = 0, /* lower bound of the interval */
cl = 100; /* upper bound of the interval */
/* variables for generating additional arcs */
int a_f = 0, ax_f = 0, am_f = 0, al_f = 0;
long ax = 0, /* number of additional arcs */
am = 0, /* lower bound of the interval */
al = 100; /* upper bound of the interval */
/* variables for inter-layer arcs */
int i_f = 0, ip_f = 0, ix_f = 0, ih_f = 0,
im_f = 0, il_f = 0, in_f = 0, is_f = 0;
int ip = NO; /* to mess or not to mess */
long ix = 1, /* number of interlayered arcs in a NODE */
ih = 1, /* step between two layeres */
il = 10000, /* upper bound of the interval */
im = 1000; /* lower bound of the interval */
double in = 1, /* l *= in * |x1-x2| */
is = 0; /* l *= is * |x1-x2|^2 */
/* variables for artifical source */
int s_f = 0, sl_f = 0, sm_f = 0;
long sl = VERY_FAR, /* upper bound of artifical arc */
sm, /* lower bound of artifical arc */
s;
/* variables for potentials */
int p_f = 0, pl_f = 0, pm_f = 0, pn_f = 0, ps_f = 0;
long pl, /* upper bound of the interval */
pm; /* lower bound of the interval */
double pn = 0, /* p += ln * (x+1) */
ps = 0; /* p += ls * (x+1)^2 */
int np; /* number of parameter parsing now */
void
free_arc (void *val) {
free(val);
}
void
print_arc (struct vty *vty, struct list *topology, long i, long j, long length)
{
struct arc *myarc;
l = length;
if ( p_f ) l += ( p[i] - p[j] );
// vty_out (vty,"a %8ld %8ld %12ld%s", i, j, l ,VTY_NEWLINE);
myarc = malloc (sizeof(struct arc));
myarc->from_node = i;
myarc->to_node = j;
myarc->distance = l;
topology->del = free_arc;
listnode_add (topology, myarc);
}
/* ---- help ---- */
void
help (struct vty *vty) {
// if ( args[2] == 'h') hhelp (vty);
vty_out (vty,"grid network generator for shortest paths problem.%s",VTY_NEWLINE);
vty_out (vty,"Generates problems in extended DIMACS format.%s",VTY_NEWLINE);
vty_out (vty,"X Y seed [ -cl#i -cm#i -c{c|d|p} -ip -il#i -im#i -p -pl#i -pm#i... ]%s",VTY_NEWLINE);
vty_out (vty,"#i - integer number%s",VTY_NEWLINE);
vty_out (vty,"-cl#i - #i is the upper bound on layer arc lengths (default 100)%s",VTY_NEWLINE);
vty_out (vty,"-cm#i - #i is the lower bound on layer arc lengths (default 0)%s",VTY_NEWLINE);
vty_out (vty,"-c#t - #t is the type of connecting graph: { c | d | p }%s",VTY_NEWLINE);
vty_out (vty," c - cycle, d - double cycle, p - path (default d)%s",VTY_NEWLINE);
vty_out (vty,"-ip - shuffle inter-layer arcs (default NO)%s",VTY_NEWLINE);
vty_out (vty,"-il#i - #i is the upper bound on inter-layer arc lengths (default 10000)%s",VTY_NEWLINE);
vty_out (vty,"-im#i - #i is the lower bound on inter-layer arc lengths (default 1000)%s",VTY_NEWLINE);
vty_out (vty,"-p - generate potentials%s",VTY_NEWLINE);
vty_out (vty,"-pl#i - #i is the upper bound on potentials (default il)%s",VTY_NEWLINE);
vty_out (vty,"-pm#i - #i is the lower bound on potentials (default im)%s",VTY_NEWLINE);
vty_out (vty,"%s",VTY_NEWLINE);
vty_out (vty,"-hh - extended help%s",VTY_NEWLINE);
}
/* --------- sophisticated help ------------ */
void
hhelp (struct vty *vty) {
/*
zlog_info (
"\n'%s' - grid network generator for shortest paths problem.\n\
Generates problems in extended DIMACS format.\n\
\n\
%s X Y seed [ -cl#i -cm#i -c{c|d|p}\n\
-ax#i -al#i -am#i\n\
-ip -il#i -im#i -in#i -is#i -ix#i -ih#i\n\
-p -pl#i -pm#i -pn#f -ps#f\n\
-s -sl#i -sm#i\n\
]\n\
%s -hh file_name\n\
\n\
#i - integer number #f - real number\n\
\n\
Parameters of connecting arcs within one layer:\n\
-cl#i - #i is the upper bound on arc lengths (default 100)\n\
-cm#i - #i is the lower bound on arc lengths (default 0)\n\
-c#t - #t is the type of connecting graph: { c | d | p }\n\
c - cycle, d - double cycle, p - path (default d)\n\
\n\
Parameters of additional arcs within one layer:\n\
-ax#i - #i is the number of additional arcs (default 0)\n\
-al#i - #i is the upper bound on arc lengths (default 100)\n\
-am#i - #i is the lower bound on arc lengths (default 0)\n\
\n\
Interlayerd arc parameters:\n\
-ip - shuffle inter-layer arcs (default NO)\n\
-il#i - #i is the upper bound on arc lengths (default 10000)\n\
-im#i - #i is the lower bound on arc lengths (default 1000)\n\
-in#f - multiply l(i, j) by #f * x(j)-x(i) (default 1)\n\
if #f=0 - don't multiply\n\
-is#f - multiply l(i, j) by #f * (x(j)-x(i))^2 (default NO)\n\
-ix#i - #i - is the number of arcs from a node (default 1)\n\
-ih#i - #i - is the step between connected layers (default 1)\n\
\n\
Potential parameters:\n\
-p - generate potentials \n\
-pl#i - #i is the upper bound on potentials (default ll)\n\
-pm#i - #i is the lower bound on potentials (default lm)\n\
-pn#f - multiply p(i) by #f * x(i) (default NO)\n\
-ps#f - multiply p(i) by #f * x(i)^2 (default NO)\n\
\n");
zlog_info (
" Artificial source parameters:\n\
-s - generate artificial source with default connecting arc lengths\n\
-sl#i - #i is the upper bound on art. arc lengths (default 100000000)\n\
-sm#i - #i is the lower bound on art. arc lengths (default sl)\n\"
);*/
}
/* ----- wrong usage ----- */
void
usage (struct vty *vty) {
vty_out (vty,"usage: X Y seed [-ll#i -lm#i -cl#i -p -pl#i -pm#i ...]%s",VTY_NEWLINE);
vty_out (vty,"help: -h or -hh%s",VTY_NEWLINE);
if ( np > 0 )
zlog_err ("error in parameter # %d\n\n", np );
}
/* parsing parameters */
/* checks the validity of incoming parameters */
int
spgrid_check_params ( struct vty *vty, int argc, char **argv)
{
/* initialized by default values */
ext=0;
/* variables for generating one layer */
/* variables for generating spanning graph */
c_f = 0;
cw_f = 0;
cm_f = 0;
cl_f = 0;
cw = PATH; /* type of spanning graph */
cm = 0; /* lower bound of the interval */
cl = 63; /* upper bound of the interval */
/* variables for generating additional arcs */
a_f = 0;
ax_f = 0;
am_f = 0;
al_f = 0;
ax = 0; /* number of additional arcs */
am = 0; /* lower bound of the interval */
al = 63; /* upper bound of the interval */
/* variables for inter-layer arcs */
i_f = 0;
ip_f = 0;
ix_f = 0;
ih_f = 0;
im_f = 0;
il_f = 0;
in_f = 0;
is_f = 0;
ip = NO; /* to mess or not to mess */
ix = 1; /* number of interlayered arcs in a NODE */
ih = 1; /* step between two layeres */
il = 63; //was 10000; /* upper bound of the interval */
im = 0; //was 1000; /* lower bound of the interval */
in = 1; /* l *= in * |x1-x2| */
is = 0; /* l *= is * |x1-x2|^2 */
/* variables for artifical source */
s_f = 0;
sl_f = 0;
sm_f = 0;
sl = VERY_FAR; /* upper bound of artifical arc */
/* variables for potentials */
p_f = 0;
pl_f = 0;
pm_f = 0;
pn_f = 0;
ps_f = 0;
pn = 0; /* p += ln * (x+1) */
ps = 0; /* p += ls * (x+1)^2 */
if ( argc < 1 ) {
usage (vty);
return 1;
}
np = 0;
strcpy ( args, argv[0] );
if ((args[0] == DASH) && (args[1] == 'h'))
help (vty);
if ( argc < 3 ) {
usage (vty);
return 1;
}
/* first parameter - horizontal size */
np = 1;
if ( ( X = atoi ( argv[0] ) ) < 1 ) {
usage (vty);
return 1;
}
/* second parameter - vertical size */
np = 2;
if ( ( Y = atoi ( argv[1] ) ) < 1 ) {
usage (vty);
return 1;
}
/* third parameter - seed */
np=3;
if ( ( seed = atoi ( argv[2] ) ) <= 0 ) {
usage (vty);
return 1;
}
/* other parameters */
for ( np = 3; np < argc; np ++ ) {
strcpy ( args, argv[np] );
if ( args[0] != DASH ) {
usage (vty);
return 1;
}
switch ( args[1] ) {
case 'c' : /* spanning graph in one layer */
c_f = 1;
switch ( args[2] ) {
case 'l': /* upper bound of the interval */
cl_f = 1;
cl = (long) atof ( &args[3] );
break;
case 'm': /* lower bound */
cm_f = 1;
cm = (long ) atof ( &args[3] );
break;
case 'c': /* type - cycle */
cw_f = 1;
cw = CYCLE;
break;
case 'd': /* type - double cycle */
cw_f = 1;
cw = DOUBLE_CYCLE;
break;
case 'p': /* type - path */
cw_f = 1;
cw = PATH;
break;
default: /* unknown switch value */
usage (vty);
return 1;
}
break;
case 'a' : /* additional arcs in one layer */
a_f = 1;
switch ( args[2] )
{
case 'l': /* upper bound of the interval */
al_f = 1;
al = (long) atof ( &args[3] );
break;
case 'm': /* lower bound */
am_f = 1;
am = (long ) atof ( &args[3] );
break;
case 'x': /* number of additional arcs */
ax_f = 1;
ax = (long ) atof ( &args[3] );
if ( ax < 0 )
{
usage (vty);
return 1;
}
break;
default: /* unknown switch value */
{
usage (vty);
return 1;
}
}
break;
case 'i' : /* interlayered arcs */
i_f = 1;
switch ( args[2] )
{
case 'l': /* upper bound */
il_f = 1;
il = (long) atof ( &args[3] );
break;
case 'm': /* lower bound */
im_f = 1;
im = (long ) atof ( &args[3] );
break;
case 'n': /* additional length: l *= in*|i1-i2| */
in_f = 1;
in = atof ( &args[3] );
break;
case 's': /* additional length: l *= is*|i1-i2|^2 */
is_f = 1;
is = atof ( &args[3] );
break;
case 'p': /* mess interlayered arcs */
ip_f = 1;
ip = YES;
break;
case 'x': /* number of interlayered arcs */
ix_f = 1;
ix = atof ( &args[3] );
if ( ix < 1 ) {
usage (vty);
return 1;
}
break;
case 'h': /* step between two layeres */
ih_f = 1;
ih = atof ( &args[3] );
if ( ih < 1 ) {
usage (vty);
return 1;
}
break;
default: /* unknown switch value */
usage (vty);
return 1;
}
break;
case 's' : /* additional source */
s_f = 1;
if ( strlen ( args ) > 2 )
{
switch ( args[2] )
{
case 'l': /* upper bound of art. arc */
sl_f = 1;
sl = (long) atof ( &args[3] );
break;
case 'm': /* lower bound of art. arc */
sm_f = 1;
sm = (long) atof ( &args[3] );
break;
default: /* unknown switch value */
usage (vty);
return 1;
}
}
break;
case 'p' : /* potentials */
p_f = 1;
if ( strlen ( args ) > 2 )
{
switch ( args[2] )
{
case 'l': /* upper bound */
pl_f = 1;
pl = (long) atof ( &args[3] );
break;
case 'm': /* lower bound */
pm_f = 1;
pm = (long ) atof ( &args[3] );
break;
case 'n': /* additional: p *= pn*(x+1) */
pn_f = 1;
pn = atof ( &args[3] );
break;
case 's': /* additional: p = ps* (x+1)^2 */
ps_f = 1;
ps = atof ( &args[3] );
break;
default: /* unknown switch value */
usage (vty);
return 1;
}
}
break;
default: /* unknoun case */
usage (vty);
return 1;
}
}
return 0;
}
/* generator of layered networks for the shortest paths problem;
extended DIMACS format for output */
int
gen_spgrid_topology (struct vty *vty, struct list *topology)
{
/* ----- ajusting parameters ----- */
/* spanning */
if ( cl < cm ) { lx = cl; cl = cm; cm = lx; }
/* additional arcs */
if ( al < am ) { lx = al; al = am; am = lx; }
/* interlayered arcs */
if ( il < im ) { lx = il; il = im; im = lx; }
/* potential parameters */
if ( p_f )
{
if ( ! pl_f ) pl = il;
if ( ! pm_f ) pm = im;
if ( pl < pm ) { lx = pl; pl = pm; pm = lx; }
}
/* number of nodes and arcs */
n = (double)X *(double)Y + 1;
m = (double)Y; /* arcs from source */
switch ( cw )
{
case PATH:
mc = (double)Y - 1;
break;
case CYCLE:
mc = (double)Y;
break;
case DOUBLE_CYCLE:
mc = 2*(double)Y;
}
m += (double)X * (double)mc; /* spanning arcs */
m += (double)X * (double)ax; /* additional arcs */
/* interlayered arcs */
for ( x = 0; x < X; x ++ )
{
dl = ( ( X - x - 1 ) + ( ih - 1 ) ) / ih;
if ( dl > ix ) dl = ix;
m += (double)Y * (double)dl;
}
/* artifical source parameters */
if ( s_f ) {
m += n; n ++ ;
if ( ! sm_f ) sm = sl;
if ( sl < sm ) { lx = sl; sl = sm; sm = lx; }
}
if ( n >= (double)MAXLONG || m >= (double)MAXLONG )
{
zlog_err ("Too large problem. It can't be generated\n");
exit (4);
}
else
{
n0 = (long)n; m0 = (long)m;
}
if ( ip_f )
mess = (long*) calloc ( Y, sizeof ( long ) );
/* printing title */
zlog_info ("Generating topology for ISIS");
source = ( s_f ) ? n0-1 : n0;
if ( p_f ) /* generating potentials */ {
p = (long*) calloc ( n0+1, sizeof (long) );
seed1 = 2*seed + 1;
init_rand ( seed1);
pl = pl - pm + 1;
for ( x = 0; x < X; x ++ )
for ( y = 0; y < Y; y ++ ) {
p_t = pm + nrand ( pl );
if ( pn_f ) p_t *= (long) ( (1 + x) * pn );
if ( ps_f ) p_t *= (long) ( (1 + x) * ( (1 + x) * ps ));
p[ NODE ( x, y ) ] = p_t;
}
p[n0] = 0;
if ( s_f ) p[n0-1] = 0;
}
if ( s_f ) /* additional arcs from artifical source */
{
seed2 = 3*seed + 1;
init_rand ( seed2 );
sl = sl - sm + 1;
for ( x = X - 1; x >= 0; x -- )
for ( y = Y - 1; y >= 0; y -- )
{
i = NODE ( x, y );
s = sm + nrand ( sl );
print_arc (vty, topology, n0, i, s );
}
print_arc (vty, topology, n0, n0-1, 0 );
}
/* ----- generating arcs within layers ----- */
init_rand ( seed );
cl = cl - cm + 1;
al = al - am + 1;
for ( x = 0; x < X; x ++ )
{
/* generating arcs within one layer */
for ( y = 0; y < Y-1; y ++ )
{
/* generating spanning graph */
i = NODE ( x, y );
j = NODE ( x, y+1 );
l = cm + nrand ( cl );
print_arc (vty, topology, i, j, l );
if ( cw == DOUBLE_CYCLE )
{
l = cm + nrand ( cl );
print_arc (vty, topology, j, i, l );
}
}
if ( cw <= CYCLE )
{
i = NODE ( x, Y-1 );
j = NODE ( x, 0 );
l = cm + nrand ( cl );
print_arc (vty, topology, i, j, l );
if ( cw == DOUBLE_CYCLE )
{
l = cm + nrand ( cl );
print_arc (vty, topology, j, i, l );
}
}
/* generating additional arcs */
for ( k = ax; k > 0; k -- )
{
y1 = nrand ( Y );
do
y2 = nrand ( Y );
while ( y2 == y1 );
i = NODE ( x, y1 );
j = NODE ( x, y2 );
l = am + nrand ( al );
print_arc (vty, topology, i, j, l );
}
}
/* ----- generating interlayered arcs ------ */
il = il - im + 1;
/* arcs from the source */
for ( y = 0; y < Y; y ++ )
{
l = im + nrand ( il );
i = NODE ( 0, y );
print_arc (vty, topology, source, i, l );
}
for ( x = 0; x < X-1; x ++ )
{
/* generating arcs from one layer */
for ( count = 0, xn = x + 1;
count < ix && xn < X;
count ++, xn += ih )
{
if ( ip_f )
for ( y = 0; y < Y; y ++ )
mess[y] = y;
for ( y = 0; y < Y; y ++ )
{
i = NODE ( x, y );
dx = xn - x;
if ( ip_f )
{
yp = nrand(Y-y);
yn = mess[ yp ];
mess[ yp ] = mess[ Y - y - 1 ];
}
else
yn = y;
j = NODE ( xn, yn );
l = im + nrand ( il );
if ( in != 0 )
l *= (long) ( in * dx );
if ( is_f )
l *= (long) ( ( is * dx ) * dx );
print_arc (vty, topology, i, j, l );
}
}
}
/* all is done */
return ext;
return 0;
}

45
isisd/topology/spgrid.h Normal file
View File

@ -0,0 +1,45 @@
/*
* IS-IS Rout(e)ing protocol - topology/spgrid.h
Routines for manipulation of SSN and SRM flags
* Copyright (C) 2001 Sampo Saaristo, Ofer Wald
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public Licenseas published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
* Based on:
* SPLIB Copyright C 1994 by Cherkassky, Goldberg, and Radzik
*
*/
#ifndef _ZEBRA_ISIS_TOPOLOGY_SPGRID_H
#define _ZEBRA_ISIS_TOPOLOGY_SPGRID_H
struct arc {
long from_node;
long to_node;
long distance;
};
int gen_spgrid_topology (struct vty *vty, struct list *topology);
int spgrid_check_params (struct vty *vty, int argc, char **argv);
#endif /* _ZEBRA_ISIS_TOPOLOGY_SPGRID_H */

499
isisd/topology/sprand.c Normal file
View File

@ -0,0 +1,499 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <values.h>
#include "random.c"
#define DASH '-'
#define VERY_FAR 100000000
/* generator of random networks for the shortest paths problem;
extended DIMACS format for output */
main ( argc, argv )
int argc;
char* argv[];
{
char args[30];
long n,
n0,
source,
i,
i0,
j,
dij;
long m,
m0,
mc,
k;
long *p,
p_t,
l,
lx;
long seed,
seed1,
seed2;
int ext=0;
FILE *fout;
/* variables for lengths generating */
/* initialized by default values */
int l_f = 0, ll_f = 0, lm_f = 0, ln_f = 0, ls_f = 0;
long ll = 10000, /* length of the interval */
lm = 0; /* minimal bound of the interval */
double ln = 0, /* l += ln * |i-j| */
ls = 0; /* l += ls * |i-j|^2 */
/* variables for connecting cycle(s) */
int c_f = 0, cl_f = 0, ch_f = 0, c_random = 1;
long cl = 1; /* length of cycle arc */
long ch; /* number of arcs in the cycle
n - by default */
/* variables for artifical source */
int s_f = 0, sl_f = 0, sm_f = 0;
long sl = VERY_FAR, /* upper bound of artifical arc */
sm, /* lower bound of artifical arc */
s;
/* variables for potentials */
int p_f = 0, pl_f = 0, pm_f = 0, pn_f = 0, ps_f = 0,
pa_f = 0, pap_f = 0, pac_f = 0;
long pl, /* length of the interval */
pm; /* minimal bound of the interval */
double pn = 0, /* l += ln * |i-j| */
ps = 0, /* l += ls * |i-j|^2 */
pap = 0, /* part of nodes with alternative dustribution */
pac = -1; /* multiplier for alternative distribution */
int np; /* number of parameter parsing now */
#define PRINT_ARC( i, j, length )\
{\
l = length;\
if ( p_f ) l += ( p[i] - p[j] );\
printf ("a %8ld %8ld %12ld\n", i, j, l );\
}
/* parsing parameters */
if ( argc < 2 ) goto usage;
np = 0;
strcpy ( args, argv[1] );
if ( ( args[0] == DASH ) && ( args[1] == 'h')
)
goto help;
if ( argc < 4 ) goto usage;
/* first parameter - number of nodes */
np = 1;
if ( ( n = atoi ( argv[1] ) ) < 2 ) goto usage;
/* second parameter - number of arcs */
np = 2;
if ( ( m = atoi ( argv[2] ) ) < n ) goto usage;
/* third parameter - seed */
np=3;
if ( ( seed = atoi ( argv[3] ) ) <= 0 ) goto usage;
/* other parameters */
for ( np = 4; np < argc; np ++ )
{
strcpy ( args, argv[np] );
if ( args[0] != DASH ) goto usage;
switch ( args[1] )
{
case 'l' : /* an interval for arc length */
l_f = 1;
switch ( args[2] )
{
case 'l': /* length of the interval */
ll_f = 1;
ll = (long) atof ( &args[3] );
break;
case 'm': /* minimal bound */
lm_f = 1;
lm = (long ) atof ( &args[3] );
break;
case 'n': /* additional length: l*|i-j| */
ln_f = 1;
ln = atof ( &args[3] );
break;
case 's': /* additional length: l*|i-j|^2 */
ls_f = 1;
ls = atof ( &args[3] );
break;
default: /* unknown switch value */
goto usage;
}
break;
case 'c' : /* connecting cycle(s) */
c_f = 1;
switch ( args[2] )
{
case 'l':
c_random = 0;
cl_f = 1;
cl = (long) atof ( &args[3] );
if ( cl < 0 ) goto usage;
break;
case 'h':
ch_f = 1;
ch = (long) atof ( &args[3] );
if ( ch < 2 || ch > n ) goto usage;
break;
default: /* unknown switch value */
goto usage;
}
break;
case 's' : /* additional source */
s_f = 1;
if ( strlen ( args ) > 2 )
{
switch ( args[2] )
{
case 'l': /* upper bound of art. arc */
sl_f = 1;
sl = (long) atof ( &args[3] );
break;
case 'm': /* lower bound of art. arc */
sm_f = 1;
sm = (long) atof ( &args[3] );
break;
default: /* unknown switch value */
goto usage;
}
}
break;
case 'p' : /* potentials */
p_f = 1;
if ( strlen ( args ) > 2 )
{
switch ( args[2] )
{
case 'l': /* length of the interval */
pl_f = 1;
pl = (long) atof ( &args[3] );
break;
case 'm': /* minimal bound */
pm_f = 1;
pm = (long ) atof ( &args[3] );
break;
case 'n': /* additional length: l*|i-j| */
pn_f = 1;
pn = atof ( &args[3] );
break;
case 's': /* additional length: l*|i-j|^2 */
ps_f = 1;
ps = atof ( &args[3] );
break;
case 'a': /* bipolar distribution */
pa_f = 1;
switch ( args[3] )
{
case 'p': /* % of alternative potentials */
pap_f = 1;
pap = atof ( &args[4] );
if ( pap < 0 ) pap = 0;
if ( pap > 100 ) pap = 100;
pap /= 100;
break;
case 'c': /* multiplier */
pac_f = 1;
pac = atof ( &args[4] );
break;
default: /* unknown switch value */
goto usage;
}
break;
default: /* unknown switch value */
goto usage;
}
}
break;
default : /* unknoun case */
goto usage;
}
}
/* ----- ajusting parameters ----- */
n0 = n; m0 = m;
/* length parameters */
if ( ll < lm ) { lx = ll; ll = lm; lm = lx; }
/* potential parameters */
if ( p_f )
{
if ( ! pl_f ) pl = ll;
if ( ! pm_f ) pm = lm;
if ( pl < pm ) { lx = pl; pl = pm; pm = lx; }
}
/* path(s) parameters */
if ( ! ch_f ) ch = n;
mc = n + (n-2) / (ch-1);
if ( mc > m )
{ fprintf ( stderr,
"Error: not enough arcs for generating connecting cycle(s)\n" );
exit (4);
}
/* artifical source parameters */
if ( s_f )
{ m0 += n; n0 ++ ;
if ( ! sm_f ) sm = sl;
if ( sl < sm ) { lx = sl; sl = sm; sm = lx; }
}
/* printing title */
printf ("c random network for shortest paths problem\n");
printf ("c extended DIMACS format\nc\n" );
/* name of the problem */
printf ("t rd_%ld_%ld_%ld_", n, m, seed );
if ( l_f )
printf ("%c", 'l');
if ( c_f )
printf ("%c", 'c');
if ( s_f )
printf ("%c", 's');
if ( p_f )
printf ("%c", 'p');
printf ("\nc\n");
/* printing additional information */
if ( l_f )
printf ("c length -> min: %ld max: %ld k1: %.2f k2: %.2f\n",
lm, ll, ln, ls );
if ( c_f )
{
if ( c_random )
printf ("c cycle -> number of arcs: %ld arc length: random\n", ch);
else
printf ("c cycle -> number of arcs: %ld arc length: %ld\n",
ch, cl );
}
if ( s_f )
printf ("c length of arcs from artifical source -> min: %ld max: %ld\n",
sm, sl );
if ( p_f )
{
printf ("c potentials -> min: %ld max: %ld k1: %.2f k2: %.2f\n",
pm, pl, pn, ps );
if ( pa_f )
printf ("c potentials -> part of alternative distribution: %.2f k: %.2f\n",
pap, pac );
}
printf ("c\n" );
printf ("p sp %8ld %8ld\nc\n", n0, m0 );
source = ( s_f ) ? n0 : 1;
printf ("n %8ld\nc\n", source );
if ( p_f ) /* generating potentials */
{
p = (long*) calloc ( n+2, sizeof (long) );
seed1 = 2*seed + 1;
init_rand ( seed1);
pl = pl - pm + 1;
for ( i = 0; i <= n; i ++ )
{
p_t = pm + nrand ( pl );
if ( pn_f ) p_t += (long) ( i * pn );
if ( ps_f ) p_t += (long) ( i * ( i * ps ));
if ( pap_f )
if ( rand01() < pap )
p_t = (long) ( p_t * pac );
p[i] = p_t;
}
p[n+1] = 0;
}
if ( s_f ) /* additional arcs from artifical source */
{
seed2 = 3*seed + 1;
init_rand ( seed2 );
sl = sl - sm + 1;
for ( i = n; i > 1; i -- )
{
s = sm + nrand ( sl );
PRINT_ARC ( n0, i, s )
}
PRINT_ARC ( n0, 1, 0 )
}
/* initialize random number generator */
init_rand ( seed );
ll = ll - lm + 1;
/* generating connecting cycle(s) */
if (c_random)
cl = lm + nrand ( ll );
PRINT_ARC ( 1, 2, cl )
if (c_random)
cl = lm + nrand ( ll );
PRINT_ARC ( n, 1, cl )
for ( i = 2; i < n; i ++ )
{
if (c_random)
cl = lm + nrand ( ll );
if ( ( (i-1) % (ch-1) ) != 0 )
PRINT_ARC ( i, i+1, cl )
else
{ PRINT_ARC ( i, 1, cl )
if (c_random)
cl = lm + nrand ( ll );
PRINT_ARC ( 1, i+1, cl )
}
}
/* generating random arcs */
for ( k = 1; k <= m - mc; k ++ )
{
i = 1 + nrand ( n );
do
j = 1 + nrand ( n );
while ( j == i );
dij = ( i > j ) ? ( i - j ) : ( j - i );
l = lm + nrand ( ll );
if ( ln_f ) l += (long) ( dij * ln );
if ( ls_f ) l += (long) ( dij * ( dij * ls ) );
PRINT_ARC ( i, j, l );
}
/* all is done */
exit (ext);
/* ----- wrong usage ----- */
usage:
fprintf ( stderr,
"\nusage: %s n m seed [ -ll#i -lm#i -cl#i -p -pl#i -pm#i ... ]\n\
help: %s -h\n\n", argv[0], argv[0] );
if ( np > 0 )
fprintf ( stderr, "error in parameter # %d\n\n", np );
exit (4);
/* ---- help ---- */
help:
if ( args[2] == 'h') goto hhelp;
fprintf ( stderr,
"\n'%s' - random network generator for shortest paths problem.\n\
Generates problems in extended DIMACS format.\n\
\n\
%s n m seed [ -ll#i -lm#i -cl#i -p -pl#i -pm#i ... ]\n\
%s -hh\n\
\n\
#i - integer number #f - real number\n\
\n\
-ll#i - #i is the upper bound on arc lengths (default 10000)\n\
-lm#i - #i is the lower bound on arc lengths (default 0)\n\
-cl#i - #i is length of arcs in connecting cycle(s) (default random)\n\
-p - generate potentials \n\
-pl#i - #i is the upper bound on potentials (default ll)\n\
-pm#i - #i is the lower bound on potentials (default lm)\n\
\n\
-hh - extended help \n\n",
argv[0], argv[0], argv[0] );
exit (0);
/* --------- sophisticated help ------------ */
hhelp:
if ( argc < 3 )
fout = stderr;
else
fout = fopen ( argv[2], "w" );
if ( fout == NULL )
{ fprintf ( stderr, "\nCan't open file '%s' for writing help\n\n", argv[2] );
exit ( 2 );
}
fprintf (fout,
"\n'%s' - random network generator for shortest paths problem.\n\
Generates problems in extended DIMACS format.\n\
\n\
%s n m seed [ -ll#i -lm#i -ln#f -ls#f\n\
-p -pl#i -pm#i -pn#f -ps#f -pap#i -pac#f\n\
-cl#i -ch#i\n\
-s -sl#i -sm#i\n\
]\n\
%s -hh file_name\n\
\n\
#i - integer number #f - real number\n\
\n\
Arc length parameters:\n\
-ll#i - #i is the upper bound on arc lengths (default 10000)\n\
-lm#i - #i is the lower bound on arc lengths (default 0)\n\
-ln#f - multipliy l(i, j) by #f * |i-j| (default 0)\n\
-ls#f - multipliy l(i, j) by #f * |i-j|^2 (default 0)\n\
\n\
Potential parameters:\n\
-p - generate potentials \n\
-pl#i - #i is the upper bound on potentials (default ll)\n\
-pm#i - #i is the lower bound on potentials (default lm)\n\
-pn#f - multiply p(i) by #f * i (default 0)\n\
-ps#f - multiply p(i) by #f * i^2 (default 0)\n\
-pap#i - percentage of alternative potential nodes (default 0)\n\
-pac#f - if i is alternative, multiply p(i) by #f (default -1)\n\
\n\
Connecting cycle(s) parameters:\n\
-cl#i - #i is length of arcs in connecting cycle(s) (default random)\n\
-ch#i - #i is length of connecting cycles (default n)\n\
\n\
Artificial source parameters:\n\
-s - generate artificial source with default connecting arc lengths\n\
-sl#i - #i is the upper bound on art. arc lengths (default 100000000)\n\
-sm#i - #i is the lower bound on art. arc lengths (default sl)\n\
\n\
-hh file_name - save this help in the file 'file_name'\n\n",
argv[0], argv[0], argv[0] );
exit (0);
}