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