mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-04-28 11:50:21 +00:00
Initial revision
This commit is contained in:
commit
718e374419
10
.cvsignore
Normal file
10
.cvsignore
Normal 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
6
AUTHORS
Normal 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
339
COPYING
Normal 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
482
COPYING.LIB
Normal 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
674
ChangeLog
Normal 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
181
INSTALL
Normal 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
16
Makefile.am
Normal 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
548
Makefile.in
Normal 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:
|
12
README
Normal file
12
README
Normal 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
28
REPORTING-BUGS
Normal 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
17
SERVICES
Normal 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
29
TODO
Normal 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
161
acconfig.h
Normal 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
811
aclocal.m4
vendored
Normal 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
8
bgpd/.cvsignore
Normal file
@ -0,0 +1,8 @@
|
||||
Makefile
|
||||
*.o
|
||||
bgpd
|
||||
bgp_btoa
|
||||
bgpd.conf
|
||||
tags
|
||||
TAGS
|
||||
.deps
|
929
bgpd/BGP4-MIB.txt
Normal file
929
bgpd/BGP4-MIB.txt
Normal 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
2368
bgpd/ChangeLog
Normal file
File diff suppressed because it is too large
Load Diff
44
bgpd/Makefile.am
Normal file
44
bgpd/Makefile.am
Normal 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
534
bgpd/Makefile.in
Normal 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
405
bgpd/bgp_advertise.c
Normal 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
178
bgpd/bgp_advertise.h
Normal 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
1186
bgpd/bgp_aspath.c
Normal file
File diff suppressed because it is too large
Load Diff
77
bgpd/bgp_aspath.h
Normal file
77
bgpd/bgp_aspath.h
Normal 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
1838
bgpd/bgp_attr.c
Normal file
File diff suppressed because it is too large
Load Diff
125
bgpd/bgp_attr.h
Normal file
125
bgpd/bgp_attr.h
Normal 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
291
bgpd/bgp_btoa.c
Normal 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
905
bgpd/bgp_clist.c
Normal 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
143
bgpd/bgp_clist.h
Normal 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
629
bgpd/bgp_community.c
Normal 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
68
bgpd/bgp_community.h
Normal 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
648
bgpd/bgp_damp.c
Normal 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
141
bgpd/bgp_damp.h
Normal 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
732
bgpd/bgp_debug.c
Normal 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
113
bgpd/bgp_debug.h
Normal 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
741
bgpd/bgp_dump.c
Normal 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
34
bgpd/bgp_dump.h
Normal 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
641
bgpd/bgp_ecommunity.c
Normal 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
72
bgpd/bgp_ecommunity.h
Normal 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
658
bgpd/bgp_filter.c
Normal 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
31
bgpd/bgp_filter.h
Normal 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
864
bgpd/bgp_fsm.c
Normal 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
42
bgpd/bgp_fsm.h
Normal 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
285
bgpd/bgp_main.c
Normal 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
741
bgpd/bgp_mplsvpn.c
Normal 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
45
bgpd/bgp_mplsvpn.h
Normal 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
381
bgpd/bgp_network.c
Normal 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
23
bgpd/bgp_network.h
Normal 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
1405
bgpd/bgp_nexthop.c
Normal file
File diff suppressed because it is too large
Load Diff
52
bgpd/bgp_nexthop.h
Normal file
52
bgpd/bgp_nexthop.h
Normal 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
793
bgpd/bgp_open.c
Normal 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
69
bgpd/bgp_open.h
Normal 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
2240
bgpd/bgp_packet.c
Normal file
File diff suppressed because it is too large
Load Diff
49
bgpd/bgp_packet.h
Normal file
49
bgpd/bgp_packet.h
Normal 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
93
bgpd/bgp_regex.c
Normal 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
31
bgpd/bgp_regex.h
Normal 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
9053
bgpd/bgp_route.c
Normal file
File diff suppressed because it is too large
Load Diff
159
bgpd/bgp_route.h
Normal file
159
bgpd/bgp_route.h
Normal 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
3207
bgpd/bgp_routemap.c
Normal file
File diff suppressed because it is too large
Load Diff
875
bgpd/bgp_snmp.c
Normal file
875
bgpd/bgp_snmp.c
Normal 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
23
bgpd/bgp_snmp.h
Normal 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
489
bgpd/bgp_table.c
Normal 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
65
bgpd/bgp_table.h
Normal 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
258
bgpd/bgp_view.c
Normal 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
9416
bgpd/bgp_vty.c
Normal file
File diff suppressed because it is too large
Load Diff
21
bgpd/bgp_vty.h
Normal file
21
bgpd/bgp_vty.h
Normal 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
1001
bgpd/bgp_zebra.c
Normal file
File diff suppressed because it is too large
Load Diff
39
bgpd/bgp_zebra.h
Normal file
39
bgpd/bgp_zebra.h
Normal 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
4601
bgpd/bgpd.c
Normal file
File diff suppressed because it is too large
Load Diff
29
bgpd/bgpd.conf.sample
Normal file
29
bgpd/bgpd.conf.sample
Normal 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
77
bgpd/bgpd.conf.sample2
Normal 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
824
bgpd/bgpd.h
Normal 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
1321
config.guess
vendored
Executable file
File diff suppressed because it is too large
Load Diff
367
config.h.in
Normal file
367
config.h.in
Normal 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
1332
config.sub
vendored
Executable file
File diff suppressed because it is too large
Load Diff
873
configure.in
Executable file
873
configure.in
Executable 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
423
depcomp
Executable 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
3
doc/.cvsignore
Normal file
@ -0,0 +1,3 @@
|
||||
Makefile
|
||||
draft-zebra-00.txt
|
||||
zebra.info-*
|
24
doc/BGP-TypeCode
Normal file
24
doc/BGP-TypeCode
Normal 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
90
doc/ChangeLog
Normal 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
14
doc/Makefile.am
Normal 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
482
doc/Makefile.in
Normal 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
238
doc/appendix.texi
Normal 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
510
doc/basic.texi
Normal 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
169
doc/bgpd.8
Normal 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
1288
doc/bgpd.texi
Normal file
File diff suppressed because it is too large
Load Diff
209
doc/draft-zebra-00.ms
Normal file
209
doc/draft-zebra-00.ms
Normal 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
192
doc/filter.texi
Normal 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
218
doc/install.texi
Normal 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
32
doc/ipv6.texi
Normal 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
48
doc/kernel.texi
Normal 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
186
doc/main.texi
Normal 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
127
doc/ospf6d.8
Normal 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
102
doc/ospf6d.texi
Normal 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
131
doc/ospfd.8
Normal 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
345
doc/ospfd.texi
Normal 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
352
doc/overview.texi
Normal 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
52
doc/protocol.texi
Normal 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
212
doc/ripd.8
Normal 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
Loading…
Reference in New Issue
Block a user