Initial revision

This commit is contained in:
paul 2002-12-13 20:15:29 +00:00
commit 718e374419
420 changed files with 243853 additions and 0 deletions

10
.cvsignore Normal file
View File

@ -0,0 +1,10 @@
config.log
config.h
config.cache
config.status
stamp-h
stamp-h[0-9]*
Makefile
.deps
autom4te.cache
configure.lineno

6
AUTHORS Normal file
View File

@ -0,0 +1,6 @@
Kunihiro Ishiguro <kunihiro@zebra.org>
Toshiaki Takada <takada@zebra.org>
Yasuhiro Ohara <yasu@sfc.wide.ad.jp>
Alex D. Zinin <azinin@hotmail.com>
Gleb Natapov <gleb@nbase.co.il>
Akihiro Mizutani <mizutani@dml.com>

339
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.

482
COPYING.LIB Normal file
View File

@ -0,0 +1,482 @@
GNU LIBRARY GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1991 Free Software Foundation, Inc.
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the library GPL. It is
numbered 2 because it goes with version 2 of the ordinary GPL.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Library General Public License, applies to some
specially designated Free Software Foundation software, and to any
other libraries whose authors decide to use it. You can use it for
your libraries, 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 library, or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link a program with the library, you must provide
complete object files to the recipients so that they can relink them
with the library, after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
Our method of protecting your rights has two steps: (1) copyright
the library, and (2) offer you this license which gives you legal
permission to copy, distribute and/or modify the library.
Also, for each distributor's protection, we want to make certain
that everyone understands that there is no warranty for this free
library. If the library is modified by someone else and passed on, we
want its recipients to know that what they have is not the original
version, 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 companies distributing free
software will individually obtain patent licenses, thus in effect
transforming the program into proprietary software. To prevent this,
we have made it clear that any patent must be licensed for everyone's
free use or not licensed at all.
Most GNU software, including some libraries, is covered by the ordinary
GNU General Public License, which was designed for utility programs. This
license, the GNU Library General Public License, applies to certain
designated libraries. This license is quite different from the ordinary
one; be sure to read it in full, and don't assume that anything in it is
the same as in the ordinary license.
The reason we have a separate public license for some libraries is that
they blur the distinction we usually make between modifying or adding to a
program and simply using it. Linking a program with a library, without
changing the library, is in some sense simply using the library, and is
analogous to running a utility program or application program. However, in
a textual and legal sense, the linked executable is a combined work, a
derivative of the original library, and the ordinary General Public License
treats it as such.
Because of this blurred distinction, using the ordinary General
Public License for libraries did not effectively promote software
sharing, because most developers did not use the libraries. We
concluded that weaker conditions might promote sharing better.
However, unrestricted linking of non-free programs would deprive the
users of those programs of all benefit from the free status of the
libraries themselves. This Library General Public License is intended to
permit developers of non-free programs to use free libraries, while
preserving your freedom as a user of such programs to change the free
libraries that are incorporated in them. (We have not seen how to achieve
this as regards changes in header files, but we have achieved it as regards
changes in the actual functions of the Library.) The hope is that this
will lead to faster development of free libraries.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, while the latter only
works together with the library.
Note that it is possible for a library to be covered by the ordinary
General Public License rather than by this special one.
GNU LIBRARY GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library which
contains a notice placed by the copyright holder or other authorized
party saying it may be distributed under the terms of this Library
General Public License (also called "this License"). Each licensee is
addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, 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 library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete 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 distribute a copy of this License along with the
Library.
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 Library or any portion
of it, thus forming a work based on the Library, 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) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
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 Library, 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 Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you 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.
If distribution of 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 satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also compile or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
c) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
d) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. 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.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library 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.
9. 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 Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
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.
11. 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 Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library 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 Library.
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.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library 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.
13. The Free Software Foundation may publish revised and/or new
versions of the Library 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 Library
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 Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
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
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "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
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. 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 LIBRARY 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
LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), 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 Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. 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 library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

674
ChangeLog Normal file
View File

@ -0,0 +1,674 @@
2002-07-07 Kunihiro Ishiguro <kunihiro@ipinfusion.com>
* zebra-0.93 released.
2002-06-28 Kunihiro Ishiguro <kunihiro@ipinfusion.com>
* update-autotools: Change file name from update-auto-tools.sh.
2002-06-21 Kunihiro Ishiguro <kunihiro@ipinfusion.com>
* update-auto-tools.sh: Add a new script to clean up build
environment.
2002-06-18 Kunihiro Ishiguro <kunihiro@ipinfusion.com>
* Shift to the latest build environment autoconf-2.53 and
automake-1.6.2.
2001-10-22 Kunihiro Ishiguro <kunihiro@ipinfusion.com>
* Integrate Glen Turner <glen.turner@aarnet.edu.au>'s pid option.
2001-08-19 Kunihiro Ishiguro <kunihiro@ipinfusion.com>
* zebra-0.92a released.
2001-08-19 "Peter Galbavy" <peter.galbavy@knowtion.net>
* configure.in: SNMP library check problem fix when the library is
installed under /usr/local/lib.
2001-08-15 Kunihiro Ishiguro <kunihiro@ipinfusion.com>
* zebra-0.92 released.
2001-04-22 Kunihiro Ishiguro <kunihiro@zebra.org>
* configure.in (LIBPAM): Use ZEBRA_AC_C_BIGENDIAN to avoid a
warning.
(IF_METHOD): Use test -r instead of AC_CHECK_FILE to avoid
warnings.
* config.guess: Update to 2000-11-10 version.
2001-04-11 Kunihiro Ishiguro <kunihiro@zebra.org>
* configure.in: Use AC_TRY_COMPILE instead of AC_EGREP_HEADER to
detect in_pktinfo structure. Suggested by: Vlad Lungu
<vlad@rls.roknet.ro>.
2001-03-07 Michael Rozhavsky <mrozhavsky@opticalaccess.com>
* configure.in: Add check for structure in_pktinfo.
2001-02-07 "Bjoern A. Zeeb" <bzeeb+zebra@zabbadoz.net>
* configure.in (USE_PAM): Fix PAM library detection code.
2001-02-01 Kunihiro Ishiguro <kunihiro@zebra.org>
* zebra-0.91 is released.
2001-01-12 Kunihiro Ishiguro <kunihiro@zebra.org>
* configure.in: Remove guile related definition.
2001-01-11 Kunihiro Ishiguro <kunihiro@zebra.org>
* configure.in (ac_cv_htonl_works): HAVE_REPAIRABLE_HTONL is
removed. htonl should work fine on any platform.
2001-01-10 Kunihiro Ishiguro <kunihiro@zebra.org>
* configure.in: Remove --enable-oldrib option.
* acconfig.h: OLD_RIB definition is removed.
* zebra-0.90 is released.
* configure.in (LIBS): Add check for sun_len field in struct
sun_len.
2001-01-09 Kunihiro Ishiguro <kunihiro@zebra.org>
* Makefile.am: Include init/redhat files to distribution.
2001-01-07 Yasuhiro Ohara <yasu@sfc.wide.ad.jp>
* configure.in: check libm.a for BGPd compile error.
AC_CHECK_LIB(m, main) was added.
2000-12-29 Kunihiro Ishiguro <kunihiro@zebra.org>
* configure.in: --enable-unixdomain becomes default. Add
--enable-tcp-zebra for TCP/IP communication between protocol
daemon and zebra.
* COPYING.LIB: Added for lib/getopt.c, lib/getopt.h,
lib/getopt1.c, lib/md5-gnu.h, lib/md5.c, lib/regex-gnu.h,
lib/regex.c.
* Makefile.am (dist-hook): Include tools/*.cgi to distribution.
2000-12-26 Kunihiro Ishiguro <kunihiro@zebra.org>
* configure.in (MULTIPATH_NUM): --enable-multipath=ARG specify
multipath number. ARG must be digit.
2000-12-11 Kunihiro Ishiguro <kunihiro@zebra.org>
* configure.in: Add --enable-newrib for test new RIB code.
2000-11-25 Yasuhiro Ohara <yasu@sfc.wide.ad.jp>
* configure.in, config.h.in: Add check for libutil.h and
setproctitle().
2000-10-26 Kunihiro Ishiguro <kunihiro@zebra.org>
* configure.in: Add --enable-nssa for OSPF NSSA option.
* acconfig.h: Define HAVE_NSSA.
2000-10-25 "Bjoern A. Zeeb" <bzeeb+zebra@zabbadoz.net>
* configure.in: pam_misc is only linked when the platform is
GNU/Linux.
2000-10-24 Arkadiusz Miskiewicz <misiek@pld.org.pl>
* configure.in (LIBS): Add check for crypto library. test x`ls
${ac_snmp}` is replaced with sipmle test -f.
2000-10-23 Kunihiro Ishiguro <kunihiro@zebra.org>
* configure.in: Add --enable-unixdomain option. This will be
default behavior in zebra-0.90.
2000-10-02 Kunihiro Ishiguro <kunihiro@zebra.org>
* zebra-0.89 is released.
2000-09-27 Kunihiro Ishiguro <kunihiro@zebra.org>
* configure.in: Add check for Intel CPU for Solaris on x86 check.
2000-09-21 Kunihiro Ishiguro <kunihiro@zebra.org>
* configure.in: Add check for getifaddrs().
Set AM_INIT_AUTOMAKE version to 0.89.
2000-09-14 Kunihiro Ishiguro <kunihiro@zebra.org>
* config.guess: Update to the latest version.
* config.sub: Likewise
2000-09-14 David Lipovkov <dlipovkov@OpticalAccess.com>
* REPORTING-BUGS: New file is added.
2000-08-27 itojun@iijlab.net
* configure.in: Add ncurses library check when --enable-vtysh is
specified.
2000-08-22 Kunihiro Ishiguro <kunihiro@zebra.org>
* configure.in: Add check for readline/history.h.
* acconfig.h: Remove pthread related variables.
* configure.in: Add --with-libpam option for vtysh PAM
authentication. Remove --disable-pthread because we don't support
pthread.
2000-08-17 Kunihiro Ishiguro <kunihiro@zebra.org>
* zebra-0.88 is released.
* configure.in: Add Solaris -lcurses for vtysh.
2000-08-02 Kunihiro Ishiguro <kunihiro@zebra.org>
* configure.in: Add check for ncurses for compiling on Solaris.
2000-07-27 Kunihiro Ishiguro <kunihiro@zebra.org>
* configure.in: Add check for libreadline when --enable-vtysh is
specified.
2000-07-23 Kunihiro Ishiguro <kunihiro@zebra.org>
* configure.in: Add AC_DEFINE(OPEN_BSD). When OS is OpenBSD
interface method is if_ioctl.o
2000-07-09 Chris Dunlop <chris@onthe.net.au>
* acconfig.h: Add HAVE_BROKEN_ALIASES.
* configure.in: Add --enable-broken-aliases.
2000-06-12 Kunihiro Ishiguro <kunihiro@zebra.org>
* Set version to zebra-0.87.
2000-06-05 Kunihiro Ishiguro <kunihiro@zebra.org>
* configure.in: Remove --enable-mpls-vpn. Now MPLS-VPN support is
default.
* Set version to zebra-0.87-pre
* Makefile.am: Likewise.
2000-04-27 Kunihiro Ishiguro <kunihiro@zebra.org>
* Set version to 0.86.
2000-03-21 Kunihiro Ishiguro <kunihiro@zebra.org>
* Set version to 0.85b for ospfd test.
2000-03-20 Kunihiro Ishiguro <kunihiro@zebra.org>
* Set version to 0.85a for ospfd test.
2000-03-08 Kunihiro Ishiguro <kunihiro@zebra.org>
* Set version to 0.85.
2000-01-26 Kunihiro Ishiguro <kunihiro@zebra.org>
* Makefile.in: Regenerated by patched automake for fixing "make
clean" problem on FreeBSD.
1999-12-08 Kunihiro Ishiguro <kunihiro@zebra.org>
* Set version to 0.83a. This is for *BSD static route lookup
problem.
1999-12-06 Kunihiro Ishiguro <kunihiro@zebra.org>
* Set version to 0.83.
1999-11-29 Kunihiro Ishiguro <kunihiro@zebra.org>
* Set version to 0.82.
1999-11-23 Kunihiro Ishiguro <kunihiro@zebra.org>
* aczebra.m4: New file added.
1999-11-21 Michael Handler <handler@sub-rosa.com>
* configure.in (LIBS): Add sa_len check of sockaddr.
* acconfig.h: Add HAVE_SA_LEN.
1999-11-12 Kunihiro Ishiguro <kunihiro@zebra.org>
* version.h: Update version to zebra-0.81b for bgpd test.
1999-11-09 Kunihiro Ishiguro <kunihiro@zebra.org>
* configure.in: Add --enable-mbgp.
1999-11-05 Kunihiro Ishiguro <kunihiro@zebra.org>
* Makefile.am (EXTRA_DIST): Add TODO to the distribution.
1999-11-04 Kunihiro Ishiguro <kunihiro@zebra.org>
* TODO: New file is added.
1999-11-03 Kunihiro Ishiguro <kunihiro@zebra.org>
* version.h: Update version to zebra-0.81a for ospfd test.
1999-10-28 Kunihiro Ishiguro <kunihiro@zebra.org>
* configure.in: New option --enable-snmp is added.
1999-10-24 Kunihiro Ishiguro <kunihiro@zebra.org>
* version.h: Update version to zebra-0.80.
1999-10-21 Kunihiro Ishiguro <kunihiro@zebra.org>
* version.h: Update version to zebra-0.80-pre3
1999-10-18 Kunihiro Ishiguro <kunihiro@zebra.org>
* configure.in (LIBS): SNMP check is done by ucd-snmp/asn1.h.
1999-10-10 Peter Galbavy <Peter.Galbavy@knowledge.com>
* configure.in: Add support of OpenBSD.
1999-10-04 Kunihiro Ishiguro <kunihiro@zebra.org>
* version.h: Update version to zebra-0.80-pre2.
1999-09-27 Kunihiro Ishiguro <kunihiro@zebra.org>
* version.h: Update version to zebra-0.80-pre. From this version,
access-list and prefix-list's name space is divided into IPv4 and
IPv6.
1999-09-17 Kunihiro Ishiguro <kunihiro@zebra.org>
* version.h: For test recent fixes Set version to zebra-0.79a.
1999-09-14 Kunihiro Ishiguro <kunihiro@zebra.org>
* version.h: zebra-0.79 is out.
1999-09-08 Kunihiro Ishiguro <kunihiro@zebra.org>
* version.h: For ospfd's virtual link test. Set version to 0.78h.
1999-09-07 Kunihiro Ishiguro <kunihiro@zebra.org>
* version.h: For ospfd test. Set version to 0.78g.
1999-09-05 Kunihiro Ishiguro <kunihiro@zebra.org>
* version.h: For internal test of ospfd. Set version to 0.78f.
1999-09-02 Kunihiro Ishiguro <kunihiro@zebra.org>
* version.h: To test ospfd's fix, set version to 0.78e.
1999-09-01 Kunihiro Ishiguro <kunihiro@zebra.org>
* version.h: To test ospfd's area related bug fix, set version
to 0.78d.
1999-09-01 Kunihiro Ishiguro <kunihiro@zebra.org>
* version.h: To test ospfd, set version to 0.78c.
1999-08-31 Janos Farkas <chexum@shadow.banki.hu>
* Many misspelling correction.
1999-08-31 Kunihiro Ishiguro <kunihiro@zebra.org>
* version.h: To test ospfd, set version to 0.78b.
1999-08-31 Kunihiro Ishiguro <kunihiro@zebra.org>
* configure.in (LIBS): Add UCD-SNMP include path check.
1999-08-31 Lars Fenneberg <lf@elemental.net>
* configure.in: The logic which detects the UCD-SNMP library
should first check in the default system locations for the library
and then in /usr/local.
1999-08-27 itojun@iijlab.net
* configure.in (LIBS): Fix problem about libsnmp.a check.
1999-08-26 kay <kay@v6.access.co.jp>
* configure.in (CFLAGS): Add <sys/socket.h> to check socklen_t.
1999-08-24 VOP <vop@unity.net>
* filter.c: Include "sockunion.h".
plist.c: Likewise.
table.c: Likewise.
1999-08-24 Kunihiro Ishiguro <kunihiro@zebra.org>
* configure.in: Add netinet6/in6.h check.
1999-08-21 Masaki Minami <masaki@minami.org>
* BSD/OS 4.0 porting.
1999-08-15 Kunihiro Ishiguro <kunihiro@zebra.org>
* configure.in: Add --enable-netlink option to force to use Linux
netlink interface.
(CFLAGS): Add ucd-snmp library check.
* acconfig.h: If socklen_t is not defined, typedef int to
socklen_t.
1999-08-15 Arkadiusz Miskiewicz <misiek@misiek.eu.org>
* configure.in: When --enable-ipv6 specified, then only kernel
version is checked.
1999-08-14 Kunihiro Ishiguro <kunihiro@zebra.org>
* configure.in: Add GNU libc 2.1 check.
1999-08-02 Kunihiro Ishiguro <kunihiro@zebra.org>
* configure.in: Fix privious Linux IPv6 check changes.
1999-08-02 Arkadiusz Miskiewicz <misiek@misiek.eu.org>
* configure.in: Improve Linux IPv6 feature check.
1999-07-29 Rick Payne <rickp@rossfell.co.uk>
* Changed route-maps to behave in a more cisco-like fashion
1999-07-27 Gerhard Poul <gpoul@gnu.org>
* SERVICES: New file added.
1999-07-12 itojun@iijlab.net
* configure.in: Add check for getaddrinfo. Improve Kame related
library check.
1999-07-07 Yasuhiro Ohara <yasu@sfc.wide.ad.jp>
* configure.in, acconfig.h: Add check for FreeBSD 3.2.
1999-07-07 Kunihiro Ishiguro <kunihiro@zebra.org>
* configure.in: Delete check for netinet/ip6.h.
1999-06-30 Gerhard Poul <gpoul@gnu.org>
* README: remixed the old files and added some new parts.
moved some INSTALL stuff into INSTALL file.
moved some other stuff to doc/zebra.texi
1999-06-29 Kunihiro Ishiguro <kunihiro@zebra.org>
* configure.in (LIBS): Add libresolv check.
Change --enabe-all-in-one option to --enable-one-vty.
1999-06-20 Kunihiro Ishiguro <kunihiro@zebra.org>
* configure.in: Add --enabe-all-in-one option.
1999-06-16 Kunihiro Ishiguro <kunihiro@zebra.org>
* configure.in: Add socklen_t check.
1999-06-16 Gerhard Poul <gpoul@gnu.org>
* Many compile warnings fixed.
1999-05-31 Kunihiro Ishiguro <kunihiro@zebra.org>
* configure.in: Change message from Linux 2.2.X IPv6 to Linux IPv6.
OpenBSD (NRL) check is enabled.
1999-05-30 Kunihiro Ishiguro <kunihiro@zebra.org>
* configure.in (LIBS): Add crypt library check.
1999-05-08 Kunihiro Ishiguro <kunihiro@zebra.org>
* configure.in: Add sin6_scope_id in struct sockaddr_in6 check.
1999-04-30 Kunihiro Ishiguro <kunihiro@zebra.org>
* Set version to 0.63 for first beta package.
1999-04-15 Kunihiro Ishiguro <kunihiro@zebra.org>
* guile.m4: Added from guile package.
1999-04-14 Kunihiro Ishiguro <kunihiro@zebra.org>
* Set version to 0.60 for beta package preparation.
1999-04-12 Kunihiro Ishiguro <kunihiro@zebra.org>
* Makefile.am: Add noninst_LIBRARIES each directory's Makefile.am.
This change is for linking these libraries to guile.
1999-04-08 Kunihiro Ishiguro <kunihiro@zebra.org>
* configure.in (LIBS): Add struct rt_addrinfo check.
1999-04-07 Kunihiro Ishiguro <kunihiro@zebra.org>
* configure.in: AC_STDC_HEADERS added.
1999-03-29 Kunihiro Ishiguro <kunihiro@zebra.org>
* Add dependencies to each directory's Makefile.am.
1999-03-02 Peter Galbavy <Peter.Galbavy@knowledge.com>
* reworked include file structure, and configure so that all
source files get all system-dependent include files by including
<zebra.h> which is really lib/zebra.h. This means that the
different programs include files are now available as #include
"zebra/zebra.h" - note the use of quotes, not <> as delimiters.
In practical terms, if I haven't really screwed up, the main file
that maintainers for other OSes have to change is lib/zebra.h for
all the conditional includes etc.
* added --disable-pthread for those systems that seem to have
POSIX threads, but do not work. OpenBSD 2.4+ is like that just
now. Changed all occurance of #ifdef PTHREAD to use HAVE_PTHREAD
instead.
1999-02-24 <kunihiro@zebra.org>
* configure.in: update to AC_PREREQ(1.13).
Change message from Linux 2.1.x to Linux 2.2.x.
* Added ospf6d directory support.
1999-02-22 Peter Galbavy <Peter.Galbavy@knowledge.com>
* added a "log" element to the BGPd peer structure, enabling us to
start thinging about a log stream per peer. This is currently
ignored by the wrapper code, but developers should try to use the
"appropriate" ZLOG stream. Documentation will follow, when the
real routines start to exist.
The current plan is to use a copy of the BSD syslog() routines and
replace the syslog library function with our own. I will need
feedback from users of other platforms as this work is done to see
if all is well elsewhere.
* preliminary work on zlog() library. directly replaces syslog()
currently with zlog(ZLOG *, ...) where the new first argument
is a pointer to a ZLOG structure (defined in lib/log.h) and will
encapsulate all the information necessary to maintain multiple
logging streams.
1999-02-19 Peter Galbavy <Peter.Galbavy@knowledge.com>
* added vsnprintf() macro to lib/str.h if required and removed
#ifdef SUNOS_5 dependency on it
1999-02-18 Peter Galbavy <Peter.Galbavy@knowledge.com>
* syslog support added
1999-02-18 Peter Galbavy <Peter.Galbavy@knowledge.com>
* configure.in: Add daemon function check.
1999-01-21 Kunihiro Ishiguro <kunihiro@zebra.org>
* configure.in: Add --disable-ipv6, --disable-zebra,
--disable-bgpd, --disable-ripd, --disable-ripngd, --disable-ospfd
options to configure.
1998-12-07 Kunihiro Ishiguro <kunihiro@zebra.org>
* configure.in: Check /usr/inet6/lib/libinet6.a exists or not.
1998-10-14 Kunihiro Ishiguro <kunihiro@zebra.org>
* configure.in: Comment out FreeBSD's libc_r detect section. At
this moment it doesn't work correctly with zebra.
Netlink interface is only enabled when Linux kernel version is
upper than 2.1.0.
1998-09-15 HEO SeonMeyong <seirios@matrix.iri.co.jp>
* Hydrangea is now called KAME, so change all defines.
1998-08-16 Kunihiro Ishiguro <kunihiro@zebra.org>
* configure.in: ifaliasreq check added.
1998-08-12 Katsuhiro Kondou <kondou@nec.co.jp>
* Patch is applied for compile under EWS4800
1998-06-09 Kunihiro Ishiguro <kunihiro@zebra.org>
* configure.in: delete old mtu_method check.
* doc/zebra.texi (Kernel interface): chapter `Kernel interface' added
1998-06-08 Kunihiro Ishiguro <kunihiro@zebra.org>
* configure.in: add new netlink check for GNU/Linux
1998-06-07 Kunihiro Ishiguro <kunihiro@zebra.org>
* doc/zebra.texi: Update Linux netlink chapter.
1998-05-18 Yamashita TAKAO <jargon@lares.dti.ne.jp>
* config.h.in: define PTHREAD if work on Solaris 2.6
why delete the definition? I miss?
1998-05-08 Kunihiro Ishiguro <kunihiro@zebra.org>
* configure.in: add net/if.h header check.
1998-05-02 SeonMeyong HEO <seirios@Matrix.iri.co.jp>
* zebra.tex,archfig.tex,zebra.sty: Manual file is added.
* zebra.texi: Modify Introduction text.
* RIPngd.c: Patch Hydrangea code.
1998-05-01 Kunihiro Ishiguro <kunihiro@zebra.org>
* .cvsignore: added.
* Makerule.in: is gone.
* Makefile.am: Now we use automake to generate Makefile.in
1998-03-19 Yamashita TAKAO <jargon@lares.dti.ne.jp>
* lib/vty.c: modified the definition of *master
* lib/sockunion.c (inet_aton): add, but don't work. uum...
1998-03-15 Yamashita TAKAO <jargon@lares.dti.ne.jp>
* configure.in: define PTHREAD if work on Solaris 2.6
* config.h.in: likewise
* lib/thread.c: likewise
* lib/vty.c: likewise
1998-03-15 SeonMeyong HEO <seirios@Matrix.iri.co.jp>
* config.h.in: define INET6 if defined HAVE_IPV6 & HYDRANGEA
* bgpd/: remove include <netinet6/in6.h> line.
* lib/: remove include <netinet6/in6.h> line.
* ripbgd/: remove include <netinet6/in6.h> line.
* zebra/: remove include <netinet6/in6.h> line.
* ripd/*.c: remove include <netinet6/in6.h> line.
undefine IPV6 difinitions because RIPd is not worked for
IPv6 protocol.
1998-01-30 Kunihiro Ishiguro <kunihiro@zebra.org>
* configure.in: Change routing socket check method from
AC_TRY_COMPILE to AC_TRY_RUN because GNU libc version 2 has
AF_ROUTE but over linux it's meenigless.
1998-01-06 Kunihiro Ishiguro <kunihiro@zebra.org>
* config.h.in: remove err_t define.
1997-11-18 Kunihiro Ishiguro <kunihiro@zebra.org>
* configure.in (canonical): add check of IF_METHOD
1997-09-27 Kunihiro Ishiguro <kunihiro@note.digital-magic.co.jp>
* configure.in: add INRIA check
1997-09-25 Kunihiro Ishiguro <kunihiro@note.digital-magic.co.jp>
* configure.in (canonical): change ipforward_snmp.o to ipforward_proc.o
1997-09-12 Kunihiro Ishiguro <kunihiro@zebra.org>
* configure.in: change IRDPD to NDPD
1997-08-18 Kunihiro Ishiguro <kunihiro@zebra.org>
* INSTALL: new file
1997-08-14 Kunihiro Ishiguro <kunihiro@zebra.org>
* config.h: add XCALLOC()

181
INSTALL Normal file
View File

@ -0,0 +1,181 @@
Basic Installation
==================
These are generic installation instructions.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, a file
`config.cache' that saves the results of its tests to speed up
reconfiguring, and a file `config.log' containing compiler output
(useful mainly for debugging `configure').
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If at some point `config.cache'
contains results you don't want to keep, you may remove or edit it.
The file `configure.in' is used to create `configure' by a program
called `autoconf'. You only need `configure.in' if you want to change
it or regenerate `configure' using a newer version of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system. If you're
using `csh' on an old version of System V, you might need to type
`sh ./configure' instead to prevent `csh' from trying to execute
`configure' itself.
Running `configure' takes awhile. While running, it prints some
messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
the package.
4. Type `make install' to install the programs and any data files and
documentation.
5. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that
the `configure' script does not know about. You can give `configure'
initial values for variables by setting them in the environment. Using
a Bourne-compatible shell, you can do that on the command line like
this:
CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
Or on systems that have the `env' program, you can do it like this:
env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you must use a version of `make' that
supports the `VPATH' variable, such as GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'.
If you have to use a `make' that does not supports the `VPATH'
variable, you have to compile the package for one architecture at a time
in the source code directory. After you have installed the package for
one architecture, use `make distclean' before reconfiguring for another
architecture.
Installation Names
==================
By default, `make install' will install the package's files in
`/usr/local/bin', `/usr/local/man', etc. You can specify an
installation prefix other than `/usr/local' by giving `configure' the
option `--prefix=PATH'.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
give `configure' the option `--exec-prefix=PATH', the package will use
PATH as the prefix for installing programs and libraries.
Documentation and other data files will still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=PATH' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them.
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Optional Features
=================
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Specifying the System Type
==========================
There may be some features `configure' can not figure out
automatically, but needs to determine by the type of host the package
will run on. Usually `configure' can figure that out, but if it prints
a message saying it can not guess the host type, give it the
`--host=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name with three fields:
CPU-COMPANY-SYSTEM
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the host type.
If you are building compiler tools for cross-compiling, you can also
use the `--target=TYPE' option to select the type of system they will
produce code for and the `--build=TYPE' option to select the type of
system on which you are compiling the package.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share,
you can create a site shell script called `config.site' that gives
default values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Operation Controls
==================
`configure' recognizes the following options to control how it
operates.
`--cache-file=FILE'
Use and save the results of the tests in FILE instead of
`./config.cache'. Set FILE to `/dev/null' to disable caching, for
debugging `configure'.
`--help'
Print a summary of the options to `configure', and exit.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made.
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`--version'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`configure' also accepts some other, not widely useful, options.

16
Makefile.am Normal file
View File

@ -0,0 +1,16 @@
## Process this file with automake to produce Makefile.in.
SUBDIRS = lib @ZEBRA@ @BGPD@ @RIPD@ @RIPNGD@ @OSPFD@ @OSPF6D@ @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

548
Makefile.in Normal file
View File

@ -0,0 +1,548 @@
# Makefile.in generated by automake 1.7 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@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = .
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
host_triplet = @host@
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BGPD = @BGPD@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CURSES = @CURSES@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
IF_METHOD = @IF_METHOD@
IF_PROC = @IF_PROC@
INCLUDES = @INCLUDES@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
IPFORWARD = @IPFORWARD@
KERNEL_METHOD = @KERNEL_METHOD@
LDFLAGS = @LDFLAGS@
LIBPAM = @LIBPAM@
LIBS = @LIBS@
LIB_IPV6 = @LIB_IPV6@
LIB_REGEX = @LIB_REGEX@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MULTIPATH_NUM = @MULTIPATH_NUM@
OBJEXT = @OBJEXT@
OSPF6D = @OSPF6D@
OSPFD = @OSPFD@
OTHER_METHOD = @OTHER_METHOD@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
RIPD = @RIPD@
RIPNGD = @RIPNGD@
RTREAD_METHOD = @RTREAD_METHOD@
RT_METHOD = @RT_METHOD@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
VTYSH = @VTYSH@
ZEBRA = @ZEBRA@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__include = @am__include@
am__quote = @am__quote@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localstatedir = @localstatedir@
mandir = @mandir@
oldincludedir = @oldincludedir@
prefix = @prefix@
program_transform_name = @program_transform_name@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
SUBDIRS = lib @ZEBRA@ @BGPD@ @RIPD@ @RIPNGD@ @OSPFD@ @OSPF6D@ @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 pdf-recursive \
ps-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 \
configure.lineno
$(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
ctags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
done
ETAGS = etags
ETAGSFLAGS =
CTAGS = ctags
CTAGSFLAGS =
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
ctags: CTAGS
CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
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 "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_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 tags
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
distuninstallcheck_listfiles = find . -type f -print
distcleancheck_listfiles = find . -type f -print
distdir: $(DISTFILES)
$(am__remove_distdir)
mkdir $(distdir)
$(mkinstalldirs) $(distdir)/vtysh
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
esac; \
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` \
&& dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
&& $(mkinstalldirs) $$dc_destdir \
&& 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 \
&& $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
distuninstallcheck \
&& chmod -R a-w "$$dc_install_base" \
&& ({ $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
} || { rm -rf "$$dc_destdir"; exit 1; }) \
&& rm -rf "$$dc_destdir" \
&& $(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'
distuninstallcheck:
cd $(distuninstallcheck_dir) \
&& test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
|| { echo "ERROR: files left after uninstall:" ; \
if test -n "$(DESTDIR)"; then \
echo " (check DESTDIR support)"; \
fi ; \
$(distuninstallcheck_listfiles) ; \
exit 1; } >&2
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 in build directory 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
pdf: pdf-recursive
pdf-am:
ps: ps-recursive
ps-am:
uninstall-am: uninstall-info-am
uninstall-info: uninstall-info-recursive
.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am clean \
clean-generic clean-recursive ctags ctags-recursive dist \
dist-all dist-gzip distcheck distclean distclean-generic \
distclean-hdr distclean-recursive distclean-tags distcleancheck \
distdir distuninstallcheck 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 pdf pdf-am pdf-recursive ps ps-am \
ps-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:

2338
NEWS Normal file

File diff suppressed because it is too large Load Diff

12
README Normal file
View File

@ -0,0 +1,12 @@
GNU Zebra is free software that manages various IPv4 and IPv6 routing
protocols.
Currently GNU Zebra supports BGP4, BGP4+, OSPFv2, OSPFv3, RIPv1,
RIPv2, and RIPng.
See the file INSTALL for building and installation instructions.
See the file REPORTING-BUGS to report bugs.
GNU Zebra is free software. See the file COPYING for copying conditions.

28
REPORTING-BUGS Normal file
View File

@ -0,0 +1,28 @@
This file describes the procedure for reporting Zebra bugs.
You are not obliged to follow this format , but it would be
great help for Zebra developers if you report a bug as described
below.
Send your report to bug-zebra@gnu.org mailing list.
Please supply the following information:
1. Your zebra version or if it is CVS version then the date you did checkout.
Always try to report the bugs on the current CVS version.
2. Zebra daemons you run e.g. bgpd or ripd, your OS full name,
any specific options you compiled zebra with.
3. Problem description. Copy and paste relative zebra commands and their
output to describe your network setup e.g. "zebra>show ip route".
Please, also give your simple network layout and output of relative OS commands
(e.g. ifconfig).
4. All zebra configuration files you use. If you don't want to publish
your network numbers change 2 middle bytes in IPv4 address to be XXX e.g.
192.XXX.XXX.32/24. Similar could be done with IPv6.
5. If any zebra daemon core dumped, please, supply stack trace using
the following commands: host> gdb exec_file core_file , (gdb) bt .
6. Run all zebra daemons with full debugging on (see documentation on debugging) and
send _only_ part of logs which are relative to your problem.
7. If the problem is difficult to reproduce please send a shell script to
reproduce it.
8. Patches, workarounds, fixes are always welcome.
Thank You.

17
SERVICES Normal file
View File

@ -0,0 +1,17 @@
# As long as this software is in alpha testing it is not yet included
# in /etc/services files. This means that you may need to add the following
# lines into your /etc/services file on your hosts.
#
# --- Please add this to your /etc/services ---
#
# GNU Zebra services
#
zebrasrv 2600/tcp
zebra 2601/tcp
ripd 2602/tcp
ripng 2603/tcp
ospfd 2604/tcp
bgpd 2605/tcp
ospf6d 2606/tcp

29
TODO Normal file
View File

@ -0,0 +1,29 @@
Zebra TODO list
2002/06/18
zebra:
o Pointopoint address configuration.
o Multiple (alias) address configuration for the interface when kernel
support it [just starting].
bgpd:
o BGP TCP MD5 authentication (on OpenBSD) by password command.
o HUP signal support (reload configuration file).
o BGP multi-path extension
ripd:
o Multipath support.
ospfd:
o Rewrite the incremental RT update code.
o Demand circuits.
o Multiple instances.
o OSPF MIB [SNMP get is amost finished].
o HUP signal treatment.
--
Kunihiro Ishiguro <kunihiro@zebra.org>

161
acconfig.h Normal file
View File

@ -0,0 +1,161 @@
/* 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
/* 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 */

811
aclocal.m4 vendored Normal file
View File

@ -0,0 +1,811 @@
# generated automatically by aclocal 1.7 -*- Autoconf -*-
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002
# Free Software Foundation, Inc.
# This file 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.
# Do all the work for Automake. -*- Autoconf -*-
# This macro actually does too much some checks are only needed if
# your package does certain things. But this isn't really a big deal.
# Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002
# Free Software Foundation, Inc.
# 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, 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.
# serial 8
# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
# written in clear, in which case automake, when reading aclocal.m4,
# will think it sees a *use*, and therefore will trigger all it's
# C support machinery. Also note that it means that autoscan, seeing
# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
AC_PREREQ([2.54])
# Autoconf 2.50 wants to disallow AM_ names. We explicitly allow
# the ones we care about.
m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
# AM_INIT_AUTOMAKE([OPTIONS])
# -----------------------------------------------
# The call with PACKAGE and VERSION arguments is the old style
# call (pre autoconf-2.50), which is being phased out. PACKAGE
# and VERSION should now be passed to AC_INIT and removed from
# the call to AM_INIT_AUTOMAKE.
# We support both call styles for the transition. After
# the next Automake release, Autoconf can make the AC_INIT
# arguments mandatory, and then we can depend on a new Autoconf
# release and drop the old call support.
AC_DEFUN([AM_INIT_AUTOMAKE],
[AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
AC_REQUIRE([AC_PROG_INSTALL])dnl
# test to see if srcdir already configured
if test "`cd $srcdir && pwd`" != "`pwd`" &&
test -f $srcdir/config.status; then
AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
fi
# test whether we have cygpath
if test -z "$CYGPATH_W"; then
if (cygpath --version) >/dev/null 2>/dev/null; then
CYGPATH_W='cygpath -w'
else
CYGPATH_W=echo
fi
fi
AC_SUBST([CYGPATH_W])
# Define the identity of the package.
dnl Distinguish between old-style and new-style calls.
m4_ifval([$2],
[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
AC_SUBST([PACKAGE], [$1])dnl
AC_SUBST([VERSION], [$2])],
[_AM_SET_OPTIONS([$1])dnl
AC_SUBST([PACKAGE], [AC_PACKAGE_TARNAME])dnl
AC_SUBST([VERSION], [AC_PACKAGE_VERSION])])dnl
_AM_IF_OPTION([no-define],,
[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
# Some tools Automake needs.
AC_REQUIRE([AM_SANITY_CHECK])dnl
AC_REQUIRE([AC_ARG_PROGRAM])dnl
AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
AM_MISSING_PROG(AUTOCONF, autoconf)
AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
AM_MISSING_PROG(AUTOHEADER, autoheader)
AM_MISSING_PROG(MAKEINFO, makeinfo)
AM_MISSING_PROG(AMTAR, tar)
AM_PROG_INSTALL_SH
AM_PROG_INSTALL_STRIP
# We need awk for the "check" target. The system "awk" is bad on
# some platforms.
AC_REQUIRE([AC_PROG_AWK])dnl
AC_REQUIRE([AC_PROG_MAKE_SET])dnl
_AM_IF_OPTION([no-dependencies],,
[AC_PROVIDE_IFELSE([AC_PROG_CC],
[_AM_DEPENDENCIES(CC)],
[define([AC_PROG_CC],
defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
AC_PROVIDE_IFELSE([AC_PROG_CXX],
[_AM_DEPENDENCIES(CXX)],
[define([AC_PROG_CXX],
defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
])
])
# When config.status generates a header, we must update the stamp-h file.
# This file resides in the same directory as the config header
# that is generated. The stamp files are numbered to have different names.
# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
# loop where config.status creates the headers, so we can generate
# our stamp files there.
AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
[_am_stamp_count=`expr ${_am_stamp_count-0} + 1`
echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count])
# Copyright 2002 Free Software Foundation, Inc.
# 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, 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
# AM_AUTOMAKE_VERSION(VERSION)
# ----------------------------
# Automake X.Y traces this macro to ensure aclocal.m4 has been
# generated from the m4 files accompanying Automake X.Y.
AC_DEFUN([AM_AUTOMAKE_VERSION],[am__api_version="1.7"])
# AM_SET_CURRENT_AUTOMAKE_VERSION
# -------------------------------
# Call AM_AUTOMAKE_VERSION so it can be traced.
# This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
[AM_AUTOMAKE_VERSION([1.7])])
# Helper functions for option handling. -*- Autoconf -*-
# Copyright 2001, 2002 Free Software Foundation, Inc.
# 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, 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.
# serial 2
# _AM_MANGLE_OPTION(NAME)
# -----------------------
AC_DEFUN([_AM_MANGLE_OPTION],
[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
# _AM_SET_OPTION(NAME)
# ------------------------------
# Set option NAME. Presently that only means defining a flag for this option.
AC_DEFUN([_AM_SET_OPTION],
[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
# _AM_SET_OPTIONS(OPTIONS)
# ----------------------------------
# OPTIONS is a space-separated list of Automake options.
AC_DEFUN([_AM_SET_OPTIONS],
[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
# -------------------------------------------
# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
AC_DEFUN([_AM_IF_OPTION],
[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
#
# Check to make sure that the build environment is sane.
#
# Copyright 1996, 1997, 2000, 2001 Free Software Foundation, Inc.
# 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, 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.
# serial 3
# AM_SANITY_CHECK
# ---------------
AC_DEFUN([AM_SANITY_CHECK],
[AC_MSG_CHECKING([whether build environment is sane])
# Just in case
sleep 1
echo timestamp > conftest.file
# Do `set' in a subshell so we don't clobber the current shell's
# arguments. Must try -L first in case configure is actually a
# symlink; some systems play weird games with the mod time of symlinks
# (eg FreeBSD returns the mod time of the symlink's containing
# directory).
if (
set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
if test "$[*]" = "X"; then
# -L didn't work.
set X `ls -t $srcdir/configure conftest.file`
fi
rm -f conftest.file
if test "$[*]" != "X $srcdir/configure conftest.file" \
&& test "$[*]" != "X conftest.file $srcdir/configure"; then
# If neither matched, then we have a broken ls. This can happen
# if, for instance, CONFIG_SHELL is bash and it inherits a
# broken ls alias from the environment. This has actually
# happened. Such a system could not be considered "sane".
AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
alias in your environment])
fi
test "$[2]" = conftest.file
)
then
# Ok.
:
else
AC_MSG_ERROR([newly created file is older than distributed files!
Check your system clock])
fi
AC_MSG_RESULT(yes)])
# -*- Autoconf -*-
# Copyright 1997, 1999, 2000, 2001 Free Software Foundation, Inc.
# 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, 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.
# serial 3
# AM_MISSING_PROG(NAME, PROGRAM)
# ------------------------------
AC_DEFUN([AM_MISSING_PROG],
[AC_REQUIRE([AM_MISSING_HAS_RUN])
$1=${$1-"${am_missing_run}$2"}
AC_SUBST($1)])
# AM_MISSING_HAS_RUN
# ------------------
# Define MISSING if not defined so far and test if it supports --run.
# If it does, set am_missing_run to use it, otherwise, to nothing.
AC_DEFUN([AM_MISSING_HAS_RUN],
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
# Use eval to expand $SHELL
if eval "$MISSING --run true"; then
am_missing_run="$MISSING --run "
else
am_missing_run=
AC_MSG_WARN([`missing' script is too old or missing])
fi
])
# AM_AUX_DIR_EXPAND
# Copyright 2001 Free Software Foundation, Inc.
# 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, 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.
# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
#
# Of course, Automake must honor this variable whenever it calls a
# tool from the auxiliary directory. The problem is that $srcdir (and
# therefore $ac_aux_dir as well) can be either absolute or relative,
# depending on how configure is run. This is pretty annoying, since
# it makes $ac_aux_dir quite unusable in subdirectories: in the top
# source directory, any form will work fine, but in subdirectories a
# relative path needs to be adjusted first.
#
# $ac_aux_dir/missing
# fails when called from a subdirectory if $ac_aux_dir is relative
# $top_srcdir/$ac_aux_dir/missing
# fails if $ac_aux_dir is absolute,
# fails when called from a subdirectory in a VPATH build with
# a relative $ac_aux_dir
#
# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
# are both prefixed by $srcdir. In an in-source build this is usually
# harmless because $srcdir is `.', but things will broke when you
# start a VPATH build or use an absolute $srcdir.
#
# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
# and then we would define $MISSING as
# MISSING="\${SHELL} $am_aux_dir/missing"
# This will work as long as MISSING is not called from configure, because
# unfortunately $(top_srcdir) has no meaning in configure.
# However there are other variables, like CC, which are often used in
# configure, and could therefore not use this "fixed" $ac_aux_dir.
#
# Another solution, used here, is to always expand $ac_aux_dir to an
# absolute PATH. The drawback is that using absolute paths prevent a
# configured tree to be moved without reconfiguration.
# Rely on autoconf to set up CDPATH properly.
AC_PREREQ([2.50])
AC_DEFUN([AM_AUX_DIR_EXPAND], [
# expand $ac_aux_dir to an absolute path
am_aux_dir=`cd $ac_aux_dir && pwd`
])
# AM_PROG_INSTALL_SH
# ------------------
# Define $install_sh.
# Copyright 2001 Free Software Foundation, Inc.
# 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, 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.
AC_DEFUN([AM_PROG_INSTALL_SH],
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
install_sh=${install_sh-"$am_aux_dir/install-sh"}
AC_SUBST(install_sh)])
# AM_PROG_INSTALL_STRIP
# Copyright 2001 Free Software Foundation, Inc.
# 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, 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.
# One issue with vendor `install' (even GNU) is that you can't
# specify the program used to strip binaries. This is especially
# annoying in cross-compiling environments, where the build's strip
# is unlikely to handle the host's binaries.
# Fortunately install-sh will honor a STRIPPROG variable, so we
# always use install-sh in `make install-strip', and initialize
# STRIPPROG with the value of the STRIP variable (set by the user).
AC_DEFUN([AM_PROG_INSTALL_STRIP],
[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
# Installed binaries are usually stripped using `strip' when the user
# run `make install-strip'. However `strip' might not be the right
# tool to use in cross-compilation environments, therefore Automake
# will honor the `STRIP' environment variable to overrule this program.
dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
if test "$cross_compiling" != no; then
AC_CHECK_TOOL([STRIP], [strip], :)
fi
INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
AC_SUBST([INSTALL_STRIP_PROGRAM])])
# serial 4 -*- Autoconf -*-
# Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
# 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, 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.
# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
# written in clear, in which case automake, when reading aclocal.m4,
# will think it sees a *use*, and therefore will trigger all it's
# C support machinery. Also note that it means that autoscan, seeing
# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
# _AM_DEPENDENCIES(NAME)
# ----------------------
# See how the compiler implements dependency checking.
# NAME is "CC", "CXX", "GCJ", or "OBJC".
# We try a few techniques and use that to set a single cache variable.
#
# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
# dependency, and given that the user is not expected to run this macro,
# just rely on AC_PROG_CC.
AC_DEFUN([_AM_DEPENDENCIES],
[AC_REQUIRE([AM_SET_DEPDIR])dnl
AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
AC_REQUIRE([AM_MAKE_INCLUDE])dnl
AC_REQUIRE([AM_DEP_TRACK])dnl
ifelse([$1], CC, [depcc="$CC" am_compiler_list=],
[$1], CXX, [depcc="$CXX" am_compiler_list=],
[$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
[$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
[depcc="$$1" am_compiler_list=])
AC_CACHE_CHECK([dependency style of $depcc],
[am_cv_$1_dependencies_compiler_type],
[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
# We make a subdir and do the tests there. Otherwise we can end up
# making bogus files that we don't know about and never remove. For
# instance it was reported that on HP-UX the gcc test will end up
# making a dummy file named `D' -- because `-MD' means `put the output
# in D'.
mkdir conftest.dir
# Copy depcomp to subdir because otherwise we won't find it if we're
# using a relative directory.
cp "$am_depcomp" conftest.dir
cd conftest.dir
am_cv_$1_dependencies_compiler_type=none
if test "$am_compiler_list" = ""; then
am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
fi
for depmode in $am_compiler_list; do
# We need to recreate these files for each test, as the compiler may
# overwrite some of them when testing with obscure command lines.
# This happens at least with the AIX C compiler.
echo '#include "conftest.h"' > conftest.c
echo 'int i;' > conftest.h
echo "${am__include} ${am__quote}conftest.Po${am__quote}" > confmf
case $depmode in
nosideeffect)
# after this tag, mechanisms are not by side-effect, so they'll
# only be used when explicitly requested
if test "x$enable_dependency_tracking" = xyes; then
continue
else
break
fi
;;
none) break ;;
esac
# We check with `-c' and `-o' for the sake of the "dashmstdout"
# mode. It turns out that the SunPro C++ compiler does not properly
# handle `-M -o', and we need to detect this.
if depmode=$depmode \
source=conftest.c object=conftest.o \
depfile=conftest.Po tmpdepfile=conftest.TPo \
$SHELL ./depcomp $depcc -c conftest.c -o conftest.o >/dev/null 2>&1 &&
grep conftest.h conftest.Po > /dev/null 2>&1 &&
${MAKE-make} -s -f confmf > /dev/null 2>&1; then
am_cv_$1_dependencies_compiler_type=$depmode
break
fi
done
cd ..
rm -rf conftest.dir
else
am_cv_$1_dependencies_compiler_type=none
fi
])
AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
AM_CONDITIONAL([am__fastdep$1], [
test "x$enable_dependency_tracking" != xno \
&& test "$am_cv_$1_dependencies_compiler_type" = gcc3])
])
# AM_SET_DEPDIR
# -------------
# Choose a directory name for dependency files.
# This macro is AC_REQUIREd in _AM_DEPENDENCIES
AC_DEFUN([AM_SET_DEPDIR],
[rm -f .deps 2>/dev/null
mkdir .deps 2>/dev/null
if test -d .deps; then
DEPDIR=.deps
else
# MS-DOS does not allow filenames that begin with a dot.
DEPDIR=_deps
fi
rmdir .deps 2>/dev/null
AC_SUBST([DEPDIR])
])
# AM_DEP_TRACK
# ------------
AC_DEFUN([AM_DEP_TRACK],
[AC_ARG_ENABLE(dependency-tracking,
[ --disable-dependency-tracking Speeds up one-time builds
--enable-dependency-tracking Do not reject slow dependency extractors])
if test "x$enable_dependency_tracking" != xno; then
am_depcomp="$ac_aux_dir/depcomp"
AMDEPBACKSLASH='\'
fi
AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
AC_SUBST([AMDEPBACKSLASH])
])
# Generate code to set up dependency tracking. -*- Autoconf -*-
# Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
# 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, 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.
#serial 2
# _AM_OUTPUT_DEPENDENCY_COMMANDS
# ------------------------------
AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
[for mf in $CONFIG_FILES; do
# Strip MF so we end up with the name of the file.
mf=`echo "$mf" | sed -e 's/:.*$//'`
# Check whether this is an Automake generated Makefile or not.
# We used to match only the files named `Makefile.in', but
# some people rename them; so instead we look at the file content.
# Grep'ing the first line is not enough: some people post-process
# each Makefile.in and add a new line on top of each file to say so.
# So let's grep whole file.
if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then
dirpart=`AS_DIRNAME("$mf")`
else
continue
fi
grep '^DEP_FILES *= *[[^ @%:@]]' < "$mf" > /dev/null || continue
# Extract the definition of DEP_FILES from the Makefile without
# running `make'.
DEPDIR=`sed -n -e '/^DEPDIR = / s///p' < "$mf"`
test -z "$DEPDIR" && continue
# When using ansi2knr, U may be empty or an underscore; expand it
U=`sed -n -e '/^U = / s///p' < "$mf"`
test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR"
# We invoke sed twice because it is the simplest approach to
# changing $(DEPDIR) to its actual value in the expansion.
for file in `sed -n -e '
/^DEP_FILES = .*\\\\$/ {
s/^DEP_FILES = //
:loop
s/\\\\$//
p
n
/\\\\$/ b loop
p
}
/^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \
sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
# Make sure the directory exists.
test -f "$dirpart/$file" && continue
fdir=`AS_DIRNAME(["$file"])`
AS_MKDIR_P([$dirpart/$fdir])
# echo "creating $dirpart/$file"
echo '# dummy' > "$dirpart/$file"
done
done
])# _AM_OUTPUT_DEPENDENCY_COMMANDS
# AM_OUTPUT_DEPENDENCY_COMMANDS
# -----------------------------
# This macro should only be invoked once -- use via AC_REQUIRE.
#
# This code is only required when automatic dependency tracking
# is enabled. FIXME. This creates each `.P' file that we will
# need in order to bootstrap the dependency handling code.
AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
[AC_CONFIG_COMMANDS([depfiles],
[test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
[AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
])
# Check to see how 'make' treats includes. -*- Autoconf -*-
# Copyright (C) 2001, 2002 Free Software Foundation, Inc.
# 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, 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.
# serial 2
# AM_MAKE_INCLUDE()
# -----------------
# Check to see how make treats includes.
AC_DEFUN([AM_MAKE_INCLUDE],
[am_make=${MAKE-make}
cat > confinc << 'END'
doit:
@echo done
END
# If we don't find an include directive, just comment out the code.
AC_MSG_CHECKING([for style of include used by $am_make])
am__include="#"
am__quote=
_am_result=none
# First try GNU make style include.
echo "include confinc" > confmf
# We grep out `Entering directory' and `Leaving directory'
# messages which can occur if `w' ends up in MAKEFLAGS.
# In particular we don't look at `^make:' because GNU make might
# be invoked under some other name (usually "gmake"), in which
# case it prints its new name instead of `make'.
if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then
am__include=include
am__quote=
_am_result=GNU
fi
# Now try BSD make style include.
if test "$am__include" = "#"; then
echo '.include "confinc"' > confmf
if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
am__include=.include
am__quote="\""
_am_result=BSD
fi
fi
AC_SUBST(am__include)
AC_SUBST(am__quote)
AC_MSG_RESULT($_am_result)
rm -f confinc confmf
])
# AM_CONDITIONAL -*- Autoconf -*-
# Copyright 1997, 2000, 2001 Free Software Foundation, Inc.
# 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, 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.
# serial 5
AC_PREREQ(2.52)
# AM_CONDITIONAL(NAME, SHELL-CONDITION)
# -------------------------------------
# Define a conditional.
AC_DEFUN([AM_CONDITIONAL],
[ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
[$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
AC_SUBST([$1_TRUE])
AC_SUBST([$1_FALSE])
if $2; then
$1_TRUE=
$1_FALSE='#'
else
$1_TRUE='#'
$1_FALSE=
fi
AC_CONFIG_COMMANDS_PRE(
[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
AC_MSG_ERROR([conditional "$1" was never defined.
Usually this means the macro was only invoked conditionally.])
fi])])
# Like AC_CONFIG_HEADER, but automatically create stamp file. -*- Autoconf -*-
# Copyright 1996, 1997, 2000, 2001 Free Software Foundation, Inc.
# 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, 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.
AC_PREREQ([2.52])
# serial 6
# AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS.
AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)])

8
bgpd/.cvsignore Normal file
View File

@ -0,0 +1,8 @@
Makefile
*.o
bgpd
bgp_btoa
bgpd.conf
tags
TAGS
.deps

929
bgpd/BGP4-MIB.txt Normal file
View File

@ -0,0 +1,929 @@
BGP4-MIB DEFINITIONS ::= BEGIN
IMPORTS
MODULE-IDENTITY, OBJECT-TYPE, NOTIFICATION-TYPE,
IpAddress, Integer32, Counter32, Gauge32, mib-2
FROM SNMPv2-SMI
MODULE-COMPLIANCE, OBJECT-GROUP, NOTIFICATION-GROUP
FROM SNMPv2-CONF;
bgp MODULE-IDENTITY
LAST-UPDATED "9902100000Z"
ORGANIZATION "IETF IDR Working Group"
CONTACT-INFO "E-mail: idr@merit.net
Susan Hares (Editor)
Merit Network
4251 Plymouth Road
Suite C
Ann Arbor, MI 48105-2785
Tel: +1 734 936 2095
Fax: +1 734 647 3185
E-mail: skh@merit.edu
Jeff Johnson (Editor)
RedBack Networks, Inc.
1389 Moffett Park Drive
Sunnyvale, CA 94089-1134
Tel: +1 408 548 3516
Fax: +1 408 548 3599
E-mail: jeff@redback.com"
DESCRIPTION
"The MIB module for BGP-4."
REVISION "9902100000Z"
DESCRIPTION
"Corrected duplicate OBJECT IDENTIFIER
assignment in the conformance information."
REVISION "9601080000Z"
DESCRIPTION
"1) Fixed the definitions of the traps to
make them equivalent to their initial
definition in RFC 1269.
2) Added compliance and conformance info."
::= { mib-2 15 }
bgpVersion OBJECT-TYPE
SYNTAX OCTET STRING (SIZE (1..255))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Vector of supported BGP protocol version
numbers. Each peer negotiates the version
from this vector. Versions are identified
via the string of bits contained within this
object. The first octet contains bits 0 to
7, the second octet contains bits 8 to 15,
and so on, with the most significant bit
referring to the lowest bit number in the
octet (e.g., the MSB of the first octet
refers to bit 0). If a bit, i, is present
and set, then the version (i+1) of the BGP
is supported."
::= { bgp 1 }
bgpLocalAs OBJECT-TYPE
SYNTAX INTEGER (0..65535)
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The local autonomous system number."
::= { bgp 2 }
-- BGP Peer table. This table contains, one entry per BGP
-- peer, information about the BGP peer.
bgpPeerTable OBJECT-TYPE
SYNTAX SEQUENCE OF BgpPeerEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"BGP peer table. This table contains,
one entry per BGP peer, information about the
connections with BGP peers."
::= { bgp 3 }
bgpPeerEntry OBJECT-TYPE
SYNTAX BgpPeerEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"Entry containing information about the
connection with a BGP peer."
INDEX { bgpPeerRemoteAddr }
::= { bgpPeerTable 1 }
BgpPeerEntry ::= SEQUENCE {
bgpPeerIdentifier
IpAddress,
bgpPeerState
INTEGER,
bgpPeerAdminStatus
INTEGER,
bgpPeerNegotiatedVersion
Integer32,
bgpPeerLocalAddr
IpAddress,
bgpPeerLocalPort
INTEGER,
bgpPeerRemoteAddr
IpAddress,
bgpPeerRemotePort
INTEGER,
bgpPeerRemoteAs
INTEGER,
bgpPeerInUpdates
Counter32,
bgpPeerOutUpdates
Counter32,
bgpPeerInTotalMessages
Counter32,
bgpPeerOutTotalMessages
Counter32,
bgpPeerLastError
OCTET STRING,
bgpPeerFsmEstablishedTransitions
Counter32,
bgpPeerFsmEstablishedTime
Gauge32,
bgpPeerConnectRetryInterval
INTEGER,
bgpPeerHoldTime
INTEGER,
bgpPeerKeepAlive
INTEGER,
bgpPeerHoldTimeConfigured
INTEGER,
bgpPeerKeepAliveConfigured
INTEGER,
bgpPeerMinASOriginationInterval
INTEGER,
bgpPeerMinRouteAdvertisementInterval
INTEGER,
bgpPeerInUpdateElapsedTime
Gauge32
}
bgpPeerIdentifier OBJECT-TYPE
SYNTAX IpAddress
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The BGP Identifier of this entry's BGP peer."
::= { bgpPeerEntry 1 }
bgpPeerState OBJECT-TYPE
SYNTAX INTEGER {
idle(1),
connect(2),
active(3),
opensent(4),
openconfirm(5),
established(6)
}
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The BGP peer connection state."
::= { bgpPeerEntry 2 }
bgpPeerAdminStatus OBJECT-TYPE
SYNTAX INTEGER {
stop(1),
start(2)
}
MAX-ACCESS read-write
STATUS current
DESCRIPTION
"The desired state of the BGP connection. A
transition from 'stop' to 'start' will cause
the BGP Start Event to be generated. A
transition from 'start' to 'stop' will cause
the BGP Stop Event to be generated. This
parameter can be used to restart BGP peer
connections. Care should be used in providing
write access to this object without adequate
authentication."
::= { bgpPeerEntry 3 }
bgpPeerNegotiatedVersion OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The negotiated version of BGP running between
the two peers."
::= { bgpPeerEntry 4 }
bgpPeerLocalAddr OBJECT-TYPE
SYNTAX IpAddress
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The local IP address of this entry's BGP
connection."
::= { bgpPeerEntry 5 }
bgpPeerLocalPort OBJECT-TYPE
SYNTAX INTEGER (0..65535)
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The local port for the TCP connection between
the BGP peers."
::= { bgpPeerEntry 6 }
bgpPeerRemoteAddr OBJECT-TYPE
SYNTAX IpAddress
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The remote IP address of this entry's BGP
peer."
::= { bgpPeerEntry 7 }
bgpPeerRemotePort OBJECT-TYPE
SYNTAX INTEGER (0..65535)
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The remote port for the TCP connection between
the BGP peers. Note that the objects
bgpPeerLocalAddr, bgpPeerLocalPort,
bgpPeerRemoteAddr and bgpPeerRemotePort
provide the appropriate reference to the
standard MIB TCP connection table."
::= { bgpPeerEntry 8 }
bgpPeerRemoteAs OBJECT-TYPE
SYNTAX INTEGER (0..65535)
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The remote autonomous system number."
::= { bgpPeerEntry 9 }
bgpPeerInUpdates OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The number of BGP UPDATE messages received on
this connection. This object should be
initialized to zero (0) when the connection is
established."
::= { bgpPeerEntry 10 }
bgpPeerOutUpdates OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The number of BGP UPDATE messages transmitted
on this connection. This object should be
initialized to zero (0) when the connection is
established."
::= { bgpPeerEntry 11 }
bgpPeerInTotalMessages OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The total number of messages received from the
remote peer on this connection. This object
should be initialized to zero when the
connection is established."
::= { bgpPeerEntry 12 }
bgpPeerOutTotalMessages OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The total number of messages transmitted to
the remote peer on this connection. This object
should be initialized to zero when the
connection is established."
::= { bgpPeerEntry 13 }
bgpPeerLastError OBJECT-TYPE
SYNTAX OCTET STRING (SIZE (2))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The last error code and subcode seen by this
peer on this connection. If no error has
occurred, this field is zero. Otherwise, the
first byte of this two byte OCTET STRING
contains the error code, and the second byte
contains the subcode."
::= { bgpPeerEntry 14 }
bgpPeerFsmEstablishedTransitions OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The total number of times the BGP FSM
transitioned into the established state."
::= { bgpPeerEntry 15 }
bgpPeerFsmEstablishedTime OBJECT-TYPE
SYNTAX Gauge32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"This timer indicates how long (in seconds) this
peer has been in the Established state or how long
since this peer was last in the Established state.
It is set to zero when a new peer is configured or
the router is booted."
::= { bgpPeerEntry 16 }
bgpPeerConnectRetryInterval OBJECT-TYPE
SYNTAX INTEGER (1..65535)
MAX-ACCESS read-write
STATUS current
DESCRIPTION
"Time interval in seconds for the ConnectRetry
timer. The suggested value for this timer is
120 seconds."
::= { bgpPeerEntry 17 }
bgpPeerHoldTime OBJECT-TYPE
SYNTAX INTEGER ( 0 | 3..65535 )
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Time interval in seconds for the Hold Timer
established with the peer. The value of this
object is calculated by this BGP speaker by
using the smaller of the value in
bgpPeerHoldTimeConfigured and the Hold Time
received in the OPEN message. This value
must be at lease three seconds if it is not
zero (0) in which case the Hold Timer has
not been established with the peer, or, the
value of bgpPeerHoldTimeConfigured is zero (0)."
::= { bgpPeerEntry 18 }
bgpPeerKeepAlive OBJECT-TYPE
SYNTAX INTEGER ( 0 | 1..21845 )
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Time interval in seconds for the KeepAlive
timer established with the peer. The value of
this object is calculated by this BGP speaker
such that, when compared with bgpPeerHoldTime,
it has the same proportion as what
bgpPeerKeepAliveConfigured has when compared
with bgpPeerHoldTimeConfigured. If the value
of this object is zero (0), it indicates that
the KeepAlive timer has not been established
with the peer, or, the value of
bgpPeerKeepAliveConfigured is zero (0)."
::= { bgpPeerEntry 19 }
bgpPeerHoldTimeConfigured OBJECT-TYPE
SYNTAX INTEGER ( 0 | 3..65535 )
MAX-ACCESS read-write
STATUS current
DESCRIPTION
"Time interval in seconds for the Hold Time
configured for this BGP speaker with this peer.
This value is placed in an OPEN message sent to
this peer by this BGP speaker, and is compared
with the Hold Time field in an OPEN message
received from the peer when determining the Hold
Time (bgpPeerHoldTime) with the peer. This value
must not be less than three seconds if it is not
zero (0) in which case the Hold Time is NOT to be
established with the peer. The suggested value for
this timer is 90 seconds."
::= { bgpPeerEntry 20 }
bgpPeerKeepAliveConfigured OBJECT-TYPE
SYNTAX INTEGER ( 0 | 1..21845 )
MAX-ACCESS read-write
STATUS current
DESCRIPTION
"Time interval in seconds for the KeepAlive timer
configured for this BGP speaker with this peer.
The value of this object will only determine the
KEEPALIVE messages' frequency relative to the value
specified in bgpPeerHoldTimeConfigured; the actual
time interval for the KEEPALIVE messages is
indicated by bgpPeerKeepAlive. A reasonable
maximum value for this timer would be configured to
be one third of that of bgpPeerHoldTimeConfigured.
If the value of this object is zero (0), no
periodical KEEPALIVE messages are sent to the peer
after the BGP connection has been established. The
suggested value for this timer is 30 seconds."
::= { bgpPeerEntry 21 }
bgpPeerMinASOriginationInterval OBJECT-TYPE
SYNTAX INTEGER (1..65535)
MAX-ACCESS read-write
STATUS current
DESCRIPTION
"Time interval in seconds for the
MinASOriginationInterval timer.
The suggested value for this timer is 15 seconds."
::= { bgpPeerEntry 22 }
bgpPeerMinRouteAdvertisementInterval OBJECT-TYPE
SYNTAX INTEGER (1..65535)
MAX-ACCESS read-write
STATUS current
DESCRIPTION
"Time interval in seconds for the
MinRouteAdvertisementInterval timer.
The suggested value for this timer is 30 seconds."
::= { bgpPeerEntry 23 }
bgpPeerInUpdateElapsedTime OBJECT-TYPE
SYNTAX Gauge32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Elapsed time in seconds since the last BGP
UPDATE message was received from the peer.
Each time bgpPeerInUpdates is incremented,
the value of this object is set to zero (0)."
::= { bgpPeerEntry 24 }
bgpIdentifier OBJECT-TYPE
SYNTAX IpAddress
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The BGP Identifier of local system."
::= { bgp 4 }
-- Received Path Attribute Table. This table contains,
-- one entry per path to a network, path attributes
-- received from all peers running BGP version 3 or less.
-- This table is obsolete, having been replaced in
-- functionality with the bgp4PathAttrTable.
bgpRcvdPathAttrTable OBJECT-TYPE
SYNTAX SEQUENCE OF BgpPathAttrEntry
MAX-ACCESS not-accessible
STATUS obsolete
DESCRIPTION
"The BGP Received Path Attribute Table contains
information about paths to destination networks
received from all peers running BGP version 3 or
less."
::= { bgp 5 }
bgpPathAttrEntry OBJECT-TYPE
SYNTAX BgpPathAttrEntry
MAX-ACCESS not-accessible
STATUS obsolete
DESCRIPTION
"Information about a path to a network."
INDEX { bgpPathAttrDestNetwork,
bgpPathAttrPeer }
::= { bgpRcvdPathAttrTable 1 }
BgpPathAttrEntry ::= SEQUENCE {
bgpPathAttrPeer
IpAddress,
bgpPathAttrDestNetwork
IpAddress,
bgpPathAttrOrigin
INTEGER,
bgpPathAttrASPath
OCTET STRING,
bgpPathAttrNextHop
IpAddress,
bgpPathAttrInterASMetric
Integer32
}
bgpPathAttrPeer OBJECT-TYPE
SYNTAX IpAddress
MAX-ACCESS read-only
STATUS obsolete
DESCRIPTION
"The IP address of the peer where the path
information was learned."
::= { bgpPathAttrEntry 1 }
bgpPathAttrDestNetwork OBJECT-TYPE
SYNTAX IpAddress
MAX-ACCESS read-only
STATUS obsolete
DESCRIPTION
"The address of the destination network."
::= { bgpPathAttrEntry 2 }
bgpPathAttrOrigin OBJECT-TYPE
SYNTAX INTEGER {
igp(1),-- networks are interior
egp(2),-- networks learned via EGP
incomplete(3) -- undetermined
}
MAX-ACCESS read-only
STATUS obsolete
DESCRIPTION
"The ultimate origin of the path information."
::= { bgpPathAttrEntry 3 }
bgpPathAttrASPath OBJECT-TYPE
SYNTAX OCTET STRING (SIZE (2..255))
MAX-ACCESS read-only
STATUS obsolete
DESCRIPTION
"The set of ASs that must be traversed to reach
the network. This object is probably best
represented as SEQUENCE OF INTEGER. For SMI
compatibility, though, it is represented as
OCTET STRING. Each AS is represented as a pair
of octets according to the following algorithm:
first-byte-of-pair = ASNumber / 256;
second-byte-of-pair = ASNumber & 255;"
::= { bgpPathAttrEntry 4 }
bgpPathAttrNextHop OBJECT-TYPE
SYNTAX IpAddress
MAX-ACCESS read-only
STATUS obsolete
DESCRIPTION
"The address of the border router that should
be used for the destination network."
::= { bgpPathAttrEntry 5 }
bgpPathAttrInterASMetric OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS obsolete
DESCRIPTION
"The optional inter-AS metric. If this
attribute has not been provided for this route,
the value for this object is 0."
::= { bgpPathAttrEntry 6 }
-- BGP-4 Received Path Attribute Table. This table contains,
-- one entry per path to a network, path attributes
-- received from all peers running BGP-4.
bgp4PathAttrTable OBJECT-TYPE
SYNTAX SEQUENCE OF Bgp4PathAttrEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"The BGP-4 Received Path Attribute Table contains
information about paths to destination networks
received from all BGP4 peers."
::= { bgp 6 }
bgp4PathAttrEntry OBJECT-TYPE
SYNTAX Bgp4PathAttrEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"Information about a path to a network."
INDEX { bgp4PathAttrIpAddrPrefix,
bgp4PathAttrIpAddrPrefixLen,
bgp4PathAttrPeer }
::= { bgp4PathAttrTable 1 }
Bgp4PathAttrEntry ::= SEQUENCE {
bgp4PathAttrPeer
IpAddress,
bgp4PathAttrIpAddrPrefixLen
INTEGER,
bgp4PathAttrIpAddrPrefix
IpAddress,
bgp4PathAttrOrigin
INTEGER,
bgp4PathAttrASPathSegment
OCTET STRING,
bgp4PathAttrNextHop
IpAddress,
bgp4PathAttrMultiExitDisc
INTEGER,
bgp4PathAttrLocalPref
INTEGER,
bgp4PathAttrAtomicAggregate
INTEGER,
bgp4PathAttrAggregatorAS
INTEGER,
bgp4PathAttrAggregatorAddr
IpAddress,
bgp4PathAttrCalcLocalPref
INTEGER,
bgp4PathAttrBest
INTEGER,
bgp4PathAttrUnknown
OCTET STRING
}
bgp4PathAttrPeer OBJECT-TYPE
SYNTAX IpAddress
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The IP address of the peer where the path
information was learned."
::= { bgp4PathAttrEntry 1 }
bgp4PathAttrIpAddrPrefixLen OBJECT-TYPE
SYNTAX INTEGER (0..32)
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Length in bits of the IP address prefix in the
Network Layer Reachability Information field."
::= { bgp4PathAttrEntry 2 }
bgp4PathAttrIpAddrPrefix OBJECT-TYPE
SYNTAX IpAddress
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"An IP address prefix in the Network Layer
Reachability Information field. This object
is an IP address containing the prefix with
length specified by bgp4PathAttrIpAddrPrefixLen.
Any bits beyond the length specified by
bgp4PathAttrIpAddrPrefixLen are zeroed."
::= { bgp4PathAttrEntry 3 }
bgp4PathAttrOrigin OBJECT-TYPE
SYNTAX INTEGER {
igp(1),-- networks are interior
egp(2),-- networks learned via EGP
incomplete(3) -- undetermined
}
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The ultimate origin of the path information."
::= { bgp4PathAttrEntry 4 }
bgp4PathAttrASPathSegment OBJECT-TYPE
SYNTAX OCTET STRING (SIZE (2..255))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The sequence of AS path segments. Each AS
path segment is represented by a triple
<type, length, value>.
The type is a 1-octet field which has two
possible values:
1 AS_SET: unordered set of ASs a
route in the UPDATE message
has traversed
2 AS_SEQUENCE: ordered set of ASs
a route in the UPDATE message
has traversed.
The length is a 1-octet field containing the
number of ASs in the value field.
The value field contains one or more AS
numbers, each AS is represented in the octet
string as a pair of octets according to the
following algorithm:
first-byte-of-pair = ASNumber / 256;
second-byte-of-pair = ASNumber & 255;"
::= { bgp4PathAttrEntry 5 }
bgp4PathAttrNextHop OBJECT-TYPE
SYNTAX IpAddress
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The address of the border router that should
be used for the destination network."
::= { bgp4PathAttrEntry 6 }
bgp4PathAttrMultiExitDisc OBJECT-TYPE
SYNTAX INTEGER (-1..2147483647)
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"This metric is used to discriminate between
multiple exit points to an adjacent autonomous
system. A value of -1 indicates the absence of
this attribute."
::= { bgp4PathAttrEntry 7 }
bgp4PathAttrLocalPref OBJECT-TYPE
SYNTAX INTEGER (-1..2147483647)
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The originating BGP4 speaker's degree of
preference for an advertised route. A value of
-1 indicates the absence of this attribute."
::= { bgp4PathAttrEntry 8 }
bgp4PathAttrAtomicAggregate OBJECT-TYPE
SYNTAX INTEGER {
lessSpecificRrouteNotSelected(1),
lessSpecificRouteSelected(2)
}
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Whether or not a system has selected
a less specific route without selecting a
more specific route."
::= { bgp4PathAttrEntry 9 }
bgp4PathAttrAggregatorAS OBJECT-TYPE
SYNTAX INTEGER (0..65535)
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The AS number of the last BGP4 speaker that
performed route aggregation. A value of zero (0)
indicates the absence of this attribute."
::= { bgp4PathAttrEntry 10 }
bgp4PathAttrAggregatorAddr OBJECT-TYPE
SYNTAX IpAddress
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The IP address of the last BGP4 speaker that
performed route aggregation. A value of
0.0.0.0 indicates the absence of this attribute."
::= { bgp4PathAttrEntry 11 }
bgp4PathAttrCalcLocalPref OBJECT-TYPE
SYNTAX INTEGER (-1..2147483647)
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The degree of preference calculated by the
receiving BGP4 speaker for an advertised route.
A value of -1 indicates the absence of this
attribute."
::= { bgp4PathAttrEntry 12 }
bgp4PathAttrBest OBJECT-TYPE
SYNTAX INTEGER {
false(1),-- not chosen as best route
true(2) -- chosen as best route
}
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"An indication of whether or not this route
was chosen as the best BGP4 route."
::= { bgp4PathAttrEntry 13 }
bgp4PathAttrUnknown OBJECT-TYPE
SYNTAX OCTET STRING (SIZE(0..255))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"One or more path attributes not understood
by this BGP4 speaker. Size zero (0) indicates
the absence of such attribute(s). Octets
beyond the maximum size, if any, are not
recorded by this object."
::= { bgp4PathAttrEntry 14 }
-- Traps.
-- note that in RFC 1657, bgpTraps was incorrectly
-- assigned a value of { bgp 7 }, and each of the
-- traps had the bgpPeerRemoteAddr object inappropriately
-- removed from their OBJECTS clause. The following
-- definitions restore the semantics of the traps as
-- they were initially defined in RFC 1269.
-- { bgp 7 } is unused
bgpTraps OBJECT IDENTIFIER ::= { bgp 0 }
bgpEstablished NOTIFICATION-TYPE
OBJECTS { bgpPeerRemoteAddr,
bgpPeerLastError,
bgpPeerState }
STATUS current
DESCRIPTION
"The BGP Established event is generated when
the BGP FSM enters the ESTABLISHED state."
::= { bgpTraps 1 }
bgpBackwardTransition NOTIFICATION-TYPE
OBJECTS { bgpPeerRemoteAddr,
bgpPeerLastError,
bgpPeerState }
STATUS current
DESCRIPTION
"The BGPBackwardTransition Event is generated
when the BGP FSM moves from a higher numbered
state to a lower numbered state."
::= { bgpTraps 2 }
-- conformance information
bgpMIBConformance OBJECT IDENTIFIER ::= { bgp 8 }
bgpMIBCompliances OBJECT IDENTIFIER ::= { bgpMIBConformance 1 }
bgpMIBGroups OBJECT IDENTIFIER ::= { bgpMIBConformance 2 }
-- compliance statements
bgpMIBCompliance MODULE-COMPLIANCE
STATUS current
DESCRIPTION
"The compliance statement for entities which
implement the BGP4 mib."
MODULE -- this module
MANDATORY-GROUPS { bgp4MIBGlobalsGroup,
bgp4MIBPeerGroup,
bgp4MIBPathAttrGroup,
bgp4MIBNotificationGroup }
::= { bgpMIBCompliances 1 }
-- units of conformance
bgp4MIBGlobalsGroup OBJECT-GROUP
OBJECTS { bgpVersion,
bgpLocalAs,
bgpIdentifier }
STATUS current
DESCRIPTION
"A collection of objects providing information
on global BGP state."
::= { bgpMIBGroups 1 }
bgp4MIBPeerGroup OBJECT-GROUP
OBJECTS { bgpPeerIdentifier,
bgpPeerState,
bgpPeerAdminStatus,
bgpPeerNegotiatedVersion,
bgpPeerLocalAddr,
bgpPeerLocalPort,
bgpPeerRemoteAddr,
bgpPeerRemotePort,
bgpPeerRemoteAs,
bgpPeerInUpdates,
bgpPeerOutUpdates,
bgpPeerInTotalMessages,
bgpPeerOutTotalMessages,
bgpPeerLastError,
bgpPeerFsmEstablishedTransitions,
bgpPeerFsmEstablishedTime,
bgpPeerConnectRetryInterval,
bgpPeerHoldTime,
bgpPeerKeepAlive,
bgpPeerHoldTimeConfigured,
bgpPeerKeepAliveConfigured,
bgpPeerMinASOriginationInterval,
bgpPeerMinRouteAdvertisementInterval,
bgpPeerInUpdateElapsedTime }
STATUS current
DESCRIPTION
"A collection of objects for managing
BGP peers."
::= { bgpMIBGroups 2 }
bgp4MIBRcvdPathAttrGroup OBJECT-GROUP
OBJECTS { bgpPathAttrPeer,
bgpPathAttrDestNetwork,
bgpPathAttrOrigin,
bgpPathAttrASPath,
bgpPathAttrNextHop,
bgpPathAttrInterASMetric }
STATUS obsolete
DESCRIPTION
"A collection of objects for managing BGP
path entries.
This conformance group is obsolete,
replaced by bgp4MIBPathAttrGroup."
::= { bgpMIBGroups 3 }
bgp4MIBPathAttrGroup OBJECT-GROUP
OBJECTS { bgp4PathAttrPeer,
bgp4PathAttrIpAddrPrefixLen,
bgp4PathAttrIpAddrPrefix,
bgp4PathAttrOrigin,
bgp4PathAttrASPathSegment,
bgp4PathAttrNextHop,
bgp4PathAttrMultiExitDisc,
bgp4PathAttrLocalPref,
bgp4PathAttrAtomicAggregate,
bgp4PathAttrAggregatorAS,
bgp4PathAttrAggregatorAddr,
bgp4PathAttrCalcLocalPref,
bgp4PathAttrBest,
bgp4PathAttrUnknown }
STATUS current
DESCRIPTION
"A collection of objects for managing
BGP path entries."
::= { bgpMIBGroups 4 }
bgp4MIBNotificationGroup NOTIFICATION-GROUP
NOTIFICATIONS { bgpEstablished,
bgpBackwardTransition }
STATUS current
DESCRIPTION
"A collection of notifications for signaling
changes in BGP peer relationships."
::= { bgpMIBGroups 5 }
END

2368
bgpd/ChangeLog Normal file

File diff suppressed because it is too large Load Diff

44
bgpd/Makefile.am Normal file
View File

@ -0,0 +1,44 @@
## Process this file with automake to produce Makefile.in.
INCLUDES = @INCLUDES@ -I.. -I$(top_srcdir) -I$(top_srcdir)/lib
DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
INSTALL_SDATA=@INSTALL@ -m 600
noinst_LIBRARIES = libbgp.a
sbin_PROGRAMS = bgpd
libbgp_a_SOURCES = \
bgpd.c bgp_fsm.c bgp_aspath.c bgp_community.c bgp_attr.c \
bgp_debug.c bgp_route.c bgp_zebra.c bgp_open.c bgp_routemap.c \
bgp_packet.c bgp_network.c bgp_filter.c bgp_regex.c bgp_clist.c \
bgp_dump.c bgp_snmp.c bgp_ecommunity.c bgp_mplsvpn.c bgp_nexthop.c \
bgp_damp.c bgp_table.c bgp_advertise.c bgp_vty.c
noinst_HEADERS = \
bgp_aspath.h bgp_attr.h bgp_community.h bgp_debug.h bgp_fsm.h \
bgp_network.h bgp_open.h bgp_packet.h bgp_regex.h bgp_route.h \
bgpd.h bgp_filter.h bgp_clist.h bgp_dump.h bgp_zebra.h \
bgp_ecommunity.h bgp_mplsvpn.h bgp_nexthop.h bgp_damp.h bgp_table.h \
bgp_advertise.h bgp_snmp.h bgp_vty.h
bgpd_SOURCES = \
bgp_main.c $(libbgp_a_SOURCES)
bgpd_LDADD = ../lib/libzebra.a
sysconf_DATA = bgpd.conf.sample bgpd.conf.sample2
EXTRA_DIST = $(sysconf_DATA) BGP4-MIB.txt
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

534
bgpd/Makefile.in Normal file
View File

@ -0,0 +1,534 @@
# Makefile.in generated by automake 1.7 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@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
host_triplet = @host@
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BGPD = @BGPD@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CURSES = @CURSES@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
DEPDIR = @DEPDIR@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
IF_METHOD = @IF_METHOD@
IF_PROC = @IF_PROC@
INCLUDES = @INCLUDES@ -I.. -I$(top_srcdir) -I$(top_srcdir)/lib
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
IPFORWARD = @IPFORWARD@
KERNEL_METHOD = @KERNEL_METHOD@
LDFLAGS = @LDFLAGS@
LIBPAM = @LIBPAM@
LIBS = @LIBS@
LIB_IPV6 = @LIB_IPV6@
LIB_REGEX = @LIB_REGEX@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MULTIPATH_NUM = @MULTIPATH_NUM@
OBJEXT = @OBJEXT@
OSPF6D = @OSPF6D@
OSPFD = @OSPFD@
OTHER_METHOD = @OTHER_METHOD@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
RIPD = @RIPD@
RIPNGD = @RIPNGD@
RTREAD_METHOD = @RTREAD_METHOD@
RT_METHOD = @RT_METHOD@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
VTYSH = @VTYSH@
ZEBRA = @ZEBRA@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__include = @am__include@
am__quote = @am__quote@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localstatedir = @localstatedir@
mandir = @mandir@
oldincludedir = @oldincludedir@
prefix = @prefix@
program_transform_name = @program_transform_name@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
INSTALL_SDATA = @INSTALL@ -m 600
noinst_LIBRARIES = libbgp.a
sbin_PROGRAMS = bgpd
libbgp_a_SOURCES = \
bgpd.c bgp_fsm.c bgp_aspath.c bgp_community.c bgp_attr.c \
bgp_debug.c bgp_route.c bgp_zebra.c bgp_open.c bgp_routemap.c \
bgp_packet.c bgp_network.c bgp_filter.c bgp_regex.c bgp_clist.c \
bgp_dump.c bgp_snmp.c bgp_ecommunity.c bgp_mplsvpn.c bgp_nexthop.c \
bgp_damp.c bgp_table.c bgp_advertise.c bgp_vty.c
noinst_HEADERS = \
bgp_aspath.h bgp_attr.h bgp_community.h bgp_debug.h bgp_fsm.h \
bgp_network.h bgp_open.h bgp_packet.h bgp_regex.h bgp_route.h \
bgpd.h bgp_filter.h bgp_clist.h bgp_dump.h bgp_zebra.h \
bgp_ecommunity.h bgp_mplsvpn.h bgp_nexthop.h bgp_damp.h bgp_table.h \
bgp_advertise.h bgp_snmp.h bgp_vty.h
bgpd_SOURCES = \
bgp_main.c $(libbgp_a_SOURCES)
bgpd_LDADD = ../lib/libzebra.a
sysconf_DATA = bgpd.conf.sample bgpd.conf.sample2
EXTRA_DIST = $(sysconf_DATA) BGP4-MIB.txt
subdir = bgpd
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
LIBRARIES = $(noinst_LIBRARIES)
libbgp_a_AR = $(AR) cru
libbgp_a_LIBADD =
am_libbgp_a_OBJECTS = bgpd.$(OBJEXT) bgp_fsm.$(OBJEXT) \
bgp_aspath.$(OBJEXT) bgp_community.$(OBJEXT) bgp_attr.$(OBJEXT) \
bgp_debug.$(OBJEXT) bgp_route.$(OBJEXT) bgp_zebra.$(OBJEXT) \
bgp_open.$(OBJEXT) bgp_routemap.$(OBJEXT) bgp_packet.$(OBJEXT) \
bgp_network.$(OBJEXT) bgp_filter.$(OBJEXT) bgp_regex.$(OBJEXT) \
bgp_clist.$(OBJEXT) bgp_dump.$(OBJEXT) bgp_snmp.$(OBJEXT) \
bgp_ecommunity.$(OBJEXT) bgp_mplsvpn.$(OBJEXT) \
bgp_nexthop.$(OBJEXT) bgp_damp.$(OBJEXT) bgp_table.$(OBJEXT) \
bgp_advertise.$(OBJEXT) bgp_vty.$(OBJEXT)
libbgp_a_OBJECTS = $(am_libbgp_a_OBJECTS)
sbin_PROGRAMS = bgpd$(EXEEXT)
PROGRAMS = $(sbin_PROGRAMS)
am__objects_1 = bgpd.$(OBJEXT) bgp_fsm.$(OBJEXT) bgp_aspath.$(OBJEXT) \
bgp_community.$(OBJEXT) bgp_attr.$(OBJEXT) bgp_debug.$(OBJEXT) \
bgp_route.$(OBJEXT) bgp_zebra.$(OBJEXT) bgp_open.$(OBJEXT) \
bgp_routemap.$(OBJEXT) bgp_packet.$(OBJEXT) \
bgp_network.$(OBJEXT) bgp_filter.$(OBJEXT) bgp_regex.$(OBJEXT) \
bgp_clist.$(OBJEXT) bgp_dump.$(OBJEXT) bgp_snmp.$(OBJEXT) \
bgp_ecommunity.$(OBJEXT) bgp_mplsvpn.$(OBJEXT) \
bgp_nexthop.$(OBJEXT) bgp_damp.$(OBJEXT) bgp_table.$(OBJEXT) \
bgp_advertise.$(OBJEXT) bgp_vty.$(OBJEXT)
am_bgpd_OBJECTS = bgp_main.$(OBJEXT) $(am__objects_1)
bgpd_OBJECTS = $(am_bgpd_OBJECTS)
bgpd_DEPENDENCIES = ../lib/libzebra.a
bgpd_LDFLAGS =
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/bgp_advertise.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/bgp_aspath.Po ./$(DEPDIR)/bgp_attr.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/bgp_clist.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/bgp_community.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/bgp_damp.Po ./$(DEPDIR)/bgp_debug.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/bgp_dump.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/bgp_ecommunity.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/bgp_filter.Po ./$(DEPDIR)/bgp_fsm.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/bgp_main.Po ./$(DEPDIR)/bgp_mplsvpn.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/bgp_network.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/bgp_nexthop.Po ./$(DEPDIR)/bgp_open.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/bgp_packet.Po ./$(DEPDIR)/bgp_regex.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/bgp_route.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/bgp_routemap.Po ./$(DEPDIR)/bgp_snmp.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/bgp_table.Po ./$(DEPDIR)/bgp_vty.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/bgp_zebra.Po ./$(DEPDIR)/bgpd.Po
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
DIST_SOURCES = $(libbgp_a_SOURCES) $(bgpd_SOURCES)
DATA = $(sysconf_DATA)
HEADERS = $(noinst_HEADERS)
DIST_COMMON = $(noinst_HEADERS) ChangeLog Makefile.am Makefile.in
SOURCES = $(libbgp_a_SOURCES) $(bgpd_SOURCES)
all: all-am
.SUFFIXES:
.SUFFIXES: .c .o .obj
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && \
$(AUTOMAKE) --foreign bgpd/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)
libbgp.a: $(libbgp_a_OBJECTS) $(libbgp_a_DEPENDENCIES)
-rm -f libbgp.a
$(libbgp_a_AR) libbgp.a $(libbgp_a_OBJECTS) $(libbgp_a_LIBADD)
$(RANLIB) libbgp.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 \
f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
echo " $(INSTALL_PROGRAM_ENV) $(sbinPROGRAMS_INSTALL) $$p $(DESTDIR)$(sbindir)/$$f"; \
$(INSTALL_PROGRAM_ENV) $(sbinPROGRAMS_INSTALL) $$p $(DESTDIR)$(sbindir)/$$f || exit 1; \
else :; fi; \
done
uninstall-sbinPROGRAMS:
@$(NORMAL_UNINSTALL)
@list='$(sbin_PROGRAMS)'; for p in $$list; do \
f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
echo " rm -f $(DESTDIR)$(sbindir)/$$f"; \
rm -f $(DESTDIR)$(sbindir)/$$f; \
done
clean-sbinPROGRAMS:
-test -z "$(sbin_PROGRAMS)" || rm -f $(sbin_PROGRAMS)
bgpd$(EXEEXT): $(bgpd_OBJECTS) $(bgpd_DEPENDENCIES)
@rm -f bgpd$(EXEEXT)
$(LINK) $(bgpd_LDFLAGS) $(bgpd_OBJECTS) $(bgpd_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT) core *.core
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bgp_advertise.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bgp_aspath.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bgp_attr.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bgp_clist.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bgp_community.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bgp_damp.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bgp_debug.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bgp_dump.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bgp_ecommunity.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bgp_filter.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bgp_fsm.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bgp_main.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bgp_mplsvpn.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bgp_network.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bgp_nexthop.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bgp_open.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bgp_packet.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bgp_regex.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bgp_route.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bgp_routemap.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bgp_snmp.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bgp_table.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bgp_vty.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bgp_zebra.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bgpd.Po@am__quote@
distclean-depend:
-rm -rf ./$(DEPDIR)
.c.o:
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
@am__fastdepCC_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
@am__fastdepCC_TRUE@ then mv "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
@am__fastdepCC_TRUE@ fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$<
.c.obj:
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
@am__fastdepCC_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'`; \
@am__fastdepCC_TRUE@ then mv "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
@am__fastdepCC_TRUE@ fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'`
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 =
CTAGS = ctags
CTAGSFLAGS =
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
ctags: CTAGS
CTAGS: $(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 "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_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 tags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
top_distdir = ..
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
esac; \
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
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-info-am uninstall-sbinPROGRAMS \
uninstall-sysconfDATA
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-noinstLIBRARIES clean-sbinPROGRAMS ctags 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 pdf pdf-am ps ps-am 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
# 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:

405
bgpd/bgp_advertise.c Normal file
View File

@ -0,0 +1,405 @@
/* BGP advertisement and adjacency
Copyright (C) 1996, 97, 98, 99, 2000 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 "command.h"
#include "memory.h"
#include "prefix.h"
#include "hash.h"
#include "thread.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_table.h"
#include "bgpd/bgp_route.h"
#include "bgpd/bgp_advertise.h"
#include "bgpd/bgp_attr.h"
#include "bgpd/bgp_aspath.h"
#include "bgpd/bgp_packet.h"
#include "bgpd/bgp_fsm.h"
#include "bgpd/bgp_mplsvpn.h"
/* BGP advertise attribute is used for pack same attribute update into
one packet. To do that we maintain attribute hash in struct
peer. */
static struct bgp_advertise_attr *
baa_new ()
{
return (struct bgp_advertise_attr *)
XCALLOC (MTYPE_BGP_ADVERTISE_ATTR, sizeof (struct bgp_advertise_attr));
}
static void
baa_free (struct bgp_advertise_attr *baa)
{
XFREE (MTYPE_BGP_ADVERTISE_ATTR, baa);
}
static void *
baa_hash_alloc (struct bgp_advertise_attr *ref)
{
struct bgp_advertise_attr *baa;
baa = baa_new ();
baa->attr = ref->attr;
return baa;
}
static unsigned int
baa_hash_key (struct bgp_advertise_attr *baa)
{
return attrhash_key_make (baa->attr);
}
static int
baa_hash_cmp (struct bgp_advertise_attr *baa1, struct bgp_advertise_attr *baa2)
{
return attrhash_cmp (baa1->attr, baa2->attr);
}
/* BGP update and withdraw information is stored in BGP advertise
structure. This structure is referred from BGP adjacency
information. */
static struct bgp_advertise *
bgp_advertise_new ()
{
return (struct bgp_advertise *)
XCALLOC (MTYPE_BGP_ADVERTISE, sizeof (struct bgp_advertise));
}
void
bgp_advertise_free (struct bgp_advertise *adv)
{
XFREE (MTYPE_BGP_ADVERTISE, adv);
}
void
bgp_advertise_add (struct bgp_advertise_attr *baa,
struct bgp_advertise *adv)
{
adv->next = baa->adv;
if (baa->adv)
baa->adv->prev = adv;
baa->adv = adv;
}
void
bgp_advertise_delete (struct bgp_advertise_attr *baa,
struct bgp_advertise *adv)
{
if (adv->next)
adv->next->prev = adv->prev;
if (adv->prev)
adv->prev->next = adv->next;
else
baa->adv = adv->next;
}
static struct bgp_advertise_attr *
bgp_advertise_intern (struct hash *hash, struct attr *attr)
{
struct bgp_advertise_attr ref;
struct bgp_advertise_attr *baa;
ref.attr = bgp_attr_intern (attr);
baa = (struct bgp_advertise_attr *) hash_get (hash, &ref, baa_hash_alloc);
baa->refcnt++;
return baa;
}
void
bgp_advertise_unintern (struct hash *hash, struct bgp_advertise_attr *baa)
{
if (baa->refcnt)
baa->refcnt--;
if (baa->refcnt && baa->attr)
bgp_attr_unintern (baa->attr);
else
{
if (baa->attr)
{
hash_release (hash, baa);
bgp_attr_unintern (baa->attr);
}
baa_free (baa);
}
}
/* BGP adjacency keeps minimal advertisement information. */
void
bgp_adj_out_free (struct bgp_adj_out *adj)
{
XFREE (MTYPE_BGP_ADJ_OUT, adj);
}
int
bgp_adj_out_lookup (struct peer *peer, struct prefix *p,
afi_t afi, safi_t safi, struct bgp_node *rn)
{
struct bgp_adj_out *adj;
for (adj = rn->adj_out; adj; adj = adj->next)
if (adj->peer == peer)
break;
if (! adj)
return 0;
return (adj->adv
? (adj->adv->baa ? 1 : 0)
: (adj->attr ? 1 : 0));
}
struct bgp_advertise *
bgp_advertise_clean (struct peer *peer, struct bgp_adj_out *adj,
afi_t afi, safi_t safi)
{
struct bgp_advertise *adv;
struct bgp_advertise_attr *baa;
struct bgp_advertise *next;
adv = adj->adv;
baa = adv->baa;
next = NULL;
if (baa)
{
/* Unlink myself from advertise attribute FIFO. */
bgp_advertise_delete (baa, adv);
/* Fetch next advertise candidate. */
next = baa->adv;
/* Unintern BGP advertise attribute. */
bgp_advertise_unintern (peer->hash[afi][safi], baa);
adv->baa = NULL;
adv->rn = NULL;
}
/* Unlink myself from advertisement FIFO. */
FIFO_DEL (adv);
/* Free memory. */
bgp_advertise_free (adj->adv);
adj->adv = NULL;
return next;
}
void
bgp_adj_out_set (struct bgp_node *rn, struct peer *peer, struct prefix *p,
struct attr *attr, afi_t afi, safi_t safi,
struct bgp_info *binfo)
{
struct bgp_adj_out *adj = NULL;
struct bgp_advertise *adv;
#ifdef DISABLE_BGP_ANNOUNCE
return;
#endif /* DISABLE_BGP_ANNOUNCE */
/* Look for adjacency information. */
if (rn)
{
for (adj = rn->adj_out; adj; adj = adj->next)
if (adj->peer == peer)
break;
}
if (! adj)
{
adj = XCALLOC (MTYPE_BGP_ADJ_OUT, sizeof (struct bgp_adj_out));
if (rn)
{
BGP_ADJ_OUT_ADD (rn, adj);
bgp_lock_node (rn);
}
}
if (adj->adv)
bgp_advertise_clean (peer, adj, afi, safi);
adj->peer = peer;
adj->adv = bgp_advertise_new ();
adv = adj->adv;
adv->rn = rn;
adv->binfo = binfo;
if (attr)
adv->baa = bgp_advertise_intern (peer->hash[afi][safi], attr);
else
adv->baa = baa_new ();
adv->adj = adj;
/* Add new advertisement to advertisement attribute list. */
bgp_advertise_add (adv->baa, adv);
FIFO_ADD (&peer->sync[afi][safi]->update, &adv->fifo);
}
void
bgp_adj_out_unset (struct bgp_node *rn, struct peer *peer, struct prefix *p,
afi_t afi, safi_t safi)
{
struct bgp_adj_out *adj;
struct bgp_advertise *adv;
#ifdef DISABLE_BGP_ANNOUNCE
return;
#endif /* DISABLE_BGP_ANNOUNCE */
/* Lookup existing adjacency, if it is not there return immediately. */
for (adj = rn->adj_out; adj; adj = adj->next)
if (adj->peer == peer)
break;
if (! adj)
return;
/* Clearn up previous advertisement. */
if (adj->adv)
bgp_advertise_clean (peer, adj, afi, safi);
if (adj->attr)
{
/* We need advertisement structure. */
adj->adv = bgp_advertise_new ();
adv = adj->adv;
adv->rn = rn;
adv->adj = adj;
/* Add to synchronization entry for withdraw announcement. */
FIFO_ADD (&peer->sync[afi][safi]->withdraw, &adv->fifo);
/* Schedule packet write. */
BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
}
else
{
/* Remove myself from adjacency. */
BGP_ADJ_OUT_DEL (rn, adj);
/* Free allocated information. */
bgp_adj_out_free (adj);
bgp_unlock_node (rn);
}
}
void
bgp_adj_out_remove (struct bgp_node *rn, struct bgp_adj_out *adj,
struct peer *peer, afi_t afi, safi_t safi)
{
if (adj->attr)
bgp_attr_unintern (adj->attr);
if (adj->adv)
bgp_advertise_clean (peer, adj, afi, safi);
BGP_ADJ_OUT_DEL (rn, adj);
bgp_adj_out_free (adj);
}
void
bgp_adj_in_set (struct bgp_node *rn, struct peer *peer, struct attr *attr)
{
struct bgp_adj_in *adj;
for (adj = rn->adj_in; adj; adj = adj->next)
{
if (adj->peer == peer)
{
if (adj->attr != attr)
{
bgp_attr_unintern (adj->attr);
adj->attr = bgp_attr_intern (attr);
}
return;
}
}
adj = XCALLOC (MTYPE_BGP_ADJ_IN, sizeof (struct bgp_adj_in));
adj->peer = peer;
adj->attr = bgp_attr_intern (attr);
BGP_ADJ_IN_ADD (rn, adj);
bgp_lock_node (rn);
}
void
bgp_adj_in_remove (struct bgp_node *rn, struct bgp_adj_in *bai)
{
bgp_attr_unintern (bai->attr);
BGP_ADJ_IN_DEL (rn, bai);
XFREE (MTYPE_BGP_ADJ_IN, bai);
}
void
bgp_adj_in_unset (struct bgp_node *rn, struct peer *peer)
{
struct bgp_adj_in *adj;
for (adj = rn->adj_in; adj; adj = adj->next)
if (adj->peer == peer)
break;
if (! adj)
return;
bgp_adj_in_remove (rn, adj);
bgp_unlock_node (rn);
}
void
bgp_sync_init (struct peer *peer)
{
afi_t afi;
safi_t safi;
struct bgp_synchronize *sync;
for (afi = AFI_IP; afi < AFI_MAX; afi++)
for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
{
sync = XCALLOC (MTYPE_TMP, sizeof (struct bgp_synchronize));
FIFO_INIT (&sync->update);
FIFO_INIT (&sync->withdraw);
FIFO_INIT (&sync->withdraw_low);
peer->sync[afi][safi] = sync;
peer->hash[afi][safi] = hash_create (baa_hash_key, baa_hash_cmp);
}
}
void
bgp_sync_delete (struct peer *peer)
{
afi_t afi;
safi_t safi;
for (afi = AFI_IP; afi < AFI_MAX; afi++)
for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
{
if (peer->sync[afi][safi])
XFREE (MTYPE_TMP, peer->sync[afi][safi]);
peer->sync[afi][safi] = NULL;
hash_free (peer->hash[afi][safi]);
}
}

178
bgpd/bgp_advertise.h Normal file
View File

@ -0,0 +1,178 @@
/* BGP advertisement and adjacency
Copyright (C) 1996, 97, 98, 99, 2000 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. */
/* BGP advertise FIFO. */
struct bgp_advertise_fifo
{
struct bgp_advertise *next;
struct bgp_advertise *prev;
};
/* BGP advertise attribute. */
struct bgp_advertise_attr
{
/* Head of advertisement pointer. */
struct bgp_advertise *adv;
/* Reference counter. */
unsigned long refcnt;
/* Attribute pointer to be announced. */
struct attr *attr;
};
struct bgp_advertise
{
/* FIFO for advertisement. */
struct bgp_advertise_fifo fifo;
/* Link list for same attribute advertise. */
struct bgp_advertise *next;
struct bgp_advertise *prev;
/* Prefix information. */
struct bgp_node *rn;
/* Reference pointer. */
struct bgp_adj_out *adj;
/* Advertisement attribute. */
struct bgp_advertise_attr *baa;
/* BGP info. */
struct bgp_info *binfo;
};
/* BGP adjacency out. */
struct bgp_adj_out
{
/* Lined list pointer. */
struct bgp_adj_out *next;
struct bgp_adj_out *prev;
/* Advertised peer. */
struct peer *peer;
/* Advertised attribute. */
struct attr *attr;
/* Advertisement information. */
struct bgp_advertise *adv;
};
/* BGP adjacency in. */
struct bgp_adj_in
{
/* Linked list pointer. */
struct bgp_adj_in *next;
struct bgp_adj_in *prev;
/* Received peer. */
struct peer *peer;
/* Received attribute. */
struct attr *attr;
};
/* BGP advertisement list. */
struct bgp_synchronize
{
struct bgp_advertise_fifo update;
struct bgp_advertise_fifo withdraw;
struct bgp_advertise_fifo withdraw_low;
};
/* FIFO -- first in first out structure and macros. */
struct fifo
{
struct fifo *next;
struct fifo *prev;
};
#define FIFO_INIT(F) \
do { \
struct fifo *Xfifo = (struct fifo *)(F); \
Xfifo->next = Xfifo->prev = Xfifo; \
} while (0)
#define FIFO_ADD(F,N) \
do { \
struct fifo *Xfifo = (struct fifo *)(F); \
struct fifo *Xnode = (struct fifo *)(N); \
Xnode->next = Xfifo; \
Xnode->prev = Xfifo->prev; \
Xfifo->prev = Xfifo->prev->next = Xnode; \
} while (0)
#define FIFO_DEL(N) \
do { \
struct fifo *Xnode = (struct fifo *)(N); \
Xnode->prev->next = Xnode->next; \
Xnode->next->prev = Xnode->prev; \
} while (0)
#define FIFO_HEAD(F) \
((((struct fifo *)(F))->next == (struct fifo *)(F)) \
? NULL : (F)->next)
/* BGP adjacency linked list. */
#define BGP_INFO_ADD(N,A,TYPE) \
do { \
(A)->prev = NULL; \
(A)->next = (N)->TYPE; \
if ((N)->TYPE) \
(N)->TYPE->prev = (A); \
(N)->TYPE = (A); \
} while (0)
#define BGP_INFO_DEL(N,A,TYPE) \
do { \
if ((A)->next) \
(A)->next->prev = (A)->prev; \
if ((A)->prev) \
(A)->prev->next = (A)->next; \
else \
(N)->TYPE = (A)->next; \
} while (0)
#define BGP_ADJ_IN_ADD(N,A) BGP_INFO_ADD(N,A,adj_in)
#define BGP_ADJ_IN_DEL(N,A) BGP_INFO_DEL(N,A,adj_in)
#define BGP_ADJ_OUT_ADD(N,A) BGP_INFO_ADD(N,A,adj_out)
#define BGP_ADJ_OUT_DEL(N,A) BGP_INFO_DEL(N,A,adj_out)
/* Prototypes. */
void bgp_adj_out_set (struct bgp_node *, struct peer *, struct prefix *,
struct attr *, afi_t, safi_t, struct bgp_info *);
void bgp_adj_out_unset (struct bgp_node *, struct peer *, struct prefix *,
afi_t, safi_t);
void bgp_adj_out_remove (struct bgp_node *, struct bgp_adj_out *,
struct peer *, afi_t, safi_t);
int bgp_adj_out_lookup (struct peer *, struct prefix *, afi_t, safi_t,
struct bgp_node *);
void bgp_adj_in_set (struct bgp_node *, struct peer *, struct attr *);
void bgp_adj_in_unset (struct bgp_node *, struct peer *);
void bgp_adj_in_remove (struct bgp_node *, struct bgp_adj_in *);
struct bgp_advertise *
bgp_advertise_clean (struct peer *, struct bgp_adj_out *, afi_t, safi_t);
void bgp_sync_init (struct peer *);
void bgp_sync_delete (struct peer *);

1186
bgpd/bgp_aspath.c Normal file

File diff suppressed because it is too large Load Diff

77
bgpd/bgp_aspath.h Normal file
View File

@ -0,0 +1,77 @@
/* AS path related definitions.
Copyright (C) 1997, 98, 99 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. */
/* AS path segment type. */
#define AS_SET 1
#define AS_SEQUENCE 2
#define AS_CONFED_SEQUENCE 3
#define AS_CONFED_SET 4
/* Private AS range defined in RFC2270. */
#define BGP_PRIVATE_AS_MIN 64512
#define BGP_PRIVATE_AS_MAX 65535
/* AS path may be include some AsSegments. */
struct aspath
{
/* Reference count to this aspath. */
unsigned long refcnt;
/* Rawdata length. */
int length;
/* AS count. */
int count;
/* Rawdata. */
caddr_t data;
/* String expression of AS path. This string is used by vty output
and AS path regular expression match. */
char *str;
};
#define ASPATH_STR_DEFAULT_LEN 32
/* Prototypes. */
void aspath_init ();
struct aspath *aspath_parse ();
struct aspath *aspath_dup (struct aspath *);
struct aspath *aspath_aggregate (struct aspath *, struct aspath *);
struct aspath *aspath_prepend (struct aspath *, struct aspath *);
struct aspath *aspath_add_seq (struct aspath *, as_t);
struct aspath *aspath_add_confed_seq (struct aspath *, as_t);
int aspath_cmp_left (struct aspath *, struct aspath *);
int aspath_cmp_left_confed (struct aspath *, struct aspath *);
struct aspath *aspath_delete_confed_seq (struct aspath *);
struct aspath *aspath_empty ();
struct aspath *aspath_empty_get ();
struct aspath *aspath_str2aspath (char *);
void aspath_free (struct aspath *);
struct aspath *aspath_intern (struct aspath *);
void aspath_unintern (struct aspath *);
const char *aspath_print (struct aspath *);
void aspath_print_vty (struct vty *, struct aspath *);
void aspath_print_all_vty (struct vty *);
unsigned int aspath_key_make (struct aspath *);
int aspath_loop_check (struct aspath *, as_t);
int aspath_private_as_check (struct aspath *);
int aspath_firstas_check (struct aspath *, as_t);
unsigned long aspath_count ();

1838
bgpd/bgp_attr.c Normal file

File diff suppressed because it is too large Load Diff

125
bgpd/bgp_attr.h Normal file
View File

@ -0,0 +1,125 @@
/* BGP attributes.
Copyright (C) 1996, 97, 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. */
/* Simple bit mapping. */
#define BITMAP_NBBY 8
#define SET_BITMAP(MAP, NUM) \
SET_FLAG (MAP[(NUM) / BITMAP_NBBY], 1 << ((NUM) % BITMAP_NBBY))
#define CHECK_BITMAP(MAP, NUM) \
CHECK_FLAG (MAP[(NUM) / BITMAP_NBBY], 1 << ((NUM) % BITMAP_NBBY))
/* BGP Attribute type range. */
#define BGP_ATTR_TYPE_RANGE 256
#define BGP_ATTR_BITMAP_SIZE (BGP_ATTR_TYPE_RANGE / BITMAP_NBBY)
/* BGP Attribute flags. */
#define BGP_ATTR_FLAG_OPTIONAL 0x80 /* Attribute is optional. */
#define BGP_ATTR_FLAG_TRANS 0x40 /* Attribute is transitive. */
#define BGP_ATTR_FLAG_PARTIAL 0x20 /* Attribute is partial. */
#define BGP_ATTR_FLAG_EXTLEN 0x10 /* Extended length flag. */
/* BGP attribute header must bigger than 2. */
#define BGP_ATTR_MIN_LEN 2 /* Attribute flag and type. */
/* BGP attribute structure. */
struct attr
{
/* Reference count of this attribute. */
unsigned long refcnt;
/* Flag of attribute is set or not. */
u_int32_t flag;
/* Attributes. */
u_char origin;
struct in_addr nexthop;
u_int32_t med;
u_int32_t local_pref;
as_t aggregator_as;
struct in_addr aggregator_addr;
u_int32_t weight;
struct in_addr originator_id;
struct cluster_list *cluster;
u_char mp_nexthop_len;
#ifdef HAVE_IPV6
struct in6_addr mp_nexthop_global;
struct in6_addr mp_nexthop_local;
#endif /* HAVE_IPV6 */
struct in_addr mp_nexthop_global_in;
struct in_addr mp_nexthop_local_in;
/* AS Path structure */
struct aspath *aspath;
/* Community structure */
struct community *community;
/* Extended Communities attribute. */
struct ecommunity *ecommunity;
/* Unknown transitive attribute. */
struct transit *transit;
};
/* Router Reflector related structure. */
struct cluster_list
{
unsigned long refcnt;
int length;
struct in_addr *list;
};
/* Unknown transit attribute. */
struct transit
{
unsigned long refcnt;
int length;
u_char *val;
};
#define ATTR_FLAG_BIT(X) (1 << ((X) - 1))
/* Prototypes. */
void bgp_attr_init ();
int bgp_attr_parse (struct peer *, struct attr *, bgp_size_t,
struct bgp_nlri *, struct bgp_nlri *);
int bgp_attr_check (struct peer *, struct attr *);
struct attr *bgp_attr_intern (struct attr *attr);
void bgp_attr_unintern (struct attr *);
void bgp_attr_flush (struct attr *);
struct attr *bgp_attr_default_set (struct attr *attr, u_char);
struct attr *bgp_attr_default_intern (u_char);
struct attr *bgp_attr_aggregate_intern (struct bgp *, u_char, struct aspath *, struct community *, int as_set);
bgp_size_t bgp_packet_attribute (struct bgp *bgp, struct peer *, struct stream *, struct attr *, struct prefix *, afi_t, safi_t, struct peer *, struct prefix_rd *, u_char *);
bgp_size_t bgp_packet_withdraw (struct peer *peer, struct stream *s, struct prefix *p, afi_t, safi_t, struct prefix_rd *, u_char *);
void bgp_dump_routes_attr (struct stream *, struct attr *);
unsigned int attrhash_key_make (struct attr *);
int attrhash_cmp (struct attr *, struct attr *);
void attr_show_all (struct vty *);
/* Cluster list prototypes. */
int cluster_loop_check (struct cluster_list *, struct in_addr);
void cluster_unintern (struct cluster_list *);
/* Transit attribute prototypes. */
void transit_unintern (struct transit *);

291
bgpd/bgp_btoa.c Normal file
View File

@ -0,0 +1,291 @@
/* BGP dump to ascii converter
Copyright (C) 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 "zebra.h"
#include "stream.h"
#include "log.h"
#include "prefix.h"
#include "command.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_dump.h"
#include "bgpd/bgp_attr.h"
#include "bgpd/bgp_aspath.h"
enum MRT_MSG_TYPES {
MSG_NULL,
MSG_START, /* sender is starting up */
MSG_DIE, /* receiver should shut down */
MSG_I_AM_DEAD, /* sender is shutting down */
MSG_PEER_DOWN, /* sender's peer is down */
MSG_PROTOCOL_BGP, /* msg is a BGP packet */
MSG_PROTOCOL_RIP, /* msg is a RIP packet */
MSG_PROTOCOL_IDRP, /* msg is an IDRP packet */
MSG_PROTOCOL_RIPNG, /* msg is a RIPNG packet */
MSG_PROTOCOL_BGP4PLUS, /* msg is a BGP4+ packet */
MSG_PROTOCOL_BGP4PLUS_01, /* msg is a BGP4+ (draft 01) packet */
MSG_PROTOCOL_OSPF, /* msg is an OSPF packet */
MSG_TABLE_DUMP /* routing table dump */
};
int
attr_parse (struct stream *s, u_int16_t len)
{
u_int flag;
u_int type;
u_int16_t length;
u_int16_t lim;
lim = s->getp + len;
printf ("attr_parse s->getp %d, len %d, lim %d\n", s->getp, len, lim);
while (s->getp < lim)
{
flag = stream_getc (s);
type = stream_getc (s);
if (flag & ATTR_FLAG_EXTLEN)
length = stream_getw (s);
else
length = stream_getc (s);
printf ("FLAG: %d\n", flag);
printf ("TYPE: %d\n", type);
printf ("Len: %d\n", length);
switch (type)
{
case BGP_ATTR_ORIGIN:
{
u_char origin;
origin = stream_getc (s);
printf ("ORIGIN: %d\n", origin);
}
break;
case BGP_ATTR_AS_PATH:
{
struct aspath aspath;
aspath.data = (s->data + s->getp);
aspath.length = length;
aspath.str = aspath_make_str_count (&aspath);
printf ("ASPATH: %s\n", aspath.str);
free (aspath.str);
stream_forward (s, length);
}
break;
case BGP_ATTR_NEXT_HOP:
{
struct in_addr nexthop;
nexthop.s_addr = stream_get_ipv4 (s);
printf ("NEXTHOP: %s\n", inet_ntoa (nexthop));
/* stream_forward (s, length); */
}
break;
default:
stream_forward (s, length);
break;
}
}
return 0;
}
int
main (int argc, char **argv)
{
int ret;
FILE *fp;
struct stream *s;
time_t now;
int type;
int subtype;
int len;
int source_as;
int dest_as;
int ifindex;
int family;
struct in_addr sip;
struct in_addr dip;
u_int16_t viewno, seq_num;
struct prefix_ipv4 p;
s = stream_new (10000);
if (argc != 2)
{
fprintf (stderr, "Usage: %s FILENAME\n", argv[0]);
exit (1);
}
fp = fopen (argv[1], "r");
if (!fp)
{
perror ("fopen");
exit (1);
}
while (1)
{
stream_reset (s);
ret = fread (s->data, 12, 1, fp);
if (feof (fp))
{
printf ("END OF FILE\n");
break;
}
if (ferror (fp))
{
printf ("ERROR OF FREAD\n");
break;
}
/* Extract header. */
now = stream_getl (s);
type = stream_getw (s);
subtype = stream_getw (s);
len = stream_getl (s);
printf ("TIME: %s", ctime (&now));
/* printf ("TYPE: %d/%d\n", type, subtype); */
if (type == MSG_PROTOCOL_BGP4MP)
printf ("TYPE: BGP4MP");
else if (type == MSG_TABLE_DUMP)
printf ("TYPE: MSG_TABLE_DUMP");
else
printf ("TYPE: Unknown %d", type);
if (type == MSG_TABLE_DUMP)
switch (subtype)
{
case AFI_IP:
printf ("/AFI_IP\n");
break;
case AFI_IP6:
printf ("/AFI_IP6\n");
break;
default:
printf ("/UNKNOWN %d", subtype);
break;
}
else
{
switch (subtype)
{
case BGP4MP_STATE_CHANGE:
printf ("/CHANGE\n");
break;
case BGP4MP_MESSAGE:
printf ("/MESSAGE\n");
break;
case BGP4MP_ENTRY:
printf ("/ENTRY\n");
break;
case BGP4MP_SNAPSHOT:
printf ("/SNAPSHOT\n");
break;
default:
printf ("/UNKNOWN %d", subtype);
break;
}
}
printf ("len: %d\n", len);
ret = fread (s->data + 12, len, 1, fp);
if (feof (fp))
{
printf ("ENDOF FILE 2\n");
break;
}
if (ferror (fp))
{
printf ("ERROR OF FREAD 2\n");
break;
}
/* printf ("now read %d\n", len); */
if (type == MSG_TABLE_DUMP)
{
u_char status;
time_t originated;
struct in_addr peer;
u_int16_t attrlen;
viewno = stream_getw (s);
seq_num = stream_getw (s);
printf ("VIEW: %d\n", viewno);
printf ("SEQUENCE: %d\n", seq_num);
/* start */
while (s->getp < len - 16)
{
p.prefix.s_addr = stream_get_ipv4 (s);
p.prefixlen = stream_getc (s);
printf ("PREFIX: %s/%d\n", inet_ntoa (p.prefix), p.prefixlen);
status = stream_getc (s);
originated = stream_getl (s);
peer.s_addr = stream_get_ipv4 (s);
source_as = stream_getw(s);
printf ("FROM: %s AS%d\n", inet_ntoa (peer), source_as);
printf ("ORIGINATED: %s", ctime (&originated));
attrlen = stream_getw (s);
printf ("ATTRLEN: %d\n", attrlen);
attr_parse (s, attrlen);
printf ("STATUS: 0x%x\n", status);
}
}
else
{
source_as = stream_getw (s);
dest_as = stream_getw (s);
printf ("source_as: %d\n", source_as);
printf ("dest_as: %d\n", dest_as);
ifindex = stream_getw (s);
family = stream_getw (s);
printf ("ifindex: %d\n", ifindex);
printf ("family: %d\n", family);
sip.s_addr = stream_get_ipv4 (s);
dip.s_addr = stream_get_ipv4 (s);
printf ("saddr: %s\n", inet_ntoa (sip));
printf ("daddr: %s\n", inet_ntoa (dip));
printf ("\n");
}
}
fclose (fp);
return 0;
}

905
bgpd/bgp_clist.c Normal file
View File

@ -0,0 +1,905 @@
/* BGP community-list and extcommunity-list.
Copyright (C) 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 "command.h"
#include "prefix.h"
#include "memory.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_community.h"
#include "bgpd/bgp_ecommunity.h"
#include "bgpd/bgp_aspath.h"
#include "bgpd/bgp_regex.h"
#include "bgpd/bgp_clist.h"
/* Lookup master structure for community-list or
extcommunity-list. */
struct community_list_master *
community_list_master_lookup (struct community_list_handler *ch, int style)
{
if (ch)
switch (style)
{
case COMMUNITY_LIST_STANDARD:
case COMMUNITY_LIST_EXPANDED:
case COMMUNITY_LIST_AUTO:
return &ch->community_list;
break;
case EXTCOMMUNITY_LIST_STANDARD:
case EXTCOMMUNITY_LIST_EXPANDED:
case EXTCOMMUNITY_LIST_AUTO:
return &ch->extcommunity_list;
}
return NULL;
}
/* Allocate a new community list entry. */
struct community_entry *
community_entry_new ()
{
struct community_entry *new;
new = XMALLOC (MTYPE_COMMUNITY_LIST_ENTRY, sizeof (struct community_entry));
memset (new, 0, sizeof (struct community_entry));
return new;
}
/* Free community list entry. */
void
community_entry_free (struct community_entry *entry)
{
switch (entry->style)
{
case COMMUNITY_LIST_STANDARD:
if (entry->u.com)
community_free (entry->u.com);
break;
case EXTCOMMUNITY_LIST_STANDARD:
/* In case of standard extcommunity-list, configuration string
is made by ecommunity_ecom2str(). */
if (entry->config)
XFREE (MTYPE_ECOMMUNITY_STR, entry->config);
if (entry->u.ecom)
ecommunity_free (entry->u.ecom);
break;
case COMMUNITY_LIST_EXPANDED:
case EXTCOMMUNITY_LIST_EXPANDED:
if (entry->config)
XFREE (MTYPE_COMMUNITY_LIST_CONFIG, entry->config);
if (entry->reg)
bgp_regex_free (entry->reg);
default:
break;
}
XFREE (MTYPE_COMMUNITY_LIST_ENTRY, entry);
}
/* Allocate a new community-list. */
struct community_list *
community_list_new ()
{
struct community_list *new;
new = XMALLOC (MTYPE_COMMUNITY_LIST, sizeof (struct community_list));
memset (new, 0, sizeof (struct community_list));
return new;
}
/* Free community-list. */
void
community_list_free (struct community_list *list)
{
if (list->name)
XFREE (MTYPE_COMMUNITY_LIST_NAME, list->name);
XFREE (MTYPE_COMMUNITY_LIST, list);
}
struct community_list *
community_list_insert (struct community_list_handler *ch,
char *name, int style)
{
int i;
long number;
struct community_list *new;
struct community_list *point;
struct community_list_list *list;
struct community_list_master *cm;
/* Lookup community-list master. */
cm = community_list_master_lookup (ch, style);
if (! cm)
return NULL;
/* Allocate new community_list and copy given name. */
new = community_list_new ();
new->name = XSTRDUP (MTYPE_COMMUNITY_LIST_NAME, name);
/* If name is made by all digit character. We treat it as
number. */
for (number = 0, i = 0; i < strlen (name); i++)
{
if (isdigit ((int) name[i]))
number = (number * 10) + (name[i] - '0');
else
break;
}
/* In case of name is all digit character */
if (i == strlen (name))
{
new->sort = COMMUNITY_LIST_NUMBER;
/* Set access_list to number list. */
list = &cm->num;
for (point = list->head; point; point = point->next)
if (atol (point->name) >= number)
break;
}
else
{
new->sort = COMMUNITY_LIST_STRING;
/* Set access_list to string list. */
list = &cm->str;
/* Set point to insertion point. */
for (point = list->head; point; point = point->next)
if (strcmp (point->name, name) >= 0)
break;
}
/* Link to upper list. */
new->parent = list;
/* In case of this is the first element of master. */
if (list->head == NULL)
{
list->head = list->tail = new;
return new;
}
/* In case of insertion is made at the tail of access_list. */
if (point == NULL)
{
new->prev = list->tail;
list->tail->next = new;
list->tail = new;
return new;
}
/* In case of insertion is made at the head of access_list. */
if (point == list->head)
{
new->next = list->head;
list->head->prev = new;
list->head = new;
return new;
}
/* Insertion is made at middle of the access_list. */
new->next = point;
new->prev = point->prev;
if (point->prev)
point->prev->next = new;
point->prev = new;
return new;
}
struct community_list *
community_list_lookup (struct community_list_handler *ch,
char *name, int style)
{
struct community_list *list;
struct community_list_master *cm;
if (! name)
return NULL;
cm = community_list_master_lookup (ch, style);
if (! cm)
return NULL;
for (list = cm->num.head; list; list = list->next)
if (strcmp (list->name, name) == 0)
return list;
for (list = cm->str.head; list; list = list->next)
if (strcmp (list->name, name) == 0)
return list;
return NULL;
}
struct community_list *
community_list_get (struct community_list_handler *ch, char *name, int style)
{
struct community_list *list;
list = community_list_lookup (ch, name, style);
if (! list)
list = community_list_insert (ch, name, style);
return list;
}
void
community_list_delete (struct community_list *list)
{
struct community_list_list *clist;
struct community_entry *entry, *next;
for (entry = list->head; entry; entry = next)
{
next = entry->next;
community_entry_free (entry);
}
clist = list->parent;
if (list->next)
list->next->prev = list->prev;
else
clist->tail = list->prev;
if (list->prev)
list->prev->next = list->next;
else
clist->head = list->next;
community_list_free (list);
}
int
community_list_empty_p (struct community_list *list)
{
return (list->head == NULL && list->tail == NULL) ? 1 : 0;
}
/* Add community-list entry to the list. */
static void
community_list_entry_add (struct community_list *list,
struct community_entry *entry)
{
entry->next = NULL;
entry->prev = list->tail;
if (list->tail)
list->tail->next = entry;
else
list->head = entry;
list->tail = entry;
}
/* Delete community-list entry from the list. */
static void
community_list_entry_delete (struct community_list *list,
struct community_entry *entry, int style)
{
if (entry->next)
entry->next->prev = entry->prev;
else
list->tail = entry->prev;
if (entry->prev)
entry->prev->next = entry->next;
else
list->head = entry->next;
community_entry_free (entry);
if (community_list_empty_p (list))
community_list_delete (list);
}
/* Lookup community-list entry from the list. */
static struct community_entry *
community_list_entry_lookup (struct community_list *list, void *arg,
int direct)
{
struct community_entry *entry;
for (entry = list->head; entry; entry = entry->next)
{
switch (entry->style)
{
case COMMUNITY_LIST_STANDARD:
if (community_cmp (entry->u.com, arg))
return entry;
break;
case EXTCOMMUNITY_LIST_STANDARD:
if (ecommunity_cmp (entry->u.ecom, arg))
return entry;
break;
case COMMUNITY_LIST_EXPANDED:
case EXTCOMMUNITY_LIST_EXPANDED:
if (strcmp (entry->config, arg) == 0)
return entry;
break;
default:
break;
}
}
return NULL;
}
/* Internal function to perform regular expression match for community
attribute. */
static int
community_regexp_match (struct community *com, regex_t *reg)
{
char *str;
/* When there is no communities attribute it is treated as empty
string. */
if (com == NULL || com->size == 0)
str = "";
else
str = community_str (com);
/* Regular expression match. */
if (regexec (reg, str, 0, NULL, 0) == 0)
return 1;
/* No match. */
return 0;
}
/* Delete community attribute using regular expression match. Return
modified communites attribute. */
static struct community *
community_regexp_delete (struct community *com, regex_t *reg)
{
int i;
u_int32_t comval;
/* Maximum is "65535:65535" + '\0'. */
char c[12];
char *str;
if (! com)
return NULL;
i = 0;
while (i < com->size)
{
memcpy (&comval, com_nthval (com, i), sizeof (u_int32_t));
comval = ntohl (comval);
switch (comval)
{
case COMMUNITY_INTERNET:
str = "internet";
break;
case COMMUNITY_NO_EXPORT:
str = "no-export";
break;
case COMMUNITY_NO_ADVERTISE:
str = "no-advertise";
break;
case COMMUNITY_LOCAL_AS:
str = "local-AS";
break;
default:
sprintf (c, "%d:%d", (comval >> 16) & 0xFFFF, comval & 0xFFFF);
str = c;
break;
}
if (regexec (reg, str, 0, NULL, 0) == 0)
community_del_val (com, com_nthval (com, i));
else
i++;
}
return com;
}
/* When given community attribute matches to the community-list return
1 else return 0. */
int
community_list_match (struct community *com, struct community_list *list)
{
struct community_entry *entry;
for (entry = list->head; entry; entry = entry->next)
{
if (entry->any)
return entry->direct == COMMUNITY_PERMIT ? 1 : 0;
if (entry->style == COMMUNITY_LIST_STANDARD)
{
if (community_include (entry->u.com, COMMUNITY_INTERNET))
return entry->direct == COMMUNITY_PERMIT ? 1 : 0;
if (community_match (com, entry->u.com))
return entry->direct == COMMUNITY_PERMIT ? 1 : 0;
}
else if (entry->style == COMMUNITY_LIST_EXPANDED)
{
if (community_regexp_match (com, entry->reg))
return entry->direct == COMMUNITY_PERMIT ? 1 : 0;
}
}
return 0;
}
/* Perform exact matching. In case of expanded community-list, do
same thing as community_list_match(). */
int
community_list_exact_match (struct community *com, struct community_list *list)
{
struct community_entry *entry;
for (entry = list->head; entry; entry = entry->next)
{
if (entry->any)
return entry->direct == COMMUNITY_PERMIT ? 1 : 0;
if (entry->style == COMMUNITY_LIST_STANDARD)
{
if (community_include (entry->u.com, COMMUNITY_INTERNET))
return entry->direct == COMMUNITY_PERMIT ? 1 : 0;
if (community_cmp (com, entry->u.com))
return entry->direct == COMMUNITY_PERMIT ? 1 : 0;
}
else if (entry->style == COMMUNITY_LIST_EXPANDED)
{
if (community_regexp_match (com, entry->reg))
return entry->direct == COMMUNITY_PERMIT ? 1 : 0;
}
}
return 0;
}
/* Delete all permitted communities in the list from com1 */
struct community *
community_list_match_delete (struct community *com,
struct community_list *list)
{
struct community_entry *entry;
for (entry = list->head; entry; entry = entry->next)
{
if (entry->any && entry->direct == COMMUNITY_PERMIT)
{
/* This is a tricky part. Currently only
route_set_community_delete() uses this function. In the
function com->size is zero, it free the community
structure. */
com->size = 0;
return com;
}
if (entry->style == COMMUNITY_LIST_STANDARD)
{
if (entry->direct == COMMUNITY_PERMIT)
community_delete (com, entry->u.com);
}
else if (entry->style == COMMUNITY_LIST_EXPANDED)
{
if (entry->direct == COMMUNITY_PERMIT)
community_regexp_delete (com, entry->reg);
}
}
return com;
}
/* To avoid duplicated entry in the community-list, this function
compares specified entry to existing entry. */
int
community_list_dup_check (struct community_list *list,
struct community_entry *new)
{
struct community_entry *entry;
for (entry = list->head; entry; entry = entry->next)
{
if (entry->style != new->style)
continue;
if (entry->direct != new->direct)
continue;
if (entry->any != new->any)
continue;
if (entry->any)
return 1;
switch (entry->style)
{
case COMMUNITY_LIST_STANDARD:
if (community_cmp (entry->u.com, new->u.com))
return 1;
break;
case EXTCOMMUNITY_LIST_STANDARD:
if (ecommunity_cmp (entry->u.ecom, new->u.ecom))
return 1;
break;
case COMMUNITY_LIST_EXPANDED:
case EXTCOMMUNITY_LIST_EXPANDED:
if (strcmp (entry->config, new->config) == 0)
return 1;
break;
default:
break;
}
}
return 0;
}
/* Set community-list. */
int
community_list_set (struct community_list_handler *ch,
char *name, char *str, int direct, int style)
{
struct community_entry *entry;
struct community_list *list;
struct community *com;
regex_t *regex;
entry = NULL;
/* Get community list. */
list = community_list_get (ch, name, style);
/* When community-list already has entry, new entry should have same
style. If you want to have mixed style community-list, you can
comment out this check. */
if (! community_list_empty_p (list))
{
struct community_entry *first;
first = list->head;
if (style == COMMUNITY_LIST_AUTO)
style = first->style;
else if (style != first->style)
{
return (first->style == COMMUNITY_LIST_STANDARD
? COMMUNITY_LIST_ERR_STANDARD_CONFLICT
: COMMUNITY_LIST_ERR_EXPANDED_CONFLICT);
}
}
/* When str is NULL, it is matches any. */
if (! str)
{
entry = community_entry_new ();
entry->direct = direct;
entry->any = 1;
if (style == COMMUNITY_LIST_AUTO)
entry->style = COMMUNITY_LIST_STANDARD;
else
entry->style = style;
}
else
{
/* Standard community-list parse. String must be converted into
community structure without problem. */
if (style == COMMUNITY_LIST_STANDARD || style == COMMUNITY_LIST_AUTO)
{
com = community_str2com (str);
if (com)
{
entry = community_entry_new ();
entry->u.com = com;
entry->direct = direct;
entry->style = COMMUNITY_LIST_STANDARD;
}
else if (style == COMMUNITY_LIST_STANDARD)
return COMMUNITY_LIST_ERR_MALFORMED_VAL;
/* We can't convert string into communities value. When
community-list type is auto, fall dawn to regular expression
match. */
}
/* Expanded community-list parse. String may include regular
expression. */
if (! entry && (style == COMMUNITY_LIST_EXPANDED
|| style == COMMUNITY_LIST_AUTO))
{
regex = bgp_regcomp (str);
if (regex)
{
entry = community_entry_new ();
entry->reg = regex;
entry->config = XSTRDUP (MTYPE_COMMUNITY_LIST_CONFIG, str);
entry->direct = direct;
entry->style = COMMUNITY_LIST_EXPANDED;
}
else
return COMMUNITY_LIST_ERR_MALFORMED_VAL;
}
}
/* Do not put duplicated community entry. */
if (community_list_dup_check (list, entry))
community_entry_free (entry);
else
community_list_entry_add (list, entry);
return 0;
}
/* Unset community-list. When str is NULL, delete all of
community-list entry belongs to the specified name. */
int
community_list_unset (struct community_list_handler *ch,
char *name, char *str, int direct, int style)
{
struct community_entry *entry;
struct community_list *list;
struct community *com;
regex_t *regex;
entry = NULL;
/* Lookup community list. */
list = community_list_lookup (ch, name, style);
if (list == NULL)
return COMMUNITY_LIST_ERR_CANT_FIND_LIST;
/* Delete all of entry belongs to this community-list. */
if (! str)
{
community_list_delete (list);
return 0;
}
/* Community list string is specified. Lookup entry from community
list. */
if (style == COMMUNITY_LIST_STANDARD || style == COMMUNITY_LIST_AUTO)
{
com = community_str2com (str);
if (com)
{
entry = community_list_entry_lookup (list, com, direct);
community_free (com);
}
else if (style == COMMUNITY_LIST_STANDARD)
return COMMUNITY_LIST_ERR_MALFORMED_VAL;
/* If we can't convert string into community and community-list
type is auto, fall dawn to expanded community-list. */
}
/* Expanded community-list parse. String may include regular
expression. */
if (! entry
&& (style == COMMUNITY_LIST_EXPANDED || style == COMMUNITY_LIST_AUTO))
{
regex = bgp_regcomp (str);
if (regex)
{
entry = community_list_entry_lookup (list, str, direct);
bgp_regex_free (regex);
}
else
return COMMUNITY_LIST_ERR_MALFORMED_VAL;
}
if (! entry)
return COMMUNITY_LIST_ERR_CANT_FIND_LIST;
community_list_entry_delete (list, entry, style);
return 0;
}
/* Set extcommunity-list. */
int
extcommunity_list_set (struct community_list_handler *ch,
char *name, char *str, int direct, int style)
{
struct community_entry *entry;
struct community_list *list;
struct ecommunity *ecom;
regex_t *regex;
entry = NULL;
/* Get community list. */
list = community_list_get (ch, name, style);
/* When community-list already has entry, new entry should have same
style. If you want to have mixed style community-list, you can
comment out this check. */
if (! community_list_empty_p (list))
{
struct community_entry *first;
first = list->head;
if (style == EXTCOMMUNITY_LIST_AUTO)
style = first->style;
else if (style != first->style)
{
return (first->style == EXTCOMMUNITY_LIST_STANDARD
? COMMUNITY_LIST_ERR_STANDARD_CONFLICT
: COMMUNITY_LIST_ERR_EXPANDED_CONFLICT);
}
}
/* When str is NULL, it is matches any. */
if (! str)
{
entry = community_entry_new ();
entry->direct = direct;
entry->any = 1;
if (style == EXTCOMMUNITY_LIST_AUTO)
entry->style = EXTCOMMUNITY_LIST_STANDARD;
else
entry->style = style;
}
else
{
/* Standard extcommunity-list parse. String is converted into
ecommunity structure. */
if (style == EXTCOMMUNITY_LIST_STANDARD
|| style == EXTCOMMUNITY_LIST_AUTO)
{
/* Type is unknown. String includes keyword. */
ecom = ecommunity_str2com (str, 0, 1);
if (ecom)
{
entry = community_entry_new ();
entry->config
= ecommunity_ecom2str (ecom, ECOMMUNITY_FORMAT_COMMUNITY_LIST);
ecom->str = ecommunity_ecom2str (ecom, ECOMMUNITY_FORMAT_DISPLAY);
entry->u.ecom = ecom;
entry->direct = direct;
entry->style = EXTCOMMUNITY_LIST_STANDARD;
}
else if (style == EXTCOMMUNITY_LIST_STANDARD)
return COMMUNITY_LIST_ERR_MALFORMED_VAL;
/* We can't convert string into communities value. When
community-list type is auto, fall dawn to regular expression
match. */
}
/* Expanded extcommunity-list parse. String may include regular
expression. */
if (! entry && (style == EXTCOMMUNITY_LIST_EXPANDED
|| style == EXTCOMMUNITY_LIST_AUTO))
{
regex = bgp_regcomp (str);
if (regex)
{
entry = community_entry_new ();
entry->reg = regex;
entry->config = XSTRDUP (MTYPE_COMMUNITY_LIST_CONFIG, str);
entry->direct = direct;
entry->style = EXTCOMMUNITY_LIST_EXPANDED;
}
else
return COMMUNITY_LIST_ERR_MALFORMED_VAL;
}
}
/* Do not put duplicated community entry. */
if (community_list_dup_check (list, entry))
community_entry_free (entry);
else
community_list_entry_add (list, entry);
return 0;
}
/* Unset extcommunity-list. When str is NULL, delete all of
extcommunity-list entry belongs to the specified name. */
int
extcommunity_list_unset (struct community_list_handler *ch,
char *name, char *str, int direct, int style)
{
struct community_entry *entry;
struct community_list *list;
struct ecommunity *ecom = NULL;
regex_t *regex;
entry = NULL;
/* Lookup extcommunity list. */
list = community_list_lookup (ch, name, style);
if (list == NULL)
return COMMUNITY_LIST_ERR_CANT_FIND_LIST;
/* Delete all of entry belongs to this extcommunity-list. */
if (! str)
{
community_list_delete (list);
return 0;
}
/* Community list string is specified. Lookup entry from community
list. */
if (style == EXTCOMMUNITY_LIST_STANDARD || style == EXTCOMMUNITY_LIST_AUTO)
{
ecom = ecommunity_str2com (str, 0, 1);
if (ecom)
{
entry = community_list_entry_lookup (list, ecom, direct);
ecommunity_free (ecom);
}
else if (style == COMMUNITY_LIST_STANDARD)
return COMMUNITY_LIST_ERR_MALFORMED_VAL;
/* If we can't convert string into community and community-list
type is auto, fall dawn to expanded community-list. */
}
/* Expanded community-list parse. String may include regular
expression. */
if (! entry
&& (style == COMMUNITY_LIST_EXPANDED || style == COMMUNITY_LIST_AUTO))
{
regex = bgp_regcomp (str);
if (regex)
{
entry = community_list_entry_lookup (list, str, direct);
bgp_regex_free (regex);
}
else
return COMMUNITY_LIST_ERR_MALFORMED_VAL;
}
if (! entry)
return COMMUNITY_LIST_ERR_CANT_FIND_LIST;
community_list_entry_delete (list, entry, style);
return 0;
}
/* Initializa community-list. Return community-list handler. */
struct community_list_handler *
community_list_init ()
{
struct community_list_handler *ch;
ch = XCALLOC (MTYPE_COMMUNITY_LIST_HANDLER,
sizeof (struct community_list_handler));
return ch;
}
/* Terminate community-list. */
void
community_list_terminate (struct community_list_handler *ch)
{
struct community_list_master *cm;
struct community_list *list;
cm = &ch->community_list;
while ((list = cm->num.head) != NULL)
community_list_delete (list);
while ((list = cm->str.head) != NULL)
community_list_delete (list);
cm = &ch->extcommunity_list;
while ((list = cm->num.head) != NULL)
community_list_delete (list);
while ((list = cm->str.head) != NULL)
community_list_delete (list);
XFREE (MTYPE_COMMUNITY_LIST_HANDLER, ch);
}

143
bgpd/bgp_clist.h Normal file
View File

@ -0,0 +1,143 @@
/* BGP Community list.
Copyright (C) 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. */
/* Community-list deny and permit. */
#define COMMUNITY_DENY 0
#define COMMUNITY_PERMIT 1
/* Number and string based community-list name. */
#define COMMUNITY_LIST_STRING 0
#define COMMUNITY_LIST_NUMBER 1
/* Community-list entry types. */
#define COMMUNITY_LIST_STANDARD 0 /* Standard community-list. */
#define COMMUNITY_LIST_EXPANDED 1 /* Expanded community-list. */
#define COMMUNITY_LIST_AUTO 2 /* Automatically detected. */
#define EXTCOMMUNITY_LIST_STANDARD 3 /* Standard extcommunity-list. */
#define EXTCOMMUNITY_LIST_EXPANDED 4 /* Expanded extcommunity-list. */
#define EXTCOMMUNITY_LIST_AUTO 5 /* Automatically detected. */
/* Community-list. */
struct community_list
{
/* Name of the community-list. */
char *name;
/* String or number. */
int sort;
/* Link to upper list. */
struct community_list_list *parent;
/* Linked list for other community-list. */
struct community_list *next;
struct community_list *prev;
/* Community-list entry in this community-list. */
struct community_entry *head;
struct community_entry *tail;
};
/* Each entry in community-list. */
struct community_entry
{
struct community_entry *next;
struct community_entry *prev;
/* Permit or deny. */
u_char direct;
/* Standard or expanded. */
u_char style;
/* Any match. */
u_char any;
/* Community structure. */
union
{
struct community *com;
struct ecommunity *ecom;
} u;
/* Configuration string. */
char *config;
/* Expanded community-list regular expression. */
regex_t *reg;
};
/* Linked list of community-list. */
struct community_list_list
{
struct community_list *head;
struct community_list *tail;
};
/* Master structure of community-list and extcommunity-list. */
struct community_list_master
{
struct community_list_list num;
struct community_list_list str;
};
/* Community-list handler. community_list_init() returns this
structure as handler. */
struct community_list_handler
{
/* Community-list. */
struct community_list_master community_list;
/* Exteded community-list. */
struct community_list_master extcommunity_list;
};
/* Error code of community-list. */
#define COMMUNITY_LIST_ERR_CANT_FIND_LIST -1
#define COMMUNITY_LIST_ERR_MALFORMED_VAL -2
#define COMMUNITY_LIST_ERR_STANDARD_CONFLICT -3
#define COMMUNITY_LIST_ERR_EXPANDED_CONFLICT -4
/* Handler. */
extern struct community_list_handler *bgp_clist;
/* Prototypes. */
struct community_list_handler *community_list_init ();
int community_list_set (struct community_list_handler *ch,
char *name, char *str, int direct, int style);
int community_list_unset (struct community_list_handler *ch,
char *name, char *str, int direct, int style);
int extcommunity_list_set (struct community_list_handler *ch,
char *name, char *str, int direct, int style);
int extcommunity_list_unset (struct community_list_handler *ch,
char *name, char *str, int direct, int style);
struct community_list_master *
community_list_master_lookup (struct community_list_handler *, int);
struct community_list *
community_list_lookup (struct community_list_handler *, char *, int);
int community_list_match (struct community *, struct community_list *);
int community_list_exact_match (struct community *, struct community_list *);
struct community *
community_list_match_delete (struct community *,
struct community_list *);

629
bgpd/bgp_community.c Normal file
View File

@ -0,0 +1,629 @@
/* Community attribute related functions.
Copyright (C) 1998, 2001 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 "hash.h"
#include "memory.h"
#include "bgpd/bgp_community.h"
/* Hash of community attribute. */
struct hash *comhash;
/* Allocate a new communities value. */
struct community *
community_new ()
{
return (struct community *) XCALLOC (MTYPE_COMMUNITY,
sizeof (struct community));
}
/* Free communities value. */
void
community_free (struct community *com)
{
if (com->val)
XFREE (MTYPE_COMMUNITY_VAL, com->val);
if (com->str)
XFREE (MTYPE_COMMUNITY_STR, com->str);
XFREE (MTYPE_COMMUNITY, com);
}
/* Add one community value to the community. */
void
community_add_val (struct community *com, u_int32_t val)
{
com->size++;
if (com->val)
com->val = XREALLOC (MTYPE_COMMUNITY_VAL, com->val, com_length (com));
else
com->val = XMALLOC (MTYPE_COMMUNITY_VAL, com_length (com));
val = htonl (val);
memcpy (com_lastval (com), &val, sizeof (u_int32_t));
}
/* Delete one community. */
void
community_del_val (struct community *com, u_int32_t *val)
{
int i = 0;
int c = 0;
if (! com->val)
return;
while (i < com->size)
{
if (memcmp (com->val + i, val, sizeof (u_int32_t)) == 0)
{
c = com->size -i -1;
if (c > 0)
memcpy (com->val + i, com->val + (i + 1), c * sizeof (val));
com->size--;
if (com->size > 0)
com->val = XREALLOC (MTYPE_COMMUNITY_VAL, com->val,
com_length (com));
else
{
XFREE (MTYPE_COMMUNITY_VAL, com->val);
com->val = NULL;
}
return;
}
i++;
}
}
/* Delete all communities listed in com2 from com1 */
struct community *
community_delete (struct community *com1, struct community *com2)
{
int i = 0;
while(i < com2->size)
{
community_del_val (com1, com2->val + i);
i++;
}
return com1;
}
/* Callback function from qsort(). */
int
community_compare (const void *a1, const void *a2)
{
u_int32_t v1;
u_int32_t v2;
memcpy (&v1, a1, sizeof (u_int32_t));
memcpy (&v2, a2, sizeof (u_int32_t));
v1 = ntohl (v1);
v2 = ntohl (v2);
if (v1 < v2)
return -1;
if (v1 > v2)
return 1;
return 0;
}
int
community_include (struct community *com, u_int32_t val)
{
int i;
val = htonl (val);
for (i = 0; i < com->size; i++)
if (memcmp (&val, com_nthval (com, i), sizeof (u_int32_t)) == 0)
return 1;
return 0;
}
u_int32_t
community_val_get (struct community *com, int i)
{
u_char *p;
u_int32_t val;
p = (u_char *) com->val;
p += (i * 4);
memcpy (&val, p, sizeof (u_int32_t));
return ntohl (val);
}
/* Sort and uniq given community. */
struct community *
community_uniq_sort (struct community *com)
{
int i;
struct community *new;
u_int32_t val;
if (! com)
return NULL;
new = community_new ();;
for (i = 0; i < com->size; i++)
{
val = community_val_get (com, i);
if (! community_include (new, val))
community_add_val (new, val);
}
qsort (new->val, new->size, sizeof (u_int32_t), community_compare);
return new;
}
/* Convert communities attribute to string.
For Well-known communities value, below keyword is used.
0x0 "internet"
0xFFFFFF01 "no-export"
0xFFFFFF02 "no-advertise"
0xFFFFFF03 "local-AS"
For other values, "AS:VAL" format is used. */
static char *
community_com2str (struct community *com)
{
int i;
char *str;
char *pnt;
int len;
int first;
u_int32_t comval;
u_int16_t as;
u_int16_t val;
/* When communities attribute is empty. */
if (com->size == 0)
{
str = XMALLOC (MTYPE_COMMUNITY_STR, 1);
str[0] = '\0';
return str;
}
/* Memory allocation is time consuming work. So we calculate
required string length first. */
len = 0;
for (i = 0; i < com->size; i++)
{
memcpy (&comval, com_nthval (com, i), sizeof (u_int32_t));
comval = ntohl (comval);
switch (comval)
{
case COMMUNITY_INTERNET:
len += strlen (" internet");
break;
case COMMUNITY_NO_EXPORT:
len += strlen (" no-export");
break;
case COMMUNITY_NO_ADVERTISE:
len += strlen (" no-advertise");
break;
case COMMUNITY_LOCAL_AS:
len += strlen (" local-AS");
break;
default:
len += strlen (" 65536:65535");
break;
}
}
/* Allocate memory. */
str = pnt = XMALLOC (MTYPE_COMMUNITY_STR, len);
first = 1;
/* Fill in string. */
for (i = 0; i < com->size; i++)
{
memcpy (&comval, com_nthval (com, i), sizeof (u_int32_t));
comval = ntohl (comval);
if (first)
first = 0;
else
*pnt++ = ' ';
switch (comval)
{
case COMMUNITY_INTERNET:
strcpy (pnt, "internet");
pnt += strlen ("internet");
break;
case COMMUNITY_NO_EXPORT:
strcpy (pnt, "no-export");
pnt += strlen ("no-export");
break;
case COMMUNITY_NO_ADVERTISE:
strcpy (pnt, "no-advertise");
pnt += strlen ("no-advertise");
break;
case COMMUNITY_LOCAL_AS:
strcpy (pnt, "local-AS");
pnt += strlen ("local-AS");
break;
default:
as = (comval >> 16) & 0xFFFF;
val = comval & 0xFFFF;
sprintf (pnt, "%d:%d", as, val);
pnt += strlen (pnt);
break;
}
}
*pnt = '\0';
return str;
}
/* Intern communities attribute. */
struct community *
community_intern (struct community *com)
{
struct community *find;
/* Assert this community structure is not interned. */
assert (com->refcnt == 0);
/* Lookup community hash. */
find = (struct community *) hash_get (comhash, com, hash_alloc_intern);
/* Arguemnt com is allocated temporary. So when it is not used in
hash, it should be freed. */
if (find != com)
community_free (com);
/* Increment refrence counter. */
find->refcnt++;
/* Make string. */
if (! find->str)
find->str = community_com2str (find);
return find;
}
/* Free community attribute. */
void
community_unintern (struct community *com)
{
struct community *ret;
if (com->refcnt)
com->refcnt--;
/* Pull off from hash. */
if (com->refcnt == 0)
{
/* Community value com must exist in hash. */
ret = (struct community *) hash_release (comhash, com);
assert (ret != NULL);
community_free (com);
}
}
/* Create new community attribute. */
struct community *
community_parse (char *pnt, u_short length)
{
struct community tmp;
struct community *new;
/* If length is malformed return NULL. */
if (length % 4)
return NULL;
/* Make temporary community for hash look up. */
tmp.size = length / 4;
tmp.val = (u_int32_t *) pnt;
new = community_uniq_sort (&tmp);
return community_intern (new);
}
struct community *
community_dup (struct community *com)
{
struct community *new;
new = XCALLOC (MTYPE_COMMUNITY, sizeof (struct community));
new->size = com->size;
if (new->size)
{
new->val = XMALLOC (MTYPE_COMMUNITY_VAL, com->size * 4);
memcpy (new->val, com->val, com->size * 4);
}
else
new->val = NULL;
return new;
}
/* Retrun string representation of communities attribute. */
char *
community_str (struct community *com)
{
if (! com->str)
com->str = community_com2str (com);
return com->str;
}
/* Make hash value of community attribute. This function is used by
hash package.*/
unsigned int
community_hash_make (struct community *com)
{
int c;
unsigned int key;
unsigned char *pnt;
key = 0;
pnt = (unsigned char *)com->val;
for(c = 0; c < com->size * 4; c++)
key += pnt[c];
return key;
}
int
community_match (struct community *com1, struct community *com2)
{
int i = 0;
int j = 0;
if (com1 == NULL && com2 == NULL)
return 1;
if (com1 == NULL || com2 == NULL)
return 0;
if (com1->size < com2->size)
return 0;
/* Every community on com2 needs to be on com1 for this to match */
while (i < com1->size && j < com2->size)
{
if (memcmp (com1->val + i, com2->val + j, sizeof (u_int32_t)) == 0)
j++;
i++;
}
if (j == com2->size)
return 1;
else
return 0;
}
/* If two aspath have same value then return 1 else return 0. This
function is used by hash package. */
int
community_cmp (struct community *com1, struct community *com2)
{
if (com1 == NULL && com2 == NULL)
return 1;
if (com1 == NULL || com2 == NULL)
return 0;
if (com1->size == com2->size)
if (memcmp (com1->val, com2->val, com1->size * 4) == 0)
return 1;
return 0;
}
/* Add com2 to the end of com1. */
struct community *
community_merge (struct community *com1, struct community *com2)
{
if (com1->val)
com1->val = XREALLOC (MTYPE_COMMUNITY_VAL, com1->val,
(com1->size + com2->size) * 4);
else
com1->val = XMALLOC (MTYPE_COMMUNITY_VAL, (com1->size + com2->size) * 4);
memcpy (com1->val + com1->size, com2->val, com2->size * 4);
com1->size += com2->size;
return com1;
}
/* Community token enum. */
enum community_token
{
community_token_val,
community_token_no_export,
community_token_no_advertise,
community_token_local_as,
community_token_unknown
};
/* Get next community token from string. */
char *
community_gettoken (char *buf, enum community_token *token, u_int32_t *val)
{
char *p = buf;
/* Skip white space. */
while (isspace ((int) *p))
p++;
/* Check the end of the line. */
if (*p == '\0')
return NULL;
/* Well known community string check. */
if (isalpha ((int) *p))
{
if (strncmp (p, "internet", strlen ("internet")) == 0)
{
*val = COMMUNITY_INTERNET;
*token = community_token_no_export;
p += strlen ("internet");
return p;
}
if (strncmp (p, "no-export", strlen ("no-export")) == 0)
{
*val = COMMUNITY_NO_EXPORT;
*token = community_token_no_export;
p += strlen ("no-export");
return p;
}
if (strncmp (p, "no-advertise", strlen ("no-advertise")) == 0)
{
*val = COMMUNITY_NO_ADVERTISE;
*token = community_token_no_advertise;
p += strlen ("no-advertise");
return p;
}
if (strncmp (p, "local-AS", strlen ("local-AS")) == 0)
{
*val = COMMUNITY_LOCAL_AS;
*token = community_token_local_as;
p += strlen ("local-AS");
return p;
}
/* Unknown string. */
*token = community_token_unknown;
return p;
}
/* Community value. */
if (isdigit ((int) *p))
{
int separator = 0;
int digit = 0;
u_int32_t community_low = 0;
u_int32_t community_high = 0;
while (isdigit ((int) *p) || *p == ':')
{
if (*p == ':')
{
if (separator)
{
*token = community_token_unknown;
return p;
}
else
{
separator = 1;
digit = 0;
community_high = community_low << 16;
community_low = 0;
}
}
else
{
digit = 1;
community_low *= 10;
community_low += (*p - '0');
}
p++;
}
if (! digit)
{
*token = community_token_unknown;
return p;
}
*val = community_high + community_low;
*token = community_token_val;
return p;
}
*token = community_token_unknown;
return p;
}
/* convert string to community structure */
struct community *
community_str2com (char *str)
{
struct community *com = NULL;
struct community *com_sort = NULL;
u_int32_t val;
enum community_token token;
while ((str = community_gettoken (str, &token, &val)))
{
switch (token)
{
case community_token_val:
case community_token_no_export:
case community_token_no_advertise:
case community_token_local_as:
if (com == NULL)
com = community_new();
community_add_val (com, val);
break;
case community_token_unknown:
default:
if (com)
community_free (com);
return NULL;
break;
}
}
if (! com)
return NULL;
com_sort = community_uniq_sort (com);
community_free (com);
return com_sort;
}
/* Return communities hash entry count. */
unsigned long
community_count ()
{
return comhash->count;
}
/* Return communities hash. */
struct hash *
community_hash ()
{
return comhash;
}
/* Initialize comminity related hash. */
void
community_init ()
{
comhash = hash_create (community_hash_make, community_cmp);
}

68
bgpd/bgp_community.h Normal file
View File

@ -0,0 +1,68 @@
/* Community attribute related functions.
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. */
/* Communities attribute. */
struct community
{
/* Reference count of communities value. */
unsigned long refcnt;
/* Communities value size. */
int size;
/* Communities value. */
u_int32_t *val;
/* String of community attribute. This sring is used by vty output
and expanded community-list for regular expression match. */
char *str;
};
/* Well-known communities value. */
#define COMMUNITY_INTERNET 0x0
#define COMMUNITY_NO_EXPORT 0xFFFFFF01
#define COMMUNITY_NO_ADVERTISE 0xFFFFFF02
#define COMMUNITY_NO_EXPORT_SUBCONFED 0xFFFFFF03
#define COMMUNITY_LOCAL_AS 0xFFFFFF03
/* Macros of community attribute. */
#define com_length(X) ((X)->size * 4)
#define com_lastval(X) ((X)->val + (X)->size - 1)
#define com_nthval(X,n) ((X)->val + (n))
/* Prototypes of communities attribute functions. */
void community_init ();
void community_free (struct community *);
struct community *community_uniq_sort (struct community *);
struct community *community_parse (char *, u_short);
struct community *community_intern (struct community *);
void community_unintern (struct community *);
char *community_str (struct community *);
unsigned int community_hash_make (struct community *);
struct community *community_str2com (char *);
int community_match (struct community *, struct community *);
int community_cmp (struct community *, struct community *);
struct community *community_merge (struct community *, struct community *);
struct community *community_delete (struct community *, struct community *);
struct community *community_dup (struct community *);
int community_include (struct community *, u_int32_t);
void community_del_val (struct community *, u_int32_t *);
unsigned long community_count ();
struct hash *community_hash ();

648
bgpd/bgp_damp.c Normal file
View File

@ -0,0 +1,648 @@
/* BGP flap dampening
Copyright (C) 2001 IP Infusion Inc.
This file is part of GNU Zebra.
GNU Zebra is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
GNU Zebra is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Zebra; see the file COPYING. If not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
#include <zebra.h>
#include <math.h>
#include "prefix.h"
#include "memory.h"
#include "command.h"
#include "log.h"
#include "thread.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_damp.h"
#include "bgpd/bgp_table.h"
#include "bgpd/bgp_route.h"
#include "bgpd/bgp_attr.h"
#include "bgpd/bgp_advertise.h"
/* Global variable to access damping configuration */
struct bgp_damp_config bgp_damp_cfg;
struct bgp_damp_config *damp = &bgp_damp_cfg;
/* Utility macro to add and delete BGP dampening information to no
used list. */
#define BGP_DAMP_LIST_ADD(N,A) BGP_INFO_ADD(N,A,no_reuse_list)
#define BGP_DAMP_LIST_DEL(N,A) BGP_INFO_DEL(N,A,no_reuse_list)
/* Calculate reuse list index by penalty value. */
static int
bgp_reuse_index (int penalty)
{
int i;
int index;
i = (int)(((double) penalty / damp->reuse_limit - 1.0) * damp->scale_factor);
if ( i >= damp->reuse_index_size )
i = damp->reuse_index_size - 1;
index = damp->reuse_index[i] - damp->reuse_index[0];
return (damp->reuse_offset + index) % damp->reuse_list_size;
}
/* Add BGP dampening information to reuse list. */
static void
bgp_reuse_list_add (struct bgp_damp_info *bdi)
{
int index;
index = bdi->index = bgp_reuse_index (bdi->penalty);
bdi->prev = NULL;
bdi->next = damp->reuse_list[index];
if (damp->reuse_list[index])
damp->reuse_list[index]->prev = bdi;
damp->reuse_list[index] = bdi;
}
/* Delete BGP dampening information from reuse list. */
static void
bgp_reuse_list_delete (struct bgp_damp_info *bdi)
{
if (bdi->next)
bdi->next->prev = bdi->prev;
if (bdi->prev)
bdi->prev->next = bdi->next;
else
damp->reuse_list[bdi->index] = bdi->next;
}
/* Return decayed penalty value. */
int
bgp_damp_decay (time_t tdiff, int penalty)
{
int i;
i = (int) ((double) tdiff / DELTA_T);
if (i == 0)
return penalty;
if (i >= damp->decay_array_size)
return 0;
return (int) (penalty * damp->decay_array[i]);
}
/* Handler of reuse timer event. Each route in the current reuse-list
is evaluated. RFC2439 Section 4.8.7. */
int
bgp_reuse_timer (struct thread *t)
{
struct bgp_damp_info *bdi;
struct bgp_damp_info *next;
time_t t_now, t_diff;
struct bgp *bgp;
int bgp_process (struct bgp *, struct bgp_node *, afi_t, safi_t);
damp->t_reuse = NULL;
damp->t_reuse =
thread_add_timer (master, bgp_reuse_timer, NULL, DELTA_REUSE);
bgp = bgp_get_default ();
if (! bgp)
return 0;
t_now = time (NULL);
/* 1. save a pointer to the current zeroth queue head and zero the
list head entry. */
bdi = damp->reuse_list[damp->reuse_offset];
damp->reuse_list[damp->reuse_offset] = NULL;
/* 2. set offset = modulo reuse-list-size ( offset + 1 ), thereby
rotating the circular queue of list-heads. */
damp->reuse_offset = (damp->reuse_offset + 1) % damp->reuse_list_size;
/* 3. if ( the saved list head pointer is non-empty ) */
for (; bdi; bdi = next)
{
next = bdi->next;
/* Set t-diff = t-now - t-updated. */
t_diff = t_now - bdi->t_updated;
/* Set figure-of-merit = figure-of-merit * decay-array-ok [t-diff] */
bdi->penalty = bgp_damp_decay (t_diff, bdi->penalty);
/* Set t-updated = t-now. */
bdi->t_updated = t_now;
/* if (figure-of-merit < reuse). */
if (bdi->penalty < damp->reuse_limit)
{
/* Reuse the route. */
UNSET_FLAG (bdi->binfo->flags, BGP_INFO_DAMPED);
bdi->suppress_time = 0;
if (bdi->lastrecord == BGP_RECORD_UPDATE)
{
UNSET_FLAG (bdi->binfo->flags, BGP_INFO_HISTORY);
bgp_aggregate_increment (bgp, &bdi->rn->p, bdi->binfo,
bdi->afi, bdi->safi);
bgp_process (bgp, bdi->rn, bdi->afi, bdi->safi);
}
if (bdi->penalty <= damp->reuse_limit / 2.0)
bgp_damp_info_free (bdi, 1);
else
BGP_DAMP_LIST_ADD (damp, bdi);
}
else
/* Re-insert into another list (See RFC2439 Section 4.8.6). */
bgp_reuse_list_add (bdi);
}
return 0;
}
/* A route becomes unreachable (RFC2439 Section 4.8.2). */
int
bgp_damp_withdraw (struct bgp_info *binfo, struct bgp_node *rn,
afi_t afi, safi_t safi, int attr_change)
{
time_t t_now;
struct bgp_damp_info *bdi;
double last_penalty = 0;
t_now = time (NULL);
/* Processing Unreachable Messages. */
bdi = binfo->damp_info;
if (bdi == NULL)
{
/* If there is no previous stability history. */
/* RFC2439 said:
1. allocate a damping structure.
2. set figure-of-merit = 1.
3. withdraw the route. */
bdi = XCALLOC (MTYPE_BGP_DAMP_INFO, sizeof (struct bgp_damp_info));
bdi->binfo = binfo;
bdi->rn = rn;
bdi->penalty = (attr_change ? DEFAULT_PENALTY / 2 : DEFAULT_PENALTY);
bdi->flap = 1;
bdi->start_time = t_now;
bdi->suppress_time = 0;
bdi->index = -1;
bdi->afi = afi;
bdi->safi = safi;
binfo->damp_info = bdi;
BGP_DAMP_LIST_ADD (damp, bdi);
}
else
{
last_penalty = bdi->penalty;
/* 1. Set t-diff = t-now - t-updated. */
bdi->penalty =
(bgp_damp_decay (t_now - bdi->t_updated, bdi->penalty)
+ (attr_change ? DEFAULT_PENALTY / 2 : DEFAULT_PENALTY));
if (bdi->penalty > damp->ceiling)
bdi->penalty = damp->ceiling;
bdi->flap++;
}
bdi->lastrecord = BGP_RECORD_WITHDRAW;
bdi->t_updated = t_now;
/* Make this route as historical status. */
SET_FLAG (binfo->flags, BGP_INFO_HISTORY);
/* Remove the route from a reuse list if it is on one. */
if (CHECK_FLAG (bdi->binfo->flags, BGP_INFO_DAMPED))
{
/* If decay rate isn't equal to 0, reinsert brn. */
if (bdi->penalty != last_penalty)
{
bgp_reuse_list_delete (bdi);
bgp_reuse_list_add (bdi);
}
return BGP_DAMP_SUPPRESSED;
}
/* If not suppressed before, do annonunce this withdraw and
insert into reuse_list. */
if (bdi->penalty >= damp->suppress_value)
{
SET_FLAG (bdi->binfo->flags, BGP_INFO_DAMPED);
bdi->suppress_time = t_now;
BGP_DAMP_LIST_DEL (damp, bdi);
bgp_reuse_list_add (bdi);
}
return BGP_DAMP_USED;
}
int
bgp_damp_update (struct bgp_info *binfo, struct bgp_node *rn,
afi_t afi, safi_t safi)
{
time_t t_now;
struct bgp_damp_info *bdi;
int status;
bdi = binfo->damp_info;
if (! bdi)
return BGP_DAMP_USED;
t_now = time (NULL);
UNSET_FLAG (binfo->flags, BGP_INFO_HISTORY);
bdi->lastrecord = BGP_RECORD_UPDATE;
bdi->penalty = bgp_damp_decay (t_now - bdi->t_updated, bdi->penalty);
if (! CHECK_FLAG (bdi->binfo->flags, BGP_INFO_DAMPED)
&& (bdi->penalty < damp->suppress_value))
status = BGP_DAMP_USED;
else if (CHECK_FLAG (bdi->binfo->flags, BGP_INFO_DAMPED)
&& (bdi->penalty < damp->reuse_limit) )
{
UNSET_FLAG (bdi->binfo->flags, BGP_INFO_DAMPED);
bgp_reuse_list_delete (bdi);
BGP_DAMP_LIST_ADD (damp, bdi);
bdi->suppress_time = 0;
status = BGP_DAMP_USED;
}
else
status = BGP_DAMP_SUPPRESSED;
if (bdi->penalty > damp->reuse_limit / 2.0)
bdi->t_updated = t_now;
else
bgp_damp_info_free (bdi, 0);
return status;
}
/* Remove dampening information and history route. */
int
bgp_damp_scan (struct bgp_info *binfo, afi_t afi, safi_t safi)
{
time_t t_now, t_diff;
struct bgp_damp_info *bdi;
t_now = time (NULL);
bdi = binfo->damp_info;
if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED))
{
t_diff = t_now - bdi->suppress_time;
if (t_diff >= damp->max_suppress_time)
{
UNSET_FLAG (binfo->flags, BGP_INFO_DAMPED);
bgp_reuse_list_delete (bdi);
BGP_DAMP_LIST_ADD (damp, bdi);
bdi->penalty = damp->reuse_limit;
bdi->suppress_time = 0;
bdi->t_updated = t_now;
/* Need to announce UPDATE once this binfo is usable again. */
if (bdi->lastrecord == BGP_RECORD_UPDATE)
return 1;
else
return 0;
}
}
else
{
t_diff = t_now - bdi->t_updated;
bdi->penalty = bgp_damp_decay (t_diff, bdi->penalty);
if (bdi->penalty <= damp->reuse_limit / 2.0)
{
/* release the bdi, bdi->binfo. */
bgp_damp_info_free (bdi, 1);
return 0;
}
else
bdi->t_updated = t_now;
}
return 0;
}
void
bgp_damp_info_free (struct bgp_damp_info *bdi, int withdraw)
{
struct bgp_info *binfo;
void bgp_info_delete (struct bgp_node *, struct bgp_info *);
void bgp_info_free (struct bgp_info *);
if (! bdi)
return;
binfo = bdi->binfo;
binfo->damp_info = NULL;
if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED))
bgp_reuse_list_delete (bdi);
else
BGP_DAMP_LIST_DEL (damp, bdi);
UNSET_FLAG (binfo->flags, BGP_INFO_DAMPED);
UNSET_FLAG (binfo->flags, BGP_INFO_HISTORY);
if (bdi->lastrecord == BGP_RECORD_WITHDRAW && withdraw)
{
bgp_info_delete (bdi->rn, binfo);
bgp_info_free (binfo);
bgp_unlock_node (bdi->rn);
}
XFREE (MTYPE_BGP_DAMP_INFO, bdi);
}
void
bgp_damp_parameter_set (int hlife, int reuse, int sup, int maxsup)
{
double reuse_max_ratio;
int i;
double j;
damp->suppress_value = sup;
damp->half_life = hlife;
damp->reuse_limit = reuse;
damp->max_suppress_time = maxsup;
/* Initialize params per bgp_damp_config. */
damp->reuse_index_size = REUSE_ARRAY_SIZE;
damp->ceiling = (int)(damp->reuse_limit * (pow(2, (double)damp->max_suppress_time/damp->half_life)));
/* Decay-array computations */
damp->decay_array_size = ceil ((double) damp->max_suppress_time / DELTA_T);
damp->decay_array = XMALLOC (MTYPE_BGP_DAMP_ARRAY,
sizeof(double) * (damp->decay_array_size));
damp->decay_array[0] = 1.0;
damp->decay_array[1] = exp ((1.0/((double)damp->half_life/DELTA_T)) * log(0.5));
/* Calculate decay values for all possible times */
for (i = 2; i < damp->decay_array_size; i++)
damp->decay_array[i] = damp->decay_array[i-1] * damp->decay_array[1];
/* Reuse-list computations */
i = ceil ((double)damp->max_suppress_time / DELTA_REUSE) + 1;
if (i > REUSE_LIST_SIZE || i == 0)
i = REUSE_LIST_SIZE;
damp->reuse_list_size = i;
damp->reuse_list = XCALLOC (MTYPE_BGP_DAMP_ARRAY,
damp->reuse_list_size
* sizeof (struct bgp_reuse_node *));
memset (damp->reuse_list, 0x00,
damp->reuse_list_size * sizeof (struct bgp_reuse_node *));
/* Reuse-array computations */
damp->reuse_index = XMALLOC (MTYPE_BGP_DAMP_ARRAY,
sizeof(int) * damp->reuse_index_size);
memset (damp->reuse_index, 0x00,
damp->reuse_list_size * sizeof (int));
reuse_max_ratio = (double)damp->ceiling/damp->reuse_limit;
j = (exp((double)damp->max_suppress_time/damp->half_life) * log10(2.0));
if ( reuse_max_ratio > j && j != 0 )
reuse_max_ratio = j;
damp->scale_factor = (double)damp->reuse_index_size/(reuse_max_ratio - 1);
for (i = 0; i < damp->reuse_index_size; i++)
{
damp->reuse_index[i] =
(int)(((double)damp->half_life / DELTA_REUSE)
* log10 (1.0 / (damp->reuse_limit * ( 1.0 + ((double)i/damp->scale_factor)))) / log10(0.5));
}
}
int
bgp_damp_enable (struct bgp *bgp, afi_t afi, safi_t safi, int half,
int reuse, int suppress, int max)
{
if (CHECK_FLAG (bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING))
{
if (damp->half_life == half
&& damp->reuse_limit == reuse
&& damp->suppress_value == suppress
&& damp->max_suppress_time == max)
return 0;
bgp_damp_disable (bgp, afi, safi);
}
SET_FLAG (bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING);
bgp_damp_parameter_set (half, reuse, suppress, max);
/* Register reuse timer. */
if (! damp->t_reuse)
damp->t_reuse =
thread_add_timer (master, bgp_reuse_timer, NULL, DELTA_REUSE);
return 0;
}
void
bgp_damp_config_clean (struct bgp_damp_config *damp)
{
/* Free decay array */
XFREE (MTYPE_BGP_DAMP_ARRAY, damp->decay_array);
/* Free reuse index array */
XFREE (MTYPE_BGP_DAMP_ARRAY, damp->reuse_index);
/* Free reuse list array. */
XFREE (MTYPE_BGP_DAMP_ARRAY, damp->reuse_list);
}
/* Clean all the bgp_damp_info stored in reuse_list. */
void
bgp_damp_info_clean ()
{
int i;
struct bgp_damp_info *bdi, *next;
damp->reuse_offset = 0;
for (i = 0; i < damp->reuse_list_size; i++)
{
if (! damp->reuse_list[i])
continue;
for (bdi = damp->reuse_list[i]; bdi; bdi = next)
{
next = bdi->next;
bgp_damp_info_free (bdi, 1);
}
damp->reuse_list[i] = NULL;
}
for (bdi = damp->no_reuse_list; bdi; bdi = next)
{
next = bdi->next;
bgp_damp_info_free (bdi, 1);
}
damp->no_reuse_list = NULL;
}
int
bgp_damp_disable (struct bgp *bgp, afi_t afi, safi_t safi)
{
/* Cancel reuse thread. */
if (damp->t_reuse )
thread_cancel (damp->t_reuse);
damp->t_reuse = NULL;
/* Clean BGP dampening information. */
bgp_damp_info_clean ();
/* Clear configuration */
bgp_damp_config_clean (&bgp_damp_cfg);
UNSET_FLAG (bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING);
return 0;
}
int
bgp_config_write_damp (struct vty *vty)
{
if (&bgp_damp_cfg)
{
if (bgp_damp_cfg.half_life == DEFAULT_HALF_LIFE*60
&& bgp_damp_cfg.reuse_limit == DEFAULT_REUSE
&& bgp_damp_cfg.suppress_value == DEFAULT_SUPPRESS
&& bgp_damp_cfg.max_suppress_time == bgp_damp_cfg.half_life*4)
vty_out (vty, " bgp dampening%s", VTY_NEWLINE);
else if (bgp_damp_cfg.half_life != DEFAULT_HALF_LIFE*60
&& bgp_damp_cfg.reuse_limit == DEFAULT_REUSE
&& bgp_damp_cfg.suppress_value == DEFAULT_SUPPRESS
&& bgp_damp_cfg.max_suppress_time == bgp_damp_cfg.half_life*4)
vty_out (vty, " bgp dampening %d%s",
bgp_damp_cfg.half_life/60,
VTY_NEWLINE);
else
vty_out (vty, " bgp dampening %d %d %d %d%s",
bgp_damp_cfg.half_life/60,
bgp_damp_cfg.reuse_limit,
bgp_damp_cfg.suppress_value,
bgp_damp_cfg.max_suppress_time/60,
VTY_NEWLINE);
return 1;
}
return 0;
}
#define BGP_UPTIME_LEN 25
char *
bgp_get_reuse_time (int penalty, char *buf, size_t len)
{
time_t reuse_time = 0;
struct tm *tm = NULL;
if (penalty > damp->reuse_limit)
{
reuse_time = (int) (DELTA_T * ((log((double)damp->reuse_limit/penalty))/(log(damp->decay_array[1]))));
if (reuse_time > damp->max_suppress_time)
reuse_time = damp->max_suppress_time;
tm = gmtime (&reuse_time);
}
else
reuse_time = 0;
/* Making formatted timer strings. */
#define ONE_DAY_SECOND 60*60*24
#define ONE_WEEK_SECOND 60*60*24*7
if (reuse_time == 0)
snprintf (buf, len, "00:00:00");
else if (reuse_time < ONE_DAY_SECOND)
snprintf (buf, len, "%02d:%02d:%02d",
tm->tm_hour, tm->tm_min, tm->tm_sec);
else if (reuse_time < ONE_WEEK_SECOND)
snprintf (buf, len, "%dd%02dh%02dm",
tm->tm_yday, tm->tm_hour, tm->tm_min);
else
snprintf (buf, len, "%02dw%dd%02dh",
tm->tm_yday/7, tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
return buf;
}
void
bgp_damp_info_vty (struct vty *vty, struct bgp_info *binfo)
{
struct bgp_damp_info *bdi;
time_t t_now, t_diff;
char timebuf[BGP_UPTIME_LEN];
int penalty;
/* BGP dampening information. */
bdi = binfo->damp_info;
/* If dampening is not enabled or there is no dampening information,
return immediately. */
if (! damp || ! bdi)
return;
/* Calculate new penalty. */
t_now = time (NULL);
t_diff = t_now - bdi->t_updated;
penalty = bgp_damp_decay (t_diff, bdi->penalty);
vty_out (vty, " Dampinfo: penalty %d, flapped %d times in %s",
penalty, bdi->flap,
peer_uptime (bdi->start_time, timebuf, BGP_UPTIME_LEN));
if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED)
&& ! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
vty_out (vty, ", reuse in %s",
bgp_get_reuse_time (penalty, timebuf, BGP_UPTIME_LEN));
vty_out (vty, "%s", VTY_NEWLINE);
}
char *
bgp_damp_reuse_time_vty (struct vty *vty, struct bgp_info *binfo)
{
struct bgp_damp_info *bdi;
time_t t_now, t_diff;
char timebuf[BGP_UPTIME_LEN];
int penalty;
/* BGP dampening information. */
bdi = binfo->damp_info;
/* If dampening is not enabled or there is no dampening information,
return immediately. */
if (! damp || ! bdi)
return NULL;
/* Calculate new penalty. */
t_now = time (NULL);
t_diff = t_now - bdi->t_updated;
penalty = bgp_damp_decay (t_diff, bdi->penalty);
return bgp_get_reuse_time (penalty, timebuf, BGP_UPTIME_LEN);
}

141
bgpd/bgp_damp.h Normal file
View File

@ -0,0 +1,141 @@
/* BGP flap dampening
Copyright (C) 2001 IP Infusion Inc.
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. */
/* Structure maintained on a per-route basis. */
struct bgp_damp_info
{
/* Doubly linked list. This information must be linked to
reuse_list or no_reuse_list. */
struct bgp_damp_info *next;
struct bgp_damp_info *prev;
/* Figure-of-merit. */
int penalty;
/* Number of flapping. */
int flap;
/* First flap time */
time_t start_time;
/* Last time penalty was updated. */
time_t t_updated;
/* Time of route start to be suppressed. */
time_t suppress_time;
/* Back reference to bgp_info. */
struct bgp_info *binfo;
/* Back reference to bgp_node. */
struct bgp_node *rn;
/* Current index in the reuse_list. */
int index;
/* Last time message type. */
u_char lastrecord;
#define BGP_RECORD_UPDATE 1
#define BGP_RECORD_WITHDRAW 2
afi_t afi;
safi_t safi;
};
/* Specified parameter set configuration. */
struct bgp_damp_config
{
/* Value over which routes suppressed. */
int suppress_value;
/* Value below which suppressed routes reused. */
int reuse_limit;
/* Max time a route can be suppressed. */
int max_suppress_time;
/* Time during which accumulated penalty reduces by half. */
int half_life;
/* Non-configurable parameters but fixed at implementation time.
* To change this values, init_bgp_damp() should be modified.
*/
int tmax; /* Max time previous instability retained */
int reuse_list_size; /* Number of reuse lists */
int reuse_index_size; /* Size of reuse index array */
/* Non-configurable parameters. Most of these are calculated from
* the configurable parameters above.
*/
unsigned int ceiling; /* Max value a penalty can attain */
int decay_rate_per_tick; /* Calculated from half-life */
int decay_array_size; /* Calculated using config parameters */
double scale_factor;
int reuse_scale_factor;
/* Decay array per-set based. */
double *decay_array;
/* Reuse index array per-set based. */
int *reuse_index;
/* Reuse list array per-set based. */
struct bgp_damp_info **reuse_list;
int reuse_offset;
/* All dampening information which is not on reuse list. */
struct bgp_damp_info *no_reuse_list;
/* Reuse timer thread per-set base. */
struct thread* t_reuse;
};
#define BGP_DAMP_NONE 0
#define BGP_DAMP_USED 1
#define BGP_DAMP_SUPPRESSED 2
/* Time granularity for reuse lists */
#define DELTA_REUSE 10
/* Time granularity for decay arrays */
#define DELTA_T 5
#define DEFAULT_PENALTY 1000
#define DEFAULT_HALF_LIFE 15
#define DEFAULT_REUSE 750
#define DEFAULT_SUPPRESS 2000
#define REUSE_LIST_SIZE 256
#define REUSE_ARRAY_SIZE 1024
int bgp_damp_enable (struct bgp *, afi_t, safi_t, int, int, int, int);
int bgp_damp_disable (struct bgp *, afi_t, safi_t);
int bgp_damp_withdraw (struct bgp_info *, struct bgp_node *,
afi_t, safi_t, int);
int bgp_damp_update (struct bgp_info *, struct bgp_node *, afi_t, safi_t);
int bgp_damp_scan (struct bgp_info *, afi_t, safi_t);
void bgp_damp_info_free (struct bgp_damp_info *, int);
void bgp_damp_info_clean ();
char * bgp_get_reuse_time (int, char*, size_t);
int bgp_damp_decay (time_t, int);
int bgp_config_write_damp (struct vty *);
void bgp_damp_info_vty (struct vty *, struct bgp_info *);
char * bgp_damp_reuse_time_vty (struct vty *, struct bgp_info *);

732
bgpd/bgp_debug.c Normal file
View File

@ -0,0 +1,732 @@
/* BGP-4, BGP-4+ packet debug routine
Copyright (C) 1996, 97, 99 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 "version.h"
#include "prefix.h"
#include "linklist.h"
#include "stream.h"
#include "command.h"
#include "str.h"
#include "log.h"
#include "sockunion.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_aspath.h"
#include "bgpd/bgp_route.h"
#include "bgpd/bgp_attr.h"
#include "bgpd/bgp_debug.h"
#include "bgpd/bgp_community.h"
unsigned long conf_bgp_debug_fsm;
unsigned long conf_bgp_debug_events;
unsigned long conf_bgp_debug_packet;
unsigned long conf_bgp_debug_filter;
unsigned long conf_bgp_debug_keepalive;
unsigned long conf_bgp_debug_update;
unsigned long conf_bgp_debug_normal;
unsigned long term_bgp_debug_fsm;
unsigned long term_bgp_debug_events;
unsigned long term_bgp_debug_packet;
unsigned long term_bgp_debug_filter;
unsigned long term_bgp_debug_keepalive;
unsigned long term_bgp_debug_update;
unsigned long term_bgp_debug_normal;
/* messages for BGP-4 status */
struct message bgp_status_msg[] =
{
{ 0, "null" },
{ Idle, "Idle" },
{ Connect, "Connect" },
{ Active, "Active" },
{ OpenSent, "OpenSent" },
{ OpenConfirm, "OpenConfirm" },
{ Established, "Established" },
};
int bgp_status_msg_max = BGP_STATUS_MAX;
/* BGP message type string. */
char *bgp_type_str[] =
{
NULL,
"OPEN",
"UPDATE",
"NOTIFICATION",
"KEEPALIVE",
"ROUTE-REFRESH",
"CAPABILITY"
};
/* message for BGP-4 Notify */
struct message bgp_notify_msg[] =
{
{ 0, "" },
{ BGP_NOTIFY_HEADER_ERR, "Message Header Error"},
{ BGP_NOTIFY_OPEN_ERR, "OPEN Message Error"},
{ BGP_NOTIFY_UPDATE_ERR, "UPDATE Message Error"},
{ BGP_NOTIFY_HOLD_ERR, "Hold Timer Expired"},
{ BGP_NOTIFY_FSM_ERR, "Finite State Machine Error"},
{ BGP_NOTIFY_CEASE, "Cease"},
{ BGP_NOTIFY_CAPABILITY_ERR, "CAPABILITY Message Error"},
};
int bgp_notify_msg_max = BGP_NOTIFY_MAX;
struct message bgp_notify_head_msg[] =
{
{ 0, "null"},
{ BGP_NOTIFY_HEADER_NOT_SYNC, "/Connection Not Synchronized."},
{ BGP_NOTIFY_HEADER_BAD_MESLEN, "/Bad Message Length."},
{ BGP_NOTIFY_HEADER_BAD_MESTYPE, "/Bad Message Type."}
};
int bgp_notify_head_msg_max = BGP_NOTIFY_HEADER_MAX;
struct message bgp_notify_open_msg[] =
{
{ 0, "null" },
{ BGP_NOTIFY_OPEN_UNSUP_VERSION, "/Unsupported Version Number." },
{ BGP_NOTIFY_OPEN_BAD_PEER_AS, "/Bad Peer AS."},
{ BGP_NOTIFY_OPEN_BAD_BGP_IDENT, "/Bad BGP Identifier."},
{ BGP_NOTIFY_OPEN_UNSUP_PARAM, "/Unsupported Optional Parameter."},
{ BGP_NOTIFY_OPEN_AUTH_FAILURE, "/Authentication Failure."},
{ BGP_NOTIFY_OPEN_UNACEP_HOLDTIME, "/Unacceptable Hold Time."},
{ BGP_NOTIFY_OPEN_UNSUP_CAPBL, "/Unsupported Capability."},
};
int bgp_notify_open_msg_max = BGP_NOTIFY_OPEN_MAX;
struct message bgp_notify_update_msg[] =
{
{ 0, "null"},
{ BGP_NOTIFY_UPDATE_MAL_ATTR, "/Malformed Attribute List."},
{ BGP_NOTIFY_UPDATE_UNREC_ATTR, "/Unrecognized Well-known Attribute."},
{ BGP_NOTIFY_UPDATE_MISS_ATTR, "/Missing Well-known Attribute."},
{ BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, "/Attribute Flags Error."},
{ BGP_NOTIFY_UPDATE_ATTR_LENG_ERR, "/Attribute Length Error."},
{ BGP_NOTIFY_UPDATE_INVAL_ORIGIN, "/Invalid ORIGIN Attribute."},
{ BGP_NOTIFY_UPDATE_AS_ROUTE_LOOP, "/AS Routing Loop."},
{ BGP_NOTIFY_UPDATE_INVAL_NEXT_HOP, "/Invalid NEXT_HOP Attribute."},
{ BGP_NOTIFY_UPDATE_OPT_ATTR_ERR, "/Optional Attribute Error."},
{ BGP_NOTIFY_UPDATE_INVAL_NETWORK, "/Invalid Network Field."},
{ BGP_NOTIFY_UPDATE_MAL_AS_PATH, "/Malformed AS_PATH."},
};
int bgp_notify_update_msg_max = BGP_NOTIFY_UPDATE_MAX;
struct message bgp_notify_cease_msg[] =
{
{ 0, ""},
{ BGP_NOTIFY_CEASE_MAX_PREFIX, "/Maximum Number of Prefixes Reached."},
{ BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN, "/Administratively Shutdown."},
{ BGP_NOTIFY_CEASE_PEER_UNCONFIG, "/Peer Unconfigured."},
{ BGP_NOTIFY_CEASE_ADMIN_RESET, "/Administratively Reset."},
{ BGP_NOTIFY_CEASE_CONNECT_REJECT, "/Connection Rejected."},
{ BGP_NOTIFY_CEASE_CONFIG_CHANGE, "/Other Configuration Change."},
};
int bgp_notify_cease_msg_max = BGP_NOTIFY_CEASE_MAX;
struct message bgp_notify_capability_msg[] =
{
{ 0, "null" },
{ BGP_NOTIFY_CAPABILITY_INVALID_ACTION, "/Invalid Action Value." },
{ BGP_NOTIFY_CAPABILITY_INVALID_LENGTH, "/Invalid Capability Length."},
{ BGP_NOTIFY_CAPABILITY_MALFORMED_CODE, "/Malformed Capability Value."},
};
int bgp_notify_capability_msg_max = BGP_NOTIFY_CAPABILITY_MAX;
/* Origin strings. */
char *bgp_origin_str[] = {"i","e","?"};
char *bgp_origin_long_str[] = {"IGP","EGP","incomplete"};
/* Dump attribute. */
void
bgp_dump_attr (struct peer *peer, struct attr *attr, char *buf, size_t size)
{
if (! attr)
return;
snprintf (buf, size, "nexthop %s", inet_ntoa (attr->nexthop));
snprintf (buf + strlen (buf), size - strlen (buf), ", origin %s",
bgp_origin_str[attr->origin]);
#ifdef HAVE_IPV6
{
char addrbuf[BUFSIZ];
/* Add MP case. */
if (attr->mp_nexthop_len == 16 || attr->mp_nexthop_len == 32)
snprintf (buf + strlen (buf), size - strlen (buf), ", mp_nexthop %s",
inet_ntop (AF_INET6, &attr->mp_nexthop_global,
addrbuf, BUFSIZ));
if (attr->mp_nexthop_len == 32)
snprintf (buf + strlen (buf), size - strlen (buf), "(%s)",
inet_ntop (AF_INET6, &attr->mp_nexthop_local,
addrbuf, BUFSIZ));
}
#endif /* HAVE_IPV6 */
if (peer_sort (peer) == BGP_PEER_IBGP)
snprintf (buf + strlen (buf), size - strlen (buf), ", localpref %d",
attr->local_pref);
if (attr->med)
snprintf (buf + strlen (buf), size - strlen (buf), ", metric %d",
attr->med);
if (attr->community)
snprintf (buf + strlen (buf), size - strlen (buf), ", community %s",
community_str (attr->community));
if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
snprintf (buf + strlen (buf), size - strlen (buf), ", atomic-aggregate");
if (attr->aggregator_as)
snprintf (buf + strlen (buf), size - strlen (buf), ", aggregated by %d %s",
attr->aggregator_as, inet_ntoa (attr->aggregator_addr));
if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID))
snprintf (buf + strlen (buf), size - strlen (buf), ", originator %s",
inet_ntoa (attr->originator_id));
if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_CLUSTER_LIST))
{
int i;
snprintf (buf + strlen (buf), size - strlen (buf), ", clusterlist ");
for (i = 0; i < attr->cluster->length / 4; i++)
snprintf (buf + strlen (buf), size - strlen (buf), "%s",
inet_ntoa (attr->cluster->list[i]));
}
if (attr->aspath)
snprintf (buf + strlen (buf), size - strlen (buf), ", path %s",
aspath_print (attr->aspath));
}
/* dump notify packet */
void
bgp_notify_print(struct peer *peer, struct bgp_notify *bgp_notify, char *direct)
{
char *subcode_str;
subcode_str = "";
switch (bgp_notify->code)
{
case BGP_NOTIFY_HEADER_ERR:
subcode_str = LOOKUP (bgp_notify_head_msg, bgp_notify->subcode);
break;
case BGP_NOTIFY_OPEN_ERR:
subcode_str = LOOKUP (bgp_notify_open_msg, bgp_notify->subcode);
break;
case BGP_NOTIFY_UPDATE_ERR:
subcode_str = LOOKUP (bgp_notify_update_msg, bgp_notify->subcode);
break;
case BGP_NOTIFY_HOLD_ERR:
subcode_str = "";
break;
case BGP_NOTIFY_FSM_ERR:
subcode_str = "";
break;
case BGP_NOTIFY_CEASE:
subcode_str = LOOKUP (bgp_notify_cease_msg, bgp_notify->subcode);
break;
case BGP_NOTIFY_CAPABILITY_ERR:
subcode_str = LOOKUP (bgp_notify_capability_msg, bgp_notify->subcode);
break;
}
if (BGP_DEBUG (normal, NORMAL))
plog_info (peer->log, "%s %s NOTIFICATION %d/%d (%s%s) %d bytes %s",
peer ? peer->host : "",
direct, bgp_notify->code, bgp_notify->subcode,
LOOKUP (bgp_notify_msg, bgp_notify->code),
subcode_str, bgp_notify->length,
bgp_notify->data ? bgp_notify->data : "");
}
/* Debug option setting interface. */
unsigned long bgp_debug_option = 0;
int
debug (unsigned int option)
{
return bgp_debug_option & option;
}
DEFUN (debug_bgp_fsm,
debug_bgp_fsm_cmd,
"debug bgp fsm",
DEBUG_STR
BGP_STR
"BGP Finite State Machine\n")
{
if (vty->node == CONFIG_NODE)
DEBUG_ON (fsm, FSM);
else
{
TERM_DEBUG_ON (fsm, FSM);
vty_out (vty, "BGP fsm debugging is on%s", VTY_NEWLINE);
}
return CMD_SUCCESS;
}
DEFUN (no_debug_bgp_fsm,
no_debug_bgp_fsm_cmd,
"no debug bgp fsm",
NO_STR
DEBUG_STR
BGP_STR
"Finite State Machine\n")
{
if (vty->node == CONFIG_NODE)
DEBUG_OFF (fsm, FSM);
else
{
TERM_DEBUG_OFF (fsm, FSM);
vty_out (vty, "BGP fsm debugging is off%s", VTY_NEWLINE);
}
return CMD_SUCCESS;
}
ALIAS (no_debug_bgp_fsm,
undebug_bgp_fsm_cmd,
"undebug bgp fsm",
UNDEBUG_STR
DEBUG_STR
BGP_STR
"Finite State Machine\n")
DEFUN (debug_bgp_events,
debug_bgp_events_cmd,
"debug bgp events",
DEBUG_STR
BGP_STR
"BGP events\n")
{
if (vty->node == CONFIG_NODE)
DEBUG_ON (events, EVENTS);
else
{
TERM_DEBUG_ON (events, EVENTS);
vty_out (vty, "BGP events debugging is on%s", VTY_NEWLINE);
}
return CMD_SUCCESS;
}
DEFUN (no_debug_bgp_events,
no_debug_bgp_events_cmd,
"no debug bgp events",
NO_STR
DEBUG_STR
BGP_STR
"BGP events\n")
{
if (vty->node == CONFIG_NODE)
DEBUG_OFF (events, EVENTS);
else
{
TERM_DEBUG_OFF (events, EVENTS);
vty_out (vty, "BGP events debugging is off%s", VTY_NEWLINE);
}
return CMD_SUCCESS;
}
ALIAS (no_debug_bgp_events,
undebug_bgp_events_cmd,
"undebug bgp events",
UNDEBUG_STR
BGP_STR
"BGP events\n")
DEFUN (debug_bgp_filter,
debug_bgp_filter_cmd,
"debug bgp filters",
DEBUG_STR
BGP_STR
"BGP filters\n")
{
if (vty->node == CONFIG_NODE)
DEBUG_ON (filter, FILTER);
else
{
TERM_DEBUG_ON (filter, FILTER);
vty_out (vty, "BGP filters debugging is on%s", VTY_NEWLINE);
}
return CMD_SUCCESS;
}
DEFUN (no_debug_bgp_filter,
no_debug_bgp_filter_cmd,
"no debug bgp filters",
NO_STR
DEBUG_STR
BGP_STR
"BGP filters\n")
{
if (vty->node == CONFIG_NODE)
DEBUG_OFF (filter, FILTER);
else
{
TERM_DEBUG_OFF (filter, FILTER);
vty_out (vty, "BGP filters debugging is off%s", VTY_NEWLINE);
}
return CMD_SUCCESS;
}
ALIAS (no_debug_bgp_filter,
undebug_bgp_filter_cmd,
"undebug bgp filters",
UNDEBUG_STR
BGP_STR
"BGP filters\n")
DEFUN (debug_bgp_keepalive,
debug_bgp_keepalive_cmd,
"debug bgp keepalives",
DEBUG_STR
BGP_STR
"BGP keepalives\n")
{
if (vty->node == CONFIG_NODE)
DEBUG_ON (keepalive, KEEPALIVE);
else
{
TERM_DEBUG_ON (keepalive, KEEPALIVE);
vty_out (vty, "BGP keepalives debugging is on%s", VTY_NEWLINE);
}
return CMD_SUCCESS;
}
DEFUN (no_debug_bgp_keepalive,
no_debug_bgp_keepalive_cmd,
"no debug bgp keepalives",
NO_STR
DEBUG_STR
BGP_STR
"BGP keepalives\n")
{
if (vty->node == CONFIG_NODE)
DEBUG_OFF (keepalive, KEEPALIVE);
else
{
TERM_DEBUG_OFF (keepalive, KEEPALIVE);
vty_out (vty, "BGP keepalives debugging is off%s", VTY_NEWLINE);
}
return CMD_SUCCESS;
}
ALIAS (no_debug_bgp_keepalive,
undebug_bgp_keepalive_cmd,
"undebug bgp keepalives",
UNDEBUG_STR
BGP_STR
"BGP keepalives\n")
DEFUN (debug_bgp_update,
debug_bgp_update_cmd,
"debug bgp updates",
DEBUG_STR
BGP_STR
"BGP updates\n")
{
if (vty->node == CONFIG_NODE)
{
DEBUG_ON (update, UPDATE_IN);
DEBUG_ON (update, UPDATE_OUT);
}
else
{
TERM_DEBUG_ON (update, UPDATE_IN);
TERM_DEBUG_ON (update, UPDATE_OUT);
vty_out (vty, "BGP updates debugging is on%s", VTY_NEWLINE);
}
return CMD_SUCCESS;
}
DEFUN (debug_bgp_update_direct,
debug_bgp_update_direct_cmd,
"debug bgp updates (in|out)",
DEBUG_STR
BGP_STR
"BGP updates\n"
"Inbound updates\n"
"Outbound updates\n")
{
if (vty->node == CONFIG_NODE)
{
if (strncmp ("i", argv[0], 1) == 0)
{
DEBUG_OFF (update, UPDATE_OUT);
DEBUG_ON (update, UPDATE_IN);
}
else
{
DEBUG_OFF (update, UPDATE_IN);
DEBUG_ON (update, UPDATE_OUT);
}
}
else
{
if (strncmp ("i", argv[0], 1) == 0)
{
TERM_DEBUG_OFF (update, UPDATE_OUT);
TERM_DEBUG_ON (update, UPDATE_IN);
vty_out (vty, "BGP updates debugging is on (inbound)%s", VTY_NEWLINE);
}
else
{
TERM_DEBUG_OFF (update, UPDATE_IN);
TERM_DEBUG_ON (update, UPDATE_OUT);
vty_out (vty, "BGP updates debugging is on (outbound)%s", VTY_NEWLINE);
}
}
return CMD_SUCCESS;
}
DEFUN (no_debug_bgp_update,
no_debug_bgp_update_cmd,
"no debug bgp updates",
NO_STR
DEBUG_STR
BGP_STR
"BGP updates\n")
{
if (vty->node == CONFIG_NODE)
{
DEBUG_OFF (update, UPDATE_IN);
DEBUG_OFF (update, UPDATE_OUT);
}
else
{
TERM_DEBUG_OFF (update, UPDATE_IN);
TERM_DEBUG_OFF (update, UPDATE_OUT);
vty_out (vty, "BGP updates debugging is off%s", VTY_NEWLINE);
}
return CMD_SUCCESS;
}
ALIAS (no_debug_bgp_update,
undebug_bgp_update_cmd,
"undebug bgp updates",
UNDEBUG_STR
BGP_STR
"BGP updates\n")
DEFUN (debug_bgp_normal,
debug_bgp_normal_cmd,
"debug bgp",
DEBUG_STR
BGP_STR)
{
if (vty->node == CONFIG_NODE)
DEBUG_ON (normal, NORMAL);
else
{
TERM_DEBUG_ON (normal, NORMAL);
vty_out (vty, "BGP debugging is on%s", VTY_NEWLINE);
}
return CMD_SUCCESS;
}
DEFUN (no_debug_bgp_normal,
no_debug_bgp_normal_cmd,
"no debug bgp",
NO_STR
DEBUG_STR
BGP_STR)
{
if (vty->node == CONFIG_NODE)
DEBUG_OFF (normal, NORMAL);
else
{
TERM_DEBUG_OFF (normal, NORMAL);
vty_out (vty, "BGP debugging is off%s", VTY_NEWLINE);
}
return CMD_SUCCESS;
}
ALIAS (no_debug_bgp_normal,
undebug_bgp_normal_cmd,
"undebug bgp",
UNDEBUG_STR
BGP_STR)
DEFUN (no_debug_bgp_all,
no_debug_bgp_all_cmd,
"no debug all bgp",
NO_STR
DEBUG_STR
"Enable all debugging\n"
BGP_STR)
{
TERM_DEBUG_OFF (normal, NORMAL);
TERM_DEBUG_OFF (events, EVENTS);
TERM_DEBUG_OFF (keepalive, KEEPALIVE);
TERM_DEBUG_OFF (update, UPDATE_IN);
TERM_DEBUG_OFF (update, UPDATE_OUT);
TERM_DEBUG_OFF (fsm, FSM);
TERM_DEBUG_OFF (filter, FILTER);
vty_out (vty, "All possible debugging has been turned off%s", VTY_NEWLINE);
return CMD_SUCCESS;
}
ALIAS (no_debug_bgp_all,
undebug_bgp_all_cmd,
"undebug all bgp",
UNDEBUG_STR
"Enable all debugging\n"
BGP_STR)
DEFUN (show_debugging_bgp,
show_debugging_bgp_cmd,
"show debugging bgp",
SHOW_STR
DEBUG_STR
BGP_STR)
{
vty_out (vty, "BGP debugging status:%s", VTY_NEWLINE);
if (BGP_DEBUG (normal, NORMAL))
vty_out (vty, " BGP debugging is on%s", VTY_NEWLINE);
if (BGP_DEBUG (events, EVENTS))
vty_out (vty, " BGP events debugging is on%s", VTY_NEWLINE);
if (BGP_DEBUG (keepalive, KEEPALIVE))
vty_out (vty, " BGP keepalives debugging is on%s", VTY_NEWLINE);
if (BGP_DEBUG (update, UPDATE_IN) && BGP_DEBUG (update, UPDATE_OUT))
vty_out (vty, " BGP updates debugging is on%s", VTY_NEWLINE);
else if (BGP_DEBUG (update, UPDATE_IN))
vty_out (vty, " BGP updates debugging is on (inbound)%s", VTY_NEWLINE);
else if (BGP_DEBUG (update, UPDATE_OUT))
vty_out (vty, " BGP updates debugging is on (outbound)%s", VTY_NEWLINE);
if (BGP_DEBUG (fsm, FSM))
vty_out (vty, " BGP fsm debugging is on%s", VTY_NEWLINE);
if (BGP_DEBUG (filter, FILTER))
vty_out (vty, " BGP filter debugging is on%s", VTY_NEWLINE);
vty_out (vty, "%s", VTY_NEWLINE);
return CMD_SUCCESS;
}
int
bgp_config_write_debug (struct vty *vty)
{
int write = 0;
if (CONF_BGP_DEBUG (normal, NORMAL))
{
vty_out (vty, "debug bgp%s", VTY_NEWLINE);
write++;
}
if (CONF_BGP_DEBUG (events, EVENTS))
{
vty_out (vty, "debug bgp events%s", VTY_NEWLINE);
write++;
}
if (CONF_BGP_DEBUG (keepalive, KEEPALIVE))
{
vty_out (vty, "debug bgp keepalives%s", VTY_NEWLINE);
write++;
}
if (CONF_BGP_DEBUG (update, UPDATE_IN) && CONF_BGP_DEBUG (update, UPDATE_OUT))
{
vty_out (vty, "debug bgp updates%s", VTY_NEWLINE);
write++;
}
else if (CONF_BGP_DEBUG (update, UPDATE_IN))
{
vty_out (vty, "debug bgp updates in%s", VTY_NEWLINE);
write++;
}
else if (CONF_BGP_DEBUG (update, UPDATE_OUT))
{
vty_out (vty, "debug bgp updates out%s", VTY_NEWLINE);
write++;
}
if (CONF_BGP_DEBUG (fsm, FSM))
{
vty_out (vty, "debug bgp fsm%s", VTY_NEWLINE);
write++;
}
if (CONF_BGP_DEBUG (filter, FILTER))
{
vty_out (vty, "debug bgp filters%s", VTY_NEWLINE);
write++;
}
return write;
}
struct cmd_node debug_node =
{
DEBUG_NODE,
"",
1
};
void
bgp_debug_init ()
{
install_node (&debug_node, bgp_config_write_debug);
install_element (ENABLE_NODE, &show_debugging_bgp_cmd);
install_element (ENABLE_NODE, &debug_bgp_fsm_cmd);
install_element (CONFIG_NODE, &debug_bgp_fsm_cmd);
install_element (ENABLE_NODE, &debug_bgp_events_cmd);
install_element (CONFIG_NODE, &debug_bgp_events_cmd);
install_element (ENABLE_NODE, &debug_bgp_filter_cmd);
install_element (CONFIG_NODE, &debug_bgp_filter_cmd);
install_element (ENABLE_NODE, &debug_bgp_keepalive_cmd);
install_element (CONFIG_NODE, &debug_bgp_keepalive_cmd);
install_element (ENABLE_NODE, &debug_bgp_update_cmd);
install_element (CONFIG_NODE, &debug_bgp_update_cmd);
install_element (ENABLE_NODE, &debug_bgp_update_direct_cmd);
install_element (CONFIG_NODE, &debug_bgp_update_direct_cmd);
install_element (ENABLE_NODE, &debug_bgp_normal_cmd);
install_element (CONFIG_NODE, &debug_bgp_normal_cmd);
install_element (ENABLE_NODE, &no_debug_bgp_fsm_cmd);
install_element (ENABLE_NODE, &undebug_bgp_fsm_cmd);
install_element (CONFIG_NODE, &no_debug_bgp_fsm_cmd);
install_element (ENABLE_NODE, &no_debug_bgp_events_cmd);
install_element (ENABLE_NODE, &undebug_bgp_events_cmd);
install_element (CONFIG_NODE, &no_debug_bgp_events_cmd);
install_element (ENABLE_NODE, &no_debug_bgp_filter_cmd);
install_element (ENABLE_NODE, &undebug_bgp_filter_cmd);
install_element (CONFIG_NODE, &no_debug_bgp_filter_cmd);
install_element (ENABLE_NODE, &no_debug_bgp_keepalive_cmd);
install_element (ENABLE_NODE, &undebug_bgp_keepalive_cmd);
install_element (CONFIG_NODE, &no_debug_bgp_keepalive_cmd);
install_element (ENABLE_NODE, &no_debug_bgp_update_cmd);
install_element (ENABLE_NODE, &undebug_bgp_update_cmd);
install_element (CONFIG_NODE, &no_debug_bgp_update_cmd);
install_element (ENABLE_NODE, &no_debug_bgp_normal_cmd);
install_element (ENABLE_NODE, &undebug_bgp_normal_cmd);
install_element (CONFIG_NODE, &no_debug_bgp_normal_cmd);
install_element (ENABLE_NODE, &no_debug_bgp_all_cmd);
install_element (ENABLE_NODE, &undebug_bgp_all_cmd);
}

113
bgpd/bgp_debug.h Normal file
View File

@ -0,0 +1,113 @@
/* BGP message debug header.
Copyright (C) 1996, 97, 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. */
/* sort of packet direction */
#define DUMP_ON 1
#define DUMP_SEND 2
#define DUMP_RECV 4
/* for dump_update */
#define DUMP_WITHDRAW 8
#define DUMP_NLRI 16
/* dump detail */
#define DUMP_DETAIL 32
extern int dump_open;
extern int dump_update;
extern int dump_keepalive;
extern int dump_notify;
extern int Debug_Event;
extern int Debug_Keepalive;
extern int Debug_Update;
extern int Debug_Radix;
#define NLRI 1
#define WITHDRAW 2
#define NO_OPT 3
#define SEND 4
#define RECV 5
#define DETAIL 6
/* Prototypes. */
void bgp_debug_init ();
void bgp_packet_dump (struct stream *);
int debug (unsigned int option);
extern unsigned long conf_bgp_debug_fsm;
extern unsigned long conf_bgp_debug_events;
extern unsigned long conf_bgp_debug_packet;
extern unsigned long conf_bgp_debug_filter;
extern unsigned long conf_bgp_debug_keepalive;
extern unsigned long conf_bgp_debug_update;
extern unsigned long conf_bgp_debug_normal;
extern unsigned long term_bgp_debug_fsm;
extern unsigned long term_bgp_debug_events;
extern unsigned long term_bgp_debug_packet;
extern unsigned long term_bgp_debug_filter;
extern unsigned long term_bgp_debug_keepalive;
extern unsigned long term_bgp_debug_update;
extern unsigned long term_bgp_debug_normal;
#define BGP_DEBUG_FSM 0x01
#define BGP_DEBUG_EVENTS 0x01
#define BGP_DEBUG_PACKET 0x01
#define BGP_DEBUG_FILTER 0x01
#define BGP_DEBUG_KEEPALIVE 0x01
#define BGP_DEBUG_UPDATE_IN 0x01
#define BGP_DEBUG_UPDATE_OUT 0x02
#define BGP_DEBUG_NORMAL 0x01
#define BGP_DEBUG_PACKET_SEND 0x01
#define BGP_DEBUG_PACKET_SEND_DETAIL 0x02
#define BGP_DEBUG_PACKET_RECV 0x01
#define BGP_DEBUG_PACKET_RECV_DETAIL 0x02
#define CONF_DEBUG_ON(a, b) (conf_bgp_debug_ ## a |= (BGP_DEBUG_ ## b))
#define CONF_DEBUG_OFF(a, b) (conf_bgp_debug_ ## a &= ~(BGP_DEBUG_ ## b))
#define TERM_DEBUG_ON(a, b) (term_bgp_debug_ ## a |= (BGP_DEBUG_ ## b))
#define TERM_DEBUG_OFF(a, b) (term_bgp_debug_ ## a &= ~(BGP_DEBUG_ ## b))
#define DEBUG_ON(a, b) \
do { \
CONF_DEBUG_ON(a, b); \
TERM_DEBUG_ON(a, b); \
} while (0)
#define DEBUG_OFF(a, b) \
do { \
CONF_DEBUG_OFF(a, b); \
TERM_DEBUG_OFF(a, b); \
} while (0)
#define BGP_DEBUG(a, b) (term_bgp_debug_ ## a & BGP_DEBUG_ ## b)
#define CONF_BGP_DEBUG(a, b) (conf_bgp_debug_ ## a & BGP_DEBUG_ ## b)
extern char *bgp_type_str[];
void bgp_dump_attr (struct peer *, struct attr *, char *, size_t);
void bgp_notify_print (struct peer *, struct bgp_notify *, char *);
extern struct message bgp_status_msg[];
extern int bgp_status_msg_max;

741
bgpd/bgp_dump.c Normal file
View File

@ -0,0 +1,741 @@
/* BGP-4 dump routine
Copyright (C) 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 "stream.h"
#include "sockunion.h"
#include "command.h"
#include "prefix.h"
#include "thread.h"
#include "bgpd/bgp_table.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_route.h"
#include "bgpd/bgp_attr.h"
#include "bgpd/bgp_dump.h"
enum bgp_dump_type
{
BGP_DUMP_ALL,
BGP_DUMP_UPDATES,
BGP_DUMP_ROUTES
};
enum MRT_MSG_TYPES {
MSG_NULL,
MSG_START, /* sender is starting up */
MSG_DIE, /* receiver should shut down */
MSG_I_AM_DEAD, /* sender is shutting down */
MSG_PEER_DOWN, /* sender's peer is down */
MSG_PROTOCOL_BGP, /* msg is a BGP packet */
MSG_PROTOCOL_RIP, /* msg is a RIP packet */
MSG_PROTOCOL_IDRP, /* msg is an IDRP packet */
MSG_PROTOCOL_RIPNG, /* msg is a RIPNG packet */
MSG_PROTOCOL_BGP4PLUS, /* msg is a BGP4+ packet */
MSG_PROTOCOL_BGP4PLUS_01, /* msg is a BGP4+ (draft 01) packet */
MSG_PROTOCOL_OSPF, /* msg is an OSPF packet */
MSG_TABLE_DUMP /* routing table dump */
};
struct bgp_dump
{
enum bgp_dump_type type;
char *filename;
FILE *fp;
unsigned int interval;
char *interval_str;
struct thread *t_interval;
};
/* BGP packet dump output buffer. */
struct stream *bgp_dump_obuf;
/* BGP dump strucuture for 'dump bgp all' */
struct bgp_dump bgp_dump_all;
/* BGP dump structure for 'dump bgp updates' */
struct bgp_dump bgp_dump_updates;
/* BGP dump structure for 'dump bgp routes' */
struct bgp_dump bgp_dump_routes;
/* Dump whole BGP table is very heavy process. */
struct thread *t_bgp_dump_routes;
/* Some define for BGP packet dump. */
FILE *
bgp_dump_open_file (struct bgp_dump *bgp_dump)
{
int ret;
time_t clock;
struct tm *tm;
char fullpath[MAXPATHLEN];
char realpath[MAXPATHLEN];
time (&clock);
tm = localtime (&clock);
if (bgp_dump->filename[0] != DIRECTORY_SEP)
{
sprintf (fullpath, "%s/%s", vty_get_cwd (), bgp_dump->filename);
ret = strftime (realpath, MAXPATHLEN, fullpath, tm);
}
else
ret = strftime (realpath, MAXPATHLEN, bgp_dump->filename, tm);
if (ret == 0)
{
zlog_warn ("bgp_dump_open_file: strftime error");
return NULL;
}
if (bgp_dump->fp)
fclose (bgp_dump->fp);
bgp_dump->fp = fopen (realpath, "w");
if (bgp_dump->fp == NULL)
return NULL;
return bgp_dump->fp;
}
int
bgp_dump_interval_add (struct bgp_dump *bgp_dump, int interval)
{
int bgp_dump_interval_func (struct thread *);
bgp_dump->t_interval = thread_add_timer (master, bgp_dump_interval_func,
bgp_dump, interval);
return 0;
}
/* Dump common header. */
void
bgp_dump_header (struct stream *obuf, int type, int subtype)
{
time_t now;
/* Set header. */
time (&now);
/* Put dump packet header. */
stream_putl (obuf, now);
stream_putw (obuf, type);
stream_putw (obuf, subtype);
stream_putl (obuf, 0); /* len */
}
void
bgp_dump_set_size (struct stream *s, int type)
{
stream_putl_at (s, 8, stream_get_putp (s) - BGP_DUMP_HEADER_SIZE);
}
void
bgp_dump_routes_entry (struct prefix *p, struct bgp_info *info, int afi,
int type, unsigned int seq)
{
struct stream *obuf;
struct attr *attr;
struct peer *peer;
int plen;
int safi = 0;
/* Make dump stream. */
obuf = bgp_dump_obuf;
stream_reset (obuf);
attr = info->attr;
peer = info->peer;
/* We support MRT's old format. */
if (type == MSG_TABLE_DUMP)
{
bgp_dump_header (obuf, MSG_TABLE_DUMP, afi);
stream_putw (obuf, 0); /* View # */
stream_putw (obuf, seq); /* Sequence number. */
}
else
{
bgp_dump_header (obuf, MSG_PROTOCOL_BGP4MP, BGP4MP_ENTRY);
stream_putl (obuf, info->uptime); /* Time Last Change */
stream_putw (obuf, afi); /* Address Family */
stream_putc (obuf, safi); /* SAFI */
}
if (afi == AFI_IP)
{
if (type == MSG_TABLE_DUMP)
{
/* Prefix */
stream_put_in_addr (obuf, &p->u.prefix4);
stream_putc (obuf, p->prefixlen);
/* Status */
stream_putc (obuf, 1);
/* Originated */
stream_putl (obuf, info->uptime);
/* Peer's IP address */
stream_put_in_addr (obuf, &peer->su.sin.sin_addr);
/* Peer's AS number. */
stream_putw (obuf, peer->as);
/* Dump attribute. */
bgp_dump_routes_attr (obuf, attr);
}
else
{
/* Next-Hop-Len */
stream_putc (obuf, IPV4_MAX_BYTELEN);
stream_put_in_addr (obuf, &attr->nexthop);
stream_putc (obuf, p->prefixlen);
plen = PSIZE (p->prefixlen);
stream_put (obuf, &p->u.prefix4, plen);
bgp_dump_routes_attr (obuf, attr);
}
}
#ifdef HAVE_IPV6
else if (afi == AFI_IP6)
{
if (type == MSG_TABLE_DUMP)
{
/* Prefix */
stream_write (obuf, (u_char *)&p->u.prefix6, IPV6_MAX_BYTELEN);
stream_putc (obuf, p->prefixlen);
/* Status */
stream_putc (obuf, 1);
/* Originated */
stream_putl (obuf, info->uptime);
/* Peer's IP address */
stream_write (obuf, (u_char *)&peer->su.sin6.sin6_addr,
IPV6_MAX_BYTELEN);
/* Peer's AS number. */
stream_putw (obuf, peer->as);
/* Dump attribute. */
bgp_dump_routes_attr (obuf, attr);
}
else
{
;
}
}
#endif /* HAVE_IPV6 */
/* Set length. */
bgp_dump_set_size (obuf, type);
fwrite (STREAM_DATA (obuf), stream_get_putp (obuf), 1, bgp_dump_routes.fp);
fflush (bgp_dump_routes.fp);
}
/* Runs under child process. */
void
bgp_dump_routes_func (int afi)
{
struct stream *obuf;
struct bgp_node *rn;
struct bgp_info *info;
struct bgp *bgp;
struct bgp_table *table;
unsigned int seq = 0;
obuf = bgp_dump_obuf;
bgp = bgp_get_default ();
if (!bgp)
return;
if (bgp_dump_routes.fp == NULL)
return;
/* Walk down each BGP route. */
table = bgp->rib[afi][SAFI_UNICAST];
for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
for (info = rn->info; info; info = info->next)
bgp_dump_routes_entry (&rn->p, info, afi, MSG_TABLE_DUMP, seq++);
}
int
bgp_dump_interval_func (struct thread *t)
{
struct bgp_dump *bgp_dump;
bgp_dump = THREAD_ARG (t);
bgp_dump->t_interval = NULL;
if (bgp_dump_open_file (bgp_dump) == NULL)
return 0;
/* In case of bgp_dump_routes, we need special route dump function. */
if (bgp_dump->type == BGP_DUMP_ROUTES)
{
bgp_dump_routes_func (AFI_IP);
bgp_dump_routes_func (AFI_IP6);
}
bgp_dump_interval_add (bgp_dump, bgp_dump->interval);
return 0;
}
/* Dump common information. */
void
bgp_dump_common (struct stream *obuf, struct peer *peer)
{
char empty[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
/* Source AS number and Destination AS number. */
stream_putw (obuf, peer->as);
stream_putw (obuf, peer->local_as);
if (peer->afc[AFI_IP][SAFI_UNICAST])
{
stream_putw (obuf, peer->ifindex);
stream_putw (obuf, AFI_IP);
stream_put (obuf, &peer->su.sin.sin_addr, IPV4_MAX_BYTELEN);
if (peer->su_local)
stream_put (obuf, &peer->su_local->sin.sin_addr, IPV4_MAX_BYTELEN);
else
stream_put (obuf, empty, IPV4_MAX_BYTELEN);
}
#ifdef HAVE_IPV6
else if (peer->afc[AFI_IP6][SAFI_UNICAST])
{
/* Interface Index and Address family. */
stream_putw (obuf, peer->ifindex);
stream_putw (obuf, AFI_IP6);
/* Source IP Address and Destination IP Address. */
stream_put (obuf, &peer->su.sin6.sin6_addr, IPV6_MAX_BYTELEN);
if (peer->su_local)
stream_put (obuf, &peer->su_local->sin6.sin6_addr, IPV6_MAX_BYTELEN);
else
stream_put (obuf, empty, IPV6_MAX_BYTELEN);
}
#endif /* HAVE_IPV6 */
}
/* Dump BGP status change. */
void
bgp_dump_state (struct peer *peer, int status_old, int status_new)
{
struct stream *obuf;
/* If dump file pointer is disabled return immediately. */
if (bgp_dump_all.fp == NULL)
return;
/* Make dump stream. */
obuf = bgp_dump_obuf;
stream_reset (obuf);
bgp_dump_header (obuf, MSG_PROTOCOL_BGP4MP, BGP4MP_STATE_CHANGE);
bgp_dump_common (obuf, peer);
stream_putw (obuf, status_old);
stream_putw (obuf, status_new);
/* Set length. */
bgp_dump_set_size (obuf, MSG_PROTOCOL_BGP4MP);
/* Write to the stream. */
fwrite (STREAM_DATA (obuf), stream_get_putp (obuf), 1, bgp_dump_all.fp);
fflush (bgp_dump_all.fp);
}
void
bgp_dump_packet_func (struct bgp_dump *bgp_dump, struct peer *peer,
struct stream *packet)
{
struct stream *obuf;
/* If dump file pointer is disabled return immediately. */
if (bgp_dump->fp == NULL)
return;
/* Make dump stream. */
obuf = bgp_dump_obuf;
stream_reset (obuf);
/* Dump header and common part. */
bgp_dump_header (obuf, MSG_PROTOCOL_BGP4MP, BGP4MP_MESSAGE);
bgp_dump_common (obuf, peer);
/* Packet contents. */
stream_put (obuf, STREAM_DATA (packet), stream_get_endp (packet));
/* Set length. */
bgp_dump_set_size (obuf, MSG_PROTOCOL_BGP4MP);
/* Write to the stream. */
fwrite (STREAM_DATA (obuf), stream_get_putp (obuf), 1, bgp_dump->fp);
fflush (bgp_dump->fp);
}
/* Called from bgp_packet.c when BGP packet is received. */
void
bgp_dump_packet (struct peer *peer, int type, struct stream *packet)
{
/* bgp_dump_all. */
bgp_dump_packet_func (&bgp_dump_all, peer, packet);
/* bgp_dump_updates. */
if (type == BGP_MSG_UPDATE)
bgp_dump_packet_func (&bgp_dump_updates, peer, packet);
}
unsigned int
bgp_dump_parse_time (char *str)
{
int i;
int len;
int seen_h;
int seen_m;
int time;
unsigned int total;
time = 0;
total = 0;
seen_h = 0;
seen_m = 0;
len = strlen (str);
for (i = 0; i < len; i++)
{
if (isdigit ((int) str[i]))
{
time *= 10;
time += str[i] - '0';
}
else if (str[i] == 'H' || str[i] == 'h')
{
if (seen_h)
return 0;
if (seen_m)
return 0;
total += time * 60 *60;
time = 0;
seen_h = 1;
}
else if (str[i] == 'M' || str[i] == 'm')
{
if (seen_m)
return 0;
total += time * 60;
time = 0;
seen_h = 1;
}
else
return 0;
}
return total + time;
}
int
bgp_dump_set (struct vty *vty, struct bgp_dump *bgp_dump, int type,
char *path, char *interval_str)
{
if (interval_str)
{
unsigned int interval;
/* Check interval string. */
interval = bgp_dump_parse_time (interval_str);
if (interval == 0)
{
vty_out (vty, "Malformed interval string%s", VTY_NEWLINE);
return CMD_WARNING;
}
/* Set interval. */
bgp_dump->interval = interval;
if (bgp_dump->interval_str)
free (bgp_dump->interval_str);
bgp_dump->interval_str = strdup (interval_str);
/* Create interval thread. */
bgp_dump_interval_add (bgp_dump, interval);
}
/* Set type. */
bgp_dump->type = type;
/* Set file name. */
if (bgp_dump->filename)
free (bgp_dump->filename);
bgp_dump->filename = strdup (path);
/* This should be called when interval is expired. */
bgp_dump_open_file (bgp_dump);
return CMD_SUCCESS;
}
int
bgp_dump_unset (struct vty *vty, struct bgp_dump *bgp_dump)
{
/* Set file name. */
if (bgp_dump->filename)
{
free (bgp_dump->filename);
bgp_dump->filename = NULL;
}
/* This should be called when interval is expired. */
if (bgp_dump->fp)
{
fclose (bgp_dump->fp);
bgp_dump->fp = NULL;
}
/* Create interval thread. */
if (bgp_dump->t_interval)
{
thread_cancel (bgp_dump->t_interval);
bgp_dump->t_interval = NULL;
}
bgp_dump->interval = 0;
if (bgp_dump->interval_str)
{
free (bgp_dump->interval_str);
bgp_dump->interval_str = NULL;
}
return CMD_SUCCESS;
}
DEFUN (dump_bgp_all,
dump_bgp_all_cmd,
"dump bgp all PATH",
"Dump packet\n"
"BGP packet dump\n"
"Dump all BGP packets\n"
"Output filename\n")
{
return bgp_dump_set (vty, &bgp_dump_all, BGP_DUMP_ALL, argv[0], NULL);
}
DEFUN (dump_bgp_all_interval,
dump_bgp_all_interval_cmd,
"dump bgp all PATH INTERVAL",
"Dump packet\n"
"BGP packet dump\n"
"Dump all BGP packets\n"
"Output filename\n"
"Interval of output\n")
{
return bgp_dump_set (vty, &bgp_dump_all, BGP_DUMP_ALL, argv[0], argv[1]);
}
DEFUN (no_dump_bgp_all,
no_dump_bgp_all_cmd,
"no dump bgp all [PATH] [INTERVAL]",
NO_STR
"Dump packet\n"
"BGP packet dump\n"
"Dump all BGP packets\n")
{
return bgp_dump_unset (vty, &bgp_dump_all);
}
DEFUN (dump_bgp_updates,
dump_bgp_updates_cmd,
"dump bgp updates PATH",
"Dump packet\n"
"BGP packet dump\n"
"Dump BGP updates only\n"
"Output filename\n")
{
return bgp_dump_set (vty, &bgp_dump_updates, BGP_DUMP_UPDATES, argv[0], NULL);
}
DEFUN (dump_bgp_updates_interval,
dump_bgp_updates_interval_cmd,
"dump bgp updates PATH INTERVAL",
"Dump packet\n"
"BGP packet dump\n"
"Dump BGP updates only\n"
"Output filename\n"
"Interval of output\n")
{
return bgp_dump_set (vty, &bgp_dump_updates, BGP_DUMP_UPDATES, argv[0], argv[1]);
}
DEFUN (no_dump_bgp_updates,
no_dump_bgp_updates_cmd,
"no dump bgp updates [PATH] [INTERVAL]",
NO_STR
"Dump packet\n"
"BGP packet dump\n"
"Dump BGP updates only\n")
{
return bgp_dump_unset (vty, &bgp_dump_updates);
}
DEFUN (dump_bgp_routes,
dump_bgp_routes_cmd,
"dump bgp routes-mrt PATH",
"Dump packet\n"
"BGP packet dump\n"
"Dump whole BGP routing table\n"
"Output filename\n")
{
return bgp_dump_set (vty, &bgp_dump_routes, BGP_DUMP_ROUTES, argv[0], NULL);
}
DEFUN (dump_bgp_routes_interval,
dump_bgp_routes_interval_cmd,
"dump bgp routes-mrt PATH INTERVAL",
"Dump packet\n"
"BGP packet dump\n"
"Dump whole BGP routing table\n"
"Output filename\n"
"Interval of output\n")
{
return bgp_dump_set (vty, &bgp_dump_routes, BGP_DUMP_ROUTES, argv[0], argv[1]);
}
DEFUN (no_dump_bgp_routes,
no_dump_bgp_routes_cmd,
"no dump bgp routes-mrt [PATH] [INTERVAL]",
NO_STR
"Dump packet\n"
"BGP packet dump\n"
"Dump whole BGP routing table\n")
{
return bgp_dump_unset (vty, &bgp_dump_routes);
}
/* BGP node structure. */
struct cmd_node bgp_dump_node =
{
DUMP_NODE,
"",
};
#if 0
char *
config_time2str (unsigned int interval)
{
static char buf[BUFSIZ];
buf[0] = '\0';
if (interval / 3600)
{
sprintf (buf, "%dh", interval / 3600);
interval %= 3600;
}
if (interval / 60)
{
sprintf (buf + strlen (buf), "%dm", interval /60);
interval %= 60;
}
if (interval)
{
sprintf (buf + strlen (buf), "%d", interval);
}
return buf;
}
#endif
int
config_write_bgp_dump (struct vty *vty)
{
if (bgp_dump_all.filename)
{
if (bgp_dump_all.interval_str)
vty_out (vty, "dump bgp all %s %s%s",
bgp_dump_all.filename, bgp_dump_all.interval_str,
VTY_NEWLINE);
else
vty_out (vty, "dump bgp all %s%s",
bgp_dump_all.filename, VTY_NEWLINE);
}
if (bgp_dump_updates.filename)
{
if (bgp_dump_updates.interval_str)
vty_out (vty, "dump bgp updates %s %s%s",
bgp_dump_updates.filename, bgp_dump_updates.interval_str,
VTY_NEWLINE);
else
vty_out (vty, "dump bgp updates %s%s",
bgp_dump_updates.filename, VTY_NEWLINE);
}
if (bgp_dump_routes.filename)
{
if (bgp_dump_routes.interval_str)
vty_out (vty, "dump bgp routes-mrt %s %s%s",
bgp_dump_routes.filename, bgp_dump_routes.interval_str,
VTY_NEWLINE);
else
vty_out (vty, "dump bgp routes-mrt %s%s",
bgp_dump_routes.filename, VTY_NEWLINE);
}
return 0;
}
/* Initialize BGP packet dump functionality. */
void
bgp_dump_init ()
{
memset (&bgp_dump_all, 0, sizeof (struct bgp_dump));
memset (&bgp_dump_updates, 0, sizeof (struct bgp_dump));
memset (&bgp_dump_routes, 0, sizeof (struct bgp_dump));
bgp_dump_obuf = stream_new (BGP_MAX_PACKET_SIZE + BGP_DUMP_HEADER_SIZE);
install_node (&bgp_dump_node, config_write_bgp_dump);
install_element (CONFIG_NODE, &dump_bgp_all_cmd);
install_element (CONFIG_NODE, &dump_bgp_all_interval_cmd);
install_element (CONFIG_NODE, &no_dump_bgp_all_cmd);
install_element (CONFIG_NODE, &dump_bgp_updates_cmd);
install_element (CONFIG_NODE, &dump_bgp_updates_interval_cmd);
install_element (CONFIG_NODE, &no_dump_bgp_updates_cmd);
install_element (CONFIG_NODE, &dump_bgp_routes_cmd);
install_element (CONFIG_NODE, &dump_bgp_routes_interval_cmd);
install_element (CONFIG_NODE, &no_dump_bgp_routes_cmd);
}

34
bgpd/bgp_dump.h Normal file
View File

@ -0,0 +1,34 @@
/* BGP dump routine.
Copyright (C) 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. */
/* MRT compatible packet dump values. */
/* type value */
#define MSG_PROTOCOL_BGP4MP 16
/* subtype value */
#define BGP4MP_STATE_CHANGE 0
#define BGP4MP_MESSAGE 1
#define BGP4MP_ENTRY 2
#define BGP4MP_SNAPSHOT 3
#define BGP_DUMP_HEADER_SIZE 12
void bgp_dump_init ();
void bgp_dump_state (struct peer *, int, int);
void bgp_dump_packet (struct peer *, int, struct stream *);

641
bgpd/bgp_ecommunity.c Normal file
View File

@ -0,0 +1,641 @@
/* BGP Extended Communities Attribute
Copyright (C) 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. */
#include <zebra.h>
#include "hash.h"
#include "memory.h"
#include "prefix.h"
#include "command.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_ecommunity.h"
/* Hash of community attribute. */
struct hash *ecomhash;
/* Allocate a new ecommunities. */
struct ecommunity *
ecommunity_new ()
{
return (struct ecommunity *) XCALLOC (MTYPE_ECOMMUNITY,
sizeof (struct ecommunity));
}
/* Allocate ecommunities. */
void
ecommunity_free (struct ecommunity *ecom)
{
if (ecom->val)
XFREE (MTYPE_ECOMMUNITY_VAL, ecom->val);
if (ecom->str)
XFREE (MTYPE_ECOMMUNITY_STR, ecom->str);
XFREE (MTYPE_ECOMMUNITY, ecom);
}
/* Add a new Extended Communities value to Extended Communities
Attribute structure. When the value is already exists in the
structure, we don't add the value. Newly added value is sorted by
numerical order. When the value is added to the structure return 1
else return 0. */
static int
ecommunity_add_val (struct ecommunity *ecom, struct ecommunity_val *eval)
{
u_char *p;
int ret;
int c;
/* When this is fist value, just add it. */
if (ecom->val == NULL)
{
ecom->size++;
ecom->val = XMALLOC (MTYPE_ECOMMUNITY_VAL, ecom_length (ecom));
memcpy (ecom->val, eval->val, ECOMMUNITY_SIZE);
return 1;
}
/* If the value already exists in the structure return 0. */
c = 0;
for (p = ecom->val; c < ecom->size; p += ECOMMUNITY_SIZE, c++)
{
ret = memcmp (p, eval->val, ECOMMUNITY_SIZE);
if (ret == 0)
return 0;
if (ret > 0)
break;
}
/* Add the value to the structure with numerical sorting. */
ecom->size++;
ecom->val = XREALLOC (MTYPE_ECOMMUNITY_VAL, ecom->val, ecom_length (ecom));
memmove (ecom->val + (c + 1) * ECOMMUNITY_SIZE,
ecom->val + c * ECOMMUNITY_SIZE,
(ecom->size - 1 - c) * ECOMMUNITY_SIZE);
memcpy (ecom->val + c * ECOMMUNITY_SIZE, eval->val, ECOMMUNITY_SIZE);
return 1;
}
/* This function takes pointer to Extended Communites strucutre then
create a new Extended Communities structure by uniq and sort each
Exteneded Communities value. */
struct ecommunity *
ecommunity_uniq_sort (struct ecommunity *ecom)
{
int i;
struct ecommunity *new;
struct ecommunity_val *eval;
if (! ecom)
return NULL;
new = ecommunity_new ();;
for (i = 0; i < ecom->size; i++)
{
eval = (struct ecommunity_val *) (ecom->val + (i * ECOMMUNITY_SIZE));
ecommunity_add_val (new, eval);
}
return new;
}
/* Parse Extended Communites Attribute in BGP packet. */
struct ecommunity *
ecommunity_parse (char *pnt, u_short length)
{
struct ecommunity tmp;
struct ecommunity *new;
/* Length check. */
if (length % ECOMMUNITY_SIZE)
return NULL;
/* Prepare tmporary structure for making a new Extended Communities
Attribute. */
tmp.size = length / ECOMMUNITY_SIZE;
tmp.val = pnt;
/* Create a new Extended Communities Attribute by uniq and sort each
Extended Communities value */
new = ecommunity_uniq_sort (&tmp);
return ecommunity_intern (new);
}
/* Duplicate the Extended Communities Attribute structure. */
struct ecommunity *
ecommunity_dup (struct ecommunity *ecom)
{
struct ecommunity *new;
new = XCALLOC (MTYPE_ECOMMUNITY, sizeof (struct ecommunity));
new->size = ecom->size;
if (new->size)
{
new->val = XMALLOC (MTYPE_ECOMMUNITY_VAL, ecom->size * ECOMMUNITY_SIZE);
memcpy (new->val, ecom->val, ecom->size * ECOMMUNITY_SIZE);
}
else
new->val = NULL;
return new;
}
/* Merge two Extended Communities Attribute structure. */
struct ecommunity *
ecommunity_merge (struct ecommunity *ecom1, struct ecommunity *ecom2)
{
if (ecom1->val)
ecom1->val = XREALLOC (MTYPE_ECOMMUNITY_VAL, ecom1->val,
(ecom1->size + ecom2->size) * ECOMMUNITY_SIZE);
else
ecom1->val = XMALLOC (MTYPE_ECOMMUNITY_VAL,
(ecom1->size + ecom2->size) * ECOMMUNITY_SIZE);
memcpy (ecom1->val + (ecom1->size * ECOMMUNITY_SIZE),
ecom2->val, ecom2->size * ECOMMUNITY_SIZE);
ecom1->size += ecom2->size;
return ecom1;
}
/* Intern Extended Communities Attribute. */
struct ecommunity *
ecommunity_intern (struct ecommunity *ecom)
{
struct ecommunity *find;
assert (ecom->refcnt == 0);
find = (struct ecommunity *) hash_get (ecomhash, ecom, hash_alloc_intern);
if (find != ecom)
ecommunity_free (ecom);
find->refcnt++;
if (! find->str)
find->str = ecommunity_ecom2str (find, ECOMMUNITY_FORMAT_DISPLAY);
return find;
}
/* Unintern Extended Communities Attribute. */
void
ecommunity_unintern (struct ecommunity *ecom)
{
struct ecommunity *ret;
if (ecom->refcnt)
ecom->refcnt--;
/* Pull off from hash. */
if (ecom->refcnt == 0)
{
/* Extended community must be in the hash. */
ret = (struct ecommunity *) hash_release (ecomhash, ecom);
assert (ret != NULL);
ecommunity_free (ecom);
}
}
/* Utinity function to make hash key. */
unsigned int
ecommunity_hash_make (struct ecommunity *ecom)
{
int c;
unsigned int key;
unsigned char *pnt;
key = 0;
pnt = ecom->val;
for (c = 0; c < ecom->size * ECOMMUNITY_SIZE; c++)
key += pnt[c];
return key;
}
/* Compare two Extended Communities Attribute structure. */
int
ecommunity_cmp (struct ecommunity *ecom1, struct ecommunity *ecom2)
{
if (ecom1->size == ecom2->size
&& memcmp (ecom1->val, ecom2->val, ecom1->size * ECOMMUNITY_SIZE) == 0)
return 1;
return 0;
}
/* Initialize Extended Comminities related hash. */
void
ecommunity_init ()
{
ecomhash = hash_create (ecommunity_hash_make, ecommunity_cmp);
}
/* Extended Communities token enum. */
enum ecommunity_token
{
ecommunity_token_rt,
ecommunity_token_soo,
ecommunity_token_val,
ecommunity_token_unknown
};
/* Get next Extended Communities token from the string. */
char *
ecommunity_gettoken (char *str, struct ecommunity_val *eval,
enum ecommunity_token *token)
{
int ret;
int dot = 0;
int digit = 0;
int separator = 0;
u_int32_t val_low = 0;
u_int32_t val_high = 0;
char *p = str;
struct in_addr ip;
char ipstr[INET_ADDRSTRLEN + 1];
/* Skip white space. */
while (isspace ((int) *p))
{
p++;
str++;
}
/* Check the end of the line. */
if (*p == '\0')
return NULL;
/* "rt" and "soo" keyword parse. */
if (! isdigit ((int) *p))
{
/* "rt" match check. */
if (tolower ((int) *p) == 'r')
{
p++;
if (tolower ((int) *p) == 't')
{
p++;
*token = ecommunity_token_rt;
return p;
}
if (isspace ((int) *p) || *p == '\0')
{
*token = ecommunity_token_rt;
return p;
}
goto error;
}
/* "soo" match check. */
else if (tolower ((int) *p) == 's')
{
p++;
if (tolower ((int) *p) == 'o')
{
p++;
if (tolower ((int) *p) == 'o')
{
p++;
*token = ecommunity_token_soo;
return p;
}
if (isspace ((int) *p) || *p == '\0')
{
*token = ecommunity_token_soo;
return p;
}
goto error;
}
if (isspace ((int) *p) || *p == '\0')
{
*token = ecommunity_token_soo;
return p;
}
goto error;
}
goto error;
}
while (isdigit ((int) *p) || *p == ':' || *p == '.')
{
if (*p == ':')
{
if (separator)
goto error;
separator = 1;
digit = 0;
if (dot)
{
if ((p - str) > INET_ADDRSTRLEN)
goto error;
memset (ipstr, 0, INET_ADDRSTRLEN + 1);
memcpy (ipstr, str, p - str);
ret = inet_aton (ipstr, &ip);
if (ret == 0)
goto error;
}
else
val_high = val_low;
val_low = 0;
}
else if (*p == '.')
{
if (separator)
goto error;
dot++;
if (dot > 4)
goto error;
}
else
{
digit = 1;
val_low *= 10;
val_low += (*p - '0');
}
p++;
}
/* Low digit part must be there. */
if (! digit || ! separator)
goto error;
/* Encode result into routing distinguisher. */
if (dot)
{
eval->val[0] = ECOMMUNITY_ENCODE_IP;
eval->val[1] = 0;
memcpy (&eval->val[2], &ip, sizeof (struct in_addr));
eval->val[6] = (val_low >> 8) & 0xff;
eval->val[7] = val_low & 0xff;
}
else
{
eval->val[0] = ECOMMUNITY_ENCODE_AS;
eval->val[1] = 0;
eval->val[2] = (val_high >>8) & 0xff;
eval->val[3] = val_high & 0xff;
eval->val[4] = (val_low >>24) & 0xff;
eval->val[5] = (val_low >>16) & 0xff;
eval->val[6] = (val_low >>8) & 0xff;
eval->val[7] = val_low & 0xff;
}
*token = ecommunity_token_val;
return p;
error:
*token = ecommunity_token_unknown;
return p;
}
/* Convert string to extended community attribute.
When type is already known, please specify both str and type. str
should not include keyword such as "rt" and "soo". Type is
ECOMMUNITY_ROUTE_TARGET or ECOMMUNITY_SITE_ORIGIN.
keyword_included should be zero.
For example route-map's "set extcommunity" command case:
"rt 100:1 100:2 100:3" -> str = "100:1 100:2 100:3"
type = ECOMMUNITY_ROUTE_TARGET
keyword_included = 0
"soo 100:1" -> str = "100:1"
type = ECOMMUNITY_SITE_ORIGIN
keyword_included = 0
When string includes keyword for each extended community value.
Please specify keyword_included as non-zero value.
For example standard extcommunity-list case:
"rt 100:1 rt 100:2 soo 100:1" -> str = "rt 100:1 rt 100:2 soo 100:1"
type = 0
keyword_include = 1
*/
struct ecommunity *
ecommunity_str2com (char *str, int type, int keyword_included)
{
struct ecommunity *ecom = NULL;
enum ecommunity_token token;
struct ecommunity_val eval;
int keyword = 0;
while ((str = ecommunity_gettoken (str, &eval, &token)))
{
switch (token)
{
case ecommunity_token_rt:
case ecommunity_token_soo:
if (! keyword_included || keyword)
{
if (ecom)
ecommunity_free (ecom);
return NULL;
}
keyword = 1;
if (token == ecommunity_token_rt)
{
type = ECOMMUNITY_ROUTE_TARGET;
}
if (token == ecommunity_token_soo)
{
type = ECOMMUNITY_SITE_ORIGIN;
}
break;
case ecommunity_token_val:
if (keyword_included)
{
if (! keyword)
{
if (ecom)
ecommunity_free (ecom);
return NULL;
}
keyword = 0;
}
if (ecom == NULL)
ecom = ecommunity_new ();
eval.val[1] = type;
ecommunity_add_val (ecom, &eval);
break;
case ecommunity_token_unknown:
default:
if (ecom)
ecommunity_free (ecom);
return NULL;
break;
}
}
return ecom;
}
/* Convert extended community attribute to string.
Due to historical reason of industry standard implementation, there
are three types of format.
route-map set extcommunity format
"rt 100:1 100:2"
"soo 100:3"
extcommunity-list
"rt 100:1 rt 100:2 soo 100:3"
"show ip bgp" and extcommunity-list regular expression matching
"RT:100:1 RT:100:2 SoO:100:3"
For each formath please use below definition for format:
ECOMMUNITY_FORMAT_ROUTE_MAP
ECOMMUNITY_FORMAT_COMMUNITY_LIST
ECOMMUNITY_FORMAT_DISPLAY
*/
char *
ecommunity_ecom2str (struct ecommunity *ecom, int format)
{
int i;
u_char *pnt;
int encode = 0;
int type = 0;
#define ECOMMUNITY_STR_DEFAULT_LEN 26
int str_size;
int str_pnt;
u_char *str_buf;
char *prefix;
int len = 0;
int first = 1;
/* For parse Extended Community attribute tupple. */
struct ecommunity_as
{
as_t as;
u_int32_t val;
} eas;
struct ecommunity_ip
{
struct in_addr ip;
u_int16_t val;
} eip;
if (ecom->size == 0)
{
str_buf = XMALLOC (MTYPE_ECOMMUNITY_STR, 1);
str_buf[0] = '\0';
return str_buf;
}
/* Prepare buffer. */
str_buf = XMALLOC (MTYPE_ECOMMUNITY_STR, ECOMMUNITY_STR_DEFAULT_LEN + 1);
str_size = ECOMMUNITY_STR_DEFAULT_LEN + 1;
str_pnt = 0;
for (i = 0; i < ecom->size; i++)
{
pnt = ecom->val + (i * 8);
/* High-order octet of type. */
encode = *pnt++;
if (encode != ECOMMUNITY_ENCODE_AS && encode != ECOMMUNITY_ENCODE_IP)
{
if (str_buf)
XFREE (MTYPE_ECOMMUNITY_STR, str_buf);
return "Unknown";
}
/* Low-order octet of type. */
type = *pnt++;
if (type != ECOMMUNITY_ROUTE_TARGET && type != ECOMMUNITY_SITE_ORIGIN)
{
if (str_buf)
XFREE (MTYPE_ECOMMUNITY_STR, str_buf);
return "Unknown";
}
switch (format)
{
case ECOMMUNITY_FORMAT_COMMUNITY_LIST:
prefix = (type == ECOMMUNITY_ROUTE_TARGET ? "rt " : "soo ");
break;
case ECOMMUNITY_FORMAT_DISPLAY:
prefix = (type == ECOMMUNITY_ROUTE_TARGET ? "RT:" : "SoO:");
break;
case ECOMMUNITY_FORMAT_ROUTE_MAP:
prefix = "";
break;
default:
if (str_buf)
XFREE (MTYPE_ECOMMUNITY_STR, str_buf);
return "Unknown";
break;
}
/* Make it sure size is enough. */
while (str_pnt + ECOMMUNITY_STR_DEFAULT_LEN >= str_size)
{
str_size *= 2;
str_buf = XREALLOC (MTYPE_ECOMMUNITY_STR, str_buf, str_size);
}
/* Space between each value. */
if (! first)
str_buf[str_pnt++] = ' ';
/* Put string into buffer. */
if (encode == ECOMMUNITY_ENCODE_AS)
{
eas.as = (*pnt++ << 8);
eas.as |= (*pnt++);
eas.val = (*pnt++ << 24);
eas.val |= (*pnt++ << 16);
eas.val |= (*pnt++ << 8);
eas.val |= (*pnt++);
len = sprintf (str_buf + str_pnt, "%s%d:%d", prefix,
eas.as, eas.val);
str_pnt += len;
first = 0;
}
else if (encode == ECOMMUNITY_ENCODE_IP)
{
memcpy (&eip.ip, pnt, 4);
pnt += 4;
eip.val = (*pnt++ << 8);
eip.val |= (*pnt++);
len = sprintf (str_buf + str_pnt, "%s%s:%d", prefix,
inet_ntoa (eip.ip), eip.val);
str_pnt += len;
first = 0;
}
}
return str_buf;
}

72
bgpd/bgp_ecommunity.h Normal file
View File

@ -0,0 +1,72 @@
/* BGP Extended Communities Attribute.
Copyright (C) 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. */
/* High-order octet of the Extended Communities type field. */
#define ECOMMUNITY_ENCODE_AS 0x00
#define ECOMMUNITY_ENCODE_IP 0x01
/* Low-order octet of the Extended Communityes type field. */
#define ECOMMUNITY_ROUTE_TARGET 0x02
#define ECOMMUNITY_SITE_ORIGIN 0x03
/* Extended communities attribute string format. */
#define ECOMMUNITY_FORMAT_ROUTE_MAP 0
#define ECOMMUNITY_FORMAT_COMMUNITY_LIST 1
#define ECOMMUNITY_FORMAT_DISPLAY 2
/* Extended Communities value is eight octet long. */
#define ECOMMUNITY_SIZE 8
/* Extended Communities attribute. */
struct ecommunity
{
/* Reference counter. */
unsigned long refcnt;
/* Size of Extended Communities attribute. */
int size;
/* Extended Communities value. */
u_char *val;
/* Human readable format string. */
char *str;
};
/* Extended community value is eight octet. */
struct ecommunity_val
{
char val[ECOMMUNITY_SIZE];
};
#define ecom_length(X) ((X)->size * ECOMMUNITY_SIZE)
void ecommunity_init (void);
void ecommunity_free (struct ecommunity *);
struct ecommunity *ecommunity_new (void);
struct ecommunity *ecommunity_parse (char *, u_short);
struct ecommunity *ecommunity_dup (struct ecommunity *);
struct ecommunity *ecommunity_merge (struct ecommunity *, struct ecommunity *);
struct ecommunity *ecommunity_intern (struct ecommunity *);
int ecommunity_cmp (struct ecommunity *, struct ecommunity *);
void ecommunity_unintern (struct ecommunity *);
unsigned int ecommunity_hash_make (struct ecommunity *);
struct ecommunity *ecommunity_str2com (char *, int, int);
char *ecommunity_ecom2str (struct ecommunity *, int);

658
bgpd/bgp_filter.c Normal file
View File

@ -0,0 +1,658 @@
/* AS path filter list.
Copyright (C) 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 "command.h"
#include "log.h"
#include "memory.h"
#include "buffer.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_aspath.h"
#include "bgpd/bgp_regex.h"
#include "bgpd/bgp_filter.h"
/* List of AS filter list. */
struct as_list_list
{
struct as_list *head;
struct as_list *tail;
};
/* AS path filter master. */
struct as_list_master
{
/* List of access_list which name is number. */
struct as_list_list num;
/* List of access_list which name is string. */
struct as_list_list str;
/* Hook function which is executed when new access_list is added. */
void (*add_hook) ();
/* Hook function which is executed when access_list is deleted. */
void (*delete_hook) ();
};
/* Element of AS path filter. */
struct as_filter
{
struct as_filter *next;
struct as_filter *prev;
enum as_filter_type type;
regex_t *reg;
char *reg_str;
};
enum as_list_type
{
ACCESS_TYPE_STRING,
ACCESS_TYPE_NUMBER
};
/* AS path filter list. */
struct as_list
{
char *name;
enum as_list_type type;
struct as_list *next;
struct as_list *prev;
struct as_filter *head;
struct as_filter *tail;
};
/* ip as-path access-list 10 permit AS1. */
static struct as_list_master as_list_master =
{
{NULL, NULL},
{NULL, NULL},
NULL,
NULL
};
/* Allocate new AS filter. */
struct as_filter *
as_filter_new ()
{
struct as_filter *new;
new = XMALLOC (MTYPE_AS_FILTER, sizeof (struct as_filter));
memset (new, 0, sizeof (struct as_filter));
return new;
}
/* Free allocated AS filter. */
void
as_filter_free (struct as_filter *asfilter)
{
if (asfilter->reg)
bgp_regex_free (asfilter->reg);
if (asfilter->reg_str)
XFREE (MTYPE_AS_FILTER_STR, asfilter->reg_str);
XFREE (MTYPE_AS_FILTER, asfilter);
}
/* Make new AS filter. */
struct as_filter *
as_filter_make (regex_t *reg, char *reg_str, enum as_filter_type type)
{
struct as_filter *asfilter;
asfilter = as_filter_new ();
asfilter->reg = reg;
asfilter->type = type;
asfilter->reg_str = XSTRDUP (MTYPE_AS_FILTER_STR, reg_str);
return asfilter;
}
struct as_filter *
as_filter_lookup (struct as_list *aslist, char *reg_str,
enum as_filter_type type)
{
struct as_filter *asfilter;
for (asfilter = aslist->head; asfilter; asfilter = asfilter->next)
if (strcmp (reg_str, asfilter->reg_str) == 0)
return asfilter;
return NULL;
}
void
as_list_filter_add (struct as_list *aslist, struct as_filter *asfilter)
{
asfilter->next = NULL;
asfilter->prev = aslist->tail;
if (aslist->tail)
aslist->tail->next = asfilter;
else
aslist->head = asfilter;
aslist->tail = asfilter;
}
/* Lookup as_list from list of as_list by name. */
struct as_list *
as_list_lookup (char *name)
{
struct as_list *aslist;
if (name == NULL)
return NULL;
for (aslist = as_list_master.num.head; aslist; aslist = aslist->next)
if (strcmp (aslist->name, name) == 0)
return aslist;
for (aslist = as_list_master.str.head; aslist; aslist = aslist->next)
if (strcmp (aslist->name, name) == 0)
return aslist;
return NULL;
}
struct as_list *
as_list_new ()
{
struct as_list *new;
new = XMALLOC (MTYPE_AS_LIST, sizeof (struct as_list));
memset (new, 0, sizeof (struct as_list));
return new;
}
void
as_list_free (struct as_list *aslist)
{
XFREE (MTYPE_AS_LIST, aslist);
}
/* Insert new AS list to list of as_list. Each as_list is sorted by
the name. */
struct as_list *
as_list_insert (char *name)
{
int i;
long number;
struct as_list *aslist;
struct as_list *point;
struct as_list_list *list;
/* Allocate new access_list and copy given name. */
aslist = as_list_new ();
aslist->name = strdup (name);
/* If name is made by all digit character. We treat it as
number. */
for (number = 0, i = 0; i < strlen (name); i++)
{
if (isdigit ((int) name[i]))
number = (number * 10) + (name[i] - '0');
else
break;
}
/* In case of name is all digit character */
if (i == strlen (name))
{
aslist->type = ACCESS_TYPE_NUMBER;
/* Set access_list to number list. */
list = &as_list_master.num;
for (point = list->head; point; point = point->next)
if (atol (point->name) >= number)
break;
}
else
{
aslist->type = ACCESS_TYPE_STRING;
/* Set access_list to string list. */
list = &as_list_master.str;
/* Set point to insertion point. */
for (point = list->head; point; point = point->next)
if (strcmp (point->name, name) >= 0)
break;
}
/* In case of this is the first element of master. */
if (list->head == NULL)
{
list->head = list->tail = aslist;
return aslist;
}
/* In case of insertion is made at the tail of access_list. */
if (point == NULL)
{
aslist->prev = list->tail;
list->tail->next = aslist;
list->tail = aslist;
return aslist;
}
/* In case of insertion is made at the head of access_list. */
if (point == list->head)
{
aslist->next = list->head;
list->head->prev = aslist;
list->head = aslist;
return aslist;
}
/* Insertion is made at middle of the access_list. */
aslist->next = point;
aslist->prev = point->prev;
if (point->prev)
point->prev->next = aslist;
point->prev = aslist;
return aslist;
}
struct as_list *
as_list_get (char *name)
{
struct as_list *aslist;
aslist = as_list_lookup (name);
if (aslist == NULL)
{
aslist = as_list_insert (name);
/* Run hook function. */
if (as_list_master.add_hook)
(*as_list_master.add_hook) ();
}
return aslist;
}
static char *
filter_type_str (enum as_filter_type type)
{
switch (type)
{
case AS_FILTER_PERMIT:
return "permit";
break;
case AS_FILTER_DENY:
return "deny";
break;
default:
return "";
break;
}
}
void
as_list_delete (struct as_list *aslist)
{
struct as_list_list *list;
struct as_filter *filter, *next;
for (filter = aslist->head; filter; filter = next)
{
next = filter->next;
as_filter_free (filter);
}
if (aslist->type == ACCESS_TYPE_NUMBER)
list = &as_list_master.num;
else
list = &as_list_master.str;
if (aslist->next)
aslist->next->prev = aslist->prev;
else
list->tail = aslist->prev;
if (aslist->prev)
aslist->prev->next = aslist->next;
else
list->head = aslist->next;
as_list_free (aslist);
}
static int
as_list_empty (struct as_list *aslist)
{
if (aslist->head == NULL && aslist->tail == NULL)
return 1;
else
return 0;
}
void
as_list_filter_delete (struct as_list *aslist, struct as_filter *asfilter)
{
if (asfilter->next)
asfilter->next->prev = asfilter->prev;
else
aslist->tail = asfilter->prev;
if (asfilter->prev)
asfilter->prev->next = asfilter->next;
else
aslist->head = asfilter->next;
as_filter_free (asfilter);
/* If access_list becomes empty delete it from access_master. */
if (as_list_empty (aslist))
as_list_delete (aslist);
/* Run hook function. */
if (as_list_master.delete_hook)
(*as_list_master.delete_hook) ();
}
static int
as_filter_match (struct as_filter *asfilter, struct aspath *aspath)
{
if (bgp_regexec (asfilter->reg, aspath) != REG_NOMATCH)
return 1;
return 0;
}
/* Apply AS path filter to AS. */
enum as_filter_type
as_list_apply (struct as_list *aslist, void *object)
{
struct as_filter *asfilter;
struct aspath *aspath;
aspath = (struct aspath *) object;
if (aslist == NULL)
return AS_FILTER_DENY;
for (asfilter = aslist->head; asfilter; asfilter = asfilter->next)
{
if (as_filter_match (asfilter, aspath))
return asfilter->type;
}
return AS_FILTER_DENY;
}
/* Add hook function. */
void
as_list_add_hook (void (*func) ())
{
as_list_master.add_hook = func;
}
/* Delete hook function. */
void
as_list_delete_hook (void (*func) ())
{
as_list_master.delete_hook = func;
}
int
as_list_dup_check (struct as_list *aslist, struct as_filter *new)
{
struct as_filter *asfilter;
for (asfilter = aslist->head; asfilter; asfilter = asfilter->next)
{
if (asfilter->type == new->type
&& strcmp (asfilter->reg_str, new->reg_str) == 0)
return 1;
}
return 0;
}
DEFUN (ip_as_path, ip_as_path_cmd,
"ip as-path access-list WORD (deny|permit) .LINE",
IP_STR
"BGP autonomous system path filter\n"
"Specify an access list name\n"
"Regular expression access list name\n"
"Specify packets to reject\n"
"Specify packets to forward\n"
"A regular-expression to match the BGP AS paths\n")
{
enum as_filter_type type;
struct as_filter *asfilter;
struct as_list *aslist;
regex_t *regex;
struct buffer *b;
int i;
char *regstr;
int first = 0;
/* Check the filter type. */
if (strncmp (argv[1], "p", 1) == 0)
type = AS_FILTER_PERMIT;
else if (strncmp (argv[1], "d", 1) == 0)
type = AS_FILTER_DENY;
else
{
vty_out (vty, "filter type must be [permit|deny]%s", VTY_NEWLINE);
return CMD_WARNING;
}
/* Check AS path regex. */
b = buffer_new (1024);
for (i = 2; i < argc; i++)
{
if (first)
buffer_putc (b, ' ');
else
first = 1;
buffer_putstr (b, argv[i]);
}
buffer_putc (b, '\0');
regstr = buffer_getstr (b);
buffer_free (b);
regex = bgp_regcomp (regstr);
if (!regex)
{
free (regstr);
vty_out (vty, "can't compile regexp %s%s", argv[0],
VTY_NEWLINE);
return CMD_WARNING;
}
asfilter = as_filter_make (regex, regstr, type);
free (regstr);
/* Install new filter to the access_list. */
aslist = as_list_get (argv[0]);
/* Duplicate insertion check. */;
if (as_list_dup_check (aslist, asfilter))
as_filter_free (asfilter);
else
as_list_filter_add (aslist, asfilter);
return CMD_SUCCESS;
}
DEFUN (no_ip_as_path,
no_ip_as_path_cmd,
"no ip as-path access-list WORD (deny|permit) .LINE",
NO_STR
IP_STR
"BGP autonomous system path filter\n"
"Specify an access list name\n"
"Regular expression access list name\n"
"Specify packets to reject\n"
"Specify packets to forward\n"
"A regular-expression to match the BGP AS paths\n")
{
enum as_filter_type type;
struct as_filter *asfilter;
struct as_list *aslist;
struct buffer *b;
int i;
int first = 0;
char *regstr;
regex_t *regex;
/* Lookup AS list from AS path list. */
aslist = as_list_lookup (argv[0]);
if (aslist == NULL)
{
vty_out (vty, "ip as-path access-list %s doesn't exist%s", argv[0],
VTY_NEWLINE);
return CMD_WARNING;
}
/* Check the filter type. */
if (strncmp (argv[1], "p", 1) == 0)
type = AS_FILTER_PERMIT;
else if (strncmp (argv[1], "d", 1) == 0)
type = AS_FILTER_DENY;
else
{
vty_out (vty, "filter type must be [permit|deny]%s", VTY_NEWLINE);
return CMD_WARNING;
}
/* Compile AS path. */
b = buffer_new (1024);
for (i = 2; i < argc; i++)
{
if (first)
buffer_putc (b, ' ');
else
first = 1;
buffer_putstr (b, argv[i]);
}
buffer_putc (b, '\0');
regstr = buffer_getstr (b);
buffer_free (b);
regex = bgp_regcomp (regstr);
if (!regex)
{
free (regstr);
vty_out (vty, "can't compile regexp %s%s", argv[0],
VTY_NEWLINE);
return CMD_WARNING;
}
/* Lookup asfilter. */
asfilter = as_filter_lookup (aslist, regstr, type);
free (regstr);
bgp_regex_free (regex);
if (asfilter == NULL)
{
vty_out (vty, "%s", VTY_NEWLINE);
return CMD_WARNING;
}
as_list_filter_delete (aslist, asfilter);
return CMD_SUCCESS;
}
DEFUN (no_ip_as_path_all,
no_ip_as_path_all_cmd,
"no ip as-path access-list WORD",
NO_STR
IP_STR
"BGP autonomous system path filter\n"
"Specify an access list name\n"
"Regular expression access list name\n")
{
struct as_list *aslist;
aslist = as_list_lookup (argv[0]);
if (aslist == NULL)
{
vty_out (vty, "ip as-path access-list %s doesn't exist%s", argv[0],
VTY_NEWLINE);
return CMD_WARNING;
}
as_list_delete (aslist);
return CMD_SUCCESS;
}
int
config_write_as_list (struct vty *vty)
{
struct as_list *aslist;
struct as_filter *asfilter;
int write = 0;
for (aslist = as_list_master.num.head; aslist; aslist = aslist->next)
for (asfilter = aslist->head; asfilter; asfilter = asfilter->next)
{
vty_out (vty, "ip as-path access-list %s %s %s%s",
aslist->name, filter_type_str (asfilter->type),
asfilter->reg_str,
VTY_NEWLINE);
write++;
}
for (aslist = as_list_master.str.head; aslist; aslist = aslist->next)
for (asfilter = aslist->head; asfilter; asfilter = asfilter->next)
{
vty_out (vty, "ip as-path access-list %s %s %s%s",
aslist->name, filter_type_str (asfilter->type),
asfilter->reg_str,
VTY_NEWLINE);
write++;
}
return write;
}
struct cmd_node as_list_node =
{
AS_LIST_NODE,
"",
1
};
/* Register functions. */
void
bgp_filter_init ()
{
install_node (&as_list_node, config_write_as_list);
install_element (CONFIG_NODE, &ip_as_path_cmd);
install_element (CONFIG_NODE, &no_ip_as_path_cmd);
install_element (CONFIG_NODE, &no_ip_as_path_all_cmd);
}

31
bgpd/bgp_filter.h Normal file
View File

@ -0,0 +1,31 @@
/* AS path filter list.
Copyright (C) 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. */
enum as_filter_type
{
AS_FILTER_DENY,
AS_FILTER_PERMIT
};
enum as_filter_type as_list_apply (struct as_list *, void *);
struct as_list *as_list_lookup (char *);
void as_list_add_hook (void (*func) ());
void as_list_delete_hook (void (*func) ());

864
bgpd/bgp_fsm.c Normal file
View File

@ -0,0 +1,864 @@
/* BGP-4 Finite State Machine
From RFC1771 [A Border Gateway Protocol 4 (BGP-4)]
Copyright (C) 1996, 97, 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. */
#include <zebra.h>
#include "linklist.h"
#include "prefix.h"
#include "vty.h"
#include "sockunion.h"
#include "thread.h"
#include "log.h"
#include "stream.h"
#include "memory.h"
#include "plist.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_attr.h"
#include "bgpd/bgp_debug.h"
#include "bgpd/bgp_fsm.h"
#include "bgpd/bgp_packet.h"
#include "bgpd/bgp_network.h"
#include "bgpd/bgp_route.h"
#include "bgpd/bgp_dump.h"
#include "bgpd/bgp_open.h"
#ifdef HAVE_SNMP
#include "bgpd/bgp_snmp.h"
#endif /* HAVE_SNMP */
/* BGP FSM (finite state machine) has three types of functions. Type
one is thread functions. Type two is event functions. Type three
is FSM functions. Timer functions are set by bgp_timer_set
function. */
/* BGP event function. */
int bgp_event (struct thread *);
/* BGP thread functions. */
static int bgp_start_timer (struct thread *);
static int bgp_connect_timer (struct thread *);
static int bgp_holdtime_timer (struct thread *);
static int bgp_keepalive_timer (struct thread *);
/* BGP FSM functions. */
static int bgp_start (struct peer *);
/* BGP start timer jitter. */
int
bgp_start_jitter (int time)
{
return ((rand () % (time + 1)) - (time / 2));
}
/* Hook function called after bgp event is occered. And vty's
neighbor command invoke this function after making neighbor
structure. */
void
bgp_timer_set (struct peer *peer)
{
int jitter = 0;
switch (peer->status)
{
case Idle:
/* First entry point of peer's finite state machine. In Idle
status start timer is on unless peer is shutdown or peer is
inactive. All other timer must be turned off */
if (CHECK_FLAG (peer->flags, PEER_FLAG_SHUTDOWN)
|| CHECK_FLAG (peer->sflags, PEER_STATUS_PREFIX_OVERFLOW)
|| ! peer_active (peer))
{
BGP_TIMER_OFF (peer->t_start);
}
else
{
jitter = bgp_start_jitter (peer->v_start);
BGP_TIMER_ON (peer->t_start, bgp_start_timer,
peer->v_start + jitter);
}
BGP_TIMER_OFF (peer->t_connect);
BGP_TIMER_OFF (peer->t_holdtime);
BGP_TIMER_OFF (peer->t_keepalive);
BGP_TIMER_OFF (peer->t_asorig);
BGP_TIMER_OFF (peer->t_routeadv);
break;
case Connect:
/* After start timer is expired, the peer moves to Connnect
status. Make sure start timer is off and connect timer is
on. */
BGP_TIMER_OFF (peer->t_start);
BGP_TIMER_ON (peer->t_connect, bgp_connect_timer, peer->v_connect);
BGP_TIMER_OFF (peer->t_holdtime);
BGP_TIMER_OFF (peer->t_keepalive);
BGP_TIMER_OFF (peer->t_asorig);
BGP_TIMER_OFF (peer->t_routeadv);
break;
case Active:
/* Active is waiting connection from remote peer. And if
connect timer is expired, change status to Connect. */
BGP_TIMER_OFF (peer->t_start);
/* If peer is passive mode, do not set connect timer. */
if (CHECK_FLAG (peer->flags, PEER_FLAG_PASSIVE))
{
BGP_TIMER_OFF (peer->t_connect);
}
else
{
BGP_TIMER_ON (peer->t_connect, bgp_connect_timer, peer->v_connect);
}
BGP_TIMER_OFF (peer->t_holdtime);
BGP_TIMER_OFF (peer->t_keepalive);
BGP_TIMER_OFF (peer->t_asorig);
BGP_TIMER_OFF (peer->t_routeadv);
break;
case OpenSent:
/* OpenSent status. */
BGP_TIMER_OFF (peer->t_start);
BGP_TIMER_OFF (peer->t_connect);
if (peer->v_holdtime != 0)
{
BGP_TIMER_ON (peer->t_holdtime, bgp_holdtime_timer,
peer->v_holdtime);
}
else
{
BGP_TIMER_OFF (peer->t_holdtime);
}
BGP_TIMER_OFF (peer->t_keepalive);
BGP_TIMER_OFF (peer->t_asorig);
BGP_TIMER_OFF (peer->t_routeadv);
break;
case OpenConfirm:
/* OpenConfirm status. */
BGP_TIMER_OFF (peer->t_start);
BGP_TIMER_OFF (peer->t_connect);
/* If the negotiated Hold Time value is zero, then the Hold Time
timer and KeepAlive timers are not started. */
if (peer->v_holdtime == 0)
{
BGP_TIMER_OFF (peer->t_holdtime);
BGP_TIMER_OFF (peer->t_keepalive);
}
else
{
BGP_TIMER_ON (peer->t_holdtime, bgp_holdtime_timer,
peer->v_holdtime);
BGP_TIMER_ON (peer->t_keepalive, bgp_keepalive_timer,
peer->v_keepalive);
}
BGP_TIMER_OFF (peer->t_asorig);
BGP_TIMER_OFF (peer->t_routeadv);
break;
case Established:
/* In Established status start and connect timer is turned
off. */
BGP_TIMER_OFF (peer->t_start);
BGP_TIMER_OFF (peer->t_connect);
/* Same as OpenConfirm, if holdtime is zero then both holdtime
and keepalive must be turned off. */
if (peer->v_holdtime == 0)
{
BGP_TIMER_OFF (peer->t_holdtime);
BGP_TIMER_OFF (peer->t_keepalive);
}
else
{
BGP_TIMER_ON (peer->t_holdtime, bgp_holdtime_timer,
peer->v_holdtime);
BGP_TIMER_ON (peer->t_keepalive, bgp_keepalive_timer,
peer->v_keepalive);
}
BGP_TIMER_OFF (peer->t_asorig);
break;
}
}
/* BGP start timer. This function set BGP_Start event to thread value
and process event. */
static int
bgp_start_timer (struct thread *thread)
{
struct peer *peer;
peer = THREAD_ARG (thread);
peer->t_start = NULL;
if (BGP_DEBUG (fsm, FSM))
zlog (peer->log, LOG_DEBUG,
"%s [FSM] Timer (start timer expire).", peer->host);
THREAD_VAL (thread) = BGP_Start;
bgp_event (thread);
return 0;
}
/* BGP connect retry timer. */
static int
bgp_connect_timer (struct thread *thread)
{
struct peer *peer;
peer = THREAD_ARG (thread);
peer->t_connect = NULL;
if (BGP_DEBUG (fsm, FSM))
zlog (peer->log, LOG_DEBUG, "%s [FSM] Timer (connect timer expire)",
peer->host);
THREAD_VAL (thread) = ConnectRetry_timer_expired;
bgp_event (thread);
return 0;
}
/* BGP holdtime timer. */
static int
bgp_holdtime_timer (struct thread *thread)
{
struct peer *peer;
peer = THREAD_ARG (thread);
peer->t_holdtime = NULL;
if (BGP_DEBUG (fsm, FSM))
zlog (peer->log, LOG_DEBUG,
"%s [FSM] Timer (holdtime timer expire)",
peer->host);
THREAD_VAL (thread) = Hold_Timer_expired;
bgp_event (thread);
return 0;
}
/* BGP keepalive fire ! */
static int
bgp_keepalive_timer (struct thread *thread)
{
struct peer *peer;
peer = THREAD_ARG (thread);
peer->t_keepalive = NULL;
if (BGP_DEBUG (fsm, FSM))
zlog (peer->log, LOG_DEBUG,
"%s [FSM] Timer (keepalive timer expire)",
peer->host);
THREAD_VAL (thread) = KeepAlive_timer_expired;
bgp_event (thread);
return 0;
}
int
bgp_routeadv_timer (struct thread *thread)
{
struct peer *peer;
peer = THREAD_ARG (thread);
peer->t_routeadv = NULL;
if (BGP_DEBUG (fsm, FSM))
zlog (peer->log, LOG_DEBUG,
"%s [FSM] Timer (routeadv timer expire)",
peer->host);
peer->synctime = time (NULL);
BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
BGP_TIMER_ON (peer->t_routeadv, bgp_routeadv_timer,
peer->v_routeadv);
return 0;
}
/* Reset bgp update timer */
static void
bgp_uptime_reset (struct peer *peer)
{
peer->uptime = time (NULL);
}
/* Administrative BGP peer stop event. */
int
bgp_stop (struct peer *peer)
{
int established = 0;
afi_t afi;
safi_t safi;
char orf_name[BUFSIZ];
/* Increment Dropped count. */
if (peer->status == Established)
{
established = 1;
peer->dropped++;
bgp_fsm_change_status (peer, Idle);
#ifdef HAVE_SNMP
bgpTrapBackwardTransition (peer);
#endif /* HAVE_SNMP */
}
/* Reset uptime. */
bgp_uptime_reset (peer);
/* Need of clear of peer. */
if (established)
bgp_clear_route_all (peer);
/* Stop read and write threads when exists. */
BGP_READ_OFF (peer->t_read);
BGP_WRITE_OFF (peer->t_write);
/* Stop all timers. */
BGP_TIMER_OFF (peer->t_start);
BGP_TIMER_OFF (peer->t_connect);
BGP_TIMER_OFF (peer->t_holdtime);
BGP_TIMER_OFF (peer->t_keepalive);
BGP_TIMER_OFF (peer->t_asorig);
BGP_TIMER_OFF (peer->t_routeadv);
/* Delete all existing events of the peer. */
BGP_EVENT_DELETE (peer);
/* Stream reset. */
peer->packet_size = 0;
/* Clear input and output buffer. */
if (peer->ibuf)
stream_reset (peer->ibuf);
if (peer->work)
stream_reset (peer->work);
stream_fifo_clean (peer->obuf);
/* Close of file descriptor. */
if (peer->fd >= 0)
{
close (peer->fd);
peer->fd = -1;
}
/* Connection information. */
if (peer->su_local)
{
XFREE (MTYPE_SOCKUNION, peer->su_local);
peer->su_local = NULL;
}
if (peer->su_remote)
{
XFREE (MTYPE_SOCKUNION, peer->su_remote);
peer->su_remote = NULL;
}
/* Clear remote router-id. */
peer->remote_id.s_addr = 0;
/* Reset all negotiated variables */
peer->afc_nego[AFI_IP][SAFI_UNICAST] = 0;
peer->afc_nego[AFI_IP][SAFI_MULTICAST] = 0;
peer->afc_nego[AFI_IP][SAFI_MPLS_VPN] = 0;
peer->afc_nego[AFI_IP6][SAFI_UNICAST] = 0;
peer->afc_nego[AFI_IP6][SAFI_MULTICAST] = 0;
peer->afc_adv[AFI_IP][SAFI_UNICAST] = 0;
peer->afc_adv[AFI_IP][SAFI_MULTICAST] = 0;
peer->afc_adv[AFI_IP][SAFI_MPLS_VPN] = 0;
peer->afc_adv[AFI_IP6][SAFI_UNICAST] = 0;
peer->afc_adv[AFI_IP6][SAFI_MULTICAST] = 0;
peer->afc_recv[AFI_IP][SAFI_UNICAST] = 0;
peer->afc_recv[AFI_IP][SAFI_MULTICAST] = 0;
peer->afc_recv[AFI_IP][SAFI_MPLS_VPN] = 0;
peer->afc_recv[AFI_IP6][SAFI_UNICAST] = 0;
peer->afc_recv[AFI_IP6][SAFI_MULTICAST] = 0;
/* Reset route refresh flag. */
UNSET_FLAG (peer->cap, PEER_CAP_REFRESH_ADV);
UNSET_FLAG (peer->cap, PEER_CAP_REFRESH_OLD_RCV);
UNSET_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV);
UNSET_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV);
UNSET_FLAG (peer->cap, PEER_CAP_DYNAMIC_RCV);
for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
{
/* peer address family capability flags*/
peer->af_cap[afi][safi] = 0;
/* peer address family status flags*/
peer->af_sflags[afi][safi] = 0;
/* Received ORF prefix-filter */
peer->orf_plist[afi][safi] = NULL;
/* ORF received prefix-filter pnt */
sprintf (orf_name, "%s.%d.%d", peer->host, afi, safi);
prefix_bgp_orf_remove_all (orf_name);
}
/* Reset keepalive and holdtime */
if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
{
peer->v_keepalive = peer->keepalive;
peer->v_holdtime = peer->holdtime;
}
else
{
peer->v_keepalive = peer->bgp->default_keepalive;
peer->v_holdtime = peer->bgp->default_holdtime;
}
peer->update_time = 0;
/* Until we are sure that there is no problem about prefix count
this should be commented out.*/
#if 0
/* Reset prefix count */
peer->pcount[AFI_IP][SAFI_UNICAST] = 0;
peer->pcount[AFI_IP][SAFI_MULTICAST] = 0;
peer->pcount[AFI_IP][SAFI_MPLS_VPN] = 0;
peer->pcount[AFI_IP6][SAFI_UNICAST] = 0;
peer->pcount[AFI_IP6][SAFI_MULTICAST] = 0;
#endif /* 0 */
return 0;
}
/* BGP peer is stoped by the error. */
int
bgp_stop_with_error (struct peer *peer)
{
/* Double start timer. */
peer->v_start *= 2;
/* Overflow check. */
if (peer->v_start >= (60 * 2))
peer->v_start = (60 * 2);
bgp_stop (peer);
return 0;
}
/* TCP connection open. Next we send open message to remote peer. And
add read thread for reading open message. */
int
bgp_connect_success (struct peer *peer)
{
if (peer->fd < 0)
{
zlog_err ("bgp_connect_success peer's fd is negative value %d",
peer->fd);
return -1;
}
BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
/* bgp_getsockname (peer); */
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
bgp_open_send (peer);
return 0;
}
/* TCP connect fail */
int
bgp_connect_fail (struct peer *peer)
{
bgp_stop (peer);
return 0;
}
/* This function is the first starting point of all BGP connection. It
try to connect to remote peer with non-blocking IO. */
int
bgp_start (struct peer *peer)
{
int status;
/* If the peer is passive mode, force to move to Active mode. */
if (CHECK_FLAG (peer->flags, PEER_FLAG_PASSIVE))
{
BGP_EVENT_ADD (peer, TCP_connection_open_failed);
return 0;
}
status = bgp_connect (peer);
switch (status)
{
case connect_error:
if (BGP_DEBUG (fsm, FSM))
plog_info (peer->log, "%s [FSM] Connect error", peer->host);
BGP_EVENT_ADD (peer, TCP_connection_open_failed);
break;
case connect_success:
if (BGP_DEBUG (fsm, FSM))
plog_info (peer->log, "%s [FSM] Connect immediately success",
peer->host);
BGP_EVENT_ADD (peer, TCP_connection_open);
break;
case connect_in_progress:
/* To check nonblocking connect, we wait until socket is
readable or writable. */
if (BGP_DEBUG (fsm, FSM))
plog_info (peer->log, "%s [FSM] Non blocking connect waiting result",
peer->host);
if (peer->fd < 0)
{
zlog_err ("bgp_start peer's fd is negative value %d",
peer->fd);
return -1;
}
BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
break;
}
return 0;
}
/* Connect retry timer is expired when the peer status is Connect. */
int
bgp_reconnect (struct peer *peer)
{
bgp_stop (peer);
bgp_start (peer);
return 0;
}
int
bgp_fsm_open (struct peer *peer)
{
/* Send keepalive and make keepalive timer */
bgp_keepalive_send (peer);
/* Reset holdtimer value. */
BGP_TIMER_OFF (peer->t_holdtime);
return 0;
}
/* Called after event occured, this function change status and reset
read/write and timer thread. */
void
bgp_fsm_change_status (struct peer *peer, int status)
{
bgp_dump_state (peer, peer->status, status);
/* Preserve old status and change into new status. */
peer->ostatus = peer->status;
peer->status = status;
}
/* Keepalive send to peer. */
int
bgp_fsm_keepalive_expire (struct peer *peer)
{
bgp_keepalive_send (peer);
return 0;
}
/* Hold timer expire. This is error of BGP connection. So cut the
peer and change to Idle status. */
int
bgp_fsm_holdtime_expire (struct peer *peer)
{
if (BGP_DEBUG (fsm, FSM))
zlog (peer->log, LOG_DEBUG, "%s [FSM] Hold timer expire", peer->host);
/* Send notify to remote peer. */
bgp_notify_send (peer, BGP_NOTIFY_HOLD_ERR, 0);
/* Sweep if it is temporary peer. */
if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
{
zlog_info ("%s [Event] Accepting BGP peer is deleted", peer->host);
peer_delete (peer);
return -1;
}
return 0;
}
/* Status goes to Established. Send keepalive packet then make first
update information. */
int
bgp_establish (struct peer *peer)
{
struct bgp_notify *notify;
afi_t afi;
safi_t safi;
/* Reset capability open status flag. */
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN))
SET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
/* Clear last notification data. */
notify = &peer->notify;
if (notify->data)
XFREE (MTYPE_TMP, notify->data);
memset (notify, 0, sizeof (struct bgp_notify));
/* Clear start timer value to default. */
peer->v_start = BGP_INIT_START_TIMER;
/* Increment established count. */
peer->established++;
bgp_fsm_change_status (peer, Established);
#ifdef HAVE_SNMP
bgpTrapEstablished (peer);
#endif /* HAVE_SNMP */
/* Reset uptime, send keepalive, send current table. */
bgp_uptime_reset (peer);
/* Send route-refresh when ORF is enabled */
for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV))
{
if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_RCV))
bgp_route_refresh_send (peer, afi, safi, ORF_TYPE_PREFIX,
REFRESH_IMMEDIATE, 0);
else if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_OLD_RCV))
bgp_route_refresh_send (peer, afi, safi, ORF_TYPE_PREFIX_OLD,
REFRESH_IMMEDIATE, 0);
}
if (peer->v_keepalive)
bgp_keepalive_send (peer);
/* First update is deferred until ORF or ROUTE-REFRESH is received */
for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV))
if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
|| CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_OLD_RCV))
SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH);
bgp_announce_route_all (peer);
BGP_TIMER_ON (peer->t_routeadv, bgp_routeadv_timer, 1);
return 0;
}
/* Keepalive packet is received. */
int
bgp_fsm_keepalive (struct peer *peer)
{
/* peer count update */
peer->keepalive_in++;
BGP_TIMER_OFF (peer->t_holdtime);
return 0;
}
/* Update packet is received. */
int
bgp_fsm_update (struct peer *peer)
{
BGP_TIMER_OFF (peer->t_holdtime);
return 0;
}
/* This is empty event. */
int
bgp_ignore (struct peer *peer)
{
if (BGP_DEBUG (fsm, FSM))
zlog (peer->log, LOG_DEBUG, "%s [FSM] bgp_ignore called", peer->host);
return 0;
}
/* Finite State Machine structure */
struct {
int (*func) ();
int next_state;
} FSM [BGP_STATUS_MAX - 1][BGP_EVENTS_MAX - 1] =
{
{
/* Idle state: In Idle state, all events other than BGP_Start is
ignored. With BGP_Start event, finite state machine calls
bgp_start(). */
{bgp_start, Connect}, /* BGP_Start */
{bgp_stop, Idle}, /* BGP_Stop */
{bgp_stop, Idle}, /* TCP_connection_open */
{bgp_stop, Idle}, /* TCP_connection_closed */
{bgp_ignore, Idle}, /* TCP_connection_open_failed */
{bgp_stop, Idle}, /* TCP_fatal_error */
{bgp_ignore, Idle}, /* ConnectRetry_timer_expired */
{bgp_ignore, Idle}, /* Hold_Timer_expired */
{bgp_ignore, Idle}, /* KeepAlive_timer_expired */
{bgp_ignore, Idle}, /* Receive_OPEN_message */
{bgp_ignore, Idle}, /* Receive_KEEPALIVE_message */
{bgp_ignore, Idle}, /* Receive_UPDATE_message */
{bgp_ignore, Idle}, /* Receive_NOTIFICATION_message */
},
{
/* Connect */
{bgp_ignore, Connect}, /* BGP_Start */
{bgp_stop, Idle}, /* BGP_Stop */
{bgp_connect_success, OpenSent}, /* TCP_connection_open */
{bgp_stop, Idle}, /* TCP_connection_closed */
{bgp_connect_fail, Active}, /* TCP_connection_open_failed */
{bgp_connect_fail, Idle}, /* TCP_fatal_error */
{bgp_reconnect, Connect}, /* ConnectRetry_timer_expired */
{bgp_ignore, Idle}, /* Hold_Timer_expired */
{bgp_ignore, Idle}, /* KeepAlive_timer_expired */
{bgp_ignore, Idle}, /* Receive_OPEN_message */
{bgp_ignore, Idle}, /* Receive_KEEPALIVE_message */
{bgp_ignore, Idle}, /* Receive_UPDATE_message */
{bgp_stop, Idle}, /* Receive_NOTIFICATION_message */
},
{
/* Active, */
{bgp_ignore, Active}, /* BGP_Start */
{bgp_stop, Idle}, /* BGP_Stop */
{bgp_connect_success, OpenSent}, /* TCP_connection_open */
{bgp_stop, Idle}, /* TCP_connection_closed */
{bgp_ignore, Active}, /* TCP_connection_open_failed */
{bgp_ignore, Idle}, /* TCP_fatal_error */
{bgp_start, Connect}, /* ConnectRetry_timer_expired */
{bgp_ignore, Idle}, /* Hold_Timer_expired */
{bgp_ignore, Idle}, /* KeepAlive_timer_expired */
{bgp_ignore, Idle}, /* Receive_OPEN_message */
{bgp_ignore, Idle}, /* Receive_KEEPALIVE_message */
{bgp_ignore, Idle}, /* Receive_UPDATE_message */
{bgp_stop_with_error, Idle}, /* Receive_NOTIFICATION_message */
},
{
/* OpenSent, */
{bgp_ignore, OpenSent}, /* BGP_Start */
{bgp_stop, Idle}, /* BGP_Stop */
{bgp_stop, Idle}, /* TCP_connection_open */
{bgp_stop, Active}, /* TCP_connection_closed */
{bgp_ignore, Idle}, /* TCP_connection_open_failed */
{bgp_stop, Idle}, /* TCP_fatal_error */
{bgp_ignore, Idle}, /* ConnectRetry_timer_expired */
{bgp_fsm_holdtime_expire, Idle}, /* Hold_Timer_expired */
{bgp_ignore, Idle}, /* KeepAlive_timer_expired */
{bgp_fsm_open, OpenConfirm}, /* Receive_OPEN_message */
{bgp_ignore, Idle}, /* Receive_KEEPALIVE_message */
{bgp_ignore, Idle}, /* Receive_UPDATE_message */
{bgp_stop_with_error, Idle}, /* Receive_NOTIFICATION_message */
},
{
/* OpenConfirm, */
{bgp_ignore, OpenConfirm}, /* BGP_Start */
{bgp_stop, Idle}, /* BGP_Stop */
{bgp_stop, Idle}, /* TCP_connection_open */
{bgp_stop, Idle}, /* TCP_connection_closed */
{bgp_stop, Idle}, /* TCP_connection_open_failed */
{bgp_stop, Idle}, /* TCP_fatal_error */
{bgp_ignore, Idle}, /* ConnectRetry_timer_expired */
{bgp_fsm_holdtime_expire, Idle}, /* Hold_Timer_expired */
{bgp_ignore, OpenConfirm}, /* KeepAlive_timer_expired */
{bgp_ignore, Idle}, /* Receive_OPEN_message */
{bgp_establish, Established}, /* Receive_KEEPALIVE_message */
{bgp_ignore, Idle}, /* Receive_UPDATE_message */
{bgp_stop_with_error, Idle}, /* Receive_NOTIFICATION_message */
},
{
/* Established, */
{bgp_ignore, Established}, /* BGP_Start */
{bgp_stop, Idle}, /* BGP_Stop */
{bgp_stop, Idle}, /* TCP_connection_open */
{bgp_stop, Idle}, /* TCP_connection_closed */
{bgp_ignore, Idle}, /* TCP_connection_open_failed */
{bgp_stop, Idle}, /* TCP_fatal_error */
{bgp_ignore, Idle}, /* ConnectRetry_timer_expired */
{bgp_fsm_holdtime_expire, Idle}, /* Hold_Timer_expired */
{bgp_fsm_keepalive_expire, Established}, /* KeepAlive_timer_expired */
{bgp_stop, Idle}, /* Receive_OPEN_message */
{bgp_fsm_keepalive, Established}, /* Receive_KEEPALIVE_message */
{bgp_fsm_update, Established}, /* Receive_UPDATE_message */
{bgp_stop_with_error, Idle}, /* Receive_NOTIFICATION_message */
},
};
static char *bgp_event_str[] =
{
NULL,
"BGP_Start",
"BGP_Stop",
"TCP_connection_open",
"TCP_connection_closed",
"TCP_connection_open_failed",
"TCP_fatal_error",
"ConnectRetry_timer_expired",
"Hold_Timer_expired",
"KeepAlive_timer_expired",
"Receive_OPEN_message",
"Receive_KEEPALIVE_message",
"Receive_UPDATE_message",
"Receive_NOTIFICATION_message"
};
/* Execute event process. */
int
bgp_event (struct thread *thread)
{
int ret;
int event;
int next;
struct peer *peer;
peer = THREAD_ARG (thread);
event = THREAD_VAL (thread);
/* Logging this event. */
next = FSM [peer->status -1][event - 1].next_state;
if (BGP_DEBUG (fsm, FSM))
plog_info (peer->log, "%s [FSM] %s (%s->%s)", peer->host,
bgp_event_str[event],
LOOKUP (bgp_status_msg, peer->status),
LOOKUP (bgp_status_msg, next));
if (BGP_DEBUG (normal, NORMAL)
&& strcmp (LOOKUP (bgp_status_msg, peer->status), LOOKUP (bgp_status_msg, next)))
zlog_info ("%s went from %s to %s",
peer->host,
LOOKUP (bgp_status_msg, peer->status),
LOOKUP (bgp_status_msg, next));
/* Call function. */
ret = (*(FSM [peer->status - 1][event - 1].func))(peer);
/* When function do not want proceed next job return -1. */
if (ret < 0)
return ret;
/* If status is changed. */
if (next != peer->status)
bgp_fsm_change_status (peer, next);
/* Make sure timer is set. */
bgp_timer_set (peer);
return 0;
}

42
bgpd/bgp_fsm.h Normal file
View File

@ -0,0 +1,42 @@
/* BGP-4 Finite State Machine
From RFC1771 [A Border Gateway Protocol 4 (BGP-4)]
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. */
/* Macro for BGP read, write and timer thread. */
#define BGP_READ_ON(T,F,V) THREAD_READ_ON(master,T,F,peer,V)
#define BGP_READ_OFF(X) THREAD_READ_OFF(X)
#define BGP_WRITE_ON(T,F,V) THREAD_WRITE_ON(master,T,F,peer,V)
#define BGP_WRITE_OFF(X) THREAD_WRITE_OFF(X)
#define BGP_TIMER_ON(T,F,V) THREAD_TIMER_ON(master,T,F,peer,V)
#define BGP_TIMER_OFF(X) THREAD_TIMER_OFF(X)
#define BGP_EVENT_ADD(P,E) \
thread_add_event (master, bgp_event, (P), (E))
#define BGP_EVENT_DELETE(P) \
thread_cancel_event (master, (P))
/* Prototypes. */
int bgp_event (struct thread *);
int bgp_stop (struct peer *peer);
void bgp_timer_set (struct peer *);
void bgp_fsm_change_status (struct peer *peer, int status);

285
bgpd/bgp_main.c Normal file
View File

@ -0,0 +1,285 @@
/* Main routine of bgpd.
Copyright (C) 1996, 97, 98, 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 "vector.h"
#include "vty.h"
#include "command.h"
#include "getopt.h"
#include "thread.h"
#include "version.h"
#include "memory.h"
#include "prefix.h"
#include "log.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_attr.h"
#include "bgpd/bgp_mplsvpn.h"
/* bgpd options, we use GNU getopt library. */
struct option longopts[] =
{
{ "daemon", no_argument, NULL, 'd'},
{ "config_file", required_argument, NULL, 'f'},
{ "pid_file", required_argument, NULL, 'i'},
{ "bgp_port", required_argument, NULL, 'p'},
{ "vty_addr", required_argument, NULL, 'A'},
{ "vty_port", required_argument, NULL, 'P'},
{ "retain", no_argument, NULL, 'r'},
{ "no_kernel", no_argument, NULL, 'n'},
{ "version", no_argument, NULL, 'v'},
{ "help", no_argument, NULL, 'h'},
{ 0 }
};
/* Configuration file and directory. */
char config_current[] = BGP_DEFAULT_CONFIG;
char config_default[] = SYSCONFDIR BGP_DEFAULT_CONFIG;
/* Route retain mode flag. */
int retain_mode = 0;
/* Master of threads. */
struct thread_master *master;
/* Manually specified configuration file name. */
char *config_file = NULL;
/* Process ID saved for use by init system */
char *pid_file = PATH_BGPD_PID;
/* VTY port number and address. */
int vty_port = BGP_VTY_PORT;
char *vty_addr = NULL;
/* Help information display. */
static void
usage (char *progname, 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 kernel routing table management and \
redistribution between different routing protocols.\n\n\
-d, --daemon Runs in daemon mode\n\
-f, --config_file Set configuration file name\n\
-i, --pid_file Set process identifier file name\n\
-p, --bgp_port Set bgp protocol's port number\n\
-A, --vty_addr Set vty's bind address\n\
-P, --vty_port Set vty's port number\n\
-r, --retain When program terminates, retain added route by bgpd.\n\
-n, --no_kernel Do not install route to kernel.\n\
-v, --version Print program version\n\
-h, --help Display this help and exit\n\
\n\
Report bugs to %s\n", progname, ZEBRA_BUG_ADDRESS);
}
exit (status);
}
/* SIGHUP handler. */
void
sighup (int sig)
{
zlog (NULL, LOG_INFO, "SIGHUP received");
/* Terminate all thread. */
bgp_terminate ();
bgp_reset ();
zlog_info ("bgpd restarting!");
/* Reload config file. */
vty_read_config (config_file, config_current, config_default);
/* Create VTY's socket */
vty_serv_sock (vty_addr, vty_port ? vty_port : BGP_VTY_PORT, BGP_VTYSH_PATH);
/* Try to return to normal operation. */
}
/* SIGINT handler. */
void
sigint (int sig)
{
zlog (NULL, LOG_INFO, "Terminating on signal");
if (! retain_mode)
bgp_terminate ();
exit (0);
}
/* SIGUSR1 handler. */
void
sigusr1 (int sig)
{
zlog_rotate (NULL);
}
/* Signale 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);
}
/* Initialization of signal handles. */
void
signal_init ()
{
signal_set (SIGHUP, sighup);
signal_set (SIGINT, sigint);
signal_set (SIGTERM, sigint);
signal_set (SIGPIPE, SIG_IGN);
signal_set (SIGUSR1, sigusr1);
}
/* Main routine of bgpd. Treatment of argument and start bgp finite
state machine is handled at here. */
int
main (int argc, char **argv)
{
char *p;
int opt;
int daemon_mode = 0;
char *progname;
struct thread thread;
/* Set umask before anything for security */
umask (0027);
/* Preserve name of myself. */
progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
zlog_default = openzlog (progname, ZLOG_NOLOG, ZLOG_BGP,
LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
/* BGP master init. */
bgp_master_init ();
/* Command line argument treatment. */
while (1)
{
opt = getopt_long (argc, argv, "df:hp:A:P:rnv", longopts, 0);
if (opt == EOF)
break;
switch (opt)
{
case 0:
break;
case 'd':
daemon_mode = 1;
break;
case 'f':
config_file = optarg;
break;
case 'i':
pid_file = optarg;
break;
case 'p':
bm->port = atoi (optarg);
break;
case 'A':
vty_addr = optarg;
break;
case 'P':
vty_port = atoi (optarg);
break;
case 'r':
retain_mode = 1;
break;
case 'n':
bgp_option_set (BGP_OPT_NO_FIB);
break;
case 'v':
print_version (progname);
exit (0);
break;
case 'h':
usage (progname, 0);
break;
default:
usage (progname, 1);
break;
}
}
/* Make thread master. */
master = bm->master;
/* Initializations. */
srand (time (NULL));
signal_init ();
cmd_init (1);
vty_init ();
memory_init ();
/* BGP related initialization. */
bgp_init ();
/* Sort CLI commands. */
sort_node ();
/* Parse config file. */
vty_read_config (config_file, config_current, config_default);
/* Turn into daemon if daemon_mode is set. */
if (daemon_mode)
daemon (0, 0);
/* Process ID file creation. */
pid_output (pid_file);
/* Make bgp vty socket. */
vty_serv_sock (vty_addr, vty_port, BGP_VTYSH_PATH);
/* Print banner. */
zlog_info ("BGPd %s starting: vty@%d, bgp@%d", ZEBRA_VERSION,
vty_port, bm->port);
/* Start finite state machine, here we go! */
while (thread_fetch (master, &thread))
thread_call (&thread);
/* Not reached. */
exit (0);
}

741
bgpd/bgp_mplsvpn.c Normal file
View File

@ -0,0 +1,741 @@
/* MPLS-VPN
Copyright (C) 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. */
#include <zebra.h>
#include "command.h"
#include "prefix.h"
#include "log.h"
#include "memory.h"
#include "stream.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_table.h"
#include "bgpd/bgp_route.h"
#include "bgpd/bgp_attr.h"
#include "bgpd/bgp_mplsvpn.h"
int route_vty_out (struct vty *, struct prefix *, struct bgp_info *, int, safi_t);
int route_vty_out_tag (struct vty *, struct prefix *, struct bgp_info *, int, safi_t);
void route_vty_out_tmp (struct vty *, struct prefix *, struct attr *, safi_t);
u_int16_t
decode_rd_type (u_char *pnt)
{
u_int16_t v;
v = ((u_int16_t) *pnt++ << 8);
v |= (u_int16_t) *pnt;
return v;
}
u_int32_t
decode_label (u_char *pnt)
{
u_int32_t l;
l = ((u_int32_t) *pnt++ << 12);
l |= (u_int32_t) *pnt++ << 4;
l |= (u_int32_t) ((*pnt & 0xf0) >> 4);
return l;
}
void
decode_rd_as (u_char *pnt, struct rd_as *rd_as)
{
rd_as->as = (u_int16_t) *pnt++ << 8;
rd_as->as |= (u_int16_t) *pnt++;
rd_as->val = ((u_int32_t) *pnt++ << 24);
rd_as->val |= ((u_int32_t) *pnt++ << 16);
rd_as->val |= ((u_int32_t) *pnt++ << 8);
rd_as->val |= (u_int32_t) *pnt;
}
void
decode_rd_ip (u_char *pnt, struct rd_ip *rd_ip)
{
memcpy (&rd_ip->ip, pnt, 4);
pnt += 4;
rd_ip->val = ((u_int16_t) *pnt++ << 8);
rd_ip->val |= (u_int16_t) *pnt;
}
int bgp_update (struct peer *, struct prefix *, struct attr *,
afi_t, safi_t, int, int, struct prefix_rd *, u_char *);
int bgp_withdraw (struct peer *, struct prefix *, struct attr *,
int, int, int, int, struct prefix_rd *, u_char *);
int
bgp_nlri_parse_vpnv4 (struct peer *peer, struct attr *attr,
struct bgp_nlri *packet)
{
u_char *pnt;
u_char *lim;
struct prefix p;
int psize;
int prefixlen;
u_int32_t label;
u_int16_t type;
struct rd_as rd_as;
struct rd_ip rd_ip;
struct prefix_rd prd;
u_char *tagpnt;
/* Check peer status. */
if (peer->status != Established)
return 0;
/* Make prefix_rd */
prd.family = AF_UNSPEC;
prd.prefixlen = 64;
pnt = packet->nlri;
lim = pnt + packet->length;
for (; pnt < lim; pnt += psize)
{
/* Clear prefix structure. */
memset (&p, 0, sizeof (struct prefix));
/* Fetch prefix length. */
prefixlen = *pnt++;
p.family = AF_INET;
psize = PSIZE (prefixlen);
if (prefixlen < 88)
{
zlog_err ("prefix length is less than 88: %d", prefixlen);
return -1;
}
label = decode_label (pnt);
/* Copyr label to prefix. */
tagpnt = pnt;;
/* Copy routing distinguisher to rd. */
memcpy (&prd.val, pnt + 3, 8);
/* Decode RD type. */
type = decode_rd_type (pnt + 3);
/* Decode RD value. */
if (type == RD_TYPE_AS)
decode_rd_as (pnt + 5, &rd_as);
else if (type == RD_TYPE_IP)
decode_rd_ip (pnt + 5, &rd_ip);
else
{
zlog_err ("Invalid RD type %d", type);
return -1;
}
p.prefixlen = prefixlen - 88;
memcpy (&p.u.prefix, pnt + 11, psize - 11);
#if 0
if (type == RD_TYPE_AS)
zlog_info ("prefix %ld:%ld:%ld:%s/%d", label, rd_as.as, rd_as.val,
inet_ntoa (p.u.prefix4), p.prefixlen);
else if (type == RD_TYPE_IP)
zlog_info ("prefix %ld:%s:%ld:%s/%d", label, inet_ntoa (rd_ip.ip),
rd_ip.val, inet_ntoa (p.u.prefix4), p.prefixlen);
#endif /* 0 */
if (pnt + psize > lim)
return -1;
if (attr)
bgp_update (peer, &p, attr, AFI_IP, SAFI_MPLS_VPN,
ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt);
else
bgp_withdraw (peer, &p, attr, AFI_IP, SAFI_MPLS_VPN,
ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt);
}
/* Packet length consistency check. */
if (pnt != lim)
return -1;
return 0;
}
int
str2prefix_rd (u_char *str, struct prefix_rd *prd)
{
int ret;
u_char *p;
u_char *p2;
struct stream *s;
u_char *half;
struct in_addr addr;
s = stream_new (8);
prd->family = AF_UNSPEC;
prd->prefixlen = 64;
p = strchr (str, ':');
if (! p)
return 0;
if (! all_digit (p + 1))
return 0;
half = XMALLOC (MTYPE_TMP, (p - str) + 1);
memcpy (half, str, (p - str));
half[p - str] = '\0';
p2 = strchr (str, '.');
if (! p2)
{
if (! all_digit (half))
{
XFREE (MTYPE_TMP, half);
return 0;
}
stream_putw (s, RD_TYPE_AS);
stream_putw (s, atoi (half));
stream_putl (s, atol (p + 1));
}
else
{
ret = inet_aton (half, &addr);
if (! ret)
{
XFREE (MTYPE_TMP, half);
return 0;
}
stream_putw (s, RD_TYPE_IP);
stream_put_in_addr (s, &addr);
stream_putw (s, atol (p + 1));
}
memcpy (prd->val, s->data, 8);
return 1;
}
int
str2tag (u_char *str, u_char *tag)
{
u_int32_t l;
l = atol (str);
tag[0] = (u_char)(l >> 12);
tag[1] = (u_char)(l >> 4);
tag[2] = (u_char)(l << 4);
return 1;
}
char *
prefix_rd2str (struct prefix_rd *prd, char *buf, size_t size)
{
u_char *pnt;
u_int16_t type;
struct rd_as rd_as;
struct rd_ip rd_ip;
if (size < RD_ADDRSTRLEN)
return NULL;
pnt = prd->val;
type = decode_rd_type (pnt);
if (type == RD_TYPE_AS)
{
decode_rd_as (pnt + 2, &rd_as);
snprintf (buf, size, "%d:%d", rd_as.as, rd_as.val);
return buf;
}
else if (type == RD_TYPE_IP)
{
decode_rd_ip (pnt + 2, &rd_ip);
snprintf (buf, size, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
return buf;
}
return NULL;
}
/* For testing purpose, static route of MPLS-VPN. */
DEFUN (vpnv4_network,
vpnv4_network_cmd,
"network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
"Specify a network to announce via BGP\n"
"IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
"Specify Route Distinguisher\n"
"VPN Route Distinguisher\n"
"BGP tag\n"
"tag value\n")
{
return bgp_static_set_vpnv4 (vty, argv[0], argv[1], argv[2]);
}
/* For testing purpose, static route of MPLS-VPN. */
DEFUN (no_vpnv4_network,
no_vpnv4_network_cmd,
"no network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
NO_STR
"Specify a network to announce via BGP\n"
"IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
"Specify Route Distinguisher\n"
"VPN Route Distinguisher\n"
"BGP tag\n"
"tag value\n")
{
return bgp_static_unset_vpnv4 (vty, argv[0], argv[1], argv[2]);
}
int
show_adj_route_vpn (struct vty *vty, struct peer *peer, struct prefix_rd *prd)
{
struct bgp *bgp;
struct bgp_table *table;
struct bgp_node *rn;
struct bgp_node *rm;
struct attr *attr;
int rd_header;
int header = 1;
char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s";
bgp = bgp_get_default ();
if (bgp == NULL)
{
vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
return CMD_WARNING;
}
for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rn;
rn = bgp_route_next (rn))
{
if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
continue;
if ((table = rn->info) != NULL)
{
rd_header = 1;
for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
if ((attr = rm->info) != NULL)
{
if (header)
{
vty_out (vty, "BGP table version is 0, local router ID is %s%s",
inet_ntoa (bgp->router_id), VTY_NEWLINE);
vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
VTY_NEWLINE);
vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
VTY_NEWLINE, VTY_NEWLINE);
vty_out (vty, v4_header, VTY_NEWLINE);
header = 0;
}
if (rd_header)
{
u_int16_t type;
struct rd_as rd_as;
struct rd_ip rd_ip;
u_char *pnt;
pnt = rn->p.u.val;
/* Decode RD type. */
type = decode_rd_type (pnt);
/* Decode RD value. */
if (type == RD_TYPE_AS)
decode_rd_as (pnt + 2, &rd_as);
else if (type == RD_TYPE_IP)
decode_rd_ip (pnt + 2, &rd_ip);
vty_out (vty, "Route Distinguisher: ");
if (type == RD_TYPE_AS)
vty_out (vty, "%d:%d", rd_as.as, rd_as.val);
else if (type == RD_TYPE_IP)
vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
vty_out (vty, "%s", VTY_NEWLINE);
rd_header = 0;
}
route_vty_out_tmp (vty, &rm->p, attr, SAFI_MPLS_VPN);
}
}
}
return CMD_SUCCESS;
}
enum bgp_show_type
{
bgp_show_type_normal,
bgp_show_type_regexp,
bgp_show_type_prefix_list,
bgp_show_type_filter_list,
bgp_show_type_neighbor,
bgp_show_type_cidr_only,
bgp_show_type_prefix_longer,
bgp_show_type_community_all,
bgp_show_type_community,
bgp_show_type_community_exact,
bgp_show_type_community_list,
bgp_show_type_community_list_exact
};
int
bgp_show_mpls_vpn (struct vty *vty, struct prefix_rd *prd, enum bgp_show_type type,
void *output_arg, int tags)
{
struct bgp *bgp;
struct bgp_table *table;
struct bgp_node *rn;
struct bgp_node *rm;
struct bgp_info *ri;
int rd_header;
int header = 1;
char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s";
char v4_header_tag[] = " Network Next Hop In tag/Out tag%s";
bgp = bgp_get_default ();
if (bgp == NULL)
{
vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
return CMD_WARNING;
}
for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rn; rn = bgp_route_next (rn))
{
if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
continue;
if ((table = rn->info) != NULL)
{
rd_header = 1;
for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
for (ri = rm->info; ri; ri = ri->next)
{
if (type == bgp_show_type_neighbor)
{
union sockunion *su = output_arg;
if (ri->peer->su_remote == NULL || ! sockunion_same(ri->peer->su_remote, su))
continue;
}
if (header)
{
if (tags)
vty_out (vty, v4_header_tag, VTY_NEWLINE);
else
{
vty_out (vty, "BGP table version is 0, local router ID is %s%s",
inet_ntoa (bgp->router_id), VTY_NEWLINE);
vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
VTY_NEWLINE);
vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
VTY_NEWLINE, VTY_NEWLINE);
vty_out (vty, v4_header, VTY_NEWLINE);
}
header = 0;
}
if (rd_header)
{
u_int16_t type;
struct rd_as rd_as;
struct rd_ip rd_ip;
u_char *pnt;
pnt = rn->p.u.val;
/* Decode RD type. */
type = decode_rd_type (pnt);
/* Decode RD value. */
if (type == RD_TYPE_AS)
decode_rd_as (pnt + 2, &rd_as);
else if (type == RD_TYPE_IP)
decode_rd_ip (pnt + 2, &rd_ip);
vty_out (vty, "Route Distinguisher: ");
if (type == RD_TYPE_AS)
vty_out (vty, "%d:%d", rd_as.as, rd_as.val);
else if (type == RD_TYPE_IP)
vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
vty_out (vty, "%s", VTY_NEWLINE);
rd_header = 0;
}
if (tags)
route_vty_out_tag (vty, &rm->p, ri, 0, SAFI_MPLS_VPN);
else
route_vty_out (vty, &rm->p, ri, 0, SAFI_MPLS_VPN);
}
}
}
return CMD_SUCCESS;
}
DEFUN (show_ip_bgp_vpnv4_all,
show_ip_bgp_vpnv4_all_cmd,
"show ip bgp vpnv4 all",
SHOW_STR
IP_STR
BGP_STR
"Display VPNv4 NLRI specific information\n"
"Display information about all VPNv4 NLRIs\n")
{
return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_normal, NULL, 0);
}
DEFUN (show_ip_bgp_vpnv4_rd,
show_ip_bgp_vpnv4_rd_cmd,
"show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn",
SHOW_STR
IP_STR
BGP_STR
"Display VPNv4 NLRI specific information\n"
"Display information for a route distinguisher\n"
"VPN Route Distinguisher\n")
{
int ret;
struct prefix_rd prd;
ret = str2prefix_rd (argv[0], &prd);
if (! ret)
{
vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
return CMD_WARNING;
}
return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_normal, NULL, 0);
}
DEFUN (show_ip_bgp_vpnv4_all_tags,
show_ip_bgp_vpnv4_all_tags_cmd,
"show ip bgp vpnv4 all tags",
SHOW_STR
IP_STR
BGP_STR
"Display VPNv4 NLRI specific information\n"
"Display information about all VPNv4 NLRIs\n"
"Display BGP tags for prefixes\n")
{
return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_normal, NULL, 1);
}
DEFUN (show_ip_bgp_vpnv4_rd_tags,
show_ip_bgp_vpnv4_rd_tags_cmd,
"show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn tags",
SHOW_STR
IP_STR
BGP_STR
"Display VPNv4 NLRI specific information\n"
"Display information for a route distinguisher\n"
"VPN Route Distinguisher\n"
"Display BGP tags for prefixes\n")
{
int ret;
struct prefix_rd prd;
ret = str2prefix_rd (argv[0], &prd);
if (! ret)
{
vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
return CMD_WARNING;
}
return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_normal, NULL, 1);
}
DEFUN (show_ip_bgp_vpnv4_all_neighbor_routes,
show_ip_bgp_vpnv4_all_neighbor_routes_cmd,
"show ip bgp vpnv4 all neighbors A.B.C.D routes",
SHOW_STR
IP_STR
BGP_STR
"Display VPNv4 NLRI specific information\n"
"Display information about all VPNv4 NLRIs\n"
"Detailed information on TCP and BGP neighbor connections\n"
"Neighbor to display information about\n"
"Display routes learned from neighbor\n")
{
union sockunion *su;
struct peer *peer;
su = sockunion_str2su (argv[0]);
if (su == NULL)
{
vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
return CMD_WARNING;
}
peer = peer_lookup (NULL, su);
if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
{
vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
return CMD_WARNING;
}
return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_neighbor, su, 0);
}
DEFUN (show_ip_bgp_vpnv4_rd_neighbor_routes,
show_ip_bgp_vpnv4_rd_neighbor_routes_cmd,
"show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D routes",
SHOW_STR
IP_STR
BGP_STR
"Display VPNv4 NLRI specific information\n"
"Display information for a route distinguisher\n"
"VPN Route Distinguisher\n"
"Detailed information on TCP and BGP neighbor connections\n"
"Neighbor to display information about\n"
"Display routes learned from neighbor\n")
{
int ret;
union sockunion *su;
struct peer *peer;
struct prefix_rd prd;
ret = str2prefix_rd (argv[0], &prd);
if (! ret)
{
vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
return CMD_WARNING;
}
su = sockunion_str2su (argv[1]);
if (su == NULL)
{
vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
return CMD_WARNING;
}
peer = peer_lookup (NULL, su);
if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
{
vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
return CMD_WARNING;
}
return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_neighbor, su, 0);
}
DEFUN (show_ip_bgp_vpnv4_all_neighbor_advertised_routes,
show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd,
"show ip bgp vpnv4 all neighbors A.B.C.D advertised-routes",
SHOW_STR
IP_STR
BGP_STR
"Display VPNv4 NLRI specific information\n"
"Display information about all VPNv4 NLRIs\n"
"Detailed information on TCP and BGP neighbor connections\n"
"Neighbor to display information about\n"
"Display the routes advertised to a BGP neighbor\n")
{
int ret;
struct peer *peer;
union sockunion su;
ret = str2sockunion (argv[0], &su);
if (ret < 0)
{
vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE);
return CMD_WARNING;
}
peer = peer_lookup (NULL, &su);
if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
{
vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
return CMD_WARNING;
}
return show_adj_route_vpn (vty, peer, NULL);
}
DEFUN (show_ip_bgp_vpnv4_rd_neighbor_advertised_routes,
show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd,
"show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D advertised-routes",
SHOW_STR
IP_STR
BGP_STR
"Display VPNv4 NLRI specific information\n"
"Display information for a route distinguisher\n"
"VPN Route Distinguisher\n"
"Detailed information on TCP and BGP neighbor connections\n"
"Neighbor to display information about\n"
"Display the routes advertised to a BGP neighbor\n")
{
int ret;
struct peer *peer;
struct prefix_rd prd;
union sockunion su;
ret = str2sockunion (argv[1], &su);
if (ret < 0)
{
vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE);
return CMD_WARNING;
}
peer = peer_lookup (NULL, &su);
if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
{
vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
return CMD_WARNING;
}
ret = str2prefix_rd (argv[0], &prd);
if (! ret)
{
vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
return CMD_WARNING;
}
return show_adj_route_vpn (vty, peer, &prd);
}
void
bgp_mplsvpn_init ()
{
install_element (BGP_VPNV4_NODE, &vpnv4_network_cmd);
install_element (BGP_VPNV4_NODE, &no_vpnv4_network_cmd);
install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_cmd);
install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_cmd);
install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_tags_cmd);
install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_tags_cmd);
install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_neighbor_routes_cmd);
install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_neighbor_routes_cmd);
install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd);
install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_tags_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_tags_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_neighbor_routes_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_neighbor_routes_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd);
}

45
bgpd/bgp_mplsvpn.h Normal file
View File

@ -0,0 +1,45 @@
/* MPLS-VPN
Copyright (C) 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 RD_TYPE_AS 0
#define RD_TYPE_IP 1
#define RD_ADDRSTRLEN 28
struct rd_as
{
u_int16_t type;
as_t as;
u_int32_t val;
};
struct rd_ip
{
u_int16_t type;
struct in_addr ip;
u_int16_t val;
};
void bgp_mplsvpn_init ();
int bgp_nlri_parse_vpnv4 (struct peer *, struct attr *, struct bgp_nlri *);
u_int32_t decode_label (u_char *);
int str2prefix_rd (u_char *, struct prefix_rd *);
int str2tag (u_char *, u_char *);
char *prefix_rd2str (struct prefix_rd *, char *, size_t);

381
bgpd/bgp_network.c Normal file
View File

@ -0,0 +1,381 @@
/* BGP network related fucntions
Copyright (C) 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 "thread.h"
#include "sockunion.h"
#include "memory.h"
#include "log.h"
#include "if.h"
#include "prefix.h"
#include "command.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_fsm.h"
#include "bgpd/bgp_attr.h"
#include "bgpd/bgp_debug.h"
#include "bgpd/bgp_network.h"
/* Accept bgp connection. */
static int
bgp_accept (struct thread *thread)
{
int bgp_sock;
int accept_sock;
union sockunion su;
struct peer *peer;
struct peer *peer1;
struct bgp *bgp;
char buf[SU_ADDRSTRLEN];
/* Regiser accept thread. */
accept_sock = THREAD_FD (thread);
bgp = THREAD_ARG (thread);
if (accept_sock < 0)
{
zlog_err ("accept_sock is nevative value %d", accept_sock);
return -1;
}
thread_add_read (master, bgp_accept, bgp, accept_sock);
/* Accept client connection. */
bgp_sock = sockunion_accept (accept_sock, &su);
if (bgp_sock < 0)
{
zlog_err ("[Error] BGP socket accept failed (%s)", strerror (errno));
return -1;
}
if (BGP_DEBUG (events, EVENTS))
zlog_info ("[Event] BGP connection from host %s", inet_sutop (&su, buf));
/* Check remote IP address */
peer1 = peer_lookup (bgp, &su);
if (! peer1 || peer1->status == Idle)
{
if (BGP_DEBUG (events, EVENTS))
{
if (! peer1)
zlog_info ("[Event] BGP connection IP address %s is not configured",
inet_sutop (&su, buf));
else
zlog_info ("[Event] BGP connection IP address %s is Idle state",
inet_sutop (&su, buf));
}
close (bgp_sock);
return -1;
}
/* In case of peer is EBGP, we should set TTL for this connection. */
if (peer_sort (peer1) == BGP_PEER_EBGP)
sockopt_ttl (peer1->su.sa.sa_family, bgp_sock, peer1->ttl);
if (! bgp)
bgp = peer1->bgp;
/* Make dummy peer until read Open packet. */
if (BGP_DEBUG (events, EVENTS))
zlog_info ("[Event] Make dummy peer structure until read Open packet");
{
char buf[SU_ADDRSTRLEN + 1];
peer = peer_create_accept (bgp);
SET_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER);
peer->su = su;
peer->fd = bgp_sock;
peer->status = Active;
peer->local_id = peer1->local_id;
/* Make peer's address string. */
sockunion2str (&su, buf, SU_ADDRSTRLEN);
peer->host = strdup (buf);
}
BGP_EVENT_ADD (peer, TCP_connection_open);
return 0;
}
/* BGP socket bind. */
int
bgp_bind (struct peer *peer)
{
#ifdef SO_BINDTODEVICE
int ret;
struct ifreq ifreq;
if (! peer->ifname)
return 0;
strncpy ((char *)&ifreq.ifr_name, peer->ifname, sizeof (ifreq.ifr_name));
ret = setsockopt (peer->fd, SOL_SOCKET, SO_BINDTODEVICE,
&ifreq, sizeof (ifreq));
if (ret < 0)
{
zlog (peer->log, LOG_INFO, "bind to interface %s failed", peer->ifname);
return ret;
}
#endif /* SO_BINDTODEVICE */
return 0;
}
int
bgp_bind_address (int sock, struct in_addr *addr)
{
int ret;
struct sockaddr_in local;
memset (&local, 0, sizeof (struct sockaddr_in));
local.sin_family = AF_INET;
#ifdef HAVE_SIN_LEN
local.sin_len = sizeof(struct sockaddr_in);
#endif /* HAVE_SIN_LEN */
memcpy (&local.sin_addr, addr, sizeof (struct in_addr));
ret = bind (sock, (struct sockaddr *)&local, sizeof (struct sockaddr_in));
if (ret < 0)
;
return 0;
}
struct in_addr *
bgp_update_address (struct interface *ifp)
{
struct prefix_ipv4 *p;
struct connected *connected;
listnode node;
for (node = listhead (ifp->connected); node; nextnode (node))
{
connected = getdata (node);
p = (struct prefix_ipv4 *) connected->address;
if (p->family == AF_INET)
return &p->prefix;
}
return NULL;
}
/* Update source selection. */
void
bgp_update_source (struct peer *peer)
{
struct interface *ifp;
struct in_addr *addr;
/* Source is specified with interface name. */
if (peer->update_if)
{
ifp = if_lookup_by_name (peer->update_if);
if (! ifp)
return;
addr = bgp_update_address (ifp);
if (! addr)
return;
bgp_bind_address (peer->fd, addr);
}
/* Source is specified with IP address. */
if (peer->update_source)
sockunion_bind (peer->fd, peer->update_source, 0, peer->update_source);
}
/* BGP try to connect to the peer. */
int
bgp_connect (struct peer *peer)
{
unsigned int ifindex = 0;
/* Make socket for the peer. */
peer->fd = sockunion_socket (&peer->su);
if (peer->fd < 0)
return -1;
/* If we can get socket for the peer, adjest TTL and make connection. */
if (peer_sort (peer) == BGP_PEER_EBGP)
sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl);
sockopt_reuseaddr (peer->fd);
sockopt_reuseport (peer->fd);
/* Bind socket. */
bgp_bind (peer);
/* Update source bind. */
bgp_update_source (peer);
#ifdef HAVE_IPV6
if (peer->ifname)
ifindex = if_nametoindex (peer->ifname);
#endif /* HAVE_IPV6 */
if (BGP_DEBUG (events, EVENTS))
plog_info (peer->log, "%s [Event] Connect start to %s fd %d",
peer->host, peer->host, peer->fd);
/* Connect to the remote peer. */
return sockunion_connect (peer->fd, &peer->su, htons (peer->port), ifindex);
}
/* After TCP connection is established. Get local address and port. */
void
bgp_getsockname (struct peer *peer)
{
if (peer->su_local)
{
XFREE (MTYPE_TMP, peer->su_local);
peer->su_local = NULL;
}
if (peer->su_remote)
{
XFREE (MTYPE_TMP, peer->su_remote);
peer->su_remote = NULL;
}
peer->su_local = sockunion_getsockname (peer->fd);
peer->su_remote = sockunion_getpeername (peer->fd);
bgp_nexthop_set (peer->su_local, peer->su_remote, &peer->nexthop, peer);
}
/* IPv6 supported version of BGP server socket setup. */
#if defined (HAVE_IPV6) && ! defined (NRL)
int
bgp_socket (struct bgp *bgp, unsigned short port)
{
int ret;
struct addrinfo req;
struct addrinfo *ainfo;
struct addrinfo *ainfo_save;
int sock = 0;
char port_str[BUFSIZ];
memset (&req, 0, sizeof (struct addrinfo));
req.ai_flags = AI_PASSIVE;
req.ai_family = AF_UNSPEC;
req.ai_socktype = SOCK_STREAM;
sprintf (port_str, "%d", port);
port_str[sizeof (port_str) - 1] = '\0';
ret = getaddrinfo (NULL, port_str, &req, &ainfo);
if (ret != 0)
{
zlog_err ("getaddrinfo: %s", gai_strerror (ret));
return -1;
}
ainfo_save = ainfo;
do
{
if (ainfo->ai_family != AF_INET && ainfo->ai_family != AF_INET6)
continue;
sock = socket (ainfo->ai_family, ainfo->ai_socktype, ainfo->ai_protocol);
if (sock < 0)
{
zlog_err ("socket: %s", strerror (errno));
continue;
}
sockopt_reuseaddr (sock);
sockopt_reuseport (sock);
ret = bind (sock, ainfo->ai_addr, ainfo->ai_addrlen);
if (ret < 0)
{
zlog_err ("bind: %s", strerror (errno));
close (sock);
continue;
}
ret = listen (sock, 3);
if (ret < 0)
{
zlog_err ("listen: %s", strerror (errno));
close (sock);
continue;
}
thread_add_read (master, bgp_accept, bgp, sock);
}
while ((ainfo = ainfo->ai_next) != NULL);
freeaddrinfo (ainfo_save);
return sock;
}
#else
/* Traditional IPv4 only version. */
int
bgp_socket (struct bgp *bgp, unsigned short port)
{
int sock;
int socklen;
struct sockaddr_in sin;
int ret;
sock = socket (AF_INET, SOCK_STREAM, 0);
if (sock < 0)
{
zlog_err ("socket: %s", strerror (errno));
return sock;
}
sockopt_reuseaddr (sock);
sockopt_reuseport (sock);
memset (&sin, 0, sizeof (struct sockaddr_in));
sin.sin_family = AF_INET;
sin.sin_port = htons (port);
socklen = sizeof (struct sockaddr_in);
#ifdef HAVE_SIN_LEN
sin.sin_len = socklen;
#endif /* HAVE_SIN_LEN */
ret = bind (sock, (struct sockaddr *) &sin, socklen);
if (ret < 0)
{
zlog_err ("bind: %s", strerror (errno));
close (sock);
return ret;
}
ret = listen (sock, 3);
if (ret < 0)
{
zlog_err ("listen: %s", strerror (errno));
close (sock);
return ret;
}
thread_add_read (bm->master, bgp_accept, bgp, sock);
return sock;
}
#endif /* HAVE_IPV6 && !NRL */

23
bgpd/bgp_network.h Normal file
View File

@ -0,0 +1,23 @@
/* BGP network related header
Copyright (C) 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. */
int bgp_socket (struct bgp *, unsigned short);
int bgp_connect (struct peer *);
void bgp_getsockname (struct peer *);

1405
bgpd/bgp_nexthop.c Normal file

File diff suppressed because it is too large Load Diff

52
bgpd/bgp_nexthop.h Normal file
View File

@ -0,0 +1,52 @@
/* BGP nexthop scan
Copyright (C) 2000 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. */
#define BGP_SCAN_INTERVAL_DEFAULT 60
#define BGP_IMPORT_INTERVAL_DEFAULT 15
/* BGP nexthop cache value structure. */
struct bgp_nexthop_cache
{
/* This nexthop exists in IGP. */
u_char valid;
/* Nexthop is changed. */
u_char changed;
/* Nexthop is changed. */
u_char metricchanged;
/* IGP route's metric. */
u_int32_t metric;
/* Nexthop number and nexthop linked list.*/
u_char nexthop_num;
struct nexthop *nexthop;
};
void bgp_scan_init ();
int bgp_nexthop_lookup (afi_t, struct peer *peer, struct bgp_info *,
int *, int *);
void bgp_connected_add (struct connected *c);
void bgp_connected_delete (struct connected *c);
int bgp_multiaccess_check_v4 (struct in_addr, char *);
int bgp_config_write_scan_time (struct vty *);
int bgp_nexthop_check_ebgp (afi_t, struct attr *);
int bgp_nexthop_self (afi_t, struct attr *);

793
bgpd/bgp_open.c Normal file
View File

@ -0,0 +1,793 @@
/* BGP open message handling
Copyright (C) 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 "linklist.h"
#include "prefix.h"
#include "stream.h"
#include "thread.h"
#include "log.h"
#include "command.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_attr.h"
#include "bgpd/bgp_debug.h"
#include "bgpd/bgp_fsm.h"
#include "bgpd/bgp_packet.h"
#include "bgpd/bgp_open.h"
/* BGP-4 Multiprotocol Extentions lead us to the complex world. We can
negotiate remote peer supports extentions or not. But if
remote-peer doesn't supports negotiation process itself. We would
like to do manual configuration.
So there is many configurable point. First of all we want set each
peer whether we send capability negotiation to the peer or not.
Next, if we send capability to the peer we want to set my capabilty
inforation at each peer. */
void
bgp_capability_vty_out (struct vty *vty, struct peer *peer)
{
u_char *pnt;
u_char *end;
struct capability cap;
pnt = peer->notify.data;
end = pnt + peer->notify.length;
while (pnt < end)
{
memcpy(&cap, pnt, sizeof(struct capability));
if (pnt + 2 > end)
return;
if (pnt + (cap.length + 2) > end)
return;
if (cap.code == CAPABILITY_CODE_MP)
{
vty_out (vty, " Capability error for: Multi protocol ");
switch (ntohs (cap.mpc.afi))
{
case AFI_IP:
vty_out (vty, "AFI IPv4, ");
break;
case AFI_IP6:
vty_out (vty, "AFI IPv6, ");
break;
default:
vty_out (vty, "AFI Unknown %d, ", ntohs (cap.mpc.afi));
break;
}
switch (cap.mpc.safi)
{
case SAFI_UNICAST:
vty_out (vty, "SAFI Unicast");
break;
case SAFI_MULTICAST:
vty_out (vty, "SAFI Multicast");
break;
case SAFI_UNICAST_MULTICAST:
vty_out (vty, "SAFI Unicast Multicast");
break;
case BGP_SAFI_VPNV4:
vty_out (vty, "SAFI MPLS-VPN");
break;
default:
vty_out (vty, "SAFI Unknown %d ", cap.mpc.safi);
break;
}
vty_out (vty, "%s", VTY_NEWLINE);
}
else if (cap.code >= 128)
vty_out (vty, " Capability error: vendor specific capability code %d",
cap.code);
else
vty_out (vty, " Capability error: unknown capability code %d",
cap.code);
pnt += cap.length + 2;
}
}
/* Set negotiated capability value. */
int
bgp_capability_mp (struct peer *peer, struct capability *cap)
{
if (ntohs (cap->mpc.afi) == AFI_IP)
{
if (cap->mpc.safi == SAFI_UNICAST)
{
peer->afc_recv[AFI_IP][SAFI_UNICAST] = 1;
if (peer->afc[AFI_IP][SAFI_UNICAST])
peer->afc_nego[AFI_IP][SAFI_UNICAST] = 1;
else
return -1;
}
else if (cap->mpc.safi == SAFI_MULTICAST)
{
peer->afc_recv[AFI_IP][SAFI_MULTICAST] = 1;
if (peer->afc[AFI_IP][SAFI_MULTICAST])
peer->afc_nego[AFI_IP][SAFI_MULTICAST] = 1;
else
return -1;
}
else if (cap->mpc.safi == BGP_SAFI_VPNV4)
{
peer->afc_recv[AFI_IP][SAFI_MPLS_VPN] = 1;
if (peer->afc[AFI_IP][SAFI_MPLS_VPN])
peer->afc_nego[AFI_IP][SAFI_MPLS_VPN] = 1;
else
return -1;
}
else
return -1;
}
#ifdef HAVE_IPV6
else if (ntohs (cap->mpc.afi) == AFI_IP6)
{
if (cap->mpc.safi == SAFI_UNICAST)
{
peer->afc_recv[AFI_IP6][SAFI_UNICAST] = 1;
if (peer->afc[AFI_IP6][SAFI_UNICAST])
peer->afc_nego[AFI_IP6][SAFI_UNICAST] = 1;
else
return -1;
}
else if (cap->mpc.safi == SAFI_MULTICAST)
{
peer->afc_recv[AFI_IP6][SAFI_MULTICAST] = 1;
if (peer->afc[AFI_IP6][SAFI_MULTICAST])
peer->afc_nego[AFI_IP6][SAFI_MULTICAST] = 1;
else
return -1;
}
else
return -1;
}
#endif /* HAVE_IPV6 */
else
{
/* Unknown Address Family. */
return -1;
}
return 0;
}
void
bgp_capability_orf_not_support (struct peer *peer, afi_t afi, safi_t safi,
u_char type, u_char mode)
{
if (BGP_DEBUG (normal, NORMAL))
zlog_info ("%s Addr-family %d/%d has ORF type/mode %d/%d not supported",
peer->host, afi, safi, type, mode);
}
int
bgp_capability_orf (struct peer *peer, struct capability *cap,
u_char *pnt)
{
afi_t afi = ntohs(cap->mpc.afi);
safi_t safi = cap->mpc.safi;
u_char number_of_orfs;
u_char type;
u_char mode;
u_int16_t sm_cap = 0; /* capability send-mode receive */
u_int16_t rm_cap = 0; /* capability receive-mode receive */
int i;
/* Check length. */
if (cap->length < 7)
{
zlog_info ("%s ORF Capability length error %d",
peer->host, cap->length);
bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
return -1;
}
if (BGP_DEBUG (normal, NORMAL))
zlog_info ("%s OPEN has ORF CAP(%s) for afi/safi: %u/%u",
peer->host, (cap->code == CAPABILITY_CODE_ORF ?
"new" : "old"), afi, safi);
/* Check AFI and SAFI. */
if ((afi != AFI_IP && afi != AFI_IP6)
|| (safi != SAFI_UNICAST && safi != SAFI_MULTICAST
&& safi != BGP_SAFI_VPNV4))
{
zlog_info ("%s Addr-family %d/%d not supported. Ignoring the ORF capability",
peer->host, afi, safi);
return -1;
}
number_of_orfs = *pnt++;
for (i = 0 ; i < number_of_orfs ; i++)
{
type = *pnt++;
mode = *pnt++;
/* ORF Mode error check */
if (mode != ORF_MODE_BOTH && mode != ORF_MODE_SEND
&& mode != ORF_MODE_RECEIVE)
{
bgp_capability_orf_not_support (peer, afi, safi, type, mode);
continue;
}
/* ORF Type and afi/safi error check */
if (cap->code == CAPABILITY_CODE_ORF)
{
if (type == ORF_TYPE_PREFIX &&
((afi == AFI_IP && safi == SAFI_UNICAST)
|| (afi == AFI_IP && safi == SAFI_MULTICAST)
|| (afi == AFI_IP6 && safi == SAFI_UNICAST)))
{
sm_cap = PEER_CAP_ORF_PREFIX_SM_RCV;
rm_cap = PEER_CAP_ORF_PREFIX_RM_RCV;
if (BGP_DEBUG (normal, NORMAL))
zlog_info ("%s OPEN has Prefixlist ORF(%d) capability as %s for afi/safi: %d/%d",
peer->host, ORF_TYPE_PREFIX, (mode == ORF_MODE_SEND ? "SEND" :
mode == ORF_MODE_RECEIVE ? "RECEIVE" : "BOTH") , afi, safi);
}
else
{
bgp_capability_orf_not_support (peer, afi, safi, type, mode);
continue;
}
}
else if (cap->code == CAPABILITY_CODE_ORF_OLD)
{
if (type == ORF_TYPE_PREFIX_OLD &&
((afi == AFI_IP && safi == SAFI_UNICAST)
|| (afi == AFI_IP && safi == SAFI_MULTICAST)
|| (afi == AFI_IP6 && safi == SAFI_UNICAST)))
{
sm_cap = PEER_CAP_ORF_PREFIX_SM_OLD_RCV;
rm_cap = PEER_CAP_ORF_PREFIX_RM_OLD_RCV;
if (BGP_DEBUG (normal, NORMAL))
zlog_info ("%s OPEN has Prefixlist ORF(%d) capability as %s for afi/safi: %d/%d",
peer->host, ORF_TYPE_PREFIX_OLD, (mode == ORF_MODE_SEND ? "SEND" :
mode == ORF_MODE_RECEIVE ? "RECEIVE" : "BOTH") , afi, safi);
}
else
{
bgp_capability_orf_not_support (peer, afi, safi, type, mode);
continue;
}
}
else
{
bgp_capability_orf_not_support (peer, afi, safi, type, mode);
continue;
}
switch (mode)
{
case ORF_MODE_BOTH:
SET_FLAG (peer->af_cap[afi][safi], sm_cap);
SET_FLAG (peer->af_cap[afi][safi], rm_cap);
break;
case ORF_MODE_SEND:
SET_FLAG (peer->af_cap[afi][safi], sm_cap);
break;
case ORF_MODE_RECEIVE:
SET_FLAG (peer->af_cap[afi][safi], rm_cap);
break;
}
}
return 0;
}
/* Parse given capability. */
int
bgp_capability_parse (struct peer *peer, u_char *pnt, u_char length,
u_char **error)
{
int ret;
u_char *end;
struct capability cap;
end = pnt + length;
while (pnt < end)
{
afi_t afi;
safi_t safi;
/* Fetch structure to the byte stream. */
memcpy (&cap, pnt, sizeof (struct capability));
afi = ntohs(cap.mpc.afi);
safi = cap.mpc.safi;
if (BGP_DEBUG (normal, NORMAL))
zlog_info ("%s OPEN has CAPABILITY code: %d, length %d",
peer->host, cap.code, cap.length);
/* We need at least capability code and capability length. */
if (pnt + 2 > end)
{
zlog_info ("%s Capability length error", peer->host);
bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
return -1;
}
/* Capability length check. */
if (pnt + (cap.length + 2) > end)
{
zlog_info ("%s Capability length error", peer->host);
bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
return -1;
}
/* We know MP Capability Code. */
if (cap.code == CAPABILITY_CODE_MP)
{
if (BGP_DEBUG (normal, NORMAL))
zlog_info ("%s OPEN has MP_EXT CAP for afi/safi: %u/%u",
peer->host, afi, safi);
/* Ignore capability when override-capability is set. */
if (! CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
{
/* Set negotiated value. */
ret = bgp_capability_mp (peer, &cap);
/* Unsupported Capability. */
if (ret < 0)
{
/* Store return data. */
memcpy (*error, &cap, cap.length + 2);
*error += cap.length + 2;
}
}
}
else if (cap.code == CAPABILITY_CODE_REFRESH
|| cap.code == CAPABILITY_CODE_REFRESH_OLD)
{
/* Check length. */
if (cap.length != 0)
{
zlog_info ("%s Route Refresh Capability length error %d",
peer->host, cap.length);
bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
return -1;
}
if (BGP_DEBUG (normal, NORMAL))
zlog_info ("%s OPEN has ROUTE-REFRESH capability(%s) for all address-families",
peer->host,
cap.code == CAPABILITY_CODE_REFRESH_OLD ? "old" : "new");
/* BGP refresh capability */
if (cap.code == CAPABILITY_CODE_REFRESH_OLD)
SET_FLAG (peer->cap, PEER_CAP_REFRESH_OLD_RCV);
else
SET_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV);
}
else if (cap.code == CAPABILITY_CODE_ORF
|| cap.code == CAPABILITY_CODE_ORF_OLD)
bgp_capability_orf (peer, &cap, pnt + sizeof (struct capability));
else if (cap.code == CAPABILITY_CODE_DYNAMIC)
{
/* Check length. */
if (cap.length != 0)
{
zlog_info ("%s Dynamic Capability length error %d",
peer->host, cap.length);
bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
return -1;
}
if (BGP_DEBUG (normal, NORMAL))
zlog_info ("%s OPEN has DYNAMIC capability", peer->host);
SET_FLAG (peer->cap, PEER_CAP_DYNAMIC_RCV);
}
else if (cap.code > 128)
{
/* We don't send Notification for unknown vendor specific
capabilities. It seems reasonable for now... */
zlog_warn ("%s Vendor specific capability %d",
peer->host, cap.code);
}
else
{
zlog_warn ("%s unrecognized capability code: %d - ignored",
peer->host, cap.code);
memcpy (*error, &cap, cap.length + 2);
*error += cap.length + 2;
}
pnt += cap.length + 2;
}
return 0;
}
int
bgp_auth_parse (struct peer *peer, u_char *pnt, size_t length)
{
bgp_notify_send (peer,
BGP_NOTIFY_OPEN_ERR,
BGP_NOTIFY_OPEN_AUTH_FAILURE);
return -1;
}
int
strict_capability_same (struct peer *peer)
{
int i, j;
for (i = AFI_IP; i < AFI_MAX; i++)
for (j = SAFI_UNICAST; j < SAFI_MAX; j++)
if (peer->afc[i][j] != peer->afc_nego[i][j])
return 0;
return 1;
}
/* Parse open option */
int
bgp_open_option_parse (struct peer *peer, u_char length, int *capability)
{
int ret;
u_char *end;
u_char opt_type;
u_char opt_length;
u_char *pnt;
u_char *error;
u_char error_data[BGP_MAX_PACKET_SIZE];
/* Fetch pointer. */
pnt = stream_pnt (peer->ibuf);
ret = 0;
opt_type = 0;
opt_length = 0;
end = pnt + length;
error = error_data;
if (BGP_DEBUG (normal, NORMAL))
zlog_info ("%s rcv OPEN w/ OPTION parameter len: %u",
peer->host, length);
while (pnt < end)
{
/* Check the length. */
if (pnt + 2 > end)
{
zlog_info ("%s Option length error", peer->host);
bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
return -1;
}
/* Fetch option type and length. */
opt_type = *pnt++;
opt_length = *pnt++;
/* Option length check. */
if (pnt + opt_length > end)
{
zlog_info ("%s Option length error", peer->host);
bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
return -1;
}
if (BGP_DEBUG (normal, NORMAL))
zlog_info ("%s rcvd OPEN w/ optional parameter type %u (%s) len %u",
peer->host, opt_type,
opt_type == BGP_OPEN_OPT_AUTH ? "Authentication" :
opt_type == BGP_OPEN_OPT_CAP ? "Capability" : "Unknown",
opt_length);
switch (opt_type)
{
case BGP_OPEN_OPT_AUTH:
ret = bgp_auth_parse (peer, pnt, opt_length);
break;
case BGP_OPEN_OPT_CAP:
ret = bgp_capability_parse (peer, pnt, opt_length, &error);
*capability = 1;
break;
default:
bgp_notify_send (peer,
BGP_NOTIFY_OPEN_ERR,
BGP_NOTIFY_OPEN_UNSUP_PARAM);
ret = -1;
break;
}
/* Parse error. To accumulate all unsupported capability codes,
bgp_capability_parse does not return -1 when encounter
unsupported capability code. To detect that, please check
error and erro_data pointer, like below. */
if (ret < 0)
return -1;
/* Forward pointer. */
pnt += opt_length;
}
/* All OPEN option is parsed. Check capability when strict compare
flag is enabled.*/
if (CHECK_FLAG (peer->flags, PEER_FLAG_STRICT_CAP_MATCH))
{
/* If Unsupported Capability exists. */
if (error != error_data)
{
bgp_notify_send_with_data (peer,
BGP_NOTIFY_OPEN_ERR,
BGP_NOTIFY_OPEN_UNSUP_CAPBL,
error_data, error - error_data);
return -1;
}
/* Check local capability does not negotiated with remote
peer. */
if (! strict_capability_same (peer))
{
bgp_notify_send (peer,
BGP_NOTIFY_OPEN_ERR,
BGP_NOTIFY_OPEN_UNSUP_CAPBL);
return -1;
}
}
/* Check there is no common capability send Unsupported Capability
error. */
if (*capability && ! CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
{
if (! peer->afc_nego[AFI_IP][SAFI_UNICAST]
&& ! peer->afc_nego[AFI_IP][SAFI_MULTICAST]
&& ! peer->afc_nego[AFI_IP][SAFI_MPLS_VPN]
&& ! peer->afc_nego[AFI_IP6][SAFI_UNICAST]
&& ! peer->afc_nego[AFI_IP6][SAFI_MULTICAST])
{
plog_err (peer->log, "%s [Error] No common capability", peer->host);
if (error != error_data)
bgp_notify_send_with_data (peer,
BGP_NOTIFY_OPEN_ERR,
BGP_NOTIFY_OPEN_UNSUP_CAPBL,
error_data, error - error_data);
else
bgp_notify_send (peer,
BGP_NOTIFY_OPEN_ERR,
BGP_NOTIFY_OPEN_UNSUP_CAPBL);
return -1;
}
}
return 0;
}
void
bgp_open_capability_orf (struct stream *s, struct peer *peer,
afi_t afi, safi_t safi, u_char code)
{
u_char cap_len;
u_char orf_len;
unsigned long capp;
unsigned long orfp;
unsigned long numberp;
int number_of_orfs = 0;
if (safi == SAFI_MPLS_VPN)
safi = BGP_SAFI_VPNV4;
stream_putc (s, BGP_OPEN_OPT_CAP);
capp = stream_get_putp (s); /* Set Capability Len Pointer */
stream_putc (s, 0); /* Capability Length */
stream_putc (s, code); /* Capability Code */
orfp = stream_get_putp (s); /* Set ORF Len Pointer */
stream_putc (s, 0); /* ORF Length */
stream_putw (s, afi);
stream_putc (s, 0);
stream_putc (s, safi);
numberp = stream_get_putp (s); /* Set Number Pointer */
stream_putc (s, 0); /* Number of ORFs */
/* Address Prefix ORF */
if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
|| CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
{
stream_putc (s, (code == CAPABILITY_CODE_ORF ?
ORF_TYPE_PREFIX : ORF_TYPE_PREFIX_OLD));
if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
&& CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
{
SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV);
SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV);
stream_putc (s, ORF_MODE_BOTH);
}
else if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM))
{
SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV);
stream_putc (s, ORF_MODE_SEND);
}
else
{
SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV);
stream_putc (s, ORF_MODE_RECEIVE);
}
number_of_orfs++;
}
/* Total Number of ORFs. */
stream_putc_at (s, numberp, number_of_orfs);
/* Total ORF Len. */
orf_len = stream_get_putp (s) - orfp - 1;
stream_putc_at (s, orfp, orf_len);
/* Total Capability Len. */
cap_len = stream_get_putp (s) - capp - 1;
stream_putc_at (s, capp, cap_len);
}
/* Fill in capability open option to the packet. */
void
bgp_open_capability (struct stream *s, struct peer *peer)
{
u_char len;
unsigned long cp;
afi_t afi;
safi_t safi;
/* Remember current pointer for Opt Parm Len. */
cp = stream_get_putp (s);
/* Opt Parm Len. */
stream_putc (s, 0);
/* Do not send capability. */
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN)
|| CHECK_FLAG (peer->flags, PEER_FLAG_DONT_CAPABILITY))
return;
/* When the peer is IPv4 unicast only, do not send capability. */
if (! peer->afc[AFI_IP][SAFI_MULTICAST]
&& ! peer->afc[AFI_IP][SAFI_MPLS_VPN]
&& ! peer->afc[AFI_IP6][SAFI_UNICAST]
&& ! peer->afc[AFI_IP6][SAFI_MULTICAST]
&& CHECK_FLAG (peer->flags, PEER_FLAG_NO_ROUTE_REFRESH_CAP)
&& ! CHECK_FLAG (peer->af_flags[AFI_IP][SAFI_UNICAST],
PEER_FLAG_ORF_PREFIX_SM)
&& ! CHECK_FLAG (peer->af_flags[AFI_IP][SAFI_UNICAST],
PEER_FLAG_ORF_PREFIX_RM)
&& ! CHECK_FLAG (peer->af_flags[AFI_IP][SAFI_MULTICAST],
PEER_FLAG_ORF_PREFIX_SM)
&& ! CHECK_FLAG (peer->af_flags[AFI_IP][SAFI_MULTICAST],
PEER_FLAG_ORF_PREFIX_RM)
&& ! CHECK_FLAG (peer->flags, PEER_FLAG_DYNAMIC_CAPABILITY))
return;
/* IPv4 unicast. */
if (peer->afc[AFI_IP][SAFI_UNICAST])
{
peer->afc_adv[AFI_IP][SAFI_UNICAST] = 1;
stream_putc (s, BGP_OPEN_OPT_CAP);
stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
stream_putc (s, CAPABILITY_CODE_MP);
stream_putc (s, CAPABILITY_CODE_MP_LEN);
stream_putw (s, AFI_IP);
stream_putc (s, 0);
stream_putc (s, SAFI_UNICAST);
}
/* IPv4 multicast. */
if (peer->afc[AFI_IP][SAFI_MULTICAST])
{
peer->afc_adv[AFI_IP][SAFI_MULTICAST] = 1;
stream_putc (s, BGP_OPEN_OPT_CAP);
stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
stream_putc (s, CAPABILITY_CODE_MP);
stream_putc (s, CAPABILITY_CODE_MP_LEN);
stream_putw (s, AFI_IP);
stream_putc (s, 0);
stream_putc (s, SAFI_MULTICAST);
}
/* IPv4 VPN */
if (peer->afc[AFI_IP][SAFI_MPLS_VPN])
{
peer->afc_adv[AFI_IP][SAFI_MPLS_VPN] = 1;
stream_putc (s, BGP_OPEN_OPT_CAP);
stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
stream_putc (s, CAPABILITY_CODE_MP);
stream_putc (s, CAPABILITY_CODE_MP_LEN);
stream_putw (s, AFI_IP);
stream_putc (s, 0);
stream_putc (s, BGP_SAFI_VPNV4);
}
#ifdef HAVE_IPV6
/* IPv6 unicast. */
if (peer->afc[AFI_IP6][SAFI_UNICAST])
{
peer->afc_adv[AFI_IP6][SAFI_UNICAST] = 1;
stream_putc (s, BGP_OPEN_OPT_CAP);
stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
stream_putc (s, CAPABILITY_CODE_MP);
stream_putc (s, CAPABILITY_CODE_MP_LEN);
stream_putw (s, AFI_IP6);
stream_putc (s, 0);
stream_putc (s, SAFI_UNICAST);
}
/* IPv6 multicast. */
if (peer->afc[AFI_IP6][SAFI_MULTICAST])
{
peer->afc_adv[AFI_IP6][SAFI_MULTICAST] = 1;
stream_putc (s, BGP_OPEN_OPT_CAP);
stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
stream_putc (s, CAPABILITY_CODE_MP);
stream_putc (s, CAPABILITY_CODE_MP_LEN);
stream_putw (s, AFI_IP6);
stream_putc (s, 0);
stream_putc (s, SAFI_MULTICAST);
}
#endif /* HAVE_IPV6 */
/* Route refresh. */
if (! CHECK_FLAG (peer->flags, PEER_FLAG_NO_ROUTE_REFRESH_CAP))
{
SET_FLAG (peer->cap, PEER_CAP_REFRESH_ADV);
stream_putc (s, BGP_OPEN_OPT_CAP);
stream_putc (s, CAPABILITY_CODE_REFRESH_LEN + 2);
stream_putc (s, CAPABILITY_CODE_REFRESH_OLD);
stream_putc (s, CAPABILITY_CODE_REFRESH_LEN);
stream_putc (s, BGP_OPEN_OPT_CAP);
stream_putc (s, CAPABILITY_CODE_REFRESH_LEN + 2);
stream_putc (s, CAPABILITY_CODE_REFRESH);
stream_putc (s, CAPABILITY_CODE_REFRESH_LEN);
}
/* ORF capability. */
for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
|| CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
{
bgp_open_capability_orf (s, peer, afi, safi, CAPABILITY_CODE_ORF_OLD);
bgp_open_capability_orf (s, peer, afi, safi, CAPABILITY_CODE_ORF);
}
/* Dynamic capability. */
if (CHECK_FLAG (peer->flags, PEER_FLAG_DYNAMIC_CAPABILITY))
{
SET_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV);
stream_putc (s, BGP_OPEN_OPT_CAP);
stream_putc (s, CAPABILITY_CODE_DYNAMIC_LEN + 2);
stream_putc (s, CAPABILITY_CODE_DYNAMIC);
stream_putc (s, CAPABILITY_CODE_DYNAMIC_LEN);
}
/* Total Opt Parm Len. */
len = stream_get_putp (s) - cp - 1;
stream_putc_at (s, cp, len);
}

69
bgpd/bgp_open.h Normal file
View File

@ -0,0 +1,69 @@
/* BGP open message handling
Copyright (C) 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. */
/* MP Capability information. */
struct capability_mp
{
u_int16_t afi;
u_char reserved;
u_char safi;
};
/* BGP open message capability. */
struct capability
{
u_char code;
u_char length;
struct capability_mp mpc;
};
/* Multiprotocol Extensions capabilities. */
#define CAPABILITY_CODE_MP 1
#define CAPABILITY_CODE_MP_LEN 4
/* Route refresh capabilities. */
#define CAPABILITY_CODE_REFRESH 2
#define CAPABILITY_CODE_REFRESH_OLD 128
#define CAPABILITY_CODE_REFRESH_LEN 0
/* Cooperative Route Filtering Capability. */
#define CAPABILITY_CODE_ORF 3
#define CAPABILITY_CODE_ORF_OLD 130
/* ORF Type. */
#define ORF_TYPE_PREFIX 64
#define ORF_TYPE_PREFIX_OLD 128
/* ORF Mode. */
#define ORF_MODE_RECEIVE 1
#define ORF_MODE_SEND 2
#define ORF_MODE_BOTH 3
/* Dynamic capability. */
#define CAPABILITY_CODE_DYNAMIC 66
#define CAPABILITY_CODE_DYNAMIC_LEN 0
/* Capability Message Action. */
#define CAPABILITY_ACTION_SET 0
#define CAPABILITY_ACTION_UNSET 1
int bgp_open_option_parse (struct peer *, u_char, int *);
void bgp_open_capability (struct stream *, struct peer *);
void bgp_capability_vty_out (struct vty *, struct peer *);

2240
bgpd/bgp_packet.c Normal file

File diff suppressed because it is too large Load Diff

49
bgpd/bgp_packet.h Normal file
View File

@ -0,0 +1,49 @@
/* BGP packet management header.
Copyright (C) 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. */
#define BGP_NLRI_LENGTH 1
#define BGP_TOTAL_ATTR_LEN 2
#define BGP_UNFEASIBLE_LEN 2
#define BGP_WRITE_PACKET_MAX 10
/* When to refresh */
#define REFRESH_IMMEDIATE 1
#define REFRESH_DEFER 2
/* ORF Common part flag */
#define ORF_COMMON_PART_ADD 0x00
#define ORF_COMMON_PART_REMOVE 0x80
#define ORF_COMMON_PART_REMOVE_ALL 0xC0
#define ORF_COMMON_PART_PERMIT 0x00
#define ORF_COMMON_PART_DENY 0x20
/* Packet send and receive function prototypes. */
int bgp_read (struct thread *);
int bgp_write (struct thread *);
void bgp_keepalive_send (struct peer *);
void bgp_open_send (struct peer *);
void bgp_notify_send (struct peer *, u_char, u_char);
void bgp_notify_send_with_data (struct peer *, u_char, u_char, u_char *, size_t);
void bgp_route_refresh_send (struct peer *, afi_t, safi_t, u_char, u_char, int);
void bgp_capability_send (struct peer *, afi_t, safi_t, int, int);
void bgp_default_update_send (struct peer *, struct attr *,
afi_t, safi_t, struct peer *);
void bgp_default_withdraw_send (struct peer *, afi_t, safi_t);

93
bgpd/bgp_regex.c Normal file
View File

@ -0,0 +1,93 @@
/* AS regular expression routine
Copyright (C) 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 "command.h"
#include "memory.h"
#include "bgpd.h"
#include "bgp_aspath.h"
#include "bgp_regex.h"
/* Character `_' has special mean. It represents [,{}() ] and the
beginning of the line(^) and the end of the line ($).
(^|[,{}() ]|$) */
regex_t *
bgp_regcomp (char *regstr)
{
/* Convert _ character to generic regular expression. */
int i, j;
int len;
int magic = 0;
char *magic_str;
char magic_regexp[] = "(^|[,{}() ]|$)";
int ret;
regex_t *regex;
len = strlen (regstr);
for (i = 0; i < len; i++)
if (regstr[i] == '_')
magic++;
magic_str = XMALLOC (MTYPE_TMP, len + (14 * magic) + 1);
for (i = 0, j = 0; i < len; i++)
{
if (regstr[i] == '_')
{
memcpy (magic_str + j, magic_regexp, strlen (magic_regexp));
j += strlen (magic_regexp);
}
else
magic_str[j++] = regstr[i];
}
magic_str[j] = '\0';
regex = XMALLOC (MTYPE_BGP_REGEXP, sizeof (regex_t));
ret = regcomp (regex, magic_str, REG_EXTENDED);
XFREE (MTYPE_TMP, magic_str);
if (ret != 0)
{
XFREE (MTYPE_BGP_REGEXP, regex);
return NULL;
}
return regex;
}
int
bgp_regexec (regex_t *regex, struct aspath *aspath)
{
return regexec (regex, aspath->str, 0, NULL, 0);
}
void
bgp_regex_free (regex_t *regex)
{
regfree (regex);
XFREE (MTYPE_BGP_REGEXP, regex);
}

31
bgpd/bgp_regex.h Normal file
View File

@ -0,0 +1,31 @@
/* AS regular expression routine
Copyright (C) 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>
#ifdef HAVE_GNU_REGEX
#include <regex.h>
#else
#include "regex-gnu.h"
#endif /* HAVE_GNU_REGEX */
void bgp_regex_free (regex_t *regex);
regex_t *bgp_regcomp (char *str);
int bgp_regexec (regex_t *regex, struct aspath *aspath);

9053
bgpd/bgp_route.c Normal file

File diff suppressed because it is too large Load Diff

159
bgpd/bgp_route.h Normal file
View File

@ -0,0 +1,159 @@
/* BGP routing information base
Copyright (C) 1996, 97, 98, 2000 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. */
struct bgp_info
{
/* For linked list. */
struct bgp_info *next;
struct bgp_info *prev;
/* BGP route type. This can be static, RIP, OSPF, BGP etc. */
u_char type;
/* When above type is BGP. This sub type specify BGP sub type
information. */
u_char sub_type;
#define BGP_ROUTE_NORMAL 0
#define BGP_ROUTE_STATIC 1
#define BGP_ROUTE_AGGREGATE 2
#define BGP_ROUTE_REDISTRIBUTE 3
/* BGP information status. */
u_char flags;
#define BGP_INFO_IGP_CHANGED (1 << 0)
#define BGP_INFO_DAMPED (1 << 1)
#define BGP_INFO_HISTORY (1 << 2)
#define BGP_INFO_SELECTED (1 << 3)
#define BGP_INFO_VALID (1 << 4)
#define BGP_INFO_ATTR_CHANGED (1 << 5)
#define BGP_INFO_DMED_CHECK (1 << 6)
#define BGP_INFO_DMED_SELECTED (1 << 7)
/* Peer structure. */
struct peer *peer;
/* Attribute structure. */
struct attr *attr;
/* This route is suppressed with aggregation. */
int suppress;
/* Nexthop reachability check. */
u_int32_t igpmetric;
/* Uptime. */
time_t uptime;
/* Pointer to dampening structure. */
struct bgp_damp_info *damp_info;
/* MPLS label. */
u_char tag[3];
};
/* BGP static route configuration. */
struct bgp_static
{
/* Backdoor configuration. */
int backdoor;
/* Import check status. */
u_char valid;
/* IGP metric. */
u_int32_t igpmetric;
/* IGP nexthop. */
struct in_addr igpnexthop;
/* BGP redistribute route-map. */
struct
{
char *name;
struct route_map *map;
} rmap;
/* MPLS label. */
u_char tag[3];
};
#define DISTRIBUTE_IN_NAME(F) ((F)->dlist[FILTER_IN].name)
#define DISTRIBUTE_IN(F) ((F)->dlist[FILTER_IN].alist)
#define DISTRIBUTE_OUT_NAME(F) ((F)->dlist[FILTER_OUT].name)
#define DISTRIBUTE_OUT(F) ((F)->dlist[FILTER_OUT].alist)
#define PREFIX_LIST_IN_NAME(F) ((F)->plist[FILTER_IN].name)
#define PREFIX_LIST_IN(F) ((F)->plist[FILTER_IN].plist)
#define PREFIX_LIST_OUT_NAME(F) ((F)->plist[FILTER_OUT].name)
#define PREFIX_LIST_OUT(F) ((F)->plist[FILTER_OUT].plist)
#define FILTER_LIST_IN_NAME(F) ((F)->aslist[FILTER_IN].name)
#define FILTER_LIST_IN(F) ((F)->aslist[FILTER_IN].aslist)
#define FILTER_LIST_OUT_NAME(F) ((F)->aslist[FILTER_OUT].name)
#define FILTER_LIST_OUT(F) ((F)->aslist[FILTER_OUT].aslist)
#define ROUTE_MAP_IN_NAME(F) ((F)->map[FILTER_IN].name)
#define ROUTE_MAP_IN(F) ((F)->map[FILTER_IN].map)
#define ROUTE_MAP_OUT_NAME(F) ((F)->map[FILTER_OUT].name)
#define ROUTE_MAP_OUT(F) ((F)->map[FILTER_OUT].map)
#define UNSUPPRESS_MAP_NAME(F) ((F)->usmap.name)
#define UNSUPPRESS_MAP(F) ((F)->usmap.map)
/* Prototypes. */
void bgp_route_init ();
void bgp_announce_route (struct peer *, afi_t, safi_t);
void bgp_announce_route_all (struct peer *);
void bgp_default_originate (struct peer *, afi_t, safi_t, int);
void bgp_soft_reconfig_in (struct peer *, afi_t, safi_t);
void bgp_clear_route (struct peer *, afi_t, safi_t);
void bgp_clear_route_all (struct peer *);
void bgp_clear_adj_in (struct peer *, afi_t, safi_t);
int bgp_nlri_sanity_check (struct peer *, int, u_char *, bgp_size_t);
int bgp_nlri_parse (struct peer *, struct attr *, struct bgp_nlri *);
int bgp_maximum_prefix_overflow (struct peer *, afi_t, safi_t);
void bgp_redistribute_add (struct prefix *, struct in_addr *, u_int32_t, u_char);
void bgp_redistribute_delete (struct prefix *, u_char);
void bgp_redistribute_withdraw (struct bgp *, afi_t, int);
void bgp_static_delete (struct bgp *);
void bgp_static_update (struct bgp *, struct prefix *, struct bgp_static *,
afi_t, safi_t);
void bgp_static_withdraw (struct bgp *, struct prefix *, afi_t, safi_t);
int bgp_static_set_vpnv4 (struct vty *vty, char *, char *, char *);
int bgp_static_unset_vpnv4 (struct vty *, char *, char *, char *);
int bgp_config_write_network (struct vty *, struct bgp *, afi_t, safi_t, int *);
int bgp_config_write_distance (struct vty *, struct bgp *);
void bgp_aggregate_increment (struct bgp *, struct prefix *, struct bgp_info *,
afi_t, safi_t);
void bgp_aggregate_decrement (struct bgp *, struct prefix *, struct bgp_info *,
afi_t, safi_t);
u_char bgp_distance_apply (struct prefix *, struct bgp_info *, struct bgp *);
afi_t bgp_node_afi (struct vty *);
safi_t bgp_node_safi (struct vty *);

3207
bgpd/bgp_routemap.c Normal file

File diff suppressed because it is too large Load Diff

875
bgpd/bgp_snmp.c Normal file
View File

@ -0,0 +1,875 @@
/* BGP4 SNMP support
Copyright (C) 1999, 2000 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>
#ifdef HAVE_SNMP
#include <asn1.h>
#include <snmp.h>
#include <snmp_impl.h>
#include "if.h"
#include "log.h"
#include "prefix.h"
#include "command.h"
#include "thread.h"
#include "smux.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_table.h"
#include "bgpd/bgp_aspath.h"
#include "bgpd/bgp_attr.h"
#include "bgpd/bgp_route.h"
#include "bgpd/bgp_fsm.h"
/* BGP4-MIB described in RFC1657. */
#define BGP4MIB 1,3,6,1,2,1,15
/* Zebra enterprise BGP MIB. This variable is used for register
OSPF MIB to SNMP agent under SMUX protocol. */
#define BGPDMIB 1,3,6,1,4,1,3317,1,2,2
/* BGP MIB bgpVersion. */
#define BGPVERSION 0
/* BGP MIB bgpLocalAs. */
#define BGPLOCALAS 0
/* BGP MIB bgpPeerTable. */
#define BGPPEERIDENTIFIER 1
#define BGPPEERSTATE 2
#define BGPPEERADMINSTATUS 3
#define BGPPEERNEGOTIATEDVERSION 4
#define BGPPEERLOCALADDR 5
#define BGPPEERLOCALPORT 6
#define BGPPEERREMOTEADDR 7
#define BGPPEERREMOTEPORT 8
#define BGPPEERREMOTEAS 9
#define BGPPEERINUPDATES 10
#define BGPPEEROUTUPDATES 11
#define BGPPEERINTOTALMESSAGES 12
#define BGPPEEROUTTOTALMESSAGES 13
#define BGPPEERLASTERROR 14
#define BGPPEERFSMESTABLISHEDTRANSITIONS 15
#define BGPPEERFSMESTABLISHEDTIME 16
#define BGPPEERCONNECTRETRYINTERVAL 17
#define BGPPEERHOLDTIME 18
#define BGPPEERKEEPALIVE 19
#define BGPPEERHOLDTIMECONFIGURED 20
#define BGPPEERKEEPALIVECONFIGURED 21
#define BGPPEERMINASORIGINATIONINTERVAL 22
#define BGPPEERMINROUTEADVERTISEMENTINTERVAL 23
#define BGPPEERINUPDATEELAPSEDTIME 24
/* BGP MIB bgpIdentifier. */
#define BGPIDENTIFIER 0
/* BGP MIB bgpRcvdPathAttrTable */
#define BGPPATHATTRPEER 1
#define BGPPATHATTRDESTNETWORK 2
#define BGPPATHATTRORIGIN 3
#define BGPPATHATTRASPATH 4
#define BGPPATHATTRNEXTHOP 5
#define BGPPATHATTRINTERASMETRIC 6
/* BGP MIB bgp4PathAttrTable. */
#define BGP4PATHATTRPEER 1
#define BGP4PATHATTRIPADDRPREFIXLEN 2
#define BGP4PATHATTRIPADDRPREFIX 3
#define BGP4PATHATTRORIGIN 4
#define BGP4PATHATTRASPATHSEGMENT 5
#define BGP4PATHATTRNEXTHOP 6
#define BGP4PATHATTRMULTIEXITDISC 7
#define BGP4PATHATTRLOCALPREF 8
#define BGP4PATHATTRATOMICAGGREGATE 9
#define BGP4PATHATTRAGGREGATORAS 10
#define BGP4PATHATTRAGGREGATORADDR 11
#define BGP4PATHATTRCALCLOCALPREF 12
#define BGP4PATHATTRBEST 13
#define BGP4PATHATTRUNKNOWN 14
/* SNMP value hack. */
#define INTEGER ASN_INTEGER
#define INTEGER32 ASN_INTEGER
#define COUNTER32 ASN_COUNTER
#define OCTET_STRING ASN_OCTET_STR
#define IPADDRESS ASN_IPADDRESS
#define GAUGE32 ASN_UNSIGNED
/* Declare static local variables for convenience. */
SNMP_LOCAL_VARIABLES
/* BGP-MIB instances. */
oid bgp_oid [] = { BGP4MIB };
oid bgpd_oid [] = { BGPDMIB };
/* IP address 0.0.0.0. */
static struct in_addr bgp_empty_addr = {0};
/* Hook functions. */
static u_char *bgpVersion ();
static u_char *bgpLocalAs ();
static u_char *bgpPeerTable ();
static u_char *bgpRcvdPathAttrTable ();
static u_char *bgpIdentifier ();
static u_char *bgp4PathAttrTable ();
/* static u_char *bgpTraps (); */
struct variable bgp_variables[] =
{
/* BGP version. */
{BGPVERSION, OCTET_STRING, RONLY, bgpVersion,
1, {1}},
/* BGP local AS. */
{BGPLOCALAS, INTEGER, RONLY, bgpLocalAs,
1, {2}},
/* BGP peer table. */
{BGPPEERIDENTIFIER, IPADDRESS, RONLY, bgpPeerTable,
3, {3, 1, 1}},
{BGPPEERSTATE, INTEGER, RONLY, bgpPeerTable,
3, {3, 1, 2}},
{BGPPEERADMINSTATUS, INTEGER, RWRITE, bgpPeerTable,
3, {3, 1, 3}},
{BGPPEERNEGOTIATEDVERSION, INTEGER32, RONLY, bgpPeerTable,
3, {3, 1, 4}},
{BGPPEERLOCALADDR, IPADDRESS, RONLY, bgpPeerTable,
3, {3, 1, 5}},
{BGPPEERLOCALPORT, INTEGER, RONLY, bgpPeerTable,
3, {3, 1, 6}},
{BGPPEERREMOTEADDR, IPADDRESS, RONLY, bgpPeerTable,
3, {3, 1, 7}},
{BGPPEERREMOTEPORT, INTEGER, RONLY, bgpPeerTable,
3, {3, 1, 8}},
{BGPPEERREMOTEAS, INTEGER, RONLY, bgpPeerTable,
3, {3, 1, 9}},
{BGPPEERINUPDATES, COUNTER32, RONLY, bgpPeerTable,
3, {3, 1, 10}},
{BGPPEEROUTUPDATES, COUNTER32, RONLY, bgpPeerTable,
3, {3, 1, 11}},
{BGPPEERINTOTALMESSAGES, COUNTER32, RONLY, bgpPeerTable,
3, {3, 1, 12}},
{BGPPEEROUTTOTALMESSAGES, COUNTER32, RONLY, bgpPeerTable,
3, {3, 1, 13}},
{BGPPEERLASTERROR, OCTET_STRING, RONLY, bgpPeerTable,
3, {3, 1, 14}},
{BGPPEERFSMESTABLISHEDTRANSITIONS, COUNTER32, RONLY, bgpPeerTable,
3, {3, 1, 15}},
{BGPPEERFSMESTABLISHEDTIME, GAUGE32, RONLY, bgpPeerTable,
3, {3, 1, 16}},
{BGPPEERCONNECTRETRYINTERVAL, INTEGER, RWRITE, bgpPeerTable,
3, {3, 1, 17}},
{BGPPEERHOLDTIME, INTEGER, RONLY, bgpPeerTable,
3, {3, 1, 18}},
{BGPPEERKEEPALIVE, INTEGER, RONLY, bgpPeerTable,
3, {3, 1, 19}},
{BGPPEERHOLDTIMECONFIGURED, INTEGER, RWRITE, bgpPeerTable,
3, {3, 1, 20}},
{BGPPEERKEEPALIVECONFIGURED, INTEGER, RWRITE, bgpPeerTable,
3, {3, 1, 21}},
{BGPPEERMINASORIGINATIONINTERVAL, INTEGER, RWRITE, bgpPeerTable,
3, {3, 1, 22}},
{BGPPEERMINROUTEADVERTISEMENTINTERVAL, INTEGER, RWRITE, bgpPeerTable,
3, {3, 1, 23}},
{BGPPEERINUPDATEELAPSEDTIME, GAUGE32, RONLY, bgpPeerTable,
3, {3, 1, 24}},
/* BGP identifier. */
{BGPIDENTIFIER, IPADDRESS, RONLY, bgpIdentifier,
1, {4}},
/* BGP received path attribute table. */
{BGPPATHATTRPEER, IPADDRESS, RONLY, bgpRcvdPathAttrTable,
3, {5, 1, 1}},
{BGPPATHATTRDESTNETWORK, IPADDRESS, RONLY, bgpRcvdPathAttrTable,
3, {5, 1, 2}},
{BGPPATHATTRORIGIN, INTEGER, RONLY, bgpRcvdPathAttrTable,
3, {5, 1, 3}},
{BGPPATHATTRASPATH, OCTET_STRING, RONLY, bgpRcvdPathAttrTable,
3, {5, 1, 4}},
{BGPPATHATTRNEXTHOP, IPADDRESS, RONLY, bgpRcvdPathAttrTable,
3, {5, 1, 5}},
{BGPPATHATTRINTERASMETRIC, INTEGER32, RONLY, bgpRcvdPathAttrTable,
3, {5, 1, 6}},
/* BGP-4 received path attribute table. */
{BGP4PATHATTRPEER, IPADDRESS, RONLY, bgp4PathAttrTable,
3, {6, 1, 1}},
{BGP4PATHATTRIPADDRPREFIXLEN, INTEGER, RONLY, bgp4PathAttrTable,
3, {6, 1, 2}},
{BGP4PATHATTRIPADDRPREFIX, IPADDRESS, RONLY, bgp4PathAttrTable,
3, {6, 1, 3}},
{BGP4PATHATTRORIGIN, INTEGER, RONLY, bgp4PathAttrTable,
3, {6, 1, 4}},
{BGP4PATHATTRASPATHSEGMENT, OCTET_STRING, RONLY, bgp4PathAttrTable,
3, {6, 1, 5}},
{BGP4PATHATTRNEXTHOP, IPADDRESS, RONLY, bgp4PathAttrTable,
3, {6, 1, 6}},
{BGP4PATHATTRMULTIEXITDISC, INTEGER, RONLY, bgp4PathAttrTable,
3, {6, 1, 7}},
{BGP4PATHATTRLOCALPREF, INTEGER, RONLY, bgp4PathAttrTable,
3, {6, 1, 8}},
{BGP4PATHATTRATOMICAGGREGATE, INTEGER, RONLY, bgp4PathAttrTable,
3, {6, 1, 9}},
{BGP4PATHATTRAGGREGATORAS, INTEGER, RONLY, bgp4PathAttrTable,
3, {6, 1, 10}},
{BGP4PATHATTRAGGREGATORADDR, IPADDRESS, RONLY, bgp4PathAttrTable,
3, {6, 1, 11}},
{BGP4PATHATTRCALCLOCALPREF, INTEGER, RONLY, bgp4PathAttrTable,
3, {6, 1, 12}},
{BGP4PATHATTRBEST, INTEGER, RONLY, bgp4PathAttrTable,
3, {6, 1, 13}},
{BGP4PATHATTRUNKNOWN, OCTET_STRING, RONLY, bgp4PathAttrTable,
3, {6, 1, 14}},
};
static u_char *
bgpVersion (struct variable *v, oid name[], size_t *length, int exact,
size_t *var_len, WriteMethod **write_method)
{
static u_char version;
if (smux_header_generic(v, name, length, exact, var_len, write_method)
== MATCH_FAILED)
return NULL;
/* Retrun BGP version. Zebra bgpd only support version 4. */
version = (0x80 >> (BGP_VERSION_4 - 1));
/* Return octet string length 1. */
*var_len = 1;
return (u_char *)&version;
}
static u_char *
bgpLocalAs (struct variable *v, oid name[], size_t *length,
int exact, size_t *var_len, WriteMethod **write_method)
{
struct bgp *bgp;
if (smux_header_generic(v, name, length, exact, var_len, write_method)
== MATCH_FAILED)
return NULL;
/* Get BGP structure. */
bgp = bgp_get_default ();
if (! bgp)
return NULL;
return SNMP_INTEGER (bgp->as);
}
struct peer *
peer_lookup_addr_ipv4 (struct in_addr *src)
{
struct bgp *bgp;
struct peer *peer;
struct listnode *nn;
struct in_addr addr;
int ret;
bgp = bgp_get_default ();
if (! bgp)
return NULL;
LIST_LOOP (bgp->peer, peer, nn)
{
ret = inet_pton (AF_INET, peer->host, &addr);
if (ret > 0)
{
if (IPV4_ADDR_SAME (&addr, src))
return peer;
}
}
return NULL;
}
struct peer *
bgp_peer_lookup_next (struct in_addr *src)
{
struct bgp *bgp;
struct peer *peer;
struct listnode *nn;
struct in_addr *p;
union sockunion su;
int ret;
memset (&su, 0, sizeof (union sockunion));
bgp = bgp_get_default ();
if (! bgp)
return NULL;
LIST_LOOP (bgp->peer, peer, nn)
{
ret = inet_pton (AF_INET, peer->host, &su.sin.sin_addr);
if (ret > 0)
{
p = &su.sin.sin_addr;
if (ntohl (p->s_addr) > ntohl (src->s_addr))
{
src->s_addr = p->s_addr;
return peer;
}
}
}
return NULL;
}
struct peer *
bgpPeerTable_lookup (struct variable *v, oid name[], size_t *length,
struct in_addr *addr, int exact)
{
struct peer *peer = NULL;
int len;
if (exact)
{
/* Check the length. */
if (*length - v->namelen != sizeof (struct in_addr))
return NULL;
oid2in_addr (name + v->namelen, IN_ADDR_SIZE, addr);
peer = peer_lookup_addr_ipv4 (addr);
return peer;
}
else
{
len = *length - v->namelen;
if (len > 4) len = 4;
oid2in_addr (name + v->namelen, len, addr);
peer = bgp_peer_lookup_next (addr);
if (peer == NULL)
return NULL;
oid_copy_addr (name + v->namelen, addr, sizeof (struct in_addr));
*length = sizeof (struct in_addr) + v->namelen;
return peer;
}
return NULL;
}
/* BGP write methods. */
int
write_bgpPeerTable (int action, u_char *var_val,
u_char var_val_type, size_t var_val_len,
u_char *statP, oid *name, size_t length,
struct variable *v)
{
struct in_addr addr;
struct peer *peer;
long intval;
int bigsize = SNMP_MAX_LEN;
if (var_val_type != ASN_INTEGER)
{
return SNMP_ERR_WRONGTYPE;
}
if (var_val_len != sizeof (long))
{
return SNMP_ERR_WRONGLENGTH;
}
if (! asn_parse_int(var_val, &bigsize, &var_val_type,
&intval, sizeof(long)))
{
return SNMP_ERR_WRONGENCODING;
}
memset (&addr, 0, sizeof (struct in_addr));
peer = bgpPeerTable_lookup (v, name, &length, &addr, 1);
if (! peer)
return SNMP_ERR_NOSUCHNAME;
printf ("val: %ld\n", intval);
switch (v->magic)
{
case BGPPEERADMINSTATUS:
#define BGP_PeerAdmin_stop 1
#define BGP_PeerAdmin_start 2
/* When the peer is established, */
if (intval == BGP_PeerAdmin_stop)
BGP_EVENT_ADD (peer, BGP_Stop);
else if (intval == BGP_PeerAdmin_start)
; /* Do nothing. */
else
return SNMP_ERR_NOSUCHNAME;
break;
case BGPPEERCONNECTRETRYINTERVAL:
SET_FLAG (peer->config, PEER_CONFIG_CONNECT);
peer->connect = intval;
peer->v_connect = intval;
break;
case BGPPEERHOLDTIMECONFIGURED:
SET_FLAG (peer->config, PEER_CONFIG_TIMER);
peer->holdtime = intval;
peer->v_holdtime = intval;
break;
case BGPPEERKEEPALIVECONFIGURED:
SET_FLAG (peer->config, PEER_CONFIG_TIMER);
peer->keepalive = intval;
peer->v_keepalive = intval;
break;
case BGPPEERMINASORIGINATIONINTERVAL:
peer->v_asorig = intval;
break;
case BGPPEERMINROUTEADVERTISEMENTINTERVAL:
peer->v_routeadv = intval;
break;
}
return SNMP_ERR_NOERROR;
}
u_char *
bgpPeerTable (struct variable *v, oid name[], size_t *length,
int exact, size_t *var_len, WriteMethod **write_method)
{
static struct in_addr addr;
struct peer *peer;
*write_method = NULL;
memset (&addr, 0, sizeof (struct in_addr));
peer = bgpPeerTable_lookup (v, name, length, &addr, exact);
if (! peer)
return NULL;
switch (v->magic)
{
case BGPPEERIDENTIFIER:
return SNMP_IPADDRESS (peer->remote_id);
break;
case BGPPEERSTATE:
return SNMP_INTEGER (peer->status);
break;
case BGPPEERADMINSTATUS:
*write_method = write_bgpPeerTable;
#define BGP_PeerAdmin_stop 1
#define BGP_PeerAdmin_start 2
if (CHECK_FLAG (peer->flags, PEER_FLAG_SHUTDOWN))
return SNMP_INTEGER (BGP_PeerAdmin_stop);
else
return SNMP_INTEGER (BGP_PeerAdmin_start);
break;
case BGPPEERNEGOTIATEDVERSION:
return SNMP_INTEGER (peer->version);
break;
case BGPPEERLOCALADDR:
if (peer->su_local)
return SNMP_IPADDRESS (peer->su_local->sin.sin_addr);
else
return SNMP_IPADDRESS (bgp_empty_addr);
break;
case BGPPEERLOCALPORT:
if (peer->su_local)
return SNMP_INTEGER (ntohs (peer->su_local->sin.sin_port));
else
return SNMP_INTEGER (0);
break;
case BGPPEERREMOTEADDR:
if (peer->su_remote)
return SNMP_IPADDRESS (peer->su_remote->sin.sin_addr);
else
return SNMP_IPADDRESS (bgp_empty_addr);
break;
case BGPPEERREMOTEPORT:
if (peer->su_remote)
return SNMP_INTEGER (ntohs (peer->su_remote->sin.sin_port));
else
return SNMP_INTEGER (0);
break;
case BGPPEERREMOTEAS:
return SNMP_INTEGER (peer->as);
break;
case BGPPEERINUPDATES:
return SNMP_INTEGER (peer->update_in);
break;
case BGPPEEROUTUPDATES:
return SNMP_INTEGER (peer->update_out);
break;
case BGPPEERINTOTALMESSAGES:
return SNMP_INTEGER (peer->open_in + peer->update_in
+ peer->keepalive_in + peer->notify_in
+ peer->refresh_in + peer->dynamic_cap_in);
break;
case BGPPEEROUTTOTALMESSAGES:
return SNMP_INTEGER (peer->open_out + peer->update_out
+ peer->keepalive_out + peer->notify_out
+ peer->refresh_out, peer->dynamic_cap_out);
break;
case BGPPEERLASTERROR:
{
static u_char lasterror[2];
lasterror[0] = peer->notify.code;
lasterror[1] = peer->notify.subcode;
*var_len = 2;
return (u_char *)&lasterror;
}
break;
case BGPPEERFSMESTABLISHEDTRANSITIONS:
return SNMP_INTEGER (peer->established);
break;
case BGPPEERFSMESTABLISHEDTIME:
if (peer->uptime == 0)
return SNMP_INTEGER (0);
else
return SNMP_INTEGER (time (NULL) - peer->uptime);
break;
case BGPPEERCONNECTRETRYINTERVAL:
*write_method = write_bgpPeerTable;
return SNMP_INTEGER (peer->v_connect);
break;
case BGPPEERHOLDTIME:
return SNMP_INTEGER (peer->v_holdtime);
break;
case BGPPEERKEEPALIVE:
return SNMP_INTEGER (peer->v_keepalive);
break;
case BGPPEERHOLDTIMECONFIGURED:
*write_method = write_bgpPeerTable;
if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
return SNMP_INTEGER (peer->holdtime);
else
return SNMP_INTEGER (peer->v_holdtime);
break;
case BGPPEERKEEPALIVECONFIGURED:
*write_method = write_bgpPeerTable;
if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
return SNMP_INTEGER (peer->keepalive);
else
return SNMP_INTEGER (peer->v_keepalive);
break;
case BGPPEERMINASORIGINATIONINTERVAL:
*write_method = write_bgpPeerTable;
return SNMP_INTEGER (peer->v_asorig);
break;
case BGPPEERMINROUTEADVERTISEMENTINTERVAL:
*write_method = write_bgpPeerTable;
return SNMP_INTEGER (peer->v_routeadv);
break;
case BGPPEERINUPDATEELAPSEDTIME:
if (peer->update_time == 0)
return SNMP_INTEGER (0);
else
return SNMP_INTEGER (time (NULL) - peer->update_time);
break;
default:
return NULL;
break;
}
return NULL;
}
u_char *
bgpIdentifier (struct variable *v, oid name[], size_t *length,
int exact, size_t *var_len, WriteMethod **write_method)
{
struct bgp *bgp;
if (smux_header_generic(v, name, length, exact, var_len, write_method)
== MATCH_FAILED)
return NULL;
bgp = bgp_get_default ();
if (!bgp)
return NULL;
return SNMP_IPADDRESS (bgp->router_id);
}
u_char *
bgpRcvdPathAttrTable (struct variable *v, oid name[], size_t *length,
int exact, size_t *var_len, WriteMethod **write_method)
{
/* Received Path Attribute Table. This table contains, one entry
per path to a network, path attributes received from all peers
running BGP version 3 or less. This table is obsolete, having
been replaced in functionality with the bgp4PathAttrTable. */
return NULL;
}
struct bgp_info *
bgp4PathAttrLookup (struct variable *v, oid name[], size_t *length,
struct bgp *bgp, struct prefix_ipv4 *addr, int exact)
{
oid *offset;
int offsetlen;
struct bgp_info *binfo;
struct bgp_info *min;
struct bgp_node *rn;
union sockunion su;
int len;
struct in_addr paddr;
#define BGP_PATHATTR_ENTRY_OFFSET \
(IN_ADDR_SIZE + 1 + IN_ADDR_SIZE)
if (exact)
{
if (*length - v->namelen != BGP_PATHATTR_ENTRY_OFFSET)
return NULL;
/* Set OID offset for prefix. */
offset = name + v->namelen;
oid2in_addr (offset, IN_ADDR_SIZE, &addr->prefix);
offset += IN_ADDR_SIZE;
/* Prefix length. */
addr->prefixlen = *offset;
offset++;
/* Peer address. */
su.sin.sin_family = AF_INET;
oid2in_addr (offset, IN_ADDR_SIZE, &su.sin.sin_addr);
/* Lookup node. */
rn = bgp_node_lookup (bgp->rib[AFI_IP][SAFI_UNICAST],
(struct prefix *) addr);
if (rn)
{
bgp_unlock_node (rn);
for (binfo = rn->info; binfo; binfo = binfo->next)
if (sockunion_same (&binfo->peer->su, &su))
return binfo;
}
}
else
{
offset = name + v->namelen;
offsetlen = *length - v->namelen;
len = offsetlen;
if (offsetlen == 0)
rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_UNICAST]);
else
{
if (len > IN_ADDR_SIZE)
len = IN_ADDR_SIZE;
oid2in_addr (offset, len, &addr->prefix);
offset += IN_ADDR_SIZE;
offsetlen -= IN_ADDR_SIZE;
if (offsetlen > 0)
addr->prefixlen = *offset;
else
addr->prefixlen = len * 8;
rn = bgp_node_get (bgp->rib[AFI_IP][SAFI_UNICAST],
(struct prefix *) addr);
offset++;
offsetlen--;
}
if (offsetlen > 0)
{
len = offsetlen;
if (len > IN_ADDR_SIZE)
len = IN_ADDR_SIZE;
oid2in_addr (offset, len, &paddr);
}
else
paddr.s_addr = 0;
if (! rn)
return NULL;
do
{
min = NULL;
for (binfo = rn->info; binfo; binfo = binfo->next)
{
if (binfo->peer->su.sin.sin_family == AF_INET
&& ntohl (paddr.s_addr)
< ntohl (binfo->peer->su.sin.sin_addr.s_addr))
{
if (min)
{
if (ntohl (binfo->peer->su.sin.sin_addr.s_addr)
< ntohl (min->peer->su.sin.sin_addr.s_addr))
min = binfo;
}
else
min = binfo;
}
}
if (min)
{
*length = v->namelen + BGP_PATHATTR_ENTRY_OFFSET;
offset = name + v->namelen;
oid_copy_addr (offset, &rn->p.u.prefix4, IN_ADDR_SIZE);
offset += IN_ADDR_SIZE;
*offset = rn->p.prefixlen;
offset++;
oid_copy_addr (offset, &min->peer->su.sin.sin_addr,
IN_ADDR_SIZE);
addr->prefix = rn->p.u.prefix4;
addr->prefixlen = rn->p.prefixlen;
bgp_unlock_node (rn);
return min;
}
paddr.s_addr = 0;
}
while ((rn = bgp_route_next (rn)) != NULL);
}
return NULL;
}
u_char *
bgp4PathAttrTable (struct variable *v, oid name[], size_t *length,
int exact, size_t *var_len, WriteMethod **write_method)
{
struct bgp *bgp;
struct bgp_info *binfo;
struct prefix_ipv4 addr;
bgp = bgp_get_default ();
if (! bgp)
return NULL;
memset (&addr, 0, sizeof (struct prefix_ipv4));
binfo = bgp4PathAttrLookup (v, name, length, bgp, &addr, exact);
if (! binfo)
return NULL;
switch (v->magic)
{
case BGP4PATHATTRPEER: /* 1 */
return SNMP_IPADDRESS (binfo->peer->su.sin.sin_addr);
break;
case BGP4PATHATTRIPADDRPREFIXLEN: /* 2 */
return SNMP_INTEGER (addr.prefixlen);
break;
case BGP4PATHATTRIPADDRPREFIX: /* 3 */
return SNMP_IPADDRESS (addr.prefix);
break;
case BGP4PATHATTRORIGIN: /* 4 */
return SNMP_INTEGER (binfo->attr->origin);
break;
case BGP4PATHATTRASPATHSEGMENT: /* 5 */
*var_len = binfo->attr->aspath->length;
return (u_char *) binfo->attr->aspath->data;
break;
case BGP4PATHATTRNEXTHOP: /* 6 */
return SNMP_IPADDRESS (binfo->attr->nexthop);
break;
case BGP4PATHATTRMULTIEXITDISC: /* 7 */
return SNMP_INTEGER (binfo->attr->med);
break;
case BGP4PATHATTRLOCALPREF: /* 8 */
return SNMP_INTEGER (binfo->attr->local_pref);
break;
case BGP4PATHATTRATOMICAGGREGATE: /* 9 */
return SNMP_INTEGER (1);
break;
case BGP4PATHATTRAGGREGATORAS: /* 10 */
return SNMP_INTEGER (binfo->attr->aggregator_as);
break;
case BGP4PATHATTRAGGREGATORADDR: /* 11 */
return SNMP_IPADDRESS (binfo->attr->aggregator_addr);
break;
case BGP4PATHATTRCALCLOCALPREF: /* 12 */
return SNMP_INTEGER (-1);
break;
case BGP4PATHATTRBEST: /* 13 */
#define BGP4_PathAttrBest_false 1
#define BGP4_PathAttrBest_true 2
if (CHECK_FLAG (binfo->flags, BGP_INFO_SELECTED))
return SNMP_INTEGER (BGP4_PathAttrBest_true);
else
return SNMP_INTEGER (BGP4_PathAttrBest_false);
break;
case BGP4PATHATTRUNKNOWN: /* 14 */
*var_len = 0;
return NULL;
break;
}
return NULL;
}
/* BGP Traps. */
struct trap_object bgpTrapList[] =
{
{bgpPeerTable, 3, {3, 1, BGPPEERREMOTEADDR}},
{bgpPeerTable, 3, {3, 1, BGPPEERLASTERROR}},
{bgpPeerTable, 3, {3, 1, BGPPEERSTATE}}
};
void
bgpTrapEstablished (struct peer *peer)
{
int ret;
struct in_addr addr;
oid index[sizeof (oid) * IN_ADDR_SIZE];
ret = inet_aton (peer->host, &addr);
if (ret == 0)
return;
oid_copy_addr (index, &addr, IN_ADDR_SIZE);
smux_trap (bgp_oid, sizeof bgp_oid / sizeof (oid),
index, IN_ADDR_SIZE,
bgpTrapList, sizeof bgpTrapList / sizeof (struct trap_object),
bm->start_time - time (NULL));
}
void
bgpTrapBackwardTransition (struct peer *peer)
{
int ret;
struct in_addr addr;
oid index[sizeof (oid) * IN_ADDR_SIZE];
ret = inet_aton (peer->host, &addr);
if (ret == 0)
return;
oid_copy_addr (index, &addr, IN_ADDR_SIZE);
smux_trap (bgp_oid, sizeof bgp_oid / sizeof (oid),
index, IN_ADDR_SIZE,
bgpTrapList, sizeof bgpTrapList / sizeof (struct trap_object),
bm->start_time - time (NULL));
}
void
bgp_snmp_init ()
{
smux_init (bgpd_oid, sizeof bgpd_oid / sizeof (oid));
REGISTER_MIB("mibII/bgp", bgp_variables, variable, bgp_oid);
smux_start ();
}
#endif /* HAVE_SNMP */

23
bgpd/bgp_snmp.h Normal file
View File

@ -0,0 +1,23 @@
/* BGP4 SNMP support
Copyright (C) 1999, 2000 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. */
void bgp_snmp_init ();
void bgpTrapEstablished (struct peer *);
void bgpTrapBackwardTransition (struct peer *);

489
bgpd/bgp_table.c Normal file
View File

@ -0,0 +1,489 @@
/* BGP routing table
Copyright (C) 1998, 2001 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 "prefix.h"
#include "memory.h"
#include "sockunion.h"
#include "vty.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_table.h"
void bgp_node_delete (struct bgp_node *);
void bgp_table_free (struct bgp_table *);
struct bgp_table *
bgp_table_init (void)
{
struct bgp_table *rt;
rt = XMALLOC (MTYPE_BGP_TABLE, sizeof (struct bgp_table));
memset (rt, 0, sizeof (struct bgp_table));
return rt;
}
void
bgp_table_finish (struct bgp_table *rt)
{
bgp_table_free (rt);
}
struct bgp_node *
bgp_node_create ()
{
struct bgp_node *rn;
rn = (struct bgp_node *) XMALLOC (MTYPE_BGP_NODE, sizeof (struct bgp_node));
memset (rn, 0, sizeof (struct bgp_node));
return rn;
}
/* Allocate new route node with prefix set. */
struct bgp_node *
bgp_node_set (struct bgp_table *table, struct prefix *prefix)
{
struct bgp_node *node;
node = bgp_node_create ();
prefix_copy (&node->p, prefix);
node->table = table;
return node;
}
/* Free route node. */
void
bgp_node_free (struct bgp_node *node)
{
XFREE (MTYPE_BGP_NODE, node);
}
/* Free route table. */
void
bgp_table_free (struct bgp_table *rt)
{
struct bgp_node *tmp_node;
struct bgp_node *node;
if (rt == NULL)
return;
node = rt->top;
while (node)
{
if (node->l_left)
{
node = node->l_left;
continue;
}
if (node->l_right)
{
node = node->l_right;
continue;
}
tmp_node = node;
node = node->parent;
if (node != NULL)
{
if (node->l_left == tmp_node)
node->l_left = NULL;
else
node->l_right = NULL;
bgp_node_free (tmp_node);
}
else
{
bgp_node_free (tmp_node);
break;
}
}
XFREE (MTYPE_BGP_TABLE, rt);
return;
}
/* Utility mask array. */
static u_char maskbit[] =
{
0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff
};
/* Common prefix route genaration. */
static void
route_common (struct prefix *n, struct prefix *p, struct prefix *new)
{
int i;
u_char diff;
u_char mask;
u_char *np = (u_char *)&n->u.prefix;
u_char *pp = (u_char *)&p->u.prefix;
u_char *newp = (u_char *)&new->u.prefix;
for (i = 0; i < p->prefixlen / 8; i++)
{
if (np[i] == pp[i])
newp[i] = np[i];
else
break;
}
new->prefixlen = i * 8;
if (new->prefixlen != p->prefixlen)
{
diff = np[i] ^ pp[i];
mask = 0x80;
while (new->prefixlen < p->prefixlen && !(mask & diff))
{
mask >>= 1;
new->prefixlen++;
}
newp[i] = np[i] & maskbit[new->prefixlen % 8];
}
}
/* Macro version of check_bit (). */
#define CHECK_BIT(X,P) ((((u_char *)(X))[(P) / 8]) >> (7 - ((P) % 8)) & 1)
/* Check bit of the prefix. */
static int
check_bit (u_char *prefix, u_char prefixlen)
{
int offset;
int shift;
u_char *p = (u_char *)prefix;
assert (prefixlen <= 128);
offset = prefixlen / 8;
shift = 7 - (prefixlen % 8);
return (p[offset] >> shift & 1);
}
/* Macro version of set_link (). */
#define SET_LINK(X,Y) (X)->link[CHECK_BIT(&(Y)->prefix,(X)->prefixlen)] = (Y);\
(Y)->parent = (X)
static void
set_link (struct bgp_node *node, struct bgp_node *new)
{
int bit;
bit = check_bit (&new->p.u.prefix, node->p.prefixlen);
assert (bit == 0 || bit == 1);
node->link[bit] = new;
new->parent = node;
}
/* Lock node. */
struct bgp_node *
bgp_lock_node (struct bgp_node *node)
{
node->lock++;
return node;
}
/* Unlock node. */
void
bgp_unlock_node (struct bgp_node *node)
{
node->lock--;
if (node->lock == 0)
bgp_node_delete (node);
}
/* Find matched prefix. */
struct bgp_node *
bgp_node_match (struct bgp_table *table, struct prefix *p)
{
struct bgp_node *node;
struct bgp_node *matched;
matched = NULL;
node = table->top;
/* Walk down tree. If there is matched route then store it to
matched. */
while (node && node->p.prefixlen <= p->prefixlen &&
prefix_match (&node->p, p))
{
if (node->info)
matched = node;
node = node->link[check_bit(&p->u.prefix, node->p.prefixlen)];
}
/* If matched route found, return it. */
if (matched)
return bgp_lock_node (matched);
return NULL;
}
struct bgp_node *
bgp_node_match_ipv4 (struct bgp_table *table, struct in_addr *addr)
{
struct prefix_ipv4 p;
memset (&p, 0, sizeof (struct prefix_ipv4));
p.family = AF_INET;
p.prefixlen = IPV4_MAX_PREFIXLEN;
p.prefix = *addr;
return bgp_node_match (table, (struct prefix *) &p);
}
#ifdef HAVE_IPV6
struct bgp_node *
bgp_node_match_ipv6 (struct bgp_table *table, struct in6_addr *addr)
{
struct prefix_ipv6 p;
memset (&p, 0, sizeof (struct prefix_ipv6));
p.family = AF_INET6;
p.prefixlen = IPV6_MAX_PREFIXLEN;
p.prefix = *addr;
return bgp_node_match (table, (struct prefix *) &p);
}
#endif /* HAVE_IPV6 */
/* Lookup same prefix node. Return NULL when we can't find route. */
struct bgp_node *
bgp_node_lookup (struct bgp_table *table, struct prefix *p)
{
struct bgp_node *node;
node = table->top;
while (node && node->p.prefixlen <= p->prefixlen &&
prefix_match (&node->p, p))
{
if (node->p.prefixlen == p->prefixlen && node->info)
return bgp_lock_node (node);
node = node->link[check_bit(&p->u.prefix, node->p.prefixlen)];
}
return NULL;
}
/* Add node to routing table. */
struct bgp_node *
bgp_node_get (struct bgp_table *table, struct prefix *p)
{
struct bgp_node *new;
struct bgp_node *node;
struct bgp_node *match;
match = NULL;
node = table->top;
while (node && node->p.prefixlen <= p->prefixlen &&
prefix_match (&node->p, p))
{
if (node->p.prefixlen == p->prefixlen)
{
bgp_lock_node (node);
return node;
}
match = node;
node = node->link[check_bit(&p->u.prefix, node->p.prefixlen)];
}
if (node == NULL)
{
new = bgp_node_set (table, p);
if (match)
set_link (match, new);
else
table->top = new;
}
else
{
new = bgp_node_create ();
route_common (&node->p, p, &new->p);
new->p.family = p->family;
new->table = table;
set_link (new, node);
if (match)
set_link (match, new);
else
table->top = new;
if (new->p.prefixlen != p->prefixlen)
{
match = new;
new = bgp_node_set (table, p);
set_link (match, new);
}
}
bgp_lock_node (new);
return new;
}
/* Delete node from the routing table. */
void
bgp_node_delete (struct bgp_node *node)
{
struct bgp_node *child;
struct bgp_node *parent;
assert (node->lock == 0);
assert (node->info == NULL);
if (node->l_left && node->l_right)
return;
if (node->l_left)
child = node->l_left;
else
child = node->l_right;
parent = node->parent;
if (child)
child->parent = parent;
if (parent)
{
if (parent->l_left == node)
parent->l_left = child;
else
parent->l_right = child;
}
else
node->table->top = child;
bgp_node_free (node);
/* If parent node is stub then delete it also. */
if (parent && parent->lock == 0)
bgp_node_delete (parent);
}
/* Get fist node and lock it. This function is useful when one want
to lookup all the node exist in the routing table. */
struct bgp_node *
bgp_table_top (struct bgp_table *table)
{
/* If there is no node in the routing table return NULL. */
if (table->top == NULL)
return NULL;
/* Lock the top node and return it. */
bgp_lock_node (table->top);
return table->top;
}
/* Unlock current node and lock next node then return it. */
struct bgp_node *
bgp_route_next (struct bgp_node *node)
{
struct bgp_node *next;
struct bgp_node *start;
/* Node may be deleted from bgp_unlock_node so we have to preserve
next node's pointer. */
if (node->l_left)
{
next = node->l_left;
bgp_lock_node (next);
bgp_unlock_node (node);
return next;
}
if (node->l_right)
{
next = node->l_right;
bgp_lock_node (next);
bgp_unlock_node (node);
return next;
}
start = node;
while (node->parent)
{
if (node->parent->l_left == node && node->parent->l_right)
{
next = node->parent->l_right;
bgp_lock_node (next);
bgp_unlock_node (start);
return next;
}
node = node->parent;
}
bgp_unlock_node (start);
return NULL;
}
/* Unlock current node and lock next node until limit. */
struct bgp_node *
bgp_route_next_until (struct bgp_node *node, struct bgp_node *limit)
{
struct bgp_node *next;
struct bgp_node *start;
/* Node may be deleted from bgp_unlock_node so we have to preserve
next node's pointer. */
if (node->l_left)
{
next = node->l_left;
bgp_lock_node (next);
bgp_unlock_node (node);
return next;
}
if (node->l_right)
{
next = node->l_right;
bgp_lock_node (next);
bgp_unlock_node (node);
return next;
}
start = node;
while (node->parent && node != limit)
{
if (node->parent->l_left == node && node->parent->l_right)
{
next = node->parent->l_right;
bgp_lock_node (next);
bgp_unlock_node (start);
return next;
}
node = node->parent;
}
bgp_unlock_node (start);
return NULL;
}

65
bgpd/bgp_table.h Normal file
View File

@ -0,0 +1,65 @@
/* BGP routing table
Copyright (C) 1998, 2001 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. */
struct bgp_table
{
struct bgp_node *top;
};
struct bgp_node
{
struct prefix p;
struct bgp_table *table;
struct bgp_node *parent;
struct bgp_node *link[2];
#define l_left link[0]
#define l_right link[1]
unsigned int lock;
void *info;
struct bgp_adj_out *adj_out;
struct bgp_adj_in *adj_in;
void *aggregate;
struct bgp_node *prn;
};
struct bgp_table *bgp_table_init (void);
void bgp_table_finish (struct bgp_table *);
void bgp_unlock_node (struct bgp_node *node);
void bgp_node_delete (struct bgp_node *node);
struct bgp_node *bgp_table_top (struct bgp_table *);
struct bgp_node *bgp_route_next (struct bgp_node *);
struct bgp_node *bgp_route_next_until (struct bgp_node *, struct bgp_node *);
struct bgp_node *bgp_node_get (struct bgp_table *, struct prefix *);
struct bgp_node *bgp_node_lookup (struct bgp_table *, struct prefix *);
struct bgp_node *bgp_lock_node (struct bgp_node *node);
struct bgp_node *bgp_node_match (struct bgp_table *, struct prefix *);
struct bgp_node *bgp_node_match_ipv4 (struct bgp_table *,
struct in_addr *);
#ifdef HAVE_IPV6
struct bgp_node *bgp_node_match_ipv6 (struct bgp_table *,
struct in6_addr *);
#endif /* HAVE_IPV6 */

258
bgpd/bgp_view.c Normal file
View File

@ -0,0 +1,258 @@
/*
* $Id: bgp_view.c,v 1.1 2002/12/13 20:15:29 paul Exp $
*
* Multiple view function for route server.
* Copyright (C) 1997 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 "linklist.h"
#include "vector.h"
#include "vty.h"
#include "command.h"
#include "prefix.h"
#include "zebra/zebra.h"
#include "table.h"
#include "log.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_route.h"
#include "bgpd/bgp_attr.h"
#include "bgpd/bgp_dump.h"
#include "bgpd/bgp_aspath.h"
/* Static configuration of BGP annoucement. */
struct route_table *bgp_static_ipv4;
#ifdef HAVE_IPV6
struct route_table *bgp_static_ipv6;
#endif /* HAVE_IPV6 */
/* Static annoucement peer. */
struct peer *static_peer;
/* Default value setting flag */
#define VAL_LOCAL_PREF 0x01
#define VAL_MED 0x02
#define VAL_NEXT_HOP 0x04
DEFUN (default_attr_localpref,
default_attr_localpref_cmd,
"default-attr local-pref NUMBER",
"Set default local preference value\n"
"Set default local preference value\n"
"Value\n")
{
struct bgp *bgp;
long lpref;
bgp = (struct bgp *) vty->index;
lpref = strtol (argv[0], NULL, 10);
bgp->def |= VAL_LOCAL_PREF;
bgp->localpref = lpref;
return CMD_SUCCESS;
}
DEFUN (no_default_attr_localpref,
no_default_attr_localpref_cmd,
"no default-attr local-pref NUMBER",
NO_STR
"Unset default local preference value\n"
"Unset default local preference value\n"
"Value\n")
{
struct bgp *bgp;
bgp = (struct bgp *) vty->index;
bgp->def &= ~DEFAULT_LOCAL_PREF;
bgp->localpref = 0;
return CMD_SUCCESS;
}
#ifdef HAVE_IPV6
/* Network configuration for IPv6. */
int
bgp_network_config_ipv6 (struct vty *vty, char *address_str)
{
int ret;
struct prefix p;
struct route_node *node;
struct bgp_info *bgp_info;
ret = str2prefix_ipv6 (address_str, (struct prefix_ipv6 *) &p);
if (!ret)
{
vty_out (vty, "Please specify valid address\r\n");
return CMD_WARNING;
}
apply_mask_ipv6 ((struct prefix_ipv6 *) &p);
node = route_node_get (bgp_static_ipv6, &p);
if (node->info)
{
vty_out (vty, "There is already same static announcement.\r\n");
route_unlock_node (node);
return CMD_WARNING;
}
bgp_info = bgp_info_new ();
bgp_info->type = ZEBRA_ROUTE_STATIC;
bgp_info->peer = static_peer;
bgp_info->attr = bgp_attr_make_default ();
node->info = bgp_info;
nlri_process (&p, bgp_info);
return CMD_SUCCESS;
}
#endif
/* Configure static BGP network. */
DEFUN (bgp_network,
bgp_network_cmd,
"network PREFIX",
"Announce network setup\n"
"Static network for bgp announcement\n")
{
int ret;
struct bgp *bgp;
struct prefix p;
struct route_node *node;
struct bgp_info *bgp_info;
bgp = (struct bgp *) vty->index;
ret = str2prefix_ipv4 (argv[0], (struct prefix_ipv4 *) &p);
if (!ret)
{
#ifdef HAVE_IPV6
return bgp_network_config_ipv6 (vty, argv[0]);
#endif /* HAVE_IPV6 */
vty_out (vty, "Please specify address by a.b.c.d/mask\r\n");
return CMD_WARNING;
}
/* Make sure mask is applied. */
apply_mask ((struct prefix_ipv4 *) &p);
node = route_node_get (bgp_static_ipv4, &p);
if (node->info)
{
vty_out (vty, "There is already same static announcement.\r\n");
route_unlock_node (node);
return CMD_WARNING;
}
bgp_info = bgp_info_new ();
bgp_info->type = ZEBRA_ROUTE_STATIC;
bgp_info->peer = static_peer;
bgp_info->attr = bgp_attr_make_default ();
node->info = bgp_info;
nlri_process (&p, bgp_info);
return CMD_SUCCESS;
}
DEFUN (no_bgp_network,
no_bgp_network_cmd,
"no network PREFIX",
NO_STR
"Announce network setup\n"
"Delete static network for bgp announcement\n")
{
int ret;
struct bgp *bgp;
struct route_node *np;
struct prefix_ipv4 p;
bgp = (struct bgp *) vty->index;
ret = str2prefix_ipv4 (argv[0], &p);
if (!ret)
{
vty_out (vty, "Please specify address by a.b.c.d/mask\r\n");
return CMD_WARNING;
}
apply_mask (&p);
np = route_node_get (bgp_static_ipv4, (struct prefix *) &p);
if (!np->info)
{
vty_out (vty, "Can't find specified static route configuration.\r\n");
route_unlock_node (np);
return CMD_WARNING;
}
nlri_delete (static_peer, (struct prefix *) &p);
/* bgp_attr_free (np->info); */
np->info = NULL;
route_unlock_node (np);
return CMD_SUCCESS;
}
int
config_write_network (struct vty *vty, struct bgp *bgp)
{
struct route_node *node;
struct bgp_route *route;
char buf[BUFSIZ];
for (node = route_top (bgp_static_ipv4); node; node = route_next (node))
for (route = node->info; route; route = route->next)
vty_out (vty, " network %s/%d%s",
inet_ntoa (node->p.u.prefix4), node->p.prefixlen, VTY_NEWLINE);
#ifdef HAVE_IPV6
for (node = route_top (bgp_static_ipv6); node; node = route_next (node))
for (route = node->info; route; route = route->next)
vty_out (vty, " network %s/%d%s",
inet_ntop (AF_INET6, &node->p.u.prefix6, buf, BUFSIZ),
node->p.prefixlen, VTY_NEWLINE);
#endif /* HAVE_IPV6 */
return 0;
}
void
view_init ()
{
bgp_static_ipv4 = route_table_init ();
#ifdef HAVE_IPV6
bgp_static_ipv6 = route_table_init ();
#endif /* HAVE_IPV6 */
static_peer = peer_new ();
static_peer->host = "Static annucement";
install_element (BGP_NODE, &bgp_network_cmd);
install_element (BGP_NODE, &no_bgp_network_cmd);
install_element (BGP_NODE, &default_attr_localpref_cmd);
install_element (BGP_NODE, &no_default_attr_localpref_cmd);
}

9416
bgpd/bgp_vty.c Normal file

File diff suppressed because it is too large Load Diff

21
bgpd/bgp_vty.h Normal file
View File

@ -0,0 +1,21 @@
/* BGP VTY interface.
Copyright (C) 1996, 97, 98, 99, 2000 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. */
void bgp_vty_init ();

1001
bgpd/bgp_zebra.c Normal file

File diff suppressed because it is too large Load Diff

39
bgpd/bgp_zebra.h Normal file
View File

@ -0,0 +1,39 @@
/* zebra connection and redistribute fucntions.
Copyright (C) 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. */
int bgp_if_update_all ();
int bgp_config_write_redistribute (struct vty *, struct bgp *, afi_t, safi_t,
int *);
void bgp_zebra_announce (struct prefix *, struct bgp_info *, struct bgp *);
void bgp_zebra_withdraw (struct prefix *, struct bgp_info *);
int bgp_redistribute_set (struct bgp *, afi_t, int);
int bgp_redistribute_rmap_set (struct bgp *, afi_t, int, char *);
int bgp_redistribute_metric_set (struct bgp *, afi_t, int, u_int32_t);
int bgp_redistribute_unset (struct bgp *, afi_t, int);
int bgp_redistribute_routemap_unset (struct bgp *, afi_t, int);
int bgp_redistribute_metric_unset (struct bgp *, afi_t, int);
struct interface *if_lookup_by_ipv4 (struct in_addr *);
struct interface *if_lookup_by_ipv4_exact (struct in_addr *);
#ifdef HAVE_IPV6
struct interface *if_lookup_by_ipv6 (struct in6_addr *);
struct interface *if_lookup_by_ipv6_exact (struct in6_addr *);
#endif /* HAVE_IPV6 */

4601
bgpd/bgpd.c Normal file

File diff suppressed because it is too large Load Diff

29
bgpd/bgpd.conf.sample Normal file
View File

@ -0,0 +1,29 @@
! -*- bgp -*-
!
! BGPd sample configuratin file
!
! $Id: bgpd.conf.sample,v 1.1 2002/12/13 20:15:29 paul Exp $
!
hostname bgpd
password zebra
!enable password please-set-at-here
!
!bgp mulitple-instance
!
router bgp 7675
! bgp router-id 10.0.0.1
! network 10.0.0.0/8
! neighbor 10.0.0.2 remote-as 7675
! neighbor 10.0.0.2 route-map set-nexthop out
! neighbor 10.0.0.2 ebgp-multihop
! neighbor 10.0.0.2 next-hop-self
!
! access-list all permit any
!
!route-map set-nexthop permit 10
! match ip address all
! set ip next-hop 10.0.0.1
!
!log file bgpd.log
!
log stdout

77
bgpd/bgpd.conf.sample2 Normal file
View File

@ -0,0 +1,77 @@
!
! Zebra configuration saved from vty
! 2002/07/01 03:16:33
!
hostname bgpd
password zebra
log file bgpd.log
log stdout
!
router bgp 7675
no bgp default ipv4-unicast
neighbor 3ffe:506:1000::2 remote-as 7675
neighbor fe80::200:c0ff:fe30:9be3 remote-as 9377
neighbor fe80::200:c0ff:fe30:9be3 interface sit3
neighbor fe80::210:5aff:fe6b:3cee remote-as 7675
neighbor fe80::210:5aff:fe6b:3cee interface eth0
neighbor fe80::290:27ff:fe51:84c7 remote-as 4691
neighbor fe80::290:27ff:fe51:84c7 description DTI
neighbor fe80::290:27ff:fe51:84c7 interface sit7
neighbor fe80::2a0:c9ff:fec8:82ec remote-as 7530
neighbor fe80::2a0:c9ff:fec8:82ec description IRI
neighbor fe80::2a0:c9ff:fec8:82ec interface sit8
neighbor fe80::2e0:18ff:fe98:2725 remote-as 2500
neighbor fe80::2e0:18ff:fe98:2725 description WIDE
neighbor fe80::2e0:18ff:fe98:2725 interface sit5
neighbor fe80::2e0:18ff:fea8:bf5 remote-as 65000
neighbor fe80::2e0:18ff:fea8:bf5 interface sit6
!
address-family ipv6
network 3ffe:506::/33
network 3ffe:1800:e800::/40
aggregate-address 3ffe:506::/32
redistribute connected
neighbor 3ffe:506:1000::2 activate
neighbor fe80::200:c0ff:fe30:9be3 activate
neighbor fe80::200:c0ff:fe30:9be3 route-map set-nexthop out
neighbor fe80::210:5aff:fe6b:3cee activate
neighbor fe80::290:27ff:fe51:84c7 activate
neighbor fe80::290:27ff:fe51:84c7 route-map set-nexthop out
neighbor fe80::2a0:c9ff:fec8:82ec activate
neighbor fe80::2a0:c9ff:fec8:82ec route-map set-nexthop out
neighbor fe80::2e0:18ff:fe98:2725 activate
neighbor fe80::2e0:18ff:fe98:2725 distribute-list nla1 out
neighbor fe80::2e0:18ff:fe98:2725 route-map set-nexthop out
neighbor fe80::2e0:18ff:fea8:bf5 activate
neighbor fe80::2e0:18ff:fea8:bf5 route-map set-nexthop out
exit-address-family
!
ipv6 access-list all permit any
ipv6 access-list nla1 deny 3ffe:506::/33
ipv6 access-list nla1 permit 3ffe:506::/32
ipv6 access-list nla1 deny any
ipv6 access-list ntt-nla1 permit 3ffe:1800:0:ffff::c/127
ipv6 access-list ntt-nla1 deny 3ffe:1800:e800::/41
ipv6 access-list ntt-nla1 permit 3ffe:1800:e800::/40
ipv6 access-list ntt-nla1 deny any
!
ipv6 prefix-list 6bone-filter seq 5 permit 3ffe::/17 ge 24 le 24
ipv6 prefix-list 6bone-filter seq 10 permit 3ffe:8000::/17 ge 28 le 28
ipv6 prefix-list 6bone-filter seq 12 deny 3ffe::/16
ipv6 prefix-list 6bone-filter seq 15 permit 2000::/3 ge 16 le 16
ipv6 prefix-list 6bone-filter seq 20 permit 2001::/16 ge 35 le 35
!
route-map set-nexthop permit 10
match ipv6 address all
set ipv6 next-hop global 3ffe:506::1
set ipv6 next-hop local fe80::cbb5:591a
set ip next-hop 203.181.89.26
set community 7675:0
!
route-map set-link-local permit 10
match ipv6 address all
set ipv6 next-hop local fe80::cbb5:591a
set ipv6 next-hop global 3ffe:1800:0:ffff::d
!
line vty
!

824
bgpd/bgpd.h Normal file
View File

@ -0,0 +1,824 @@
/* BGP message definition header.
Copyright (C) 1996, 97, 98, 99, 2000 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. */
/* For union sockunion. */
#include "sockunion.h"
/* Typedef BGP specific types. */
typedef u_int16_t as_t;
typedef u_int16_t bgp_size_t;
/* BGP master for system wide configurations and variables. */
struct bgp_master
{
/* BGP instance list. */
struct list *bgp;
/* BGP thread master. */
struct thread_master *master;
/* BGP port number. */
u_int16_t port;
/* BGP start time. */
time_t start_time;
/* Various BGP global configuration. */
u_char options;
#define BGP_OPT_NO_FIB (1 << 0)
#define BGP_OPT_MULTIPLE_INSTANCE (1 << 1)
#define BGP_OPT_CONFIG_CISCO (1 << 2)
};
/* BGP instance structure. */
struct bgp
{
/* AS number of this BGP instance. */
as_t as;
/* Name of this BGP instance. */
char *name;
/* Self peer. */
struct peer *peer_self;
/* BGP peer. */
struct list *peer;
/* BGP peer group. */
struct list *group;
/* BGP configuration. */
u_int16_t config;
#define BGP_CONFIG_ROUTER_ID (1 << 0)
#define BGP_CONFIG_CLUSTER_ID (1 << 1)
#define BGP_CONFIG_CONFEDERATION (1 << 2)
#define BGP_CONFIG_DEFAULT_LOCAL_PREF (1 << 3)
/* BGP router identifier. */
struct in_addr router_id;
/* BGP route reflector cluster ID. */
struct in_addr cluster_id;
/* BGP confederation information. */
as_t confed_id;
as_t *confed_peers;
int confed_peers_cnt;
/* BGP flags. */
u_int16_t flags;
#define BGP_FLAG_ALWAYS_COMPARE_MED (1 << 0)
#define BGP_FLAG_DETERMINISTIC_MED (1 << 1)
#define BGP_FLAG_MED_MISSING_AS_WORST (1 << 2)
#define BGP_FLAG_MED_CONFED (1 << 3)
#define BGP_FLAG_NO_DEFAULT_IPV4 (1 << 4)
#define BGP_FLAG_NO_CLIENT_TO_CLIENT (1 << 5)
#define BGP_FLAG_ENFORCE_FIRST_AS (1 << 6)
#define BGP_FLAG_COMPARE_ROUTER_ID (1 << 7)
#define BGP_FLAG_ASPATH_IGNORE (1 << 8)
#define BGP_FLAG_IMPORT_CHECK (1 << 9)
#define BGP_FLAG_NO_FAST_EXT_FAILOVER (1 << 10)
/* BGP Per AF flags */
u_int16_t af_flags[AFI_MAX][SAFI_MAX];
#define BGP_CONFIG_DAMPENING (1 << 0)
/* Static route configuration. */
struct bgp_table *route[AFI_MAX][SAFI_MAX];
/* Aggregate address configuration. */
struct bgp_table *aggregate[AFI_MAX][SAFI_MAX];
/* BGP routing information base. */
struct bgp_table *rib[AFI_MAX][SAFI_MAX];
/* BGP redistribute configuration. */
u_char redist[AFI_MAX][ZEBRA_ROUTE_MAX];
/* BGP redistribute metric configuration. */
u_char redist_metric_flag[AFI_MAX][ZEBRA_ROUTE_MAX];
u_int32_t redist_metric[AFI_MAX][ZEBRA_ROUTE_MAX];
/* BGP redistribute route-map. */
struct
{
char *name;
struct route_map *map;
} rmap[AFI_MAX][ZEBRA_ROUTE_MAX];
/* BGP distance configuration. */
u_char distance_ebgp;
u_char distance_ibgp;
u_char distance_local;
/* BGP default local-preference. */
u_int32_t default_local_pref;
/* BGP default timer. */
u_int32_t default_holdtime;
u_int32_t default_keepalive;
};
/* BGP peer-group support. */
struct peer_group
{
/* Name of the peer-group. */
char *name;
/* Pointer to BGP. */
struct bgp *bgp;
/* Peer-group client list. */
struct list *peer;
/* Peer-group config */
struct peer *conf;
};
/* BGP Notify message format. */
struct bgp_notify
{
u_char code;
u_char subcode;
char *data;
bgp_size_t length;
};
/* Next hop self address. */
struct bgp_nexthop
{
struct interface *ifp;
struct in_addr v4;
#ifdef HAVE_IPV6
struct in6_addr v6_global;
struct in6_addr v6_local;
#endif /* HAVE_IPV6 */
};
/* BGP router distinguisher value. */
#define BGP_RD_SIZE 8
struct bgp_rd
{
u_char val[BGP_RD_SIZE];
};
/* BGP filter structure. */
struct bgp_filter
{
/* Distribute-list. */
struct
{
char *name;
struct access_list *alist;
} dlist[FILTER_MAX];
/* Prefix-list. */
struct
{
char *name;
struct prefix_list *plist;
} plist[FILTER_MAX];
/* Filter-list. */
struct
{
char *name;
struct as_list *aslist;
} aslist[FILTER_MAX];
/* Route-map. */
struct
{
char *name;
struct route_map *map;
} map[FILTER_MAX];
/* Unsuppress-map. */
struct
{
char *name;
struct route_map *map;
} usmap;
};
/* BGP neighbor structure. */
struct peer
{
/* BGP structure. */
struct bgp *bgp;
/* BGP peer group. */
struct peer_group *group;
u_char af_group[AFI_MAX][SAFI_MAX];
/* Peer's remote AS number. */
as_t as;
/* Peer's local AS number. */
as_t local_as;
/* Peer's Change local AS number. */
as_t change_local_as;
/* Remote router ID. */
struct in_addr remote_id;
/* Local router ID. */
struct in_addr local_id;
/* Packet receive and send buffer. */
struct stream *ibuf;
struct stream_fifo *obuf;
struct stream *work;
/* Status of the peer. */
int status;
int ostatus;
/* Peer information */
int fd; /* File descriptor */
int ttl; /* TTL of TCP connection to the peer. */
char *desc; /* Description of the peer. */
unsigned short port; /* Destination port for peer */
char *host; /* Printable address of the peer. */
union sockunion su; /* Sockunion address of the peer. */
time_t uptime; /* Last Up/Down time */
time_t readtime; /* Last read time */
unsigned int ifindex; /* ifindex of the BGP connection. */
char *ifname; /* bind interface name. */
char *update_if;
union sockunion *update_source;
struct zlog *log;
u_char version; /* Peer BGP version. */
union sockunion *su_local; /* Sockunion of local address. */
union sockunion *su_remote; /* Sockunion of remote address. */
int shared_network; /* Is this peer shared same network. */
struct bgp_nexthop nexthop; /* Nexthop */
/* Peer address family configuration. */
u_char afc[AFI_MAX][SAFI_MAX];
u_char afc_nego[AFI_MAX][SAFI_MAX];
u_char afc_adv[AFI_MAX][SAFI_MAX];
u_char afc_recv[AFI_MAX][SAFI_MAX];
/* Capability Flags.*/
u_char cap;
#define PEER_CAP_REFRESH_ADV (1 << 0) /* refresh advertised */
#define PEER_CAP_REFRESH_OLD_RCV (1 << 1) /* refresh old received */
#define PEER_CAP_REFRESH_NEW_RCV (1 << 2) /* refresh rfc received */
#define PEER_CAP_DYNAMIC_ADV (1 << 3) /* dynamic advertised */
#define PEER_CAP_DYNAMIC_RCV (1 << 4) /* dynamic received */
/* Capability Flags.*/
u_int16_t af_cap[AFI_MAX][SAFI_MAX];
#define PEER_CAP_ORF_PREFIX_SM_ADV (1 << 0) /* send-mode advertised */
#define PEER_CAP_ORF_PREFIX_RM_ADV (1 << 1) /* receive-mode advertised */
#define PEER_CAP_ORF_PREFIX_SM_RCV (1 << 2) /* send-mode received */
#define PEER_CAP_ORF_PREFIX_RM_RCV (1 << 3) /* receive-mode received */
#define PEER_CAP_ORF_PREFIX_SM_OLD_RCV (1 << 4) /* send-mode received */
#define PEER_CAP_ORF_PREFIX_RM_OLD_RCV (1 << 5) /* receive-mode received */
/* Global configuration flags. */
u_int32_t flags;
#define PEER_FLAG_PASSIVE (1 << 0) /* passive mode */
#define PEER_FLAG_SHUTDOWN (1 << 1) /* shutdown */
#define PEER_FLAG_DONT_CAPABILITY (1 << 2) /* dont-capability */
#define PEER_FLAG_OVERRIDE_CAPABILITY (1 << 3) /* override-capability */
#define PEER_FLAG_STRICT_CAP_MATCH (1 << 4) /* strict-match */
#define PEER_FLAG_NO_ROUTE_REFRESH_CAP (1 << 5) /* route-refresh */
#define PEER_FLAG_DYNAMIC_CAPABILITY (1 << 6) /* dynamic capability */
#define PEER_FLAG_ENFORCE_MULTIHOP (1 << 7) /* enforce-multihop */
#define PEER_FLAG_LOCAL_AS_NO_PREPEND (1 << 8) /* local-as no-prepend */
/* Per AF configuration flags. */
u_int32_t af_flags[AFI_MAX][SAFI_MAX];
#define PEER_FLAG_SEND_COMMUNITY (1 << 0) /* send-community */
#define PEER_FLAG_SEND_EXT_COMMUNITY (1 << 1) /* send-community ext. */
#define PEER_FLAG_NEXTHOP_SELF (1 << 2) /* next-hop-self */
#define PEER_FLAG_REFLECTOR_CLIENT (1 << 3) /* reflector-client */
#define PEER_FLAG_RSERVER_CLIENT (1 << 4) /* route-server-client */
#define PEER_FLAG_SOFT_RECONFIG (1 << 5) /* soft-reconfiguration */
#define PEER_FLAG_AS_PATH_UNCHANGED (1 << 6) /* transparent-as */
#define PEER_FLAG_NEXTHOP_UNCHANGED (1 << 7) /* transparent-next-hop */
#define PEER_FLAG_MED_UNCHANGED (1 << 8) /* transparent-next-hop */
#define PEER_FLAG_DEFAULT_ORIGINATE (1 << 9) /* default-originate */
#define PEER_FLAG_REMOVE_PRIVATE_AS (1 << 10) /* remove-private-as */
#define PEER_FLAG_ALLOWAS_IN (1 << 11) /* set allowas-in */
#define PEER_FLAG_ORF_PREFIX_SM (1 << 12) /* orf capability send-mode */
#define PEER_FLAG_ORF_PREFIX_RM (1 << 13) /* orf capability receive-mode */
#define PEER_FLAG_MAX_PREFIX (1 << 14) /* maximum prefix */
#define PEER_FLAG_MAX_PREFIX_WARNING (1 << 15) /* maximum prefix warning-only */
/* default-originate route-map. */
struct
{
char *name;
struct route_map *map;
} default_rmap[AFI_MAX][SAFI_MAX];
/* Peer status flags. */
u_int16_t sflags;
#define PEER_STATUS_ACCEPT_PEER (1 << 0) /* accept peer */
#define PEER_STATUS_PREFIX_OVERFLOW (1 << 1) /* prefix-overflow */
#define PEER_STATUS_CAPABILITY_OPEN (1 << 2) /* capability open send */
#define PEER_STATUS_HAVE_ACCEPT (1 << 3) /* accept peer's parent */
#define PEER_STATUS_GROUP (1 << 4) /* peer-group conf */
/* Peer status af flags. */
u_int16_t af_sflags[AFI_MAX][SAFI_MAX];
#define PEER_STATUS_ORF_PREFIX_SEND (1 << 0) /* prefix-list send peer */
#define PEER_STATUS_ORF_WAIT_REFRESH (1 << 1) /* wait refresh received peer */
#define PEER_STATUS_DEFAULT_ORIGINATE (1 << 2) /* default-originate peer */
/* Default attribute value for the peer. */
u_int32_t config;
#define PEER_CONFIG_WEIGHT (1 << 0) /* Default weight. */
#define PEER_CONFIG_TIMER (1 << 1) /* keepalive & holdtime */
#define PEER_CONFIG_CONNECT (1 << 2) /* connect */
#define PEER_CONFIG_ROUTEADV (1 << 3) /* route advertise */
u_int32_t weight;
u_int32_t holdtime;
u_int32_t keepalive;
u_int32_t connect;
u_int32_t routeadv;
/* Timer values. */
u_int32_t v_start;
u_int32_t v_connect;
u_int32_t v_holdtime;
u_int32_t v_keepalive;
u_int32_t v_asorig;
u_int32_t v_routeadv;
/* Threads. */
struct thread *t_read;
struct thread *t_write;
struct thread *t_start;
struct thread *t_connect;
struct thread *t_holdtime;
struct thread *t_keepalive;
struct thread *t_asorig;
struct thread *t_routeadv;
/* Statistics field */
u_int32_t open_in; /* Open message input count */
u_int32_t open_out; /* Open message output count */
u_int32_t update_in; /* Update message input count */
u_int32_t update_out; /* Update message ouput count */
time_t update_time; /* Update message received time. */
u_int32_t keepalive_in; /* Keepalive input count */
u_int32_t keepalive_out; /* Keepalive output count */
u_int32_t notify_in; /* Notify input count */
u_int32_t notify_out; /* Notify output count */
u_int32_t refresh_in; /* Route Refresh input count */
u_int32_t refresh_out; /* Route Refresh output count */
u_int32_t dynamic_cap_in; /* Dynamic Capability input count. */
u_int32_t dynamic_cap_out; /* Dynamic Capability output count. */
/* BGP state count */
u_int32_t established; /* Established */
u_int32_t dropped; /* Dropped */
/* Syncronization list and time. */
struct bgp_synchronize *sync[AFI_MAX][SAFI_MAX];
time_t synctime;
/* Send prefix count. */
unsigned long scount[AFI_MAX][SAFI_MAX];
/* Announcement attribute hash. */
struct hash *hash[AFI_MAX][SAFI_MAX];
/* Notify data. */
struct bgp_notify notify;
/* Whole packet size to be read. */
unsigned long packet_size;
/* Filter structure. */
struct bgp_filter filter[AFI_MAX][SAFI_MAX];
/* ORF Prefix-list */
struct prefix_list *orf_plist[AFI_MAX][SAFI_MAX];
/* Prefix count. */
unsigned long pcount[AFI_MAX][SAFI_MAX];
/* Max prefix count. */
unsigned long pmax[AFI_MAX][SAFI_MAX];
/* allowas-in. */
char allowas_in[AFI_MAX][SAFI_MAX];
};
/* This structure's member directly points incoming packet data
stream. */
struct bgp_nlri
{
/* AFI. */
afi_t afi;
/* SAFI. */
safi_t safi;
/* Pointer to NLRI byte stream. */
u_char *nlri;
/* Length of whole NLRI. */
bgp_size_t length;
};
/* BGP versions. */
#define BGP_VERSION_4 4
#define BGP_VERSION_MP_4_DRAFT_00 40
/* Default BGP port number. */
#define BGP_PORT_DEFAULT 179
/* BGP message header and packet size. */
#define BGP_MARKER_SIZE 16
#define BGP_HEADER_SIZE 19
#define BGP_MAX_PACKET_SIZE 4096
/* BGP minimum message size. */
#define BGP_MSG_OPEN_MIN_SIZE (BGP_HEADER_SIZE + 10)
#define BGP_MSG_UPDATE_MIN_SIZE (BGP_HEADER_SIZE + 4)
#define BGP_MSG_NOTIFY_MIN_SIZE (BGP_HEADER_SIZE + 2)
#define BGP_MSG_KEEPALIVE_MIN_SIZE (BGP_HEADER_SIZE + 0)
#define BGP_MSG_ROUTE_REFRESH_MIN_SIZE (BGP_HEADER_SIZE + 4)
#define BGP_MSG_CAPABILITY_MIN_SIZE (BGP_HEADER_SIZE + 3)
/* BGP message types. */
#define BGP_MSG_OPEN 1
#define BGP_MSG_UPDATE 2
#define BGP_MSG_NOTIFY 3
#define BGP_MSG_KEEPALIVE 4
#define BGP_MSG_ROUTE_REFRESH_NEW 5
#define BGP_MSG_CAPABILITY 6
#define BGP_MSG_ROUTE_REFRESH_OLD 128
/* BGP open optional parameter. */
#define BGP_OPEN_OPT_AUTH 1
#define BGP_OPEN_OPT_CAP 2
/* BGP4 attribute type codes. */
#define BGP_ATTR_ORIGIN 1
#define BGP_ATTR_AS_PATH 2
#define BGP_ATTR_NEXT_HOP 3
#define BGP_ATTR_MULTI_EXIT_DISC 4
#define BGP_ATTR_LOCAL_PREF 5
#define BGP_ATTR_ATOMIC_AGGREGATE 6
#define BGP_ATTR_AGGREGATOR 7
#define BGP_ATTR_COMMUNITIES 8
#define BGP_ATTR_ORIGINATOR_ID 9
#define BGP_ATTR_CLUSTER_LIST 10
#define BGP_ATTR_DPA 11
#define BGP_ATTR_ADVERTISER 12
#define BGP_ATTR_RCID_PATH 13
#define BGP_ATTR_MP_REACH_NLRI 14
#define BGP_ATTR_MP_UNREACH_NLRI 15
#define BGP_ATTR_EXT_COMMUNITIES 16
/* BGP update origin. */
#define BGP_ORIGIN_IGP 0
#define BGP_ORIGIN_EGP 1
#define BGP_ORIGIN_INCOMPLETE 2
/* BGP notify message codes. */
#define BGP_NOTIFY_HEADER_ERR 1
#define BGP_NOTIFY_OPEN_ERR 2
#define BGP_NOTIFY_UPDATE_ERR 3
#define BGP_NOTIFY_HOLD_ERR 4
#define BGP_NOTIFY_FSM_ERR 5
#define BGP_NOTIFY_CEASE 6
#define BGP_NOTIFY_CAPABILITY_ERR 7
#define BGP_NOTIFY_MAX 8
/* BGP_NOTIFY_HEADER_ERR sub codes. */
#define BGP_NOTIFY_HEADER_NOT_SYNC 1
#define BGP_NOTIFY_HEADER_BAD_MESLEN 2
#define BGP_NOTIFY_HEADER_BAD_MESTYPE 3
#define BGP_NOTIFY_HEADER_MAX 4
/* BGP_NOTIFY_OPEN_ERR sub codes. */
#define BGP_NOTIFY_OPEN_UNSUP_VERSION 1
#define BGP_NOTIFY_OPEN_BAD_PEER_AS 2
#define BGP_NOTIFY_OPEN_BAD_BGP_IDENT 3
#define BGP_NOTIFY_OPEN_UNSUP_PARAM 4
#define BGP_NOTIFY_OPEN_AUTH_FAILURE 5
#define BGP_NOTIFY_OPEN_UNACEP_HOLDTIME 6
#define BGP_NOTIFY_OPEN_UNSUP_CAPBL 7
#define BGP_NOTIFY_OPEN_MAX 8
/* BGP_NOTIFY_UPDATE_ERR sub codes. */
#define BGP_NOTIFY_UPDATE_MAL_ATTR 1
#define BGP_NOTIFY_UPDATE_UNREC_ATTR 2
#define BGP_NOTIFY_UPDATE_MISS_ATTR 3
#define BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR 4
#define BGP_NOTIFY_UPDATE_ATTR_LENG_ERR 5
#define BGP_NOTIFY_UPDATE_INVAL_ORIGIN 6
#define BGP_NOTIFY_UPDATE_AS_ROUTE_LOOP 7
#define BGP_NOTIFY_UPDATE_INVAL_NEXT_HOP 8
#define BGP_NOTIFY_UPDATE_OPT_ATTR_ERR 9
#define BGP_NOTIFY_UPDATE_INVAL_NETWORK 10
#define BGP_NOTIFY_UPDATE_MAL_AS_PATH 11
#define BGP_NOTIFY_UPDATE_MAX 12
/* BGP_NOTIFY_CEASE sub codes (draft-ietf-idr-cease-subcode-00). */
#define BGP_NOTIFY_CEASE_MAX_PREFIX 1
#define BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN 2
#define BGP_NOTIFY_CEASE_PEER_UNCONFIG 3
#define BGP_NOTIFY_CEASE_ADMIN_RESET 4
#define BGP_NOTIFY_CEASE_CONNECT_REJECT 5
#define BGP_NOTIFY_CEASE_CONFIG_CHANGE 6
#define BGP_NOTIFY_CEASE_MAX 7
/* BGP_NOTIFY_CAPABILITY_ERR sub codes (draft-ietf-idr-dynamic-cap-02). */
#define BGP_NOTIFY_CAPABILITY_INVALID_ACTION 1
#define BGP_NOTIFY_CAPABILITY_INVALID_LENGTH 2
#define BGP_NOTIFY_CAPABILITY_MALFORMED_CODE 3
#define BGP_NOTIFY_CAPABILITY_MAX 4
/* BGP finite state machine status. */
#define Idle 1
#define Connect 2
#define Active 3
#define OpenSent 4
#define OpenConfirm 5
#define Established 6
#define BGP_STATUS_MAX 7
/* BGP finite state machine events. */
#define BGP_Start 1
#define BGP_Stop 2
#define TCP_connection_open 3
#define TCP_connection_closed 4
#define TCP_connection_open_failed 5
#define TCP_fatal_error 6
#define ConnectRetry_timer_expired 7
#define Hold_Timer_expired 8
#define KeepAlive_timer_expired 9
#define Receive_OPEN_message 10
#define Receive_KEEPALIVE_message 11
#define Receive_UPDATE_message 12
#define Receive_NOTIFICATION_message 13
#define BGP_EVENTS_MAX 14
/* BGP timers default value. */
#define BGP_INIT_START_TIMER 5
#define BGP_ERROR_START_TIMER 30
#define BGP_DEFAULT_HOLDTIME 180
#define BGP_DEFAULT_KEEPALIVE 60
#define BGP_DEFAULT_ASORIGINATE 15
#define BGP_DEFAULT_EBGP_ROUTEADV 30
#define BGP_DEFAULT_IBGP_ROUTEADV 5
#define BGP_CLEAR_CONNECT_RETRY 20
#define BGP_DEFAULT_CONNECT_RETRY 120
/* BGP default local preference. */
#define BGP_DEFAULT_LOCAL_PREF 100
/* SAFI which used in open capability negotiation. */
#define BGP_SAFI_VPNV4 128
#define BGP_SAFI_VPNV6 129
/* Max TTL value. */
#define TTL_MAX 255
/* BGP uptime string length. */
#define BGP_UPTIME_LEN 25
/* Default configuration settings for bgpd. */
#define BGP_VTY_PORT 2605
#define BGP_VTYSH_PATH "/tmp/.bgpd"
#define BGP_DEFAULT_CONFIG "bgpd.conf"
/* Check AS path loop when we send NLRI. */
/* #define BGP_SEND_ASPATH_CHECK */
/* IBGP/EBGP identifier. We also have a CONFED peer, which is to say,
a peer who's AS is part of our Confederation. */
enum
{
BGP_PEER_IBGP,
BGP_PEER_EBGP,
BGP_PEER_INTERNAL,
BGP_PEER_CONFED
};
/* Flag for peer_clear_soft(). */
enum bgp_clear_type
{
BGP_CLEAR_SOFT_NONE,
BGP_CLEAR_SOFT_OUT,
BGP_CLEAR_SOFT_IN,
BGP_CLEAR_SOFT_BOTH,
BGP_CLEAR_SOFT_IN_ORF_PREFIX
};
/* Macros. */
#define BGP_INPUT(P) ((P)->ibuf)
#define BGP_INPUT_PNT(P) (STREAM_PNT(BGP_INPUT(P)))
/* Macro to check BGP information is alive or not. */
#define BGP_INFO_HOLDDOWN(BI) \
(! CHECK_FLAG ((BI)->flags, BGP_INFO_VALID) \
|| CHECK_FLAG ((BI)->flags, BGP_INFO_HISTORY) \
|| CHECK_FLAG ((BI)->flags, BGP_INFO_DAMPED))
/* Count prefix size from mask length */
#define PSIZE(a) (((a) + 7) / (8))
/* BGP error codes. */
#define BGP_SUCCESS 0
#define BGP_ERR_INVALID_VALUE -1
#define BGP_ERR_INVALID_FLAG -2
#define BGP_ERR_INVALID_AS -3
#define BGP_ERR_INVALID_BGP -4
#define BGP_ERR_PEER_GROUP_MEMBER -5
#define BGP_ERR_MULTIPLE_INSTANCE_USED -6
#define BGP_ERR_PEER_GROUP_MEMBER_EXISTS -7
#define BGP_ERR_PEER_BELONGS_TO_GROUP -8
#define BGP_ERR_PEER_GROUP_AF_UNCONFIGURED -9
#define BGP_ERR_PEER_GROUP_NO_REMOTE_AS -10
#define BGP_ERR_PEER_GROUP_CANT_CHANGE -11
#define BGP_ERR_PEER_GROUP_MISMATCH -12
#define BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT -13
#define BGP_ERR_MULTIPLE_INSTANCE_NOT_SET -14
#define BGP_ERR_AS_MISMATCH -15
#define BGP_ERR_PEER_INACTIVE -16
#define BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER -17
#define BGP_ERR_PEER_GROUP_HAS_THE_FLAG -18
#define BGP_ERR_PEER_FLAG_CONFLICT -19
#define BGP_ERR_PEER_GROUP_SHUTDOWN -20
#define BGP_ERR_PEER_FILTER_CONFLICT -21
#define BGP_ERR_NOT_INTERNAL_PEER -22
#define BGP_ERR_REMOVE_PRIVATE_AS -23
#define BGP_ERR_AF_UNCONFIGURED -24
#define BGP_ERR_SOFT_RECONFIG_UNCONFIGURED -25
#define BGP_ERR_INSTANCE_MISMATCH -26
#define BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP -27
#define BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS -28
#define BGP_ERR_MAX -29
extern struct bgp_master *bm;
extern struct thread_master *master;
/* Prototypes. */
void bgp_terminate (void);
void bgp_reset (void);
void bgp_zclient_reset ();
int bgp_nexthop_set (union sockunion *, union sockunion *,
struct bgp_nexthop *, struct peer *);
struct bgp *bgp_get_default ();
struct bgp *bgp_lookup (as_t, char *);
struct bgp *bgp_lookup_by_name (char *);
struct peer *peer_lookup (struct bgp *, union sockunion *);
struct peer_group *peer_group_lookup (struct bgp *, char *);
struct peer_group *peer_group_get (struct bgp *, char *);
struct peer *peer_lookup_with_open (union sockunion *, as_t, struct in_addr *,
int *);
int peer_sort (struct peer *peer);
int peer_active (struct peer *);
int peer_active_nego (struct peer *);
struct peer *peer_create_accept (struct bgp *);
char *peer_uptime (time_t, char *, size_t);
void bgp_config_write_family_header (struct vty *, afi_t, safi_t, int *);
void bgp_master_init ();
void bgp_init ();
int bgp_option_set (int);
int bgp_option_unset (int);
int bgp_option_check (int);
int bgp_get (struct bgp **, as_t *, char *);
int bgp_delete (struct bgp *);
int bgp_flag_set (struct bgp *, int);
int bgp_flag_unset (struct bgp *, int);
int bgp_flag_check (struct bgp *, int);
int bgp_router_id_set (struct bgp *, struct in_addr *);
int bgp_router_id_unset (struct bgp *);
int bgp_cluster_id_set (struct bgp *, struct in_addr *);
int bgp_cluster_id_unset (struct bgp *);
int bgp_confederation_id_set (struct bgp *, as_t);
int bgp_confederation_id_unset (struct bgp *);
int bgp_confederation_peers_check (struct bgp *, as_t);
int bgp_confederation_peers_add (struct bgp *, as_t);
int bgp_confederation_peers_remove (struct bgp *, as_t);
int bgp_timers_set (struct bgp *, u_int32_t, u_int32_t);
int bgp_timers_unset (struct bgp *);
int bgp_default_local_preference_set (struct bgp *, u_int32_t);
int bgp_default_local_preference_unset (struct bgp *);
int peer_remote_as (struct bgp *, union sockunion *, as_t *, afi_t, safi_t);
int peer_group_remote_as (struct bgp *, char *, as_t *);
int peer_delete (struct peer *peer);
int peer_group_delete (struct peer_group *);
int peer_group_remote_as_delete (struct peer_group *);
int peer_activate (struct peer *, afi_t, safi_t);
int peer_deactivate (struct peer *, afi_t, safi_t);
int peer_group_bind (struct bgp *, union sockunion *, struct peer_group *,
afi_t, safi_t, as_t *);
int peer_group_unbind (struct bgp *, struct peer *, struct peer_group *,
afi_t, safi_t);
int peer_flag_set (struct peer *, u_int32_t);
int peer_flag_unset (struct peer *, u_int32_t);
int peer_af_flag_set (struct peer *, afi_t, safi_t, u_int32_t);
int peer_af_flag_unset (struct peer *, afi_t, safi_t, u_int32_t);
int peer_af_flag_check (struct peer *, afi_t, safi_t, u_int32_t);
int peer_ebgp_multihop_set (struct peer *, int);
int peer_ebgp_multihop_unset (struct peer *);
int peer_description_set (struct peer *, char *);
int peer_description_unset (struct peer *);
int peer_update_source_if_set (struct peer *, char *);
int peer_update_source_addr_set (struct peer *, union sockunion *);
int peer_update_source_unset (struct peer *);
int peer_default_originate_set (struct peer *, afi_t, safi_t, char *);
int peer_default_originate_unset (struct peer *, afi_t, safi_t);
int peer_port_set (struct peer *, u_int16_t);
int peer_port_unset (struct peer *);
int peer_weight_set (struct peer *, u_int16_t);
int peer_weight_unset (struct peer *);
int peer_timers_set (struct peer *, u_int32_t, u_int32_t);
int peer_timers_unset (struct peer *);
int peer_timers_connect_set (struct peer *, u_int32_t);
int peer_timers_connect_unset (struct peer *);
int peer_advertise_interval_set (struct peer *, u_int32_t);
int peer_advertise_interval_unset (struct peer *);
int peer_version_set (struct peer *, int);
int peer_version_unset (struct peer *);
int peer_interface_set (struct peer *, char *);
int peer_interface_unset (struct peer *);
int peer_distribute_set (struct peer *, afi_t, safi_t, int, char *);
int peer_distribute_unset (struct peer *, afi_t, safi_t, int);
int peer_allowas_in_set (struct peer *, afi_t, safi_t, int);
int peer_allowas_in_unset (struct peer *, afi_t, safi_t);
int peer_local_as_set (struct peer *, as_t, int);
int peer_local_as_unset (struct peer *);
int peer_prefix_list_set (struct peer *, afi_t, safi_t, int, char *);
int peer_prefix_list_unset (struct peer *, afi_t, safi_t, int);
int peer_aslist_set (struct peer *, afi_t, safi_t, int, char *);
int peer_aslist_unset (struct peer *,afi_t, safi_t, int);
int peer_route_map_set (struct peer *, afi_t, safi_t, int, char *);
int peer_route_map_unset (struct peer *, afi_t, safi_t, int);
int peer_unsuppress_map_set (struct peer *, afi_t, safi_t, char *);
int peer_unsuppress_map_unset (struct peer *, afi_t, safi_t);
int peer_maximum_prefix_set (struct peer *, afi_t, safi_t, u_int32_t, int);
int peer_maximum_prefix_unset (struct peer *, afi_t, safi_t);
int peer_clear (struct peer *);
int peer_clear_soft (struct peer *, afi_t, safi_t, enum bgp_clear_type);

1321
config.guess vendored Executable file

File diff suppressed because it is too large Load Diff

367
config.h.in Normal file
View File

@ -0,0 +1,367 @@
/* 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
/* 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

1332
config.sub vendored Executable file

File diff suppressed because it is too large Load Diff

8114
configure vendored Executable file

File diff suppressed because it is too large Load Diff

873
configure.in Executable file
View File

@ -0,0 +1,873 @@
##
## 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(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
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(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")
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 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}
"

423
depcomp Executable file
View File

@ -0,0 +1,423 @@
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
# Copyright 1999, 2000 Free Software Foundation, Inc.
# 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, 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.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
echo "depcomp: Variables source, object and depmode must be set" 1>&2
exit 1
fi
# `libtool' can also be set to `yes' or `no'.
if test -z "$depfile"; then
base=`echo "$object" | sed -e 's,^.*/,,' -e 's,\.\([^.]*\)$,.P\1,'`
dir=`echo "$object" | sed 's,/.*$,/,'`
if test "$dir" = "$object"; then
dir=
fi
# FIXME: should be _deps on DOS.
depfile="$dir.deps/$base"
fi
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
rm -f "$tmpdepfile"
# Some modes work just like other modes, but use different flags. We
# parameterize here, but still list the modes in the big case below,
# to make depend.m4 easier to write. Note that we *cannot* use a case
# here, because this file can only contain one case statement.
if test "$depmode" = hp; then
# HP compiler uses -M and no extra arg.
gccflag=-M
depmode=gcc
fi
if test "$depmode" = dashXmstdout; then
# This is just like dashmstdout with a different argument.
dashmflag=-xM
depmode=dashmstdout
fi
case "$depmode" in
gcc3)
## gcc 3 implements dependency tracking that does exactly what
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
## it if -MD -MP comes after the -MF stuff. Hmm.
"$@" -MT "$object" -MD -MP -MF "$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
mv "$tmpdepfile" "$depfile"
;;
gcc)
## There are various ways to get dependency output from gcc. Here's
## why we pick this rather obscure method:
## - Don't want to use -MD because we'd like the dependencies to end
## up in a subdir. Having to rename by hand is ugly.
## (We might end up doing this anyway to support other compilers.)
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
## -MM, not -M (despite what the docs say).
## - Using -M directly means running the compiler twice (even worse
## than renaming).
if test -z "$gccflag"; then
gccflag=-MD,
fi
"$@" -Wp,"$gccflag$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
## The second -e expression handles DOS-style file names with drive letters.
sed -e 's/^[^:]*: / /' \
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
## This next piece of magic avoids the `deleted header file' problem.
## The problem is that when a header file which appears in a .P file
## is deleted, the dependency causes make to die (because there is
## typically no way to rebuild the header). We avoid this by adding
## dummy dependencies for each header file. Too bad gcc doesn't do
## this for us directly.
tr ' ' '
' < "$tmpdepfile" |
## Some versions of gcc put a space before the `:'. On the theory
## that the space means something, we add a space to the output as
## well.
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
sgi)
if test "$libtool" = yes; then
"$@" "-Wp,-MDupdate,$tmpdepfile"
else
"$@" -MDupdate "$tmpdepfile"
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
echo "$object : \\" > "$depfile"
# Clip off the initial element (the dependent). Don't try to be
# clever and replace this with sed code, as IRIX sed won't handle
# lines with more than a fixed number of characters (4096 in
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
# the IRIX cc adds comments like `#:fec' to the end of the
# dependency line.
tr ' ' '
' < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
tr '
' ' ' >> $depfile
echo >> $depfile
# The second pass generates a dummy entry for each header file.
tr ' ' '
' < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
>> $depfile
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
# "include basename.Plo" scheme.
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
aix)
# The C for AIX Compiler uses -M and outputs the dependencies
# in a .u file. This file always lives in the current directory.
# Also, the AIX compiler puts `$object:' at the start of each line;
# $object doesn't have directory information.
stripped=`echo "$object" | sed -e 's,^.*/,,' -e 's/\(.*\)\..*$/\1/'`
tmpdepfile="$stripped.u"
outname="$stripped.o"
if test "$libtool" = yes; then
"$@" -Wc,-M
else
"$@" -M
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
if test -f "$tmpdepfile"; then
# Each line is of the form `foo.o: dependent.h'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.
sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
# "include basename.Plo" scheme.
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
tru64)
# The Tru64 compiler uses -MD to generate dependencies as a side
# effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
# dependencies in `foo.d' instead, so we check for that too.
# Subdirectories are respected.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
test "x$dir" = "x$object" && dir=
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
if test "$libtool" = yes; then
tmpdepfile1="$dir.libs/$base.lo.d"
tmpdepfile2="$dir.libs/$base.d"
"$@" -Wc,-MD
else
tmpdepfile1="$dir$base.o.d"
tmpdepfile2="$dir$base.d"
"$@" -MD
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2"
exit $stat
fi
if test -f "$tmpdepfile1"; then
tmpdepfile="$tmpdepfile1"
else
tmpdepfile="$tmpdepfile2"
fi
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
# That's a space and a tab in the [].
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
else
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
#nosideeffect)
# This comment above is used by automake to tell side-effect
# dependency tracking mechanisms from slower ones.
dashmstdout)
# Important note: in order to support this mode, a compiler *must*
# always write the proprocessed file to stdout, regardless of -o.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test $1 != '--mode=compile'; do
shift
done
shift
fi
# Remove `-o $object'. We will use -o /dev/null later,
# however we can't do the remplacement now because
# `-o $object' might simply not be used
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
test -z "$dashmflag" && dashmflag=-M
"$@" -o /dev/null $dashmflag | sed 's:^[^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
tr ' ' '
' < "$tmpdepfile" | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
dashXmstdout)
# This case only exists to satisfy depend.m4. It is never actually
# run, as this mode is specially recognized in the preamble.
exit 1
;;
makedepend)
"$@" || exit $?
# X makedepend
shift
cleared=no
for arg in "$@"; do
case $cleared in
no)
set ""; shift
cleared=yes ;;
esac
case "$arg" in
-D*|-I*)
set fnord "$@" "$arg"; shift ;;
-*)
;;
*)
set fnord "$@" "$arg"; shift ;;
esac
done
obj_suffix="`echo $object | sed 's/^.*\././'`"
touch "$tmpdepfile"
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
sed '1,2d' "$tmpdepfile" | tr ' ' '
' | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile" "$tmpdepfile".bak
;;
cpp)
# Important note: in order to support this mode, a compiler *must*
# always write the proprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test $1 != '--mode=compile'; do
shift
done
shift
fi
# Remove `-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
"$@" -E |
sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
sed '$ s: \\$::' > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
cat < "$tmpdepfile" >> "$depfile"
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvisualcpp)
# Important note: in order to support this mode, a compiler *must*
# always write the proprocessed file to stdout, regardless of -o,
# because we must use -o when running libtool.
"$@" || exit $?
IFS=" "
for arg
do
case "$arg" in
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
set fnord "$@"
shift
shift
;;
*)
set fnord "$@" "$arg"
shift
shift
;;
esac
done
"$@" -E |
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
. "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
echo " " >> "$depfile"
. "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
rm -f "$tmpdepfile"
;;
none)
exec "$@"
;;
*)
echo "Unknown depmode $depmode" 1>&2
exit 1
;;
esac
exit 0

3
doc/.cvsignore Normal file
View File

@ -0,0 +1,3 @@
Makefile
draft-zebra-00.txt
zebra.info-*

24
doc/BGP-TypeCode Normal file
View File

@ -0,0 +1,24 @@
BGP-4[+] UPDATE Attribute TypeCode list
Value Attribute References
=========================================================================
1 ORIGIN [RFC 1771]
2 AS_PATH [RFC 1771]
3 NEXT_HOP [RFC 1771]
4 MULTI_EXIT_DISC [RFC 1771]
5 LOCAL_PREF [RFC 1771]
6 ATOMIC_AGGREGATE [RFC 1771]
7 AGGREGATOR [RFC 1771]
8 COMMUNITIES [RFC 1997]
9 ORIGINATOR_ID [RFC 1966]
10 CLUSTER_LIST [RFC 1966]
11 DPA [draft-ietf-idr-bgp-dpa-05.txt(expired)]
12 ADVERTISER [Changed from RFC 1863 bgp@ans.net ML?]
13 RCID_PATH [Changed from RFC 1863 bgp@ans.net ML?]
14 MP_REACH_NLRI [RFC 2283]
15 MP_UNREACH_NLRI [RFC 2283]
16 EXT_COMMUNITIES [draft-ramachandra-bgp-ext-communities-09.txt]
254 RCID_PATH [RFC 1863]
255 ADVERTISER [RFC 1863]
=========================================================================

90
doc/ChangeLog Normal file
View File

@ -0,0 +1,90 @@
2002-07-07 Kunihiro Ishiguro <kunihiro@ipinfusion.com>
* zebra-0.93 released.
2001-02-07 Pekka Savola <pekkas@netcore.fi>
* Correct bad English ;-).
2001-02-01 Kunihiro Ishiguro <kunihiro@zebra.org>
* zebra-0.91 released.
2001-01-09 Kunihiro Ishiguro <kunihiro@zebra.org>
* zebra-0.90 released.
2000-10-02 Kunihiro Ishiguro <kunihiro@zebra.org>
* zebra-0.89 released.
2000-10-02 Horms <horms@vergenet.net>
* Makefile.am: Fix texinfo file installation problem.
2000-08-17 Kunihiro Ishiguro <kunihiro@zebra.org>
* zebra-0.88 released.
* ospfd.texi (Redistribute routes to OSPF): distance <1-255>
@var{source} command is temporary disabled. So it is removed from
document.
2000-07-04 Kunihiro Ishiguro <kunihiro@zebra.org>
* vtysh.1: Add man entry for vtysh.
* bgpd.1: Change section to 8.
* ospfd.1: Likewise.
* ospf6d.1: Likewise.
* ripd.1: Likewise.
* ripngd.1: Likewise.
* zebra.1: Likewise.
1999-09-01 "A.Waddington" <waddington@usa.net>
* zebra.texi: Replace @command with @code until it gets ready.
Remove @macro.
1999-08-26 Andrew Waddington <waddington@usa.net>
* bgpd.1: Add man page.
ospf6d.1: Likewise.
ospfd.1: Likewise.
ripd.1: Likewise.
ripngd.1: Likewise.
zebra.1: Likewise.
1999-08-14 Andrew Waddington <waddington@usa.net>
* zebra.texi: Many typo is fixed. Some grammatical rectifications
is made.
1999-07-27 Gerhard Poul <gpoul@gnu.org>
* zebra.texi: Update zebra.texi.
1999-07-02 Gerhard Poul <gpoul@gnu.org>
* draft-zebra-00.ms: New file added. This is groff version of
draft-zebra-00.txt. This is a master file of draft-zebra-00.txt.
* draft-zebra-00.txt: Generated from draft-zebra-00.txt.
1999-05-07 Kunihiro Ishiguro <kunihiro@zebra.org>
* zebra.texi (Top): Add ospf6d chapter.
1999-03-31 Jeroen Ruigrok/Asmodai <asmodai@wxs.nl>
* zebra.texi: Improve some sections.
1999-03-04 Kunihiro Ishiguro <kunihiro@zebra.org>
* archfig.tex, zebra.sty, zebra.tex: Temporary removed due to the
description is out of date.
1999-02-24 Kunihiro Ishiguro <kunihiro@zebra.org>
* texinfo.tex: New file added. Automake complains the absence of
texinfo.tex.

14
doc/Makefile.am Normal file
View File

@ -0,0 +1,14 @@
## Process this file with automake to produce Makefile.in.
info_TEXINFOS = zebra.texi
zebra_TEXINFOS = appendix.texi basic.texi bgpd.texi filter.texi install.texi \
ipv6.texi kernel.texi main.texi ospf6d.texi ospfd.texi overview.texi \
protocol.texi ripd.texi ripngd.texi routemap.texi snmp.texi vtysh.texi
man_MANS = vtysh.1 bgpd.8 ospf6d.8 ospfd.8 ripd.8 ripngd.8 zebra.8
EXTRA_DIST = BGP-TypeCode draft-zebra-00.ms draft-zebra-00.txt $(man_MANS)
draft-zebra-00.txt:
groff -T ascii -ms draft-zebra-00.ms > draft-zebra-00.txt

482
doc/Makefile.in Normal file
View File

@ -0,0 +1,482 @@
# Makefile.in generated by automake 1.7 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@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
host_triplet = @host@
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BGPD = @BGPD@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CURSES = @CURSES@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
IF_METHOD = @IF_METHOD@
IF_PROC = @IF_PROC@
INCLUDES = @INCLUDES@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
IPFORWARD = @IPFORWARD@
KERNEL_METHOD = @KERNEL_METHOD@
LDFLAGS = @LDFLAGS@
LIBPAM = @LIBPAM@
LIBS = @LIBS@
LIB_IPV6 = @LIB_IPV6@
LIB_REGEX = @LIB_REGEX@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MULTIPATH_NUM = @MULTIPATH_NUM@
OBJEXT = @OBJEXT@
OSPF6D = @OSPF6D@
OSPFD = @OSPFD@
OTHER_METHOD = @OTHER_METHOD@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
RIPD = @RIPD@
RIPNGD = @RIPNGD@
RTREAD_METHOD = @RTREAD_METHOD@
RT_METHOD = @RT_METHOD@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
VTYSH = @VTYSH@
ZEBRA = @ZEBRA@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__include = @am__include@
am__quote = @am__quote@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localstatedir = @localstatedir@
mandir = @mandir@
oldincludedir = @oldincludedir@
prefix = @prefix@
program_transform_name = @program_transform_name@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
info_TEXINFOS = zebra.texi
zebra_TEXINFOS = appendix.texi basic.texi bgpd.texi filter.texi install.texi \
ipv6.texi kernel.texi main.texi ospf6d.texi ospfd.texi overview.texi \
protocol.texi ripd.texi ripngd.texi routemap.texi snmp.texi vtysh.texi
man_MANS = vtysh.1 bgpd.8 ospf6d.8 ospfd.8 ripd.8 ripngd.8 zebra.8
EXTRA_DIST = BGP-TypeCode draft-zebra-00.ms draft-zebra-00.txt $(man_MANS)
subdir = doc
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
DIST_SOURCES =
am__TEXINFO_TEX_DIR = $(srcdir)
INFO_DEPS = zebra.info
DVIS = zebra.dvi
PDFS = zebra.pdf
PSS = zebra.ps
TEXINFOS = zebra.texi
NROFF = nroff
MANS = $(man_MANS)
DIST_COMMON = $(zebra_TEXINFOS) ChangeLog Makefile.am Makefile.in \
texinfo.tex
all: all-am
.SUFFIXES:
.SUFFIXES: .dvi .info .pdf .ps .texi
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && \
$(AUTOMAKE) --foreign doc/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
.texi.info:
@rm -f $@ $@-[0-9] $@-[0-9][0-9]
$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \
`test -f '$<' || echo '$(srcdir)/'`$< -o $@
.texi.dvi:
TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \
$(TEXI2DVI) `test -f '$<' || echo '$(srcdir)/'`$<
.texi.pdf:
TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \
$(TEXI2PDF) `test -f '$<' || echo '$(srcdir)/'`$<
zebra.info: zebra.texi $(zebra_TEXINFOS)
zebra.dvi: zebra.texi $(zebra_TEXINFOS)
zebra.pdf: zebra.texi $(zebra_TEXINFOS)
TEXI2DVI = texi2dvi
TEXI2PDF = $(TEXI2DVI) --pdf --batch
DVIPS = dvips
.dvi.ps:
$(DVIPS) $< -o $@
uninstall-info-am:
$(PRE_UNINSTALL)
@if (install-info --version && \
install-info --version | grep -i -v debian) >/dev/null 2>&1; then \
list='$(INFO_DEPS)'; \
for file in $$list; do \
echo " install-info --info-dir=$(DESTDIR)$(infodir) --remove $(DESTDIR)$(infodir)/$$file"; \
install-info --info-dir=$(DESTDIR)$(infodir) --remove $(DESTDIR)$(infodir)/$$file; \
done; \
else :; fi
@$(NORMAL_UNINSTALL)
@list='$(INFO_DEPS)'; \
for file in $$list; do \
(if cd $(DESTDIR)$(infodir); then \
echo " rm -f $$file $$file-[0-9] $$file-[0-9][0-9])"; \
rm -f $$file $$file-[0-9] $$file-[0-9][0-9]; \
else :; fi); \
done
dist-info: $(INFO_DEPS)
list='$(INFO_DEPS)'; \
for base in $$list; do \
if test -f $$base; then d=.; else d=$(srcdir); fi; \
for file in $$d/$$base*; do \
relfile=`expr "$$file" : "$$d/\(.*\)"`; \
test -f $(distdir)/$$relfile || \
cp -p $$file $(distdir)/$$relfile; \
done; \
done
mostlyclean-aminfo:
-rm -f zebra.aux zebra.cp zebra.cps zebra.fn zebra.ky zebra.log zebra.op \
zebra.pg zebra.tmp zebra.toc zebra.tp zebra.vr zebra.dvi \
zebra.pdf zebra.ps
maintainer-clean-aminfo:
list='$(INFO_DEPS)'; for i in $$list; do \
rm -f $$i; \
if test "`echo $$i-[0-9]*`" != "$$i-[0-9]*"; then \
rm -f $$i-[0-9]*; \
fi; \
done
man1dir = $(mandir)/man1
install-man1: $(man1_MANS) $(man_MANS)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(man1dir)
@list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \
l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
for i in $$l2; do \
case "$$i" in \
*.1*) list="$$list $$i" ;; \
esac; \
done; \
for i in $$list; do \
if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
else file=$$i; fi; \
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
case "$$ext" in \
1*) ;; \
*) ext='1' ;; \
esac; \
inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
inst=`echo $$inst | sed -e 's/^.*\///'`; \
inst=`echo $$inst | sed '$(transform)'`.$$ext; \
echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst"; \
$(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst; \
done
uninstall-man1:
@$(NORMAL_UNINSTALL)
@list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \
l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
for i in $$l2; do \
case "$$i" in \
*.1*) list="$$list $$i" ;; \
esac; \
done; \
for i in $$list; do \
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
inst=`echo $$inst | sed -e 's/^.*\///'`; \
inst=`echo $$inst | sed '$(transform)'`.$$ext; \
echo " rm -f $(DESTDIR)$(man1dir)/$$inst"; \
rm -f $(DESTDIR)$(man1dir)/$$inst; \
done
man8dir = $(mandir)/man8
install-man8: $(man8_MANS) $(man_MANS)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(man8dir)
@list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \
l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
for i in $$l2; do \
case "$$i" in \
*.8*) list="$$list $$i" ;; \
esac; \
done; \
for i in $$list; do \
if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
else file=$$i; fi; \
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
case "$$ext" in \
8*) ;; \
*) ext='8' ;; \
esac; \
inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
inst=`echo $$inst | sed -e 's/^.*\///'`; \
inst=`echo $$inst | sed '$(transform)'`.$$ext; \
echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst"; \
$(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst; \
done
uninstall-man8:
@$(NORMAL_UNINSTALL)
@list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \
l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
for i in $$l2; do \
case "$$i" in \
*.8*) list="$$list $$i" ;; \
esac; \
done; \
for i in $$list; do \
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
inst=`echo $$inst | sed -e 's/^.*\///'`; \
inst=`echo $$inst | sed '$(transform)'`.$$ext; \
echo " rm -f $(DESTDIR)$(man8dir)/$$inst"; \
rm -f $(DESTDIR)$(man8dir)/$$inst; \
done
tags: TAGS
TAGS:
ctags: CTAGS
CTAGS:
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
top_distdir = ..
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
esac; \
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
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$(top_distdir)" distdir="$(distdir)" \
dist-info
check-am: all-am
check: check-am
all-am: Makefile $(INFO_DEPS) $(MANS)
installdirs:
$(mkinstalldirs) $(DESTDIR)$(infodir) $(DESTDIR)$(man1dir) $(DESTDIR)$(man8dir)
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 mostlyclean-am
distclean: distclean-am
distclean-am: clean-am distclean-generic
dvi: dvi-am
dvi-am: $(DVIS)
info: info-am
info-am: $(INFO_DEPS)
install-data-am: install-info-am install-man
install-exec-am:
install-info: install-info-am
install-info-am: $(INFO_DEPS)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(infodir)
@list='$(INFO_DEPS)'; \
for file in $$list; do \
if test -f $$file; then d=.; else d=$(srcdir); fi; \
for ifile in echo $$d/$$file $$d/$$file-[0-9] $$d/$$file-[0-9][0-9]; do \
if test -f $$ifile; then \
relfile=`expr "$$ifile" : "$$d/\(.*\)"`; \
echo " $(INSTALL_DATA) $$ifile $(DESTDIR)$(infodir)/$$relfile"; \
$(INSTALL_DATA) $$ifile $(DESTDIR)$(infodir)/$$relfile; \
else : ; fi; \
done; \
done
@$(POST_INSTALL)
@if (install-info --version && \
install-info --version | grep -i -v debian) >/dev/null 2>&1; then \
list='$(INFO_DEPS)'; \
for file in $$list; do \
echo " install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/$$file";\
install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/$$file || :;\
done; \
else : ; fi
install-man: install-man1 install-man8
installcheck-am:
maintainer-clean: maintainer-clean-am
maintainer-clean-am: distclean-am maintainer-clean-aminfo \
maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-aminfo mostlyclean-generic
pdf: pdf-am
pdf-am: $(PDFS)
ps: ps-am
ps-am: $(PSS)
uninstall-am: uninstall-info-am uninstall-man
uninstall-man: uninstall-man1 uninstall-man8
.PHONY: all all-am check check-am clean clean-generic dist-info \
distclean distclean-generic 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-man1 install-man8 install-strip installcheck \
installcheck-am installdirs maintainer-clean \
maintainer-clean-aminfo maintainer-clean-generic mostlyclean \
mostlyclean-aminfo mostlyclean-generic pdf pdf-am ps ps-am \
uninstall uninstall-am uninstall-info-am uninstall-man \
uninstall-man1 uninstall-man8
draft-zebra-00.txt:
groff -T ascii -ms draft-zebra-00.ms > draft-zebra-00.txt
# 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:

238
doc/appendix.texi Normal file
View File

@ -0,0 +1,238 @@
@node Packet Binary Dump Format, , Zebra Protocol, Top
@comment node-name, next, previous, up
@appendix Packet Binary Dump Format
Zebra can dump routing protocol packet into file with a binary format
(@pxref{Dump BGP packets and table}).
It seems to be better that we share the MRT's header format for
backward compatibility with MRT's dump logs. We should also define the
binary format excluding the header, because we must support both IP
v4 and v6 addresses as socket addresses and / or routing entries.
In the last meeting, we discussed to have a version field in the
header. But Masaki told us that we can define new `type' value rather
than having a `version' field, and it seems to be better because we
don't need to change header format.
Here is the common header format. This is same as that of MRT.
@example
@group
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Time |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Subtype |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@end group
@end example
If `type' is PROTOCOL_BGP4MP, `subtype' is BGP4MP_STATE_CHANGE, and
Address Family == IP (version 4)
@example
@group
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source AS number | Destination AS number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Interface Index | Address Family |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source IP address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Destination IP address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Old State | New State |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@end group
@end example
Where State is the value defined in RFC1771.
If `type' is PROTOCOL_BGP4MP, `subtype' is BGP4MP_STATE_CHANGE,
and Address Family == IP version 6
@example
@group
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source AS number | Destination AS number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Interface Index | Address Family |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source IP address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source IP address (Cont'd) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source IP address (Cont'd) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source IP address (Cont'd) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Destination IP address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Destination IP address (Cont'd) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Destination IP address (Cont'd) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Destination IP address (Cont'd) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Old State | New State |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@end group
@end example
If `type' is PROTOCOL_BGP4MP, `subtype' is BGP4MP_MESSAGE,
and Address Family == IP (version 4)
@example
@group
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source AS number | Destination AS number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Interface Index | Address Family |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source IP address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Destination IP address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| BGP Message Packet |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@end group
@end example
Where BGP Message Packet is the whole contents of the
BGP4 message including header portion.
If `type' is PROTOCOL_BGP4MP, `subtype' is BGP4MP_MESSAGE,
and Address Family == IP version 6
@example
@group
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source AS number | Destination AS number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Interface Index | Address Family |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source IP address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source IP address (Cont'd) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source IP address (Cont'd) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source IP address (Cont'd) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Destination IP address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Destination IP address (Cont'd) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Destination IP address (Cont'd) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Destination IP address (Cont'd) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| BGP Message Packet |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@end group
@end example
If `type' is PROTOCOL_BGP4MP, `subtype' is BGP4MP_ENTRY,
and Address Family == IP (version 4)
@example
@group
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| View # | Status |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Time Last Change |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Address Family | SAFI | Next-Hop-Len |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Next Hop Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Prefix Length | Address Prefix [variable] |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Attribute Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| BGP Attribute [variable length] |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@end group
@end example
If `type' is PROTOCOL_BGP4MP, `subtype' is BGP4MP_ENTRY,
and Address Family == IP version 6
@example
@group
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| View # | Status |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Time Last Change |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Address Family | SAFI | Next-Hop-Len |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Next Hop Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Next Hop Address (Cont'd) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Next Hop Address (Cont'd) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Next Hop Address (Cont'd) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Prefix Length | Address Prefix [variable] |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Address Prefix (cont'd) [variable] |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Attribute Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| BGP Attribute [variable length] |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@end group
@end example
BGP4 Attribute must not contain MP_UNREACH_NLRI.
If BGP Attribute has MP_REACH_NLRI field, it must has
zero length NLRI, e.g., MP_REACH_NLRI has only Address
Family, SAFI and next-hop values.
If `type' is PROTOCOL_BGP4MP and `subtype' is BGP4MP_SNAPSHOT,
@example
@group
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| View # | File Name [variable] |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@end group
@end example
The file specified in "File Name" contains all routing entries,
which are in the format of ``subtype == BGP4MP_ENTRY''.
@example
@group
Constants:
/* type value */
#define MSG_PROTOCOL_BGP4MP 16
/* subtype value */
#define BGP4MP_STATE_CHANGE 0
#define BGP4MP_MESSAGE 1
#define BGP4MP_ENTRY 2
#define BGP4MP_SNAPSHOT 3
@end group
@end example

510
doc/basic.texi Normal file
View File

@ -0,0 +1,510 @@
@node Basic commands
@comment node-name, next, previous, up
@chapter Basic commands
There are five routing daemons in use, and there is one manager daemon.
These daemons may be located on separate machines from the manager
daemon. Each of these daemons will listen on a particular port for
incoming VTY connections. The routing daemons are:
@itemize @bullet
@item @command{ripd}, @command{ripngd}, @command{ospfd}, @command{ospf6d}, @command{bgpd}
@item @command{zebra}
@end itemize
The following sections discuss commands common to all the routing
daemons.
@menu
* Config Commands:: Commands used in config files
* Common Invocation Options:: Starting the daemons
* Virtual Terminal Interfaces:: Interacting with the daemons
@end menu
@node Config Commands, Common Invocation Options, Basic commands, Basic commands
@comment node-name, next, previous, up
@section Config Commands
@cindex Configuration files for running the software
@c A -not configuration files for installing the software
@cindex Files for running configurations
@cindex Modifying the herd's behavior
@cindex Getting the herd running
@menu
* Basic Config Commands:: Some of the generic config commands
* Sample Config File:: An example config file
@end menu
In a config file, you can write the debugging options, a vty's password,
routing daemon configurations, a log file name, and so forth. This
information forms the initial command set for a routing beast as it is
starting.
Config files are generally found in:
@itemize @asis
@item @file{@value{INSTALL_PREFIX_ETC}/*.conf}
@end itemize
Each of the daemons has its own
config file. For example, zebra's default config file name is:
@itemize @asis
@item @file{@value{INSTALL_PREFIX_ETC}/zebra.conf}
@end itemize
The daemon name plus @file{.conf} is the default config file name. You
can specify a config file using the @kbd{-f} or @kbd{--config-file}
options when starting the daemon.
@node Basic Config Commands, Sample Config File, Config Commands, Config Commands
@comment node-name, next, previous, up
@subsection Basic Config Commands
@deffn Command {hostname @var{hostname}} {}
Set hostname of the router.
@end deffn
@deffn Command {password @var{password}} {}
Set password for vty interface. If there is no password, a vty won't
accept connections.
@end deffn
@deffn Command {enable password @var{password}} {}
Set enable password.
@end deffn
@deffn Command {log stdout} {}
@deffnx Command {no log stdout} {}
Set logging output to stdout.
@end deffn
@deffn Command {log file @var{filename}} {}
If you want to log into a file please specify @code{filename} as
follows.
@example
log file /usr/local/etc/bgpd.log
@end example
@end deffn
@deffn Command {log syslog} {}
@deffnx Command {no log syslog} {}
Set logging output to syslog.
@end deffn
@deffn Command {write terminal} {}
Displays the current configuration to the vty interface.
@end deffn
@deffn Command {write file} {}
Write current configuration to configuration file.
@end deffn
@deffn Command {configure terminal} {}
Change to configuration mode. This command is the first step to
configuration.
@end deffn
@deffn Command {terminal length @var{<0-512>}} {}
Set terminal display length to @var{<0-512>}. If length is 0, no
display control is performed.
@end deffn
@deffn Command {who} {}
@end deffn
@deffn Command {list} {}
List commands.
@end deffn
@deffn Command {service password-encryption} {}
Encrypt password.
@end deffn
@deffn Command {service advanced-vty} {}
Enable advanced mode VTY.
@end deffn
@deffn Command {service terminal-length @var{<0-512>}} {}
Set system wide line configuration. This configuration command applies
to all VTY interfaces.
@end deffn
@deffn Command {show version} {}
Show the current version of the Zebra and its build host information.
@end deffn
@deffn Command {line vty} {}
Enter vty configuration mode.
@end deffn
@deffn Command {banner motd default} {}
Set default motd string.
@end deffn
@deffn Command {no banner motd} {}
No motd banner string will be printed.
@end deffn
@deffn {Line Command} {exec-timeout @var{minute}} {}
@deffnx {Line Command} {exec-timeout @var{minute} @var{second}} {}
Set VTY connection timeout value. When only one argument is specified
it is used for timeout value in minutes. Optional second argument is
used for timeout value in seconds. Default timeout value is 10 minutes.
When timeout value is zero, it means no timeout.
@end deffn
@deffn {Line Command} {no exec-timeout} {}
Do not perform timeout at all. This command is as same as
@command{exec-timeout 0 0}.
@end deffn
@deffn {Line Command} {access-class @var{access-list}} {}
Restrict vty connections with an access list.
@end deffn
@node Sample Config File, , Basic Config Commands, Config Commands
@comment node-name, next, previous, up
@subsection Sample Config File
Below is a sample configuration file for the zebra daemon.
@example
@group
!
! Zebra configuration file
!
hostname Router
password zebra
enable password zebra
!
log stdout
!
!
@end group
@end example
'!' and '#' are comment characters. If the first character of the word
is one of the comment characters then from the rest of the line forward
will be ignored as a comment.
@example
password zebra!password
@end example
If a comment character is not the first character of the word, it's a
normal character. So in the above example '!' will not be regarded as a
comment and the password is set to 'zebra!password'.
@node Common Invocation Options, Virtual Terminal Interfaces, Config Commands, Basic commands
@comment node-name, next, previous, up
@section Common Invocation Options
@c COMMON_OPTIONS
@c OPTIONS section of the man page
These options apply to all Zebra daemons.
@table @samp
@item -d
@itemx --daemon
Runs in daemon mode.
@item -f @var{file}
@itemx --config_file=@var{file}
Set configuration file name.
@item -h
@itemx --help
Display this help and exit.
@item -i @var{file}
@itemx --pid_file=@var{file}
Upon startup the process identifier of the daemon is written to a file,
typically in @file{/var/run}. This file can be used by the init system
to implement commands such as @command{@dots{}/init.d/zebra status},
@command{@dots{}/init.d/zebra restart} or @command{@dots{}/init.d/zebra
stop}.
The file name is an run-time option rather than a configure-time option
so that multiple routing daemons can be run simultaneously. This is
useful when using Zebra to implement a routing looking glass. One
machine can be used to collect differing routing views from differing
points in the network.
@item -P @var{port}
@itemx --vty_port=@var{port}
Set the VTY port number.
@item -v
@itemx --version
Print program version.
@end table
@node Virtual Terminal Interfaces, , Common Invocation Options, Basic commands
@comment node-name, next, previous, up
@section Virtual Terminal Interfaces
VTY -- Virtual Terminal [aka TeletYpe] Interface is a command line
interface (CLI) for user interaction with the routing daemon.
@menu
* VTY Overview:: Basics about VTYs
* VTY Modes:: View, Enable, and Other VTY modes
* VTY CLI Commands:: Commands for movement, edition, and management
@end menu
@node VTY Overview, VTY Modes, Virtual Terminal Interfaces, Virtual Terminal Interfaces
@comment node-name, next, previous, up
@subsection VTY Overview
VTY stands for Virtual TeletYpe interface. It means you can connect to
the daemon via the telnet protocol.
To enable a VTY interface, you have to setup a VTY password. If there
is no VTY password, one cannot connect to the VTY interface at all.
@example
@group
% telnet localhost 2601
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Hello, this is zebra (version @value{VERSION})
Copyright 1997-2000 Kunihiro Ishiguro
User Access Verification
Password: XXXXX
Router> ?
enable Turn on privileged commands
exit Exit current mode and down to previous mode
help Description of the interactive help system
list Print command list
show Show running system information
who Display who is on a vty
Router> enable
Password: XXXXX
Router# configure terminal
Router(config)# interface eth0
Router(config-if)# ip address 10.0.0.1/8
Router(config-if)# ^Z
Router#
@end group
@end example
'?' is very useful for looking up commands.
@node VTY Modes, VTY CLI Commands, VTY Overview, Virtual Terminal Interfaces
@comment node-name, next, previous, up
@subsection VTY Modes
There are three basic VTY modes:
@menu
* VTY View Mode:: Mode for read-only interaction
* VTY Enable Mode:: Mode for read-write interaction
* VTY Other Modes:: Special modes (tftp, etc)
@end menu
There are commands that may be restricted to specific VTY modes.
@node VTY View Mode, VTY Enable Mode, VTY Modes, VTY Modes
@comment node-name, next, previous, up
@subsubsection VTY View Mode
@c to be written (gpoul)
This mode is for read-only access to the CLI. One may exit the mode by
leaving the system, or by entering @code{enable} mode.
@node VTY Enable Mode, VTY Other Modes, VTY View Mode, VTY Modes
@comment node-name, next, previous, up
@subsubsection VTY Enable Mode
@c to be written (gpoul)
This mode is for read-write access to the CLI. One may exit the mode by
leaving the system, or by escaping to view mode.
@node VTY Other Modes, , VTY Enable Mode, VTY Modes
@comment node-name, next, previous, up
@subsubsection VTY Other Modes
@c to be written (gpoul)
This page is for describing other modes.
@node VTY CLI Commands, , VTY Modes, Virtual Terminal Interfaces
@comment node-name, next, previous, up
@subsection VTY CLI Commands
Commands that you may use at the command-line are described in the following three subsubsections.
@menu
* CLI Movement Commands:: Commands for moving the cursor about
* CLI Editing Commands:: Commands for changing text
* CLI Advanced Commands:: Other commands, session management and so on
@end menu
@node CLI Movement Commands, CLI Editing Commands, VTY CLI Commands, VTY CLI Commands
@comment node-name, next, previous, up
@subsubsection CLI Movement Commands
These commands are used for moving the CLI cursor. The @key{C} character
means press the Control Key.
@table @kbd
@item C-f
@itemx @key{RIGHT}
@kindex C-f
@kindex @key{RIGHT}
Move forward one character.
@item C-b
@itemx @key{LEFT}
@kindex C-b
@kindex @key{LEFT}
Move backward one character.
@item M-f
@kindex M-f
Move forward one word.
@item M-b
@kindex M-b
Move backward one word.
@item C-a
@kindex C-a
Move to the beginning of the line.
@item C-e
@kindex C-e
Move to the end of the line.
@end table
@node CLI Editing Commands, CLI Advanced Commands, CLI Movement Commands, VTY CLI Commands
@comment node-name, next, previous, up
@subsubsection CLI Editing Commands
These commands are used for editing text on a line. The @key{C}
character means press the Control Key.
@table @kbd
@item C-h
@itemx @key{DEL}
@kindex C-h
@kindex @key{DEL}
Delete the character before point.
@item C-d
@kindex C-d
Delete the character after point.
@item M-d
@kindex M-d
Forward kill word.
@item C-w
@kindex C-w
Backward kill word.
@item C-k
@kindex C-k
Kill to the end of the line.
@item C-u
@kindex C-u
Kill line from the beginning, erasing input.
@item C-t
@kindex C-t
Transpose character.
@end table
@node CLI Advanced Commands, , CLI Editing Commands, VTY CLI Commands
@comment node-name, next, previous, up
@subsubsection CLI Advanced Commands
There are several additional CLI commands for command line completions,
insta-help, and VTY session management.
@table @kbd
@item C-c
@kindex C-c
Interrupt current input and moves to the next line.
@item C-z
@kindex C-z
End current configuration session and move to top node.
@item C-n
@itemx @key{DOWN}
@kindex C-n
@kindex @key{DOWN}
Move down to next line in the history buffer.
@item C-p
@itemx @key{UP}
@kindex C-p
@kindex @key{UP}
Move up to previous line in the history buffer.
@item TAB
@kindex @key{TAB}
Use command line completion by typing @key{TAB}.
@item
@kindex ?
You can use command line help by typing @code{help} at the beginning of
the line. Typing @kbd{?} at any point in the line will show possible
completions.
@end table

169
doc/bgpd.8 Normal file
View File

@ -0,0 +1,169 @@
.TH BGPD 8 "July 2000" "Zebra Beast - BGPD" "Version 0.88"
.SH NAME
bgpd \- a BGPv4, BGPv4+, BGPv4- routing engine for use with Zebra
.SH SYNOPSIS
.B bgpd
[
.B \-dhpPv
]
[
.B \-f config-file
]
[
.B \-i pid-file
]
[
.B \-p bgp-port-number
]
[
.B \--bgp_port=port-number
]
[
.B \-P vty-port-number
]
.SH DESCRIPTION
.B bgpd
is a routing component that works with the
.B zebra
routing engine.
.SH OPTIONS
.TP
\fB\-d\fR, \fB\-\-daemon\fR
Runs in daemon mode, forking and exiting from tty.
.TP
\fB\-f\fR, \fB\-\-config-file \fR\fIconfig-file\fR
Specifies the config file to use for startup. If not specified this
option will likely default to \fB\fI/usr/local/etc/bgpd.conf\fR.
.TP
\fB\-h\fR, \fB\-\-help\fR
A brief message.
.TP
\fB\-i\fR, \fB\-\-pid_file \fR\fIpid-file\fR
When bgpd starts its process idenifier is written to
\fB\fIpid-file\fR. The init system uses the recorded PID to stop or
restart bgpd. The likely default is \fB\fI/var/run/bgpd.pid\fR.
.TP
\fB\-p\fR, \fB\-\-bgp_port=\fR\fIport\fR
Set the port that bgpd will listen to for bgp data.
.TP
\fB\-P\fR, \fB\-\-vty_port \fR\fIport-number\fR
Specify the port that the bgpd VTY will listen on. This defaults to
2605, as specified in \fI/etc/services\fR.
.TP
\fB\-r\fR, \fB\-\-retain\fR
When the program terminates, retain routes added by \fBbgpd\fR.
.TP
\fB\-v\fR, \fB\-\-version\fR
Print the version and exit.
.SH COMMANDS
\fB router zebra \fR -- (Move routes into kernel table)
\fB router bgp [AS-NUMBER] \fR
\fB bgp router-id [BGP-ROUTER-ID] \fR
\fB network [NETWORK] area [BGP-AREA-ID] \fR
\fB no network [NETWORK] \fR
\fB aggregate-address [NETWORK] \fR
\fB neighbor [PEER-IP-ADDRESS] remote-as [REMOTE-AS] \fR
\fB neighbor [PEER-IP-ADDRESS] version [ 4 | 4+ | 4- ] \fR
\fB neighbor [PEER-IP-ADDRESS] description \fR
\fB no neighbor [PEER-IP-ADDRESS] description \fR
\fB neighbor [PEER-IP-ADDRESS] route-map [in | out] \fR
\fB neighbor [PEER-IP-ADDRESS] distribute-list [in | out] \fR
\fB neighbor [PEER-IP-ADDRESS] next-hop-self \fR
\fB neighbor [PEER-IP-ADDRESS] weight [WEIGHT] \fR
\fB neighbor [PEER-IP-ADDRESS] default-originate \fR
\fB neighbor [PEER-IP-ADDRESS] ebgp-multihop \fR
\fB neighbor [PEER-IP-ADDRESS] shutdown \fR
\fB no neighbor [PEER-IP-ADDRESS] shutdown \fR
\fB clear ip bgp [PEER-IP-ADDRESS] \fR
\fB show ip bgp [NETWORK] \fR
\fB show ip bgp reg-exp [AS-REGEXP] \fR
\fB show ip bgp summary \fR
\fB show ip bgp neighbor [PEER-IP-ADDRESS] \fR
\fB show ip bgp route \fR
\fB show debug \fR
\fB debug bgp \fR
\fB debug event \fR
\fB debug update \fR
\fB debug keepalive \fR
\fB no debug event \fR
\fB no debug update \fR
\fB no debug keepalive \fR
.SH FILES
.TP
.BI /usr/local/sbin/bgpd
The default location of the
.B bgpd
binary.
.TP
.BI /usr/local/etc/bgpd.conf
The default location of the
.B bgpd
config file.
.TP
.BI $(PWD)/bgpd.log
If the
.B bgpd
process is config'd to output logs to a file, then you will find this
file in the directory where you started \fBbgpd\fR.
.SH WARNING
This man page is intended as a quick reference for command line
options, and for config file commands. The definitive document is the
Info file \fBzebra\fR.
.SH DIAGNOSTICS
The bgpd process may log to standard output, to a VTY, to a log
file, or through syslog to the system logs. \fBbgpd\fR supports many
debugging options, see the Info file, or the source for details.
.SH "SEE ALSO"
References to other related man pages:
ripd(8), ripngd(8), ospfd(8), ospf6d(8), zebra(8), vtysh(1)
.SH BUGS
.B bgpd
eats bugs for breakfast. If you have food for the maintainers try
.BI <bug-zebra@gnu.org>
.SH AUTHOR[S]
See <\fBwww.zebra.org\fR>, or the Info file for an accurate list of authors.

1288
doc/bgpd.texi Normal file

File diff suppressed because it is too large Load Diff

209
doc/draft-zebra-00.ms Normal file
View File

@ -0,0 +1,209 @@
.pl 10.0i
.po 0
.ll 7.2i
.lt 7.2i
.nr LL 7.2i
.nr LT 7.2i
.ds LF Ishiguro
.ds RF FORMFEED[Page %]
.ds CF
.ds LH RFC DRAFT
.ds RH March 1998
.ds CH
.hy 0
.ad l
Network Working Group K. Ishiguro
Request for Comments: DRAFT Digital Magic Labs, Inc.
March 1998
.sp 2
.ce
Zebra Protocol Draft
.sp 2
.fi
.ne 4
Status of this Memo
.sp
.in 3
This draft is very eary beta version.
.sp
.in 0
.ne 4
Introduction
.sp
.in 3
The zebra protocol is a communication protocol between kernel
routing table manager and routing protocol daemon. It is built over
TCP/IP protocol suite.
.sp
.in 0
.ne 4
Request message formats
.sp
.in 3
zebra is TCP-based protocol.
.sp
Below is request packet format.
.sp
.in 0
.DS
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Length (2) | Command (1) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
.DE
.sp
.in 3
Length is total packet length.
.sp
Here is summary of command list.
.sp
.in 0
.DS
1 - ZEBRA_IPV4_ROUTE_ADD
2 - ZEBRA_IPV4_ROUTE_DELETE
3 - ZEBRA_IPV6_ROUTE_ADD
4 - ZEBRA_IPV6_ROUTE_DELETE
5 - ZEBRA_GET_ONE_INTERFACE
6 - ZEBRA_GET_ALL_INTERFACE
7 - ZEBRA_GET_HOSTINFO
.DE
.sp
.in 0
.ne 4
IPv4 reply message formats
.sp
.in 0
.DS
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+
| Type (1) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Gateway (4) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
.DE
.sp
.in 3
Type field specify route's origin type.
.sp
.in 0
.DS
1 - ZEBRA_ROUTE_RESERVE
2 - ZEBRA_ROUTE_CONNECT
3 - ZEBRA_ROUTE_STATIC
4 - ZEBRA_ROUTE_RIP
5 - ZEBRA_ROUTE_RIPNG
6 - ZEBRA_ROUTE_BGP
7 - ZEBRA_ROUTE_RADIX
.DE
.sp
.in 3
After above message there can be variale length IPv4 prefix data.
Each IPv4 prefix is encoded as a two tuple of the form <masklength,
prefix>
.sp
.in 0
.DS
+----------------------+
|Subnet mask (1 octet) |
+----------------------+
|IPv4 prefix (variable)|
+----------------------+
.DE
.sp
.in 0
.ne 4
IPv6 reply message formats
.sp
.in 0
.DS
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+
| Type (1) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Gateway (16) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
.DE
.sp
.in 3
Type field specify route's origin type.
.sp
.in 0
.DS
1 - ZEBRA_ROUTE_RESERVE
2 - ZEBRA_ROUTE_CONNECT
3 - ZEBRA_ROUTE_STATIC
4 - ZEBRA_ROUTE_RIP
5 - ZEBRA_ROUTE_RIPNG
6 - ZEBRA_ROUTE_BGP
7 - ZEBRA_ROUTE_RADIX
.DE
.sp
.in 0
.DS
+----------------------+
| ifindex (4 octet) |
+----------------------+
| prefixlen (1 octet)|
+----------------------+
|IPv6 prefix (variable)|
+----------------------+
.DE
.sp
.in 3
I am not sure but it seems some operation systems IPv6
implementation may need interface index when add and delete
linklocal routes.
.sp
I have added ifindex field to specify IPv6 routes interface
index. If this index is value zero, it will ignored.
.sp
.in 0
.ne 4
Interface information message format.
.sp
.in 0
.DS
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Interface name (20) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Index (1) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Inteface flag (4) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Inteface metric (4) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Inteface MTU (4) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Inteface Address count (4) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
.DE
.sp
.in 3
Address message format.
.sp
.in 0
.ne 4
Host inforamtion message format.
.sp
.in 0
.DS
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|IPv4 forwarding|IPv6 forwarding|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
.DE
.sp
.in 3
Host information contain IPv4/IPv6 forwarding information.

192
doc/filter.texi Normal file
View File

@ -0,0 +1,192 @@
@node Filtering
@comment node-name, next, previous, up
@chapter Filtering
Zebra provides many very flexible filtering features. Filtering is used
for both input and output of the routing information. Once filtering is
defined, it can be applied in any direction.
@menu
* IP Access List::
* IP Prefix List::
@end menu
@node IP Access List, IP Prefix List, Filtering, Filtering
@comment node-name, next, previous, up
@subsection IP Access List
@deffn {Command} {access-list @var{name} permit @var{ipv4-network}} {}
@deffnx {Command} {access-list @var{name} deny @var{ipv4-network}} {}
@end deffn
Basic filtering is done by @code{access-list} as shown in the
following example.
@example
access-list filter deny 10.0.0.0/9
access-list filter permit 10.0.0.0/8
@end example
@node IP Prefix List, , IP Access List, Filtering
@comment node-name, next, previous, up
@subsection IP Prefix List
@command{ip prefix-list} provides the most powerful prefix based
filtering mechanism. In addition to @command{access-list} functionality,
@command{ip prefix-list} has prefix length range specification and
sequential number specification. You can add or delete prefix based
filters to arbitrary points of prefix-list using sequential number specification.
If no ip prefix-list is specified, it acts as permit. If @command{ip prefix-list}
is defined, and no match is found, default deny is applied.
@c @deffn {Command} {ip prefix-list @var{name} [seq @var{number}] permit|deny [le @var{prefixlen}] [ge @var{prefixlen}]} {}
@deffn {Command} {ip prefix-list @var{name} (permit|deny) @var{prefix} [le @var{len}] [ge @var{len}]} {}
@deffnx {Command} {ip prefix-list @var{name} seq @var{number} (permit|deny) @var{prefix} [le @var{len}] [ge @var{len}]} {}
You can create @command{ip prefix-list} using above commands.
@table @asis
@item @asis{seq}
seq @var{number} can be set either automatically or manually. In the
case that sequential numbers are set manually, the user may pick any
number less than 4294967295. In the case that sequential number are set
automatically, the sequential number will increase by a unit of five (5)
per list. If a list with no specified sequential number is created
after a list with a specified sequential number, the list will
automatically pick the next multiple of five (5) as the list number.
For example, if a list with number 2 already exists and a new list with
no specified number is created, the next list will be numbered 5. If
lists 2 and 7 already exist and a new list with no specified number is
created, the new list will be numbered 10.
@item @asis{le}
@command{le} command specifies prefix length. The prefix list will be
applied if the prefix length is less than or equal to the le prefix length.
@item @asis{ge}
@command{ge} command specifies prefix length. The prefix list will be
applied if the prefix length is greater than or equal to the ge prefix length.
@end table
@end deffn
Less than or equal to prefix numbers and greater than or equal to
prefix numbers can be used together. The order of the le and ge
commands does not matter.
If a prefix list with a different sequential number but with the exact
same rules as a previous list is created, an error will result.
However, in the case that the sequential number and the rules are
exactly similar, no error will result.
If a list with the same sequential number as a previous list is created,
the new list will overwrite the old list.
Matching of IP Prefix is performed from the smaller sequential number to the
larger. The matching will stop once any rule has been applied.
In the case of no le or ge command,
Version 0.85: the matching rule will apply to all prefix lengths that
matched the prefix list.
Version 0.86 or later: In the case of no le or ge command, the prefix
length must match exactly the length specified in the prefix list.
@deffn {Command} {no ip prefix-list @var{name}} {}
@end deffn
@menu
* ip prefix-list description::
* ip prefix-list sequential number control::
* Showing ip prefix-list::
* Clear counter of ip prefix-list::
@end menu
@node ip prefix-list description, ip prefix-list sequential number control, IP Prefix List, IP Prefix List
@comment node-name, next, previous, up
@subsubsection ip prefix-list description
@deffn {Command} {ip prefix-list @var{name} description @var{desc}} {}
Descriptions may be added to prefix lists. This command adds a
description to the prefix list.
@end deffn
@deffn {Command} {no ip prefix-list @var{name} description [@var{desc}]} {}
Deletes the description from a prefix list. It is possible to use the
command without the full description.
@end deffn
@node ip prefix-list sequential number control, Showing ip prefix-list, ip prefix-list description, IP Prefix List
@comment node-name, next, previous, up
@subsubsection ip prefix-list sequential number control
@deffn {Command} {ip prefix-list sequence-number} {}
With this command, the IP prefix list sequential number is displayed.
This is the default behavior.
@end deffn
@deffn {Command} {no ip prefix-list sequence-number} {}
With this command, the IP prefix list sequential number is not
displayed.
@end deffn
@node Showing ip prefix-list, Clear counter of ip prefix-list, ip prefix-list sequential number control, IP Prefix List
@comment node-name, next, previous, up
@subsubsection Showing ip prefix-list
@deffn {Command} {show ip prefix-list} {}
Display all IP prefix lists.
@end deffn
@deffn {Command} {show ip prefix-list @var{name}} {}
Show IP prefix list can be used with a prefix list name.
@end deffn
@deffn {Command} {show ip prefix-list @var{name} seq @var{num}} {}
Show IP prefix list can be used with a prefix list name and sequential
number.
@end deffn
@deffn {Command} {show ip prefix-list @var{name} @var{a.b.c.d/m}} {}
If the command longer is used, all prefix lists with prefix lengths equal to
or longer than the specified length will be displayed.
If the command first match is used, the first prefix length match will be
displayed.
@end deffn
@deffn {Command} {show ip prefix-list @var{name} @var{a.b.c.d/m} longer} {}
@end deffn
@deffn {Command} {show ip prefix-list @var{name} @var{a.b.c.d/m} first-match} {}
@end deffn
@deffn {Command} {show ip prefix-list summary} {}
@end deffn
@deffn {Command} {show ip prefix-list summary @var{name}} {}
@end deffn
@deffn {Command} {show ip prefix-list detail} {}
@end deffn
@deffn {Command} {show ip prefix-list detail @var{name}} {}
@end deffn
@node Clear counter of ip prefix-list, , Showing ip prefix-list, IP Prefix List
@comment node-name, next, previous, up
@subsubsection Clear counter of ip prefix-list
@deffn {Command} {clear ip prefix-list} {}
Clears the counters of all IP prefix lists. Clear IP Prefix List can be
used with a specified name and prefix.
@end deffn
@deffn {Command} {clear ip prefix-list @var{name}} {}
@end deffn
@deffn {Command} {clear ip prefix-list @var{name} @var{a.b.c.d/m}} {}
@end deffn

218
doc/install.texi Normal file
View File

@ -0,0 +1,218 @@
@node Installation, Basic commands, Overview, Top
@comment node-name, next, previous, up
@chapter Installation
@cindex How to install Zebra
@cindex Installation
@cindex Installing Zebra
@cindex Building the system
@cindex Making Zebra
There are three steps for installing the software: configuration,
compilation, and installation.
@menu
* Configure the Software::
* Build the Software::
* Install the Software::
@end menu
The easiest way to get Zebra running is to issue the following
commands:
@example
% configure
% make
% make install
@end example
@node Configure the Software, Build the Software, Installation, Installation
@comment node-name, next, previous, up
@section Configure the Software
@cindex Configuration options
@cindex Options for configuring
@cindex Build options
@cindex Distribution configuration
@cindex Options to @code{./configure}
Zebra has an excellent configure script which
automatically detects most host configurations. There are several
additional configure options you can use to turn off IPv6 support, to
disable the compilation of specific daemons, and to enable SNMP support.
@table @option
@item --enable-guile
Turn on compilation of the zebra-guile interpreter. You will need the
guile library to make this. zebra-guile implementation is not yet
finished. So this option is only useful for zebra-guile developers.
@item --disable-ipv6
Turn off IPv6 related features and daemons. Zebra configure script
automatically detects IPv6 stack. But sometimes you might want to
disable IPv6 support of Zebra.
@item --disable-zebra
Do not build zebra daemon.
@item --disable-ripd
Do not build ripd.
@item --disable-ripngd
Do not build ripngd.
@item --disable-ospfd
Do not build ospfd.
@item --disable-ospf6d
Do not build ospf6d.
@item --disable-bgpd
Do not build bgpd.
@item --disable-bgp-announce
Make @command{bgpd} which does not make bgp announcements at all. This
feature is good for using @command{bgpd} as a BGP announcement listener.
@item --enable-netlink
Force to enable @sc{gnu}/Linux netlink interface. Zebra configure
script detects netlink interface by checking a header file. When the header
file does not match to the current running kernel, configure script will
not turn on netlink support.
@item --enable-snmp
Enable SNMP support. By default, SNMP support is disabled.
@end table
You may specify any combination of the above options to the configure
script. By default, the executables are placed in @file{/usr/local/sbin}
and the configuration files in @file{/usr/local/etc}. The @file{/usr/local/}
installation prefix and other directories may be changed using the following
options to the configuration script.
@table @option
@item --prefix=@var{prefix}
Install architecture-independent files in @var{prefix} [/usr/local].
@item --sysconfdir=@var{dir}
Read-only sample configuration file in @var{dir} [@var{prefix}/etc].
@end table
@example
% ./configure --disable-ipv6
@end example
This command will configure zebra and the routing daemons.
@cindex Configuring Zebra
@cindex Configuration the software build
@cindex Building on Linux boxes
@cindex Linux configurations
There are several options available only to @sc{gnu}/Linux systems:
@footnote{GNU/Linux has very flexible kernel configuration features. If
you use GNU/Linux, make sure that the current kernel configuration is
what you want. Zebra will run with any kernel configuration but some
recommendations do exist.
@table @var
@item CONFIG_NETLINK
Kernel/User netlink socket.
This is a brand new feature which enables
an advanced interface between the Linux kernel and Zebra (@pxref{Kernel Interface}).
@item CONFIG_RTNETLINK
Routing messages.
This makes it possible to receive netlink routing messages. If you
specify this option, @command{zebra} can detect routing information
updates directly from the kernel (@pxref{Kernel Interface}).
@item CONFIG_IP_MULTICAST
IP: multicasting.
This option should be specified when you use @command{ripd} or
@command{ospfd} because these protocols use multicast.
@end table
IPv6 support has been added in @sc{gnu}/Linux kernel version 2.2. If you
try to use the Zebra IPv6 feature on a @sc{gnu}/Linux kernel, please
make sure the following libraries have been installed. Please note that
these libraries will not be needed when you uses @sc{gnu} C library 2.1
or upper.
@table @code
@item inet6-apps
The @code{inet6-apps} package includes basic IPv6 related libraries such
as @code{inet_ntop} and @code{inet_pton}. Some basic IPv6 programs such
as @command{ping}, @command{ftp}, and @command{inetd} are also
included. The @code{inet-apps} can be found at
@url{ftp://ftp.inner.net/pub/ipv6/}.
@item net-tools
The @code{net-tools} package provides an IPv6 enabled interface and
routing utility. It contains @command{ifconfig}, @command{route},
@command{netstat}, and other tools. @code{net-tools} may be found at
@url{http://www.tazenda.demon.co.uk/phil/net-tools/}.
@end table
@c A - end of footnote
}.
@node Build the Software, Install the Software, Configure the Software, Installation
@comment node-name, next, previous, up
@section Build the Software
After configuring the software, you will need to compile it for your
system. Simply issue the command @command{make} in the root of the source
directory and the software will be compiled. If you have *any* problems
at this stage, be certain to send a bug report @xref{Bug Reports}.
@example
% ./configure
.
.
.
./configure output
.
.
.
% make
@end example
@c A - End of node, Building the Software
@node Install the Software, , Build the Software, Installation
@comment node-name, next, previous, up
@section Install the Software
Installing the software to your system consists of copying the compiled
programs and supporting files to a standard location. After the
installation process has completed, these files have been copied
from your work directory to @file{/usr/local/bin}, and @file{/usr/local/etc}.
To install the Zebra suite, issue the following command at your shell
prompt: @command{make install}.
@example
%
% make install
%
@end example
@c A - removed this section and placed it with Install the Software
@c @node Additional Notes, , Install the Software, Installation
@comment node-name, next, previous, up
@c @section Additional Notes
Zebra daemons have their own terminal interface or VTY. After
installation, you have to setup each beast's port number to connect to
them. Please add the following entries to @file{/etc/services}.
@example
zebrasrv 2600/tcp # zebra service
zebra 2601/tcp # zebra vty
ripd 2602/tcp # RIPd vty
ripngd 2603/tcp # RIPngd vty
ospfd 2604/tcp # OSPFd vty
bgpd 2605/tcp # BGPd vty
ospf6d 2606/tcp # OSPF6d vty
@end example
If you use a FreeBSD newer than 2.2.8, the above entries are already
added to @file{/etc/services} so there is no need to add it. If you
specify a port number when starting the daemon, these entries may not be
needed.
You may need to make changes to the config files in
@file{@value{INSTALL_PREFIX_ETC}/*.conf}. @xref{Config Commands}.

32
doc/ipv6.texi Normal file
View File

@ -0,0 +1,32 @@
@node IPv6 Support, Kernel Interface, Route Map, Top
@comment node-name, next, previous, up
@chapter IPv6 Support
Zebra fully supports IPv6 routing. As described so far, Zebra supports
RIPng, OSPFv3 and BGP-4+. You can give IPv6 addresses to an interface
and configure static IPv6 routing information. Zebra-IPv6 also provides
automatic address configuration via a feature called @code{address
auto configuration}. To do it, the router must send router advertisement
messages to the all nodes that exist on the network.
@menu
* Router Advertisement::
@end menu
@node Router Advertisement, , IPv6 Support, IPv6 Support
@comment node-name, next, previous, up
@section Router Advertisement
@deffn {Interface Command} {ipv6 nd send-ra} {}
@end deffn
@deffn {Interface Command} {ipv6 nd prefix-advertisement @var{ipv6prefix}} {}
@end deffn
@example
@group
interface eth0
ipv6 nd send-ra
ipv6 nd prefix-advertisement 3ffe:506:5009::/64
@end group
@end example

48
doc/kernel.texi Normal file
View File

@ -0,0 +1,48 @@
@node Kernel Interface, SNMP Support, IPv6 Support, Top
@comment node-name, next, previous, up
@chapter Kernel Interface
There are several different methods for reading kernel routing table
information, updating kernel routing tables, and for looking up
interfaces.
@table @samp
@item ioctl
The @samp{ioctl} method is a very traditional way for reading or writing
kernel information. @samp{ioctl} can be used for looking up interfaces
and for modifying interface addresses, flags, mtu settings and other
types of information. Also, @samp{ioctl} can insert and delete kernel
routing table entries. It will soon be available on almost any platform
which zebra supports, but it is a little bit ugly thus far, so if a
better method is supported by the kernel, zebra will use that.
@item sysctl
@samp{sysctl} can lookup kernel information using MIB (Management
Information Base) syntax. Normally, it only provides a way of getting
information from the kernel. So one would usually want to change kernel
information using another method such as @samp{ioctl}.
@item proc filesystem
@samp{proc filesystem} provides an easy way of getting kernel
information.
@item routing socket
@item netlink
On recent Linux kernels (2.0.x and 2.2.x), there is a kernel/user
communication support called @code{netlink}. It makes asynchronous
communication between kernel and Zebra possible, similar to a routing
socket on BSD systems.
Before you use this feature, be sure to select (in kernel configuration)
the kernel/netlink support option 'Kernel/User network link driver' and
'Routing messages'.
Today, the /dev/route special device file is obsolete. Netlink
communication is done by reading/writing over netlink socket.
After the kernel configuration, please reconfigure and rebuild Zebra.
You can use netlink as a dynamic routing update channel between Zebra
and the kernel.
@end table

186
doc/main.texi Normal file
View File

@ -0,0 +1,186 @@
@node Zebra
@comment node-name, next, previous, up
@chapter Zebra
@c SYNOPSIS
@command{zebra} is an IP routing manager. It provides kernel routing
table updates, interface lookups, and redistribution of routes between
different routing protocols.
@menu
* Invoking zebra:: Running the program
* Interface Commands:: Commands for zebra interfaces
* Static Route Commands:: Commands for adding static routes
* zebra Terminal Mode Commands:: Commands for zebra's VTY
@end menu
@node Invoking zebra, Interface Commands, Zebra, Zebra
@comment node-name, next, previous, up
@section Invoking zebra
Besides the common invocation options (@pxref{Common Invocation Options}), the
@command{zebra} specific invocation options are listed below.
@table @samp
@item -b
@itemx --batch
Runs in batch mode. @command{zebra} parses configuration file and terminates
immediately.
@item -k
@itemx --keep_kernel
When zebra starts up, don't delete old self inserted routes.
@item -l
@itemx --log_mode
Set verbose logging on.
@item -r
@itemx --retain
When program terminates, retain routes added by zebra.
@end table
@node Interface Commands, Static Route Commands, Invoking zebra, Zebra
@comment node-name, next, previous, up
@section Interface Commands
@deffn Command {interface @var{ifname}} {}
@end deffn
@deffn {Interface Command} {shutdown} {}
@deffnx {Interface Command} {no shutdown} {}
Up or down the current interface.
@end deffn
@deffn {Interface Command} {ip address @var{address}} {}
Set ip address for the interface.
@end deffn
@deffn {Interface Command} {description @var{description} ...} {}
Set description for the interface.
@end deffn
@deffn {Interface Command} {multicast} {}
@deffnx {Interface Command} {no multicast} {}
Enable or disables multicast flag for the interface.
@end deffn
@deffn {Interface Command} {bandwidth <1-10000000>} {}
@deffnx {Interface Command} {no bandwidth <1-10000000>} {}
Set bandwidth value to the interface. This is for calculating OSPF
cost. This command does not affect the actual device configuration.
@end deffn
@node Static Route Commands, zebra Terminal Mode Commands, Interface Commands, Zebra
@comment node-name, next, previous, up
@section Static Route Commands
Static routing is a very fundamental feature of routing technology. It
defines static prefix and gateway.
@deffn Command {ip route @var{network} @var{gateway}} {}
@var{network} is destination prefix with format of A.B.C.D/M.
@var{gateway} is gateway for the prefix. When @var{gateway} is
A.B.C.D format. It is taken as a IPv4 address gateway. Otherwise it
is treated as an interface name.
@example
ip route 10.0.0.0/8 10.0.0.2
ip route 10.0.0.0/8 ppp0
@end example
First example defines 10.0.0.0/8 static route with gateway 10.0.0.2.
Second one defines the same prefix but with gateway to interface ppp0.
@end deffn
@deffn Command {ip route @var{network} @var{netmask} @var{gateway}} {}
This is alternate version of above command. When @var{network} is
A.B.C.D format, user must define @var{netmask} value with A.B.C.D
format. @var{gateway} is same option as above command
@example
ip route 10.0.0.0 255.255.255.0 10.0.0.2
ip route 10.0.0.0 255.255.255.0 ppp0
@end example
This is a same setting using this statement.
@end deffn
@deffn Command {ip route @var{network} @var{gateway} @var{distance}} {}
@end deffn
Multiple nexthop static route
@example
ip route 10.0.0.1/32 10.0.0.2
ip route 10.0.0.1/32 10.0.0.3
ip route 10.0.0.1/32 eth0
@end example
If there is no route to 10.0.0.2 and 10.0.0.3, and interface eth0
is reachable, then the last route is installed into the kernel.
@example
zebra> show ip route
S> 10.0.0.1/32 [1/0] via 10.0.0.2 inactive
via 10.0.0.3 inactive
* is directly connected, eth0
@end example
Floating static route
@deffn Command {ipv6 route @var{network} @var{gateway}} {}
@end deffn
@deffn Command {ipv6 route @var{network} @var{gateway} @var{distance}} {}
@end deffn
@deffn Command {table @var{tableno}} {}
Select the primary kernel routing table to be used. This only works
for kernels supporting multiple routing tables (like GNU/Linux 2.2.x
and later). After setting @var{tableno} with this command,
static routes defined after this are added to the specified table.
@end deffn
@node zebra Terminal Mode Commands, , Static Route Commands, Zebra
@comment node-name, next, previous, up
@section zebra Terminal Mode Commands
@deffn Command {show ip route} {}
Display current routes which zebra holds in its database.
@example
@group
Router# show ip route
Codes: K - kernel route, C - connected, S - static, R - RIP,
B - BGP * - FIB route.
K* 0.0.0.0/0 203.181.89.241
S 0.0.0.0/0 203.181.89.1
C* 127.0.0.0/8 lo
C* 203.181.89.240/28 eth0
@end group
@end example
@end deffn
@deffn Command {show ipv6 route} {}
@end deffn
@deffn Command {show interface} {}
@end deffn
@deffn Command {show ipforward} {}
Display whether the host's IP forwarding function is enabled or not.
Almost any UNIX kernel can be configured with IP forwarding disabled.
If so, the box can't work as a router.
@end deffn
@deffn Command {show ipv6forward} {}
Display whether the host's IP v6 forwarding is enabled or not.
@end deffn

127
doc/ospf6d.8 Normal file
View File

@ -0,0 +1,127 @@
.TH OSPF6D 8 "July 2000" "Zebra Beast - OSPF6D" "Version 0.88"
.SH NAME
ospf6d \- an OSPF routing engine for use with Zebra and IPv6
.SH SYNOPSIS
.B ospf6d
[
.B \-dhv
]
[
.B \-f config-file
]
[
.B \-i pid-file
]
[
.B \-P port-number
]
.SH DESCRIPTION
.B ospf6d
is a routing component that works with the
.B zebra
routing engine.
\fBospf6d\fR.
.SH OPTIONS
.TP
\fB\-d\fR, \fB\-\-daemon\fR
Runs in daemon mode, forking and exiting from tty.
.TP
\fB\-f\fR, \fB\-\-config-file \fR\fIconfig-file\fR
Specifies the config file to use for startup. If not specified this
option will likely default to \fB\fI/usr/local/etc/ospf6d.conf\fR.
.TP
\fB\-h\fR, \fB\-\-help\fR
A brief message.
.TP
\fB\-i\fR, \fB\-\-pid_file \fR\fIpid-file\fR
When ospf6d starts its process idenifier is written to
\fB\fIpid-file\fR. The init system uses the recorded PID to stop or
restart ospf6d. The likely default is \fB\fI/var/run/ospf6d.pid\fR.
.TP
\fB\-P\fR, \fB\-\-vty_port \fR\fIport-number\fR
Specify the port that the ospf6d VTY will listen on. This defaults to
2606, as specified in \fB\fI/etc/services\fR.
.TP
\fB\-v\fR, \fB\-\-version\fR
Print the version and exit.
.SH COMMANDS
\fB router ospf6 \fR
\fB router zebra \fR -- (Move routes into kernel table)
\fB network [NETWORK] area [OSPF6-AREA-ID] \fR
\fB no network [NETWORK] \fR
\fB show ip ospf6 interface \fR
\fB show ip ospf6 neighbor \fR
\fB show ip ospf6 database \fR
\fB show ip ospf6 route \fR
\fB debug ospf6 ism \fR
\fB debug ospf6 packet \fR
\fB debug ospf6 nsm \fR
.SH FILES
.TP
.BI /usr/local/sbin/ospf6d
The default location of the
.B ospf6d
binary.
.TP
.BI /usr/local/etc/ospf6d.conf
The default location of the
.B ospf6d
config file.
.TP
.BI $(PWD)/ospf6d.log
If the
.B ospf6d
process is config'd to output logs to a file, then you will find this
file in the directory where you started \fBospf6d\fR.
.SH WARNING
This man page is intended as a quick reference for command line
options, and for config file commands. The definitive document is the
Info file \fBzebra\fR.
.SH DIAGNOSTICS
The ospf6d process may log to standard output, to a VTY, to a log
file, or through syslog to the system logs. \fBospf6d\fR supports many
debugging options, see the Info file, or the source for details.
.SH "SEE ALSO"
References to other related man pages:
ripd(8), ripngd(8), ospfd(8), bgpd(8), zebra(8), vtysh(1)
.SH BUGS
.B ospf6d
eats bugs for breakfast. If you have food for the maintainers try
.BI <bug-zebra@gnu.org>
.SH AUTHOR[S]
See <\fBwww.zebra.org\fR>, or the Info file for an accurate list of authors.

102
doc/ospf6d.texi Normal file
View File

@ -0,0 +1,102 @@
@node OSPFv3, BGP, OSPFv2, Top
@comment node-name, next, previous, up
@chapter OSPFv3
@command{ospf6d} is a daemon support OSPF version 3 for IPv6 network.
OSPF for IPv6 is described in RFC2740.
@menu
* OSPF6 router::
* OSPF6 area::
* OSPF6 interface::
* Redistribute routes to OSPF6::
* Showing OSPF6 information::
@end menu
@node OSPF6 router, OSPF6 area, OSPFv3, OSPFv3
@comment node-name, next, previous, up
@section OSPF6 router
@deffn {Command} {router ospf6} {}
@end deffn
@deffn {OSPF6 Command} {router-id @var{a.b.c.d}} {}
Set router's Router-ID.
@end deffn
@deffn {OSPF6 Command} {interface @var{ifname} area @var{area}} {}
Bind interface to specified area, and start sending OSPF packets. @var{area} can
be specified as 0.
@end deffn
@node OSPF6 area, OSPF6 interface, OSPF6 router, OSPFv3
@comment node-name, next, previous, up
@section OSPF6 area
Area support for OSPFv3 is not yet implemented.
@node OSPF6 interface, Redistribute routes to OSPF6, OSPF6 area, OSPFv3
@comment node-name, next, previous, up
@section OSPF6 interface
@deffn {Interface Command} {ipv6 ospf6 cost COST} {}
Sets interface's output cost. Default value is 1.
@end deffn
@deffn {Interface Command} {ipv6 ospf6 hello-interval HELLOINTERVAL} {}
Sets interface's Hello Interval. Default 40
@end deffn
@deffn {Interface Command} {ipv6 ospf6 dead-interval DEADINTERVAL} {}
Sets interface's Router Dead Interval. Default value is 40.
@end deffn
@deffn {Interface Command} {ipv6 ospf6 retransmit-interval RETRANSMITINTERVAL} {}
Sets interface's Rxmt Interval. Default value is 5.
@end deffn
@deffn {Interface Command} {ipv6 ospf6 priority PRIORITY} {}
Sets interface's Router Priority. Default value is 1.
@end deffn
@deffn {Interface Command} {ipv6 ospf6 transmit-delay TRANSMITDELAY} {}
Sets interface's Inf-Trans-Delay. Default value is 1.
@end deffn
@node Redistribute routes to OSPF6, Showing OSPF6 information, OSPF6 interface, OSPFv3
@comment node-name, next, previous, up
@section Redistribute routes to OSPF6
@deffn {OSPF6 Command} {redistribute static} {}
@deffnx {OSPF6 Command} {redistribute connected} {}
@deffnx {OSPF6 Command} {redistribute ripng} {}
@end deffn
@node Showing OSPF6 information, , Redistribute routes to OSPF6, OSPFv3
@comment node-name, next, previous, up
@section Showing OSPF6 information
@deffn {Command} {show ipv6 ospf6 [INSTANCE_ID]} {}
INSTANCE_ID is an optional OSPF instance ID. To see router ID and OSPF
instance ID, simply type "show ipv6 ospf6 <cr>".
@end deffn
@deffn {Command} {show ipv6 ospf6 database} {}
This command shows LSA database summary. You can specify the type of LSA.
@end deffn
@deffn {Command} {show ipv6 ospf6 interface} {}
To see OSPF interface configuration like costs.
@end deffn
@deffn {Command} {show ipv6 ospf6 neighbor} {}
Shows state and chosen (Backup) DR of neighbor.
@end deffn
@deffn {Command} {show ipv6 ospf6 request-list A.B.C.D} {}
Shows requestlist of neighbor.
@end deffn
@deffn {Command} {show ipv6 route ospf6} {}
This command shows internal routing table.
@end deffn

131
doc/ospfd.8 Normal file
View File

@ -0,0 +1,131 @@
.TH OSPFD 8 "July 2000" "Zebra Beast - OSPFD" "Version 0.88"
.SH NAME
ospfd \- an OSPF v2 routing engine for use with Zebra
.SH SYNOPSIS
.B ospfd
[
.B \-dhlv
]
[
.B \-f config-file
]
[
.B \-i pid-file
]
[
.B \-P port-number
]
.SH DESCRIPTION
.B ospfd
is a routing component that works with the
.B zebra
routing engine.
.SH OPTIONS
.TP
\fB\-d\fR, \fB\-\-daemon\fR
Runs in daemon mode, forking and exiting from tty.
.TP
\fB\-f\fR, \fB\-\-config-file \fR\fIconfig-file\fR
Specifies the config file to use for startup. If not specified this
option will likely default to \fB\fI/usr/local/etc/ospfd.conf\fR.
.TP
\fB\-h\fR, \fB\-\-help\fR
A brief message.
.TP
\fB\-i\fR, \fB\-\-pid_file \fR\fIpid-file\fR
When ospfd starts its process idenifier is written to
\fB\fIpid-file\fR. The init system uses the recorded PID to stop or
restart ospfd. The likely default is \fB\fI/var/run/ospfd.pid\fR.
.TP
\fB\-l\fR, \fB\-\-log_mode\fR
Turn verbose logging on.
.TP
\fB\-P\fR, \fB\-\-vty_port \fR\fIport-number\fR
Specify the port that the ospfd VTY will listen on. This defaults to
2604, as specified in \fB\fI/etc/services\fR.
.TP
\fB\-v\fR, \fB\-\-version\fR
Print the version and exit.
.SH COMMANDS
\fB router ospf \fR
\fB router zebra \fR -- (Move routes into kernel table)
\fB network [NETWORK] area [OSPF-AREA-ID] \fR
\fB no network [NETWORK] \fR
\fB show ip ospf interface \fR
\fB show ip ospf neighbor \fR
\fB show ip ospf database \fR
\fB show ip ospf route \fR
\fB debug ospf ism \fR
\fB debug ospf packet \fR
\fB debug ospf nsm \fR
.SH FILES
.TP
.BI /usr/local/sbin/ospfd
The default location of the
.B ospfd
binary.
.TP
.BI /usr/local/etc/ospfd.conf
The default location of the
.B ospfd
config file.
.TP
.BI $(PWD)/ospfd.log
If the
.B ospfd
process is config'd to output logs to a file, then you will find this
file in the directory where you started \fBospfd\fR.
.SH WARNING
This man page is intended as a quick reference for command line
options, and for config file commands. The definitive document is the
Info file \fBzebra\fR.
.SH DIAGNOSTICS
The ospfd process may log to standard output, to a VTY, to a log
file, or through syslog to the system logs. \fBospfd\fR supports many
debugging options, see the Info file, or the source for details.
.SH "SEE ALSO"
References to other related man pages:
ripd(8), ripngd(8), ospf6d(8), bgpd(8), zebra(8), vtysh(1)
.SH BUGS
.B ospfd
eats bugs for breakfast. If you have food for the maintainers try
.BI <bug-zebra@gnu.org>
.SH AUTHOR[S]
See <\fBwww.zebra.org\fR>, or the Info file for an accurate list of authors.

345
doc/ospfd.texi Normal file
View File

@ -0,0 +1,345 @@
@node OSPFv2, OSPFv3, RIPng, Top
@comment node-name, next, previous, up
@chapter OSPFv2
OSPF version 2 is a routing protocol which described in
@asis{RFC2328} - @cite{OSPF Version 2}. OSPF is IGP (Interior Gateway
Protocols). Compared with RIP, OSPF can provide scalable network
support and faster convergence time. OSPF is widely used in large
networks such as ISP backbone and enterprise networks.
@menu
* Configuring ospfd::
* OSPF router::
* OSPF area::
* OSPF interface::
* Redistribute routes to OSPF::
* Showing OSPF information::
* Debugging OSPF::
@end menu
@node Configuring ospfd, OSPF router, OSPFv2, OSPFv2
@comment node-name, next, previous, up
@section Configuring ospfd
There is no @command{ospfd} specific options. Common options can be
specified (@pxref{Common Invocation Options}) to @command{ospfd}.
@command{ospfd} needs interface information from @command{zebra}. So
please make it sure @command{zebra} is running before invoking
@command{ospfd}.
Like other daemons, @command{ospfd} configuration is done in OSPF
specific configuration file @file{ospfd.conf}.
@node OSPF router, OSPF area, Configuring ospfd, OSPFv2
@comment node-name, next, previous, up
@section OSPF router
To start OSPF process you have to specify the OSPF router. As of this
writing, @command{ospfd} does not support multiple OSPF processes.
@deffn Command {router ospf} {}
@deffnx Command {no router ospf} {}
Enable or disable the OSPF process. @command{ospfd} does not yet
support multiple OSPF processes. So you can not specify an OSPF process
number.
@end deffn
@deffn {OSPF Command} {ospf router-id @var{a.b.c.d}} {}
@deffnx {OSPF Command} {no ospf router-id} {}
@end deffn
@deffn {OSPF Command} {ospf abr-type @var{type}} {}
@deffnx {OSPF Command} {no ospf abr-type @var{type}} {}
@var{type} can be cisco|ibm|shortcut|standard
@end deffn
@deffn {OSPF Command} {ospf rfc1583compatibility} {}
@deffnx {OSPF Command} {no ospf rfc1583compatibility} {}
@end deffn
@deffn {OSPF Command} {passive interface @var{interface}} {}
@deffnx {OSPF Command} {no passive interface @var{interface}} {}
@end deffn
@deffn {OSPF Command} {timers spf <0-4294967295> <0-4294967295>} {}
@deffnx {OSPF Command} {no timers spf} {}
@end deffn
@deffn {OSPF Command} {refresh group-limit <0-10000>} {}
@deffnx {OSPF Command} {refresh per-slice <0-10000>} {}
@deffnx {OSPF Command} {refresh age-diff <0-10000>} {}
@end deffn
@deffn {OSPF Command} {auto-cost refrence-bandwidth <1-4294967>} {}
@deffnx {OSPF Command} {no auto-cost refrence-bandwidth} {}
@end deffn
@deffn {OSPF Command} {network @var{a.b.c.d/m} area @var{a.b.c.d}} {}
@deffnx {OSPF Command} {network @var{a.b.c.d/m} area @var{<0-4294967295>}} {}
@deffnx {OSPF Command} {no network @var{a.b.c.d/m} area @var{a.b.c.d}} {}
@deffnx {OSPF Command} {no network @var{a.b.c.d/m} area @var{<0-4294967295>}} {}
This command specifies the OSPF enabled interface. If the interface has
an address of 10.0.0.1/8 then the command below provides network
information to the ospf routers
@example
@group
router ospf
network 10.0.0.0/8 area 0
@end group
@end example
the network command's mask length should be the same as the interface
address's mask.
@end deffn
@node OSPF area, OSPF interface, OSPF router, OSPFv2
@comment node-name, next, previous, up
@section OSPF area
@deffn {OSPF Command} {area @var{a.b.c.d} range @var{a.b.c.d/m}} {}
@deffnx {OSPF Command} {area <0-4294967295> range @var{a.b.c.d/m}} {}
@deffnx {OSPF Command} {no area @var{a.b.c.d} range @var{a.b.c.d/m}} {}
@deffnx {OSPF Command} {no area <0-4294967295> range @var{a.b.c.d/m}} {}
@end deffn
@deffn {OSPF Command} {area @var{a.b.c.d} range IPV4_PREFIX suppress} {}
@deffnx {OSPF Command} {no area @var{a.b.c.d} range IPV4_PREFIX suppress} {}
@deffnx {OSPF Command} {area @var{a.b.c.d} range IPV4_PREFIX substitute IPV4_PREFIX} {}
@deffnx {OSPF Command} {no area @var{a.b.c.d} range IPV4_PREFIX substitute IPV4_PREFIX} {}
@end deffn
@deffn {OSPF Command} {area @var{a.b.c.d} virtual-link @var{a.b.c.d}} {}
@deffnx {OSPF Command} {area <0-4294967295> virtual-link @var{a.b.c.d}} {}
@deffnx {OSPF Command} {no area @var{a.b.c.d} virtual-link @var{a.b.c.d}} {}
@deffnx {OSPF Command} {no area <0-4294967295> virtual-link @var{a.b.c.d}} {}
@end deffn
@deffn {OSPF Command} {area @var{a.b.c.d} shortcut} {}
@deffnx {OSPF Command} {area <0-4294967295> shortcut} {}
@deffnx {OSPF Command} {no area @var{a.b.c.d} shortcut} {}
@deffnx {OSPF Command} {no area <0-4294967295> shortcut} {}
@end deffn
@deffn {OSPF Command} {area @var{a.b.c.d} stub} {}
@deffnx {OSPF Command} {area <0-4294967295> stub} {}
@deffnx {OSPF Command} {no area @var{a.b.c.d} stub} {}
@deffnx {OSPF Command} {no area <0-4294967295> stub} {}
@end deffn
@deffn {OSPF Command} {area @var{a.b.c.d} stub no-summary} {}
@deffnx {OSPF Command} {area <0-4294967295> stub no-summary} {}
@deffnx {OSPF Command} {no area @var{a.b.c.d} stub no-summary} {}
@deffnx {OSPF Command} {no area <0-4294967295> stub no-summary} {}
@end deffn
@deffn {OSPF Command} {area @var{a.b.c.d} default-cost <0-16777215>} {}
@deffnx {OSPF Command} {no area @var{a.b.c.d} default-cost <0-16777215>} {}
@end deffn
@deffn {OSPF Command} {area @var{a.b.c.d} export-list NAME} {}
@deffnx {OSPF Command} {area <0-4294967295> export-list NAME} {}
@deffnx {OSPF Command} {no area @var{a.b.c.d} export-list NAME} {}
@deffnx {OSPF Command} {no area <0-4294967295> export-list NAME} {}
@end deffn
@deffn {OSPF Command} {area @var{a.b.c.d} import-list NAME} {}
@deffnx {OSPF Command} {area <0-4294967295> import-list NAME} {}
@deffnx {OSPF Command} {no area @var{a.b.c.d} import-list NAME} {}
@deffnx {OSPF Command} {no area <0-4294967295> import-list NAME} {}
@end deffn
@deffn {OSPF Command} {area @var{a.b.c.d} authentication} {}
@deffnx {OSPF Command} {area <0-4294967295> authentication} {}
@deffnx {OSPF Command} {no area @var{a.b.c.d} authentication} {}
@deffnx {OSPF Command} {no area <0-4294967295> authentication} {}
@end deffn
@deffn {OSPF Command} {area @var{a.b.c.d} authentication message-digest} {}
@deffnx {OSPF Command} {area <0-4294967295> authentication message-digest} {}
@end deffn
@node OSPF interface, Redistribute routes to OSPF, OSPF area, OSPFv2
@comment node-name, next, previous, up
@section OSPF interface
@deffn {Interface Command} {ip ospf authentication-key AUTH_KEY} {}
@deffnx {Interface Command} {no ip ospf authentication-key} {}
Set OSPF authentication key to a simple password. After setting @var{AUTH_KEY},
all OSPF packets are authenticated. @var{AUTH_KEY} has length up to 8 chars.
@end deffn
@deffn {Interface Command} {ip ospf message-digest-key KEYID md5 KEY} {}
@deffnx {Interface Command} {no ip ospf message-digest-key} {}
Set OSPF authentication key to a cryptographic password. The cryptographic
algorithm is MD5. KEYID identifies secret key used to create the message
digest. KEY is the actual message digest key up to 16 chars.
@end deffn
@deffn {Interface Command} {ip ospf cost <1-65535>} {}
@deffnx {Interface Command} {no ip ospf cost} {}
Set link cost for the specified interface. The cost value is set to router-LSA's
metric field and used for SPF calculation.
@end deffn
@deffn {Interface Command} {ip ospf dead-interval <1-65535>} {}
@deffnx {Interface Command} {no ip ospf dead-interval} {}
Set number of seconds for RouterDeadInterval timer value used for Wait Timer
and Inactivity Timer. This value must be the same for all routers attached
to a common network. The default value is 40 seconds.
@end deffn
@deffn {Interface Command} {ip ospf hello-interval <1-65535>} {}
@deffnx {Interface Command} {no ip ospf hello-interval} {}
Set number of seconds for HelloInterval timer value. Setting this value,
Hello packet will be sent every timer value seconds on the specified interface.
This value must be the same for all routers attached to a common network.
The default value is 10 seconds.
@end deffn
@deffn {Interface Command} {ip ospf network (broadcast|non-broadcast|point-to-multipoint|point-to-point)} {}
@deffnx {Interface Command} {no ip ospf network} {}
Set explicitly network type for specifed interface.
@end deffn
@deffn {Interface Command} {ip ospf priority <0-255>} {}
@deffnx {Interface Command} {no ip ospf priority} {}
Set RouterPriority integer value. Setting higher value, router will be more
eligible to become Designated Router. Setting the value to 0, router is no
longer eligible to Designated Router.
The default value is 1.
@end deffn
@deffn {Interface Command} {ip ospf retransmit-interval <1-65535>} {}
@deffnx {Interface Command} {no ip ospf retransmit interval} {}
Set number of seconds for RxmtInterval timer value. This value is used
when retransmitting Database Description and Link State Request packets.
The default value is 5 seconds.
@end deffn
@deffn {Interface Command} {ip ospf transmit-delay} {}
@deffnx {Interface Command} {no ip ospf transmit-delay} {}
Set number of seconds for InfTransDelay value. LSAs' age should be
incremented by this value when transmitting.
The default value is 1 seconds.
@end deffn
@node Redistribute routes to OSPF, Showing OSPF information, OSPF interface, OSPFv2
@comment node-name, next, previous, up
@section Redistribute routes to OSPF
@deffn {OSPF Command} {redistribute (kernel|connected|static|rip|bgp)} {}
@deffnx {OSPF Command} {redistribute (kernel|connected|static|rip|bgp) @var{route-map}} {}
@deffnx {OSPF Command} {redistribute (kernel|connected|static|rip|bgp) metric-type (1|2)} {}
@deffnx {OSPF Command} {redistribute (kernel|connected|static|rip|bgp) metric-type (1|2) route-map @var{word}} {}
@deffnx {OSPF Command} {redistribute (kernel|connected|static|rip|bgp) metric <0-16777214>} {}
@deffnx {OSPF Command} {redistribute (kernel|connected|static|rip|bgp) metric <0-16777214> route-map @var{word}} {}
@deffnx {OSPF Command} {redistribute (kernel|connected|static|rip|bgp) metric-type (1|2) metric <0-16777214>} {}
@deffnx {OSPF Command} {redistribute (kernel|connected|static|rip|bgp) metric-type (1|2) metric <0-16777214> route-map @var{word}} {}
@deffnx {OSPF Command} {no redistribute (kernel|connected|static|rip|bgp)} {}
@end deffn
@deffn {OSPF Command} {default-information originate} {}
@deffnx {OSPF Command} {default-information originate metric <0-16777214>} {}
@deffnx {OSPF Command} {default-information originate metric <0-16777214> metric-type (1|2)} {}
@deffnx {OSPF Command} {default-information originate metric <0-16777214> metric-type (1|2) route-map @var{word}} {}
@deffnx {OSPF Command} {default-information originate always} {}
@deffnx {OSPF Command} {default-information originate always metric <0-16777214>} {}
@deffnx {OSPF Command} {default-information originate always metric <0-16777214> metric-type (1|2)} {}
@deffnx {OSPF Command} {default-information originate always metric <0-16777214> metric-type (1|2) route-map @var{word}} {}
@deffnx {OSPF Command} {no default-information originate} {}
@end deffn
@deffn {OSPF Command} {distribute-list NAME out (kernel|connected|static|rip|ospf} {}
@deffnx {OSPF Command} {no distribute-list NAME out (kernel|connected|static|rip|ospf} {}
@end deffn
@deffn {OSPF Command} {default-metric <0-16777214>} {}
@deffnx {OSPF Command} {no default-metric} {}
@end deffn
@deffn {OSPF Command} {distance <1-255>} {}
@deffnx {OSPF Command} {no distance <1-255>} {}
@end deffn
@deffn {OSPF Command} {distance ospf (intra-area|inter-area|external) <1-255>} {}
@deffnx {OSPF Command} {no distance ospf} {}
@end deffn
@deffn {Command} {router zebra} {}
@deffnx {Command} {no router zebra} {}
@end deffn
@node Showing OSPF information, Debugging OSPF, Redistribute routes to OSPF, OSPFv2
@comment node-name, next, previous, up
@section Showing OSPF information
@deffn {Command} {show ip ospf} {}
@end deffn
@deffn {Command} {show ip ospf interface [INTERFACE]} {}
@end deffn
@deffn {Command} {show ip ospf neighbor} {}
@deffnx {Command} {show ip ospf neighbor INTERFACE} {}
@deffnx {Command} {show ip ospf neighbor detail} {}
@deffnx {Command} {show ip ospf neighbor INTERFACE detail} {}
@end deffn
@deffn {Command} {show ip ospf database} {}
@end deffn
@deffn {Command} {show ip ospf database (asbr-summary|external|network|router|summary)} {}
@deffnx {Command} {show ip ospf database (asbr-summary|external|network|router|summary) @var{link-state-id}} {}
@deffnx {Command} {show ip ospf database (asbr-summary|external|network|router|summary) @var{link-state-id} adv-router @var{adv-router}} {}
@deffnx {Command} {show ip ospf database (asbr-summary|external|network|router|summary) adv-router @var{adv-router}} {}
@deffnx {Command} {show ip ospf database (asbr-summary|external|network|router|summary) @var{link-state-id} self-originate} {}
@deffnx {Command} {show ip ospf database (asbr-summary|external|network|router|summary) self-originate} {}
@end deffn
@deffn {Command} {show ip ospf database max-age} {}
@end deffn
@deffn {Command} {show ip ospf database self-originate} {}
@end deffn
@deffn {Command} {show ip ospf refresher} {}
@end deffn
@deffn {Command} {show ip ospf route} {}
@end deffn
@node Debugging OSPF, , Showing OSPF information, OSPFv2
@comment node-name, next, previous, up
@section Debugging OSPF
@deffn {Command} {debug ospf packet (hello|dd|ls-request|ls-update|ls-ack|all) (send|recv) [detail]} {}
@deffnx {Command} {no debug ospf packet (hello|dd|ls-request|ls-update|ls-ack|all) (send|recv) [detail]} {}
@end deffn
@deffn {Command} {debug ospf ism} {}
@deffnx {Command} {debug ospf ism (status|events|timers)} {}
@deffnx {Command} {no debug ospf ism} {}
@deffnx {Command} {no debug ospf ism (status|events|timers)} {}
@end deffn
@deffn {Command} {debug ospf nsm} {}
@deffnx {Command} {debug ospf nsm (status|events|timers)} {}
@deffnx {Command} {no debug ospf nsm} {}
@deffnx {Command} {no debug ospf nsm (status|events|timers)} {}
@end deffn
@deffn {Command} {debug ospf lsa} {}
@deffnx {Command} {debug ospf lsa (generate|flooding|refresh)} {}
@deffnx {Command} {no debug ospf lsa} {}
@deffnx {Command} {no debug ospf lsa (generate|flooding|refresh)} {}
@end deffn
@deffn {Command} {debug ospf zebra} {}
@deffnx {Command} {debug ospf zebra (interface|redistribute)} {}
@deffnx {Command} {no debug ospf zebra} {}
@deffnx {Command} {no debug ospf zebra (interface|redistribute)} {}
@end deffn
@deffn {Command} {show debugging ospf} {}
@end deffn

352
doc/overview.texi Normal file
View File

@ -0,0 +1,352 @@
@node Overview, Installation, Top, Top
@comment node-name, next, previous, up
@chapter Overview
@cindex Overview
Zebra is a routing software package that provides TCP/IP based
routing services with routing protocols support such as RIPv1, RIPv2,
RIPng, OSPFv2, OSPFv3, BGP-4, and BGP-4+ (@pxref{Supported RFC}).
Zebra also supports special BGP Route Reflector and Route Server
behavior. In addition to traditional IPv4 routing protocols, Zebra
also supports IPv6 routing protocols. With SNMP daemon which supports
SMUX protocol, Zebra provides routing protocol MIBs (@pxref{SNMP
Support}).
Zebra uses an advanced software architecture to provide you with a
high quality, multi server routing engine. Zebra has an interactive
user interface for each routing protocol and supports common client
commands. Due to this design, you can add new protocol daemons to Zebra
easily. You can use Zebra library as your program's client user
interface.
Zebra is an official @sc{gnu} software and distributed under the
@sc{gnu} General Public License.
@menu
* About Zebra:: Basic information about Zebra
* System Architecture:: The Zebra system architecture
* Supported Platforms:: Supported platforms and future plans
* Supported RFC:: Supported RFCs
* How to get Zebra::
* Mailing List:: Mailing list information
* Bug Reports:: Mail address for bug data
@end menu
@node About Zebra, System Architecture, Overview, Overview
@comment node-name, next, previous, up
@section About Zebra
@cindex About Zebra
Today, TCP/IP networks are covering all of the world. The Internet
has been deployed in many countries, companies, and to the home. When
you connect to the Internet your packet will pass many routers which
have TCP/IP routing functionality.
A system with Zebra installed acts as a dedicated router. With Zebra,
your machine exchanges routing information with other routers using
routing protocols. Zebra uses this information to update the kernel
routing table so that the right data goes to the right place. You can
dynamically change the configuration and you may view routing table
information from the Zebra terminal interface.
Adding to routing protocol support, Zebra can setup interface's flags,
interface's address, static routes and so on. If you have a small
network, or a stub network, or xDSL connection, configuring the Zebra
routing software is very easy. The only thing you have to do is to set
up the interfaces and put a few commands about static routes and/or
default routes. If the network is rather large, or if the network
structure changes frequently, you will want to take advantage of Zebra's
dynamic routing protocol support for protocols such as RIP, OSPF or BGP.
Zebra is with you.
Traditionally, UNIX based router configuration is done by
@command{ifconfig} and @command{route} commands. Status of routing
table is displayed by @command{netstat} utility. Almost of these
commands work only if the user has root privileges. Zebra has a different
system administration method. There are two user modes in Zebra. One is
normal mode, the other is enable mode. Normal mode user can only view
system status, enable mode user can change system configuration. This
UNIX account independent feature will be great help to the router
administrator.
Currently, Zebra supports common unicast routing protocols. Multicast
routing protocols such as BGMP, PIM-SM, PIM-DM will be supported in
Zebra 2.0. MPLS support is going on. In the future, TCP/IP filtering
control, QoS control, diffserv configuration will be added to Zebra.
Zebra project's final goal is making a productive, quality free TCP/IP
routing software.
@node System Architecture, Supported Platforms, About Zebra, Overview
@comment node-name, next, previous, up
@section System Architecture
@cindex System architecture
@cindex Software architecture
@cindex Software internals
Traditional routing software is made as a one process program which
provides all of the routing protocol functionalities. Zebra takes a
different approach. It is made from a collection of several daemons
that work together to build the routing table. There may be several
protocol-specific routing daemons and zebra the kernel routing manager.
The @command{ripd} daemon handles the RIP protocol, while
@command{ospfd} is a daemon which supports OSPF version 2.
@command{bgpd} supports the BGP-4 protocol. For changing the kernel
routing table and for redistribution of routes between different routing
protocols, there is a kernel routing table manager @command{zebra}
daemon. It is easy to add a new routing protocol daemons to the entire
routing system without affecting any other software. You need to run only
the protocol daemon associated with routing protocols in use. Thus,
user may run a specific daemon and send routing reports to a central
routing console.
There is no need for these daemons to be running on the same machine.
You can even run several same protocol daemons on the same machine. This
architecture creates new possibilities for the routing system.
@example
@group
+----+ +----+ +-----+ +-----+
|bgpd| |ripd| |ospfd| |zebra|
+----+ +----+ +-----+ +-----+
|
+---------------------------|--+
| v |
| UNIX Kernel routing table |
| |
+------------------------------+
Zebra System Architecture
@end group
@end example
Multi-process architecture brings extensibility, modularity and
maintainability. At the same time it also brings many configuration
files and terminal interfaces. Each daemon has it's own configuration
file and terminal interface. When you configure a static route, it must
be done in @command{zebra} configuration file. When you configure BGP
network it must be done in @command{bgpd} configuration file. This can be a
very annoying thing. To resolve the problem, Zebra provides integrated
user interface shell called @command{vtysh}. @command{vtysh} connects to
each daemon with UNIX domain socket and then works as a proxy for user input.
Zebra was planned to use multi-threaded mechanism when it runs with a
kernel that supports multi-threads. But at the moment, the thread
library which comes with @sc{gnu}/Linux or FreeBSD has some problems with
running reliable services such as routing software, so we don't use
threads at all. Instead we use the @command{select(2)} system call for
multiplexing the events.
When @command{zebra} runs under a @sc{gnu} Hurd kernel it will act as a
kernel routing table itself. Under @sc{gnu} Hurd, all TCP/IP services are
provided by user processes called @command{pfinet}. Zebra will provide
all the routing selection mechanisms for the process. This feature will
be implemented when @sc{gnu} Hurd becomes stable.
@node Supported Platforms, Supported RFC, System Architecture, Overview
@comment node-name, next, previous, up
@section Supported Platforms
@cindex Supported platforms
@cindex Zebra on other systems
@cindex Compatibility with other systems
@cindex Operating systems that support Zebra
Currently Zebra supports @sc{gnu}/Linux, BSD and Solaris. Below is a list
of OS versions on which Zebra runs. Porting Zebra to other platforms is
not so too difficult. Platform dependent codes exist only in
@command{zebra} daemon. Protocol daemons are platform independent.
Please let us know when you find out Zebra runs on a platform which is not
listed below.
@sp 1
@itemize @bullet
@item
GNU/Linux 2.0.37
@item
GNU/Linux 2.2.x
@item
GNU/Linux 2.3.x
@item
FreeBSD 2.2.8
@item
FreeBSD 3.x
@item
FreeBSD 4.x
@item
NetBSD 1.4
@item
OpenBSD 2.5
@item
Solaris 2.6
@item
Solaris 7
@end itemize
@sp 1
Some IPv6 stacks are in development. Zebra supports following IPv6
stacks. For BSD, we recommend KAME IPv6 stack. Solaris IPv6 stack is
not yet supported.
@sp 1
@itemize @bullet
@item
Linux IPv6 stack for GNU/Linux 2.2.x and higher.
@item
KAME IPv6 stack for BSD.
@item
INRIA IPv6 stack for BSD.
@end itemize
@node Supported RFC, How to get Zebra, Supported Platforms, Overview
@comment node-name, next, previous, up
@section Supported RFC
Below is the list of currently supported RFC's.
@table @asis
@item @asis{RFC1058}
@cite{Routing Information Protocol. C.L. Hedrick. Jun-01-1988.}
@item @asis{RF2082}
@cite{RIP-2 MD5 Authentication. F. Baker, R. Atkinson. January 1997.}
@item @asis{RFC2453}
@cite{RIP Version 2. G. Malkin. November 1998.}
@item @asis{RFC2080}
@cite{RIPng for IPv6. G. Malkin, R. Minnear. January 1997.}
@item @asis{RFC2328}
@cite{OSPF Version 2. J. Moy. April 1998.}
@item @asis{RFC2740}
@cite{OSPF for IPv6. R. Coltun, D. Ferguson, J. Moy. December 1999.}
@item @asis{RFC1771}
@cite{A Border Gateway Protocol 4 (BGP-4). Y. Rekhter & T. Li. March 1995.}
@item @asis{RFC1965}
@cite{Autonomous System Confederations for BGP. P. Traina. June 1996.}
@item @asis{RFC1997}
@cite{BGP Communities Attribute. R. Chandra, P. Traina & T. Li. August 1996.}
@item @asis{RFC2545}
@cite{Use of BGP-4 Multiprotocol Extensions for IPv6 Inter-Domain Routing. P. Marques, F. Dupont. March 1999.}
@item @asis{RFC2796}
@cite{BGP Route Reflection An alternative to full mesh IBGP. T. Bates & R. Chandrasekeran. June 1996.}
@item @asis{RFC2858}
@cite{Multiprotocol Extensions for BGP-4. T. Bates, Y. Rekhter, R. Chandra, D. Katz. June 2000.}
@item @asis{RFC2842}
@cite{Capabilities Advertisement with BGP-4. R. Chandra, J. Scudder. May 2000.}
@end table
When SNMP support is enabled, below RFC is also supported.
@table @asis
@item @asis{RFC1227}
@cite{SNMP MUX protocol and MIB. M.T. Rose. May-01-1991.}
@item @asis{RFC1657}
@cite{Definitions of Managed Objects for the Fourth Version of the
Border Gateway Protocol (BGP-4) using SMIv2. S. Willis, J. Burruss,
J. Chu, Editor. July 1994.}
@item @asis{RFC1724}
@cite{RIP Version 2 MIB Extension. G. Malkin & F. Baker. November 1994.}
@item @asis{RFC1850}
@cite{OSPF Version 2 Management Information Base. F. Baker, R. Coltun.
November 1995.}
@end table
@node How to get Zebra, Mailing List, Supported RFC, Overview
@comment node-name, next, previous, up
@section How to get Zebra
Zebra is still beta software and there is no officially
released version. So currently Zebra is distributed from Zebra beta ftp
site located at:
@url{ftp://ftp.zebra.org/pub/zebra}
Once Zebra is released you can get it from @sc{gnu} FTP site and
its mirror sites. We are planning Zebra-1.0 as the first released
version.
Zebra's official web page is located at:
@url{http://www.gnu.org/software/zebra/zebra.html}.
There is a Zebra beta tester web page at:
@url{http://www.zebra.org/}.
You can get the latest beta software information from this page.
@node Mailing List, Bug Reports, How to get Zebra, Overview
@comment node-name, next, previous, up
@section Mailing List
@cindex How to get in touch with Zebra
@cindex Mailing Zebra
@cindex Contact information
@cindex Mailing lists
There is a mailing list for discussions about Zebra. If you have any
comments or suggestions to Zebra, please send mail to
@email{zebra@@zebra.org}. New snapshot announcements, improvement
notes, and patches are sent to the list.
To subscribe to the @email{zebra@@zebra.org, Zebra mailing list},
please send a mail to @email{majordomo@@zebra.org} with a message body
that includes only:
@quotation
subscribe zebra
@end quotation
To unsubscribe from the list, please send a mail to
@email{majordomo@@zebra.org} with a message body that includes only:
@quotation
unsubscribe zebra
@end quotation
@node Bug Reports, , Mailing List, Overview
@comment node-name, next, previous, up
@section Bug Reports
@cindex Bug Reports
@cindex Bug hunting
@cindex Found a bug?
@cindex Reporting bugs
@cindex Reporting software errors
@cindex Errors in the software
If you think you have found a bug, please send a bug report to
@email{bug-zebra@@gnu.org}. When you send a bug report, please be
careful about the points below.
@itemize @bullet
@item
Please note what kind of OS you are using. If you use the IPv6 stack
please note that as well.
@item
Please show us the results of @code{netstat -rn} and @code{ifconfig -a}.
Information from zebra's VTY command @code{show ip route} will also be
helpful.
@item
Please send your configuration file with the report. If you specify
arguments to the configure script please note that too.
@end itemize
Bug reports are very important for us to improve the quality of Zebra.
Zebra is still in the development stage, but please don't hesitate to
send a bug report to @email{bug-zebra@@gnu.org}.

52
doc/protocol.texi Normal file
View File

@ -0,0 +1,52 @@
@node Zebra Protocol, Packet Binary Dump Format, SNMP Support, Top
@comment node-name, next, previous, up
@appendix Zebra Protocol
Zebra Protocol is a protocol which is used between protocol daemon and
zebra. Each protocol daemon sends selected routes to zebra daemon. Then
zebra manages which route is installed into the forwarding table.
Zebra Protocol is a TCP-based protocol. Below is common header of Zebra
Protocol.
@example
@group
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Length (2) | Command (1) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@end group
@end example
Length is total packet length including this header length. So minimum
length is three. Command is Zebra Protocol command.
@example
ZEBRA_INTERFACE_ADD 1
ZEBRA_INTERFACE_DELETE 2
ZEBRA_INTERFACE_ADDRESS_ADD 3
ZEBRA_INTERFACE_ADDRESS_DELETE 4
ZEBRA_INTERFACE_UP 5
ZEBRA_INTERFACE_DOWN 6
ZEBRA_IPV4_ROUTE_ADD 7
ZEBRA_IPV4_ROUTE_DELETE 8
ZEBRA_IPV6_ROUTE_ADD 9
ZEBRA_IPV6_ROUTE_DELETE 10
ZEBRA_REDISTRIBUTE_ADD 11
ZEBRA_REDISTRIBUTE_DELETE 12
ZEBRA_REDISTRIBUTE_DEFAULT_ADD 13
ZEBRA_REDISTRIBUTE_DEFAULT_DELETE 14
ZEBRA_IPV4_NEXTHOP_LOOKUP 15
ZEBRA_IPV6_NEXTHOP_LOOKUP 16
@end example
@example
@group
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Flags |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@end group
@end example

212
doc/ripd.8 Normal file
View File

@ -0,0 +1,212 @@
.TH RIPD 8 "July 2000" "Zebra" "Version 0.88"
.SH NAME
ripd \- a RIP routing engine for use with Zebra
.SH SYNOPSIS
.B ripd
[
.B \-dhrv
]
[
.B \-f config-file
]
[
.B \-i pid-file
]
[
.B \-P port-number
]
.SH DESCRIPTION
.B ripd
is a routing component that supports the
.B zebra
route engine.
.B ripd
supports RIPv1, RIPv2, and so forth.
.SH OPTIONS
.TP
\fB\-d\fR, \fB\-\-daemon\fR
Runs in daemon mode, forking and exiting from tty.
.TP
\fB\-f\fR, \fB\-\-config-file \fR\fIconfig-file\fR
Specifies the config file to use for startup. If not specified this option will likely default to \fB\fI/usr/local/etc/ripd.conf\fR.
.TP
\fB\-h\fR, \fB\-\-help\fR
A brief message.
.TP
\fB\-i\fR, \fB\-\-pid_file \fR\fIpid-file\fR
When ripd starts its process idenifier is written to
\fB\fIpid-file\fR. The init system uses the recorded PID to stop or
restart ripd. The likely default is \fB\fI/var/run/ripd.pid\fR.
.TP
\fB\-P\fR, \fB\-\-vty_port \fR\fIport-number\fR
Specify the port that the ripd VTY will listen on. This defaults to
2602, as specified in \fB\fI/etc/services\fR.
.TP
\fB\-r\fR, \fB\-\-retain\fR
When the program terminates, retain routes added by \fBripd\fR.
.TP
\fB\-v\fR, \fB\-\-version\fR
Print the version and exit.
.SH COMMANDS
\fB router rip \fR
\fB no router rip \fR
\fB rip version [1|2] \fR
\fB no rip version [1|2] \fR
\fB network [A.B.C.D/M] \fR
\fB no network [A.B.C.D/M] \fR
\fB network [IFNAME] \fR
\fB no network [IFNAME] \fR
\fB neighbor [A.B.C.D] \fR
\fB no neighbor [A.B.C.D] \fR
\fB redistribute kernel \fR
\fB redistribute kernel metric [METRIC]\fR
\fB redistribute kernel route-map [ROUTE-MAP]\fR
\fB no redistribute kernel \fR
\fB redistribute static \fR
\fB redistribute static metric [METRIC]\fR
\fB redistribute static route-map [ROUTE-MAP]\fR
\fB no redistribute static \fR
\fB redistribute connected \fR
\fB redistribute connected metric [METRIC]\fR
\fB redistribute connected route-map [ROUTE-MAP]\fR
\fB no redistribute connected \fR
\fB redistribute ospf \fR
\fB redistribute ospf metric [METRIC]\fR
\fB redistribute ospf route-map [ROUTE-MAP]\fR
\fB no redistribute ospf \fR
\fB redistribute bgp \fR
\fB redistribute bgp metric [METRIC]\fR
\fB redistribute bgp route-map [ROUTE-MAP]\fR
\fB no redistribute bgp \fR
\fB route [A.B.C.D/M] \fR
\fB no route [A.B.C.D/M] \fR
\fB default-information originate \fR
\fB no default-information originate \fR
\fB default-metric [METRIC] \fR
\fB no default-metric [METRIC] \fR
\fB passive-interface [IFNAME] \fR
\fB no passive-interface [IFNAME] \fR
\fB offset-list [ACCESS-LIST] [in|out]\fR
\fB offset-list [ACCESS-LIST] [in|out] [IFNAME]\fR
\fB no offset-list [ACCESS-LIST] [in|out]\fR
\fB timers basic [UPDATE-INTERVAL] [INVALID] [TIMEOUT] [GARBAGE-COLLECT] \fR
\fB no timers basic \fR
\fB distribute-list [ACCESS-LIST] [in|out] [IFNAME] \fR
\fB no distribute-list [ACCESS-LIST] [in|out] [IFNAME] \fR
\fB distribute-list prefix [PREFIX-LIST] [in|out] [IFNAME] \fR
\fB no distribute-list prefix [PREFIX-LIST] [in|out] [IFNAME] \fR
\fB distance [DISTANCE] \fR
\fB no distance [DISTANCE] \fR
\fB distance [DISTANCE] [A.B.C.D/M] \fR
\fB no distance [DISTANCE] [A.B.C.D/M] \fR
\fB distance [DISTANCE] [A.B.C.D/M] [ACCESS-LIST]\fR
\fB no distance [DISTANCE] [A.B.C.D/M] [ACCESS-LIST]\fR
\fB ip rip send version [VERSION] \fR
\fB no ip rip send version [VERSION] \fR
\fB ip rip receive version [VERSION] \fR
\fB no ip rip receive version [VERSION] \fR
\fB ip rip authentication mode [md5|text]\fR
\fB no ip rip authentication mode [md5|text]\fR
\fB ip rip authentication key-chain [KEY-CHAIN]\fR
\fB no ip rip authentication key-chain [KEY-CHAIN]\fR
\fB ip rip authentication string [STRING]\fR
\fB no ip rip authentication string [STRING]\fR
\fB ip spli-horizon\fR
\fB no ip spli-horizon\fR
\fB show ip rip \fR
\fB show ip protocols \fR
\fB show debugging rip \fR
\fB debug rip \fR
\fB debug rip events \fR
\fB debug rip packet \fR
\fB debug rip zebra \fR
.SH FILES
.TP
.BI /usr/local/sbin/ripd
The default location of the
.B ripd
binary.
.TP
.BI /usr/local/etc/ripd.conf
The default location of the
.B ripd
config file.
.TP
.BI $(PWD)/ripd.log
If the
.B ripd
process is config'd to output logs to a file, then you will find this
file in the directory where you started \fBripd\fR.
.SH WARNING
This man page is intended as a quick reference for command line options, and for config file commands. The definitive document is the Info file \fBzebra\fR.
.SH DIAGNOSTICS
The ripd process may log to standard output, to a VTY, to a log file, or through syslog to the system logs.
.B ripd
supports many debugging options, see the Info file, or the source for details.
.SH "SEE ALSO"
References to other related man pages:
ripngd(8), ospfd(8), ospf6d(8), bgpd(8), zebra(8)
.SH BUGS
.B ripd
eats bugs for breakfast. If you have food for the maintainers try
.BI <bug-zebra@gnu.org>
.SH AUTHOR[S]
See <\fBwww.zebra.org\fR>, or the Info file for an accurate list of authors.

Some files were not shown because too many files have changed in this diff Show More