Merge branch 'master' into PIM_VRF

This commit is contained in:
Donald Sharp 2017-08-02 09:39:38 -04:00 committed by GitHub
commit 0ecfe5bf38
126 changed files with 3233 additions and 4521 deletions

View File

@ -1,4 +1,7 @@
# Developing for PROJECT (DRAFT)
Developing for FRRouting
=========================
## Table of Contents
[TOC]
@ -14,55 +17,57 @@ it's the document that needs to be updated, not reality.
## Git Structure
The master Git for PROJECT resides on Github at
[https://github.com/PROJECT/XXX](https://github.com/PROJECT/XXX)
The master Git for FRRouting resides on Github at
[https://github.com/frrouting/frr](https://github.com/FRRouting/frr)
![git branches continually merging to the left from 3 lanes; float-right](doc/git_branches.svg
"git branch mechanics")
There is one main branch for development and a release branch for each
major release.
There is one main branch for development and a release branch for each major
release.
New contributions are done against the head of the master branch. The CI
systems will pick up the Github Pull Requests or the new patch from
Patchwork, run some basic build and functional tests.
systems will pick up the Github Pull Requests or the new patch from Patchwork,
run some basic build and functional tests.
For each major release (1.0, 1.1 etc) a new release branch is created based
on the master.
For each major release (1.0, 1.1 etc) a new release branch is created based on
the master.
There was an attempt to use a "develop" branch automatically maintained by
the CI system. This is not currently in active use, though the system is
operational. If the "develop" branch is in active use and this paragraph
is still here, this document obviously wasn't updated.
There was an attempt to use a "develop" branch automatically maintained by the
CI system. This is not currently in active use, though the system is
operational. If the "develop" branch is in active use and this paragraph is
still here, this document obviously wasn't updated.
## Programming language, Tools and Libraries
The core of PROJECT is written in C (gcc or clang supported). A few
non-essential scripts are implemented in Perl and Python. PROJECT requires
the following tools to build distribution packages: automake, autoconf,
texinfo, libtool and gawk and various libraries (i.e. libpam and libjson-c).
The core of FRRouting is written in C (gcc or clang supported) and makes use of
GNU compiler extensions. A few non-essential scripts are implemented in Perl
and Python. FRRouting requires the following tools to build distribution
packages: automake, autoconf, texinfo, libtool and gawk and various libraries
(i.e. libpam and libjson-c).
If your contribution requires a new library or other tool, then please
highlight this in your description of the change. Also make sure its
supported by all PROJECT platform OSes or provide a way to build without the
library (potentially without the new feature) on the other platforms.
highlight this in your description of the change. Also make sure its supported
by all FRRouting platform OSes or provide a way to build without the library
(potentially without the new feature) on the other platforms.
Documentation should be written in Tex (.texi) or Markdown (.md) format with
preference on Markdown.
Documentation should be written in Tex (.texi) or Markdown (.md) format with a
preference for Markdown.
## Before Submitting your changes
## Mailing lists
Italicized lists are private.
| Topic | List |
|--------------------------------|------------------------------|
| Development | dev@lists.frrouting.org |
| Users & Operators | frog@lists.frrouting.org |
| Announcements | announce@lists.frrouting.org |
| _Security_ | security@lists.frrouting.org |
| _Technical Steering Committee_ | tsc@lists.frrouting.org |
* Format code (see [Code Styling requirements](#code-styling-requirements))
* Verify and acknowledge license (see [License for contributions](#license-for-contributions))
* Test building with various configurations:
* `buildtest.sh`
* Verify building source distribution:
* `make dist` (and try rebuilding from the resulting tar file)
* Run DejaGNU unit tests:
* `make test`
* Document Regression Runs and plans for continued maintenance of the feature
### Changelog
@ -75,16 +80,45 @@ for the release notes.
## Submitting Patches and Enhancements
### Pre-submission Checklist
* Format code (see [Coding style requirements](#coding-style-requirements))
* Verify and acknowledge license (see [License for contributions](#license-for-contributions))
* Ensure you have properly signed off (see [Signing Off](#signing-off))
* Test building with various configurations:
* `buildtest.sh`
* Verify building source distribution:
* `make dist` (and try rebuilding from the resulting tar file)
* Run unit tests:
* `make test`
* Document Regression Runs and plans for continued maintenance of the feature
### License for contributions
PROJECT is under a “GPLv2 or later” license. Any code submitted must be
FRRouting is under a “GPLv2 or later” license. Any code submitted must be
released under the same license (preferred) or any license which allows
redistribution under this GPLv2 license (eg MIT License).
### Signed-off required
### Signing Off
Submissions to PROJECT require a “Signed-off” in the patch or git commit.
We follow the same standard as the Linux Kernel Development.
Code submitted to FRRouting must be signed off. We have the same requirements
for using the signed-off-by process as the Linux kernel. In short, you must
include a signed-off-by tag in every patch.
`Signed-off-by:` this is a developer's certification that he or she has the
right to submit the patch for inclusion into the project. It is an agreement to
the Developer's Certificate of Origin (below). Code without a proper signoff
can not and will not be merged.
If you are unfamiliar with this process, you should read the [official policy
at kernel.org](http://www.kernel.org/doc/Documentation/SubmittingPatches) and
you might find this article about [participating in the Linux community on the
Linux Foundation
website](http://www.linuxfoundation.org/content/how-participate-linux-community-0)
to be a helpful resource.
In short, when you sign off on a commit, you assert your agreement to all of
the following:
> Developer's Certificate of Origin 1.1
>
@ -112,79 +146,46 @@ We follow the same standard as the Linux Kernel Development.
> maintained indefinitely and may be redistributed consistent with
> this project or the open source license(s) involved.
#### Using this Process
We have the same requirements for using the signed-off-by process as the Linux
kernel. In short, you need to include a signed-off-by tag in every patch:
* `Signed-off-by:` this is a developer's certification that he or she has the
right to submit the patch for inclusion into the project. It is an agreement to
the Developer's Certificate of Origin (above). Code without a proper signoff
cannot be merged into the mainline.
Please make sure to have a `Signed-off-by:` in each commit/patch or the patches
will be rejected until this is added.
If you are unfamiliar with this process, you should read the [official policy
at kernel.org](http://www.kernel.org/doc/Documentation/SubmittingPatches) and
you might find this article about [participating in the Linux community on the
Linux Foundation
website](http://www.linuxfoundation.org/content/how-participate-linux-community-0)
to be a helpful resource.
### Code submission - What do I submit my changes against?
### What do I submit my changes against?
We've documented where we would like to have the different fixes applied at
https://github.com/FRRouting/frr/wiki/Where-Do-I-create-a-Pull-Request-against%3F
If you are unsure where your submission goes, look at that document or ask
the question of a maintainer.
If you are unsure where your submission goes, look at that document or ask a
project maintainer.
### Code submission - Github Pull Request (Strongly Preferred)
### Github pull requests
Preferred submission of code is by using a Github Pull Request against the
Develop branch. Code submitted by Pull Request will have an email generated to
the PROJECT-devel mailing list for review and the submission will be
automatically tested by one or more CI systems. Only after this test succeeds
(and the submission is based on the head of the develop branch), then it will
be automatically merged into the develop branch. In case of failed tests, it is
up to the submitter to either amend the request with further commits or close,
fix and create a new pull request.
The preferred method of submitting changes is a Github pull request. Code
submitted by pull request will be automatically tested by one or more CI
systems. Once the automated tests succeed, other developers will review your
code for quality and correctness. After any concerns are resolved, your code
will be merged into the branch it was submitted against.
Further (manual) code review and discussion happens after the merge into the
develop branch.
### Patch submission via mailing list
### Code submission - Mailing Patch to PROJECT-Devel list
As an alternative submission, a patch can be mailed to the PROJECT-Devel
mailing list. Preferred way to send the patch is using git send-mail. Patches
received on the mailing list will be picked up by Patchwork and tested against
the latest develop branch. After a further ACK by someone on the mailing list,
the patch is then merged into the develop branch.
Further (manual) code review and discussion happens after the merge into the
develop branch.
#### Sending patch to mailing list
As an alternative submission method, a patch can be mailed to the development
mailing list. Patches received on the mailing list will be picked up by
Patchwork and tested against the latest development branch.
The recommended way to send the patch (or series of NN patches) to the list is
by using git send-email as follows (assuming they are the most recent NN
by using `git send-email` as follows (assuming they are the N most recent
commit(s) in your git history:
```
git send-email -NN --annotate --to=XXX-Devel@XXX.org
git send-email -NN --annotate --to=dev@lists.frrouting.org
```
If your commits do not already contain a `Signed-off-by` line, then use the
following version to add it (after making sure to be able to agree to the
Developer Certificate of Origin as outlined above):
following command to add it (after making sure you agree to the Developer
Certificate of Origin as outlined above):
```
git send-email -NN --annotate --signoff --to=XXX-Devel@XXX.org
git send-email -NN --annotate --signoff --to=dev@lists.frrouting.org
```
Submitting multi-commit patches as a Github Pull Request is strongly encouraged
and will allow your changes to merge faster
Submitting multi-commit patches as a Github pull request is **strongly
encouraged** and increases the probability of your patch getting reviewed and
merged in a timely manner.
## After submitting your changes
@ -194,35 +195,34 @@ and will allow your changes to merge faster
less than 2 hrs of the submission. If you dont get the email, then check
status on the github pull request (if submitted by pull request) or on
Patchwork at
[https://patchwork.PROJECT.org](https://patchwork.PROJECT.org) (if
[https://patchwork.frrouting.org](https://patchwork.frrouting.org) (if
submitted as patch to mailing list).
* Please notify PROJECT-Devel mailing list if you think something doesnt
work
* Please notify the development mailing list if you think something doesnt
work.
* If the tests failed:
* In general, expect the community to ignore the submission until the tests
pass.
* It is up to you to fix and resubmit.
* This includes fixing existing dejagnu (“make test”) tests if your
* This includes fixing existing unit (“make test”) tests if your
changes broke or changed them.
* It also includes fixing distribution packages for the failing
platforms (ie if new libraries are required)
* Feel free to ask for help on PROJECT-Devel list
platforms (ie if new libraries are required).
* Feel free to ask for help on the development list.
* Go back to the submission process and repeat until the tests pass.
* If the tests pass:
* If the changes are done as a pull request, then they should be
automatically merged to the develop branch.
* Changes sent to mailing list require a manual ACK to be merged and should
be merged within 2 weeks. If you dont see the merge or any
reason/discussion on PROJECT-Devel, then please ask.
* Wait for reviewers. Someone will review your code or be assigned to
review your code.
* Respond to any comments or concerns the reviewer has.
* After all comments and concerns are addressed, expect your patch to be
merged.
* Watch out for questions on the mailing list. At this time there will be a
manual code review and further (longer) tests by various community members.
* Your submission is done once it is merged to the master branch. (which should
happen every few weeks from the develop branch)
* Your submission is done once it is merged to the master branch.
## Code Styling requirements
## Developer's Guidelines
### File header required for new files added
### Source file header
New files need to have a Copyright header (see [License for
contributions](#license-for-contributions) above) added to the file. Preferred
@ -251,7 +251,7 @@ form of the header is as follows:
#include <zebra.h>
```
### Adding Copyright claims to already existing file
### Adding copyright claims to existing files
When adding copyright claims for modifications to an existing file, please
preface the claim with "Portions: " on a line before it and indent the
@ -264,95 +264,147 @@ Portions:
Copyright (C) 2016 Your name [optional brief change description]
```
### Code styling / format
### Code formatting
Coding style standards in FRR vary depending on location. Pre-existing
code uses GNU coding standards. New code may use Linux kernel coding style.
FRR uses Linux kernel style except where noted below. Code which does not
comply with these style guidelines will not be accepted.
GNU coding style apply to the following parts:
* lib/
* zebra/
* bgpd/
* ospfd/
* ospf6d/
* isisd/
* ripd/
* ripngd/
* vtysh/
Linux kernel coding style applies to:
* nhrpd/
* watchfrr/
* pimd/
* lib/{checksum,hook,imsg-buffer,imsg,libfrr,md5,module,monotime,queue}.[ch]
BSD coding style applies to:
* ldpd/
To assist with compliance, in the project root there is a .clang-format
configuration file which can be used with the `clang-format` tool from the LLVM
project. In the `tools/` directory there is a Python script named `indent.py`
that wraps clang-format and handles some edge cases specific to FRR. If you are
submitting a new file, it is recommended to run that script over the new file
after ensuring that the latest stable release of `clang-format` is in your
PATH.
**Whitespace changes in untouched parts of the code are not acceptable in
patches that change actual code.** To change/fix formatting issues, please
create a separate patch that only does formatting changes and nothing else.
It is acceptable to rewrap entire files to Linux kernel style, but this
**MUST** come as a separate patch that does nothing other than this
reformatting.
#### Style documentation
Kernel and BSD styles are documented externally:
* [https://www.kernel.org/doc/html/latest/process/coding-style.html](https://www.kernel.org/doc/html/latest/process/coding-style.html)
* [http://man.openbsd.org/style](http://man.openbsd.org/style)
#### GNU style
For GNU coding style, Indentation follows the result of invoking GNU indent:
For GNU coding style, use `indent` with the following invocation:
```
indent -nut -nfc1 file_for_submission.c
```
Originally, tabs were used instead of spaces, with tabs are every 8 columns.
However, tab interoperability issues mean space characters are now preferred for
new changes. We generally only clean up whitespace when code is unmaintainable
due to whitespace issues, to minimise merging conflicts.
#### Exceptions
FRR project code comes from a variety of sources, so there are some stylistic
exceptions in place. They are organized here by branch.
**For `master`:**
BSD coding style applies to:
* `ldpd/`
`babeld` uses, approximately, the following style:
* K&R style braces
* Indents are 4 spaces
* Function return types are on their own line
#### Linux kernel & BSD style
**For `stable/3.0` and `stable/2.0`:**
These styles are documented externally:
GNU coding style apply to the following parts:
* [https://www.kernel.org/doc/Documentation/CodingStyle](https://www.kernel.org/doc/Documentation/CodingStyle).
* [http://man.openbsd.org/style](http://man.openbsd.org/style)
* `lib/`
* `zebra/`
* `bgpd/`
* `ospfd/`
* `ospf6d/`
* `isisd/`
* `ripd/`
* `ripngd/`
* `vtysh/`
They are relatively similar but differ in details.
BSD coding style applies to:
pimd deviates from Linux kernel style in using 2 spaces for indentation, with
Tabs replacing 8 spaces, as well as adding a line break between `}` and `else`.
It is acceptable to convert indentation in pimd/ to Linux kernel style, but
please convert an entire file at a time. (Rationale: apart from 2-space
indentation, the styles are sufficiently close to not upset when mixed.)
Unlike GNU style, these styles use tabs, not spaces.
* `ldpd/`
### Compile-Time conditional code
### Documentation
Many users access PROJECT via binary packages from 3rd party sources;
compile-time code puts inclusion/exclusion in the hands of the package
maintainer. Please think very carefully before making code conditional at
compile time, as it increases regression testing, maintenance burdens, and user
confusion. In particular, please avoid gratuitous --enable-… switches to the
configure script - typically code should be good enough to be in PROJECT, or it
shouldnt be there at all.
FRRouting is a large and complex software project developed by many different
people over a long period of time. Without adequate documentation, it can be
exceedingly difficult to understand code segments, APIs and other interfaces.
In the interest of keeping the project healthy and maintainable, you should
make every effort to document your code so that other people can understand
what it does without needing to closely read the code itself.
Some specific guidelines that contributors should follow are:
* Functions exposed in header files should have descriptive comments above
their signatures in the header file. At a minimum, a function comment should
contain information about the return value, parameters, and a general summary
of the function's purpose. Documentation on parameter values can be omitted
if it is (very) obvious what they are used for.
Function comments must follow the style for multiline comments laid out in
the kernel style guide.
Example:
```
/*
* Determines whether or not a string is cool.
*
* @param text - the string to check for coolness
* @param is_clccfc - whether capslock is cruise control for cool
* @return 7 if the text is cool, 0 otherwise
*/
int check_coolness(const char *text, bool is_clccfc);
```
The Javadoc-style annotations are not required, but you should still strive to
make it equally clear what parameters and return values are used for.
* Static functions should have descriptive comments in the same form as above
if what they do is not immediately obvious. Use good engineering judgement
when deciding whether a comment is necessary. If you are unsure, document
your code.
* Global variables, static or not, should have a comment describing their use.
* **For new code in `lib/`, these guidelines are hard requirements.**
If you are contributing code that adds significant user-visible functionality
or introduces a new API, please document it in `doc/`. Markdown and LaTeX are
acceptable formats, although Markdown is currently preferred for new
documentation. This may change in the near future.
Finally, if you come across some code that is undocumented and feel like going
above and beyond, document it! We absolutely appreciate and accept patches that
document previously undocumented code.
### Compile-time conditional code
Many users access FRR via binary packages from 3rd party sources; compile-time
code puts inclusion/exclusion in the hands of the package maintainer. Please
think very carefully before making code conditional at compile time, as it
increases regression testing, maintenance burdens, and user confusion. In
particular, please avoid gratuitous `--enable-…` switches to the configure
script - in general, code should be of high quality and in working condition,
or it shouldnt be in FRR at all.
When code must be compile-time conditional, try have the compiler make it
conditional rather than the C pre-processor - so that it will still be checked
by the compiler, even if disabled. I.e. this:
conditional rather than the C pre-processor so that it will still be checked by
the compiler, even if disabled. For example,
```
if (SOME_SYMBOL)
frobnicate();
```
rather than
is preferred to
```
#ifdef SOME_SYMBOL
@ -363,53 +415,55 @@ frobnicate ();
Note that the former approach requires ensuring that `SOME_SYMBOL` will be
defined (watch your `AC_DEFINE`s).
### Debug-Guards in code
### Debug-guards in code
Debugs are an important methodology to allow developers to fix issues
found in the code after it has been released. The caveat here is
that the developer must remember that people will be using the code
at scale and in ways that can be unexpected for the original implementor.
As such debugs MUST be guarded in such a way that they can be turned off.
This PROJECT has the ability to turn on/off debugs from the CLI and it is
expected that the developer will use this convention to allow control
of their debugs.
Debugging statements are an important methodology to allow developers to fix
issues found in the code after it has been released. The caveat here is that
the developer must remember that people will be using the code at scale and in
ways that can be unexpected for the original implementor. As such debugs
**MUST** be guarded in such a way that they can be turned off. FRR has the
ability to turn on/off debugs from the CLI and it is expected that the
developer will use this convention to allow control of their debugs.
### CLI-Changes
### CLI changes
CLI's are a complicated ugly beast. Additions or changes to the CLI
should use a DEFUN to encapsulate one setting as much as is possible.
Additionally as new DEFUN's are added to the system, documentation
should be provided for the new commands.
CLI's are a complicated ugly beast. Additions or changes to the CLI should use
a DEFUN to encapsulate one setting as much as is possible. Additionally as new
DEFUN's are added to the system, documentation should be provided for the new
commands.
### Backwards Compatibility
As a general principle, changes to CLI and code in the lib/ directory
should be made in a backwards compatible fashion. This means that
changes that are purely stylistic in nature should be avoided, e.g.,
renaming an existing macro or library function name without any
functional change. When adding new parameters to common functions, it is
also good to consider if this too should be done in a backward
compatible fashion, e.g., by preserving the old form in addition to
As a general principle, changes to CLI and code in the lib/ directory should be
made in a backwards compatible fashion. This means that changes that are purely
stylistic in nature should be avoided, e.g., renaming an existing macro or
library function name without any functional change. When adding new parameters
to common functions, it is also good to consider if this too should be done in
a backward compatible fashion, e.g., by preserving the old form in addition to
adding the new form.
This is not to say that minor or even major functional changes to CLI
and common code should be avoided, but rather that the benefit gained
from a change should be weighed against the added cost/complexity to
existing code. Also, that when making such changes, it is good to
preserve compatibility when possible to do so without introducing
maintenance overhead/cost. It is also important to keep in mind,
existing code includes code that may reside in private repositories (and
is yet to be submitted) or code that has yet to be migrated from Quagga
to FRR.
This is not to say that minor or even major functional changes to CLI and
common code should be avoided, but rather that the benefit gained from a change
should be weighed against the added cost/complexity to existing code. Also,
that when making such changes, it is good to preserve compatibility when
possible to do so without introducing maintenance overhead/cost. It is also
important to keep in mind, existing code includes code that may reside in
private repositories (and is yet to be submitted) or code that has yet to be
migrated from Quagga to FRR.
That said, compatibility measures can (and should) be removed when either:
* they become a significant burden, e.g. when data structures change and
the compatibility measure would need a complex adaptation layer or becomes
* they become a significant burden, e.g. when data structures change and the
compatibility measure would need a complex adaptation layer or becomes
flat-out impossible
* some measure of time (dependent on the specific case) has passed, so that
the compatibility grace period is considered expired.
* some measure of time (dependent on the specific case) has passed, so that the
compatibility grace period is considered expired.
In all cases, compatibility pieces should be marked with compiler/preprocessor
annotations to print warnings at compile time, pointing to the appropriate
update path. A `-Werror` build should fail if compatibility bits are used.
### Miscellaneous
When in doubt, follow the guidelines in the Linux kernel style guide, or ask on
the development mailing list / public Slack instance.

View File

@ -1,23 +1,95 @@
## Process this file with automake to produce Makefile.in.
SUBDIRS = lib qpb fpm @ZEBRA@ @LIBRFP@ @RFPTEST@ \
AUTOMAKE_OPTIONS = subdir-objects 1.12
include common.am
AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir) -I$(top_builddir)/lib
AM_CFLAGS = $(WERROR)
DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
LIBCAP = @LIBCAP@
EXTRA_DIST =
BUILT_SOURCES =
CLEANFILES =
examplesdir = $(exampledir)
bin_PROGRAMS =
sbin_PROGRAMS =
noinst_PROGRAMS =
noinst_HEADERS =
noinst_LIBRARIES =
lib_LTLIBRARIES =
module_LTLIBRARIES =
pkginclude_HEADERS =
dist_examples_DATA =
include lib/subdir.am
include zebra/subdir.am
include qpb/subdir.am
include fpm/subdir.am
SUBDIRS = . @LIBRFP@ @RFPTEST@ \
@BGPD@ @RIPD@ @RIPNGD@ @OSPFD@ @OSPF6D@ @LDPD@ \
@ISISD@ @PIMD@ @NHRPD@ @EIGRPD@ @BABELD@ \
@WATCHFRR@ @VTYSH@ @OSPFCLIENT@ @DOC@ m4 @pkgsrcdir@ \
redhat @SOLARIS@ tests tools snapcraft
@WATCHFRR@ @VTYSH@ @OSPFCLIENT@ @DOC@ \
@SOLARIS@ tests tools
DIST_SUBDIRS = lib qpb fpm zebra bgpd ripd ripngd ospfd ospf6d ldpd \
isisd watchfrr vtysh ospfclient doc m4 pkgsrc redhat tests \
DIST_SUBDIRS = . bgpd ripd ripngd ospfd ospf6d ldpd \
isisd watchfrr vtysh ospfclient doc tests \
solaris pimd nhrpd eigrpd bgpd/rfp-example/librfp \
bgpd/rfp-example/rfptest tools snapcraft babeld python \
bgpd/rfp-example/rfptest tools babeld \
# end
EXTRA_DIST = aclocal.m4 SERVICES REPORTING-BUGS \
if PKGSRC
rcdir=@pkgsrcrcdir@
rc_SCRIPTS = \
pkgsrc/bgpd.sh \
pkgsrc/ospf6d.sh \
pkgsrc/ospfd.sh \
pkgsrc/ripd.sh \
pkgsrc/ripngd.sh \
pkgsrc/zebra.sh \
# end
endif
EXTRA_DIST += \
REPORTING-BUGS \
SERVICES \
aclocal.m4 \
update-autotools \
vtysh/Makefile.in vtysh/Makefile.am \
tools/rrcheck.pl tools/rrlookup.pl tools/zc.pl \
tools/zebra.el tools/multiple-bgpd.sh
m4/README.txt \
\
python/clidef.py \
python/clippy/__init__.py \
\
redhat/frr.init \
redhat/frr.service \
redhat/daemons \
redhat/frr.logrotate \
redhat/frr.pam \
redhat/frr.spec \
redhat/README.rpm_build.md \
\
snapcraft/snapcraft.yaml \
snapcraft/README.snap_build.md \
snapcraft/README.usage.md \
snapcraft/extra_version_info.txt \
snapcraft/scripts \
snapcraft/defaults \
snapcraft/helpers \
snapcraft/snap \
\
tools/multiple-bgpd.sh \
tools/rrcheck.pl \
tools/rrlookup.pl \
tools/zc.pl \
tools/zebra.el \
\
vtysh/Makefile.am \
vtysh/Makefile.in \
# end
ACLOCAL_AMFLAGS = -I m4
noinst_HEADERS = defaults.h
noinst_HEADERS += defaults.h

View File

@ -207,8 +207,6 @@ main(int argc, char **argv)
schedule_neighbours_check(5000, 1);
zlog_notice ("BABELd %s starting: vty@%d", BABEL_VERSION, babel_vty_port);
frr_config_fork();
frr_run(master);

View File

@ -55,25 +55,6 @@ static struct {
{0, 0, NULL}
};
static struct {
int str_min_len;
const char *str;
} proto_redistnum_type[ZEBRA_ROUTE_MAX] = {
[ZEBRA_ROUTE_BABEL] = {2, "babel"},
[ZEBRA_ROUTE_BGP] = {2, "bgp"},
[ZEBRA_ROUTE_CONNECT] = {1, "connected"},
[ZEBRA_ROUTE_HSLS] = {1, "hsls"},
[ZEBRA_ROUTE_ISIS] = {1, "isis"},
[ZEBRA_ROUTE_KERNEL] = {1, "kernel"},
[ZEBRA_ROUTE_OLSR] = {2, "olsr"},
[ZEBRA_ROUTE_OSPF] = {2, "ospf"},
[ZEBRA_ROUTE_OSPF6] = {5, "ospf6"},
[ZEBRA_ROUTE_RIP] = {1, "rip"},
[ZEBRA_ROUTE_RIPNG] = {4, "ripng"},
[ZEBRA_ROUTE_STATIC] = {2, "static"},
[ZEBRA_ROUTE_SYSTEM] = {2, "system"},
};
/* Zebra node structure. */
struct cmd_node zebra_node =
{
@ -191,66 +172,46 @@ babel_zebra_read_ipv4 (int command, struct zclient *zclient,
return 0;
}
static int
babel_proto_redistnum(const char *s)
{
int i;
if (! s)
return -1;
int len = strlen(s);
for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
if (len <= (int)strlen(proto_redistnum_type[i].str) &&
strncmp(proto_redistnum_type[i].str, s,
proto_redistnum_type[i].str_min_len) == 0) {
return i;
}
}
return -1;
}
/* [Babel Command] */
DEFUN (babel_redistribute_type,
babel_redistribute_type_cmd,
"redistribute " FRR_REDIST_STR_BABELD,
"Redistribute\n"
FRR_REDIST_HELP_STR_BABELD)
{
int type;
type = babel_proto_redistnum(argv[1]->arg);
if (type < 0) {
vty_out (vty, "Invalid type %s\n", argv[1]->arg);
return CMD_WARNING_CONFIG_FAILED;
}
zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP, type, 0, VRF_DEFAULT);
zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP6, type, 0, VRF_DEFAULT);
return CMD_SUCCESS;
}
/* [Babel Command] */
DEFUN (no_babel_redistribute_type,
no_babel_redistribute_type_cmd,
"no redistribute " FRR_REDIST_STR_BABELD,
"[no] redistribute <ipv4 " FRR_IP_REDIST_STR_BABELD "|ipv6 " FRR_IP6_REDIST_STR_BABELD ">",
NO_STR
"Redistribute\n"
FRR_REDIST_HELP_STR_BABELD)
"Redistribute IPv4 routes\n"
FRR_IP_REDIST_HELP_STR_BABELD
"Redistribute IPv6 routes\n"
FRR_IP6_REDIST_HELP_STR_BABELD)
{
int negate = 0;
int family;
int afi;
int type;
int idx = 0;
type = babel_proto_redistnum(argv[2]->arg);
if (argv_find(argv, argc, "no", &idx))
negate = 1;
argv_find(argv, argc, "redistribute", &idx);
family = str2family(argv[idx + 1]->text);
if (family < 0)
return CMD_WARNING_CONFIG_FAILED;
afi = family2afi(family);
if (!afi)
return CMD_WARNING_CONFIG_FAILED;
type = proto_redistnum(afi, argv[idx + 2]->text);
if (type < 0) {
vty_out (vty, "Invalid type %s\n", argv[2]->arg);
vty_out (vty, "Invalid type %s\n", argv[idx + 2]->arg);
return CMD_WARNING_CONFIG_FAILED;
}
zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE, zclient, AFI_IP, type, 0, VRF_DEFAULT);
zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE, zclient, AFI_IP6, type, 0, VRF_DEFAULT);
/* perhaps should we remove xroutes having the same type... */
if (!negate)
zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, afi, type, 0, VRF_DEFAULT);
else {
zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE, zclient, afi, type, 0, VRF_DEFAULT);
/* perhaps should we remove xroutes having the same type... */
}
return CMD_SUCCESS;
}
@ -374,7 +335,6 @@ void babelz_zebra_init(void)
install_node (&zebra_node, zebra_config_write);
install_element(BABEL_NODE, &babel_redistribute_type_cmd);
install_element(BABEL_NODE, &no_babel_redistribute_type_cmd);
install_element(ENABLE_NODE, &debug_babel_cmd);
install_element(ENABLE_NODE, &no_debug_babel_cmd);
install_element(CONFIG_NODE, &debug_babel_cmd);

View File

@ -76,6 +76,7 @@ static int
babel_config_write (struct vty *vty)
{
int lines = 0;
int afi;
int i;
/* list enabled debug modes */
@ -108,13 +109,17 @@ babel_config_write (struct vty *vty)
/* list enabled interfaces */
lines = 1 + babel_enable_if_config_write (vty);
/* list redistributed protocols */
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
if (i != zclient->redist_default &&
vrf_bitmap_check (zclient->redist[AFI_IP][i], VRF_DEFAULT))
{
vty_out (vty, " redistribute %s\n", zebra_route_string(i));
lines++;
for (afi = AFI_IP; afi <= AFI_IP6; afi++) {
for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
if (i != zclient->redist_default &&
vrf_bitmap_check (zclient->redist[afi][i], VRF_DEFAULT)) {
vty_out (vty, " redistribute %s %s\n",
(afi == AFI_IP) ? "ipv4" : "ipv6",
zebra_route_string(i));
lines++;
}
}
}
lines += config_write_distribute (vty);

View File

@ -9,8 +9,8 @@ debug babel common
router babel
! network wlan0
! network eth0
! redistribute kernel
! no redistribute static
! redistribute ipv4 kernel
! no redistribute ipv6 static
! The defaults are fine for a wireless interface

View File

@ -90,7 +90,6 @@ THE SOFTWARE.
#define BABEL_VTY_PORT 2609
#define BABEL_DEFAULT_CONFIG "babeld.conf"
#define BABEL_VERSION "0.1 for quagga"
/* Values in milliseconds */
#define BABEL_DEFAULT_HELLO_INTERVAL 4000

View File

@ -1677,7 +1677,8 @@ int bgp_mp_reach_parse(struct bgp_attr_parser_args *args,
{
iana_afi_t pkt_afi;
afi_t afi;
safi_t pkt_safi, safi;
iana_safi_t pkt_safi;
safi_t safi;
bgp_size_t nlri_len;
size_t start;
struct stream *s;
@ -1826,7 +1827,8 @@ int bgp_mp_unreach_parse(struct bgp_attr_parser_args *args,
struct stream *s;
iana_afi_t pkt_afi;
afi_t afi;
safi_t pkt_safi, safi;
iana_safi_t pkt_safi;
safi_t safi;
u_int16_t withdraw_len;
struct peer *const peer = args->peer;
struct attr *const attr = args->attr;
@ -2039,7 +2041,7 @@ static int bgp_attr_encap(uint8_t type, struct peer *peer, /* IN */
}
#endif
}
stlv_last->next = tlv;
stlv_last = tlv;
}
if (BGP_ATTR_ENCAP == type) {
@ -2593,7 +2595,7 @@ size_t bgp_packet_mpattr_start(struct stream *s, struct peer *peer, afi_t afi,
{
size_t sizep;
iana_afi_t pkt_afi;
safi_t pkt_safi;
iana_safi_t pkt_safi;
afi_t nh_afi;
/* Set extended bit always to encode the attribute length as 2 bytes */
@ -3280,7 +3282,7 @@ size_t bgp_packet_mpunreach_start(struct stream *s, afi_t afi, safi_t safi)
{
unsigned long attrlen_pnt;
iana_afi_t pkt_afi;
safi_t pkt_safi;
iana_safi_t pkt_safi;
/* Set extended bit always to encode the attribute length as 2 bytes */
stream_putc(s, BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_EXTLEN);

View File

@ -347,6 +347,8 @@ static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd,
if (bgp == NULL) {
if (!use_json)
vty_out(vty, "No BGP process is configured\n");
else
vty_out(vty, "{}\n");
return CMD_WARNING;
}

View File

@ -488,7 +488,7 @@ static int bgp_graceful_restart_timer_expire(struct thread *thread)
/* NSF delete stale route */
for (afi = AFI_IP; afi < AFI_MAX; afi++)
for (safi = SAFI_UNICAST; safi < SAFI_RESERVED_4; safi++)
for (safi = SAFI_UNICAST; safi <= SAFI_MPLS_VPN; safi++)
if (peer->nsf[afi][safi])
bgp_clear_stale_route(peer, afi, safi);
@ -521,7 +521,7 @@ static int bgp_graceful_stale_timer_expire(struct thread *thread)
/* NSF delete stale route */
for (afi = AFI_IP; afi < AFI_MAX; afi++)
for (safi = SAFI_UNICAST; safi < SAFI_RESERVED_4; safi++)
for (safi = SAFI_UNICAST; safi <= SAFI_MPLS_VPN; safi++)
if (peer->nsf[afi][safi])
bgp_clear_stale_route(peer, afi, safi);
@ -1022,7 +1022,7 @@ int bgp_stop(struct peer *peer)
for (afi = AFI_IP; afi < AFI_MAX; afi++)
for (safi = SAFI_UNICAST;
safi < SAFI_RESERVED_4; safi++)
safi <= SAFI_MPLS_VPN; safi++)
peer->nsf[afi][safi] = 0;
}
@ -1425,7 +1425,7 @@ static int bgp_establish(struct peer *peer)
/* graceful restart */
UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT);
for (afi = AFI_IP; afi < AFI_MAX; afi++)
for (safi = SAFI_UNICAST; safi < SAFI_RESERVED_4; safi++) {
for (safi = SAFI_UNICAST; safi <= SAFI_MPLS_VPN; safi++) {
if (peer->afc_nego[afi][safi]
&& CHECK_FLAG(peer->cap, PEER_CAP_RESTART_ADV)
&& CHECK_FLAG(peer->af_cap[afi][safi],

View File

@ -102,6 +102,7 @@ int bgp_maximum_paths_unset(struct bgp *bgp, afi_t afi, safi_t safi,
int bgp_info_nexthop_cmp(struct bgp_info *bi1, struct bgp_info *bi2)
{
int compare;
struct in6_addr addr1, addr2;
compare = IPV4_ADDR_CMP(&bi1->attr->nexthop, &bi2->attr->nexthop);
if (!compare) {
@ -120,13 +121,18 @@ int bgp_info_nexthop_cmp(struct bgp_info *bi1, struct bgp_info *bi2)
&bi2->attr->mp_nexthop_global);
break;
case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
compare = IPV6_ADDR_CMP(
&bi1->attr->mp_nexthop_global,
&bi2->attr->mp_nexthop_global);
addr1 = (bi1->attr->mp_nexthop_prefer_global) ?
bi1->attr->mp_nexthop_global
: bi1->attr->mp_nexthop_local;
addr2 = (bi2->attr->mp_nexthop_prefer_global) ?
bi2->attr->mp_nexthop_global
: bi2->attr->mp_nexthop_local;
if (!bi1->attr->mp_nexthop_prefer_global &&
!bi2->attr->mp_nexthop_prefer_global)
compare = !(bi1->peer->ifindex == bi2->peer->ifindex);
if (!compare)
compare = IPV6_ADDR_CMP(
&bi1->attr->mp_nexthop_local,
&bi2->attr->mp_nexthop_local);
compare = IPV6_ADDR_CMP(&addr1, &addr2);
break;
}
}

View File

@ -374,6 +374,8 @@ int bgp_show_mpls_vpn(struct vty *vty, afi_t afi, struct prefix_rd *prd,
if (bgp == NULL) {
if (!use_json)
vty_out(vty, "No BGP process is configured\n");
else
vty_out(vty, "{}\n");
return CMD_WARNING;
}

View File

@ -298,7 +298,8 @@ static int bgp_capability_orf_entry(struct peer *peer,
u_char num;
iana_afi_t pkt_afi;
afi_t afi;
safi_t pkt_safi, safi;
iana_safi_t pkt_safi;
safi_t safi;
u_char type;
u_char mode;
u_int16_t sm_cap = 0; /* capability send-mode receive */
@ -466,7 +467,7 @@ static int bgp_capability_restart(struct peer *peer,
afi_t afi;
safi_t safi;
iana_afi_t pkt_afi = stream_getw(s);
safi_t pkt_safi = stream_getc(s);
iana_safi_t pkt_safi = stream_getc(s);
u_char flag = stream_getc(s);
/* Convert AFI, SAFI to internal values, check. */
@ -543,7 +544,7 @@ static int bgp_capability_addpath(struct peer *peer,
afi_t afi;
safi_t safi;
iana_afi_t pkt_afi = stream_getw(s);
safi_t pkt_safi = stream_getc(s);
iana_safi_t pkt_safi = stream_getc(s);
u_char send_receive = stream_getc(s);
if (bgp_debug_neighbor_events(peer))
@ -600,7 +601,8 @@ static int bgp_capability_enhe(struct peer *peer, struct capability_header *hdr)
while (stream_get_getp(s) + 6 <= end) {
iana_afi_t pkt_afi = stream_getw(s);
afi_t afi;
safi_t safi, pkt_safi = stream_getw(s);
iana_safi_t pkt_safi = stream_getw(s);
safi_t safi;
iana_afi_t pkt_nh_afi = stream_getw(s);
afi_t nh_afi;
@ -1199,7 +1201,7 @@ static void bgp_open_capability_orf(struct stream *s, struct peer *peer,
unsigned long numberp;
int number_of_orfs = 0;
iana_afi_t pkt_afi;
safi_t pkt_safi;
iana_safi_t pkt_safi;
/* Convert AFI, SAFI to values for packet. */
bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi, &pkt_safi);
@ -1264,7 +1266,8 @@ void bgp_open_capability(struct stream *s, struct peer *peer)
unsigned long cp, capp, rcapp;
iana_afi_t pkt_afi;
afi_t afi;
safi_t safi, pkt_safi;
safi_t safi;
iana_safi_t pkt_safi;
as_t local_as;
u_int32_t restart_time;
u_char afi_safi_count = 0;

View File

@ -29,9 +29,9 @@ struct capability_header {
/* Generic MP capability data */
struct capability_mp_data {
iana_afi_t afi;
uint16_t afi; /* iana_afi_t */
u_char reserved;
safi_t safi;
uint8_t safi; /* iana_safi_t */
};
struct capability_as4 {

View File

@ -142,7 +142,7 @@ static struct stream *bgp_update_packet_eor(struct peer *peer, afi_t afi,
{
struct stream *s;
iana_afi_t pkt_afi;
safi_t pkt_safi;
iana_safi_t pkt_safi;
if (DISABLE_BGP_ANNOUNCE)
return NULL;
@ -671,7 +671,7 @@ void bgp_route_refresh_send(struct peer *peer, afi_t afi, safi_t safi,
struct bgp_filter *filter;
int orf_refresh = 0;
iana_afi_t pkt_afi;
safi_t pkt_safi;
iana_safi_t pkt_safi;
if (DISABLE_BGP_ANNOUNCE)
return;
@ -761,7 +761,7 @@ void bgp_capability_send(struct peer *peer, afi_t afi, safi_t safi,
{
struct stream *s;
iana_afi_t pkt_afi;
safi_t pkt_safi;
iana_safi_t pkt_safi;
/* Convert AFI, SAFI to values for packet. */
bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi, &pkt_safi);
@ -1338,8 +1338,9 @@ int bgp_nlri_parse(struct peer *peer, struct attr *attr,
packet);
case SAFI_EVPN:
return bgp_nlri_parse_evpn(peer, attr, packet, mp_withdraw);
default:
return -1;
}
return -1;
}
/* Parse BGP Update packet and make attribute object. */
@ -1697,7 +1698,8 @@ static void bgp_route_refresh_receive(struct peer *peer, bgp_size_t size)
{
iana_afi_t pkt_afi;
afi_t afi;
safi_t pkt_safi, safi;
iana_safi_t pkt_safi;
safi_t safi;
struct stream *s;
struct peer_af *paf;
struct update_group *updgrp;
@ -1965,7 +1967,8 @@ static int bgp_capability_msg_parse(struct peer *peer, u_char *pnt,
u_char action;
iana_afi_t pkt_afi;
afi_t afi;
safi_t pkt_safi, safi;
iana_safi_t pkt_safi;
safi_t safi;
end = pnt + length;

View File

@ -2078,7 +2078,7 @@ static wq_item_status bgp_process_main(struct work_queue *wq, void *data)
vnc_import_bgp_add_route(bgp, p, old_select);
vnc_import_bgp_exterior_add_route(bgp, p, old_select);
#endif
if (bgp_fibupd_safi(safi) && !bgp->name
if (bgp_fibupd_safi(safi)
&& !bgp_option_check(BGP_OPT_NO_FIB)
&& new_select->type == ZEBRA_ROUTE_BGP
&& new_select->sub_type == BGP_ROUTE_NORMAL)
@ -2288,7 +2288,7 @@ int bgp_maximum_prefix_overflow(struct peer *peer, afi_t afi, safi_t safi,
int always)
{
iana_afi_t pkt_afi;
safi_t pkt_safi;
iana_safi_t pkt_safi;
if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
return 0;
@ -8257,6 +8257,8 @@ static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
if (bgp == NULL) {
if (!use_json)
vty_out(vty, "No BGP process is configured\n");
else
vty_out(vty, "{}\n");
return CMD_WARNING;
}
@ -8617,8 +8619,16 @@ static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str,
int prefix_check, enum bgp_path_type pathtype,
u_char use_json)
{
if (!bgp)
if (!bgp) {
bgp = bgp_get_default();
if (!bgp) {
if (!use_json)
vty_out(vty, "No BGP process is configured\n");
else
vty_out(vty, "{}\n");
return CMD_WARNING;
}
}
/* labeled-unicast routes live in the unicast table */
if (safi == SAFI_LABELED_UNICAST)

View File

@ -700,6 +700,7 @@ struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp)
int send_attr_printed = 0;
int num_pfx = 0;
int addpath_encode = 0;
int addpath_overhead = 0;
u_int32_t addpath_tx_id = 0;
struct prefix_rd *prd = NULL;
mpls_label_t label = MPLS_INVALID_LABEL;
@ -721,6 +722,7 @@ struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp)
bpacket_attr_vec_arr_reset(&vecarr);
addpath_encode = bgp_addpath_encode_tx(peer, afi, safi);
addpath_overhead = addpath_encode ? BGP_ADDPATH_ID_LEN : 0;
adv = BGP_ADV_FIFO_HEAD(&subgrp->sync->update);
while (adv) {
@ -732,8 +734,8 @@ struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp)
space_remaining = STREAM_CONCAT_REMAIN(s, snlri, STREAM_SIZE(s))
- BGP_MAX_PACKET_SIZE_OVERFLOW;
space_needed = BGP_NLRI_LENGTH + bgp_packet_mpattr_prefix_size(
afi, safi, &rn->p);
space_needed = BGP_NLRI_LENGTH + addpath_overhead +
bgp_packet_mpattr_prefix_size(afi, safi, &rn->p);
/* When remaining space can't include NLRI and it's length. */
if (space_remaining < space_needed)
@ -777,9 +779,9 @@ struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp)
space_remaining =
STREAM_CONCAT_REMAIN(s, snlri, STREAM_SIZE(s))
- BGP_MAX_PACKET_SIZE_OVERFLOW;
space_needed =
BGP_NLRI_LENGTH + bgp_packet_mpattr_prefix_size(
afi, safi, &rn->p);
space_needed = BGP_NLRI_LENGTH + addpath_overhead +
bgp_packet_mpattr_prefix_size(afi, safi,
&rn->p);
/* If the attributes alone do not leave any room for
* NLRI then
@ -843,7 +845,7 @@ struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp)
send_attr_str);
if (!stream_empty(snlri)) {
iana_afi_t pkt_afi;
safi_t pkt_safi;
iana_safi_t pkt_safi;
pkt_afi = afi_int2iana(afi);
pkt_safi = safi_int2iana(safi);
@ -936,6 +938,7 @@ struct bpacket *subgroup_withdraw_packet(struct update_subgroup *subgrp)
int space_needed = 0;
int num_pfx = 0;
int addpath_encode = 0;
int addpath_overhead = 0;
u_int32_t addpath_tx_id = 0;
struct prefix_rd *prd = NULL;
@ -952,6 +955,7 @@ struct bpacket *subgroup_withdraw_packet(struct update_subgroup *subgrp)
s = subgrp->work;
stream_reset(s);
addpath_encode = bgp_addpath_encode_tx(peer, afi, safi);
addpath_overhead = addpath_encode ? BGP_ADDPATH_ID_LEN : 0;
while ((adv = BGP_ADV_FIFO_HEAD(&subgrp->sync->withdraw)) != NULL) {
assert(adv->rn);
@ -962,7 +966,7 @@ struct bpacket *subgroup_withdraw_packet(struct update_subgroup *subgrp)
space_remaining =
STREAM_REMAIN(s) - BGP_MAX_PACKET_SIZE_OVERFLOW;
space_needed =
BGP_NLRI_LENGTH + BGP_TOTAL_ATTR_LEN
BGP_NLRI_LENGTH + addpath_overhead + BGP_TOTAL_ATTR_LEN
+ bgp_packet_mpattr_prefix_size(afi, safi, &rn->p);
if (space_remaining < space_needed)
@ -985,7 +989,7 @@ struct bpacket *subgroup_withdraw_packet(struct update_subgroup *subgrp)
/* If first time, format the MP_UNREACH header */
if (first_time) {
iana_afi_t pkt_afi;
safi_t pkt_safi;
iana_safi_t pkt_safi;
pkt_afi = afi_int2iana(afi);
pkt_safi = safi_int2iana(safi);

View File

@ -51,6 +51,8 @@ int show_adj_route_vpn(struct vty *vty, struct peer *peer,
if (bgp == NULL) {
if (!use_json)
vty_out(vty, "No BGP process is configured\n");
else
vty_out(vty, "{}\n");
return CMD_WARNING;
}

View File

@ -78,6 +78,10 @@ static enum node_type bgp_node_type(afi_t afi, safi_t safi)
case SAFI_MPLS_VPN:
return BGP_VPNV4_NODE;
break;
default:
/* not expected */
return BGP_IPV4_NODE;
break;
}
break;
case AFI_IP6:
@ -94,6 +98,10 @@ static enum node_type bgp_node_type(afi_t afi, safi_t safi)
case SAFI_MPLS_VPN:
return BGP_VPNV6_NODE;
break;
default:
/* not expected */
return BGP_IPV4_NODE;
break;
}
break;
case AFI_L2VPN:
@ -4201,8 +4209,15 @@ DEFUN (neighbor_attr_unchanged,
"Med attribute\n")
{
int idx = 0;
char *peer = argv[1]->arg;
char *peer_str = argv[1]->arg;
struct peer *peer;
u_int16_t flags = 0;
afi_t afi = bgp_node_afi(vty);
safi_t safi = bgp_node_safi(vty);
peer = peer_and_group_lookup_vty(vty, peer_str);
if (!peer)
return CMD_WARNING_CONFIG_FAILED;
if (argv_find(argv, argc, "as-path", &idx))
SET_FLAG(flags, PEER_FLAG_AS_PATH_UNCHANGED);
@ -4213,15 +4228,35 @@ DEFUN (neighbor_attr_unchanged,
if (argv_find(argv, argc, "med", &idx))
SET_FLAG(flags, PEER_FLAG_MED_UNCHANGED);
if (!flags) // no flags means all of them!
{
/* no flags means all of them! */
if (!flags) {
SET_FLAG(flags, PEER_FLAG_AS_PATH_UNCHANGED);
SET_FLAG(flags, PEER_FLAG_NEXTHOP_UNCHANGED);
SET_FLAG(flags, PEER_FLAG_MED_UNCHANGED);
} else {
if (!CHECK_FLAG(flags, PEER_FLAG_AS_PATH_UNCHANGED) &&
peer_af_flag_check(peer, afi, safi,
PEER_FLAG_AS_PATH_UNCHANGED)) {
peer_af_flag_unset_vty(vty, peer_str, afi, safi,
PEER_FLAG_AS_PATH_UNCHANGED);
}
if (!CHECK_FLAG(flags, PEER_FLAG_NEXTHOP_UNCHANGED) &&
peer_af_flag_check(peer, afi, safi,
PEER_FLAG_NEXTHOP_UNCHANGED)) {
peer_af_flag_unset_vty(vty, peer_str, afi, safi,
PEER_FLAG_NEXTHOP_UNCHANGED);
}
if (!CHECK_FLAG(flags, PEER_FLAG_MED_UNCHANGED) &&
peer_af_flag_check(peer, afi, safi,
PEER_FLAG_MED_UNCHANGED)) {
peer_af_flag_unset_vty(vty, peer_str, afi, safi,
PEER_FLAG_MED_UNCHANGED);
}
}
return peer_af_flag_set_vty(vty, peer, bgp_node_afi(vty),
bgp_node_safi(vty), flags);
return peer_af_flag_set_vty(vty, peer_str, afi, safi, flags);
}
ALIAS_HIDDEN(
@ -7052,12 +7087,6 @@ static void bgp_show_summary_afi_safi(struct vty *vty, struct bgp *bgp, int afi,
json);
}
safi++;
if (safi == SAFI_RESERVED_4
|| safi
== SAFI_RESERVED_5) /* handle special
cases to match
zebra.h */
safi++;
if (!safi_wildcard)
safi = SAFI_MAX;
}

View File

@ -269,8 +269,6 @@ static int bgp_interface_delete(int command, struct zclient *zclient,
if (!ifp) /* This may happen if we've just unregistered for a VRF. */
return 0;
ifp->ifindex = IFINDEX_DELETED;
if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("Rx Intf del VRF %u IF %s", vrf_id, ifp->name);
@ -279,6 +277,8 @@ static int bgp_interface_delete(int command, struct zclient *zclient,
return 0;
bgp_update_interface_nbrs(bgp, ifp, NULL);
ifp->ifindex = IFINDEX_DELETED;
return 0;
}

View File

@ -611,8 +611,8 @@ int bgp_listen_limit_unset(struct bgp *bgp)
return 0;
}
int bgp_map_afi_safi_iana2int(iana_afi_t pkt_afi, safi_t pkt_safi, afi_t *afi,
safi_t *safi)
int bgp_map_afi_safi_iana2int(iana_afi_t pkt_afi, iana_safi_t pkt_safi,
afi_t *afi, safi_t *safi)
{
/* Map from IANA values to internal values, return error if
* values are unrecognized.
@ -626,7 +626,7 @@ int bgp_map_afi_safi_iana2int(iana_afi_t pkt_afi, safi_t pkt_safi, afi_t *afi,
}
int bgp_map_afi_safi_int2iana(afi_t afi, safi_t safi, iana_afi_t *pkt_afi,
safi_t *pkt_safi)
iana_safi_t *pkt_safi)
{
/* Map from internal values to IANA values, return error if
* internal values are bad (unexpected).
@ -746,7 +746,7 @@ static unsigned int peer_hash_key_make(void *p)
return sockunion_hash(&peer->su);
}
static int peer_hash_cmp(const void *p1, const void *p2)
static int peer_hash_same(const void *p1, const void *p2)
{
const struct peer *peer1 = p1;
const struct peer *peer2 = p2;
@ -1842,7 +1842,7 @@ static void peer_nsf_stop(struct peer *peer)
UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_MODE);
for (afi = AFI_IP; afi < AFI_MAX; afi++)
for (safi = SAFI_UNICAST; safi < SAFI_RESERVED_4; safi++)
for (safi = SAFI_UNICAST; safi <= SAFI_MPLS_VPN; safi++)
peer->nsf[afi][safi] = 0;
if (peer->t_gr_restart) {
@ -2757,7 +2757,8 @@ static struct bgp *bgp_create(as_t *as, const char *name,
XSTRDUP(MTYPE_BGP_PEER_HOST, "Static announcement");
bgp->peer = list_new();
bgp->peer->cmp = (int (*)(void *, void *))peer_cmp;
bgp->peerhash = hash_create(peer_hash_key_make, peer_hash_cmp, NULL);
bgp->peerhash = hash_create(peer_hash_key_make, peer_hash_same, NULL);
bgp->peerhash->max_size = BGP_PEER_MAX_HASH_SIZE;
bgp->group = list_new();
bgp->group->cmp = (int (*)(void *, void *))peer_group_cmp;
@ -6926,36 +6927,34 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp,
bgp_config_write_filter(vty, peer, afi, safi, write);
/* atribute-unchanged. */
if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_AS_PATH_UNCHANGED)
|| CHECK_FLAG(peer->af_flags[afi][safi],
PEER_FLAG_NEXTHOP_UNCHANGED)
|| CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MED_UNCHANGED)) {
if (peergroup_af_flag_check(peer, afi, safi,
PEER_FLAG_AS_PATH_UNCHANGED)
&& peergroup_af_flag_check(peer, afi, safi,
PEER_FLAG_NEXTHOP_UNCHANGED)
&& peergroup_af_flag_check(peer, afi, safi,
PEER_FLAG_MED_UNCHANGED)) {
afi_header_vty_out(
vty, afi, safi, write,
" neighbor %s attribute-unchanged\n", addr);
} else {
if (peer_af_flag_check(peer, afi, safi, PEER_FLAG_AS_PATH_UNCHANGED) ||
peer_af_flag_check(peer, afi, safi, PEER_FLAG_NEXTHOP_UNCHANGED) ||
peer_af_flag_check(peer, afi, safi, PEER_FLAG_MED_UNCHANGED)) {
if (!peer_group_active(peer) ||
peergroup_af_flag_check(peer, afi, safi,
PEER_FLAG_AS_PATH_UNCHANGED) ||
peergroup_af_flag_check(peer, afi, safi,
PEER_FLAG_NEXTHOP_UNCHANGED) ||
peergroup_af_flag_check(peer, afi, safi,
PEER_FLAG_MED_UNCHANGED)) {
afi_header_vty_out(
vty, afi, safi, write,
" neighbor %s attribute-unchanged%s%s%s\n",
addr,
peergroup_af_flag_check(
peer_af_flag_check(
peer, afi, safi,
PEER_FLAG_AS_PATH_UNCHANGED)
? " as-path"
: "",
peergroup_af_flag_check(
peer_af_flag_check(
peer, afi, safi,
PEER_FLAG_NEXTHOP_UNCHANGED)
? " next-hop"
: "",
peergroup_af_flag_check(peer, afi, safi,
PEER_FLAG_MED_UNCHANGED)
peer_af_flag_check(peer, afi, safi,
PEER_FLAG_MED_UNCHANGED)
? " med"
: "");
}

View File

@ -36,6 +36,7 @@
#include "bitfield.h"
#define BGP_MAX_HOSTNAME 64 /* Linux max, is larger than most other sys */
#define BGP_PEER_MAX_HASH_SIZE 16384
/* Default interval for IPv6 RAs when triggered by BGP unnumbered neighbor. */
#define BGP_UNNUM_DEFAULT_RA_INTERVAL 10
@ -922,10 +923,10 @@ DECLARE_QOBJ_TYPE(peer)
stream. */
struct bgp_nlri {
/* AFI. */
afi_t afi;
uint16_t afi; /* iana_afi_t */
/* SAFI. */
safi_t safi;
uint8_t safi; /* iana_safi_t */
/* Pointer to NLRI byte stream. */
u_char *nlri;
@ -1381,10 +1382,10 @@ extern void bgp_route_map_terminate(void);
extern int peer_cmp(struct peer *p1, struct peer *p2);
extern int bgp_map_afi_safi_iana2int(iana_afi_t pkt_afi, safi_t pkt_safi,
extern int bgp_map_afi_safi_iana2int(iana_afi_t pkt_afi, iana_safi_t pkt_safi,
afi_t *afi, safi_t *safi);
extern int bgp_map_afi_safi_int2iana(afi_t afi, safi_t safi,
iana_afi_t *pkt_afi, safi_t *pkt_safi);
iana_afi_t *pkt_afi, iana_safi_t *pkt_safi);
extern struct peer_af *peer_af_create(struct peer *, afi_t, safi_t);
extern struct peer_af *peer_af_find(struct peer *, afi_t, safi_t);

View File

@ -135,10 +135,10 @@ struct rfapi_nve_group_cfg *bgp_rfapi_cfg_match_group(struct rfapi_cfg *hc,
switch (vn->family) {
case AF_INET:
rt_vn = &(hc->nve_groups_vn[AFI_IP]);
rt_vn = hc->nve_groups_vn[AFI_IP];
break;
case AF_INET6:
rt_vn = &(hc->nve_groups_vn[AFI_IP6]);
rt_vn = hc->nve_groups_vn[AFI_IP6];
break;
default:
return NULL;
@ -146,10 +146,10 @@ struct rfapi_nve_group_cfg *bgp_rfapi_cfg_match_group(struct rfapi_cfg *hc,
switch (un->family) {
case AF_INET:
rt_un = &(hc->nve_groups_un[AFI_IP]);
rt_un = hc->nve_groups_un[AFI_IP];
break;
case AF_INET6:
rt_un = &(hc->nve_groups_un[AFI_IP6]);
rt_un = hc->nve_groups_un[AFI_IP6];
break;
default:
return NULL;
@ -2503,7 +2503,7 @@ DEFUN (vnc_nve_group_prefix,
VTY_DECLVAR_CONTEXT(bgp, bgp);
VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
struct prefix p;
int afi;
afi_t afi;
struct route_table *rt;
struct route_node *rn;
int is_un_prefix = 0;
@ -2527,10 +2527,10 @@ DEFUN (vnc_nve_group_prefix,
}
if (argv[1]->arg[0] == 'u') {
rt = &(bgp->rfapi_cfg->nve_groups_un[afi]);
rt = bgp->rfapi_cfg->nve_groups_un[afi];
is_un_prefix = 1;
} else {
rt = &(bgp->rfapi_cfg->nve_groups_vn[afi]);
rt = bgp->rfapi_cfg->nve_groups_vn[afi];
}
rn = route_node_get(rt, &p); /* NB locks node */
@ -3830,7 +3830,7 @@ void bgp_rfapi_cfg_init(void)
struct rfapi_cfg *bgp_rfapi_cfg_new(struct rfapi_rfp_cfg *cfg)
{
struct rfapi_cfg *h;
int afi;
afi_t afi;
h = (struct rfapi_cfg *)XCALLOC(MTYPE_RFAPI_CFG,
sizeof(struct rfapi_cfg));
@ -3838,14 +3838,9 @@ struct rfapi_cfg *bgp_rfapi_cfg_new(struct rfapi_rfp_cfg *cfg)
h->nve_groups_sequential = list_new();
assert(h->nve_groups_sequential);
for (afi = AFI_IP; afi < AFI_MAX; afi++) {
/* ugly, to deal with addition of delegates, part of 0.99.24.1
* merge */
h->nve_groups_vn[afi].delegate =
route_table_get_default_delegate();
h->nve_groups_un[afi].delegate =
route_table_get_default_delegate();
h->nve_groups_vn[afi] = route_table_init();
h->nve_groups_un[afi] = route_table_init();
}
h->default_response_lifetime =
BGP_VNC_DEFAULT_RESPONSE_LIFETIME_DEFAULT;
@ -3885,6 +3880,7 @@ struct rfapi_cfg *bgp_rfapi_cfg_new(struct rfapi_rfp_cfg *cfg)
void bgp_rfapi_cfg_destroy(struct bgp *bgp, struct rfapi_cfg *h)
{
afi_t afi;
if (h == NULL)
return;
@ -3901,6 +3897,10 @@ void bgp_rfapi_cfg_destroy(struct bgp *bgp, struct rfapi_cfg *h)
ecommunity_free(&h->default_rt_import_list);
if (h->default_rfp_cfg)
XFREE(MTYPE_RFAPI_RFP_GROUP_CFG, h->default_rfp_cfg);
for (afi = AFI_IP; afi < AFI_MAX; afi++) {
route_table_finish(h->nve_groups_vn[afi]);
route_table_finish(h->nve_groups_un[afi]);
}
XFREE(MTYPE_RFAPI_CFG, h);
}
@ -4571,7 +4571,8 @@ int bgp_rfapi_cfg_write(struct vty *vty, struct bgp *bgp)
void bgp_rfapi_show_summary(struct bgp *bgp, struct vty *vty)
{
struct rfapi_cfg *hc = bgp->rfapi_cfg;
int afi, type, redist = 0;
afi_t afi;
int type, redist = 0;
char tmp[40];
if (hc == NULL)
return;

View File

@ -135,8 +135,8 @@ struct rfapi_cfg {
struct list *l2_groups; /* rfapi_l2_group_cfg list */
/* three views into the same collection of rfapi_nve_group_cfg */
struct list *nve_groups_sequential;
struct route_table nve_groups_vn[AFI_MAX];
struct route_table nve_groups_un[AFI_MAX];
struct route_table *nve_groups_vn[AFI_MAX];
struct route_table *nve_groups_un[AFI_MAX];
/*
* For Single VRF export to ordinary routing protocols. This is

View File

@ -205,7 +205,7 @@ static int rfapi_find_node(struct bgp *bgp, struct rfapi_ip_addr *vn_addr,
struct prefix p;
struct route_node *rn;
int rc;
int afi;
afi_t afi;
if (!bgp) {
return ENXIO;
@ -224,7 +224,7 @@ static int rfapi_find_node(struct bgp *bgp, struct rfapi_ip_addr *vn_addr,
if ((rc = rfapiRaddr2Qprefix(un_addr, &p)))
return rc;
rn = route_node_lookup(&h->un[afi], &p);
rn = route_node_lookup(h->un[afi], &p);
if (!rn)
return ENOENT;
@ -1415,7 +1415,7 @@ int rfapi_init_and_open(struct bgp *bgp, struct rfapi_descriptor *rfd,
assert(afi_vn && afi_un);
assert(!rfapiRaddr2Qprefix(&rfd->un_addr, &pfx_un));
rn = route_node_get(&(h->un[afi_un]), &pfx_un);
rn = route_node_get(h->un[afi_un], &pfx_un);
assert(rn);
rfd->next = rn->info;
rn->info = rfd;
@ -2367,7 +2367,7 @@ int rfapi_register(void *handle, struct rfapi_ip_prefix *prefix,
struct prefix p;
struct prefix *pfx_ip = NULL;
struct prefix_rd prd;
int afi;
afi_t afi;
struct prefix pfx_mac_buf;
struct prefix *pfx_mac = NULL;
struct prefix pfx_vn_buf;

View File

@ -3872,6 +3872,10 @@ rfapiBgpInfoFilteredImportFunction(safi_t safi)
case SAFI_ENCAP:
return rfapiBgpInfoFilteredImportEncap;
default:
/* not expected */
return NULL;
}
zlog_err("%s: bad safi %d", __func__, safi);
return NULL;
@ -4248,7 +4252,7 @@ static void rfapiBgpTableFilteredImport(struct bgp *bgp,
struct rfapi *bgp_rfapi_new(struct bgp *bgp)
{
struct rfapi *h;
int afi;
afi_t afi;
struct rfapi_rfp_cfg *cfg = NULL;
struct rfapi_rfp_cb_methods *cbm = NULL;
@ -4257,9 +4261,7 @@ struct rfapi *bgp_rfapi_new(struct bgp *bgp)
h = (struct rfapi *)XCALLOC(MTYPE_RFAPI, sizeof(struct rfapi));
for (afi = AFI_IP; afi < AFI_MAX; afi++) {
/* ugly, to deal with addition of delegates, part of 0.99.24.1
* merge */
h->un[afi].delegate = route_table_get_default_delegate();
h->un[afi] = route_table_init();
}
/*
@ -4292,6 +4294,8 @@ struct rfapi *bgp_rfapi_new(struct bgp *bgp)
void bgp_rfapi_destroy(struct bgp *bgp, struct rfapi *h)
{
afi_t afi;
if (bgp == NULL || h == NULL)
return;
@ -4327,6 +4331,11 @@ void bgp_rfapi_destroy(struct bgp *bgp, struct rfapi *h)
if (h->rfp != NULL)
rfp_stop(h->rfp);
for (afi = AFI_IP; afi < AFI_MAX; afi++) {
route_table_finish(h->un[afi]);
}
XFREE(MTYPE_RFAPI_IMPORTTABLE, h->it_ce);
XFREE(MTYPE_RFAPI, h);
}

View File

@ -171,7 +171,7 @@ struct rfapi_global_stats {
* check vn address to get exact match.
*/
struct rfapi {
struct route_table un[AFI_MAX];
struct route_table *un[AFI_MAX];
struct rfapi_import_table *imports; /* IPv4, IPv6 */
struct list descriptors; /* debug & resolve-nve imports */

View File

@ -2236,9 +2236,12 @@ void rfapiRibShowResponsesSummary(void *stream)
struct rfapi_descriptor *rfd;
struct listnode *node;
if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
return;
if (!bgp) {
fp(out, "Unable to find default BGP instance\n");
return;
}
fp(out, "%-24s ", "Responses: (Prefixes)");
fp(out, "%-8s %-8u ", "Active:", bgp->rfapi->rib_prefix_count_total);
@ -2388,6 +2391,11 @@ void rfapiRibShowResponses(void *stream, struct prefix *pfx_match,
if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
return;
if (!bgp) {
fp(out, "Unable to find default BGP instance\n");
return;
}
/*
* loop over NVEs
*/

View File

@ -8,12 +8,21 @@ am__v_CLIPPY_ = $(am__v_CLIPPY_$(AM_DEFAULT_VERBOSITY))
am__v_CLIPPY_0 = @echo " CLIPPY " $@;
am__v_CLIPPY_1 =
SUFFIXES = _clippy.c
CLIPPY_DEPS = $(HOSTTOOLS)lib/clippy $(top_srcdir)/python/clidef.py
SUFFIXES = _clippy.c .proto .pb-c.c .pb-c.h .pb.h
.c_clippy.c:
$(AM_V_at)$(MAKE) -C $(top_builddir)/$(CLIPPYDIR) clippy
$(AM_V_CLIPPY)$(top_builddir)/$(CLIPPYDIR)/clippy $(top_srcdir)/python/clidef.py $< > $@.tmp
@{ test -x $(top_builddir)/$(HOSTTOOLS)lib/clippy || $(MAKE) -C $(top_builddir)/$(HOSTTOOLS) lib/clippy; }
$(AM_V_CLIPPY)$(top_builddir)/$(HOSTTOOLS)lib/clippy $(top_srcdir)/python/clidef.py $< > $@.tmp
@{ test -f $@ && diff $@.tmp $@ >/dev/null 2>/dev/null; } && rm $@.tmp || mv $@.tmp $@
## automake's "ylwrap" is a great piece of GNU software... not.
.l.c:
$(AM_V_LEX)$(am__skiplex) $(LEXCOMPILE) $<
.y.c:
$(AM_V_YACC)$(am__skipyacc) $(YACCCOMPILE) $<
if HAVE_PROTOBUF
# Uncomment to use an non-system version of libprotobuf-c.
@ -27,16 +36,19 @@ Q_PROTOBUF_C_CLIENT_LDOPTS=-lprotobuf-c
Q_PROTOC=protoc
Q_PROTOC_C=protoc-c
Q_PROTOBUF_CFILES = $(filter %.pb-c.c,$(SOURCES))
Q_PROTOBUF_SRCS = $(Q_PROTOBUF_CFILES) $(Q_PROTOBUF_HFILES)
# Rules
%.pb.h: %.proto
$(Q_PROTOC) $(PROTOBUF_INCLUDES) --cpp_out=$(top_srcdir) $(top_srcdir)/$(PROTOBUF_PACKAGE)/$^
.proto.pb.h:
$(Q_PROTOC) -I$(top_srcdir) --cpp_out=$(top_srcdir) $(top_srcdir)/$^
%.pb-c.c %.pb-c.h: %.proto
$(Q_PROTOC_C) $(PROTOBUF_INCLUDES) --c_out=$(top_srcdir) $(top_srcdir)/$(PROTOBUF_PACKAGE)/$^
AM_V_PROTOC_C = $(am__v_PROTOC_C_$(V))
am__v_PROTOC_C_ = $(am__v_PROTOC_C_$(AM_DEFAULT_VERBOSITY))
am__v_PROTOC_C_0 = @echo " PROTOC_C" $@;
am__v_PROTOC_C_1 =
.proto.pb-c.c:
$(AM_V_PROTOC_C)$(Q_PROTOC_C) -I$(top_srcdir) --c_out=$(top_srcdir) $(top_srcdir)/$^
.pb-c.c.pb-c.h:
@/bin/true
#
# Information about how to link to various libraries.
@ -46,7 +58,3 @@ Q_FRR_PB_CLIENT_LDOPTS = $(top_srcdir)/qpb/libfrr_pb.la $(Q_PROTOBUF_C_CLIENT_LD
Q_FPM_PB_CLIENT_LDOPTS = $(top_srcdir)/fpm/libfrrfpm_pb.la $(Q_FRR_PB_CLIENT_LDOPTS)
endif # HAVE_PROTOBUF
Q_CLEANFILES = $(Q_PROTOBUF_SRCS)
Q_BUILT_SRCS = $(Q_PROTOBUF_SRCS)

View File

@ -46,12 +46,12 @@ AS_IF([test "$host" != "$build"], [
AC_MSG_NOTICE([...])
build_clippy="false"
CLIPPYDIR="hosttools/lib"
HOSTTOOLS="hosttools/"
], [
build_clippy="true"
CLIPPYDIR="lib"
HOSTTOOLS=""
])
AC_SUBST(CLIPPYDIR)
AC_SUBST(HOSTTOOLS)
AM_CONDITIONAL([BUILD_CLIPPY], [$build_clippy])
# Disable portability warnings -- our automake code (in particular
@ -75,14 +75,13 @@ AC_SUBST(exampledir)
dnl default is to match previous behavior
pkgsrcrcdir=""
pkgsrcdir=""
AC_ARG_ENABLE([pkgsrcrcdir],
AS_HELP_STRING([--enable-pkgsrcrcdir],
[specify directory for rc.d scripts]),
pkgsrcrcdir="$enableval"; pkgsrcdir="pkgsrc",)
pkgsrcrcdir="$enableval",)
dnl XXX add --pkgsrcrcdir to autoconf standard directory list somehow
AC_SUBST(pkgsrcdir)
AC_SUBST(pkgsrcrcdir)
AM_CONDITIONAL([PKGSRC], [test "x$pkgsrcrcdir" != "x"])
AC_ARG_WITH([moduledir], [AS_HELP_STRING([--with-moduledir=DIR], [module directory (${libdir}/frr/modules)])], [
moduledir="$withval"
@ -415,26 +414,6 @@ if test "${enable_rr_semantics}" != "no" ; then
AC_DEFINE(HAVE_V6_RR_SEMANTICS,, Compile in v6 Route Replacement Semantics)
fi
dnl ----------
dnl MPLS check
dnl ----------
AC_MSG_CHECKING(whether this OS has MPLS stack)
case "$host" in
*-linux*)
MPLS_METHOD="zebra_mpls_netlink.o"
AC_MSG_RESULT(Linux MPLS)
;;
*-openbsd*)
MPLS_METHOD="zebra_mpls_openbsd.o"
AC_MSG_RESULT(OpenBSD MPLS)
;;
*)
MPLS_METHOD="zebra_mpls_null.o"
AC_MSG_RESULT(Unsupported kernel)
;;
esac
AC_SUBST(MPLS_METHOD)
if test "${enable_datacenter}" = "yes" ; then
AC_DEFINE(HAVE_DATACENTER,,Compile extensions for a DataCenter)
DFLT_NAME="datacenter"
@ -850,50 +829,52 @@ FRR_INCLUDES
dnl V6 headers are checked below, after we check for v6
dnl Some systems (Solaris 2.x) require libnsl (Network Services Library)
case "$host" in
[*-sunos5.[6-7]*] | [*-solaris2.[6-7]*])
opsys=sol2-6
AC_DEFINE(SUNOS_56, 1, SunOS 5.6 to 5.7)
AC_DEFINE(SUNOS_5, 1, SunOS 5)
AC_CHECK_LIB(xnet, main)
CURSES=-lcurses
SOLARIS="solaris"
;;
[*-sunos5.[8-9]] \
| [*-sunos5.1[0-9]] \
| [*-sunos5.1[0-9].[0-9]] \
| [*-solaris2.[8-9]] \
| [*-solaris2.1[0-9]] \
| [*-solaris2.1[0-9].[0-9]])
opsys=sol8
AC_DEFINE(SUNOS_59, 1, [SunOS 5.8 up])
AC_DEFINE(SUNOS_5, 1, [SunOS 5])
AC_CHECK_LIB(socket, main)
AC_CHECK_LIB(nsl, main)
AC_CHECK_LIB(umem, main)
AC_CHECK_FUNCS([printstack],
[AC_DEFINE([HAVE_PRINTSTACK],1,[Solaris printstack])
AC_DEFINE([HAVE_STACK_TRACE],1,[Stack symbols decode functionality])
])
CURSES=-lcurses
SOLARIS="solaris"
;;
*-sunos5* | *-solaris2*)
AC_DEFINE(SUNOS_5,,SunOS 5, Unknown SunOS)
AC_CHECK_LIB(socket, main)
AC_CHECK_LIB(nsl, main)
CURSES=-lcurses
SOLARIS="solaris"
;;
*-linux*)
opsys=gnu-linux
AC_DEFINE(GNU_LINUX,,GNU Linux)
;;
*-openbsd*)
opsys=openbsd
AC_DEFINE(OPEN_BSD,,OpenBSD)
;;
AC_MSG_CHECKING([which operating system interface to use])
case "$host_os" in
sunos* | solaris2*)
AC_MSG_RESULT([Solaris])
AC_DEFINE(SUNOS_5, 1, [SunOS 5])
AC_DEFINE(SOLARIS_IPV6, 1, Solaris IPv6)
AC_CHECK_LIB(socket, main)
AC_CHECK_LIB(nsl, main)
AC_CHECK_LIB(umem, main)
AC_CHECK_FUNCS([printstack], [
AC_DEFINE([HAVE_PRINTSTACK],1,[Solaris printstack])
AC_DEFINE([HAVE_STACK_TRACE],1,[Stack symbols decode functionality])
])
CURSES=-lcurses
SOLARIS="solaris"
;;
linux*)
AC_MSG_RESULT([Linux])
AC_DEFINE(GNU_LINUX,,GNU Linux)
AC_DEFINE(HAVE_NETLINK,,netlink)
AC_DEFINE(LINUX_IPV6,1,Linux IPv6 stack)
dnl Linux has a compilation problem with mixing
dnl netinet/in.h and linux/in6.h they are not
dnl compatible. There has been discussion on
dnl how to fix it but no real progress on implementation
dnl when they fix it, remove this
AC_DEFINE(IPV6_MINHOPCOUNT, 73, Linux ipv6 Min Hop Count)
AC_CHECK_DECLS([IFLA_INFO_SLAVE_KIND], [], [], [#include <linux/if_link.h>])
;;
openbsd*)
AC_MSG_RESULT([OpenBSD])
AC_DEFINE(OPEN_BSD,,OpenBSD)
AC_DEFINE(KAME,1,KAME IPv6)
;;
*)
AC_MSG_RESULT([BSD])
AC_DEFINE(HAVE_NET_RT_IFLIST,,NET_RT_IFLIST)
AC_DEFINE(KAME,1,KAME IPv6)
;;
esac
AC_SYS_LARGEFILE
@ -1049,26 +1030,6 @@ AC_CHECK_HEADER([asm-generic/unistd.h],
AC_CHECK_FUNCS(setns)]
)
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
AC_MSG_RESULT(netlink)
RT_METHOD=rt_netlink.o
KERNEL_METHOD=kernel_netlink.o
AC_DEFINE(HAVE_NETLINK,,netlink)
netlink=yes
AC_CHECK_DECLS([IFLA_INFO_SLAVE_KIND], [], [], [#include <linux/if_link.h>])
else
AC_MSG_RESULT(Route socket)
KERNEL_METHOD="kernel_socket.o"
RT_METHOD="rt_socket.o"
fi
AC_SUBST(RT_METHOD)
AC_SUBST(KERNEL_METHOD)
AM_CONDITIONAL([HAVE_NETLINK], [test "x$netlink" = "xyes"])
dnl --------------------------
dnl Determine IS-IS I/O method
dnl --------------------------
@ -1078,27 +1039,32 @@ AC_DEFINE(ISIS_METHOD_BPF, 3, [ constant value for isis method bpf ])
AC_CHECK_HEADER(net/bpf.h)
AC_CHECK_HEADER(sys/dlpi.h)
AC_MSG_CHECKING(zebra IS-IS I/O method)
if test x"$opsys" = x"gnu-linux"; then
AC_MSG_RESULT(pfpacket)
ISIS_METHOD_MACRO="ISIS_METHOD_PFPACKET"
elif test x"$opsys" = x"sol2-6" -o x"$opsys" = x"sol8"; then
AC_MSG_RESULT(DLPI)
ISIS_METHOD_MACRO="ISIS_METHOD_DLPI"
else
if test $ac_cv_header_net_bpf_h = no; then
if test $ac_cv_header_sys_dlpi_h = no; then
AC_MSG_RESULT(none)
AC_MSG_WARN([*** IS-IS support will not be built ***])
ISISD=""
else
AC_MSG_RESULT(DLPI)
fi
case "$host_os" in
linux*)
AC_MSG_RESULT(pfpacket)
ISIS_METHOD_MACRO="ISIS_METHOD_PFPACKET"
;;
solaris* | sunos*)
AC_MSG_RESULT(DLPI)
ISIS_METHOD_MACRO="ISIS_METHOD_DLPI"
else
AC_MSG_RESULT(BPF)
ISIS_METHOD_MACRO="ISIS_METHOD_BPF"
fi
fi
;;
*)
if test $ac_cv_header_net_bpf_h = no; then
if test $ac_cv_header_sys_dlpi_h = no; then
AC_MSG_RESULT(none)
AC_MSG_WARN([*** IS-IS support will not be built ***])
ISISD=""
else
AC_MSG_RESULT(DLPI)
fi
ISIS_METHOD_MACRO="ISIS_METHOD_DLPI"
else
AC_MSG_RESULT(BPF)
ISIS_METHOD_MACRO="ISIS_METHOD_BPF"
fi
;;
esac
AC_DEFINE_UNQUOTED(ISIS_METHOD, $ISIS_METHOD_MACRO, [ selected method for isis, == one of the constants ])
dnl ------------------------------------
@ -1128,59 +1094,6 @@ main()
}]])],[AC_MSG_RESULT(yes - using workaround) AC_DEFINE(HAVE_BROKEN_CMSG_FIRSTHDR,,Broken CMSG_FIRSTHDR)],
[AC_MSG_RESULT(no)],[AC_MSG_RESULT(no)])
dnl ------------------------------
dnl check kernel route read method
dnl ------------------------------
AC_CACHE_CHECK([route read method], [frr_cv_rtread_method],
[if test "x$netlink" = xyes; then
frr_cv_rtread_method="netlink"
else
for frr_cv_rtread_method in /dev/ip /dev/null;
do
test x`ls $frr_cv_rtread_method 2>/dev/null` = x"$frr_cv_rtread_method" && break
done
case $frr_cv_rtread_method in
"/dev/ip")
case "$host" in
*-freebsd*) frr_cv_rtread_method="sysctl";;
*) frr_cv_rtread_method="getmsg";;
esac;;
*)
frr_cv_rtread_method="sysctl";;
esac
fi])
RTREAD_METHOD=rtread_${frr_cv_rtread_method}.o
AC_SUBST(RTREAD_METHOD)
dnl -----------------------------
dnl check interface lookup method
dnl -----------------------------
IOCTL_METHOD=ioctl.o
AC_MSG_CHECKING(interface looking up method)
if test "$netlink" = yes; then
AC_MSG_RESULT(netlink)
IF_METHOD=if_netlink.o
elif test "$opsys" = "sol2-6";then
AC_MSG_RESULT(Solaris GIF)
IF_METHOD=if_ioctl.o
elif test "$opsys" = "sol8";then
AC_MSG_RESULT(Solaris GLIF)
IF_METHOD=if_ioctl_solaris.o
IOCTL_METHOD=ioctl_solaris.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,,NET_RT_IFLIST)
else
AC_MSG_RESULT(ioctl)
IF_METHOD=if_ioctl.o
fi
AC_SUBST(IF_METHOD)
AC_SUBST(IOCTL_METHOD)
dnl ---------------------------------------------------------------
dnl figure out how to specify an interface in multicast sockets API
dnl ---------------------------------------------------------------
@ -1276,71 +1189,11 @@ if test $ac_cv_have_decl_TCP_MD5SIG = no; then
AC_CHECK_DECLS([TCP_MD5SIG], [], [], MD5_INCLUDES)])
fi
dnl -----------------------------
dnl check ipforward detect method
dnl -----------------------------
AC_CACHE_CHECK([ipforward method], [frr_cv_ipforward_method],
[if test x$cross_compiling = xyes; then
if test x"$opsys" = x"gnu-linux"; then
frr_cv_ipforward_method=/proc/net/snmp
else
frr_cv_ipforward_method=/dev/ip
fi
else
for frr_cv_ipforward_method in /proc/net/snmp /dev/ip /dev/null;
do
test x`ls $frr_cv_ipforward_method 2>/dev/null` = x"$frr_cv_ipforward_method" && break
done
fi
case $frr_cv_ipforward_method in
"/proc/net/snmp") frr_cv_ipforward_method="proc";;
"/dev/ip")
case "$host" in
*-freebsd*) frr_cv_ipforward_method="sysctl";;
*) frr_cv_ipforward_method="solaris";;
esac;;
*) frr_cv_ipforward_method="sysctl";;
esac])
IPFORWARD=ipforward_${frr_cv_ipforward_method}.o
AC_SUBST(IPFORWARD)
dnl ----------------------------------------------------------------------------
dnl figure out if domainname is available in the utsname struct (GNU extension).
dnl ----------------------------------------------------------------------------
AC_CHECK_MEMBERS([struct utsname.domainname], [], [], [#include <sys/utsname.h>])
dnl ----------
dnl IPv6 check
dnl ----------
AC_MSG_CHECKING(whether does this OS have IPv6 stack)
dnl ---------
dnl KAME IPv6
dnl ---------
if grep WIDE /usr/include/netinet6/in6.h >/dev/null 2>&1; then
AC_DEFINE(KAME,1,KAME IPv6)
AC_MSG_RESULT(KAME)
dnl ------------------------------------
dnl Solaris 9, 10 and potentially higher
dnl ------------------------------------
elif test x"$opsys" = x"sol8"; then
AC_DEFINE(SOLARIS_IPV6, 1, Solaris IPv6)
AC_MSG_RESULT(Solaris IPv6)
dnl ----------
dnl Linux IPv6
dnl ----------
elif test x"$opsys" = x"gnu-linux"; then
AC_DEFINE(LINUX_IPV6,1,Linux IPv6 stack)
dnl Linux has a compilation problem with mixing
dnl netinet/in.h and linux/in6.h they are not
dnl compatible. There has been discussion on
dnl how to fix it but no real progress on implementation
dnl when they fix it, remove this
AC_DEFINE(IPV6_MINHOPCOUNT, 73, Linux ipv6 Min Hop Count)
AC_MSG_RESULT(Linux IPv6)
else
AC_MSG_ERROR([Failed to detect IPv6 stack])
fi
dnl ------------------
dnl IPv6 header checks
dnl ------------------
@ -1375,12 +1228,7 @@ fi
dnl --------------------
dnl Daemon disable check
dnl --------------------
if test "${enable_zebra}" = "no";then
ZEBRA=""
else
ZEBRA="zebra"
fi
AM_CONDITIONAL(ZEBRA, test "x$ZEBRA" = "xzebra")
AM_CONDITIONAL(ZEBRA, test "${enable_zebra}" != "no")
if test "${enable_bgpd}" = "no";then
BGPD=""
@ -1412,15 +1260,18 @@ fi
AM_CONDITIONAL(LDPD, test "x$LDPD" = "xldpd")
NHRPD=""
if test "$opsys" = "gnu-linux"; then
if test "${enable_nhrpd}" != "no"; then
NHRPD="nhrpd"
fi
else
if test "${enable_nhrpd}" = "yes"; then
AC_MSG_ERROR([nhrpd requires kernel APIs that are only present on Linux.])
fi
fi
case "$host_os" in
linux*)
if test "${enable_nhrpd}" != "no"; then
NHRPD="nhrpd"
fi
;;
*)
if test "${enable_nhrpd}" = "yes"; then
AC_MSG_ERROR([nhrpd requires kernel APIs that are only present on Linux.])
fi
;;
esac
AM_CONDITIONAL(NHRPD, test "x$NHRPD" = "xnhrpd")
if test "${enable_eigrpd}" = "no";then
@ -1506,7 +1357,6 @@ fi
AM_CONDITIONAL([ENABLE_BGP_VNC], [test x${enable_bgp_vnc} != xno])
AC_SUBST(DOC)
AC_SUBST(ZEBRA)
AC_SUBST(RFPTEST)
AC_SUBST(LIBRFP)
AC_SUBST(RFPINC)
@ -1969,22 +1819,17 @@ AC_CACHE_VAL(ac_cv_htonl_works,
)
AC_MSG_RESULT($ac_cv_htonl_works)
AC_CONFIG_FILES([Makefile lib/Makefile qpb/Makefile zebra/Makefile ripd/Makefile
AC_CONFIG_FILES([Makefile ripd/Makefile
ripngd/Makefile bgpd/Makefile ospfd/Makefile watchfrr/Makefile
ospf6d/Makefile ldpd/Makefile isisd/Makefile vtysh/Makefile
doc/Makefile ospfclient/Makefile tests/Makefile m4/Makefile
doc/Makefile ospfclient/Makefile tests/Makefile
bgpd/rfp-example/rfptest/Makefile bgpd/rfp-example/librfp/Makefile
babeld/Makefile
pimd/Makefile
eigrpd/Makefile
nhrpd/Makefile
redhat/Makefile
tools/Makefile
pkgsrc/Makefile
python/Makefile
fpm/Makefile
redhat/frr.spec
snapcraft/Makefile
snapcraft/snapcraft.yaml
lib/version.h
tests/lib/cli/test_cli.refout

View File

@ -17,6 +17,9 @@ CentOS 6 restrictions:
- Zebra is unable to detect what bridge/vrf an interface is associcated
with (IFLA_INFO_SLAVE_KIND does not exist in the kernel headers, you
can use a newer kernel + headers to get this functionality)
- frr_reload.py will not work, as this requires Python 2.7, and CentOS 6
only has 2.6. You can install Python 2.7 via IUS, but it won't work
properly unless you compile and install the ipaddr package for it.
Install required packages
-------------------------

View File

@ -179,8 +179,8 @@ The default is 4@dmn{s}.
@node Babel redistribution, Show Babel information, Babel configuration, Babel
@section Babel redistribution
@deffn {Babel command} {redistribute @var{kind}}
@deffnx {Babel command} {no redistribute @var{kind}}
@deffn {Babel command} {redistribute @var{<ipv4|ipv6>} @var{kind}}
@deffnx {Babel command} {no redistribute @var{<ipv4|ipv6>} @var{kind}}
Specify which kind of routes should be redistributed into Babel.
@end deffn

View File

@ -50,7 +50,7 @@
#include "keychain.h"
#include "distribute.h"
#include "libfrr.h"
//#include "routemap.h"
#include "routemap.h"
//#include "if_rmap.h"
#include "eigrpd/eigrp_structs.h"
@ -192,6 +192,11 @@ int main(int argc, char **argv, char **envp)
prefix_list_add_hook(eigrp_distribute_update_all);
prefix_list_delete_hook(eigrp_distribute_update_all);
/*
* XXX: This is just to get the CLI installed to suppress VTYSH errors.
* Routemaps in EIGRP are not yet functional.
*/
route_map_init();
/*eigrp_route_map_init();
route_map_add_hook (eigrp_rmap_update);
route_map_delete_hook (eigrp_rmap_update);*/

View File

@ -237,6 +237,11 @@ DEFUN (no_router_eigrp,
struct eigrp *eigrp;
eigrp = eigrp_lookup();
if (eigrp == NULL) {
vty_out(vty, " EIGRP Routing Process not enabled\n");
return CMD_SUCCESS;
}
if (eigrp->AS != atoi(argv[3]->arg)) {
vty_out(vty, "%% Attempting to deconfigure non-existent AS\n");
return CMD_WARNING_CONFIG_FAILED;
@ -1000,9 +1005,11 @@ DEFUN (eigrp_redistribute_source_metric,
/* Get distribute source. */
argv_find(argv, argc, "redistribute", &idx);
source = proto_redistnum(AFI_IP, argv[idx + 1]->arg);
if (source < 0)
source = proto_redistnum(AFI_IP, argv[idx + 1]->text);
if (source < 0) {
vty_out(vty, "%% Invalid route type\n");
return CMD_WARNING_CONFIG_FAILED;
}
/* Get metrics values */
@ -1029,9 +1036,11 @@ DEFUN (no_eigrp_redistribute_source_metric,
/* Get distribute source. */
argv_find(argv, argc, "redistribute", &idx);
source = proto_redistnum(AFI_IP, argv[idx + 1]->arg);
if (source < 0)
source = proto_redistnum(AFI_IP, argv[idx + 1]->text);
if (source < 0) {
vty_out(vty, "%% Invalid route type\n");
return CMD_WARNING_CONFIG_FAILED;
}
/* Get metrics values */

2
fpm/.gitignore vendored
View File

@ -1,4 +1,4 @@
Makefile
!Makefile
Makefile.in
*.o
tags

10
fpm/Makefile Normal file
View File

@ -0,0 +1,10 @@
all: ALWAYS
@$(MAKE) -s -C .. fpm/libfrrfpm_pb.la
%: ALWAYS
@$(MAKE) -s -C .. fpm/$@
Makefile:
#nothing
ALWAYS:
.PHONY: ALWAYS makefiles
.SUFFIXES:

View File

@ -1,29 +0,0 @@
include ../common.am
AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib $(Q_PROTOBUF_C_CLIENT_INCLUDES)
PROTOBUF_INCLUDES=-I$(top_srcdir)
PROTOBUF_PACKAGE = fpm
lib_LTLIBRARIES = libfrrfpm_pb.la
libfrrfpm_pb_la_LDFLAGS = -version-info 0:0:0
if HAVE_PROTOBUF
protobuf_srcs =
protobuf_srcs_nodist = \
fpm.pb-c.c
endif
libfrrfpm_pb_la_SOURCES = \
fpm.h \
fpm_pb.h \
fpm_pb.c \
$(protobuf_srcs)
nodist_libfrrfpm_pb_la_SOURCES = $(protobuf_srcs_nodist)
CLEANFILES = $(Q_CLEANFILES)
BUILT_SOURCES = $(Q_PROTOBUF_SRCS)
EXTRA_DIST = fpm.proto

View File

@ -20,6 +20,8 @@
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
syntax = "proto2";
//
// Protobuf definitions pertaining to the Forwarding Plane Manager component.
//

23
fpm/subdir.am Normal file
View File

@ -0,0 +1,23 @@
if FPM
lib_LTLIBRARIES += fpm/libfrrfpm_pb.la
endif
fpm_libfrrfpm_pb_la_LDFLAGS = -version-info 0:0:0
fpm_libfrrfpm_pb_la_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir) -I$(top_builddir)/lib \
$(Q_PROTOBUF_C_CLIENT_INCLUDES)
fpm_libfrrfpm_pb_la_SOURCES = \
fpm/fpm.h \
fpm/fpm_pb.h \
fpm/fpm_pb.c \
# end
if HAVE_PROTOBUF
nodist_fpm_libfrrfpm_pb_la_SOURCES = fpm/fpm.pb-c.c
BUILT_SOURCES += fpm/fpm.pb-c.c
CLEANFILES += \
fpm/fpm.pb-c.c \
fpm/fpm.pb-c.h \
# end
endif
EXTRA_DIST += fpm/fpm.proto

1
ldpd/.gitignore vendored
View File

@ -15,3 +15,4 @@ TAGS
.arch-ids
*~
*.loT
ldp_vty_cmds_clippy.c

View File

@ -1,5 +1,7 @@
## Process this file with automake to produce Makefile.in.
include ../common.am
AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib
DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
INSTALL_SDATA=@INSTALL@ -m 600
@ -16,6 +18,8 @@ libldp_a_SOURCES = \
socket.c util.c ldp_vty_cmds.c ldp_vty_conf.c ldp_vty_exec.c \
ldp_debug.c ldp_zebra.c
ldp_vty_cmds.o: ldp_vty_cmds_clippy.c
noinst_HEADERS = \
control.h lde.h ldpd.h ldpe.h ldp.h log.h ldp_debug.h ldp_vty.h

View File

@ -1328,7 +1328,6 @@ lde_nbr_addr_update(struct lde_nbr *ln, struct lde_addr *lde_addr, int removed)
struct lde_map *me;
RB_FOREACH(fec, fec_tree, &ln->recv_map) {
fn = (struct fec_node *)fec_find(&ft, fec);
switch (fec->type) {
case FEC_TYPE_IPV4:
if (lde_addr->af != AF_INET)
@ -1342,6 +1341,11 @@ lde_nbr_addr_update(struct lde_nbr *ln, struct lde_addr *lde_addr, int removed)
continue;
}
fn = (struct fec_node *)fec_find(&ft, fec);
if (fn == NULL)
/* shouldn't happen */
continue;
LIST_FOREACH(fnh, &fn->nexthops, entry) {
if (ldp_addrcmp(fnh->af, &fnh->nexthop,
&lde_addr->addr))

View File

@ -38,31 +38,31 @@ struct cmd_node ldp_debug_node =
};
int
ldp_vty_debug(struct vty *vty, int disable, const char *type_str,
const char *dir_str, int all)
ldp_vty_debug(struct vty *vty, const char *negate, const char *type_str,
const char *dir_str, const char *all)
{
if (strcmp(type_str, "discovery") == 0) {
if (dir_str == NULL)
return (CMD_WARNING_CONFIG_FAILED);
if (dir_str[0] == 'r') {
if (disable)
if (negate)
DEBUG_OFF(hello, HELLO_RECV);
else
DEBUG_ON(hello, HELLO_RECV);
} else {
if (disable)
if (negate)
DEBUG_OFF(hello, HELLO_SEND);
else
DEBUG_ON(hello, HELLO_SEND);
}
} else if (strcmp(type_str, "errors") == 0) {
if (disable)
if (negate)
DEBUG_OFF(errors, ERRORS);
else
DEBUG_ON(errors, ERRORS);
} else if (strcmp(type_str, "event") == 0) {
if (disable)
if (negate)
DEBUG_OFF(event, EVENT);
else
DEBUG_ON(event, EVENT);
@ -71,7 +71,7 @@ ldp_vty_debug(struct vty *vty, int disable, const char *type_str,
return (CMD_WARNING_CONFIG_FAILED);
if (dir_str[0] == 'r') {
if (disable) {
if (negate) {
DEBUG_OFF(msg, MSG_RECV);
DEBUG_OFF(msg, MSG_RECV_ALL);
} else {
@ -80,7 +80,7 @@ ldp_vty_debug(struct vty *vty, int disable, const char *type_str,
DEBUG_ON(msg, MSG_RECV_ALL);
}
} else {
if (disable) {
if (negate) {
DEBUG_OFF(msg, MSG_SEND);
DEBUG_OFF(msg, MSG_SEND_ALL);
} else {
@ -90,7 +90,7 @@ ldp_vty_debug(struct vty *vty, int disable, const char *type_str,
}
}
} else if (strcmp(type_str, "zebra") == 0) {
if (disable)
if (negate)
DEBUG_OFF(zebra, ZEBRA);
else
DEBUG_ON(zebra, ZEBRA);

View File

@ -36,46 +36,46 @@ int ldp_get_address(const char *, int *, union ldpd_addr *);
int ldp_config_write(struct vty *);
int ldp_l2vpn_config_write(struct vty *);
int ldp_debug_config_write(struct vty *);
int ldp_vty_mpls_ldp (struct vty *, int);
int ldp_vty_address_family (struct vty *, int, const char *);
int ldp_vty_disc_holdtime(struct vty *, int, const char *, const char *);
int ldp_vty_disc_interval(struct vty *, int, const char *, const char *);
int ldp_vty_targeted_hello_accept(struct vty *, int, const char *);
int ldp_vty_nbr_session_holdtime(struct vty *, int, const char *, const char *);
int ldp_vty_af_session_holdtime(struct vty *, int, const char *);
int ldp_vty_interface(struct vty *, int, const char *);
int ldp_vty_trans_addr(struct vty *, int, const char *);
int ldp_vty_neighbor_targeted(struct vty *, int, const char *);
int ldp_vty_label_advertise(struct vty *, int, const char *, const char *);
int ldp_vty_label_allocate(struct vty *, int, int, const char *);
int ldp_vty_label_expnull(struct vty *, int, const char *);
int ldp_vty_label_accept(struct vty *, int, const char *, const char *);
int ldp_vty_ttl_security(struct vty *, int);
int ldp_vty_router_id(struct vty *, int, const char *);
int ldp_vty_ds_cisco_interop(struct vty *, int);
int ldp_vty_trans_pref_ipv4(struct vty *, int);
int ldp_vty_neighbor_password(struct vty *, int, const char *, const char *);
int ldp_vty_neighbor_ttl_security(struct vty *, int, const char *, const char *);
int ldp_vty_l2vpn(struct vty *, int, const char *);
int ldp_vty_l2vpn_bridge(struct vty *, int, const char *);
int ldp_vty_l2vpn_mtu(struct vty *, int, const char *);
int ldp_vty_l2vpn_pwtype(struct vty *, int, const char *);
int ldp_vty_l2vpn_interface(struct vty *, int, const char *);
int ldp_vty_l2vpn_pseudowire(struct vty *, int, const char *);
int ldp_vty_l2vpn_pw_cword(struct vty *, int, const char *);
int ldp_vty_l2vpn_pw_nbr_addr(struct vty *, int, const char *);
int ldp_vty_l2vpn_pw_nbr_id(struct vty *, int, const char *);
int ldp_vty_l2vpn_pw_pwid(struct vty *, int, const char *);
int ldp_vty_l2vpn_pw_pwstatus(struct vty *, int);
int ldp_vty_mpls_ldp (struct vty *, const char *);
int ldp_vty_address_family (struct vty *, const char *, const char *);
int ldp_vty_disc_holdtime(struct vty *, const char *, const char *, long);
int ldp_vty_disc_interval(struct vty *, const char *, const char *, long);
int ldp_vty_targeted_hello_accept(struct vty *, const char *, const char *);
int ldp_vty_nbr_session_holdtime(struct vty *, const char *, struct in_addr, long);
int ldp_vty_af_session_holdtime(struct vty *, const char *, long);
int ldp_vty_interface(struct vty *, const char *, const char *);
int ldp_vty_trans_addr(struct vty *, const char *, const char *);
int ldp_vty_neighbor_targeted(struct vty *, const char *, const char *);
int ldp_vty_label_advertise(struct vty *, const char *, const char *, const char *);
int ldp_vty_label_allocate(struct vty *, const char *, const char *, const char *);
int ldp_vty_label_expnull(struct vty *, const char *, const char *);
int ldp_vty_label_accept(struct vty *, const char *, const char *, const char *);
int ldp_vty_ttl_security(struct vty *, const char *);
int ldp_vty_router_id(struct vty *, const char *, struct in_addr);
int ldp_vty_ds_cisco_interop(struct vty *, const char *);
int ldp_vty_trans_pref_ipv4(struct vty *, const char *);
int ldp_vty_neighbor_password(struct vty *, const char *, struct in_addr, const char *);
int ldp_vty_neighbor_ttl_security(struct vty *, const char *, struct in_addr, const char *);
int ldp_vty_l2vpn(struct vty *, const char *, const char *);
int ldp_vty_l2vpn_bridge(struct vty *, const char *, const char *);
int ldp_vty_l2vpn_mtu(struct vty *, const char *, long);
int ldp_vty_l2vpn_pwtype(struct vty *, const char *, const char *);
int ldp_vty_l2vpn_interface(struct vty *, const char *, const char *);
int ldp_vty_l2vpn_pseudowire(struct vty *, const char *, const char *);
int ldp_vty_l2vpn_pw_cword(struct vty *, const char *, const char *);
int ldp_vty_l2vpn_pw_nbr_addr(struct vty *, const char *, const char *);
int ldp_vty_l2vpn_pw_nbr_id(struct vty *, const char *, struct in_addr);
int ldp_vty_l2vpn_pw_pwid(struct vty *, const char *, long);
int ldp_vty_l2vpn_pw_pwstatus(struct vty *, const char *);
int ldp_vty_clear_nbr(struct vty *, const char *);
int ldp_vty_debug(struct vty *, int, const char *, const char *, int);
int ldp_vty_show_binding(struct vty *, const char *, int, int);
int ldp_vty_show_discovery(struct vty *, const char *, int, int);
int ldp_vty_show_interface(struct vty *, const char *, int);
int ldp_vty_show_capabilities(struct vty *, int);
int ldp_vty_show_neighbor(struct vty *, int, int, int);
int ldp_vty_show_atom_binding(struct vty *, int);
int ldp_vty_show_atom_vc(struct vty *, int);
int ldp_vty_debug(struct vty *, const char *, const char *, const char *, const char *);
int ldp_vty_show_binding(struct vty *, const char *, const char *, const char *);
int ldp_vty_show_discovery(struct vty *, const char *, const char *, const char *);
int ldp_vty_show_interface(struct vty *, const char *, const char *);
int ldp_vty_show_capabilities(struct vty *, const char *);
int ldp_vty_show_neighbor(struct vty *, int, const char *, const char *);
int ldp_vty_show_atom_binding(struct vty *, const char *);
int ldp_vty_show_atom_vc(struct vty *, const char *);
int ldp_vty_show_debugging(struct vty *);
void ldp_vty_init(void);

File diff suppressed because it is too large Load Diff

View File

@ -233,7 +233,7 @@ ldp_af_config_write(struct vty *vty, int af, struct ldpd_conf *conf,
ldp_af_iface_config_write(vty, af);
vty_out (vty, " !\n");
vty_out(vty, " exit-address-family\n");
}
int
@ -407,9 +407,9 @@ ldp_iface_is_configured(struct ldpd_conf *xconf, const char *ifname)
}
int
ldp_vty_mpls_ldp(struct vty *vty, int disable)
ldp_vty_mpls_ldp(struct vty *vty, const char *negate)
{
if (disable)
if (negate)
vty_conf->flags &= ~F_LDPD_ENABLED;
else {
vty->node = LDP_NODE;
@ -422,7 +422,7 @@ ldp_vty_mpls_ldp(struct vty *vty, int disable)
}
int
ldp_vty_address_family(struct vty *vty, int disable, const char *af_str)
ldp_vty_address_family(struct vty *vty, const char *negate, const char *af_str)
{
struct ldpd_af_conf *af_conf;
int af;
@ -436,7 +436,7 @@ ldp_vty_address_family(struct vty *vty, int disable, const char *af_str)
} else
return (CMD_WARNING_CONFIG_FAILED);
if (disable) {
if (negate) {
af_conf->flags &= ~F_LDPD_AF_ENABLED;
ldp_config_apply(vty, vty_conf);
return (CMD_SUCCESS);
@ -460,23 +460,15 @@ ldp_vty_address_family(struct vty *vty, int disable, const char *af_str)
}
int
ldp_vty_disc_holdtime(struct vty *vty, int disable, const char *hello_type_str,
const char *seconds_str)
ldp_vty_disc_holdtime(struct vty *vty, const char *negate,
const char *hello_type_str, long secs)
{
struct ldpd_af_conf *af_conf;
struct iface *iface;
struct iface_af *ia;
int af;
char *ep;
long int secs;
enum hello_type hello_type;
secs = strtol(seconds_str, &ep, 10);
if (*ep != '\0' || secs < MIN_HOLDTIME || secs > MAX_HOLDTIME) {
vty_out (vty, "%% Invalid holdtime\n");
return (CMD_WARNING_CONFIG_FAILED);
}
if (hello_type_str[0] == 'h')
hello_type = HELLO_LINK;
else
@ -484,7 +476,7 @@ ldp_vty_disc_holdtime(struct vty *vty, int disable, const char *hello_type_str,
switch (vty->node) {
case LDP_NODE:
if (disable) {
if (negate) {
switch (hello_type) {
case HELLO_LINK:
vty_conf->lhello_holdtime = LINK_DFLT_HOLDTIME;
@ -511,7 +503,7 @@ ldp_vty_disc_holdtime(struct vty *vty, int disable, const char *hello_type_str,
af = ldp_vty_get_af(vty);
af_conf = ldp_af_conf_get(vty_conf, af);
if (disable) {
if (negate) {
switch (hello_type) {
case HELLO_LINK:
af_conf->lhello_holdtime = 0;
@ -539,7 +531,7 @@ ldp_vty_disc_holdtime(struct vty *vty, int disable, const char *hello_type_str,
VTY_CHECK_CONTEXT(iface);
ia = iface_af_get(iface, af);
if (disable)
if (negate)
ia->hello_holdtime = 0;
else
ia->hello_holdtime = secs;
@ -554,24 +546,15 @@ ldp_vty_disc_holdtime(struct vty *vty, int disable, const char *hello_type_str,
}
int
ldp_vty_disc_interval(struct vty *vty, int disable, const char *hello_type_str,
const char *seconds_str)
ldp_vty_disc_interval(struct vty *vty, const char *negate,
const char *hello_type_str, long secs)
{
struct ldpd_af_conf *af_conf;
struct iface *iface;
struct iface_af *ia;
int af;
char *ep;
long int secs;
enum hello_type hello_type;
secs = strtol(seconds_str, &ep, 10);
if (*ep != '\0' || secs < MIN_HELLO_INTERVAL ||
secs > MAX_HELLO_INTERVAL) {
vty_out (vty, "%% Invalid interval\n");
return (CMD_WARNING_CONFIG_FAILED);
}
if (hello_type_str[0] == 'h')
hello_type = HELLO_LINK;
else
@ -579,14 +562,15 @@ ldp_vty_disc_interval(struct vty *vty, int disable, const char *hello_type_str,
switch (vty->node) {
case LDP_NODE:
if (disable) {
if (negate) {
switch (hello_type) {
case HELLO_LINK:
vty_conf->lhello_interval = LINK_DFLT_HOLDTIME;
vty_conf->lhello_interval =
DEFAULT_HELLO_INTERVAL;
break;
case HELLO_TARGETED:
vty_conf->thello_interval =
TARGETED_DFLT_HOLDTIME;
DEFAULT_HELLO_INTERVAL;
break;
}
} else {
@ -606,7 +590,7 @@ ldp_vty_disc_interval(struct vty *vty, int disable, const char *hello_type_str,
af = ldp_vty_get_af(vty);
af_conf = ldp_af_conf_get(vty_conf, af);
if (disable) {
if (negate) {
switch (hello_type) {
case HELLO_LINK:
af_conf->lhello_interval = 0;
@ -634,7 +618,7 @@ ldp_vty_disc_interval(struct vty *vty, int disable, const char *hello_type_str,
VTY_CHECK_CONTEXT(iface);
ia = iface_af_get(iface, af);
if (disable)
if (negate)
ia->hello_interval = 0;
else
ia->hello_interval = secs;
@ -649,7 +633,7 @@ ldp_vty_disc_interval(struct vty *vty, int disable, const char *hello_type_str,
}
int
ldp_vty_targeted_hello_accept(struct vty *vty, int disable,
ldp_vty_targeted_hello_accept(struct vty *vty, const char *negate,
const char *acl_from_str)
{
struct ldpd_af_conf *af_conf;
@ -658,7 +642,7 @@ ldp_vty_targeted_hello_accept(struct vty *vty, int disable,
af = ldp_vty_get_af(vty);
af_conf = ldp_af_conf_get(vty_conf, af);
if (disable) {
if (negate) {
af_conf->flags &= ~F_LDPD_AF_THELLO_ACCEPT;
af_conf->acl_thello_accept_from[0] = '\0';
} else {
@ -676,29 +660,19 @@ ldp_vty_targeted_hello_accept(struct vty *vty, int disable,
}
int
ldp_vty_nbr_session_holdtime(struct vty *vty, int disable,
const char *lsr_id_str, const char *seconds_str)
ldp_vty_nbr_session_holdtime(struct vty *vty, const char *negate,
struct in_addr lsr_id, long secs)
{
char *ep;
long int secs;
struct in_addr lsr_id;
struct nbr_params *nbrp;
if (inet_pton(AF_INET, lsr_id_str, &lsr_id) != 1 ||
bad_addr_v4(lsr_id)) {
if (bad_addr_v4(lsr_id)) {
vty_out (vty, "%% Malformed address\n");
return (CMD_WARNING_CONFIG_FAILED);
}
secs = strtol(seconds_str, &ep, 10);
if (*ep != '\0' || secs < MIN_KEEPALIVE || secs > MAX_KEEPALIVE) {
vty_out (vty, "%% Invalid holdtime\n");
return (CMD_SUCCESS);
}
nbrp = nbr_params_find(vty_conf, lsr_id);
if (disable) {
if (negate) {
if (nbrp == NULL)
return (CMD_SUCCESS);
@ -722,24 +696,15 @@ ldp_vty_nbr_session_holdtime(struct vty *vty, int disable,
}
int
ldp_vty_af_session_holdtime(struct vty *vty, int disable,
const char *seconds_str)
ldp_vty_af_session_holdtime(struct vty *vty, const char *negate, long secs)
{
struct ldpd_af_conf *af_conf;
int af;
char *ep;
long int secs;
secs = strtol(seconds_str, &ep, 10);
if (*ep != '\0' || secs < MIN_KEEPALIVE || secs > MAX_KEEPALIVE) {
vty_out (vty, "%% Invalid holdtime\n");
return (CMD_SUCCESS);
}
af = ldp_vty_get_af(vty);
af_conf = ldp_af_conf_get(vty_conf, af);
if (disable)
if (negate)
af_conf->keepalive = DEFAULT_KEEPALIVE;
else
af_conf->keepalive = secs;
@ -750,7 +715,7 @@ ldp_vty_af_session_holdtime(struct vty *vty, int disable,
}
int
ldp_vty_interface(struct vty *vty, int disable, const char *ifname)
ldp_vty_interface(struct vty *vty, const char *negate, const char *ifname)
{
int af;
struct iface *iface;
@ -759,7 +724,7 @@ ldp_vty_interface(struct vty *vty, int disable, const char *ifname)
af = ldp_vty_get_af(vty);
iface = if_lookup_name(vty_conf, ifname);
if (disable) {
if (negate) {
if (iface == NULL)
return (CMD_SUCCESS);
@ -812,7 +777,7 @@ ldp_vty_interface(struct vty *vty, int disable, const char *ifname)
}
int
ldp_vty_trans_addr(struct vty *vty, int disable, const char *addr_str)
ldp_vty_trans_addr(struct vty *vty, const char *negate, const char *addr_str)
{
struct ldpd_af_conf *af_conf;
int af;
@ -820,7 +785,7 @@ ldp_vty_trans_addr(struct vty *vty, int disable, const char *addr_str)
af = ldp_vty_get_af(vty);
af_conf = ldp_af_conf_get(vty_conf, af);
if (disable)
if (negate)
memset(&af_conf->trans_addr, 0, sizeof(af_conf->trans_addr));
else {
if (inet_pton(af, addr_str, &af_conf->trans_addr) != 1 ||
@ -836,7 +801,7 @@ ldp_vty_trans_addr(struct vty *vty, int disable, const char *addr_str)
}
int
ldp_vty_neighbor_targeted(struct vty *vty, int disable, const char *addr_str)
ldp_vty_neighbor_targeted(struct vty *vty, const char *negate, const char *addr_str)
{
int af;
union ldpd_addr addr;
@ -856,7 +821,7 @@ ldp_vty_neighbor_targeted(struct vty *vty, int disable, const char *addr_str)
tnbr = tnbr_find(vty_conf, af, &addr);
if (disable) {
if (negate) {
if (tnbr == NULL)
return (CMD_SUCCESS);
@ -883,7 +848,7 @@ ldp_vty_neighbor_targeted(struct vty *vty, int disable, const char *addr_str)
}
int
ldp_vty_label_advertise(struct vty *vty, int disable, const char *acl_to_str,
ldp_vty_label_advertise(struct vty *vty, const char *negate, const char *acl_to_str,
const char *acl_for_str)
{
struct ldpd_af_conf *af_conf;
@ -892,7 +857,7 @@ ldp_vty_label_advertise(struct vty *vty, int disable, const char *acl_to_str,
af = ldp_vty_get_af(vty);
af_conf = ldp_af_conf_get(vty_conf, af);
if (disable) {
if (negate) {
af_conf->acl_label_advertise_to[0] = '\0';
af_conf->acl_label_advertise_for[0] = '\0';
} else {
@ -914,7 +879,7 @@ ldp_vty_label_advertise(struct vty *vty, int disable, const char *acl_to_str,
}
int
ldp_vty_label_allocate(struct vty *vty, int disable, int host_routes,
ldp_vty_label_allocate(struct vty *vty, const char *negate, const char *host_routes,
const char *acl_for_str)
{
struct ldpd_af_conf *af_conf;
@ -925,7 +890,7 @@ ldp_vty_label_allocate(struct vty *vty, int disable, int host_routes,
af_conf->flags &= ~F_LDPD_AF_ALLOCHOSTONLY;
af_conf->acl_label_allocate_for[0] = '\0';
if (!disable) {
if (!negate) {
if (host_routes)
af_conf->flags |= F_LDPD_AF_ALLOCHOSTONLY;
else
@ -939,7 +904,7 @@ ldp_vty_label_allocate(struct vty *vty, int disable, int host_routes,
}
int
ldp_vty_label_expnull(struct vty *vty, int disable, const char *acl_for_str)
ldp_vty_label_expnull(struct vty *vty, const char *negate, const char *acl_for_str)
{
struct ldpd_af_conf *af_conf;
int af;
@ -947,7 +912,7 @@ ldp_vty_label_expnull(struct vty *vty, int disable, const char *acl_for_str)
af = ldp_vty_get_af(vty);
af_conf = ldp_af_conf_get(vty_conf, af);
if (disable) {
if (negate) {
af_conf->flags &= ~F_LDPD_AF_EXPNULL;
af_conf->acl_label_expnull_for[0] = '\0';
} else {
@ -965,7 +930,7 @@ ldp_vty_label_expnull(struct vty *vty, int disable, const char *acl_for_str)
}
int
ldp_vty_label_accept(struct vty *vty, int disable, const char *acl_from_str,
ldp_vty_label_accept(struct vty *vty, const char *negate, const char *acl_from_str,
const char *acl_for_str)
{
struct ldpd_af_conf *af_conf;
@ -974,7 +939,7 @@ ldp_vty_label_accept(struct vty *vty, int disable, const char *acl_from_str,
af = ldp_vty_get_af(vty);
af_conf = ldp_af_conf_get(vty_conf, af);
if (disable) {
if (negate) {
af_conf->acl_label_accept_from[0] = '\0';
af_conf->acl_label_accept_for[0] = '\0';
} else {
@ -996,7 +961,7 @@ ldp_vty_label_accept(struct vty *vty, int disable, const char *acl_from_str,
}
int
ldp_vty_ttl_security(struct vty *vty, int disable)
ldp_vty_ttl_security(struct vty *vty, const char *negate)
{
struct ldpd_af_conf *af_conf;
int af;
@ -1004,7 +969,7 @@ ldp_vty_ttl_security(struct vty *vty, int disable)
af = ldp_vty_get_af(vty);
af_conf = ldp_af_conf_get(vty_conf, af);
if (disable)
if (negate)
af_conf->flags &= ~F_LDPD_AF_NO_GTSM;
else
af_conf->flags |= F_LDPD_AF_NO_GTSM;
@ -1015,16 +980,16 @@ ldp_vty_ttl_security(struct vty *vty, int disable)
}
int
ldp_vty_router_id(struct vty *vty, int disable, const char *addr_str)
ldp_vty_router_id(struct vty *vty, const char *negate, struct in_addr address)
{
if (disable)
if (negate)
vty_conf->rtr_id.s_addr = INADDR_ANY;
else {
if (inet_pton(AF_INET, addr_str, &vty_conf->rtr_id) != 1 ||
bad_addr_v4(vty_conf->rtr_id)) {
if (bad_addr_v4(address)) {
vty_out (vty, "%% Malformed address\n");
return (CMD_SUCCESS);
}
vty_conf->rtr_id = address;
}
ldp_config_apply(vty, vty_conf);
@ -1033,9 +998,9 @@ ldp_vty_router_id(struct vty *vty, int disable, const char *addr_str)
}
int
ldp_vty_ds_cisco_interop(struct vty *vty, int disable)
ldp_vty_ds_cisco_interop(struct vty *vty, const char * negate)
{
if (disable)
if (negate)
vty_conf->flags &= ~F_LDPD_DS_CISCO_INTEROP;
else
vty_conf->flags |= F_LDPD_DS_CISCO_INTEROP;
@ -1046,9 +1011,9 @@ ldp_vty_ds_cisco_interop(struct vty *vty, int disable)
}
int
ldp_vty_trans_pref_ipv4(struct vty *vty, int disable)
ldp_vty_trans_pref_ipv4(struct vty *vty, const char *negate)
{
if (disable)
if (negate)
vty_conf->trans_pref = DUAL_STACK_LDPOV6;
else
vty_conf->trans_pref = DUAL_STACK_LDPOV4;
@ -1059,22 +1024,20 @@ ldp_vty_trans_pref_ipv4(struct vty *vty, int disable)
}
int
ldp_vty_neighbor_password(struct vty *vty, int disable, const char *lsr_id_str,
ldp_vty_neighbor_password(struct vty *vty, const char *negate, struct in_addr lsr_id,
const char *password_str)
{
struct in_addr lsr_id;
size_t password_len;
struct nbr_params *nbrp;
if (inet_pton(AF_INET, lsr_id_str, &lsr_id) != 1 ||
bad_addr_v4(lsr_id)) {
if (bad_addr_v4(lsr_id)) {
vty_out (vty, "%% Malformed address\n");
return (CMD_WARNING_CONFIG_FAILED);
}
nbrp = nbr_params_find(vty_conf, lsr_id);
if (disable) {
if (negate) {
if (nbrp == NULL)
return (CMD_SUCCESS);
@ -1104,16 +1067,14 @@ ldp_vty_neighbor_password(struct vty *vty, int disable, const char *lsr_id_str,
}
int
ldp_vty_neighbor_ttl_security(struct vty *vty, int disable,
const char *lsr_id_str, const char *hops_str)
ldp_vty_neighbor_ttl_security(struct vty *vty, const char *negate,
struct in_addr lsr_id, const char *hops_str)
{
struct in_addr lsr_id;
struct nbr_params *nbrp;
long int hops = 0;
char *ep;
if (inet_pton(AF_INET, lsr_id_str, &lsr_id) != 1 ||
bad_addr_v4(lsr_id)) {
if (bad_addr_v4(lsr_id)) {
vty_out (vty, "%% Malformed address\n");
return (CMD_WARNING_CONFIG_FAILED);
}
@ -1128,7 +1089,7 @@ ldp_vty_neighbor_ttl_security(struct vty *vty, int disable,
nbrp = nbr_params_find(vty_conf, lsr_id);
if (disable) {
if (negate) {
if (nbrp == NULL)
return (CMD_SUCCESS);
@ -1158,7 +1119,7 @@ ldp_vty_neighbor_ttl_security(struct vty *vty, int disable,
}
int
ldp_vty_l2vpn(struct vty *vty, int disable, const char *name_str)
ldp_vty_l2vpn(struct vty *vty, const char *negate, const char *name_str)
{
struct l2vpn *l2vpn;
struct l2vpn_if *lif;
@ -1166,7 +1127,7 @@ ldp_vty_l2vpn(struct vty *vty, int disable, const char *name_str)
l2vpn = l2vpn_find(vty_conf, name_str);
if (disable) {
if (negate) {
if (l2vpn == NULL)
return (CMD_SUCCESS);
@ -1203,11 +1164,11 @@ ldp_vty_l2vpn(struct vty *vty, int disable, const char *name_str)
}
int
ldp_vty_l2vpn_bridge(struct vty *vty, int disable, const char *ifname)
ldp_vty_l2vpn_bridge(struct vty *vty, const char *negate, const char *ifname)
{
VTY_DECLVAR_CONTEXT(l2vpn, l2vpn);
if (disable)
if (negate)
memset(l2vpn->br_ifname, 0, sizeof(l2vpn->br_ifname));
else
strlcpy(l2vpn->br_ifname, ifname, sizeof(l2vpn->br_ifname));
@ -1218,19 +1179,11 @@ ldp_vty_l2vpn_bridge(struct vty *vty, int disable, const char *ifname)
}
int
ldp_vty_l2vpn_mtu(struct vty *vty, int disable, const char *mtu_str)
ldp_vty_l2vpn_mtu(struct vty *vty, const char *negate, long mtu)
{
VTY_DECLVAR_CONTEXT(l2vpn, l2vpn);
char *ep;
int mtu;
mtu = strtol(mtu_str, &ep, 10);
if (*ep != '\0' || mtu < MIN_L2VPN_MTU || mtu > MAX_L2VPN_MTU) {
vty_out (vty, "%% Invalid MTU\n");
return (CMD_WARNING_CONFIG_FAILED);
}
if (disable)
if (negate)
l2vpn->mtu = DEFAULT_L2VPN_MTU;
else
l2vpn->mtu = mtu;
@ -1241,7 +1194,7 @@ ldp_vty_l2vpn_mtu(struct vty *vty, int disable, const char *mtu_str)
}
int
ldp_vty_l2vpn_pwtype(struct vty *vty, int disable, const char *type_str)
ldp_vty_l2vpn_pwtype(struct vty *vty, const char *negate, const char *type_str)
{
VTY_DECLVAR_CONTEXT(l2vpn, l2vpn);
int pw_type;
@ -1251,7 +1204,7 @@ ldp_vty_l2vpn_pwtype(struct vty *vty, int disable, const char *type_str)
else
pw_type = PW_TYPE_ETHERNET_TAGGED;
if (disable)
if (negate)
l2vpn->pw_type = DEFAULT_PW_TYPE;
else
l2vpn->pw_type = pw_type;
@ -1262,14 +1215,14 @@ ldp_vty_l2vpn_pwtype(struct vty *vty, int disable, const char *type_str)
}
int
ldp_vty_l2vpn_interface(struct vty *vty, int disable, const char *ifname)
ldp_vty_l2vpn_interface(struct vty *vty, const char *negate, const char *ifname)
{
VTY_DECLVAR_CONTEXT(l2vpn, l2vpn);
struct l2vpn_if *lif;
lif = l2vpn_if_find(l2vpn, ifname);
if (disable) {
if (negate) {
if (lif == NULL)
return (CMD_SUCCESS);
@ -1300,14 +1253,14 @@ ldp_vty_l2vpn_interface(struct vty *vty, int disable, const char *ifname)
}
int
ldp_vty_l2vpn_pseudowire(struct vty *vty, int disable, const char *ifname)
ldp_vty_l2vpn_pseudowire(struct vty *vty, const char *negate, const char *ifname)
{
VTY_DECLVAR_CONTEXT(l2vpn, l2vpn);
struct l2vpn_pw *pw;
pw = l2vpn_pw_find(l2vpn, ifname);
if (disable) {
if (negate) {
if (pw == NULL)
return (CMD_SUCCESS);
@ -1346,11 +1299,11 @@ ldp_vty_l2vpn_pseudowire(struct vty *vty, int disable, const char *ifname)
}
int
ldp_vty_l2vpn_pw_cword(struct vty *vty, int disable, const char *preference_str)
ldp_vty_l2vpn_pw_cword(struct vty *vty, const char *negate, const char *preference_str)
{
VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw, pw);
if (disable)
if (negate)
pw->flags |= F_PW_CWORD_CONF;
else {
if (preference_str[0] == 'e')
@ -1365,7 +1318,7 @@ ldp_vty_l2vpn_pw_cword(struct vty *vty, int disable, const char *preference_str)
}
int
ldp_vty_l2vpn_pw_nbr_addr(struct vty *vty, int disable, const char *addr_str)
ldp_vty_l2vpn_pw_nbr_addr(struct vty *vty, const char *negate, const char *addr_str)
{
VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw, pw);
int af;
@ -1377,7 +1330,7 @@ ldp_vty_l2vpn_pw_nbr_addr(struct vty *vty, int disable, const char *addr_str)
return (CMD_WARNING_CONFIG_FAILED);
}
if (disable) {
if (negate) {
pw->af = AF_UNSPEC;
memset(&pw->addr, 0, sizeof(pw->addr));
pw->flags &= ~F_PW_STATIC_NBR_ADDR;
@ -1393,18 +1346,16 @@ ldp_vty_l2vpn_pw_nbr_addr(struct vty *vty, int disable, const char *addr_str)
}
int
ldp_vty_l2vpn_pw_nbr_id(struct vty *vty, int disable, const char *lsr_id_str)
ldp_vty_l2vpn_pw_nbr_id(struct vty *vty, const char *negate, struct in_addr lsr_id)
{
VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw, pw);
struct in_addr lsr_id;
if (inet_pton(AF_INET, lsr_id_str, &lsr_id) != 1 ||
bad_addr_v4(lsr_id)) {
if (bad_addr_v4(lsr_id)) {
vty_out (vty, "%% Malformed address\n");
return (CMD_WARNING_CONFIG_FAILED);
}
if (disable)
if (negate)
pw->lsr_id.s_addr = INADDR_ANY;
else
pw->lsr_id = lsr_id;
@ -1415,19 +1366,11 @@ ldp_vty_l2vpn_pw_nbr_id(struct vty *vty, int disable, const char *lsr_id_str)
}
int
ldp_vty_l2vpn_pw_pwid(struct vty *vty, int disable, const char *pwid_str)
ldp_vty_l2vpn_pw_pwid(struct vty *vty, const char *negate, long pwid)
{
VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw, pw);
char *ep;
uint32_t pwid;
pwid = strtol(pwid_str, &ep, 10);
if (*ep != '\0' || pwid < MIN_PWID_ID || pwid > MAX_PWID_ID) {
vty_out (vty, "%% Invalid pw-id\n");
return (CMD_WARNING_CONFIG_FAILED);
}
if (disable)
if (negate)
pw->pwid = 0;
else
pw->pwid = pwid;
@ -1438,11 +1381,11 @@ ldp_vty_l2vpn_pw_pwid(struct vty *vty, int disable, const char *pwid_str)
}
int
ldp_vty_l2vpn_pw_pwstatus(struct vty *vty, int disable)
ldp_vty_l2vpn_pw_pwstatus(struct vty *vty, const char *negate)
{
VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw, pw);
if (disable)
if (negate)
pw->flags |= F_PW_STATUSTLV_CONF;
else
pw->flags &= ~F_PW_STATUSTLV_CONF;

View File

@ -1565,7 +1565,7 @@ ldp_vty_get_af(const char *str, int *af)
}
int
ldp_vty_show_binding(struct vty *vty, const char *af_str, int detail, int json)
ldp_vty_show_binding(struct vty *vty, const char *af_str, const char *detail, const char *json)
{
struct imsgbuf ibuf;
struct show_params params;
@ -1579,8 +1579,8 @@ ldp_vty_show_binding(struct vty *vty, const char *af_str, int detail, int json)
memset(&params, 0, sizeof(params));
params.family = af;
params.detail = detail;
params.json = json;
params.detail = (detail) ? 1 : 0;
params.json = (json) ? 1 : 0;
if (!params.detail && !params.json)
vty_out (vty, "%-4s %-20s %-15s %-11s %-13s %6s\n", "AF",
@ -1592,8 +1592,8 @@ ldp_vty_show_binding(struct vty *vty, const char *af_str, int detail, int json)
}
int
ldp_vty_show_discovery(struct vty *vty, const char *af_str, int detail,
int json)
ldp_vty_show_discovery(struct vty *vty, const char *af_str, const char *detail,
const char *json)
{
struct imsgbuf ibuf;
struct show_params params;
@ -1607,8 +1607,8 @@ ldp_vty_show_discovery(struct vty *vty, const char *af_str, int detail,
memset(&params, 0, sizeof(params));
params.family = af;
params.detail = detail;
params.json = json;
params.detail = (detail) ? 1 : 0;
params.json = (json) ? 1 : 0;
if (!params.detail && !params.json)
vty_out (vty, "%-4s %-15s %-8s %-15s %9s\n",
@ -1623,7 +1623,7 @@ ldp_vty_show_discovery(struct vty *vty, const char *af_str, int detail,
}
int
ldp_vty_show_interface(struct vty *vty, const char *af_str, int json)
ldp_vty_show_interface(struct vty *vty, const char *af_str, const char *json)
{
struct imsgbuf ibuf;
struct show_params params;
@ -1638,7 +1638,7 @@ ldp_vty_show_interface(struct vty *vty, const char *af_str, int json)
memset(&params, 0, sizeof(params));
params.family = af;
params.json = json;
params.json = (json) ? 1 : 0;
/* header */
if (!params.json) {
@ -1652,7 +1652,7 @@ ldp_vty_show_interface(struct vty *vty, const char *af_str, int json)
}
int
ldp_vty_show_capabilities(struct vty *vty, int json)
ldp_vty_show_capabilities(struct vty *vty, const char *json)
{
if (json) {
json_object *json;
@ -1703,7 +1703,7 @@ ldp_vty_show_capabilities(struct vty *vty, int json)
}
int
ldp_vty_show_neighbor(struct vty *vty, int capabilities, int detail, int json)
ldp_vty_show_neighbor(struct vty *vty, int capabilities, const char *detail, const char *json)
{
struct imsgbuf ibuf;
struct show_params params;
@ -1713,8 +1713,8 @@ ldp_vty_show_neighbor(struct vty *vty, int capabilities, int detail, int json)
memset(&params, 0, sizeof(params));
params.capabilities = capabilities;
params.detail = detail;
params.json = json;
params.detail = (detail) ? 1 : 0;
params.json = (json) ? 1 : 0;
if (params.capabilities)
params.detail = 1;
@ -1728,7 +1728,7 @@ ldp_vty_show_neighbor(struct vty *vty, int capabilities, int detail, int json)
}
int
ldp_vty_show_atom_binding(struct vty *vty, int json)
ldp_vty_show_atom_binding(struct vty *vty, const char *json)
{
struct imsgbuf ibuf;
struct show_params params;
@ -1737,14 +1737,14 @@ ldp_vty_show_atom_binding(struct vty *vty, int json)
return (CMD_WARNING);
memset(&params, 0, sizeof(params));
params.json = json;
params.json = (json) ? 1 : 0;
imsg_compose(&ibuf, IMSG_CTL_SHOW_L2VPN_BINDING, 0, 0, -1, NULL, 0);
return (ldp_vty_dispatch(vty, &ibuf, SHOW_L2VPN_BINDING, &params));
}
int
ldp_vty_show_atom_vc(struct vty *vty, int json)
ldp_vty_show_atom_vc(struct vty *vty, const char *json)
{
struct imsgbuf ibuf;
struct show_params params;
@ -1753,7 +1753,7 @@ ldp_vty_show_atom_vc(struct vty *vty, int json)
return (CMD_WARNING);
memset(&params, 0, sizeof(params));
params.json = json;
params.json = (json) ? 1 : 0;
if (!params.json) {
/* header */

2
lib/.gitignore vendored
View File

@ -1,4 +1,4 @@
Makefile
!Makefile
Makefile.in
*.o
*.lo

10
lib/Makefile Normal file
View File

@ -0,0 +1,10 @@
all: ALWAYS
@$(MAKE) -s -C .. lib/libfrr.la
%: ALWAYS
@$(MAKE) -s -C .. lib/$@
Makefile:
#nothing
ALWAYS:
.PHONY: ALWAYS makefiles
.SUFFIXES:

View File

@ -1,155 +0,0 @@
## Process this file with automake to produce Makefile.in.
include ../common.am
AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib
AM_CFLAGS = $(WERROR)
DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
AM_YFLAGS = -d -Dapi.prefix=@BISON_OPENBRACE@cmd_yy@BISON_CLOSEBRACE@ @BISON_VERBOSE@
command_lex.h: command_lex.c
@if test ! -f $@; then rm -f command_lex.c; else :; fi
@if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) command_lex.c; else :; fi
command_parse.lo: command_lex.h
clippy-command_parse.$(OBJEXT): command_lex.h
lib_LTLIBRARIES = libfrr.la
libfrr_la_LDFLAGS = -version-info 0:0:0
libfrr_la_SOURCES = \
network.c pid_output.c getopt.c getopt1.c \
checksum.c vector.c linklist.c vty.c openbsd-tree.c \
graph.c command_parse.y command_lex.l command_match.c \
command_graph.c \
command.c \
sockunion.c prefix.c thread.c if.c buffer.c table.c hash.c \
filter.c routemap.c distribute.c stream.c log.c plist.c \
zclient.c sockopt.c md5.c if_rmap.c keychain.c privs.c \
sigevent.c pqueue.c jhash.c workqueue.c nexthop.c json.c \
ptm_lib.c csv.c bfd.c vrf.c systemd.c ns.c memory.c memory_vty.c \
imsg-buffer.c imsg.c skiplist.c \
qobj.c wheel.c \
event_counter.c \
grammar_sandbox.c \
srcdest_table.c \
spf_backoff.c \
libfrr.c \
strlcpy.c \
strlcat.c \
sha256.c \
module.c \
hook.c \
frr_pthread.c \
termtable.c \
# end
BUILT_SOURCES = route_types.h gitversion.h command_parse.h command_lex.h
libfrr_la_LIBADD = @LIBCAP@
if SNMP
lib_LTLIBRARIES += libfrrsnmp.la
endif
libfrrsnmp_la_CFLAGS = $(WERROR) $(SNMP_CFLAGS)
libfrrsnmp_la_LDFLAGS = -version-info 0:0:0
libfrrsnmp_la_LIBADD = libfrr.la $(SNMP_LIBS)
libfrrsnmp_la_SOURCES = \
agentx.c \
smux.c \
snmp.c \
#end
pkginclude_HEADERS = \
frratomic.h \
buffer.h checksum.h filter.h getopt.h hash.h \
if.h linklist.h log.h \
graph.h command_match.h \
command_graph.h \
command.h \
memory.h network.h prefix.h routemap.h distribute.h sockunion.h \
stream.h table.h thread.h vector.h version.h vty.h zebra.h \
plist.h zclient.h sockopt.h smux.h md5.h if_rmap.h keychain.h \
privs.h sigevent.h pqueue.h jhash.h zassert.h \
workqueue.h route_types.h libospf.h nexthop.h json.h \
ptm_lib.h csv.h bfd.h vrf.h ns.h systemd.h bitfield.h \
fifo.h memory_vty.h mpls.h imsg.h openbsd-queue.h openbsd-tree.h \
skiplist.h qobj.h wheel.h \
event_counter.h \
monotime.h \
spf_backoff.h \
srcdest_table.h \
module.h \
hook.h \
libfrr.h \
sha256.h \
frr_pthread.h \
vrf_int.h \
termtable.h \
vlan.h \
vxlan.h \
ipaddr.h \
# end
noinst_HEADERS = \
plist_int.h \
log_int.h \
clippy.h \
# end
noinst_PROGRAMS = grammar_sandbox
if BUILD_CLIPPY
noinst_PROGRAMS += clippy
endif
grammar_sandbox_SOURCES = grammar_sandbox_main.c
grammar_sandbox_LDADD = libfrr.la
clippy_SOURCES = \
defun_lex.l \
command_parse.y \
command_lex.l \
command_graph.c \
command_py.c \
memory.c \
graph.c \
vector.c \
clippy.c \
# end
clippy_CPPFLAGS = -D_GNU_SOURCE
clippy_CFLAGS = $(PYTHON_CFLAGS)
clippy_LDADD = $(PYTHON_LIBS)
clippy-command_graph.$(OBJEXT): route_types.h
plist.lo: plist_clippy.c
EXTRA_DIST = \
queue.h \
command_lex.h \
route_types.pl route_types.txt \
gitversion.pl
route_types.h: $(srcdir)/route_types.txt $(srcdir)/route_types.pl
@PERL@ $(srcdir)/route_types.pl < $(srcdir)/route_types.txt > $@
if GIT_VERSION
# bit of a trick here to always have up-to-date git stamps without triggering
# unneccessary rebuilds. .PHONY causes the .tmp file to be rebuilt always,
# but if we use that on gitversion.h it'll ripple through the .c file deps.
# (even if gitversion.h's file timestamp doesn't change, make will think it
# did, because of .PHONY...)
.PHONY: gitversion.h.tmp
.SILENT: gitversion.h gitversion.h.tmp
GITH=gitversion.h
gitversion.h.tmp: $(srcdir)/../.git
@PERL@ $(srcdir)/gitversion.pl $(srcdir) > ${GITH}.tmp
gitversion.h: gitversion.h.tmp
{ test -f ${GITH} && diff -s -q ${GITH}.tmp ${GITH}; } || cp -v ${GITH}.tmp ${GITH}
else
.PHONY: gitversion.h
gitversion.h:
true
endif

View File

@ -47,6 +47,74 @@ DEFINE_MTYPE(LIB, HOST, "Host config")
DEFINE_MTYPE(LIB, STRVEC, "String vector")
DEFINE_MTYPE(LIB, COMPLETION, "Completion item")
const char *node_names[] = {
"auth", // AUTH_NODE,
"view", // VIEW_NODE,
"auth enable", // AUTH_ENABLE_NODE,
"enable", // ENABLE_NODE,
"config", // CONFIG_NODE,
"service", // SERVICE_NODE,
"debug", // DEBUG_NODE,
"vrf debug", // VRF_DEBUG_NODE,
"vnc debug", // DEBUG_VNC_NODE,
"aaa", // AAA_NODE,
"keychain", // KEYCHAIN_NODE,
"keychain key", // KEYCHAIN_KEY_NODE,
"logical-router", // NS_NODE,
"vrf", // VRF_NODE,
"interface", // INTERFACE_NODE,
"zebra", // ZEBRA_NODE,
"table", // TABLE_NODE,
"rip", // RIP_NODE,
"ripng", // RIPNG_NODE,
"babel", // BABEL_NODE,
"eigrp", // EIGRP_NODE,
"bgp", // BGP_NODE,
"bgp vpnv4", // BGP_VPNV4_NODE,
"bgp vpnv6", // BGP_VPNV6_NODE,
"bgp ipv4 unicast", // BGP_IPV4_NODE,
"bgp ipv4 multicast", // BGP_IPV4M_NODE,
"bgp ipv4 labeled unicast", // BGP_IPV4L_NODE,
"bgp ipv6", // BGP_IPV6_NODE,
"bgp ipv6 multicast", // BGP_IPV6M_NODE,
"bgp ipv6 labeled unicast", // BGP_IPV6L_NODE,
"bgp vrf policy", // BGP_VRF_POLICY_NODE,
"bgp vnc defaults", // BGP_VNC_DEFAULTS_NODE,
"bgp vnc nve", // BGP_VNC_NVE_GROUP_NODE,
"bgp vnc l2", // BGP_VNC_L2_GROUP_NODE,
"rfp defaults", // RFP_DEFAULTS_NODE,
"bgp evpn", // BGP_EVPN_NODE,
"ospf", // OSPF_NODE,
"ospf6", // OSPF6_NODE,
"ldp", // LDP_NODE,
"ldp ipv4", // LDP_IPV4_NODE,
"ldp ipv6", // LDP_IPV6_NODE,
"ldp ipv4 interface", // LDP_IPV4_IFACE_NODE,
"ldp ipv6 interface", // LDP_IPV6_IFACE_NODE,
"ldp l2vpn", // LDP_L2VPN_NODE,
"ldp", // LDP_PSEUDOWIRE_NODE,
"isis", // ISIS_NODE,
"pim", // PIM_NODE,
"masc", // MASC_NODE,
"irdp", // IRDP_NODE,
"static ip", // IP_NODE,
"ipv4 access list", // ACCESS_NODE,
"ipv4 prefix list", // PREFIX_NODE,
"ipv6 access list", // ACCESS_IPV6_NODE,
"ipv6 prefix list", // PREFIX_IPV6_NODE,
"as list", // AS_LIST_NODE,
"community list", // COMMUNITY_LIST_NODE,
"routemap", // RMAP_NODE,
"smux", // SMUX_NODE,
"dump", // DUMP_NODE,
"forwarding", // FORWARDING_NODE,
"protocol", // PROTOCOL_NODE,
"mpls", // MPLS_NODE,
"vty", // VTY_NODE,
"link-params", // LINK_PARAMS_NODE,
"bgp evpn vni", // BGP_EVPN_VNI_NODE,
};
/* Command vector which includes some level of command lists. Normally
each daemon maintains each own cmdvec. */
vector cmdvec = NULL;
@ -2355,6 +2423,35 @@ DEFUN (no_banner_motd,
return CMD_SUCCESS;
}
DEFUN(find,
find_cmd,
"find COMMAND...",
"Find CLI command containing text\n"
"Text to search for\n")
{
char *text = argv_concat(argv, argc, 1);
const struct cmd_node *node;
const struct cmd_element *cli;
vector clis;
for (unsigned int i = 0; i < vector_active(cmdvec); i++) {
node = vector_slot(cmdvec, i);
if (!node)
continue;
clis = node->cmd_vector;
for (unsigned int j = 0; j < vector_active(clis); j++) {
cli = vector_slot(clis, j);
if (strcasestr(cli->string, text))
vty_out(vty, " (%s) %s\n",
node_names[node->node], cli->string);
}
}
XFREE(MTYPE_TMP, text);
return CMD_SUCCESS;
}
/* Set config filename. Called from vty.c */
void host_config_set(const char *filename)
{
@ -2375,6 +2472,7 @@ void install_default(enum node_type node)
install_element(node, &config_end_cmd);
install_element(node, &config_help_cmd);
install_element(node, &config_list_cmd);
install_element(node, &find_cmd);
install_element(node, &config_write_cmd);
install_element(node, &show_running_config_cmd);
@ -2389,6 +2487,9 @@ void install_default(enum node_type node)
* terminal = -1 -- watchfrr / no logging, but minimal config control */
void cmd_init(int terminal)
{
if (array_size(node_names) != NODE_TYPE_MAX)
assert(!"Update the CLI node description array!");
qobj_init();
varhandlers = list_new();
@ -2416,6 +2517,8 @@ void cmd_init(int terminal)
/* Each node's basic commands. */
install_element(VIEW_NODE, &show_version_cmd);
install_element(ENABLE_NODE, &show_startup_config_cmd);
if (terminal) {
install_element(VIEW_NODE, &config_list_cmd);
install_element(VIEW_NODE, &config_exit_cmd);
@ -2428,20 +2531,16 @@ void cmd_init(int terminal)
install_element(VIEW_NODE, &show_commandtree_cmd);
install_element(VIEW_NODE, &echo_cmd);
install_element(VIEW_NODE, &autocomplete_cmd);
}
install_element(VIEW_NODE, &find_cmd);
if (terminal) {
install_element(ENABLE_NODE, &config_end_cmd);
install_element(ENABLE_NODE, &config_disable_cmd);
install_element(ENABLE_NODE, &config_terminal_cmd);
install_element(ENABLE_NODE, &copy_runningconf_startupconf_cmd);
install_element(ENABLE_NODE, &config_write_cmd);
install_element(ENABLE_NODE, &show_running_config_cmd);
}
install_element(ENABLE_NODE, &show_startup_config_cmd);
if (terminal) {
install_element(ENABLE_NODE, &config_logmsg_cmd);
install_default(CONFIG_NODE);
thread_cmd_init();

View File

@ -68,7 +68,7 @@ struct host {
char *motdfile;
};
/* There are some command levels which called from command node. */
/* List of CLI nodes. Please remember to update the name array in command.c. */
enum node_type {
AUTH_NODE, /* Authentication mode of vty interface. */
VIEW_NODE, /* View node. Default mode of vty interface. */
@ -135,8 +135,12 @@ enum node_type {
VTY_NODE, /* Vty node. */
LINK_PARAMS_NODE, /* Link-parameters node */
BGP_EVPN_VNI_NODE, /* BGP EVPN VNI */
NODE_TYPE_MAX, /* maximum */
};
extern vector cmdvec;
extern const char *node_names[];
/* Node which has some commands and prompt string and configuration
function pointer . */
struct cmd_node {

View File

@ -49,8 +49,8 @@ RANGE \({NUMBER}[ ]?\-[ ]?{NUMBER}\)
%option noyywrap
%option nounput
%option noinput
%option outfile="command_lex.c"
%option header-file="command_lex.h"
%option outfile="lib/command_lex.c"
%option header-file="lib/command_lex.h"
%option prefix="cmd_yy"
%option reentrant
%option bison-bridge

View File

@ -33,8 +33,8 @@
/* define api.prefix {cmd_yy} */
/* names for generated header and parser files */
%defines "command_parse.h"
%output "command_parse.c"
%defines "lib/command_parse.h"
%output "lib/command_parse.c"
/* note: code blocks are output in order, to both .c and .h:
* 1. %code requires

View File

@ -85,7 +85,7 @@ SPECIAL [(),]
%option noyywrap
%option noinput
%option nounput
%option outfile="defun_lex.c"
%option outfile="lib/defun_lex.c"
%option prefix="def_yy"
%option 8bit

View File

@ -49,7 +49,6 @@ struct hash *hash_create_size(unsigned int size,
hash->index =
XCALLOC(MTYPE_HASH_INDEX, sizeof(struct hash_backet *) * size);
hash->size = size;
hash->no_expand = 0;
hash->hash_key = hash_key;
hash->hash_cmp = hash_cmp;
hash->count = 0;
@ -91,10 +90,14 @@ void *hash_alloc_intern(void *arg)
/* Expand hash if the chain length exceeds the threshold. */
static void hash_expand(struct hash *hash)
{
unsigned int i, new_size, losers;
unsigned int i, new_size;
struct hash_backet *hb, *hbnext, **new_index;
new_size = hash->size * 2;
if (hash->max_size && new_size > hash->max_size)
return;
new_index = XCALLOC(MTYPE_HASH_INDEX,
sizeof(struct hash_backet *) * new_size);
if (new_index == NULL)
@ -128,22 +131,6 @@ static void hash_expand(struct hash *hash)
XFREE(MTYPE_HASH_INDEX, hash->index);
hash->size = new_size;
hash->index = new_index;
/* Ideally, new index should have chains half as long as the original.
* If expansion didn't help, then not worth expanding again,
* the problem is the hash function. */
losers = 0;
for (i = 0; i < hash->size; i++) {
unsigned int len = hash->index[i] ? hash->index[i]->len : 0;
if (len > HASH_THRESHOLD / 2)
++losers;
if (len >= HASH_THRESHOLD)
hash->no_expand = 1;
}
if (losers > hash->count / 2)
hash->no_expand = 1;
}
/* Lookup and return hash backet in hash. If there is no
@ -173,7 +160,7 @@ void *hash_get(struct hash *hash, void *data, void *(*alloc_func)(void *))
if (newdata == NULL)
return NULL;
if (len > HASH_THRESHOLD && !hash->no_expand) {
if (len > HASH_THRESHOLD) {
hash_expand(hash);
index = key & (hash->size - 1);
}

View File

@ -64,8 +64,8 @@ struct hash {
/* Hash table size. Must be power of 2 */
unsigned int size;
/* If expansion failed. */
int no_expand;
/* If max_size is 0 there is no limit */
unsigned int max_size;
/* Key make function. */
unsigned int (*hash_key)(void *);

View File

@ -21,13 +21,14 @@
#include "openbsd-queue.h"
#include "imsg.h"
int ibuf_realloc(struct ibuf *, size_t);
void ibuf_enqueue(struct msgbuf *, struct ibuf *);
void ibuf_dequeue(struct msgbuf *, struct ibuf *);
int ibuf_realloc(struct ibuf *, size_t);
void ibuf_enqueue(struct msgbuf *, struct ibuf *);
void ibuf_dequeue(struct msgbuf *, struct ibuf *);
struct ibuf *ibuf_open(size_t len)
struct ibuf *
ibuf_open(size_t len)
{
struct ibuf *buf;
struct ibuf *buf;
if ((buf = calloc(1, sizeof(struct ibuf))) == NULL)
return (NULL);
@ -41,9 +42,10 @@ struct ibuf *ibuf_open(size_t len)
return (buf);
}
struct ibuf *ibuf_dynamic(size_t len, size_t max)
struct ibuf *
ibuf_dynamic(size_t len, size_t max)
{
struct ibuf *buf;
struct ibuf *buf;
if (max < len)
return (NULL);
@ -57,9 +59,10 @@ struct ibuf *ibuf_dynamic(size_t len, size_t max)
return (buf);
}
int ibuf_realloc(struct ibuf *buf, size_t len)
int
ibuf_realloc(struct ibuf *buf, size_t len)
{
u_char *b;
u_char *b;
/* on static buffers max is eq size and so the following fails */
if (buf->wpos + len > buf->max) {
@ -76,7 +79,8 @@ int ibuf_realloc(struct ibuf *buf, size_t len)
return (0);
}
int ibuf_add(struct ibuf *buf, const void *data, size_t len)
int
ibuf_add(struct ibuf *buf, const void *data, size_t len)
{
if (buf->wpos + len > buf->size)
if (ibuf_realloc(buf, len) == -1)
@ -87,9 +91,10 @@ int ibuf_add(struct ibuf *buf, const void *data, size_t len)
return (0);
}
void *ibuf_reserve(struct ibuf *buf, size_t len)
void *
ibuf_reserve(struct ibuf *buf, size_t len)
{
void *b;
void *b;
if (buf->wpos + len > buf->size)
if (ibuf_realloc(buf, len) == -1)
@ -100,7 +105,8 @@ void *ibuf_reserve(struct ibuf *buf, size_t len)
return (b);
}
void *ibuf_seek(struct ibuf *buf, size_t pos, size_t len)
void *
ibuf_seek(struct ibuf *buf, size_t pos, size_t len)
{
/* only allowed to seek in already written parts */
if (pos + len > buf->wpos)
@ -109,31 +115,34 @@ void *ibuf_seek(struct ibuf *buf, size_t pos, size_t len)
return (buf->buf + pos);
}
size_t ibuf_size(struct ibuf *buf)
size_t
ibuf_size(struct ibuf *buf)
{
return (buf->wpos);
}
size_t ibuf_left(struct ibuf *buf)
size_t
ibuf_left(struct ibuf *buf)
{
return (buf->max - buf->wpos);
}
void ibuf_close(struct msgbuf *msgbuf, struct ibuf *buf)
void
ibuf_close(struct msgbuf *msgbuf, struct ibuf *buf)
{
ibuf_enqueue(msgbuf, buf);
}
int ibuf_write(struct msgbuf *msgbuf)
int
ibuf_write(struct msgbuf *msgbuf)
{
struct iovec iov[IOV_MAX];
struct ibuf *buf;
unsigned int i = 0;
ssize_t n;
struct iovec iov[IOV_MAX];
struct ibuf *buf;
unsigned int i = 0;
ssize_t n;
memset(&iov, 0, sizeof(iov));
TAILQ_FOREACH(buf, &msgbuf->bufs, entry)
{
TAILQ_FOREACH(buf, &msgbuf->bufs, entry) {
if (i >= IOV_MAX)
break;
iov[i].iov_base = buf->buf + buf->rpos;
@ -150,7 +159,7 @@ again:
return (-1);
}
if (n == 0) { /* connection closed */
if (n == 0) { /* connection closed */
errno = 0;
return (0);
}
@ -160,7 +169,8 @@ again:
return (1);
}
void ibuf_free(struct ibuf *buf)
void
ibuf_free(struct ibuf *buf)
{
if (buf == NULL)
return;
@ -168,19 +178,21 @@ void ibuf_free(struct ibuf *buf)
free(buf);
}
void msgbuf_init(struct msgbuf *msgbuf)
void
msgbuf_init(struct msgbuf *msgbuf)
{
msgbuf->queued = 0;
msgbuf->fd = -1;
TAILQ_INIT(&msgbuf->bufs);
}
void msgbuf_drain(struct msgbuf *msgbuf, size_t n)
void
msgbuf_drain(struct msgbuf *msgbuf, size_t n)
{
struct ibuf *buf, *next;
struct ibuf *buf, *next;
for (buf = TAILQ_FIRST(&msgbuf->bufs); buf != NULL && n > 0;
buf = next) {
buf = next) {
next = TAILQ_NEXT(buf, entry);
if (buf->rpos + n >= buf->wpos) {
n -= buf->wpos - buf->rpos;
@ -192,32 +204,33 @@ void msgbuf_drain(struct msgbuf *msgbuf, size_t n)
}
}
void msgbuf_clear(struct msgbuf *msgbuf)
void
msgbuf_clear(struct msgbuf *msgbuf)
{
struct ibuf *buf;
struct ibuf *buf;
while ((buf = TAILQ_FIRST(&msgbuf->bufs)) != NULL)
ibuf_dequeue(msgbuf, buf);
}
int msgbuf_write(struct msgbuf *msgbuf)
int
msgbuf_write(struct msgbuf *msgbuf)
{
struct iovec iov[IOV_MAX];
struct ibuf *buf;
unsigned int i = 0;
ssize_t n;
struct msghdr msg;
struct cmsghdr *cmsg;
struct iovec iov[IOV_MAX];
struct ibuf *buf;
unsigned int i = 0;
ssize_t n;
struct msghdr msg;
struct cmsghdr *cmsg;
union {
struct cmsghdr hdr;
char buf[CMSG_SPACE(sizeof(int))];
struct cmsghdr hdr;
char buf[CMSG_SPACE(sizeof(int))];
} cmsgbuf;
memset(&iov, 0, sizeof(iov));
memset(&msg, 0, sizeof(msg));
memset(&cmsgbuf, 0, sizeof(cmsgbuf));
TAILQ_FOREACH(buf, &msgbuf->bufs, entry)
{
TAILQ_FOREACH(buf, &msgbuf->bufs, entry) {
if (i >= IOV_MAX)
break;
iov[i].iov_base = buf->buf + buf->rpos;
@ -249,7 +262,7 @@ again:
return (-1);
}
if (n == 0) { /* connection closed */
if (n == 0) { /* connection closed */
errno = 0;
return (0);
}
@ -268,13 +281,15 @@ again:
return (1);
}
void ibuf_enqueue(struct msgbuf *msgbuf, struct ibuf *buf)
void
ibuf_enqueue(struct msgbuf *msgbuf, struct ibuf *buf)
{
TAILQ_INSERT_TAIL(&msgbuf->bufs, buf, entry);
msgbuf->queued++;
}
void ibuf_dequeue(struct msgbuf *msgbuf, struct ibuf *buf)
void
ibuf_dequeue(struct msgbuf *msgbuf, struct ibuf *buf)
{
TAILQ_REMOVE(&msgbuf->bufs, buf, entry);

View File

@ -21,21 +21,22 @@
#include "openbsd-queue.h"
#include "imsg.h"
int imsg_fd_overhead = 0;
int imsg_fd_overhead = 0;
int imsg_get_fd(struct imsgbuf *);
int imsg_get_fd(struct imsgbuf *);
#ifndef __OpenBSD__
/*
* The original code calls getdtablecount() which is OpenBSD specific. Use
* available_fds() from OpenSMTPD instead.
*/
static int available_fds(unsigned int n)
static int
available_fds(unsigned int n)
{
unsigned int i;
int ret, fds[256];
unsigned int i;
int ret, fds[256];
if (n > (sizeof(fds) / sizeof(fds[0])))
if (n > (sizeof(fds)/sizeof(fds[0])))
return (1);
ret = 0;
@ -58,7 +59,8 @@ static int available_fds(unsigned int n)
}
#endif
void imsg_init(struct imsgbuf *ibuf, int fd)
void
imsg_init(struct imsgbuf *ibuf, int fd)
{
msgbuf_init(&ibuf->w);
memset(&ibuf->r, 0, sizeof(ibuf->r));
@ -68,18 +70,19 @@ void imsg_init(struct imsgbuf *ibuf, int fd)
TAILQ_INIT(&ibuf->fds);
}
ssize_t imsg_read(struct imsgbuf *ibuf)
ssize_t
imsg_read(struct imsgbuf *ibuf)
{
struct msghdr msg;
struct cmsghdr *cmsg;
struct msghdr msg;
struct cmsghdr *cmsg;
union {
struct cmsghdr hdr;
char buf[CMSG_SPACE(sizeof(int) * 1)];
char buf[CMSG_SPACE(sizeof(int) * 1)];
} cmsgbuf;
struct iovec iov;
ssize_t n = -1;
int fd;
struct imsg_fd *ifd;
struct iovec iov;
ssize_t n = -1;
int fd;
struct imsg_fd *ifd;
memset(&msg, 0, sizeof(msg));
memset(&cmsgbuf, 0, sizeof(cmsgbuf));
@ -96,14 +99,12 @@ ssize_t imsg_read(struct imsgbuf *ibuf)
again:
#ifdef __OpenBSD__
if (getdtablecount() + imsg_fd_overhead
+ (int)((CMSG_SPACE(sizeof(int)) - CMSG_SPACE(0))
/ sizeof(int))
if (getdtablecount() + imsg_fd_overhead +
(int)((CMSG_SPACE(sizeof(int))-CMSG_SPACE(0))/sizeof(int))
>= getdtablesize()) {
#else
if (available_fds(imsg_fd_overhead
+ (CMSG_SPACE(sizeof(int)) - CMSG_SPACE(0))
/ sizeof(int))) {
if (available_fds(imsg_fd_overhead +
(CMSG_SPACE(sizeof(int))-CMSG_SPACE(0))/sizeof(int))) {
#endif
errno = EAGAIN;
free(ifd);
@ -119,9 +120,9 @@ again:
ibuf->r.wpos += n;
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
cmsg = CMSG_NXTHDR(&msg, cmsg)) {
if (cmsg->cmsg_level == SOL_SOCKET
&& cmsg->cmsg_type == SCM_RIGHTS) {
cmsg = CMSG_NXTHDR(&msg, cmsg)) {
if (cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SCM_RIGHTS) {
int i;
int j;
@ -130,15 +131,14 @@ again:
* padding rules, our control buffer might contain
* more than one fd, and we must close them.
*/
j = ((char *)cmsg + cmsg->cmsg_len
- (char *)CMSG_DATA(cmsg))
/ sizeof(int);
j = ((char *)cmsg + cmsg->cmsg_len -
(char *)CMSG_DATA(cmsg)) / sizeof(int);
for (i = 0; i < j; i++) {
fd = ((int *)CMSG_DATA(cmsg))[i];
if (ifd != NULL) {
ifd->fd = fd;
TAILQ_INSERT_TAIL(&ibuf->fds, ifd,
entry);
entry);
ifd = NULL;
} else
close(fd);
@ -152,9 +152,10 @@ fail:
return (n);
}
ssize_t imsg_get(struct imsgbuf *ibuf, struct imsg *imsg)
ssize_t
imsg_get(struct imsgbuf *ibuf, struct imsg *imsg)
{
size_t av, left, datalen;
size_t av, left, datalen;
av = ibuf->r.wpos;
@ -162,7 +163,8 @@ ssize_t imsg_get(struct imsgbuf *ibuf, struct imsg *imsg)
return (0);
memcpy(&imsg->hdr, ibuf->r.buf, sizeof(imsg->hdr));
if (imsg->hdr.len < IMSG_HEADER_SIZE || imsg->hdr.len > MAX_IMSGSIZE) {
if (imsg->hdr.len < IMSG_HEADER_SIZE ||
imsg->hdr.len > MAX_IMSGSIZE) {
errno = ERANGE;
return (-1);
}
@ -181,7 +183,7 @@ ssize_t imsg_get(struct imsgbuf *ibuf, struct imsg *imsg)
imsg->fd = -1;
if (imsg->data)
memcpy(imsg->data, ibuf->r.rptr, datalen);
memcpy(imsg->data, ibuf->r.rptr, datalen);
if (imsg->hdr.len < av) {
left = av - imsg->hdr.len;
@ -193,10 +195,11 @@ ssize_t imsg_get(struct imsgbuf *ibuf, struct imsg *imsg)
return (datalen + IMSG_HEADER_SIZE);
}
int imsg_compose(struct imsgbuf *ibuf, u_int32_t type, u_int32_t peerid,
pid_t pid, int fd, const void *data, u_int16_t datalen)
int
imsg_compose(struct imsgbuf *ibuf, u_int32_t type, u_int32_t peerid,
pid_t pid, int fd, const void *data, u_int16_t datalen)
{
struct ibuf *wbuf;
struct ibuf *wbuf;
if ((wbuf = imsg_create(ibuf, type, peerid, pid, datalen)) == NULL)
return (-1);
@ -211,11 +214,12 @@ int imsg_compose(struct imsgbuf *ibuf, u_int32_t type, u_int32_t peerid,
return (1);
}
int imsg_composev(struct imsgbuf *ibuf, u_int32_t type, u_int32_t peerid,
pid_t pid, int fd, const struct iovec *iov, int iovcnt)
int
imsg_composev(struct imsgbuf *ibuf, u_int32_t type, u_int32_t peerid,
pid_t pid, int fd, const struct iovec *iov, int iovcnt)
{
struct ibuf *wbuf;
int i, datalen = 0;
struct ibuf *wbuf;
int i, datalen = 0;
for (i = 0; i < iovcnt; i++)
datalen += iov[i].iov_len;
@ -235,11 +239,12 @@ int imsg_composev(struct imsgbuf *ibuf, u_int32_t type, u_int32_t peerid,
}
/* ARGSUSED */
struct ibuf *imsg_create(struct imsgbuf *ibuf, u_int32_t type, u_int32_t peerid,
pid_t pid, u_int16_t datalen)
struct ibuf *
imsg_create(struct imsgbuf *ibuf, u_int32_t type, u_int32_t peerid,
pid_t pid, u_int16_t datalen)
{
struct ibuf *wbuf;
struct imsg_hdr hdr;
struct ibuf *wbuf;
struct imsg_hdr hdr;
datalen += IMSG_HEADER_SIZE;
if (datalen > MAX_IMSGSIZE) {
@ -261,7 +266,8 @@ struct ibuf *imsg_create(struct imsgbuf *ibuf, u_int32_t type, u_int32_t peerid,
return (wbuf);
}
int imsg_add(struct ibuf *msg, const void *data, u_int16_t datalen)
int
imsg_add(struct ibuf *msg, const void *data, u_int16_t datalen)
{
if (datalen)
if (ibuf_add(msg, data, datalen) == -1) {
@ -271,9 +277,10 @@ int imsg_add(struct ibuf *msg, const void *data, u_int16_t datalen)
return (datalen);
}
void imsg_close(struct imsgbuf *ibuf, struct ibuf *msg)
void
imsg_close(struct imsgbuf *ibuf, struct ibuf *msg)
{
struct imsg_hdr *hdr;
struct imsg_hdr *hdr;
hdr = (struct imsg_hdr *)msg->buf;
@ -286,15 +293,17 @@ void imsg_close(struct imsgbuf *ibuf, struct ibuf *msg)
ibuf_close(&ibuf->w, msg);
}
void imsg_free(struct imsg *imsg)
void
imsg_free(struct imsg *imsg)
{
free(imsg->data);
}
int imsg_get_fd(struct imsgbuf *ibuf)
int
imsg_get_fd(struct imsgbuf *ibuf)
{
int fd;
struct imsg_fd *ifd;
int fd;
struct imsg_fd *ifd;
if ((ifd = TAILQ_FIRST(&ibuf->fds)) == NULL)
return (-1);
@ -306,7 +315,8 @@ int imsg_get_fd(struct imsgbuf *ibuf)
return (fd);
}
int imsg_flush(struct imsgbuf *ibuf)
int
imsg_flush(struct imsgbuf *ibuf)
{
while (ibuf->w.queued)
if (msgbuf_write(&ibuf->w) <= 0)
@ -314,9 +324,10 @@ int imsg_flush(struct imsgbuf *ibuf)
return (0);
}
void imsg_clear(struct imsgbuf *ibuf)
void
imsg_clear(struct imsgbuf *ibuf)
{
int fd;
int fd;
msgbuf_clear(&ibuf->w);
while ((fd = imsg_get_fd(ibuf)) != -1)

View File

@ -26,87 +26,87 @@
#define MAX_IMSGSIZE 16384
struct ibuf {
TAILQ_ENTRY(ibuf) entry;
u_char *buf;
size_t size;
size_t max;
size_t wpos;
size_t rpos;
int fd;
TAILQ_ENTRY(ibuf) entry;
u_char *buf;
size_t size;
size_t max;
size_t wpos;
size_t rpos;
int fd;
};
struct msgbuf {
TAILQ_HEAD(, ibuf) bufs;
u_int32_t queued;
int fd;
TAILQ_HEAD(, ibuf) bufs;
u_int32_t queued;
int fd;
};
struct ibuf_read {
u_char buf[IBUF_READ_SIZE];
u_char *rptr;
size_t wpos;
u_char buf[IBUF_READ_SIZE];
u_char *rptr;
size_t wpos;
};
struct imsg_fd {
TAILQ_ENTRY(imsg_fd) entry;
int fd;
TAILQ_ENTRY(imsg_fd) entry;
int fd;
};
struct imsgbuf {
TAILQ_HEAD(, imsg_fd) fds;
struct ibuf_read r;
struct msgbuf w;
int fd;
pid_t pid;
TAILQ_HEAD(, imsg_fd) fds;
struct ibuf_read r;
struct msgbuf w;
int fd;
pid_t pid;
};
#define IMSGF_HASFD 1
struct imsg_hdr {
u_int32_t type;
u_int16_t len;
u_int16_t flags;
u_int32_t peerid;
u_int32_t pid;
u_int32_t type;
u_int16_t len;
u_int16_t flags;
u_int32_t peerid;
u_int32_t pid;
};
struct imsg {
struct imsg_hdr hdr;
int fd;
void *data;
struct imsg_hdr hdr;
int fd;
void *data;
};
/* buffer.c */
struct ibuf *ibuf_open(size_t);
struct ibuf *ibuf_dynamic(size_t, size_t);
int ibuf_add(struct ibuf *, const void *, size_t);
void *ibuf_reserve(struct ibuf *, size_t);
void *ibuf_seek(struct ibuf *, size_t, size_t);
size_t ibuf_size(struct ibuf *);
size_t ibuf_left(struct ibuf *);
void ibuf_close(struct msgbuf *, struct ibuf *);
int ibuf_write(struct msgbuf *);
void ibuf_free(struct ibuf *);
void msgbuf_init(struct msgbuf *);
void msgbuf_clear(struct msgbuf *);
int msgbuf_write(struct msgbuf *);
void msgbuf_drain(struct msgbuf *, size_t);
struct ibuf *ibuf_open(size_t);
struct ibuf *ibuf_dynamic(size_t, size_t);
int ibuf_add(struct ibuf *, const void *, size_t);
void *ibuf_reserve(struct ibuf *, size_t);
void *ibuf_seek(struct ibuf *, size_t, size_t);
size_t ibuf_size(struct ibuf *);
size_t ibuf_left(struct ibuf *);
void ibuf_close(struct msgbuf *, struct ibuf *);
int ibuf_write(struct msgbuf *);
void ibuf_free(struct ibuf *);
void msgbuf_init(struct msgbuf *);
void msgbuf_clear(struct msgbuf *);
int msgbuf_write(struct msgbuf *);
void msgbuf_drain(struct msgbuf *, size_t);
/* imsg.c */
void imsg_init(struct imsgbuf *, int);
ssize_t imsg_read(struct imsgbuf *);
ssize_t imsg_get(struct imsgbuf *, struct imsg *);
int imsg_compose(struct imsgbuf *, u_int32_t, u_int32_t, pid_t, int,
const void *, u_int16_t);
int imsg_composev(struct imsgbuf *, u_int32_t, u_int32_t, pid_t, int,
const struct iovec *, int);
void imsg_init(struct imsgbuf *, int);
ssize_t imsg_read(struct imsgbuf *);
ssize_t imsg_get(struct imsgbuf *, struct imsg *);
int imsg_compose(struct imsgbuf *, u_int32_t, u_int32_t, pid_t,
int, const void *, u_int16_t);
int imsg_composev(struct imsgbuf *, u_int32_t, u_int32_t, pid_t,
int, const struct iovec *, int);
struct ibuf *imsg_create(struct imsgbuf *, u_int32_t, u_int32_t, pid_t,
u_int16_t);
int imsg_add(struct ibuf *, const void *, u_int16_t);
void imsg_close(struct imsgbuf *, struct ibuf *);
void imsg_free(struct imsg *);
int imsg_flush(struct imsgbuf *);
void imsg_clear(struct imsgbuf *);
u_int16_t);
int imsg_add(struct ibuf *, const void *, u_int16_t);
void imsg_close(struct imsgbuf *, struct ibuf *);
void imsg_free(struct imsg *);
int imsg_flush(struct imsgbuf *);
void imsg_clear(struct imsgbuf *);
#endif

View File

@ -133,17 +133,17 @@ void copy_nexthops(struct nexthop **tnh, struct nexthop *nh,
for (nh1 = nh; nh1; nh1 = nh1->next) {
nexthop = nexthop_new();
nexthop->ifindex = nh->ifindex;
nexthop->type = nh->type;
nexthop->flags = nh->flags;
memcpy(&nexthop->gate, &nh->gate, sizeof(nh->gate));
memcpy(&nexthop->src, &nh->src, sizeof(nh->src));
memcpy(&nexthop->rmap_src, &nh->rmap_src, sizeof(nh->rmap_src));
nexthop->ifindex = nh1->ifindex;
nexthop->type = nh1->type;
nexthop->flags = nh1->flags;
memcpy(&nexthop->gate, &nh1->gate, sizeof(nh1->gate));
memcpy(&nexthop->src, &nh1->src, sizeof(nh1->src));
memcpy(&nexthop->rmap_src, &nh1->rmap_src, sizeof(nh1->rmap_src));
nexthop->rparent = rparent;
if (nh->nh_label)
nexthop_add_labels(nexthop, nh->nh_label_type,
nh->nh_label->num_labels,
&nh->nh_label->label[0]);
if (nh1->nh_label)
nexthop_add_labels(nexthop, nh1->nh_label_type,
nh1->nh_label->num_labels,
&nh1->nh_label->label[0]);
nexthop_add(tnh, nexthop);
if (CHECK_FLAG(nh1->flags, NEXTHOP_FLAG_RECURSIVE))

View File

@ -45,14 +45,16 @@
#include <lib/openbsd-tree.h>
static inline struct rb_entry *rb_n2e(const struct rb_type *t, void *node)
static inline struct rb_entry *
rb_n2e(const struct rb_type *t, void *node)
{
unsigned long addr = (unsigned long)node;
return ((struct rb_entry *)(addr + t->t_offset));
}
static inline void *rb_e2n(const struct rb_type *t, struct rb_entry *rbe)
static inline void *
rb_e2n(const struct rb_type *t, struct rb_entry *rbe)
{
unsigned long addr = (unsigned long)rbe;
@ -66,33 +68,37 @@ static inline void *rb_e2n(const struct rb_type *t, struct rb_entry *rbe)
#define RBH_ROOT(_rbt) (_rbt)->rbt_root
static inline void rbe_set(struct rb_entry *rbe, struct rb_entry *parent)
static inline void
rbe_set(struct rb_entry *rbe, struct rb_entry *parent)
{
RBE_PARENT(rbe) = parent;
RBE_LEFT(rbe) = RBE_RIGHT(rbe) = NULL;
RBE_COLOR(rbe) = RB_RED;
}
static inline void rbe_set_blackred(struct rb_entry *black,
struct rb_entry *red)
static inline void
rbe_set_blackred(struct rb_entry *black, struct rb_entry *red)
{
RBE_COLOR(black) = RB_BLACK;
RBE_COLOR(red) = RB_RED;
}
static inline void rbe_augment(const struct rb_type *t, struct rb_entry *rbe)
static inline void
rbe_augment(const struct rb_type *t, struct rb_entry *rbe)
{
(*t->t_augment)(rb_e2n(t, rbe));
}
static inline void rbe_if_augment(const struct rb_type *t, struct rb_entry *rbe)
static inline void
rbe_if_augment(const struct rb_type *t, struct rb_entry *rbe)
{
if (t->t_augment != NULL)
rbe_augment(t, rbe);
}
static inline void rbe_rotate_left(const struct rb_type *t,
struct rbt_tree *rbt, struct rb_entry *rbe)
static inline void
rbe_rotate_left(const struct rb_type *t, struct rbt_tree *rbt,
struct rb_entry *rbe)
{
struct rb_entry *parent;
struct rb_entry *tmp;
@ -124,8 +130,9 @@ static inline void rbe_rotate_left(const struct rb_type *t,
}
}
static inline void rbe_rotate_right(const struct rb_type *t,
struct rbt_tree *rbt, struct rb_entry *rbe)
static inline void
rbe_rotate_right(const struct rb_type *t, struct rbt_tree *rbt,
struct rb_entry *rbe)
{
struct rb_entry *parent;
struct rb_entry *tmp;
@ -157,13 +164,14 @@ static inline void rbe_rotate_right(const struct rb_type *t,
}
}
static inline void rbe_insert_color(const struct rb_type *t,
struct rbt_tree *rbt, struct rb_entry *rbe)
static inline void
rbe_insert_color(const struct rb_type *t, struct rbt_tree *rbt,
struct rb_entry *rbe)
{
struct rb_entry *parent, *gparent, *tmp;
while ((parent = RBE_PARENT(rbe)) != NULL
&& RBE_COLOR(parent) == RB_RED) {
while ((parent = RBE_PARENT(rbe)) != NULL &&
RBE_COLOR(parent) == RB_RED) {
gparent = RBE_PARENT(parent);
if (parent == RBE_LEFT(gparent)) {
@ -208,19 +216,14 @@ static inline void rbe_insert_color(const struct rb_type *t,
RBE_COLOR(RBH_ROOT(rbt)) = RB_BLACK;
}
static inline void rbe_remove_color(const struct rb_type *t,
struct rbt_tree *rbt,
struct rb_entry *parent,
struct rb_entry *rbe)
static inline void
rbe_remove_color(const struct rb_type *t, struct rbt_tree *rbt,
struct rb_entry *parent, struct rb_entry *rbe)
{
struct rb_entry *tmp;
/* Silence clang possible NULL deference warning. */
if (parent == NULL)
return;
while ((rbe == NULL || RBE_COLOR(rbe) == RB_BLACK)
&& rbe != RBH_ROOT(rbt)) {
while ((rbe == NULL || RBE_COLOR(rbe) == RB_BLACK) &&
rbe != RBH_ROOT(rbt) && parent) {
if (RBE_LEFT(parent) == rbe) {
tmp = RBE_RIGHT(parent);
if (RBE_COLOR(tmp) == RB_RED) {
@ -228,16 +231,16 @@ static inline void rbe_remove_color(const struct rb_type *t,
rbe_rotate_left(t, rbt, parent);
tmp = RBE_RIGHT(parent);
}
if ((RBE_LEFT(tmp) == NULL
|| RBE_COLOR(RBE_LEFT(tmp)) == RB_BLACK)
&& (RBE_RIGHT(tmp) == NULL
|| RBE_COLOR(RBE_RIGHT(tmp)) == RB_BLACK)) {
if ((RBE_LEFT(tmp) == NULL ||
RBE_COLOR(RBE_LEFT(tmp)) == RB_BLACK) &&
(RBE_RIGHT(tmp) == NULL ||
RBE_COLOR(RBE_RIGHT(tmp)) == RB_BLACK)) {
RBE_COLOR(tmp) = RB_RED;
rbe = parent;
parent = RBE_PARENT(rbe);
} else {
if (RBE_RIGHT(tmp) == NULL
|| RBE_COLOR(RBE_RIGHT(tmp)) == RB_BLACK) {
if (RBE_RIGHT(tmp) == NULL ||
RBE_COLOR(RBE_RIGHT(tmp)) == RB_BLACK) {
struct rb_entry *oleft;
oleft = RBE_LEFT(tmp);
@ -266,16 +269,16 @@ static inline void rbe_remove_color(const struct rb_type *t,
tmp = RBE_LEFT(parent);
}
if ((RBE_LEFT(tmp) == NULL
|| RBE_COLOR(RBE_LEFT(tmp)) == RB_BLACK)
&& (RBE_RIGHT(tmp) == NULL
|| RBE_COLOR(RBE_RIGHT(tmp)) == RB_BLACK)) {
if ((RBE_LEFT(tmp) == NULL ||
RBE_COLOR(RBE_LEFT(tmp)) == RB_BLACK) &&
(RBE_RIGHT(tmp) == NULL ||
RBE_COLOR(RBE_RIGHT(tmp)) == RB_BLACK)) {
RBE_COLOR(tmp) = RB_RED;
rbe = parent;
parent = RBE_PARENT(rbe);
} else {
if (RBE_LEFT(tmp) == NULL
|| RBE_COLOR(RBE_LEFT(tmp)) == RB_BLACK) {
if (RBE_LEFT(tmp) == NULL ||
RBE_COLOR(RBE_LEFT(tmp)) == RB_BLACK) {
struct rb_entry *oright;
oright = RBE_RIGHT(tmp);
@ -385,7 +388,8 @@ color:
return (old);
}
void *_rb_remove(const struct rb_type *t, struct rbt_tree *rbt, void *elm)
void *
_rb_remove(const struct rb_type *t, struct rbt_tree *rbt, void *elm)
{
struct rb_entry *rbe = rb_n2e(t, elm);
struct rb_entry *old;
@ -395,7 +399,8 @@ void *_rb_remove(const struct rb_type *t, struct rbt_tree *rbt, void *elm)
return (old == NULL ? NULL : rb_e2n(t, old));
}
void *_rb_insert(const struct rb_type *t, struct rbt_tree *rbt, void *elm)
void *
_rb_insert(const struct rb_type *t, struct rbt_tree *rbt, void *elm)
{
struct rb_entry *rbe = rb_n2e(t, elm);
struct rb_entry *tmp;
@ -435,7 +440,8 @@ void *_rb_insert(const struct rb_type *t, struct rbt_tree *rbt, void *elm)
}
/* Finds the node with the same key as elm */
void *_rb_find(const struct rb_type *t, struct rbt_tree *rbt, const void *key)
void *
_rb_find(const struct rb_type *t, struct rbt_tree *rbt, const void *key)
{
struct rb_entry *tmp = RBH_ROOT(rbt);
void *node;
@ -456,7 +462,8 @@ void *_rb_find(const struct rb_type *t, struct rbt_tree *rbt, const void *key)
}
/* Finds the first node greater than or equal to the search key */
void *_rb_nfind(const struct rb_type *t, struct rbt_tree *rbt, const void *key)
void *
_rb_nfind(const struct rb_type *t, struct rbt_tree *rbt, const void *key)
{
struct rb_entry *tmp = RBH_ROOT(rbt);
void *node;
@ -478,7 +485,8 @@ void *_rb_nfind(const struct rb_type *t, struct rbt_tree *rbt, const void *key)
return (res);
}
void *_rb_next(const struct rb_type *t, void *elm)
void *
_rb_next(const struct rb_type *t, void *elm)
{
struct rb_entry *rbe = rb_n2e(t, elm);
@ -487,11 +495,12 @@ void *_rb_next(const struct rb_type *t, void *elm)
while (RBE_LEFT(rbe) != NULL)
rbe = RBE_LEFT(rbe);
} else {
if (RBE_PARENT(rbe) && (rbe == RBE_LEFT(RBE_PARENT(rbe))))
if (RBE_PARENT(rbe) &&
(rbe == RBE_LEFT(RBE_PARENT(rbe))))
rbe = RBE_PARENT(rbe);
else {
while (RBE_PARENT(rbe)
&& (rbe == RBE_RIGHT(RBE_PARENT(rbe))))
while (RBE_PARENT(rbe) &&
(rbe == RBE_RIGHT(RBE_PARENT(rbe))))
rbe = RBE_PARENT(rbe);
rbe = RBE_PARENT(rbe);
}
@ -500,7 +509,8 @@ void *_rb_next(const struct rb_type *t, void *elm)
return (rbe == NULL ? NULL : rb_e2n(t, rbe));
}
void *_rb_prev(const struct rb_type *t, void *elm)
void *
_rb_prev(const struct rb_type *t, void *elm)
{
struct rb_entry *rbe = rb_n2e(t, elm);
@ -509,11 +519,12 @@ void *_rb_prev(const struct rb_type *t, void *elm)
while (RBE_RIGHT(rbe))
rbe = RBE_RIGHT(rbe);
} else {
if (RBE_PARENT(rbe) && (rbe == RBE_RIGHT(RBE_PARENT(rbe))))
if (RBE_PARENT(rbe) &&
(rbe == RBE_RIGHT(RBE_PARENT(rbe))))
rbe = RBE_PARENT(rbe);
else {
while (RBE_PARENT(rbe)
&& (rbe == RBE_LEFT(RBE_PARENT(rbe))))
while (RBE_PARENT(rbe) &&
(rbe == RBE_LEFT(RBE_PARENT(rbe))))
rbe = RBE_PARENT(rbe);
rbe = RBE_PARENT(rbe);
}
@ -522,14 +533,16 @@ void *_rb_prev(const struct rb_type *t, void *elm)
return (rbe == NULL ? NULL : rb_e2n(t, rbe));
}
void *_rb_root(const struct rb_type *t, struct rbt_tree *rbt)
void *
_rb_root(const struct rb_type *t, struct rbt_tree *rbt)
{
struct rb_entry *rbe = RBH_ROOT(rbt);
return (rbe == NULL ? rbe : rb_e2n(t, rbe));
}
void *_rb_min(const struct rb_type *t, struct rbt_tree *rbt)
void *
_rb_min(const struct rb_type *t, struct rbt_tree *rbt)
{
struct rb_entry *rbe = RBH_ROOT(rbt);
struct rb_entry *parent = NULL;
@ -542,7 +555,8 @@ void *_rb_min(const struct rb_type *t, struct rbt_tree *rbt)
return (parent == NULL ? NULL : rb_e2n(t, parent));
}
void *_rb_max(const struct rb_type *t, struct rbt_tree *rbt)
void *
_rb_max(const struct rb_type *t, struct rbt_tree *rbt)
{
struct rb_entry *rbe = RBH_ROOT(rbt);
struct rb_entry *parent = NULL;
@ -555,28 +569,32 @@ void *_rb_max(const struct rb_type *t, struct rbt_tree *rbt)
return (parent == NULL ? NULL : rb_e2n(t, parent));
}
void *_rb_left(const struct rb_type *t, void *node)
void *
_rb_left(const struct rb_type *t, void *node)
{
struct rb_entry *rbe = rb_n2e(t, node);
rbe = RBE_LEFT(rbe);
return (rbe == NULL ? NULL : rb_e2n(t, rbe));
}
void *_rb_right(const struct rb_type *t, void *node)
void *
_rb_right(const struct rb_type *t, void *node)
{
struct rb_entry *rbe = rb_n2e(t, node);
rbe = RBE_RIGHT(rbe);
return (rbe == NULL ? NULL : rb_e2n(t, rbe));
}
void *_rb_parent(const struct rb_type *t, void *node)
void *
_rb_parent(const struct rb_type *t, void *node)
{
struct rb_entry *rbe = rb_n2e(t, node);
rbe = RBE_PARENT(rbe);
return (rbe == NULL ? NULL : rb_e2n(t, rbe));
}
void _rb_set_left(const struct rb_type *t, void *node, void *left)
void
_rb_set_left(const struct rb_type *t, void *node, void *left)
{
struct rb_entry *rbe = rb_n2e(t, node);
struct rb_entry *rbl = (left == NULL) ? NULL : rb_n2e(t, left);
@ -584,7 +602,8 @@ void _rb_set_left(const struct rb_type *t, void *node, void *left)
RBE_LEFT(rbe) = rbl;
}
void _rb_set_right(const struct rb_type *t, void *node, void *right)
void
_rb_set_right(const struct rb_type *t, void *node, void *right)
{
struct rb_entry *rbe = rb_n2e(t, node);
struct rb_entry *rbr = (right == NULL) ? NULL : rb_n2e(t, right);
@ -592,7 +611,8 @@ void _rb_set_right(const struct rb_type *t, void *node, void *right)
RBE_RIGHT(rbe) = rbr;
}
void _rb_set_parent(const struct rb_type *t, void *node, void *parent)
void
_rb_set_parent(const struct rb_type *t, void *node, void *parent)
{
struct rb_entry *rbe = rb_n2e(t, node);
struct rb_entry *rbp = (parent == NULL) ? NULL : rb_n2e(t, parent);
@ -600,19 +620,21 @@ void _rb_set_parent(const struct rb_type *t, void *node, void *parent)
RBE_PARENT(rbe) = rbp;
}
void _rb_poison(const struct rb_type *t, void *node, unsigned long poison)
void
_rb_poison(const struct rb_type *t, void *node, unsigned long poison)
{
struct rb_entry *rbe = rb_n2e(t, node);
RBE_PARENT(rbe) = RBE_LEFT(rbe) = RBE_RIGHT(rbe) =
(struct rb_entry *)poison;
(struct rb_entry *)poison;
}
int _rb_check(const struct rb_type *t, void *node, unsigned long poison)
int
_rb_check(const struct rb_type *t, void *node, unsigned long poison)
{
struct rb_entry *rbe = rb_n2e(t, node);
return ((unsigned long)RBE_PARENT(rbe) == poison
&& (unsigned long)RBE_LEFT(rbe) == poison
&& (unsigned long)RBE_RIGHT(rbe) == poison);
return ((unsigned long)RBE_PARENT(rbe) == poison &&
(unsigned long)RBE_LEFT(rbe) == poison &&
(unsigned long)RBE_RIGHT(rbe) == poison);
}

View File

@ -24,7 +24,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _SYS_TREE_H_
#ifndef _SYS_TREE_H_
#define _SYS_TREE_H_
/*
@ -54,26 +54,23 @@
* The maximum height of a red-black tree is 2lg (n+1).
*/
#define SPLAY_HEAD(name, type) \
struct name { \
struct type *sph_root; /* root of the tree */ \
}
#define SPLAY_HEAD(name, type) \
struct name { \
struct type *sph_root; /* root of the tree */ \
}
#define SPLAY_INITIALIZER(root) \
{ \
NULL \
}
#define SPLAY_INITIALIZER(root) \
{ NULL }
#define SPLAY_INIT(root) \
do { \
(root)->sph_root = NULL; \
} while (0)
#define SPLAY_INIT(root) do { \
(root)->sph_root = NULL; \
} while (0)
#define SPLAY_ENTRY(type) \
struct { \
struct type *spe_left; /* left element */ \
struct type *spe_right; /* right element */ \
}
#define SPLAY_ENTRY(type) \
struct { \
struct type *spe_left; /* left element */ \
struct type *spe_right; /* right element */ \
}
#define SPLAY_LEFT(elm, field) (elm)->field.spe_left
#define SPLAY_RIGHT(elm, field) (elm)->field.spe_right
@ -81,220 +78,197 @@
#define SPLAY_EMPTY(head) (SPLAY_ROOT(head) == NULL)
/* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */
#define SPLAY_ROTATE_RIGHT(head, tmp, field) \
do { \
SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field); \
SPLAY_RIGHT(tmp, field) = (head)->sph_root; \
(head)->sph_root = tmp; \
} while (0)
#define SPLAY_ROTATE_RIGHT(head, tmp, field) do { \
SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field); \
SPLAY_RIGHT(tmp, field) = (head)->sph_root; \
(head)->sph_root = tmp; \
} while (0)
#define SPLAY_ROTATE_LEFT(head, tmp, field) \
do { \
SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field); \
SPLAY_LEFT(tmp, field) = (head)->sph_root; \
(head)->sph_root = tmp; \
} while (0)
#define SPLAY_ROTATE_LEFT(head, tmp, field) do { \
SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field); \
SPLAY_LEFT(tmp, field) = (head)->sph_root; \
(head)->sph_root = tmp; \
} while (0)
#define SPLAY_LINKLEFT(head, tmp, field) \
do { \
SPLAY_LEFT(tmp, field) = (head)->sph_root; \
tmp = (head)->sph_root; \
(head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \
} while (0)
#define SPLAY_LINKLEFT(head, tmp, field) do { \
SPLAY_LEFT(tmp, field) = (head)->sph_root; \
tmp = (head)->sph_root; \
(head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \
} while (0)
#define SPLAY_LINKRIGHT(head, tmp, field) \
do { \
SPLAY_RIGHT(tmp, field) = (head)->sph_root; \
tmp = (head)->sph_root; \
(head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \
} while (0)
#define SPLAY_LINKRIGHT(head, tmp, field) do { \
SPLAY_RIGHT(tmp, field) = (head)->sph_root; \
tmp = (head)->sph_root; \
(head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \
} while (0)
#define SPLAY_ASSEMBLE(head, node, left, right, field) \
do { \
SPLAY_RIGHT(left, field) = \
SPLAY_LEFT((head)->sph_root, field); \
SPLAY_LEFT(right, field) = \
SPLAY_RIGHT((head)->sph_root, field); \
SPLAY_LEFT((head)->sph_root, field) = \
SPLAY_RIGHT(node, field); \
SPLAY_RIGHT((head)->sph_root, field) = \
SPLAY_LEFT(node, field); \
} while (0)
#define SPLAY_ASSEMBLE(head, node, left, right, field) do { \
SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field); \
SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field);\
SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field); \
SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field); \
} while (0)
/* Generates prototypes and inline functions */
#define SPLAY_PROTOTYPE(name, type, field, cmp) \
void name##_SPLAY(struct name *, struct type *); \
void name##_SPLAY_MINMAX(struct name *, int); \
struct type *name##_SPLAY_INSERT(struct name *, struct type *); \
struct type *name##_SPLAY_REMOVE(struct name *, struct type *); \
\
/* Finds the node with the same key as elm */ \
static __inline struct type *name##_SPLAY_FIND(struct name *head, \
struct type *elm) \
{ \
if (SPLAY_EMPTY(head)) \
return (NULL); \
name##_SPLAY(head, elm); \
if ((cmp)(elm, (head)->sph_root) == 0) \
return (head->sph_root); \
return (NULL); \
} \
\
static __inline struct type *name##_SPLAY_NEXT(struct name *head, \
struct type *elm) \
{ \
name##_SPLAY(head, elm); \
if (SPLAY_RIGHT(elm, field) != NULL) { \
elm = SPLAY_RIGHT(elm, field); \
while (SPLAY_LEFT(elm, field) != NULL) { \
elm = SPLAY_LEFT(elm, field); \
} \
} else \
elm = NULL; \
return (elm); \
} \
\
static __inline struct type *name##_SPLAY_MIN_MAX(struct name *head, \
int val) \
{ \
name##_SPLAY_MINMAX(head, val); \
return (SPLAY_ROOT(head)); \
}
#define SPLAY_PROTOTYPE(name, type, field, cmp) \
void name##_SPLAY(struct name *, struct type *); \
void name##_SPLAY_MINMAX(struct name *, int); \
struct type *name##_SPLAY_INSERT(struct name *, struct type *); \
struct type *name##_SPLAY_REMOVE(struct name *, struct type *); \
\
/* Finds the node with the same key as elm */ \
static __inline struct type * \
name##_SPLAY_FIND(struct name *head, struct type *elm) \
{ \
if (SPLAY_EMPTY(head)) \
return(NULL); \
name##_SPLAY(head, elm); \
if ((cmp)(elm, (head)->sph_root) == 0) \
return (head->sph_root); \
return (NULL); \
} \
\
static __inline struct type * \
name##_SPLAY_NEXT(struct name *head, struct type *elm) \
{ \
name##_SPLAY(head, elm); \
if (SPLAY_RIGHT(elm, field) != NULL) { \
elm = SPLAY_RIGHT(elm, field); \
while (SPLAY_LEFT(elm, field) != NULL) { \
elm = SPLAY_LEFT(elm, field); \
} \
} else \
elm = NULL; \
return (elm); \
} \
\
static __inline struct type * \
name##_SPLAY_MIN_MAX(struct name *head, int val) \
{ \
name##_SPLAY_MINMAX(head, val); \
return (SPLAY_ROOT(head)); \
}
/* Main splay operation.
* Moves node close to the key of elm to top
*/
#define SPLAY_GENERATE(name, type, field, cmp) \
struct type *name##_SPLAY_INSERT(struct name *head, struct type *elm) \
{ \
if (SPLAY_EMPTY(head)) { \
SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = \
NULL; \
} else { \
int __comp; \
name##_SPLAY(head, elm); \
__comp = (cmp)(elm, (head)->sph_root); \
if (__comp < 0) { \
SPLAY_LEFT(elm, field) = \
SPLAY_LEFT((head)->sph_root, field); \
SPLAY_RIGHT(elm, field) = (head)->sph_root; \
SPLAY_LEFT((head)->sph_root, field) = NULL; \
} else if (__comp > 0) { \
SPLAY_RIGHT(elm, field) = \
SPLAY_RIGHT((head)->sph_root, field); \
SPLAY_LEFT(elm, field) = (head)->sph_root; \
SPLAY_RIGHT((head)->sph_root, field) = NULL; \
} else \
return ((head)->sph_root); \
} \
(head)->sph_root = (elm); \
return (NULL); \
} \
\
struct type *name##_SPLAY_REMOVE(struct name *head, struct type *elm) \
{ \
struct type *__tmp; \
if (SPLAY_EMPTY(head)) \
return (NULL); \
name##_SPLAY(head, elm); \
if ((cmp)(elm, (head)->sph_root) == 0) { \
if (SPLAY_LEFT((head)->sph_root, field) == NULL) { \
(head)->sph_root = \
SPLAY_RIGHT((head)->sph_root, field); \
} else { \
__tmp = SPLAY_RIGHT((head)->sph_root, field); \
(head)->sph_root = \
SPLAY_LEFT((head)->sph_root, field); \
name##_SPLAY(head, elm); \
SPLAY_RIGHT((head)->sph_root, field) = __tmp; \
} \
return (elm); \
} \
return (NULL); \
} \
\
void name##_SPLAY(struct name *head, struct type *elm) \
{ \
struct type __node, *__left, *__right, *__tmp; \
int __comp; \
\
SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = \
NULL; \
__left = __right = &__node; \
\
while ((__comp = (cmp)(elm, (head)->sph_root))) { \
if (__comp < 0) { \
__tmp = SPLAY_LEFT((head)->sph_root, field); \
if (__tmp == NULL) \
break; \
if ((cmp)(elm, __tmp) < 0) { \
SPLAY_ROTATE_RIGHT(head, __tmp, \
field); \
if (SPLAY_LEFT((head)->sph_root, \
field) \
== NULL) \
break; \
} \
SPLAY_LINKLEFT(head, __right, field); \
} else if (__comp > 0) { \
__tmp = SPLAY_RIGHT((head)->sph_root, field); \
if (__tmp == NULL) \
break; \
if ((cmp)(elm, __tmp) > 0) { \
SPLAY_ROTATE_LEFT(head, __tmp, field); \
if (SPLAY_RIGHT((head)->sph_root, \
field) \
== NULL) \
break; \
} \
SPLAY_LINKRIGHT(head, __left, field); \
} \
} \
SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \
} \
\
/* Splay with either the minimum or the maximum element \
* Used to find minimum or maximum element in tree. \
*/ \
void name##_SPLAY_MINMAX(struct name *head, int __comp) \
{ \
struct type __node, *__left, *__right, *__tmp; \
\
SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = \
NULL; \
__left = __right = &__node; \
\
while (1) { \
if (__comp < 0) { \
__tmp = SPLAY_LEFT((head)->sph_root, field); \
if (__tmp == NULL) \
break; \
if (__comp < 0) { \
SPLAY_ROTATE_RIGHT(head, __tmp, \
field); \
if (SPLAY_LEFT((head)->sph_root, \
field) \
== NULL) \
break; \
} \
SPLAY_LINKLEFT(head, __right, field); \
} else if (__comp > 0) { \
__tmp = SPLAY_RIGHT((head)->sph_root, field); \
if (__tmp == NULL) \
break; \
if (__comp > 0) { \
SPLAY_ROTATE_LEFT(head, __tmp, field); \
if (SPLAY_RIGHT((head)->sph_root, \
field) \
== NULL) \
break; \
} \
SPLAY_LINKRIGHT(head, __left, field); \
} \
} \
SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \
}
#define SPLAY_GENERATE(name, type, field, cmp) \
struct type * \
name##_SPLAY_INSERT(struct name *head, struct type *elm) \
{ \
if (SPLAY_EMPTY(head)) { \
SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL; \
} else { \
int __comp; \
name##_SPLAY(head, elm); \
__comp = (cmp)(elm, (head)->sph_root); \
if(__comp < 0) { \
SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field);\
SPLAY_RIGHT(elm, field) = (head)->sph_root; \
SPLAY_LEFT((head)->sph_root, field) = NULL; \
} else if (__comp > 0) { \
SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field);\
SPLAY_LEFT(elm, field) = (head)->sph_root; \
SPLAY_RIGHT((head)->sph_root, field) = NULL; \
} else \
return ((head)->sph_root); \
} \
(head)->sph_root = (elm); \
return (NULL); \
} \
\
struct type * \
name##_SPLAY_REMOVE(struct name *head, struct type *elm) \
{ \
struct type *__tmp; \
if (SPLAY_EMPTY(head)) \
return (NULL); \
name##_SPLAY(head, elm); \
if ((cmp)(elm, (head)->sph_root) == 0) { \
if (SPLAY_LEFT((head)->sph_root, field) == NULL) { \
(head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);\
} else { \
__tmp = SPLAY_RIGHT((head)->sph_root, field); \
(head)->sph_root = SPLAY_LEFT((head)->sph_root, field);\
name##_SPLAY(head, elm); \
SPLAY_RIGHT((head)->sph_root, field) = __tmp; \
} \
return (elm); \
} \
return (NULL); \
} \
\
void \
name##_SPLAY(struct name *head, struct type *elm) \
{ \
struct type __node, *__left, *__right, *__tmp; \
int __comp; \
\
SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\
__left = __right = &__node; \
\
while ((__comp = (cmp)(elm, (head)->sph_root))) { \
if (__comp < 0) { \
__tmp = SPLAY_LEFT((head)->sph_root, field); \
if (__tmp == NULL) \
break; \
if ((cmp)(elm, __tmp) < 0){ \
SPLAY_ROTATE_RIGHT(head, __tmp, field); \
if (SPLAY_LEFT((head)->sph_root, field) == NULL)\
break; \
} \
SPLAY_LINKLEFT(head, __right, field); \
} else if (__comp > 0) { \
__tmp = SPLAY_RIGHT((head)->sph_root, field); \
if (__tmp == NULL) \
break; \
if ((cmp)(elm, __tmp) > 0){ \
SPLAY_ROTATE_LEFT(head, __tmp, field); \
if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\
break; \
} \
SPLAY_LINKRIGHT(head, __left, field); \
} \
} \
SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \
} \
\
/* Splay with either the minimum or the maximum element \
* Used to find minimum or maximum element in tree. \
*/ \
void name##_SPLAY_MINMAX(struct name *head, int __comp) \
{ \
struct type __node, *__left, *__right, *__tmp; \
\
SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\
__left = __right = &__node; \
\
while (1) { \
if (__comp < 0) { \
__tmp = SPLAY_LEFT((head)->sph_root, field); \
if (__tmp == NULL) \
break; \
if (__comp < 0){ \
SPLAY_ROTATE_RIGHT(head, __tmp, field); \
if (SPLAY_LEFT((head)->sph_root, field) == NULL)\
break; \
} \
SPLAY_LINKLEFT(head, __right, field); \
} else if (__comp > 0) { \
__tmp = SPLAY_RIGHT((head)->sph_root, field); \
if (__tmp == NULL) \
break; \
if (__comp > 0) { \
SPLAY_ROTATE_LEFT(head, __tmp, field); \
if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\
break; \
} \
SPLAY_LINKRIGHT(head, __left, field); \
} \
} \
SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \
}
#define SPLAY_NEGINF -1
#define SPLAY_INF 1
@ -303,13 +277,14 @@
#define SPLAY_REMOVE(name, x, y) name##_SPLAY_REMOVE(x, y)
#define SPLAY_FIND(name, x, y) name##_SPLAY_FIND(x, y)
#define SPLAY_NEXT(name, x, y) name##_SPLAY_NEXT(x, y)
#define SPLAY_MIN(name, x) \
(SPLAY_EMPTY(x) ? NULL : name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF))
#define SPLAY_MAX(name, x) \
(SPLAY_EMPTY(x) ? NULL : name##_SPLAY_MIN_MAX(x, SPLAY_INF))
#define SPLAY_MIN(name, x) (SPLAY_EMPTY(x) ? NULL \
: name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF))
#define SPLAY_MAX(name, x) (SPLAY_EMPTY(x) ? NULL \
: name##_SPLAY_MIN_MAX(x, SPLAY_INF))
#define SPLAY_FOREACH(x, name, head) \
for ((x) = SPLAY_MIN(name, head); (x) != NULL; \
#define SPLAY_FOREACH(x, name, head) \
for ((x) = SPLAY_MIN(name, head); \
(x) != NULL; \
(x) = SPLAY_NEXT(name, head, x))
/*
@ -332,197 +307,203 @@
#define RB_RED 1
struct rb_type {
int (*t_compare)(const void *, const void *);
void (*t_augment)(void *);
unsigned int t_offset; /* offset of rb_entry in type */
int (*t_compare)(const void *, const void *);
void (*t_augment)(void *);
unsigned int t_offset; /* offset of rb_entry in type */
};
struct rbt_tree {
struct rb_entry *rbt_root;
struct rb_entry *rbt_root;
};
struct rb_entry {
struct rb_entry *rbt_parent;
struct rb_entry *rbt_left;
struct rb_entry *rbt_right;
unsigned int rbt_color;
struct rb_entry *rbt_parent;
struct rb_entry *rbt_left;
struct rb_entry *rbt_right;
unsigned int rbt_color;
};
#define RB_HEAD(_name, _type) \
struct _name { \
struct rbt_tree rbh_root; \
}
#define RB_HEAD(_name, _type) \
struct _name { \
struct rbt_tree rbh_root; \
}
#define RB_ENTRY(_type) struct rb_entry
static inline void _rb_init(struct rbt_tree *rbt)
static inline void
_rb_init(struct rbt_tree *rbt)
{
rbt->rbt_root = NULL;
}
static inline int _rb_empty(struct rbt_tree *rbt)
static inline int
_rb_empty(struct rbt_tree *rbt)
{
return (rbt->rbt_root == NULL);
}
void *_rb_insert(const struct rb_type *, struct rbt_tree *, void *);
void *_rb_remove(const struct rb_type *, struct rbt_tree *, void *);
void *_rb_find(const struct rb_type *, struct rbt_tree *, const void *);
void *_rb_nfind(const struct rb_type *, struct rbt_tree *, const void *);
void *_rb_root(const struct rb_type *, struct rbt_tree *);
void *_rb_min(const struct rb_type *, struct rbt_tree *);
void *_rb_max(const struct rb_type *, struct rbt_tree *);
void *_rb_next(const struct rb_type *, void *);
void *_rb_prev(const struct rb_type *, void *);
void *_rb_left(const struct rb_type *, void *);
void *_rb_right(const struct rb_type *, void *);
void *_rb_parent(const struct rb_type *, void *);
void _rb_set_left(const struct rb_type *, void *, void *);
void _rb_set_right(const struct rb_type *, void *, void *);
void _rb_set_parent(const struct rb_type *, void *, void *);
void _rb_poison(const struct rb_type *, void *, unsigned long);
int _rb_check(const struct rb_type *, void *, unsigned long);
void *_rb_insert(const struct rb_type *, struct rbt_tree *, void *);
void *_rb_remove(const struct rb_type *, struct rbt_tree *, void *);
void *_rb_find(const struct rb_type *, struct rbt_tree *, const void *);
void *_rb_nfind(const struct rb_type *, struct rbt_tree *, const void *);
void *_rb_root(const struct rb_type *, struct rbt_tree *);
void *_rb_min(const struct rb_type *, struct rbt_tree *);
void *_rb_max(const struct rb_type *, struct rbt_tree *);
void *_rb_next(const struct rb_type *, void *);
void *_rb_prev(const struct rb_type *, void *);
void *_rb_left(const struct rb_type *, void *);
void *_rb_right(const struct rb_type *, void *);
void *_rb_parent(const struct rb_type *, void *);
void _rb_set_left(const struct rb_type *, void *, void *);
void _rb_set_right(const struct rb_type *, void *, void *);
void _rb_set_parent(const struct rb_type *, void *, void *);
void _rb_poison(const struct rb_type *, void *, unsigned long);
int _rb_check(const struct rb_type *, void *, unsigned long);
#define RB_INITIALIZER(_head) { { NULL } }
#define RB_PROTOTYPE(_name, _type, _field, _cmp) \
extern const struct rb_type *const _name##_RB_TYPE; \
\
__attribute__((__unused__)) static inline void _name##_RB_INIT( \
struct _name *head) \
{ \
_rb_init(&head->rbh_root); \
} \
\
__attribute__((__unused__)) static inline struct _type \
*_name##_RB_INSERT(struct _name *head, struct _type *elm) \
{ \
return _rb_insert(_name##_RB_TYPE, &head->rbh_root, elm); \
} \
\
__attribute__((__unused__)) static inline struct _type \
*_name##_RB_REMOVE(struct _name *head, struct _type *elm) \
{ \
return _rb_remove(_name##_RB_TYPE, &head->rbh_root, elm); \
} \
\
__attribute__((__unused__)) static inline struct _type \
*_name##_RB_FIND(struct _name *head, const struct _type *key) \
{ \
return _rb_find(_name##_RB_TYPE, &head->rbh_root, key); \
} \
\
__attribute__((__unused__)) static inline struct _type \
*_name##_RB_NFIND(struct _name *head, const struct _type *key) \
{ \
return _rb_nfind(_name##_RB_TYPE, &head->rbh_root, key); \
} \
\
__attribute__((__unused__)) static inline struct _type \
*_name##_RB_ROOT(struct _name *head) \
{ \
return _rb_root(_name##_RB_TYPE, &head->rbh_root); \
} \
\
__attribute__((__unused__)) static inline int _name##_RB_EMPTY( \
struct _name *head) \
{ \
return _rb_empty(&head->rbh_root); \
} \
\
__attribute__((__unused__)) static inline struct _type \
*_name##_RB_MIN(struct _name *head) \
{ \
return _rb_min(_name##_RB_TYPE, &head->rbh_root); \
} \
\
__attribute__((__unused__)) static inline struct _type \
*_name##_RB_MAX(struct _name *head) \
{ \
return _rb_max(_name##_RB_TYPE, &head->rbh_root); \
} \
\
__attribute__((__unused__)) static inline struct _type \
*_name##_RB_NEXT(struct _type *elm) \
{ \
return _rb_next(_name##_RB_TYPE, elm); \
} \
\
__attribute__((__unused__)) static inline struct _type \
*_name##_RB_PREV(struct _type *elm) \
{ \
return _rb_prev(_name##_RB_TYPE, elm); \
} \
\
__attribute__((__unused__)) static inline struct _type \
*_name##_RB_LEFT(struct _type *elm) \
{ \
return _rb_left(_name##_RB_TYPE, elm); \
} \
\
__attribute__((__unused__)) static inline struct _type \
*_name##_RB_RIGHT(struct _type *elm) \
{ \
return _rb_right(_name##_RB_TYPE, elm); \
} \
\
__attribute__((__unused__)) static inline struct _type \
*_name##_RB_PARENT(struct _type *elm) \
{ \
return _rb_parent(_name##_RB_TYPE, elm); \
} \
\
__attribute__((__unused__)) static inline void _name##_RB_SET_LEFT( \
struct _type *elm, struct _type *left) \
{ \
return _rb_set_left(_name##_RB_TYPE, elm, left); \
} \
\
__attribute__((__unused__)) static inline void _name##_RB_SET_RIGHT( \
struct _type *elm, struct _type *right) \
{ \
return _rb_set_right(_name##_RB_TYPE, elm, right); \
} \
\
__attribute__((__unused__)) static inline void _name##_RB_SET_PARENT( \
struct _type *elm, struct _type *parent) \
{ \
return _rb_set_parent(_name##_RB_TYPE, elm, parent); \
} \
\
__attribute__((__unused__)) static inline void _name##_RB_POISON( \
struct _type *elm, unsigned long poison) \
{ \
return _rb_poison(_name##_RB_TYPE, elm, poison); \
} \
\
__attribute__((__unused__)) static inline int _name##_RB_CHECK( \
struct _type *elm, unsigned long poison) \
{ \
return _rb_check(_name##_RB_TYPE, elm, poison); \
}
#define RB_PROTOTYPE(_name, _type, _field, _cmp) \
extern const struct rb_type *const _name##_RB_TYPE; \
\
__attribute__((__unused__)) static inline void \
_name##_RB_INIT(struct _name *head) \
{ \
_rb_init(&head->rbh_root); \
} \
\
__attribute__((__unused__)) static inline struct _type * \
_name##_RB_INSERT(struct _name *head, struct _type *elm) \
{ \
return _rb_insert(_name##_RB_TYPE, &head->rbh_root, elm); \
} \
\
__attribute__((__unused__)) static inline struct _type * \
_name##_RB_REMOVE(struct _name *head, struct _type *elm) \
{ \
return _rb_remove(_name##_RB_TYPE, &head->rbh_root, elm); \
} \
\
__attribute__((__unused__)) static inline struct _type * \
_name##_RB_FIND(struct _name *head, const struct _type *key) \
{ \
return _rb_find(_name##_RB_TYPE, &head->rbh_root, key); \
} \
\
__attribute__((__unused__)) static inline struct _type * \
_name##_RB_NFIND(struct _name *head, const struct _type *key) \
{ \
return _rb_nfind(_name##_RB_TYPE, &head->rbh_root, key); \
} \
\
__attribute__((__unused__)) static inline struct _type * \
_name##_RB_ROOT(struct _name *head) \
{ \
return _rb_root(_name##_RB_TYPE, &head->rbh_root); \
} \
\
__attribute__((__unused__)) static inline int \
_name##_RB_EMPTY(struct _name *head) \
{ \
return _rb_empty(&head->rbh_root); \
} \
\
__attribute__((__unused__)) static inline struct _type * \
_name##_RB_MIN(struct _name *head) \
{ \
return _rb_min(_name##_RB_TYPE, &head->rbh_root); \
} \
\
__attribute__((__unused__)) static inline struct _type * \
_name##_RB_MAX(struct _name *head) \
{ \
return _rb_max(_name##_RB_TYPE, &head->rbh_root); \
} \
\
__attribute__((__unused__)) static inline struct _type * \
_name##_RB_NEXT(struct _type *elm) \
{ \
return _rb_next(_name##_RB_TYPE, elm); \
} \
\
__attribute__((__unused__)) static inline struct _type * \
_name##_RB_PREV(struct _type *elm) \
{ \
return _rb_prev(_name##_RB_TYPE, elm); \
} \
\
__attribute__((__unused__)) static inline struct _type * \
_name##_RB_LEFT(struct _type *elm) \
{ \
return _rb_left(_name##_RB_TYPE, elm); \
} \
\
__attribute__((__unused__)) static inline struct _type * \
_name##_RB_RIGHT(struct _type *elm) \
{ \
return _rb_right(_name##_RB_TYPE, elm); \
} \
\
__attribute__((__unused__)) static inline struct _type * \
_name##_RB_PARENT(struct _type *elm) \
{ \
return _rb_parent(_name##_RB_TYPE, elm); \
} \
\
__attribute__((__unused__)) static inline void \
_name##_RB_SET_LEFT(struct _type *elm, struct _type *left) \
{ \
return _rb_set_left(_name##_RB_TYPE, elm, left); \
} \
\
__attribute__((__unused__)) static inline void \
_name##_RB_SET_RIGHT(struct _type *elm, struct _type *right) \
{ \
return _rb_set_right(_name##_RB_TYPE, elm, right); \
} \
\
__attribute__((__unused__)) static inline void \
_name##_RB_SET_PARENT(struct _type *elm, struct _type *parent) \
{ \
return _rb_set_parent(_name##_RB_TYPE, elm, parent); \
} \
\
__attribute__((__unused__)) static inline void \
_name##_RB_POISON(struct _type *elm, unsigned long poison) \
{ \
return _rb_poison(_name##_RB_TYPE, elm, poison); \
} \
\
__attribute__((__unused__)) static inline int \
_name##_RB_CHECK(struct _type *elm, unsigned long poison) \
{ \
return _rb_check(_name##_RB_TYPE, elm, poison); \
}
#define RB_GENERATE_INTERNAL(_name, _type, _field, _cmp, _aug) \
static int _name##_RB_COMPARE(const void *lptr, const void *rptr) \
{ \
const struct _type *l = lptr, *r = rptr; \
return _cmp(l, r); \
} \
static const struct rb_type _name##_RB_INFO = { \
_name##_RB_COMPARE, _aug, offsetof(struct _type, _field), \
}; \
const struct rb_type *const _name##_RB_TYPE = &_name##_RB_INFO;
#define RB_GENERATE_INTERNAL(_name, _type, _field, _cmp, _aug) \
static int \
_name##_RB_COMPARE(const void *lptr, const void *rptr) \
{ \
const struct _type *l = lptr, *r = rptr; \
return _cmp(l, r); \
} \
static const struct rb_type _name##_RB_INFO = { \
_name##_RB_COMPARE, \
_aug, \
offsetof(struct _type, _field), \
}; \
const struct rb_type *const _name##_RB_TYPE = &_name##_RB_INFO;
#define RB_GENERATE_AUGMENT(_name, _type, _field, _cmp, _aug) \
static void _name##_RB_AUGMENT(void *ptr) \
{ \
struct _type *p = ptr; \
return _aug(p); \
} \
RB_GENERATE_INTERNAL(_name, _type, _field, _cmp, _name##_RB_AUGMENT)
#define RB_GENERATE_AUGMENT(_name, _type, _field, _cmp, _aug) \
static void \
_name##_RB_AUGMENT(void *ptr) \
{ \
struct _type *p = ptr; \
return _aug(p); \
} \
RB_GENERATE_INTERNAL(_name, _type, _field, _cmp, _name##_RB_AUGMENT)
#define RB_GENERATE(_name, _type, _field, _cmp) \
RB_GENERATE_INTERNAL(_name, _type, _field, _cmp, NULL)
#define RB_GENERATE(_name, _type, _field, _cmp) \
RB_GENERATE_INTERNAL(_name, _type, _field, _cmp, NULL)
#define RB_INIT(_name, _head) _name##_RB_INIT(_head)
#define RB_INSERT(_name, _head, _elm) _name##_RB_INSERT(_head, _elm)
@ -544,20 +525,24 @@ int _rb_check(const struct rb_type *, void *, unsigned long);
#define RB_POISON(_name, _elm, _p) _name##_RB_POISON(_elm, _p)
#define RB_CHECK(_name, _elm, _p) _name##_RB_CHECK(_elm, _p)
#define RB_FOREACH(_e, _name, _head) \
for ((_e) = RB_MIN(_name, (_head)); (_e) != NULL; \
#define RB_FOREACH(_e, _name, _head) \
for ((_e) = RB_MIN(_name, (_head)); \
(_e) != NULL; \
(_e) = RB_NEXT(_name, (_e)))
#define RB_FOREACH_SAFE(_e, _name, _head, _n) \
for ((_e) = RB_MIN(_name, (_head)); \
(_e) != NULL && ((_n) = RB_NEXT(_name, (_e)), 1); (_e) = (_n))
#define RB_FOREACH_SAFE(_e, _name, _head, _n) \
for ((_e) = RB_MIN(_name, (_head)); \
(_e) != NULL && ((_n) = RB_NEXT(_name, (_e)), 1); \
(_e) = (_n))
#define RB_FOREACH_REVERSE(_e, _name, _head) \
for ((_e) = RB_MAX(_name, (_head)); (_e) != NULL; \
#define RB_FOREACH_REVERSE(_e, _name, _head) \
for ((_e) = RB_MAX(_name, (_head)); \
(_e) != NULL; \
(_e) = RB_PREV(_name, (_e)))
#define RB_FOREACH_REVERSE_SAFE(_e, _name, _head, _n) \
for ((_e) = RB_MAX(_name, (_head)); \
(_e) != NULL && ((_n) = RB_PREV(_name, (_e)), 1); (_e) = (_n))
#define RB_FOREACH_REVERSE_SAFE(_e, _name, _head, _n) \
for ((_e) = RB_MAX(_name, (_head)); \
(_e) != NULL && ((_n) = RB_PREV(_name, (_e)), 1); \
(_e) = (_n))
#endif /* _SYS_TREE_H_ */
#endif /* _SYS_TREE_H_ */

View File

@ -507,8 +507,9 @@ const char *safi2str(safi_t safi)
return "evpn";
case SAFI_LABELED_UNICAST:
return "labeled-unicast";
default:
return "unknown";
}
return NULL;
}
/* If n includes p prefix then return 1 else return 0. */

260
lib/subdir.am Normal file
View File

@ -0,0 +1,260 @@
#
# libfrr
#
lib_LTLIBRARIES += lib/libfrr.la
lib_libfrr_la_LDFLAGS = -version-info 0:0:0
lib_libfrr_la_LIBADD = @LIBCAP@
lib_libfrr_la_SOURCES = \
lib/bfd.c \
lib/buffer.c \
lib/checksum.c \
lib/command.c \
lib/command_graph.c \
lib/command_lex.l \
lib/command_match.c \
lib/command_parse.y \
lib/csv.c \
lib/distribute.c \
lib/event_counter.c \
lib/filter.c \
lib/frr_pthread.c \
lib/getopt.c \
lib/getopt1.c \
lib/grammar_sandbox.c \
lib/graph.c \
lib/hash.c \
lib/hook.c \
lib/if.c \
lib/if_rmap.c \
lib/imsg-buffer.c \
lib/imsg.c \
lib/jhash.c \
lib/json.c \
lib/keychain.c \
lib/libfrr.c \
lib/linklist.c \
lib/log.c \
lib/md5.c \
lib/memory.c \
lib/memory_vty.c \
lib/module.c \
lib/network.c \
lib/nexthop.c \
lib/ns.c \
lib/openbsd-tree.c \
lib/pid_output.c \
lib/plist.c \
lib/pqueue.c \
lib/prefix.c \
lib/privs.c \
lib/ptm_lib.c \
lib/qobj.c \
lib/routemap.c \
lib/sha256.c \
lib/sigevent.c \
lib/skiplist.c \
lib/sockopt.c \
lib/sockunion.c \
lib/spf_backoff.c \
lib/srcdest_table.c \
lib/stream.c \
lib/strlcat.c \
lib/strlcpy.c \
lib/systemd.c \
lib/table.c \
lib/termtable.c \
lib/thread.c \
lib/vector.c \
lib/vrf.c \
lib/vty.c \
lib/wheel.c \
lib/workqueue.c \
lib/zclient.c \
# end
lib/plist_clippy.c: $(CLIPPY_DEPS)
lib/plist.lo: lib/plist_clippy.c
pkginclude_HEADERS += \
lib/bfd.h \
lib/bitfield.h \
lib/buffer.h \
lib/checksum.h \
lib/command.h \
lib/command_graph.h \
lib/command_match.h \
lib/csv.h \
lib/distribute.h \
lib/event_counter.h \
lib/fifo.h \
lib/filter.h \
lib/frr_pthread.h \
lib/frratomic.h \
lib/getopt.h \
lib/graph.h \
lib/hash.h \
lib/hook.h \
lib/if.h \
lib/if_rmap.h \
lib/imsg.h \
lib/ipaddr.h \
lib/jhash.h \
lib/json.h \
lib/keychain.h \
lib/libfrr.h \
lib/libospf.h \
lib/linklist.h \
lib/log.h \
lib/md5.h \
lib/memory.h \
lib/memory_vty.h \
lib/module.h \
lib/monotime.h \
lib/mpls.h \
lib/network.h \
lib/nexthop.h \
lib/ns.h \
lib/openbsd-queue.h \
lib/openbsd-tree.h \
lib/plist.h \
lib/pqueue.h \
lib/prefix.h \
lib/privs.h \
lib/ptm_lib.h \
lib/qobj.h \
lib/route_types.h \
lib/routemap.h \
lib/sha256.h \
lib/sigevent.h \
lib/skiplist.h \
lib/smux.h \
lib/sockopt.h \
lib/sockunion.h \
lib/spf_backoff.h \
lib/srcdest_table.h \
lib/stream.h \
lib/systemd.h \
lib/table.h \
lib/termtable.h \
lib/thread.h \
lib/vector.h \
lib/version.h \
lib/vlan.h \
lib/vrf.h \
lib/vrf_int.h \
lib/vty.h \
lib/vxlan.h \
lib/wheel.h \
lib/workqueue.h \
lib/zassert.h \
lib/zclient.h \
lib/zebra.h \
# end
noinst_HEADERS += \
lib/clippy.h \
lib/log_int.h \
lib/plist_int.h \
#end
#
# SNMP support
#
if SNMP
lib_LTLIBRARIES += lib/libfrrsnmp.la
endif
lib_libfrrsnmp_la_CFLAGS = $(WERROR) $(SNMP_CFLAGS)
lib_libfrrsnmp_la_LDFLAGS = -version-info 0:0:0
lib_libfrrsnmp_la_LIBADD = lib/libfrr.la $(SNMP_LIBS)
lib_libfrrsnmp_la_SOURCES = \
lib/agentx.c \
lib/smux.c \
lib/snmp.c \
# end
#
# CLI utilities
#
noinst_PROGRAMS += \
lib/clippy \
lib/grammar_sandbox \
# end
lib_grammar_sandbox_SOURCES = \
lib/grammar_sandbox_main.c
lib_grammar_sandbox_LDADD = \
lib/libfrr.la
lib_clippy_CPPFLAGS = -D_GNU_SOURCE -I$(top_srcdir)/lib
lib_clippy_CFLAGS = $(PYTHON_CFLAGS)
lib_clippy_LDADD = $(PYTHON_LIBS)
lib_clippy_SOURCES = \
lib/clippy.c \
lib/command_graph.c \
lib/command_lex.l \
lib/command_parse.y \
lib/command_py.c \
lib/defun_lex.l \
lib/graph.c \
lib/memory.c \
lib/vector.c \
# end
#
# generated sources & extra foo
#
EXTRA_DIST += \
lib/command_lex.h \
lib/gitversion.pl \
lib/queue.h \
lib/route_types.pl \
lib/route_types.txt \
# end
BUILT_SOURCES += \
lib/command_lex.h \
lib/command_parse.h \
lib/gitversion.h \
lib/route_types.h \
# end
## force route_types.h
$(lib_clippy_OBJECTS): lib/route_types.h
$(lib_libfrr_la_OBJECTS): lib/route_types.h
AM_YFLAGS = -d -Dapi.prefix=@BISON_OPENBRACE@cmd_yy@BISON_CLOSEBRACE@ @BISON_VERBOSE@
lib/command_lex.h: lib/command_lex.c
@if test ! -f $@; then rm -f "lib/command_lex.c"; else :; fi
@if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) "lib/command_lex.c"; else :; fi
lib/command_lex.lo: lib/command_parse.h
lib/command_parse.lo: lib/command_lex.h
lib/lib_clippy-command_lex.$(OBJEXT): lib/command_parse.h
lib/lib_clippy-command_parse.$(OBJEXT): lib/command_lex.h
lib/route_types.h: $(top_srcdir)/lib/route_types.txt $(top_srcdir)/lib/route_types.pl
@PERL@ $(top_srcdir)/lib/route_types.pl < $(top_srcdir)/lib/route_types.txt > $@
if GIT_VERSION
# bit of a trick here to always have up-to-date git stamps without triggering
# unneccessary rebuilds. .PHONY causes the .tmp file to be rebuilt always,
# but if we use that on gitversion.h it'll ripple through the .c file deps.
# (even if gitversion.h's file timestamp doesn't change, make will think it
# did, because of .PHONY...)
.PHONY: lib/gitversion.h.tmp
.SILENT: lib/gitversion.h lib/gitversion.h.tmp
GITH=lib/gitversion.h
lib/gitversion.h.tmp: $(top_srcdir)/.git
@PERL@ $(top_srcdir)/lib/gitversion.pl $(top_srcdir) > ${GITH}.tmp
lib/gitversion.h: lib/gitversion.h.tmp
{ test -f ${GITH} && diff -s -q ${GITH}.tmp ${GITH}; } || cp ${GITH}.tmp ${GITH}
else
.PHONY: lib/gitversion.h
lib/gitversion.h:
true
endif

View File

@ -416,22 +416,15 @@ extern const char *zserv_command_string(unsigned int command);
typedef enum { AFI_IP = 1, AFI_IP6 = 2, AFI_L2VPN = 3, AFI_MAX = 4 } afi_t;
/* Subsequent Address Family Identifier. */
#define SAFI_UNICAST 1
#define SAFI_MULTICAST 2
#define SAFI_MPLS_VPN 3
#define SAFI_RESERVED_4 4
#define SAFI_ENCAP 5
#define SAFI_RESERVED_5 5
#define SAFI_EVPN 6
#define SAFI_LABELED_UNICAST 7
#define SAFI_MAX 8
#define IANA_SAFI_RESERVED 0
#define IANA_SAFI_UNICAST 1
#define IANA_SAFI_MULTICAST 2
#define IANA_SAFI_LABELED_UNICAST 4
#define IANA_SAFI_ENCAP 7
#define IANA_SAFI_MPLS_VPN 128
typedef enum {
SAFI_UNICAST = 1,
SAFI_MULTICAST = 2,
SAFI_MPLS_VPN = 3,
SAFI_ENCAP = 4,
SAFI_EVPN = 5,
SAFI_LABELED_UNICAST = 6,
SAFI_MAX = 7
} safi_t;
/*
* The above AFI and SAFI definitions are for internal use. The protocol
@ -451,12 +444,15 @@ typedef enum {
IANA_AFI_IP6MR = 129
} iana_afi_t;
#define IANA_SAFI_RESERVED 0
#define IANA_SAFI_UNICAST 1
#define IANA_SAFI_MULTICAST 2
#define IANA_SAFI_ENCAP 7
#define IANA_SAFI_EVPN 70
#define IANA_SAFI_MPLS_VPN 128
typedef enum {
IANA_SAFI_RESERVED = 0,
IANA_SAFI_UNICAST = 1,
IANA_SAFI_MULTICAST = 2,
IANA_SAFI_LABELED_UNICAST = 4,
IANA_SAFI_ENCAP = 7,
IANA_SAFI_EVPN = 70,
IANA_SAFI_MPLS_VPN = 128
} iana_safi_t;
/* Default Administrative Distance of each protocol. */
#define ZEBRA_KERNEL_DISTANCE_DEFAULT 0
@ -477,8 +473,6 @@ typedef enum {
#define UNSET_FLAG(V,F) (V) &= ~(F)
#define RESET_FLAG(V) (V) = 0
typedef u_int8_t safi_t;
/* Zebra types. Used in Zserv message header. */
typedef u_int16_t zebra_size_t;
typedef u_int16_t zebra_command_t;
@ -492,58 +486,70 @@ typedef uint32_t route_tag_t;
static inline afi_t afi_iana2int(iana_afi_t afi)
{
if (afi == IANA_AFI_IPV4)
switch (afi) {
case IANA_AFI_IPV4:
return AFI_IP;
if (afi == IANA_AFI_IPV6)
case IANA_AFI_IPV6:
return AFI_IP6;
if (afi == IANA_AFI_L2VPN)
case IANA_AFI_L2VPN:
return AFI_L2VPN;
return AFI_MAX;
default:
return AFI_MAX;
}
}
static inline iana_afi_t afi_int2iana(afi_t afi)
{
if (afi == AFI_IP)
switch (afi) {
case AFI_IP:
return IANA_AFI_IPV4;
if (afi == AFI_IP6)
case AFI_IP6:
return IANA_AFI_IPV6;
if (afi == AFI_L2VPN)
case AFI_L2VPN:
return IANA_AFI_L2VPN;
return IANA_AFI_RESERVED;
default:
return IANA_AFI_RESERVED;
}
}
static inline safi_t safi_iana2int(safi_t safi)
static inline safi_t safi_iana2int(iana_safi_t safi)
{
if (safi == IANA_SAFI_UNICAST)
switch (safi) {
case IANA_SAFI_UNICAST:
return SAFI_UNICAST;
if (safi == IANA_SAFI_MULTICAST)
case IANA_SAFI_MULTICAST:
return SAFI_MULTICAST;
if (safi == IANA_SAFI_MPLS_VPN)
case IANA_SAFI_MPLS_VPN:
return SAFI_MPLS_VPN;
if (safi == IANA_SAFI_ENCAP)
case IANA_SAFI_ENCAP:
return SAFI_ENCAP;
if (safi == IANA_SAFI_EVPN)
case IANA_SAFI_EVPN:
return SAFI_EVPN;
if (safi == IANA_SAFI_LABELED_UNICAST)
case IANA_SAFI_LABELED_UNICAST:
return SAFI_LABELED_UNICAST;
return SAFI_MAX;
default:
return SAFI_MAX;
}
}
static inline safi_t safi_int2iana(safi_t safi)
static inline iana_safi_t safi_int2iana(safi_t safi)
{
if (safi == SAFI_UNICAST)
switch (safi) {
case SAFI_UNICAST:
return IANA_SAFI_UNICAST;
if (safi == SAFI_MULTICAST)
case SAFI_MULTICAST:
return IANA_SAFI_MULTICAST;
if (safi == SAFI_MPLS_VPN)
case SAFI_MPLS_VPN:
return IANA_SAFI_MPLS_VPN;
if (safi == SAFI_ENCAP)
case SAFI_ENCAP:
return IANA_SAFI_ENCAP;
if (safi == SAFI_EVPN)
case SAFI_EVPN:
return IANA_SAFI_EVPN;
if (safi == SAFI_LABELED_UNICAST)
case SAFI_LABELED_UNICAST:
return IANA_SAFI_LABELED_UNICAST;
return IANA_SAFI_RESERVED;
default:
return IANA_SAFI_RESERVED;
}
}
#endif /* _ZEBRA_H */

View File

@ -1 +0,0 @@
EXTRA_DIST=Makefile.am README.txt

View File

@ -1437,7 +1437,7 @@ static void ospf6_brouter_debug_print(struct ospf6_route *brouter)
char brouter_name[16];
char area_name[16];
char destination[64];
char installed[16], changed[16];
char installed[64], changed[64];
struct timeval now, res;
char id[16], adv_router[16];
char capa[16], options[16];

View File

@ -467,7 +467,7 @@ void ospf6_lsa_show(struct vty *vty, struct ospf6_lsa *lsa)
char adv_router[64], id[64];
struct ospf6_lsa_handler *handler;
struct timeval now, res;
char duration[16];
char duration[64];
assert(lsa && lsa->header);

View File

@ -582,10 +582,10 @@ int inactivity_timer(struct thread *thread)
static void ospf6_neighbor_show(struct vty *vty, struct ospf6_neighbor *on)
{
char router_id[16];
char duration[16];
char duration[64];
struct timeval res;
char nstate[16];
char deadtime[16];
char deadtime[64];
long h, m, s;
/* Router-ID (Name) */
@ -640,7 +640,7 @@ static void ospf6_neighbor_show_drchoice(struct vty *vty,
{
char router_id[16];
char drouter[16], bdrouter[16];
char duration[16];
char duration[64];
struct timeval now, res;
/*

View File

@ -945,7 +945,7 @@ void ospf6_route_show(struct vty *vty, struct ospf6_route *route)
{
int i;
char destination[PREFIX2STR_BUFFER], nexthop[64];
char duration[16];
char duration[64];
const char *ifname;
struct timeval now, res;
struct listnode *node;
@ -991,7 +991,7 @@ void ospf6_route_show_detail(struct vty *vty, struct ospf6_route *route)
char destination[PREFIX2STR_BUFFER], nexthop[64];
char area_id[16], id[16], adv_router[16], capa[16], options[16];
struct timeval now, res;
char duration[16];
char duration[64];
struct listnode *node;
struct ospf6_nexthop *nh;

View File

@ -77,6 +77,44 @@
((ntohs((lsahdr)->length) >= sizeof(struct lsa_header)) \
&& ((ntohs((lsahdr)->length) % sizeof(u_int32_t)) == 0))
/*
* Following section defines generic TLV (type, length, value) macros,
* used for various LSA opaque usage e.g. Traffic Engineering.
*/
struct tlv_header {
u_int16_t type; /* Type of Value */
u_int16_t length; /* Length of Value portion only, in bytes */
};
#define TLV_HDR_SIZE (sizeof(struct tlv_header))
#define TLV_BODY_SIZE(tlvh) \
(ROUNDUP(ntohs((tlvh)->length), sizeof(u_int32_t)))
#define TLV_SIZE(tlvh) (TLV_HDR_SIZE + TLV_BODY_SIZE(tlvh))
#define TLV_HDR_TOP(lsah) \
(struct tlv_header *)((char *)(lsah) + OSPF_LSA_HEADER_SIZE)
#define TLV_HDR_NEXT(tlvh) \
(struct tlv_header *)((char *)(tlvh) + TLV_SIZE(tlvh))
#define TLV_HDR_SUBTLV(tlvh) \
(struct tlv_header *)((char *)(tlvh) + TLV_HDR_SIZE)
#define TLV_DATA(tlvh) (void *)((char *)(tlvh) + TLV_HDR_SIZE)
#define TLV_TYPE(tlvh) tlvh.header.type
#define TLV_LEN(tlvh) tlvh.header.length
#define TLV_HDR(tlvh) tlvh.header
/* Following declaration concerns the Opaque LSA management */
enum lsa_opcode {
REORIGINATE_THIS_LSA,
REFRESH_THIS_LSA,
FLUSH_THIS_LSA
};
/* Prototypes. */
extern void ospf_opaque_init(void);
@ -108,7 +146,7 @@ extern int ospf_opaque_new_if(struct interface *ifp);
extern int ospf_opaque_del_if(struct interface *ifp);
extern void ospf_opaque_ism_change(struct ospf_interface *oi, int old_status);
extern void ospf_opaque_nsm_change(struct ospf_neighbor *nbr, int old_status);
extern void ospf_opaque_config_write_router(struct vty *vty, struct ospf *);
extern void ospf_opaque_config_write_router(struct vty *vty, struct ospf *ospf);
extern void ospf_opaque_config_write_if(struct vty *vty, struct interface *ifp);
extern void ospf_opaque_config_write_debug(struct vty *vty);
extern void show_opaque_info_detail(struct vty *vty, struct ospf_lsa *lsa);
@ -116,7 +154,7 @@ extern void ospf_opaque_lsa_dump(struct stream *s, u_int16_t length);
extern void ospf_opaque_lsa_originate_schedule(struct ospf_interface *oi,
int *init_delay);
extern struct ospf_lsa *ospf_opaque_lsa_install(struct ospf_lsa *,
extern struct ospf_lsa *ospf_opaque_lsa_install(struct ospf_lsa *lsa,
int rt_recalc);
extern struct ospf_lsa *ospf_opaque_lsa_refresh(struct ospf_lsa *lsa);

View File

@ -58,9 +58,9 @@
#include "ospfd/ospf_ri.h"
#include "ospfd/ospf_te.h"
/* Store Router Information PCE TLV and SubTLV in network byte order. */
struct ospf_pce_info {
/* Store Router Information PCE TLV and SubTLV in network byte order. */
bool enabled;
struct ri_tlv_pce pce_header;
struct ri_pce_subtlv_address pce_address;
struct ri_pce_subtlv_path_scope pce_scope;
@ -71,15 +71,14 @@ struct ospf_pce_info {
/* Following structure are internal use only. */
struct ospf_router_info {
status_t status;
bool enabled;
u_int8_t registered;
u_int8_t scope;
/* Flags to manage this router information. */
#define RIFLG_LOOKUP_DONE 0x1
#define RIFLG_LSA_ENGAGED 0x2
#define RIFLG_LSA_FORCED_REFRESH 0x4
#define RIFLG_LSA_ENGAGED 0x1
#define RIFLG_LSA_FORCED_REFRESH 0x2
u_int32_t flags;
/* area pointer if flooding is Type 10 Null if flooding is AS scope */
@ -112,7 +111,7 @@ static void ospf_router_info_config_write_router(struct vty *vty);
static void ospf_router_info_show_info(struct vty *vty, struct ospf_lsa *lsa);
static int ospf_router_info_lsa_originate(void *arg);
static struct ospf_lsa *ospf_router_info_lsa_refresh(struct ospf_lsa *lsa);
static void ospf_router_info_lsa_schedule(opcode_t opcode);
static void ospf_router_info_lsa_schedule(enum lsa_opcode opcode);
static void ospf_router_info_register_vty(void);
static void del_pce_info(void *val);
@ -120,12 +119,13 @@ int ospf_router_info_init(void)
{
memset(&OspfRI, 0, sizeof(struct ospf_router_info));
OspfRI.status = disabled;
OspfRI.enabled = false;
OspfRI.registered = 0;
OspfRI.scope = OSPF_OPAQUE_AS_LSA;
OspfRI.flags = 0;
/* Initialize pce domain and neighbor list */
OspfRI.pce_info.enabled = false;
OspfRI.pce_info.pce_domain = list_new();
OspfRI.pce_info.pce_domain->del = del_pce_info;
OspfRI.pce_info.pce_neighbor = list_new();
@ -141,7 +141,7 @@ static int ospf_router_info_register(u_int8_t scope)
int rc = 0;
if (OspfRI.registered)
return 0;
return rc;
zlog_info("Register Router Information with scope %s(%d)",
scope == OSPF_OPAQUE_AREA_LSA ? "Area" : "AS", scope);
@ -165,7 +165,7 @@ static int ospf_router_info_register(u_int8_t scope)
OspfRI.registered = 1;
OspfRI.scope = scope;
return 0;
return rc;
}
static int ospf_router_info_unregister()
@ -193,7 +193,7 @@ void ospf_router_info_term(void)
OspfRI.pce_info.pce_domain = NULL;
OspfRI.pce_info.pce_neighbor = NULL;
OspfRI.status = disabled;
OspfRI.enabled = false;
ospf_router_info_unregister();
@ -229,34 +229,36 @@ static int set_pce_header(struct ospf_pce_info *pce)
/* PCE Address */
if (ntohs(pce->pce_address.header.type) != 0)
length += RI_TLV_SIZE(&pce->pce_address.header);
length += TLV_SIZE(&pce->pce_address.header);
/* PCE Path Scope */
if (ntohs(pce->pce_scope.header.type) != 0)
length += RI_TLV_SIZE(&pce->pce_scope.header);
length += TLV_SIZE(&pce->pce_scope.header);
/* PCE Domain */
for (ALL_LIST_ELEMENTS_RO(pce->pce_domain, node, domain)) {
if (ntohs(domain->header.type) != 0)
length += RI_TLV_SIZE(&domain->header);
length += TLV_SIZE(&domain->header);
}
/* PCE Neighbor */
for (ALL_LIST_ELEMENTS_RO(pce->pce_neighbor, node, neighbor)) {
if (ntohs(neighbor->header.type) != 0)
length += RI_TLV_SIZE(&neighbor->header);
length += TLV_SIZE(&neighbor->header);
}
/* PCE Capabilities */
if (ntohs(pce->pce_cap_flag.header.type) != 0)
length += RI_TLV_SIZE(&pce->pce_cap_flag.header);
length += TLV_SIZE(&pce->pce_cap_flag.header);
if (length != 0) {
pce->pce_header.header.type = htons(RI_TLV_PCE);
pce->pce_header.header.length = htons(length);
pce->enabled = true;
} else {
pce->pce_header.header.type = 0;
pce->pce_header.header.length = 0;
pce->enabled = false;
}
return length;
@ -279,8 +281,6 @@ static void set_pce_address(struct in_addr ipv4, struct ospf_pce_info *pce)
static void set_pce_path_scope(u_int32_t scope, struct ospf_pce_info *pce)
{
/* Enable PCE Info */
pce->pce_header.header.type = htons(RI_TLV_PCE);
/* Set PCE Scope */
pce->pce_scope.header.type = htons(RI_PCE_SUBTLV_PATH_SCOPE);
pce->pce_scope.header.length = htons(RI_TLV_LENGTH);
@ -295,9 +295,6 @@ static void set_pce_domain(u_int16_t type, u_int32_t domain,
struct ri_pce_subtlv_domain *new;
/* Enable PCE Info */
pce->pce_header.header.type = htons(RI_TLV_PCE);
/* Create new domain info */
new = XCALLOC(MTYPE_OSPF_PCE_PARAMS,
sizeof(struct ri_pce_subtlv_domain));
@ -348,9 +345,6 @@ static void set_pce_neighbor(u_int16_t type, u_int32_t domain,
struct ri_pce_subtlv_neighbor *new;
/* Enable PCE Info */
pce->pce_header.header.type = htons(RI_TLV_PCE);
/* Create new neighbor info */
new = XCALLOC(MTYPE_OSPF_PCE_PARAMS,
sizeof(struct ri_pce_subtlv_neighbor));
@ -399,8 +393,6 @@ static void unset_pce_neighbor(u_int16_t type, u_int32_t domain,
static void set_pce_cap_flag(u_int32_t cap, struct ospf_pce_info *pce)
{
/* Enable PCE Info */
pce->pce_header.header.type = htons(RI_TLV_PCE);
/* Set PCE Capabilities flag */
pce->pce_cap_flag.header.type = htons(RI_PCE_SUBTLV_CAP_FLAG);
pce->pce_cap_flag.header.length = htons(RI_TLV_LENGTH);
@ -410,12 +402,12 @@ static void set_pce_cap_flag(u_int32_t cap, struct ospf_pce_info *pce)
}
static void unset_param(struct ri_tlv_header *tlv)
static void unset_param(struct tlv_header *tlv)
{
tlv->type = 0;
/* Fill the Value to 0 */
memset((tlv + RI_TLV_HDR_SIZE), 0, RI_TLV_BODY_SIZE(tlv));
memset(TLV_DATA(tlv), 0, TLV_BODY_SIZE(tlv));
tlv->length = 0;
return;
@ -423,14 +415,13 @@ static void unset_param(struct ri_tlv_header *tlv)
static void initialize_params(struct ospf_router_info *ori)
{
u_int32_t cap;
u_int32_t cap = 0;
struct ospf *top;
/*
* Initialize default Router Information Capabilities.
*/
cap = 0;
cap = cap | RI_TE_SUPPORT;
cap = RI_TE_SUPPORT;
set_router_info_capabilities(&ori->router_cap, cap);
@ -462,9 +453,6 @@ static void initialize_params(struct ospf_router_info *ori)
| PCE_CAP_ADDITIVE | PCE_CAP_MULTIPLE_REQ;
set_pce_cap_flag(cap, &ori->pce_info);
/* Finally compute PCE header */
set_pce_header(&ori->pce_info);
return;
}
@ -473,16 +461,15 @@ static int is_mandated_params_set(struct ospf_router_info ori)
int rc = 0;
if (ntohs(ori.router_cap.header.type) == 0)
goto out;
return rc;
if ((ntohs(ori.pce_info.pce_header.header.type) == RI_TLV_PCE)
&& (ntohs(ori.pce_info.pce_address.header.type) == 0)
&& (ntohs(ori.pce_info.pce_cap_flag.header.type) == 0))
goto out;
return rc;
rc = 1;
out:
return rc;
}
@ -499,7 +486,6 @@ static void ospf_router_info_ism_change(struct ospf_interface *oi,
static void ospf_router_info_nsm_change(struct ospf_neighbor *nbr,
int old_state)
{
/* So far, nothing to do here. */
return;
}
@ -508,19 +494,19 @@ static void ospf_router_info_nsm_change(struct ospf_neighbor *nbr,
* Followings are OSPF protocol processing functions for ROUTER INFORMATION
*------------------------------------------------------------------------*/
static void build_tlv_header(struct stream *s, struct ri_tlv_header *tlvh)
static void build_tlv_header(struct stream *s, struct tlv_header *tlvh)
{
stream_put(s, tlvh, sizeof(struct ri_tlv_header));
stream_put(s, tlvh, sizeof(struct tlv_header));
return;
}
static void build_tlv(struct stream *s, struct ri_tlv_header *tlvh)
static void build_tlv(struct stream *s, struct tlv_header *tlvh)
{
if (ntohs(tlvh->type) != 0) {
build_tlv_header(s, tlvh);
stream_put(s, tlvh + 1, RI_TLV_BODY_SIZE(tlvh));
stream_put(s, TLV_DATA(tlvh), TLV_BODY_SIZE(tlvh));
}
return;
}
@ -535,9 +521,11 @@ static void ospf_router_info_lsa_body_set(struct stream *s)
/* Build Router Information TLV */
build_tlv(s, &OspfRI.router_cap.header);
/* Add RI PCE TLV if it is set */
/* Compute PCE Info header first */
if ((set_pce_header(&OspfRI.pce_info)) != 0) {
set_pce_header (&OspfRI.pce_info);
/* Add RI PCE TLV if it is set */
if (OspfRI.pce_info.enabled) {
/* Build PCE TLV */
build_tlv_header(s, &OspfRI.pce_info.pce_header.header);
@ -580,7 +568,7 @@ static struct ospf_lsa *ospf_router_info_lsa_new()
/* Create a stream for LSA. */
if ((s = stream_new(OSPF_MAX_LSA_SIZE)) == NULL) {
zlog_warn("ospf_router_info_lsa_new: stream_new() ?");
goto out;
return NULL;
}
lsah = (struct lsa_header *)STREAM_DATA(s);
@ -614,14 +602,14 @@ static struct ospf_lsa *ospf_router_info_lsa_new()
if ((new = ospf_lsa_new()) == NULL) {
zlog_warn("ospf_router_info_lsa_new: ospf_lsa_new() ?");
stream_free(s);
goto out;
return NULL;
}
if ((new->data = ospf_lsa_data_new(length)) == NULL) {
zlog_warn("ospf_router_info_lsa_new: ospf_lsa_data_new() ?");
ospf_lsa_unlock(&new);
new = NULL;
stream_free(s);
goto out;
return new;
}
new->area = OspfRI.area; /* Area must be null if the Opaque type is AS
@ -631,7 +619,6 @@ static struct ospf_lsa *ospf_router_info_lsa_new()
memcpy(new->data, lsah, length);
stream_free(s);
out:
return new;
}
@ -648,7 +635,7 @@ static int ospf_router_info_lsa_originate1(void *arg)
if (area->area_id.s_addr != OspfRI.area_id.s_addr) {
zlog_debug(
"RI -> This is not the Router Information Area. Stop processing");
goto out;
return rc;
}
OspfRI.area = area;
}
@ -657,7 +644,7 @@ static int ospf_router_info_lsa_originate1(void *arg)
if ((new = ospf_router_info_lsa_new()) == NULL) {
zlog_warn(
"ospf_router_info_lsa_originate1: ospf_router_info_lsa_new() ?");
goto out;
return rc;
}
/* Get ospf info */
@ -668,7 +655,7 @@ static int ospf_router_info_lsa_originate1(void *arg)
zlog_warn(
"ospf_router_info_lsa_originate1: ospf_lsa_install() ?");
ospf_lsa_unlock(&new);
goto out;
return rc;
}
/* Now this Router Info parameter entry has associated LSA. */
@ -691,7 +678,6 @@ static int ospf_router_info_lsa_originate1(void *arg)
}
rc = 0;
out:
return rc;
}
@ -700,17 +686,17 @@ static int ospf_router_info_lsa_originate(void *arg)
int rc = -1;
if (OspfRI.status == disabled) {
if (!OspfRI.enabled) {
zlog_info(
"ospf_router_info_lsa_originate: ROUTER INFORMATION is disabled now.");
rc = 0; /* This is not an error case. */
goto out;
return rc;
}
/* Check if Router Information LSA is already engaged */
if (OspfRI.flags & RIFLG_LSA_ENGAGED) {
if (OspfRI.flags & RIFLG_LSA_FORCED_REFRESH) {
OspfRI.flags &= ~RIFLG_LSA_FORCED_REFRESH;
if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED)) {
if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_FORCED_REFRESH)) {
UNSET_FLAG(OspfRI.flags, RIFLG_LSA_FORCED_REFRESH);
ospf_router_info_lsa_schedule(REFRESH_THIS_LSA);
}
} else {
@ -720,11 +706,10 @@ static int ospf_router_info_lsa_originate(void *arg)
/* Ok, let's try to originate an LSA */
if (ospf_router_info_lsa_originate1(arg) != 0)
goto out;
return rc;
}
rc = 0;
out:
return rc;
}
@ -733,7 +718,7 @@ static struct ospf_lsa *ospf_router_info_lsa_refresh(struct ospf_lsa *lsa)
struct ospf_lsa *new = NULL;
struct ospf *top;
if (OspfRI.status == disabled) {
if (!OspfRI.enabled) {
/*
* This LSA must have flushed before due to ROUTER INFORMATION
* status change.
@ -749,21 +734,21 @@ static struct ospf_lsa *ospf_router_info_lsa_refresh(struct ospf_lsa *lsa)
if (GET_OPAQUE_ID(ntohl(lsa->data->id.s_addr)) != 0) {
zlog_warn(
"ospf_router_info_lsa_refresh: Unsupported Router Information ID");
goto out;
return NULL;
}
/* If the lsa's age reached to MaxAge, start flushing procedure. */
if (IS_LSA_MAXAGE(lsa)) {
OspfRI.flags &= ~RIFLG_LSA_ENGAGED;
UNSET_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED);
ospf_opaque_lsa_flush_schedule(lsa);
goto out;
return NULL;
}
/* Create new Opaque-LSA/ROUTER INFORMATION instance. */
if ((new = ospf_router_info_lsa_new()) == NULL) {
zlog_warn(
"ospf_router_info_lsa_refresh: ospf_router_info_lsa_new() ?");
goto out;
return NULL;
}
new->data->ls_seqnum = lsa_seqnum_increment(lsa);
@ -773,7 +758,7 @@ static struct ospf_lsa *ospf_router_info_lsa_refresh(struct ospf_lsa *lsa)
if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) {
zlog_warn("ospf_router_info_lsa_refresh: ospf_lsa_install() ?");
ospf_lsa_unlock(&new);
goto out;
return new;
}
/* Flood updated LSA through AS or AREA depending of OspfRI.scope. */
@ -790,11 +775,10 @@ static struct ospf_lsa *ospf_router_info_lsa_refresh(struct ospf_lsa *lsa)
ospf_lsa_header_dump(new->data);
}
out:
return new;
}
static void ospf_router_info_lsa_schedule(opcode_t opcode)
static void ospf_router_info_lsa_schedule(enum lsa_opcode opcode)
{
struct ospf_lsa lsa;
struct lsa_header lsah;
@ -809,6 +793,13 @@ static void ospf_router_info_lsa_schedule(opcode_t opcode)
opcode == REFRESH_THIS_LSA ? "Refresh" : "",
opcode == FLUSH_THIS_LSA ? "Flush" : "");
/* Check LSA flags state coherence */
if (!CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED) && (opcode != REORIGINATE_THIS_LSA))
return;
if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED) && (opcode == REORIGINATE_THIS_LSA))
opcode = REFRESH_THIS_LSA;
top = ospf_lookup();
if ((OspfRI.scope == OSPF_OPAQUE_AREA_LSA) && (OspfRI.area == NULL)) {
zlog_warn(
@ -838,7 +829,7 @@ static void ospf_router_info_lsa_schedule(opcode_t opcode)
ospf_opaque_lsa_refresh_schedule(&lsa);
break;
case FLUSH_THIS_LSA:
OspfRI.flags &= ~RIFLG_LSA_ENGAGED;
UNSET_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED);
ospf_opaque_lsa_flush_schedule(&lsa);
break;
default:
@ -855,7 +846,7 @@ static void ospf_router_info_lsa_schedule(opcode_t opcode)
*------------------------------------------------------------------------*/
static u_int16_t show_vty_router_cap(struct vty *vty,
struct ri_tlv_header *tlvh)
struct tlv_header *tlvh)
{
struct ri_tlv_router_cap *top = (struct ri_tlv_router_cap *)tlvh;
@ -865,11 +856,11 @@ static u_int16_t show_vty_router_cap(struct vty *vty,
else
zlog_debug(" Router Capabilities: 0x%x", ntohl(top->value));
return RI_TLV_SIZE(tlvh);
return TLV_SIZE(tlvh);
}
static u_int16_t show_vty_pce_subtlv_address(struct vty *vty,
struct ri_tlv_header *tlvh)
struct tlv_header *tlvh)
{
struct ri_pce_subtlv_address *top =
(struct ri_pce_subtlv_address *)tlvh;
@ -891,11 +882,11 @@ static u_int16_t show_vty_pce_subtlv_address(struct vty *vty,
ntohl(top->address.value.s_addr));
}
return RI_TLV_SIZE(tlvh);
return TLV_SIZE(tlvh);
}
static u_int16_t show_vty_pce_subtlv_path_scope(struct vty *vty,
struct ri_tlv_header *tlvh)
struct tlv_header *tlvh)
{
struct ri_pce_subtlv_path_scope *top =
(struct ri_pce_subtlv_path_scope *)tlvh;
@ -905,11 +896,11 @@ static u_int16_t show_vty_pce_subtlv_path_scope(struct vty *vty,
else
zlog_debug(" PCE Path Scope: 0x%x", ntohl(top->value));
return RI_TLV_SIZE(tlvh);
return TLV_SIZE(tlvh);
}
static u_int16_t show_vty_pce_subtlv_domain(struct vty *vty,
struct ri_tlv_header *tlvh)
struct tlv_header *tlvh)
{
struct ri_pce_subtlv_domain *top = (struct ri_pce_subtlv_domain *)tlvh;
struct in_addr tmp;
@ -927,11 +918,11 @@ static u_int16_t show_vty_pce_subtlv_domain(struct vty *vty,
else
zlog_debug(" PCE domain AS: %d", ntohl(top->value));
}
return RI_TLV_SIZE(tlvh);
return TLV_SIZE(tlvh);
}
static u_int16_t show_vty_pce_subtlv_neighbor(struct vty *vty,
struct ri_tlv_header *tlvh)
struct tlv_header *tlvh)
{
struct ri_pce_subtlv_neighbor *top =
@ -953,11 +944,11 @@ static u_int16_t show_vty_pce_subtlv_neighbor(struct vty *vty,
zlog_debug(" PCE neighbor AS: %d",
ntohl(top->value));
}
return RI_TLV_SIZE(tlvh);
return TLV_SIZE(tlvh);
}
static u_int16_t show_vty_pce_subtlv_cap_flag(struct vty *vty,
struct ri_tlv_header *tlvh)
struct tlv_header *tlvh)
{
struct ri_pce_subtlv_cap_flag *top =
(struct ri_pce_subtlv_cap_flag *)tlvh;
@ -969,11 +960,11 @@ static u_int16_t show_vty_pce_subtlv_cap_flag(struct vty *vty,
zlog_debug(" PCE Capabilities Flag: 0x%x",
ntohl(top->value));
return RI_TLV_SIZE(tlvh);
return TLV_SIZE(tlvh);
}
static u_int16_t show_vty_unknown_tlv(struct vty *vty,
struct ri_tlv_header *tlvh)
struct tlv_header *tlvh)
{
if (vty != NULL)
vty_out(vty, " Unknown TLV: [type(0x%x), length(0x%x)]\n",
@ -982,16 +973,16 @@ static u_int16_t show_vty_unknown_tlv(struct vty *vty,
zlog_debug(" Unknown TLV: [type(0x%x), length(0x%x)]",
ntohs(tlvh->type), ntohs(tlvh->length));
return RI_TLV_SIZE(tlvh);
return TLV_SIZE(tlvh);
}
static u_int16_t show_vty_pce_info(struct vty *vty, struct ri_tlv_header *ri,
static u_int16_t show_vty_pce_info(struct vty *vty, struct tlv_header *ri,
uint32_t total)
{
struct ri_tlv_header *tlvh;
struct tlv_header *tlvh;
u_int16_t sum = 0;
for (tlvh = ri; sum < total; tlvh = RI_TLV_HDR_NEXT(tlvh)) {
for (tlvh = ri; sum < total; tlvh = TLV_HDR_NEXT(tlvh)) {
switch (ntohs(tlvh->type)) {
case RI_PCE_SUBTLV_ADDRESS:
sum += show_vty_pce_subtlv_address(vty, tlvh);
@ -1019,21 +1010,21 @@ static u_int16_t show_vty_pce_info(struct vty *vty, struct ri_tlv_header *ri,
static void ospf_router_info_show_info(struct vty *vty, struct ospf_lsa *lsa)
{
struct lsa_header *lsah = (struct lsa_header *)lsa->data;
struct ri_tlv_header *tlvh;
struct tlv_header *tlvh;
u_int16_t length = 0, sum = 0;
/* Initialize TLV browsing */
length = ntohs(lsah->length) - OSPF_LSA_HEADER_SIZE;
for (tlvh = RI_TLV_HDR_TOP(lsah); sum < length;
tlvh = RI_TLV_HDR_NEXT(tlvh)) {
for (tlvh = TLV_HDR_TOP(lsah); sum < length;
tlvh = TLV_HDR_NEXT(tlvh)) {
switch (ntohs(tlvh->type)) {
case RI_TLV_CAPABILITIES:
sum += show_vty_router_cap(vty, tlvh);
break;
case RI_TLV_PCE:
tlvh++;
sum += RI_TLV_HDR_SIZE;
sum += TLV_HDR_SIZE;
sum += show_vty_pce_info(vty, tlvh, length - sum);
break;
default:
@ -1053,50 +1044,53 @@ static void ospf_router_info_config_write_router(struct vty *vty)
struct ri_pce_subtlv_neighbor *neighbor;
struct in_addr tmp;
if (OspfRI.status == enabled) {
if (OspfRI.enabled) {
if (OspfRI.scope == OSPF_OPAQUE_AS_LSA)
vty_out(vty, " router-info as\n");
else
vty_out(vty, " router-info area %s\n",
inet_ntoa(OspfRI.area_id));
if (pce->pce_address.header.type != 0)
vty_out(vty, " pce address %s\n",
inet_ntoa(pce->pce_address.address.value));
if (OspfRI.pce_info.enabled) {
if (pce->pce_cap_flag.header.type != 0)
vty_out(vty, " pce flag 0x%x\n",
ntohl(pce->pce_cap_flag.value));
if (pce->pce_address.header.type != 0)
vty_out(vty, " pce address %s\n",
inet_ntoa(pce->pce_address.address.value));
for (ALL_LIST_ELEMENTS_RO(pce->pce_domain, node, domain)) {
if (domain->header.type != 0) {
if (domain->type == PCE_DOMAIN_TYPE_AREA) {
tmp.s_addr = domain->value;
vty_out(vty, " pce domain area %s\n",
inet_ntoa(tmp));
} else {
vty_out(vty, " pce domain as %d\n",
ntohl(domain->value));
if (pce->pce_cap_flag.header.type != 0)
vty_out(vty, " pce flag 0x%x\n",
ntohl(pce->pce_cap_flag.value));
for (ALL_LIST_ELEMENTS_RO(pce->pce_domain, node, domain)) {
if (domain->header.type != 0) {
if (domain->type == PCE_DOMAIN_TYPE_AREA) {
tmp.s_addr = domain->value;
vty_out(vty, " pce domain area %s\n",
inet_ntoa(tmp));
} else {
vty_out(vty, " pce domain as %d\n",
ntohl(domain->value));
}
}
}
}
for (ALL_LIST_ELEMENTS_RO(pce->pce_neighbor, node, neighbor)) {
if (neighbor->header.type != 0) {
if (neighbor->type == PCE_DOMAIN_TYPE_AREA) {
tmp.s_addr = neighbor->value;
vty_out(vty, " pce neighbor area %s\n",
inet_ntoa(tmp));
} else {
vty_out(vty, " pce neighbor as %d\n",
ntohl(neighbor->value));
for (ALL_LIST_ELEMENTS_RO(pce->pce_neighbor, node, neighbor)) {
if (neighbor->header.type != 0) {
if (neighbor->type == PCE_DOMAIN_TYPE_AREA) {
tmp.s_addr = neighbor->value;
vty_out(vty, " pce neighbor area %s\n",
inet_ntoa(tmp));
} else {
vty_out(vty, " pce neighbor as %d\n",
ntohl(neighbor->value));
}
}
}
}
if (pce->pce_scope.header.type != 0)
vty_out(vty, " pce scope 0x%x\n",
ntohl(OspfRI.pce_info.pce_scope.value));
if (pce->pce_scope.header.type != 0)
vty_out(vty, " pce scope 0x%x\n",
ntohl(OspfRI.pce_info.pce_scope.value));
}
}
return;
}
@ -1118,7 +1112,7 @@ DEFUN (router_info,
u_int8_t scope;
if (OspfRI.status == enabled)
if (OspfRI.enabled)
return CMD_SUCCESS;
/* Check and get Area value if present */
@ -1137,11 +1131,11 @@ DEFUN (router_info,
/* First start to register Router Information callbacks */
if ((ospf_router_info_register(scope)) != 0) {
zlog_warn(
"Enable to register Router Information callbacks. Abort!");
"Unable to register Router Information callbacks. Abort!");
return CMD_WARNING_CONFIG_FAILED;
}
OspfRI.status = enabled;
OspfRI.enabled = true;
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("RI-> Router Information (%s flooding): OFF -> ON",
@ -1160,7 +1154,10 @@ DEFUN (router_info,
initialize_params(&OspfRI);
/* Refresh RI LSA if already engaged */
if (OspfRI.flags & RIFLG_LSA_ENGAGED) {
if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED)) {
zlog_debug ("RI-> Refresh LSA following configuration");
ospf_router_info_lsa_schedule (REFRESH_THIS_LSA);
} else {
zlog_debug("RI-> Initial origination following configuration");
ospf_router_info_lsa_schedule(REORIGINATE_THIS_LSA);
}
@ -1175,26 +1172,26 @@ DEFUN (no_router_info,
"Disable the Router Information functionality\n")
{
if (OspfRI.status == disabled)
if (!OspfRI.enabled)
return CMD_SUCCESS;
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("RI-> Router Information: ON -> OFF");
if (OspfRI.flags & RIFLG_LSA_ENGAGED)
if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED))
ospf_router_info_lsa_schedule(FLUSH_THIS_LSA);
/* Unregister the callbacks */
ospf_router_info_unregister();
OspfRI.status = disabled;
OspfRI.enabled = false;
return CMD_SUCCESS;
}
static int ospf_ri_enabled(struct vty *vty)
{
if (OspfRI.status == enabled)
if (OspfRI.enabled)
return 1;
if (vty)
@ -1229,7 +1226,7 @@ DEFUN (pce_address,
set_pce_address(value, pi);
/* Refresh RI LSA if already engaged */
if (OspfRI.flags & RIFLG_LSA_ENGAGED)
if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED))
ospf_router_info_lsa_schedule(REFRESH_THIS_LSA);
}
@ -1248,7 +1245,7 @@ DEFUN (no_pce_address,
unset_param(&OspfRI.pce_info.pce_address.header);
/* Refresh RI LSA if already engaged */
if ((OspfRI.status == enabled) && (OspfRI.flags & RIFLG_LSA_ENGAGED))
if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED))
ospf_router_info_lsa_schedule(REFRESH_THIS_LSA);
return CMD_SUCCESS;
@ -1279,7 +1276,7 @@ DEFUN (pce_path_scope,
set_pce_path_scope(scope, pi);
/* Refresh RI LSA if already engaged */
if (OspfRI.flags & RIFLG_LSA_ENGAGED)
if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED))
ospf_router_info_lsa_schedule(REFRESH_THIS_LSA);
}
@ -1298,7 +1295,7 @@ DEFUN (no_pce_path_scope,
unset_param(&OspfRI.pce_info.pce_address.header);
/* Refresh RI LSA if already engaged */
if ((OspfRI.status == enabled) && (OspfRI.flags & RIFLG_LSA_ENGAGED))
if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED))
ospf_router_info_lsa_schedule(REFRESH_THIS_LSA);
return CMD_SUCCESS;
@ -1337,7 +1334,7 @@ DEFUN (pce_domain,
set_pce_domain(PCE_DOMAIN_TYPE_AS, as, pce);
/* Refresh RI LSA if already engaged */
if (OspfRI.flags & RIFLG_LSA_ENGAGED)
if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED))
ospf_router_info_lsa_schedule(REFRESH_THIS_LSA);
return CMD_SUCCESS;
@ -1367,7 +1364,7 @@ DEFUN (no_pce_domain,
unset_pce_domain(PCE_DOMAIN_TYPE_AS, as, pce);
/* Refresh RI LSA if already engaged */
if ((OspfRI.status == enabled) && (OspfRI.flags & RIFLG_LSA_ENGAGED))
if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED))
ospf_router_info_lsa_schedule(REFRESH_THIS_LSA);
return CMD_SUCCESS;
@ -1407,7 +1404,7 @@ DEFUN (pce_neigbhor,
set_pce_neighbor(PCE_DOMAIN_TYPE_AS, as, pce);
/* Refresh RI LSA if already engaged */
if (OspfRI.flags & RIFLG_LSA_ENGAGED)
if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED))
ospf_router_info_lsa_schedule(REFRESH_THIS_LSA);
return CMD_SUCCESS;
@ -1437,7 +1434,7 @@ DEFUN (no_pce_neighbor,
unset_pce_neighbor(PCE_DOMAIN_TYPE_AS, as, pce);
/* Refresh RI LSA if already engaged */
if ((OspfRI.status == enabled) && (OspfRI.flags & RIFLG_LSA_ENGAGED))
if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED))
ospf_router_info_lsa_schedule(REFRESH_THIS_LSA);
return CMD_SUCCESS;
@ -1469,7 +1466,7 @@ DEFUN (pce_cap_flag,
set_pce_cap_flag(cap, pce);
/* Refresh RI LSA if already engaged */
if (OspfRI.flags & RIFLG_LSA_ENGAGED)
if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED))
ospf_router_info_lsa_schedule(REFRESH_THIS_LSA);
}
@ -1487,7 +1484,7 @@ DEFUN (no_pce_cap_flag,
unset_param(&OspfRI.pce_info.pce_cap_flag.header);
/* Refresh RI LSA if already engaged */
if ((OspfRI.status == enabled) && (OspfRI.flags & RIFLG_LSA_ENGAGED))
if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED))
ospf_router_info_lsa_schedule(REFRESH_THIS_LSA);
return CMD_SUCCESS;
@ -1502,7 +1499,7 @@ DEFUN (show_ip_ospf_router_info,
"Router Information\n")
{
if (OspfRI.status == enabled) {
if (OspfRI.enabled) {
vty_out(vty, "--- Router Information parameters ---\n");
show_vty_router_cap(vty, &OspfRI.router_cap.header);
} else {
@ -1528,7 +1525,7 @@ DEFUN (show_ip_opsf_router_info_pce,
struct ri_pce_subtlv_domain *domain;
struct ri_pce_subtlv_neighbor *neighbor;
if (OspfRI.status == enabled) {
if (OspfRI.enabled) {
vty_out(vty, "--- PCE parameters ---\n");
if (pce->pce_address.header.type != 0)

View File

@ -64,21 +64,6 @@
* +--------+--------+--------+--------+ ---
*/
/*
* Following section defines TLV (tag, length, value) structures,
* used for Router Information.
*/
struct ri_tlv_header {
u_int16_t type; /* RI_TLV_XXX (see below) */
u_int16_t length; /* Value portion only, in byte */
};
#define RI_TLV_HDR_SIZE (sizeof (struct ri_tlv_header))
#define RI_TLV_BODY_SIZE(tlvh) (ROUNDUP (ntohs ((tlvh)->length), sizeof (u_int32_t)))
#define RI_TLV_SIZE(tlvh) (RI_TLV_HDR_SIZE + RI_TLV_BODY_SIZE(tlvh))
#define RI_TLV_HDR_TOP(lsah) (struct ri_tlv_header *)((char *)(lsah) + OSPF_LSA_HEADER_SIZE)
#define RI_TLV_HDR_NEXT(tlvh) (struct ri_tlv_header *)((char *)(tlvh) + RI_TLV_SIZE(tlvh))
/*
* Following section defines TLV body parts.
*/
@ -91,7 +76,7 @@ struct ri_tlv_header {
#define RI_TLV_CAPABILITIES 1
struct ri_tlv_router_cap {
struct ri_tlv_header header; /* Value length is 4 bytes. */
struct tlv_header header; /* Value length is 4 bytes. */
u_int32_t value;
};
@ -109,23 +94,19 @@ struct ri_tlv_router_cap {
#define RI_TLV_PCE 6
struct ri_tlv_pce {
struct ri_tlv_header header;
struct tlv_header header;
/* A set of PCE-sub-TLVs will follow. */
};
/* PCE Address Sub-TLV */ /* Mandatory */
#define RI_PCE_SUBTLV_ADDRESS 1
struct ri_pce_subtlv_address {
struct ri_tlv_header
header; /* Type = 1; Length is 8 (IPv4) or 20 (IPv6) bytes. */
/* $FRR indent$ */
/* clang-format off */
/* Type = 1; Length is 8 (IPv4) or 20 (IPv6) bytes. */
struct tlv_header header;
#define PCE_ADDRESS_LENGTH_IPV4 8
#define PCE_ADDRESS_LENGTH_IPV6 20
struct {
u_int16_t type; /* Address type: 1 = IPv4, 2 = IPv6 */
/* $FRR indent$ */
/* clang-format off */
#define PCE_ADDRESS_TYPE_IPV4 1
#define PCE_ADDRESS_TYPE_IPV6 2
u_int16_t reserved;
@ -136,9 +117,12 @@ struct ri_pce_subtlv_address {
/* PCE Path-Scope Sub-TLV */ /* Mandatory */
#define RI_PCE_SUBTLV_PATH_SCOPE 2
struct ri_pce_subtlv_path_scope {
struct ri_tlv_header header; /* Type = 2; Length = 4 bytes. */
u_int32_t value; /* L, R, Rd, S, Sd, Y, PrefL, PrefR, PrefS and PrefY
bits see RFC5088 page 9 */
struct tlv_header header; /* Type = 2; Length = 4 bytes. */
/*
* L, R, Rd, S, Sd, Y, PrefL, PrefR, PrefS and PrefY bits:
* see RFC5088 page 9
*/
u_int32_t value;
};
/* PCE Domain Sub-TLV */ /* Optional */
@ -148,7 +132,7 @@ struct ri_pce_subtlv_path_scope {
#define PCE_DOMAIN_TYPE_AS 2
struct ri_pce_subtlv_domain {
struct ri_tlv_header header; /* Type = 3; Length = 8 bytes. */
struct tlv_header header; /* Type = 3; Length = 8 bytes. */
u_int16_t type; /* Domain type: 1 = OSPF Area ID, 2 = AS Number */
u_int16_t reserved;
u_int32_t value;
@ -157,7 +141,7 @@ struct ri_pce_subtlv_domain {
/* PCE Neighbor Sub-TLV */ /* Mandatory if R or S bit is set */
#define RI_PCE_SUBTLV_NEIGHBOR 4
struct ri_pce_subtlv_neighbor {
struct ri_tlv_header header; /* Type = 4; Length = 8 bytes. */
struct tlv_header header; /* Type = 4; Length = 8 bytes. */
u_int16_t type; /* Domain type: 1 = OSPF Area ID, 2 = AS Number */
u_int16_t reserved;
u_int32_t value;
@ -177,7 +161,7 @@ struct ri_pce_subtlv_neighbor {
#define PCE_CAP_MULTIPLE_REQ 0x0100
struct ri_pce_subtlv_cap_flag {
struct ri_tlv_header header; /* Type = 5; Length = n x 4 bytes. */
struct tlv_header header; /* Type = 5; Length = n x 4 bytes. */
u_int32_t value;
};

View File

@ -68,9 +68,7 @@
*/
struct ospf_mpls_te OspfMplsTE;
const char *mode2text[] = {"Disable", "AS", "Area", "Emulate"};
enum oifstate { OI_ANY, OI_DOWN, OI_UP };
const char *mode2text[] = {"Off", "AS", "Area"};
/*------------------------------------------------------------------------*
* Followings are initialize/terminate functions for MPLS-TE handling.
@ -106,29 +104,28 @@ int ospf_mpls_te_init(void)
if (rc != 0) {
zlog_warn(
"ospf_mpls_te_init: Failed to register Traffic Engineering functions");
goto out;
return rc;
}
memset(&OspfMplsTE, 0, sizeof(struct ospf_mpls_te));
OspfMplsTE.status = disabled;
OspfMplsTE.inter_as = Disable;
OspfMplsTE.enabled = false;
OspfMplsTE.inter_as = Off;
OspfMplsTE.iflist = list_new();
OspfMplsTE.iflist->del = del_mpls_te_link;
ospf_mpls_te_register_vty();
out:
return rc;
}
/* Additional register for RFC5392 support */
static int ospf_mpls_te_register(enum inter_as_mode mode)
{
int rc;
int rc = 0;
u_int8_t scope;
if (OspfMplsTE.inter_as != Disable)
return 0;
if (OspfMplsTE.inter_as != Off)
return rc;
if (mode == AS)
scope = OSPF_OPAQUE_AS_LSA;
@ -147,14 +144,14 @@ static int ospf_mpls_te_register(enum inter_as_mode mode)
return rc;
}
return 0;
return rc;
}
static int ospf_mpls_te_unregister()
{
u_int8_t scope;
if (OspfMplsTE.inter_as == Disable)
if (OspfMplsTE.inter_as == Off)
return 0;
if (OspfMplsTE.inter_as == AS)
@ -174,10 +171,10 @@ void ospf_mpls_te_term(void)
ospf_delete_opaque_functab(OSPF_OPAQUE_AREA_LSA,
OPAQUE_TYPE_TRAFFIC_ENGINEERING_LSA);
OspfMplsTE.status = disabled;
OspfMplsTE.enabled = false;
ospf_mpls_te_unregister();
OspfMplsTE.inter_as = Disable;
OspfMplsTE.inter_as = Off;
return;
}
@ -192,7 +189,7 @@ static void del_mpls_te_link(void *val)
return;
}
u_int32_t get_mpls_te_instance_value(void)
static u_int32_t get_mpls_te_instance_value(void)
{
static u_int32_t seqno = 0;
@ -204,41 +201,6 @@ u_int32_t get_mpls_te_instance_value(void)
return seqno;
}
static struct ospf_interface *lookup_oi_by_ifp(struct interface *ifp,
struct ospf_area *area,
enum oifstate oifstate)
{
struct ospf_interface *oi = NULL;
struct route_node *rn;
for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
if ((oi = rn->info) == NULL)
continue;
switch (oifstate) {
case OI_ANY:
break;
case OI_DOWN:
if (ospf_if_is_enable(oi))
continue;
break;
case OI_UP:
if (!ospf_if_is_enable(oi))
continue;
break;
default:
zlog_warn("lookup_oi_by_ifp: Unknown oifstate: %x",
oifstate);
goto out;
}
if (area == NULL || oi->area == area)
return oi;
}
out:
return NULL;
}
static struct mpls_te_link *lookup_linkparams_by_ifp(struct interface *ifp)
{
struct listnode *node, *nnode;
@ -267,8 +229,8 @@ static struct mpls_te_link *lookup_linkparams_by_instance(struct ospf_lsa *lsa)
}
static void ospf_mpls_te_foreach_area(void (*func)(struct mpls_te_link *lp,
opcode_t sched_opcode),
opcode_t sched_opcode)
enum lsa_opcode sched_opcode),
enum lsa_opcode sched_opcode)
{
struct listnode *node, *nnode;
struct listnode *node2;
@ -281,8 +243,8 @@ static void ospf_mpls_te_foreach_area(void (*func)(struct mpls_te_link *lp,
continue;
if ((area = lp->area) == NULL)
continue;
if
CHECK_FLAG(lp->flags, LPFLG_LOOKUP_DONE) continue;
if (CHECK_FLAG(lp->flags, LPFLG_LOOKUP_DONE))
continue;
if (func != NULL)
(*func)(lp, sched_opcode);
@ -793,14 +755,25 @@ static void update_linkparams(struct mpls_te_link *lp)
static void initialize_linkparams(struct mpls_te_link *lp)
{
struct interface *ifp = lp->ifp;
struct ospf_interface *oi;
struct ospf_interface *oi = NULL;
struct route_node *rn;
if (IS_DEBUG_OSPF_TE)
zlog_debug(
"MPLS-TE(initialize_linkparams) Initialize Link Parameters for interface %s",
ifp->name);
if ((oi = lookup_oi_by_ifp(ifp, NULL, OI_ANY)) == NULL) {
/* Search OSPF Interface parameters for this interface */
for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn)) {
if ((oi = rn->info) == NULL)
continue;
if (oi->ifp == ifp)
break;
}
if ((oi == NULL) || (oi->ifp != ifp)) {
if (IS_DEBUG_OSPF_TE)
zlog_warn(
"MPLS-TE(initialize_linkparams) Could not find corresponding OSPF Interface for %s",
@ -818,7 +791,7 @@ static void initialize_linkparams(struct mpls_te_link *lp)
set_linkparams_lclif_ipaddr(lp, oi->address->u.prefix4);
/* Set Remote IP addr if Point to Point Interface */
if (oi->type == LINK_TYPE_SUBTLV_VALUE_PTP) {
if (oi->type == OSPF_IFTYPE_POINTOPOINT) {
struct prefix *pref = CONNECTED_PREFIX(oi->connected);
if (pref != NULL)
set_linkparams_rmtif_ipaddr(lp, pref->u.prefix4);
@ -837,21 +810,20 @@ static int is_mandated_params_set(struct mpls_te_link *lp)
if (ntohs(OspfMplsTE.router_addr.header.type) == 0) {
zlog_warn(
"MPLS-TE(is_mandated_params_set) Missing Router Address");
goto out;
return rc;
}
if (ntohs(lp->link_type.header.type) == 0) {
zlog_warn("MPLS-TE(is_mandated_params_set) Missing Link Type");
goto out;
return rc;
}
if (!IS_INTER_AS(lp->type) && (ntohs(lp->link_id.header.type) == 0)) {
zlog_warn("MPLS-TE(is_mandated_params_set) Missing Link ID");
goto out;
return rc;
}
rc = 1;
out:
return rc;
}
@ -873,14 +845,14 @@ static int ospf_mpls_te_new_if(struct interface *ifp)
zlog_warn("ospf_mpls_te_new_if: ifp(%p) already in use?",
(void *)ifp);
rc = 0; /* Do nothing here. */
goto out;
return rc;
}
new = XCALLOC(MTYPE_OSPF_MPLS_TE, sizeof(struct mpls_te_link));
if (new == NULL) {
zlog_warn("ospf_mpls_te_new_if: XMALLOC: %s",
safe_strerror(errno));
goto out;
return rc;
}
new->instance = get_mpls_te_instance_value();
@ -909,7 +881,6 @@ static int ospf_mpls_te_new_if(struct interface *ifp)
/* Schedule Opaque-LSA refresh. */ /* XXX */
rc = 0;
out:
return rc;
}
@ -934,7 +905,6 @@ static int ospf_mpls_te_del_if(struct interface *ifp)
/* Schedule Opaque-LSA refresh. */ /* XXX */
rc = 0;
/*out:*/
return rc;
}
@ -952,10 +922,9 @@ void ospf_mpls_te_update_if(struct interface *ifp)
/* Get Link context from interface */
if ((lp = lookup_linkparams_by_ifp(ifp)) == NULL) {
if (IS_DEBUG_OSPF_TE)
zlog_warn(
"OSPF MPLS-TE Update: Did not find Link Parameters context for interface %s",
ifp->name);
zlog_warn(
"OSPF MPLS-TE Update: Did not find Link Parameters context for interface %s",
ifp->name);
return;
}
@ -968,20 +937,18 @@ void ospf_mpls_te_update_if(struct interface *ifp)
/* Finally Re-Originate or Refresh Opaque LSA if MPLS_TE is
* enabled */
if (OspfMplsTE.status == enabled)
if (OspfMplsTE.enabled)
if (lp->area != NULL) {
if
CHECK_FLAG(lp->flags, LPFLG_LSA_ENGAGED)
ospf_mpls_te_lsa_schedule(lp, REFRESH_THIS_LSA);
else ospf_mpls_te_lsa_schedule(
lp, REORIGINATE_THIS_LSA);
if (CHECK_FLAG(lp->flags, LPFLG_LSA_ENGAGED))
ospf_mpls_te_lsa_schedule(lp, REFRESH_THIS_LSA);
else
ospf_mpls_te_lsa_schedule(lp, REORIGINATE_THIS_LSA);
}
} else {
/* If MPLS TE is disable on this interface, flush LSA if it is
* already engaged */
if
CHECK_FLAG(lp->flags, LPFLG_LSA_ENGAGED)
ospf_mpls_te_lsa_schedule(lp, FLUSH_THIS_LSA);
if (CHECK_FLAG(lp->flags, LPFLG_LSA_ENGAGED))
ospf_mpls_te_lsa_schedule(lp, FLUSH_THIS_LSA);
else
/* Reset Activity flag */
lp->flags = LPFLG_LSA_INACTIVE;
@ -1000,14 +967,14 @@ static void ospf_mpls_te_ism_change(struct ospf_interface *oi, int old_state)
zlog_warn(
"ospf_mpls_te_ism_change: Cannot get linkparams from OI(%s)?",
IF_NAME(oi));
goto out;
return;
}
if (oi->area == NULL || oi->area->ospf == NULL) {
zlog_warn(
"ospf_mpls_te_ism_change: Cannot refer to OSPF from OI(%s)?",
IF_NAME(oi));
goto out;
return;
}
#ifdef notyet
if ((lp->area != NULL
@ -1059,24 +1026,21 @@ static void ospf_mpls_te_ism_change(struct ospf_interface *oi, int old_state)
!= ntohs(lp->link_id.header.type)
|| ntohl(old_id.value.s_addr)
!= ntohl(lp->link_id.value.s_addr))) {
if
CHECK_FLAG(lp->flags, LPFLG_LSA_ENGAGED)
ospf_mpls_te_lsa_schedule(lp, REFRESH_THIS_LSA);
else ospf_mpls_te_lsa_schedule(lp,
REORIGINATE_THIS_LSA);
if (CHECK_FLAG(lp->flags, LPFLG_LSA_ENGAGED))
ospf_mpls_te_lsa_schedule(lp, REFRESH_THIS_LSA);
else
ospf_mpls_te_lsa_schedule(lp, REORIGINATE_THIS_LSA);
}
break;
default:
lp->link_type.header.type = htons(0);
lp->link_id.header.type = htons(0);
if
CHECK_FLAG(lp->flags, LPFLG_LSA_ENGAGED)
ospf_mpls_te_lsa_schedule(lp, FLUSH_THIS_LSA);
if (CHECK_FLAG(lp->flags, LPFLG_LSA_ENGAGED))
ospf_mpls_te_lsa_schedule(lp, FLUSH_THIS_LSA);
break;
}
out:
return;
}
@ -1090,28 +1054,28 @@ static void ospf_mpls_te_nsm_change(struct ospf_neighbor *nbr, int old_state)
* Followings are OSPF protocol processing functions for MPLS-TE.
*------------------------------------------------------------------------*/
static void build_tlv_header(struct stream *s, struct te_tlv_header *tlvh)
static void build_tlv_header(struct stream *s, struct tlv_header *tlvh)
{
stream_put(s, tlvh, sizeof(struct te_tlv_header));
stream_put(s, tlvh, sizeof(struct tlv_header));
return;
}
static void build_router_tlv(struct stream *s)
{
struct te_tlv_header *tlvh = &OspfMplsTE.router_addr.header;
struct tlv_header *tlvh = &OspfMplsTE.router_addr.header;
if (ntohs(tlvh->type) != 0) {
build_tlv_header(s, tlvh);
stream_put(s, tlvh + 1, TLV_BODY_SIZE(tlvh));
stream_put(s, TLV_DATA(tlvh), TLV_BODY_SIZE(tlvh));
}
return;
}
static void build_link_subtlv(struct stream *s, struct te_tlv_header *tlvh)
static void build_link_subtlv(struct stream *s, struct tlv_header *tlvh)
{
if ((tlvh != NULL) && (ntohs(tlvh->type) != 0)) {
build_tlv_header(s, tlvh);
stream_put(s, tlvh + 1, TLV_BODY_SIZE(tlvh));
stream_put(s, TLV_DATA(tlvh), TLV_BODY_SIZE(tlvh));
}
return;
}
@ -1177,7 +1141,7 @@ static struct ospf_lsa *ospf_mpls_te_lsa_new(struct ospf_area *area,
/* Create a stream for LSA. */
if ((s = stream_new(OSPF_MAX_LSA_SIZE)) == NULL) {
zlog_warn("ospf_mpls_te_lsa_new: stream_new() ?");
goto out;
return NULL;
}
lsah = (struct lsa_header *)STREAM_DATA(s);
@ -1233,14 +1197,14 @@ static struct ospf_lsa *ospf_mpls_te_lsa_new(struct ospf_area *area,
if ((new = ospf_lsa_new()) == NULL) {
zlog_warn("ospf_mpls_te_lsa_new: ospf_lsa_new() ?");
stream_free(s);
goto out;
return NULL;
}
if ((new->data = ospf_lsa_data_new(length)) == NULL) {
zlog_warn("ospf_mpls_te_lsa_new: ospf_lsa_data_new() ?");
ospf_lsa_unlock(&new);
new = NULL;
stream_free(s);
goto out;
return new;
}
new->area = area;
@ -1248,7 +1212,6 @@ static struct ospf_lsa *ospf_mpls_te_lsa_new(struct ospf_area *area,
memcpy(new->data, lsah, length);
stream_free(s);
out:
return new;
}
@ -1262,14 +1225,14 @@ static int ospf_mpls_te_lsa_originate1(struct ospf_area *area,
if ((new = ospf_mpls_te_lsa_new(area, lp)) == NULL) {
zlog_warn(
"ospf_mpls_te_lsa_originate1: ospf_mpls_te_lsa_new() ?");
goto out;
return rc;
}
/* Install this LSA into LSDB. */
if (ospf_lsa_install(area->ospf, NULL /*oi*/, new) == NULL) {
zlog_warn("ospf_mpls_te_lsa_originate1: ospf_lsa_install() ?");
ospf_lsa_unlock(&new);
goto out;
return rc;
}
/* Now this link-parameter entry has associated LSA. */
@ -1291,7 +1254,6 @@ static int ospf_mpls_te_lsa_originate1(struct ospf_area *area,
}
rc = 0;
out:
return rc;
}
@ -1302,11 +1264,11 @@ static int ospf_mpls_te_lsa_originate_area(void *arg)
struct mpls_te_link *lp;
int rc = -1;
if (OspfMplsTE.status == disabled) {
if (!OspfMplsTE.enabled) {
zlog_info(
"ospf_mpls_te_lsa_originate_area: MPLS-TE is disabled now.");
rc = 0; /* This is not an error case. */
goto out;
return rc;
}
for (ALL_LIST_ELEMENTS(OspfMplsTE.iflist, node, nnode, lp)) {
@ -1321,23 +1283,16 @@ static int ospf_mpls_te_lsa_originate_area(void *arg)
if (!IPV4_ADDR_SAME(&lp->area->area_id, &area->area_id))
continue;
if
CHECK_FLAG(lp->flags, LPFLG_LSA_ENGAGED)
{
if
CHECK_FLAG(lp->flags,
LPFLG_LSA_FORCED_REFRESH)
{
UNSET_FLAG(
lp->flags,
LPFLG_LSA_FORCED_REFRESH);
zlog_warn(
"OSPF MPLS-TE (ospf_mpls_te_lsa_originate_area): Refresh instead of Originate");
ospf_mpls_te_lsa_schedule(
lp, REFRESH_THIS_LSA);
}
continue;
if (CHECK_FLAG(lp->flags, LPFLG_LSA_ENGAGED)) {
if (CHECK_FLAG(lp->flags, LPFLG_LSA_FORCED_REFRESH)) {
UNSET_FLAG(lp->flags, LPFLG_LSA_FORCED_REFRESH);
zlog_warn(
"OSPF MPLS-TE (ospf_mpls_te_lsa_originate_area): Refresh instead of Originate");
ospf_mpls_te_lsa_schedule(lp, REFRESH_THIS_LSA);
}
continue;
}
if (!is_mandated_params_set(lp)) {
zlog_warn(
"ospf_mpls_te_lsa_originate_area: Link(%s) lacks some mandated MPLS-TE parameters.",
@ -1352,11 +1307,10 @@ static int ospf_mpls_te_lsa_originate_area(void *arg)
lp->instance, inet_ntoa(area->area_id),
lp->ifp ? lp->ifp->name : "?");
if (ospf_mpls_te_lsa_originate1(area, lp) != 0)
goto out;
return rc;
}
rc = 0;
out:
return rc;
}
@ -1370,14 +1324,14 @@ static int ospf_mpls_te_lsa_originate2(struct ospf *top,
if ((new = ospf_mpls_te_lsa_new(NULL, lp)) == NULL) {
zlog_warn(
"ospf_mpls_te_lsa_originate2: ospf_router_info_lsa_new() ?");
goto out;
return rc;
}
/* Install this LSA into LSDB. */
if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) {
zlog_warn("ospf_mpls_te_lsa_originate2: ospf_lsa_install() ?");
ospf_lsa_unlock(&new);
goto out;
return rc;
}
/* Now this Router Info parameter entry has associated LSA. */
@ -1396,7 +1350,6 @@ static int ospf_mpls_te_lsa_originate2(struct ospf *top,
}
rc = 0;
out:
return rc;
}
@ -1408,12 +1361,12 @@ static int ospf_mpls_te_lsa_originate_as(void *arg)
struct mpls_te_link *lp;
int rc = -1;
if ((OspfMplsTE.status == disabled)
|| (OspfMplsTE.inter_as == Disable)) {
if ((!OspfMplsTE.enabled)
|| (OspfMplsTE.inter_as == Off)) {
zlog_info(
"ospf_mpls_te_lsa_originate_as: MPLS-TE Inter-AS is disabled for now.");
rc = 0; /* This is not an error case. */
goto out;
return rc;
}
for (ALL_LIST_ELEMENTS(OspfMplsTE.iflist, node, nnode, lp)) {
@ -1422,21 +1375,14 @@ static int ospf_mpls_te_lsa_originate_as(void *arg)
|| !IS_INTER_AS(lp->type))
continue;
if
CHECK_FLAG(lp->flags, LPFLG_LSA_ENGAGED)
{
if
CHECK_FLAG(lp->flags,
LPFLG_LSA_FORCED_REFRESH)
{
UNSET_FLAG(
lp->flags,
LPFLG_LSA_FORCED_REFRESH);
ospf_mpls_te_lsa_schedule(
lp, REFRESH_THIS_LSA);
}
continue;
if (CHECK_FLAG(lp->flags, LPFLG_LSA_ENGAGED)) {
if (CHECK_FLAG(lp->flags, LPFLG_LSA_FORCED_REFRESH)) {
UNSET_FLAG(lp->flags,LPFLG_LSA_FORCED_REFRESH);
ospf_mpls_te_lsa_schedule(lp, REFRESH_THIS_LSA);
}
continue;
}
if (!is_mandated_params_set(lp)) {
zlog_warn(
"ospf_mpls_te_lsa_originate_as: Link(%s) lacks some mandated MPLS-TE parameters.",
@ -1462,7 +1408,6 @@ static int ospf_mpls_te_lsa_originate_as(void *arg)
}
rc = 0;
out:
return rc;
}
@ -1473,7 +1418,7 @@ static struct ospf_lsa *ospf_mpls_te_lsa_refresh(struct ospf_lsa *lsa)
struct ospf *top;
struct ospf_lsa *new = NULL;
if (OspfMplsTE.status == disabled) {
if (!OspfMplsTE.enabled) {
/*
* This LSA must have flushed before due to MPLS-TE status
* change.
@ -1504,13 +1449,13 @@ static struct ospf_lsa *ospf_mpls_te_lsa_refresh(struct ospf_lsa *lsa)
if (lp)
UNSET_FLAG(lp->flags, LPFLG_LSA_ENGAGED);
ospf_opaque_lsa_flush_schedule(lsa);
goto out;
return NULL;
}
/* Create new Opaque-LSA/MPLS-TE instance. */
if ((new = ospf_mpls_te_lsa_new(area, lp)) == NULL) {
zlog_warn("ospf_mpls_te_lsa_refresh: ospf_mpls_te_lsa_new() ?");
goto out;
return NULL;
}
new->data->ls_seqnum = lsa_seqnum_increment(lsa);
@ -1526,7 +1471,7 @@ static struct ospf_lsa *ospf_mpls_te_lsa_refresh(struct ospf_lsa *lsa)
if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) {
zlog_warn("ospf_mpls_te_lsa_refresh: ospf_lsa_install() ?");
ospf_lsa_unlock(&new);
goto out;
return NULL;
}
/* Flood updated LSA through AS or Area depending of the RFC of the link
@ -1543,11 +1488,10 @@ static struct ospf_lsa *ospf_mpls_te_lsa_refresh(struct ospf_lsa *lsa)
ospf_lsa_header_dump(new->data);
}
out:
return new;
}
void ospf_mpls_te_lsa_schedule(struct mpls_te_link *lp, opcode_t opcode)
void ospf_mpls_te_lsa_schedule(struct mpls_te_link *lp, enum lsa_opcode opcode)
{
struct ospf_lsa lsa;
struct lsa_header lsah;
@ -1636,7 +1580,7 @@ void ospf_mpls_te_lsa_schedule(struct mpls_te_link *lp, opcode_t opcode)
*------------------------------------------------------------------------*/
static u_int16_t show_vty_router_addr(struct vty *vty,
struct te_tlv_header *tlvh)
struct tlv_header *tlvh)
{
struct te_tlv_router_addr *top = (struct te_tlv_router_addr *)tlvh;
@ -1649,7 +1593,7 @@ static u_int16_t show_vty_router_addr(struct vty *vty,
}
static u_int16_t show_vty_link_header(struct vty *vty,
struct te_tlv_header *tlvh)
struct tlv_header *tlvh)
{
struct te_tlv_link *top = (struct te_tlv_link *)tlvh;
@ -1664,7 +1608,7 @@ static u_int16_t show_vty_link_header(struct vty *vty,
}
static u_int16_t show_vty_link_subtlv_link_type(struct vty *vty,
struct te_tlv_header *tlvh)
struct tlv_header *tlvh)
{
struct te_link_subtlv_link_type *top;
const char *cp = "Unknown";
@ -1691,7 +1635,7 @@ static u_int16_t show_vty_link_subtlv_link_type(struct vty *vty,
}
static u_int16_t show_vty_link_subtlv_link_id(struct vty *vty,
struct te_tlv_header *tlvh)
struct tlv_header *tlvh)
{
struct te_link_subtlv_link_id *top;
@ -1705,7 +1649,7 @@ static u_int16_t show_vty_link_subtlv_link_id(struct vty *vty,
}
static u_int16_t show_vty_link_subtlv_lclif_ipaddr(struct vty *vty,
struct te_tlv_header *tlvh)
struct tlv_header *tlvh)
{
struct te_link_subtlv_lclif_ipaddr *top;
int i, n;
@ -1730,7 +1674,7 @@ static u_int16_t show_vty_link_subtlv_lclif_ipaddr(struct vty *vty,
}
static u_int16_t show_vty_link_subtlv_rmtif_ipaddr(struct vty *vty,
struct te_tlv_header *tlvh)
struct tlv_header *tlvh)
{
struct te_link_subtlv_rmtif_ipaddr *top;
int i, n;
@ -1754,7 +1698,7 @@ static u_int16_t show_vty_link_subtlv_rmtif_ipaddr(struct vty *vty,
}
static u_int16_t show_vty_link_subtlv_te_metric(struct vty *vty,
struct te_tlv_header *tlvh)
struct tlv_header *tlvh)
{
struct te_link_subtlv_te_metric *top;
@ -1770,7 +1714,7 @@ static u_int16_t show_vty_link_subtlv_te_metric(struct vty *vty,
}
static u_int16_t show_vty_link_subtlv_max_bw(struct vty *vty,
struct te_tlv_header *tlvh)
struct tlv_header *tlvh)
{
struct te_link_subtlv_max_bw *top;
float fval;
@ -1787,7 +1731,7 @@ static u_int16_t show_vty_link_subtlv_max_bw(struct vty *vty,
}
static u_int16_t show_vty_link_subtlv_max_rsv_bw(struct vty *vty,
struct te_tlv_header *tlvh)
struct tlv_header *tlvh)
{
struct te_link_subtlv_max_rsv_bw *top;
float fval;
@ -1806,7 +1750,7 @@ static u_int16_t show_vty_link_subtlv_max_rsv_bw(struct vty *vty,
}
static u_int16_t show_vty_link_subtlv_unrsv_bw(struct vty *vty,
struct te_tlv_header *tlvh)
struct tlv_header *tlvh)
{
struct te_link_subtlv_unrsv_bw *top;
float fval1, fval2;
@ -1837,7 +1781,7 @@ static u_int16_t show_vty_link_subtlv_unrsv_bw(struct vty *vty,
}
static u_int16_t show_vty_link_subtlv_rsc_clsclr(struct vty *vty,
struct te_tlv_header *tlvh)
struct tlv_header *tlvh)
{
struct te_link_subtlv_rsc_clsclr *top;
@ -1853,7 +1797,7 @@ static u_int16_t show_vty_link_subtlv_rsc_clsclr(struct vty *vty,
}
static u_int16_t show_vty_link_subtlv_lrrid(struct vty *vty,
struct te_tlv_header *tlvh)
struct tlv_header *tlvh)
{
struct te_link_subtlv_lrrid *top;
@ -1875,7 +1819,7 @@ static u_int16_t show_vty_link_subtlv_lrrid(struct vty *vty,
}
static u_int16_t show_vty_link_subtlv_llri(struct vty *vty,
struct te_tlv_header *tlvh)
struct tlv_header *tlvh)
{
struct te_link_subtlv_llri *top;
@ -1897,7 +1841,7 @@ static u_int16_t show_vty_link_subtlv_llri(struct vty *vty,
}
static u_int16_t show_vty_link_subtlv_rip(struct vty *vty,
struct te_tlv_header *tlvh)
struct tlv_header *tlvh)
{
struct te_link_subtlv_rip *top;
@ -1914,7 +1858,7 @@ static u_int16_t show_vty_link_subtlv_rip(struct vty *vty,
}
static u_int16_t show_vty_link_subtlv_ras(struct vty *vty,
struct te_tlv_header *tlvh)
struct tlv_header *tlvh)
{
struct te_link_subtlv_ras *top;
@ -1931,7 +1875,7 @@ static u_int16_t show_vty_link_subtlv_ras(struct vty *vty,
}
static u_int16_t show_vty_link_subtlv_av_delay(struct vty *vty,
struct te_tlv_header *tlvh)
struct tlv_header *tlvh)
{
struct te_link_subtlv_av_delay *top;
u_int32_t delay;
@ -1952,7 +1896,7 @@ static u_int16_t show_vty_link_subtlv_av_delay(struct vty *vty,
}
static u_int16_t show_vty_link_subtlv_mm_delay(struct vty *vty,
struct te_tlv_header *tlvh)
struct tlv_header *tlvh)
{
struct te_link_subtlv_mm_delay *top;
u_int32_t low, high;
@ -1974,7 +1918,7 @@ static u_int16_t show_vty_link_subtlv_mm_delay(struct vty *vty,
}
static u_int16_t show_vty_link_subtlv_delay_var(struct vty *vty,
struct te_tlv_header *tlvh)
struct tlv_header *tlvh)
{
struct te_link_subtlv_delay_var *top;
u_int32_t jitter;
@ -1991,7 +1935,7 @@ static u_int16_t show_vty_link_subtlv_delay_var(struct vty *vty,
}
static u_int16_t show_vty_link_subtlv_pkt_loss(struct vty *vty,
struct te_tlv_header *tlvh)
struct tlv_header *tlvh)
{
struct te_link_subtlv_pkt_loss *top;
u_int32_t loss;
@ -2014,7 +1958,7 @@ static u_int16_t show_vty_link_subtlv_pkt_loss(struct vty *vty,
}
static u_int16_t show_vty_link_subtlv_res_bw(struct vty *vty,
struct te_tlv_header *tlvh)
struct tlv_header *tlvh)
{
struct te_link_subtlv_res_bw *top;
float fval;
@ -2035,7 +1979,7 @@ static u_int16_t show_vty_link_subtlv_res_bw(struct vty *vty,
}
static u_int16_t show_vty_link_subtlv_ava_bw(struct vty *vty,
struct te_tlv_header *tlvh)
struct tlv_header *tlvh)
{
struct te_link_subtlv_ava_bw *top;
float fval;
@ -2056,7 +2000,7 @@ static u_int16_t show_vty_link_subtlv_ava_bw(struct vty *vty,
}
static u_int16_t show_vty_link_subtlv_use_bw(struct vty *vty,
struct te_tlv_header *tlvh)
struct tlv_header *tlvh)
{
struct te_link_subtlv_use_bw *top;
float fval;
@ -2077,7 +2021,7 @@ static u_int16_t show_vty_link_subtlv_use_bw(struct vty *vty,
}
static u_int16_t show_vty_unknown_tlv(struct vty *vty,
struct te_tlv_header *tlvh)
struct tlv_header *tlvh)
{
if (vty != NULL)
vty_out(vty, " Unknown TLV: [type(0x%x), length(0x%x)]\n",
@ -2090,11 +2034,11 @@ static u_int16_t show_vty_unknown_tlv(struct vty *vty,
}
static u_int16_t ospf_mpls_te_show_link_subtlv(struct vty *vty,
struct te_tlv_header *tlvh0,
struct tlv_header *tlvh0,
u_int16_t subtotal,
u_int16_t total)
{
struct te_tlv_header *tlvh, *next;
struct tlv_header *tlvh, *next;
u_int16_t sum = subtotal;
for (tlvh = tlvh0; sum < total;
@ -2172,9 +2116,9 @@ static u_int16_t ospf_mpls_te_show_link_subtlv(struct vty *vty,
static void ospf_mpls_te_show_info(struct vty *vty, struct ospf_lsa *lsa)
{
struct lsa_header *lsah = (struct lsa_header *)lsa->data;
struct te_tlv_header *tlvh, *next;
struct tlv_header *tlvh, *next;
u_int16_t sum, total;
u_int16_t (*subfunc)(struct vty * vty, struct te_tlv_header * tlvh,
u_int16_t (*subfunc)(struct vty * vty, struct tlv_header * tlvh,
u_int16_t subtotal, u_int16_t total) = NULL;
sum = 0;
@ -2184,7 +2128,7 @@ static void ospf_mpls_te_show_info(struct vty *vty, struct ospf_lsa *lsa)
tlvh = (next ? next : TLV_HDR_NEXT(tlvh))) {
if (subfunc != NULL) {
sum = (*subfunc)(vty, tlvh, sum, total);
next = (struct te_tlv_header *)((char *)tlvh + sum);
next = (struct tlv_header *)((char *)tlvh + sum);
subfunc = NULL;
continue;
}
@ -2197,7 +2141,7 @@ static void ospf_mpls_te_show_info(struct vty *vty, struct ospf_lsa *lsa)
case TE_TLV_LINK:
sum += show_vty_link_header(vty, tlvh);
subfunc = ospf_mpls_te_show_link_subtlv;
next = tlvh + 1;
next = TLV_DATA(tlvh);
break;
default:
sum += show_vty_unknown_tlv(vty, tlvh);
@ -2210,7 +2154,7 @@ static void ospf_mpls_te_show_info(struct vty *vty, struct ospf_lsa *lsa)
static void ospf_mpls_te_config_write_router(struct vty *vty)
{
if (OspfMplsTE.status == enabled) {
if (OspfMplsTE.enabled) {
vty_out(vty, " mpls-te on\n");
vty_out(vty, " mpls-te router-address %s\n",
inet_ntoa(OspfMplsTE.router_addr.value));
@ -2239,20 +2183,20 @@ DEFUN (ospf_mpls_te_on,
struct listnode *node;
struct mpls_te_link *lp;
if (OspfMplsTE.status == enabled)
if (OspfMplsTE.enabled)
return CMD_SUCCESS;
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("MPLS-TE: OFF -> ON");
OspfMplsTE.status = enabled;
OspfMplsTE.enabled = true;
/* Reoriginate RFC3630 & RFC6827 Links */
ospf_mpls_te_foreach_area(ospf_mpls_te_lsa_schedule,
REORIGINATE_THIS_LSA);
/* Reoriginate LSA if INTER-AS is always on */
if (OspfMplsTE.inter_as != Disable) {
if (OspfMplsTE.inter_as != Off) {
for (ALL_LIST_ELEMENTS_RO(OspfMplsTE.iflist, node, lp)) {
if (IS_INTER_AS(lp->type)) {
ospf_mpls_te_lsa_schedule(lp,
@ -2275,18 +2219,17 @@ DEFUN (no_ospf_mpls_te,
struct listnode *node, *nnode;
struct mpls_te_link *lp;
if (OspfMplsTE.status == disabled)
if (!OspfMplsTE.enabled)
return CMD_SUCCESS;
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("MPLS-TE: ON -> OFF");
OspfMplsTE.status = disabled;
OspfMplsTE.enabled = false;
for (ALL_LIST_ELEMENTS(OspfMplsTE.iflist, node, nnode, lp))
if
CHECK_FLAG(lp->flags, LPFLG_LSA_ENGAGED)
ospf_mpls_te_lsa_schedule(lp, FLUSH_THIS_LSA);
if (CHECK_FLAG(lp->flags, LPFLG_LSA_ENGAGED))
ospf_mpls_te_lsa_schedule(lp, FLUSH_THIS_LSA);
return CMD_SUCCESS;
}
@ -2317,8 +2260,8 @@ DEFUN (ospf_mpls_te_router_addr,
set_mpls_te_router_addr(value);
if (OspfMplsTE.status == disabled)
goto out;
if (!OspfMplsTE.enabled)
return CMD_SUCCESS;
for (ALL_LIST_ELEMENTS(OspfMplsTE.iflist, node, nnode, lp)) {
if ((lp->area == NULL) || IS_FLOOD_AS(lp->type))
@ -2344,7 +2287,7 @@ DEFUN (ospf_mpls_te_router_addr,
ospf_mpls_te_foreach_area(ospf_mpls_te_lsa_schedule,
REORIGINATE_THIS_LSA);
}
out:
return CMD_SUCCESS;
}
@ -2356,7 +2299,7 @@ static int set_inter_as_mode(struct vty *vty, const char *mode_name,
struct mpls_te_link *lp;
int format;
if (OspfMplsTE.status == enabled) {
if (OspfMplsTE.enabled) {
/* Read and Check inter_as mode */
if (strcmp(mode_name, "as") == 0)
@ -2385,7 +2328,7 @@ static int set_inter_as_mode(struct vty *vty, const char *mode_name,
}
/* Enable mode and re-originate LSA if needed */
if ((OspfMplsTE.inter_as == Disable)
if ((OspfMplsTE.inter_as == Off)
&& (mode != OspfMplsTE.inter_as)) {
OspfMplsTE.inter_as = mode;
/* Re-originate all InterAS-TEv2 LSA */
@ -2451,9 +2394,9 @@ DEFUN (no_ospf_mpls_te_inter_as,
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("MPLS-TE: Inter-AS support OFF");
if ((OspfMplsTE.status == enabled)
&& (OspfMplsTE.inter_as != Disable)) {
OspfMplsTE.inter_as = Disable;
if ((OspfMplsTE.enabled)
&& (OspfMplsTE.inter_as != Off)) {
OspfMplsTE.inter_as = Off;
/* Flush all Inter-AS LSA */
for (ALL_LIST_ELEMENTS(OspfMplsTE.iflist, node, nnode, lp))
if (IS_INTER_AS(lp->type)
@ -2476,7 +2419,7 @@ DEFUN (show_ip_ospf_mpls_te_router,
"MPLS-TE information\n"
"MPLS-TE Router parameters\n")
{
if (OspfMplsTE.status == enabled) {
if (OspfMplsTE.enabled) {
vty_out(vty, "--- MPLS-TE router parameters ---\n");
if (ntohs(OspfMplsTE.router_addr.header.type) != 0)
@ -2492,7 +2435,7 @@ static void show_mpls_te_link_sub(struct vty *vty, struct interface *ifp)
{
struct mpls_te_link *lp;
if ((OspfMplsTE.status == enabled) && HAS_LINK_PARAMS(ifp)
if ((OspfMplsTE.enabled) && HAS_LINK_PARAMS(ifp)
&& !if_is_loopback(ifp) && if_is_up(ifp)
&& ((lp = lookup_linkparams_by_ifp(ifp)) != NULL)) {
/* Continue only if interface is not passive or support Inter-AS

View File

@ -78,7 +78,7 @@
#define FLOOD_AS 0x20
#define EMULATED 0x80
#define IS_STD_TE(x) (x & STD_TE)
#define IS_STD_TE(x) (x & STD_TE)
#define IS_PSEUDO_TE(x) (x & PSEUDO_TE)
#define IS_INTER_AS(x) (x & INTER_AS)
#define IS_EMULATED(x) (x & EMULATED)
@ -94,58 +94,32 @@
#define LPFLG_LOOKUP_DONE 0x4
#define LPFLG_LSA_FORCED_REFRESH 0x8
/*
* Following section defines TLV (tag, length, value) structures,
* used for Traffic Engineering.
*/
struct te_tlv_header {
u_int16_t type; /* TE_TLV_XXX (see below) */
u_int16_t length; /* Value portion only, in octets */
};
#define TLV_HDR_SIZE (sizeof(struct te_tlv_header))
#define TLV_BODY_SIZE(tlvh) (ROUNDUP(ntohs((tlvh)->length), sizeof(u_int32_t)))
#define TLV_SIZE(tlvh) (TLV_HDR_SIZE + TLV_BODY_SIZE(tlvh))
#define TLV_HDR_TOP(lsah) \
(struct te_tlv_header *)((char *)(lsah) + OSPF_LSA_HEADER_SIZE)
#define TLV_HDR_NEXT(tlvh) \
(struct te_tlv_header *)((char *)(tlvh) + TLV_SIZE(tlvh))
#define TLV_HDR_SUBTLV(tlvh) \
(struct te_tlv_header *)((char *)(tlvh) + TLV_HDR_SIZE)
#define TLV_TYPE(tlvh) tlvh.header.type
#define TLV_LEN(tlvh) tlvh.header.length
#define TLV_HDR(tlvh) tlvh.header
/*
* Following section defines TLV body parts.
*/
/* Router Address TLV */ /* Mandatory */
#define TE_TLV_ROUTER_ADDR 1
struct te_tlv_router_addr {
struct te_tlv_header header; /* Value length is 4 octets. */
struct tlv_header header; /* Value length is 4 octets. */
struct in_addr value;
};
/* Link TLV */
#define TE_TLV_LINK 2
struct te_tlv_link {
struct te_tlv_header header;
struct tlv_header header;
/* A set of link-sub-TLVs will follow. */
};
/* Default TE TLV size */
#define TE_LINK_SUBTLV_DEF_SIZE 4
/* Link Type Sub-TLV */ /* Mandatory */
#define TE_LINK_SUBTLV_LINK_TYPE 1
#define TE_LINK_SUBTLV_TYPE_SIZE 1
struct te_link_subtlv_link_type {
struct te_tlv_header header; /* Value length is 1 octet. */
struct tlv_header header; /* Value length is 1 octet. */
struct {
#define LINK_TYPE_SUBTLV_VALUE_PTP 1
#define LINK_TYPE_SUBTLV_VALUE_MA 2
@ -157,42 +131,42 @@ struct te_link_subtlv_link_type {
/* Link Sub-TLV: Link ID */ /* Mandatory */
#define TE_LINK_SUBTLV_LINK_ID 2
struct te_link_subtlv_link_id {
struct te_tlv_header header; /* Value length is 4 octets. */
struct tlv_header header; /* Value length is 4 octets. */
struct in_addr value; /* Same as router-lsa's link-id. */
};
/* Link Sub-TLV: Local Interface IP Address */ /* Optional */
#define TE_LINK_SUBTLV_LCLIF_IPADDR 3
struct te_link_subtlv_lclif_ipaddr {
struct te_tlv_header header; /* Value length is 4 x N octets. */
struct tlv_header header; /* Value length is 4 x N octets. */
struct in_addr value[1]; /* Local IP address(es). */
};
/* Link Sub-TLV: Remote Interface IP Address */ /* Optional */
#define TE_LINK_SUBTLV_RMTIF_IPADDR 4
struct te_link_subtlv_rmtif_ipaddr {
struct te_tlv_header header; /* Value length is 4 x N octets. */
struct tlv_header header; /* Value length is 4 x N octets. */
struct in_addr value[1]; /* Neighbor's IP address(es). */
};
/* Link Sub-TLV: Traffic Engineering Metric */ /* Optional */
#define TE_LINK_SUBTLV_TE_METRIC 5
struct te_link_subtlv_te_metric {
struct te_tlv_header header; /* Value length is 4 octets. */
struct tlv_header header; /* Value length is 4 octets. */
u_int32_t value; /* Link metric for TE purpose. */
};
/* Link Sub-TLV: Maximum Bandwidth */ /* Optional */
#define TE_LINK_SUBTLV_MAX_BW 6
struct te_link_subtlv_max_bw {
struct te_tlv_header header; /* Value length is 4 octets. */
struct tlv_header header; /* Value length is 4 octets. */
float value; /* bytes/sec */
};
/* Link Sub-TLV: Maximum Reservable Bandwidth */ /* Optional */
#define TE_LINK_SUBTLV_MAX_RSV_BW 7
struct te_link_subtlv_max_rsv_bw {
struct te_tlv_header header; /* Value length is 4 octets. */
struct tlv_header header; /* Value length is 4 octets. */
float value; /* bytes/sec */
};
@ -200,14 +174,14 @@ struct te_link_subtlv_max_rsv_bw {
#define TE_LINK_SUBTLV_UNRSV_BW 8
#define TE_LINK_SUBTLV_UNRSV_SIZE 32
struct te_link_subtlv_unrsv_bw {
struct te_tlv_header header; /* Value length is 32 octets. */
struct tlv_header header; /* Value length is 32 octets. */
float value[MAX_CLASS_TYPE]; /* One for each priority level. */
};
/* Link Sub-TLV: Resource Class/Color */ /* Optional */
#define TE_LINK_SUBTLV_RSC_CLSCLR 9
struct te_link_subtlv_rsc_clsclr {
struct te_tlv_header header; /* Value length is 4 octets. */
struct tlv_header header; /* Value length is 4 octets. */
u_int32_t value; /* Admin. group membership. */
};
@ -216,7 +190,7 @@ struct te_link_subtlv_rsc_clsclr {
#define TE_LINK_SUBTLV_LRRID 10
#define TE_LINK_SUBTLV_LRRID_SIZE 8
struct te_link_subtlv_lrrid {
struct te_tlv_header header; /* Value length is 8 octets. */
struct tlv_header header; /* Value length is 8 octets. */
struct in_addr local; /* Local TE Router Identifier */
struct in_addr remote; /* Remote TE Router Identifier */
};
@ -225,7 +199,7 @@ struct te_link_subtlv_lrrid {
#define TE_LINK_SUBTLV_LLRI 11
#define TE_LINK_SUBTLV_LLRI_SIZE 8
struct te_link_subtlv_llri {
struct te_tlv_header header; /* Value length is 8 octets. */
struct tlv_header header; /* Value length is 8 octets. */
u_int32_t local; /* Link Local Identifier */
u_int32_t remote; /* Link Remote Identifier */
};
@ -240,14 +214,14 @@ struct te_link_subtlv_llri {
/* Remote AS Number sub-TLV */
#define TE_LINK_SUBTLV_RAS 21
struct te_link_subtlv_ras {
struct te_tlv_header header; /* Value length is 4 octets. */
struct tlv_header header; /* Value length is 4 octets. */
u_int32_t value; /* Remote AS number */
};
/* IPv4 Remote ASBR ID Sub-TLV */
#define TE_LINK_SUBTLV_RIP 22
struct te_link_subtlv_rip {
struct te_tlv_header header; /* Value length is 4 octets. */
struct tlv_header header; /* Value length is 4 octets. */
struct in_addr value; /* Remote ASBR IP address */
};
@ -261,63 +235,69 @@ struct te_link_subtlv_rip {
/* Link Sub-TLV: Average Link Delay */ /* Optional */
#define TE_LINK_SUBTLV_AV_DELAY 27
struct te_link_subtlv_av_delay {
struct te_tlv_header header; /* Value length is 4 bytes. */
u_int32_t
value; /* delay in micro-seconds only 24 bits => 0 ... 16777215
with Anomalous Bit as Upper most bit */
struct tlv_header header; /* Value length is 4 bytes. */
/*
* delay in micro-seconds only 24 bits => 0 ... 16777215
* with Anomalous Bit as Upper most bit
*/
u_int32_t value;
};
/* Link Sub-TLV: Low/High Link Delay */
#define TE_LINK_SUBTLV_MM_DELAY 28
#define TE_LINK_SUBTLV_MM_DELAY_SIZE 8
struct te_link_subtlv_mm_delay {
struct te_tlv_header header; /* Value length is 8 bytes. */
u_int32_t low; /* low delay in micro-seconds only 24 bits => 0 ...
16777215
with Anomalous Bit (A) as Upper most bit */
u_int32_t high; /* high delay in micro-seconds only 24 bits => 0 ...
16777215 */
struct tlv_header header; /* Value length is 8 bytes. */
/*
* low delay in micro-seconds only 24 bits => 0 ... 16777215
* with Anomalous Bit (A) as Upper most bit
*/
u_int32_t low;
/* high delay in micro-seconds only 24 bits => 0 ... 16777215 */
u_int32_t high;
};
/* Link Sub-TLV: Link Delay Variation i.e. Jitter */
#define TE_LINK_SUBTLV_DELAY_VAR 29
struct te_link_subtlv_delay_var {
struct te_tlv_header header; /* Value length is 4 bytes. */
u_int32_t value; /* interval in micro-seconds only 24 bits => 0 ...
16777215 */
struct tlv_header header; /* Value length is 4 bytes. */
/* interval in micro-seconds only 24 bits => 0 ... 16777215 */
u_int32_t value;
};
/* Link Sub-TLV: Routine Unidirectional Link Packet Loss */
#define TE_LINK_SUBTLV_PKT_LOSS 30
struct te_link_subtlv_pkt_loss {
struct te_tlv_header header; /* Value length is 4 bytes. */
u_int32_t
value; /* in percentage of total traffic only 24 bits (2^24 - 2)
with Anomalous Bit as Upper most bit */
struct tlv_header header; /* Value length is 4 bytes. */
/*
* in percentage of total traffic only 24 bits (2^24 - 2)
* with Anomalous Bit as Upper most bit
*/
u_int32_t value;
};
/* Link Sub-TLV: Unidirectional Residual Bandwidth */ /* Optional */
#define TE_LINK_SUBTLV_RES_BW 31
struct te_link_subtlv_res_bw {
struct te_tlv_header header; /* Value length is 4 bytes. */
float value; /* bandwidth in IEEE floating point format with units in
bytes per second */
struct tlv_header header; /* Value length is 4 bytes. */
/* bandwidth in IEEE floating point format with units in bytes/second */
float value;
};
/* Link Sub-TLV: Unidirectional Available Bandwidth */ /* Optional */
#define TE_LINK_SUBTLV_AVA_BW 32
struct te_link_subtlv_ava_bw {
struct te_tlv_header header; /* Value length is 4 octets. */
float value; /* bandwidth in IEEE floating point format with units in
bytes per second */
struct tlv_header header; /* Value length is 4 octets. */
/* bandwidth in IEEE floating point format with units in bytes/second */
float value;
};
/* Link Sub-TLV: Unidirectional Utilized Bandwidth */ /* Optional */
#define TE_LINK_SUBTLV_USE_BW 33
struct te_link_subtlv_use_bw {
struct te_tlv_header header; /* Value length is 4 octets. */
float value; /* bandwidth in IEEE floating point format with units in
bytes per second */
struct tlv_header header; /* Value length is 4 octets. */
/* bandwidth in IEEE floating point format with units in bytes/second */
float value;
};
#define TE_LINK_SUBTLV_MAX 34 /* Last SUBTLV + 1 */
@ -325,20 +305,11 @@ struct te_link_subtlv_use_bw {
/* Here are "non-official" architectural constants. */
#define MPLS_TE_MINIMUM_BANDWIDTH 1.0 /* Reasonable? *//* XXX */
/* Following declaration concerns the MPLS-TE and LINk-TE management */
typedef enum _opcode_t {
REORIGINATE_THIS_LSA,
REFRESH_THIS_LSA,
FLUSH_THIS_LSA
} opcode_t;
typedef enum _status_t { disabled, enabled } status_t;
/* Mode for Inter-AS Opaque-LSA */
enum inter_as_mode { Disable, AS, Area };
enum inter_as_mode { Off, AS, Area };
struct te_link_subtlv {
struct te_tlv_header header;
struct tlv_header header;
union {
u_int32_t link_type;
struct in_addr link_id;
@ -366,7 +337,7 @@ struct te_link_subtlv {
/* Following structure are internal use only. */
struct ospf_mpls_te {
/* Status of MPLS-TE: enable or disbale */
status_t status;
bool enabled;
/* RFC5392 */
enum inter_as_mode inter_as;
@ -437,8 +408,7 @@ extern int ospf_mpls_te_init(void);
extern void ospf_mpls_te_term(void);
extern struct ospf_mpls_te *get_ospf_mpls_te(void);
extern void ospf_mpls_te_update_if(struct interface *);
extern void ospf_mpls_te_lsa_schedule(struct mpls_te_link *, opcode_t);
extern u_int32_t get_mpls_te_instance_value(void);
extern void ospf_mpls_te_lsa_schedule(struct mpls_te_link *, enum lsa_opcode);
extern void set_linkparams_llri(struct mpls_te_link *, u_int32_t, u_int32_t);
extern void set_linkparams_lrrid(struct mpls_te_link *, struct in_addr,
struct in_addr);

View File

@ -4402,6 +4402,10 @@ static int show_ip_ospf_neighbor_id_common(struct vty *vty, struct ospf *ospf,
if (!ret) {
if (!use_json)
vty_out(vty, "Please specify Neighbor ID by A.B.C.D\n");
else {
vty_out(vty, "{}\n");
json_object_free(json);
}
return CMD_WARNING;
}
@ -4682,6 +4686,10 @@ static int show_ip_ospf_neighbor_int_detail_common(struct vty *vty,
if (!ifp) {
if (!use_json)
vty_out(vty, "No such interface.\n");
else {
vty_out(vty, "{}\n");
json_object_free(json);
}
return CMD_WARNING;
}

View File

@ -976,9 +976,13 @@ int ospf_network_unset(struct ospf *ospf, struct prefix_ipv4 *p,
rn->info = NULL;
route_unlock_node(rn); /* initial reference */
/* Find interfaces that not configured already. */
/* Find interfaces that are not configured already. */
for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi)) {
ospf_network_run_subnet(ospf, oi->connected, NULL, NULL);
if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
continue;
ospf_network_run_subnet(ospf, oi->connected, NULL, NULL);
}
/* Update connected redistribute. */

View File

@ -101,7 +101,7 @@ struct ospf_master {
/* Various OSPF global configuration. */
u_char options;
#define OSPF_MASTER_SHUTDOWN (1 << 0) /* deferred-shutdown */
#define OSPF_MASTER_SHUTDOWN (1 << 0) /* deferred-shutdown */
};
struct ospf_redist {

View File

@ -1,3 +0,0 @@
rcdir=@pkgsrcrcdir@
rc_SCRIPTS = bgpd.sh ospf6d.sh ospfd.sh ripd.sh ripngd.sh zebra.sh

View File

@ -1,3 +0,0 @@
EXTRA_DIST = \
clidef.py \
clippy/__init__.py

2
qpb/.gitignore vendored
View File

@ -1,4 +1,4 @@
Makefile
!Makefile
Makefile.in
*.o
tags

10
qpb/Makefile Normal file
View File

@ -0,0 +1,10 @@
all: ALWAYS
@$(MAKE) -s -C .. fpm/libfrr_pb.la
%: ALWAYS
@$(MAKE) -s -C .. fpm/$@
Makefile:
#nothing
ALWAYS:
.PHONY: ALWAYS makefiles
.SUFFIXES:

View File

@ -1,30 +0,0 @@
include ../common.am
AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib $(Q_PROTOBUF_C_CLIENT_INCLUDES)
PROTOBUF_INCLUDES=-I$(top_srcdir)
PROTOBUF_PACKAGE = qpb
lib_LTLIBRARIES = libfrr_pb.la
libfrr_pb_la_LDFLAGS = -version-info 0:0:0
if HAVE_PROTOBUF
protobuf_srcs = \
qpb_allocator.c
protobuf_srcs_nodist = \
qpb.pb-c.c
endif
libfrr_pb_la_SOURCES = \
linear_allocator.h \
qpb.h \
qpb.c \
qpb_allocator.h \
$(protobuf_srcs)
nodist_libfrr_pb_la_SOURCES = $(protobuf_srcs_nodist)
CLEANFILES = $(Q_CLEANFILES)
BUILT_SOURCES = $(Q_PROTOBUF_SRCS)
EXTRA_DIST = qpb.proto

View File

@ -20,6 +20,8 @@
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
syntax = "proto2";
/*
* Protobuf definitions pertaining to the Quagga/FRR Protobuf component.
*/
@ -87,4 +89,4 @@ enum Protocol {
ISIS = 8;
BGP = 9;
OTHER = 10;
}
}

View File

@ -42,8 +42,7 @@ static void _qpb_free(void *allocator_data, void *ptr)
linear_allocator_free(allocator_data, ptr);
}
static ProtobufCAllocator allocator_template = {_qpb_alloc, _qpb_free, NULL,
8192, NULL};
static ProtobufCAllocator allocator_template = {_qpb_alloc, _qpb_free, NULL};
/*
* qpb_allocator_init_linear

26
qpb/subdir.am Normal file
View File

@ -0,0 +1,26 @@
if HAVE_PROTOBUF
lib_LTLIBRARIES += qpb/libfrr_pb.la
endif
qpb_libfrr_pb_la_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir) -I$(top_builddir)/lib \
$(Q_PROTOBUF_C_CLIENT_INCLUDES)
qpb_libfrr_pb_la_LDFLAGS = -version-info 0:0:0
qpb_libfrr_pb_la_SOURCES = \
qpb/linear_allocator.h \
qpb/qpb.h \
qpb/qpb.c \
qpb/qpb_allocator.h \
# end
if HAVE_PROTOBUF
qpb_libfrr_pb_la_SOURCES += qpb/qpb_allocator.c
nodist_qpb_libfrr_pb_la_SOURCES = qpb/qpb.pb-c.c
BUILT_SOURCES += qpb/qpb.pb-c.c
CLEANFILES += \
qpb/qpb.pb-c.c \
qpb/qpb.pb-c.h \
# end
endif
EXTRA_DIST += qpb/qpb.proto

View File

@ -1,5 +0,0 @@
EXTRA_DIST = frr.init frr.service daemons \
frr.logrotate frr.pam frr.spec \
README.rpm_build.md

View File

@ -515,6 +515,18 @@ case "$1" in
if [ -z "$dmn" -o "$dmn" = "zebra" ]; then
echo "Removing all routes made by zebra."
ip route flush proto zebra
# At least in CentOS/RHEL 6, iproute2 doesn't know
# about the new protocol names, so we have to flush them
# by number (it also doesn't support rt_protos.d
ip route flush proto 186
ip route flush proto 187
ip route flush proto 188
ip route flush proto 189
ip route flush proto 190
ip route flush proto 191
ip route flush proto 192
ip route flush proto 193
ip route flush proto 194
else
[ -n "$dmn" ] && eval "${dmn/-/_}=0"
start_watchfrr

View File

@ -66,7 +66,7 @@ DEFUN (debug_rip_events,
"RIP events\n")
{
rip_debug_event = RIP_DEBUG_EVENT;
return CMD_WARNING_CONFIG_FAILED;
return CMD_SUCCESS;
}
DEFUN (debug_rip_packet,
@ -112,7 +112,7 @@ DEFUN (debug_rip_zebra,
"RIP and ZEBRA communication\n")
{
rip_debug_zebra = RIP_DEBUG_ZEBRA;
return CMD_WARNING_CONFIG_FAILED;
return CMD_SUCCESS;
}
DEFUN (no_debug_rip_events,
@ -177,7 +177,7 @@ DEFUN (no_debug_rip_zebra,
"RIP and ZEBRA communication\n")
{
rip_debug_zebra = 0;
return CMD_WARNING_CONFIG_FAILED;
return CMD_SUCCESS;
}
/* Debug node. */

View File

@ -67,7 +67,7 @@ DEFUN (debug_ripng_events,
"Debug option set for ripng events\n")
{
ripng_debug_event = RIPNG_DEBUG_EVENT;
return CMD_WARNING_CONFIG_FAILED;
return CMD_SUCCESS;
}
DEFUN (debug_ripng_packet,
@ -114,7 +114,7 @@ DEFUN (debug_ripng_zebra,
"Debug option set for ripng and zebra communication\n")
{
ripng_debug_zebra = RIPNG_DEBUG_ZEBRA;
return CMD_WARNING_CONFIG_FAILED;
return CMD_SUCCESS;
}
DEFUN (no_debug_ripng_events,
@ -179,7 +179,7 @@ DEFUN (no_debug_ripng_zebra,
"Debug option set for ripng and zebra communication\n")
{
ripng_debug_zebra = 0;
return CMD_WARNING_CONFIG_FAILED;
return CMD_SUCCESS;
}
/* Debug node. */

View File

@ -1,8 +0,0 @@
EXTRA_DIST = snapcraft.yaml \
README.snap_build.md \
README.usage.md \
extra_version_info.txt \
scripts \
defaults \
helpers \
snap

View File

@ -170,7 +170,7 @@ static struct test_segment mp_segments[] = {
/* 8 */
{
"MP6",
"MP IP4/MPLS-laveled VPN",
"MP IP4/MPLS-labeled VPN",
{CAPABILITY_CODE_MP, 0x4, 0x0, 0x1, 0x0, 0x80},
6,
SHOULD_PARSE,

View File

@ -8,7 +8,7 @@ TestCapability.okfail("MPv6: MP IPv6/Uni")
TestCapability.okfail("MP2: MP IP/Multicast")
TestCapability.okfail("MP3: MP IP6/MPLS-labeled VPN")
TestCapability.okfail("MP5: MP IP6/MPLS-VPN")
TestCapability.okfail("MP6: MP IP4/MPLS-laveled VPN")
TestCapability.okfail("MP6: MP IP4/MPLS-labeled VPN")
TestCapability.okfail("MP8: MP unknown AFI/SAFI")
TestCapability.okfail("MP-short: MP IP4/Unicast, length too short (< minimum)")
TestCapability.okfail("MP-overflow: MP IP4/Unicast, length too long")

View File

@ -1059,7 +1059,7 @@ static void parse_test(struct peer *peer, struct test_segment *t, int type)
parse_ret = bgp_mp_unreach_parse(&attr_args, &nlri);
if (!parse_ret) {
iana_afi_t pkt_afi;
safi_t pkt_safi;
iana_safi_t pkt_safi;
/* Convert AFI, SAFI to internal values, check. */
if (bgp_map_afi_safi_int2iana(nlri.afi, nlri.safi, &pkt_afi,

View File

@ -303,7 +303,9 @@ static int vtysh_execute_func(const char *line, int pager)
|| saved_node == BGP_IPV4L_NODE
|| saved_node == BGP_IPV6L_NODE
|| saved_node == BGP_IPV6M_NODE
|| saved_node == BGP_EVPN_NODE)
|| saved_node == BGP_EVPN_NODE
|| saved_node == LDP_IPV4_NODE
|| saved_node == LDP_IPV6_NODE)
&& (tried == 1)) {
vtysh_execute("exit-address-family");
} else if ((saved_node == BGP_EVPN_VNI_NODE) && (tried == 1)) {
@ -496,6 +498,29 @@ int vtysh_mark_file(const char *filename)
strcpy(vty_buf_copy, vty->buf);
vty_buf_trimmed = trim(vty_buf_copy);
switch (vty->node) {
case LDP_IPV4_IFACE_NODE:
if (strncmp(vty_buf_copy, " ", 3)) {
fprintf(stdout, " end\n");
vty->node = LDP_IPV4_NODE;
}
break;
case LDP_IPV6_IFACE_NODE:
if (strncmp(vty_buf_copy, " ", 3)) {
fprintf(stdout, " end\n");
vty->node = LDP_IPV6_NODE;
}
break;
case LDP_PSEUDOWIRE_NODE:
if (strncmp(vty_buf_copy, " ", 2)) {
fprintf(stdout, " end\n");
vty->node = LDP_L2VPN_NODE;
}
break;
default:
break;
}
if (vty_buf_trimmed[0] == '!' || vty_buf_trimmed[0] == '#') {
fprintf(stdout, "%s", vty->buf);
continue;
@ -1268,6 +1293,14 @@ DEFUNSH(VTYSH_LDPD, ldp_address_family_ipv6, ldp_address_family_ipv6_cmd,
return CMD_SUCCESS;
}
DEFUNSH(VTYSH_LDPD, ldp_exit_address_family, ldp_exit_address_family_cmd,
"exit-address-family", "Exit from Address Family configuration mode\n")
{
if (vty->node == LDP_IPV4_NODE || vty->node == LDP_IPV6_NODE)
vty->node = LDP_NODE;
return CMD_SUCCESS;
}
DEFUNSH(VTYSH_LDPD, ldp_interface_ifname, ldp_interface_ifname_cmd,
"interface IFNAME",
"Enable LDP on an interface and enter interface submode\n"
@ -2420,7 +2453,7 @@ DEFUN (vtysh_show_daemons,
/* Execute command in child process. */
static void execute_command(const char *command, int argc,
struct cmd_token *arg1, const char *arg2)
const char *arg1, const char *arg2)
{
pid_t pid;
int status;
@ -2465,7 +2498,10 @@ DEFUN (vtysh_ping,
"Send echo messages\n"
"Ping destination address or hostname\n")
{
execute_command("ping", 1, argv[0], NULL);
int idx = 1;
argv_find(argv, argc, "WORD", &idx);
execute_command("ping", 1, argv[idx]->arg, NULL);
return CMD_SUCCESS;
}
@ -2480,7 +2516,10 @@ DEFUN (vtysh_traceroute,
"Trace route to destination\n"
"Trace route to destination address or hostname\n")
{
execute_command("traceroute", 1, argv[0], NULL);
int idx = 1;
argv_find(argv, argc, "WORD", &idx);
execute_command("traceroute", 1, argv[idx]->arg, NULL);
return CMD_SUCCESS;
}
@ -2496,7 +2535,7 @@ DEFUN (vtysh_ping6,
"IPv6 echo\n"
"Ping destination address or hostname\n")
{
execute_command("ping6", 1, argv[0], NULL);
execute_command("ping6", 1, argv[2]->arg, NULL);
return CMD_SUCCESS;
}
@ -2507,7 +2546,7 @@ DEFUN (vtysh_traceroute6,
"IPv6 trace\n"
"Trace route to destination address or hostname\n")
{
execute_command("traceroute6", 1, argv[0], NULL);
execute_command("traceroute6", 1, argv[2]->arg, NULL);
return CMD_SUCCESS;
}
@ -2518,7 +2557,7 @@ DEFUN (vtysh_telnet,
"Open a telnet connection\n"
"IP address or hostname of a remote system\n")
{
execute_command("telnet", 1, argv[0], NULL);
execute_command("telnet", 1, argv[1]->arg, NULL);
return CMD_SUCCESS;
}
@ -2529,7 +2568,7 @@ DEFUN (vtysh_telnet_port,
"IP address or hostname of a remote system\n"
"TCP Port number\n")
{
execute_command("telnet", 2, argv[0], argv[1]);
execute_command("telnet", 2, argv[1]->arg, argv[2]->arg);
return CMD_SUCCESS;
}
@ -2539,7 +2578,7 @@ DEFUN (vtysh_ssh,
"Open an ssh connection\n"
"[user@]host\n")
{
execute_command("ssh", 1, argv[0], NULL);
execute_command("ssh", 1, argv[1]->arg, NULL);
return CMD_SUCCESS;
}
@ -2582,9 +2621,39 @@ DEFUN (config_list,
return cmd_list_cmds(vty, argc == 2);
}
DEFUN(find,
find_cmd,
"find COMMAND...",
"Find CLI command containing text\n"
"Text to search for\n")
{
char *text = argv_concat(argv, argc, 1);
const struct cmd_node *node;
const struct cmd_element *cli;
vector clis;
for (unsigned int i = 0; i < vector_active(cmdvec); i++) {
node = vector_slot(cmdvec, i);
if (!node)
continue;
clis = node->cmd_vector;
for (unsigned int j = 0; j < vector_active(clis); j++) {
cli = vector_slot(clis, j);
if (strcasestr(cli->string, text))
fprintf(stdout, " (%s) %s\n",
node_names[node->node], cli->string);
}
}
XFREE(MTYPE_TMP, text);
return CMD_SUCCESS;
}
static void vtysh_install_default(enum node_type node)
{
install_element(node, &config_list_cmd);
install_element(node, &find_cmd);
}
/* Making connection to protocol daemon. */
@ -2876,48 +2945,13 @@ void vtysh_init_vty(void)
install_node(&isis_node, NULL);
install_node(&vty_node, NULL);
vtysh_install_default(VIEW_NODE);
vtysh_install_default(CONFIG_NODE);
vtysh_install_default(BGP_NODE);
vtysh_install_default(RIP_NODE);
vtysh_install_default(INTERFACE_NODE);
vtysh_install_default(LINK_PARAMS_NODE);
vtysh_install_default(NS_NODE);
vtysh_install_default(VRF_NODE);
vtysh_install_default(RMAP_NODE);
vtysh_install_default(ZEBRA_NODE);
vtysh_install_default(BGP_VPNV4_NODE);
vtysh_install_default(BGP_VPNV6_NODE);
vtysh_install_default(BGP_IPV4_NODE);
vtysh_install_default(BGP_IPV4M_NODE);
vtysh_install_default(BGP_IPV4L_NODE);
vtysh_install_default(BGP_IPV6_NODE);
vtysh_install_default(BGP_IPV6M_NODE);
vtysh_install_default(BGP_EVPN_NODE);
vtysh_install_default(BGP_EVPN_VNI_NODE);
vtysh_install_default(BGP_IPV6L_NODE);
#if ENABLE_BGP_VNC
vtysh_install_default(BGP_VRF_POLICY_NODE);
vtysh_install_default(BGP_VNC_DEFAULTS_NODE);
vtysh_install_default(BGP_VNC_NVE_GROUP_NODE);
vtysh_install_default(BGP_VNC_L2_GROUP_NODE);
#endif
vtysh_install_default(OSPF_NODE);
vtysh_install_default(EIGRP_NODE);
vtysh_install_default(BABEL_NODE);
vtysh_install_default(RIPNG_NODE);
vtysh_install_default(OSPF6_NODE);
vtysh_install_default(LDP_NODE);
vtysh_install_default(LDP_IPV4_NODE);
vtysh_install_default(LDP_IPV6_NODE);
vtysh_install_default(LDP_IPV4_IFACE_NODE);
vtysh_install_default(LDP_IPV6_IFACE_NODE);
vtysh_install_default(LDP_L2VPN_NODE);
vtysh_install_default(LDP_PSEUDOWIRE_NODE);
vtysh_install_default(ISIS_NODE);
vtysh_install_default(KEYCHAIN_NODE);
vtysh_install_default(KEYCHAIN_KEY_NODE);
vtysh_install_default(VTY_NODE);
struct cmd_node *node;
for (unsigned int i = 0; i < vector_active(cmdvec); i++) {
node = vector_slot(cmdvec, i);
if (!node || node->node == VIEW_NODE)
continue;
vtysh_install_default(node->node);
}
install_element(VIEW_NODE, &vtysh_enable_cmd);
install_element(ENABLE_NODE, &vtysh_config_terminal_cmd);
@ -2945,8 +2979,10 @@ void vtysh_init_vty(void)
install_element(LDP_NODE, &vtysh_quit_ldpd_cmd);
install_element(LDP_IPV4_NODE, &vtysh_exit_ldpd_cmd);
install_element(LDP_IPV4_NODE, &vtysh_quit_ldpd_cmd);
install_element(LDP_IPV4_NODE, &ldp_exit_address_family_cmd);
install_element(LDP_IPV6_NODE, &vtysh_exit_ldpd_cmd);
install_element(LDP_IPV6_NODE, &vtysh_quit_ldpd_cmd);
install_element(LDP_IPV6_NODE, &ldp_exit_address_family_cmd);
install_element(LDP_IPV4_IFACE_NODE, &vtysh_exit_ldpd_cmd);
install_element(LDP_IPV4_IFACE_NODE, &vtysh_quit_ldpd_cmd);
install_element(LDP_IPV6_IFACE_NODE, &vtysh_exit_ldpd_cmd);

View File

@ -44,7 +44,7 @@ DECLARE_MGROUP(MVTYSH)
* run on it (logging & co. should stay in a fixed/frozen config, and
* things like prefix lists are not even initialised) */
#define VTYSH_ALL VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_LDPD|VTYSH_BGPD|VTYSH_ISISD|VTYSH_PIMD|VTYSH_NHRPD|VTYSH_EIGRPD|VTYSH_BABELD
#define VTYSH_RMAP VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_PIMD
#define VTYSH_RMAP VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_PIMD|VTYSH_EIGRPD
#define VTYSH_INTERFACE VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_ISISD|VTYSH_PIMD|VTYSH_NHRPD|VTYSH_EIGRPD|VTYSH_BABELD
#define VTYSH_NS VTYSH_ZEBRA
#define VTYSH_VRF VTYSH_ZEBRA|VTYSH_PIMD

3
zebra/.gitignore vendored
View File

@ -1,4 +1,4 @@
Makefile
!Makefile
Makefile.in
*.o
zebra
@ -13,3 +13,4 @@ TAGS
.arch-ids
*~
*.loT
zebra_vty_clippy.c

10
zebra/Makefile Normal file
View File

@ -0,0 +1,10 @@
all: ALWAYS
@$(MAKE) -s -C .. zebra/zebra
%: ALWAYS
@$(MAKE) -s -C .. zebra/$@
Makefile:
#nothing
ALWAYS:
.PHONY: ALWAYS makefiles
.SUFFIXES:

View File

@ -1,94 +0,0 @@
include ../common.am
## Process this file with automake to produce Makefile.in.
AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib
DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
INSTALL_SDATA=@INSTALL@ -m 600
LIBCAP = @LIBCAP@
ipforward = @IPFORWARD@
if_method = @IF_METHOD@
rt_method = @RT_METHOD@
rtread_method = @RTREAD_METHOD@
kernel_method = @KERNEL_METHOD@
ioctl_method = @IOCTL_METHOD@
mpls_method = @MPLS_METHOD@
otherobj = $(ioctl_method) $(ipforward) $(if_method) \
$(rt_method) $(rtread_method) $(kernel_method) $(mpls_method)
AM_CFLAGS = $(WERROR)
sbin_PROGRAMS = zebra
module_LTLIBRARIES =
zebra_SOURCES = \
zebra_memory.c \
zserv.c main.c interface.c connected.c zebra_rib.c zebra_routemap.c \
redistribute.c debug.c rtadv.c zebra_vty.c \
irdp_main.c irdp_interface.c irdp_packet.c router-id.c \
zebra_ptm.c zebra_rnh.c zebra_ptm_redistribute.c \
zebra_ns.c zebra_vrf.c zebra_static.c zebra_mpls.c zebra_mpls_vty.c \
zebra_mroute.c \
label_manager.c \
zebra_l2.c \
zebra_vxlan.c \
# end
noinst_HEADERS = \
zebra_memory.h \
connected.h ioctl.h rib.h rt.h zserv.h redistribute.h debug.h rtadv.h \
interface.h ipforward.h irdp.h router-id.h kernel_socket.h \
rt_netlink.h zebra_fpm_private.h zebra_rnh.h \
zebra_ptm_redistribute.h zebra_ptm.h zebra_routemap.h \
zebra_ns.h zebra_vrf.h ioctl_solaris.h zebra_static.h zebra_mpls.h \
kernel_netlink.h if_netlink.h zebra_mroute.h label_manager.h \
zebra_l2.h zebra_vxlan_private.h zebra_vxlan.h
zebra_LDADD = $(otherobj) ../lib/libfrr.la $(LIBCAP)
zebra_DEPENDENCIES = $(otherobj)
if SNMP
module_LTLIBRARIES += zebra_snmp.la
endif
zebra_snmp_la_SOURCES = zebra_snmp.c
zebra_snmp_la_CFLAGS = $(WERROR) $(SNMP_CFLAGS)
zebra_snmp_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
zebra_snmp_la_LIBADD = ../lib/libfrrsnmp.la
if FPM
module_LTLIBRARIES += zebra_fpm.la
endif
zebra_fpm_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
zebra_fpm_la_LIBADD = $(Q_FPM_PB_CLIENT_LDOPTS)
zebra_fpm_la_SOURCES = zebra_fpm.c
if HAVE_NETLINK
zebra_fpm_la_SOURCES += zebra_fpm_netlink.c
endif
if HAVE_PROTOBUF
zebra_fpm_la_SOURCES += zebra_fpm_protobuf.c
if DEV_BUILD
zebra_fpm_la_SOURCES += zebra_fpm_dt.c
endif
endif
EXTRA_DIST = if_ioctl.c if_ioctl_solaris.c if_netlink.c \
if_sysctl.c ipforward_proc.c \
ipforward_solaris.c ipforward_sysctl.c rt_netlink.c \
rt_socket.c rtread_netlink.c rtread_sysctl.c \
rtread_getmsg.c kernel_socket.c kernel_netlink.c \
ioctl.c ioctl_solaris.c \
zebra_mpls_netlink.c zebra_mpls_openbsd.c zebra_mpls_null.c \
GNOME-SMI GNOME-PRODUCT-ZEBRA-MIB
client : client_main.o ../lib/libfrr.la
$(CC) -g -o client client_main.o ../liblzebra.la $(LIBS) $(LIB_IPV6)
frrconfdir = $(sysconfdir)
examplesdir = $(exampledir)
dist_examples_DATA = zebra.conf.sample

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