mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-08 09:30:30 +00:00
Merge branch 'master' into PIM_VRF
This commit is contained in:
commit
0ecfe5bf38
450
COMMUNITY.md
450
COMMUNITY.md
@ -1,4 +1,7 @@
|
|||||||
# Developing for PROJECT (DRAFT)
|
Developing for FRRouting
|
||||||
|
=========================
|
||||||
|
|
||||||
|
## Table of Contents
|
||||||
|
|
||||||
[TOC]
|
[TOC]
|
||||||
|
|
||||||
@ -14,55 +17,57 @@ it's the document that needs to be updated, not reality.
|
|||||||
|
|
||||||
## Git Structure
|
## Git Structure
|
||||||
|
|
||||||
The master Git for PROJECT resides on Github at
|
The master Git for FRRouting resides on Github at
|
||||||
[https://github.com/PROJECT/XXX](https://github.com/PROJECT/XXX)
|
[https://github.com/frrouting/frr](https://github.com/FRRouting/frr)
|
||||||
|
|
||||||

|
"git branch mechanics")
|
||||||
|
|
||||||
There is one main branch for development and a release branch for each
|
There is one main branch for development and a release branch for each major
|
||||||
major release.
|
release.
|
||||||
|
|
||||||
New contributions are done against the head of the master branch. The CI
|
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
|
systems will pick up the Github Pull Requests or the new patch from Patchwork,
|
||||||
Patchwork, run some basic build and functional tests.
|
run some basic build and functional tests.
|
||||||
|
|
||||||
For each major release (1.0, 1.1 etc) a new release branch is created based
|
For each major release (1.0, 1.1 etc) a new release branch is created based on
|
||||||
on the master.
|
the master.
|
||||||
|
|
||||||
There was an attempt to use a "develop" branch automatically maintained by
|
There was an attempt to use a "develop" branch automatically maintained by the
|
||||||
the CI system. This is not currently in active use, though the system is
|
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
|
operational. If the "develop" branch is in active use and this paragraph is
|
||||||
is still here, this document obviously wasn't updated.
|
still here, this document obviously wasn't updated.
|
||||||
|
|
||||||
|
|
||||||
## Programming language, Tools and Libraries
|
## Programming language, Tools and Libraries
|
||||||
|
|
||||||
The core of PROJECT is written in C (gcc or clang supported). A few
|
The core of FRRouting is written in C (gcc or clang supported) and makes use of
|
||||||
non-essential scripts are implemented in Perl and Python. PROJECT requires
|
GNU compiler extensions. A few non-essential scripts are implemented in Perl
|
||||||
the following tools to build distribution packages: automake, autoconf,
|
and Python. FRRouting requires the following tools to build distribution
|
||||||
texinfo, libtool and gawk and various libraries (i.e. libpam and libjson-c).
|
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
|
If your contribution requires a new library or other tool, then please
|
||||||
highlight this in your description of the change. Also make sure it’s
|
highlight this in your description of the change. Also make sure it’s supported
|
||||||
supported by all PROJECT platform OSes or provide a way to build without the
|
by all FRRouting platform OSes or provide a way to build without the library
|
||||||
library (potentially without the new feature) on the other platforms.
|
(potentially without the new feature) on the other platforms.
|
||||||
|
|
||||||
Documentation should be written in Tex (.texi) or Markdown (.md) format with
|
Documentation should be written in Tex (.texi) or Markdown (.md) format with a
|
||||||
preference on Markdown.
|
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
|
### Changelog
|
||||||
|
|
||||||
@ -75,16 +80,45 @@ for the release notes.
|
|||||||
|
|
||||||
## Submitting Patches and Enhancements
|
## 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
|
### 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
|
released under the same license (preferred) or any license which allows
|
||||||
redistribution under this GPLv2 license (eg MIT License).
|
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.
|
Code submitted to FRRouting must be signed off. We have the same requirements
|
||||||
We follow the same standard as the Linux Kernel Development.
|
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
|
> 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
|
> maintained indefinitely and may be redistributed consistent with
|
||||||
> this project or the open source license(s) involved.
|
> this project or the open source license(s) involved.
|
||||||
|
|
||||||
#### Using this Process
|
### What do I submit my changes against?
|
||||||
|
|
||||||
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?
|
|
||||||
|
|
||||||
We've documented where we would like to have the different fixes applied at
|
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
|
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
|
If you are unsure where your submission goes, look at that document or ask a
|
||||||
the question of a maintainer.
|
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
|
The preferred method of submitting changes is a Github pull request. Code
|
||||||
Develop branch. Code submitted by Pull Request will have an email generated to
|
submitted by pull request will be automatically tested by one or more CI
|
||||||
the PROJECT-devel mailing list for review and the submission will be
|
systems. Once the automated tests succeed, other developers will review your
|
||||||
automatically tested by one or more CI systems. Only after this test succeeds
|
code for quality and correctness. After any concerns are resolved, your code
|
||||||
(and the submission is based on the head of the develop branch), then it will
|
will be merged into the branch it was submitted against.
|
||||||
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.
|
|
||||||
|
|
||||||
Further (manual) code review and discussion happens after the merge into the
|
### Patch submission via mailing list
|
||||||
develop branch.
|
|
||||||
|
|
||||||
|
As an alternative submission method, a patch can be mailed to the development
|
||||||
### Code submission - Mailing Patch to PROJECT-Devel list
|
mailing list. Patches received on the mailing list will be picked up by
|
||||||
|
Patchwork and tested against the latest development branch.
|
||||||
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
|
|
||||||
|
|
||||||
The recommended way to send the patch (or series of NN patches) to the list is
|
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:
|
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
|
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
|
following command to add it (after making sure you agree to the Developer
|
||||||
Developer Certificate of Origin as outlined above):
|
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
|
Submitting multi-commit patches as a Github pull request is **strongly
|
||||||
and will allow your changes to merge faster
|
encouraged** and increases the probability of your patch getting reviewed and
|
||||||
|
merged in a timely manner.
|
||||||
|
|
||||||
|
|
||||||
## After submitting your changes
|
## 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 don’t get the email, then check
|
less than 2 hrs of the submission. If you don’t get the email, then check
|
||||||
status on the github pull request (if submitted by pull request) or on
|
status on the github pull request (if submitted by pull request) or on
|
||||||
Patchwork at
|
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).
|
submitted as patch to mailing list).
|
||||||
* Please notify PROJECT-Devel mailing list if you think something doesn’t
|
* Please notify the development mailing list if you think something doesn’t
|
||||||
work
|
work.
|
||||||
* If the tests failed:
|
* If the tests failed:
|
||||||
* In general, expect the community to ignore the submission until the tests
|
* In general, expect the community to ignore the submission until the tests
|
||||||
pass.
|
pass.
|
||||||
* It is up to you to fix and resubmit.
|
* 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.
|
changes broke or changed them.
|
||||||
* It also includes fixing distribution packages for the failing
|
* It also includes fixing distribution packages for the failing
|
||||||
platforms (ie if new libraries are required)
|
platforms (ie if new libraries are required).
|
||||||
* Feel free to ask for help on PROJECT-Devel list
|
* Feel free to ask for help on the development list.
|
||||||
* Go back to the submission process and repeat until the tests pass.
|
* Go back to the submission process and repeat until the tests pass.
|
||||||
* If the tests pass:
|
* If the tests pass:
|
||||||
* If the changes are done as a pull request, then they should be
|
* Wait for reviewers. Someone will review your code or be assigned to
|
||||||
automatically merged to the develop branch.
|
review your code.
|
||||||
* Changes sent to mailing list require a manual ACK to be merged and should
|
* Respond to any comments or concerns the reviewer has.
|
||||||
be merged within 2 weeks. If you don’t see the merge or any
|
* After all comments and concerns are addressed, expect your patch to be
|
||||||
reason/discussion on PROJECT-Devel, then please ask.
|
merged.
|
||||||
* Watch out for questions on the mailing list. At this time there will be a
|
* 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.
|
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
|
* Your submission is done once it is merged to the master branch.
|
||||||
happen every few weeks from the develop 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
|
New files need to have a Copyright header (see [License for
|
||||||
contributions](#license-for-contributions) above) added to the file. Preferred
|
contributions](#license-for-contributions) above) added to the file. Preferred
|
||||||
@ -251,7 +251,7 @@ form of the header is as follows:
|
|||||||
#include <zebra.h>
|
#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
|
When adding copyright claims for modifications to an existing file, please
|
||||||
preface the claim with "Portions: " on a line before it and indent the
|
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]
|
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
|
FRR uses Linux kernel style except where noted below. Code which does not
|
||||||
code uses GNU coding standards. New code may use Linux kernel coding style.
|
comply with these style guidelines will not be accepted.
|
||||||
|
|
||||||
GNU coding style apply to the following parts:
|
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
|
||||||
* lib/
|
project. In the `tools/` directory there is a Python script named `indent.py`
|
||||||
* zebra/
|
that wraps clang-format and handles some edge cases specific to FRR. If you are
|
||||||
* bgpd/
|
submitting a new file, it is recommended to run that script over the new file
|
||||||
* ospfd/
|
after ensuring that the latest stable release of `clang-format` is in your
|
||||||
* ospf6d/
|
PATH.
|
||||||
* 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/
|
|
||||||
|
|
||||||
**Whitespace changes in untouched parts of the code are not acceptable in
|
**Whitespace changes in untouched parts of the code are not acceptable in
|
||||||
patches that change actual code.** To change/fix formatting issues, please
|
patches that change actual code.** To change/fix formatting issues, please
|
||||||
create a separate patch that only does formatting changes and nothing else.
|
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
|
#### Style documentation
|
||||||
**MUST** come as a separate patch that does nothing other than this
|
Kernel and BSD styles are documented externally:
|
||||||
reformatting.
|
|
||||||
|
|
||||||
|
* [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, use `indent` with the following invocation:
|
||||||
|
|
||||||
For GNU coding style, Indentation follows the result of invoking GNU indent:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
indent -nut -nfc1 file_for_submission.c
|
indent -nut -nfc1 file_for_submission.c
|
||||||
```
|
```
|
||||||
|
|
||||||
Originally, tabs were used instead of spaces, with tabs are every 8 columns.
|
#### Exceptions
|
||||||
However, tab interoperability issues mean space characters are now preferred for
|
|
||||||
new changes. We generally only clean up whitespace when code is unmaintainable
|
FRR project code comes from a variety of sources, so there are some stylistic
|
||||||
due to whitespace issues, to minimise merging conflicts.
|
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).
|
* `lib/`
|
||||||
* [http://man.openbsd.org/style](http://man.openbsd.org/style)
|
* `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
|
* `ldpd/`
|
||||||
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.
|
|
||||||
|
|
||||||
|
|
||||||
### Compile-Time conditional code
|
### Documentation
|
||||||
|
|
||||||
Many users access PROJECT via binary packages from 3rd party sources;
|
FRRouting is a large and complex software project developed by many different
|
||||||
compile-time code puts inclusion/exclusion in the hands of the package
|
people over a long period of time. Without adequate documentation, it can be
|
||||||
maintainer. Please think very carefully before making code conditional at
|
exceedingly difficult to understand code segments, APIs and other interfaces.
|
||||||
compile time, as it increases regression testing, maintenance burdens, and user
|
In the interest of keeping the project healthy and maintainable, you should
|
||||||
confusion. In particular, please avoid gratuitous --enable-… switches to the
|
make every effort to document your code so that other people can understand
|
||||||
configure script - typically code should be good enough to be in PROJECT, or it
|
what it does without needing to closely read the code itself.
|
||||||
shouldn’t be there at all.
|
|
||||||
|
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 shouldn’t be in FRR at all.
|
||||||
|
|
||||||
When code must be compile-time conditional, try have the compiler make it
|
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
|
conditional rather than the C pre-processor so that it will still be checked by
|
||||||
by the compiler, even if disabled. I.e. this:
|
the compiler, even if disabled. For example,
|
||||||
|
|
||||||
```
|
```
|
||||||
if (SOME_SYMBOL)
|
if (SOME_SYMBOL)
|
||||||
frobnicate();
|
frobnicate();
|
||||||
```
|
```
|
||||||
|
|
||||||
rather than
|
is preferred to
|
||||||
|
|
||||||
```
|
```
|
||||||
#ifdef SOME_SYMBOL
|
#ifdef SOME_SYMBOL
|
||||||
@ -363,53 +415,55 @@ frobnicate ();
|
|||||||
Note that the former approach requires ensuring that `SOME_SYMBOL` will be
|
Note that the former approach requires ensuring that `SOME_SYMBOL` will be
|
||||||
defined (watch your `AC_DEFINE`s).
|
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
|
Debugging statements are an important methodology to allow developers to fix
|
||||||
found in the code after it has been released. The caveat here is
|
issues found in the code after it has been released. The caveat here is that
|
||||||
that the developer must remember that people will be using the code
|
the developer must remember that people will be using the code at scale and in
|
||||||
at scale and in ways that can be unexpected for the original implementor.
|
ways that can be unexpected for the original implementor. As such debugs
|
||||||
As such debugs MUST be guarded in such a way that they can be turned off.
|
**MUST** be guarded in such a way that they can be turned off. FRR has the
|
||||||
This PROJECT has the ability to turn on/off debugs from the CLI and it is
|
ability to turn on/off debugs from the CLI and it is expected that the
|
||||||
expected that the developer will use this convention to allow control
|
developer will use this convention to allow control of their debugs.
|
||||||
of their debugs.
|
|
||||||
|
|
||||||
### CLI-Changes
|
### CLI changes
|
||||||
|
|
||||||
CLI's are a complicated ugly beast. Additions or changes to the CLI
|
CLI's are a complicated ugly beast. Additions or changes to the CLI should use
|
||||||
should use a DEFUN to encapsulate one setting as much as is possible.
|
a DEFUN to encapsulate one setting as much as is possible. Additionally as new
|
||||||
Additionally as new DEFUN's are added to the system, documentation
|
DEFUN's are added to the system, documentation should be provided for the new
|
||||||
should be provided for the new commands.
|
commands.
|
||||||
|
|
||||||
### Backwards Compatibility
|
### Backwards Compatibility
|
||||||
|
|
||||||
As a general principle, changes to CLI and code in the lib/ directory
|
As a general principle, changes to CLI and code in the lib/ directory should be
|
||||||
should be made in a backwards compatible fashion. This means that
|
made in a backwards compatible fashion. This means that changes that are purely
|
||||||
changes that are purely stylistic in nature should be avoided, e.g.,
|
stylistic in nature should be avoided, e.g., renaming an existing macro or
|
||||||
renaming an existing macro or library function name without any
|
library function name without any functional change. When adding new parameters
|
||||||
functional change. When adding new parameters to common functions, it is
|
to common functions, it is also good to consider if this too should be done in
|
||||||
also good to consider if this too should be done in a backward
|
a backward compatible fashion, e.g., by preserving the old form in addition to
|
||||||
compatible fashion, e.g., by preserving the old form in addition to
|
|
||||||
adding the new form.
|
adding the new form.
|
||||||
|
|
||||||
This is not to say that minor or even major functional changes to CLI
|
This is not to say that minor or even major functional changes to CLI and
|
||||||
and common code should be avoided, but rather that the benefit gained
|
common code should be avoided, but rather that the benefit gained from a change
|
||||||
from a change should be weighed against the added cost/complexity to
|
should be weighed against the added cost/complexity to existing code. Also,
|
||||||
existing code. Also, that when making such changes, it is good to
|
that when making such changes, it is good to preserve compatibility when
|
||||||
preserve compatibility when possible to do so without introducing
|
possible to do so without introducing maintenance overhead/cost. It is also
|
||||||
maintenance overhead/cost. It is also important to keep in mind,
|
important to keep in mind, existing code includes code that may reside in
|
||||||
existing code includes code that may reside in private repositories (and
|
private repositories (and is yet to be submitted) or code that has yet to be
|
||||||
is yet to be submitted) or code that has yet to be migrated from Quagga
|
migrated from Quagga to FRR.
|
||||||
to FRR.
|
|
||||||
|
|
||||||
That said, compatibility measures can (and should) be removed when either:
|
That said, compatibility measures can (and should) be removed when either:
|
||||||
|
|
||||||
* they become a significant burden, e.g. when data structures change and
|
* they become a significant burden, e.g. when data structures change and the
|
||||||
the compatibility measure would need a complex adaptation layer or becomes
|
compatibility measure would need a complex adaptation layer or becomes
|
||||||
flat-out impossible
|
flat-out impossible
|
||||||
* some measure of time (dependent on the specific case) has passed, so that
|
* some measure of time (dependent on the specific case) has passed, so that the
|
||||||
the compatibility grace period is considered expired.
|
compatibility grace period is considered expired.
|
||||||
|
|
||||||
In all cases, compatibility pieces should be marked with compiler/preprocessor
|
In all cases, compatibility pieces should be marked with compiler/preprocessor
|
||||||
annotations to print warnings at compile time, pointing to the appropriate
|
annotations to print warnings at compile time, pointing to the appropriate
|
||||||
update path. A `-Werror` build should fail if compatibility bits are used.
|
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.
|
||||||
|
94
Makefile.am
94
Makefile.am
@ -1,23 +1,95 @@
|
|||||||
## Process this file with automake to produce Makefile.in.
|
## 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@ \
|
@BGPD@ @RIPD@ @RIPNGD@ @OSPFD@ @OSPF6D@ @LDPD@ \
|
||||||
@ISISD@ @PIMD@ @NHRPD@ @EIGRPD@ @BABELD@ \
|
@ISISD@ @PIMD@ @NHRPD@ @EIGRPD@ @BABELD@ \
|
||||||
@WATCHFRR@ @VTYSH@ @OSPFCLIENT@ @DOC@ m4 @pkgsrcdir@ \
|
@WATCHFRR@ @VTYSH@ @OSPFCLIENT@ @DOC@ \
|
||||||
redhat @SOLARIS@ tests tools snapcraft
|
@SOLARIS@ tests tools
|
||||||
|
|
||||||
DIST_SUBDIRS = lib qpb fpm zebra bgpd ripd ripngd ospfd ospf6d ldpd \
|
DIST_SUBDIRS = . bgpd ripd ripngd ospfd ospf6d ldpd \
|
||||||
isisd watchfrr vtysh ospfclient doc m4 pkgsrc redhat tests \
|
isisd watchfrr vtysh ospfclient doc tests \
|
||||||
solaris pimd nhrpd eigrpd bgpd/rfp-example/librfp \
|
solaris pimd nhrpd eigrpd bgpd/rfp-example/librfp \
|
||||||
bgpd/rfp-example/rfptest tools snapcraft babeld python \
|
bgpd/rfp-example/rfptest tools babeld \
|
||||||
# end
|
# 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 \
|
update-autotools \
|
||||||
vtysh/Makefile.in vtysh/Makefile.am \
|
m4/README.txt \
|
||||||
tools/rrcheck.pl tools/rrlookup.pl tools/zc.pl \
|
\
|
||||||
tools/zebra.el tools/multiple-bgpd.sh
|
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
|
ACLOCAL_AMFLAGS = -I m4
|
||||||
|
|
||||||
noinst_HEADERS = defaults.h
|
noinst_HEADERS += defaults.h
|
||||||
|
@ -207,8 +207,6 @@ main(int argc, char **argv)
|
|||||||
|
|
||||||
schedule_neighbours_check(5000, 1);
|
schedule_neighbours_check(5000, 1);
|
||||||
|
|
||||||
zlog_notice ("BABELd %s starting: vty@%d", BABEL_VERSION, babel_vty_port);
|
|
||||||
|
|
||||||
frr_config_fork();
|
frr_config_fork();
|
||||||
frr_run(master);
|
frr_run(master);
|
||||||
|
|
||||||
|
@ -55,25 +55,6 @@ static struct {
|
|||||||
{0, 0, NULL}
|
{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. */
|
/* Zebra node structure. */
|
||||||
struct cmd_node zebra_node =
|
struct cmd_node zebra_node =
|
||||||
{
|
{
|
||||||
@ -191,66 +172,46 @@ babel_zebra_read_ipv4 (int command, struct zclient *zclient,
|
|||||||
return 0;
|
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] */
|
/* [Babel Command] */
|
||||||
DEFUN (babel_redistribute_type,
|
DEFUN (babel_redistribute_type,
|
||||||
babel_redistribute_type_cmd,
|
babel_redistribute_type_cmd,
|
||||||
"redistribute " FRR_REDIST_STR_BABELD,
|
"[no] redistribute <ipv4 " FRR_IP_REDIST_STR_BABELD "|ipv6 " FRR_IP6_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_STR
|
NO_STR
|
||||||
"Redistribute\n"
|
"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 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) {
|
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;
|
return CMD_WARNING_CONFIG_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE, zclient, AFI_IP, type, 0, VRF_DEFAULT);
|
if (!negate)
|
||||||
zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE, zclient, AFI_IP6, type, 0, VRF_DEFAULT);
|
zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, afi, type, 0, VRF_DEFAULT);
|
||||||
/* perhaps should we remove xroutes having the same type... */
|
else {
|
||||||
|
zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE, zclient, afi, type, 0, VRF_DEFAULT);
|
||||||
|
/* perhaps should we remove xroutes having the same type... */
|
||||||
|
}
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -374,7 +335,6 @@ void babelz_zebra_init(void)
|
|||||||
|
|
||||||
install_node (&zebra_node, zebra_config_write);
|
install_node (&zebra_node, zebra_config_write);
|
||||||
install_element(BABEL_NODE, &babel_redistribute_type_cmd);
|
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, &debug_babel_cmd);
|
||||||
install_element(ENABLE_NODE, &no_debug_babel_cmd);
|
install_element(ENABLE_NODE, &no_debug_babel_cmd);
|
||||||
install_element(CONFIG_NODE, &debug_babel_cmd);
|
install_element(CONFIG_NODE, &debug_babel_cmd);
|
||||||
|
@ -76,6 +76,7 @@ static int
|
|||||||
babel_config_write (struct vty *vty)
|
babel_config_write (struct vty *vty)
|
||||||
{
|
{
|
||||||
int lines = 0;
|
int lines = 0;
|
||||||
|
int afi;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* list enabled debug modes */
|
/* list enabled debug modes */
|
||||||
@ -108,13 +109,17 @@ babel_config_write (struct vty *vty)
|
|||||||
/* list enabled interfaces */
|
/* list enabled interfaces */
|
||||||
lines = 1 + babel_enable_if_config_write (vty);
|
lines = 1 + babel_enable_if_config_write (vty);
|
||||||
/* list redistributed protocols */
|
/* list redistributed protocols */
|
||||||
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
|
for (afi = AFI_IP; afi <= AFI_IP6; afi++) {
|
||||||
if (i != zclient->redist_default &&
|
for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
|
||||||
vrf_bitmap_check (zclient->redist[AFI_IP][i], VRF_DEFAULT))
|
if (i != zclient->redist_default &&
|
||||||
{
|
vrf_bitmap_check (zclient->redist[afi][i], VRF_DEFAULT)) {
|
||||||
vty_out (vty, " redistribute %s\n", zebra_route_string(i));
|
vty_out (vty, " redistribute %s %s\n",
|
||||||
lines++;
|
(afi == AFI_IP) ? "ipv4" : "ipv6",
|
||||||
|
zebra_route_string(i));
|
||||||
|
lines++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
lines += config_write_distribute (vty);
|
lines += config_write_distribute (vty);
|
||||||
|
|
||||||
|
@ -9,8 +9,8 @@ debug babel common
|
|||||||
router babel
|
router babel
|
||||||
! network wlan0
|
! network wlan0
|
||||||
! network eth0
|
! network eth0
|
||||||
! redistribute kernel
|
! redistribute ipv4 kernel
|
||||||
! no redistribute static
|
! no redistribute ipv6 static
|
||||||
|
|
||||||
! The defaults are fine for a wireless interface
|
! The defaults are fine for a wireless interface
|
||||||
|
|
||||||
|
@ -90,7 +90,6 @@ THE SOFTWARE.
|
|||||||
|
|
||||||
#define BABEL_VTY_PORT 2609
|
#define BABEL_VTY_PORT 2609
|
||||||
#define BABEL_DEFAULT_CONFIG "babeld.conf"
|
#define BABEL_DEFAULT_CONFIG "babeld.conf"
|
||||||
#define BABEL_VERSION "0.1 for quagga"
|
|
||||||
|
|
||||||
/* Values in milliseconds */
|
/* Values in milliseconds */
|
||||||
#define BABEL_DEFAULT_HELLO_INTERVAL 4000
|
#define BABEL_DEFAULT_HELLO_INTERVAL 4000
|
||||||
|
@ -1677,7 +1677,8 @@ int bgp_mp_reach_parse(struct bgp_attr_parser_args *args,
|
|||||||
{
|
{
|
||||||
iana_afi_t pkt_afi;
|
iana_afi_t pkt_afi;
|
||||||
afi_t afi;
|
afi_t afi;
|
||||||
safi_t pkt_safi, safi;
|
iana_safi_t pkt_safi;
|
||||||
|
safi_t safi;
|
||||||
bgp_size_t nlri_len;
|
bgp_size_t nlri_len;
|
||||||
size_t start;
|
size_t start;
|
||||||
struct stream *s;
|
struct stream *s;
|
||||||
@ -1826,7 +1827,8 @@ int bgp_mp_unreach_parse(struct bgp_attr_parser_args *args,
|
|||||||
struct stream *s;
|
struct stream *s;
|
||||||
iana_afi_t pkt_afi;
|
iana_afi_t pkt_afi;
|
||||||
afi_t afi;
|
afi_t afi;
|
||||||
safi_t pkt_safi, safi;
|
iana_safi_t pkt_safi;
|
||||||
|
safi_t safi;
|
||||||
u_int16_t withdraw_len;
|
u_int16_t withdraw_len;
|
||||||
struct peer *const peer = args->peer;
|
struct peer *const peer = args->peer;
|
||||||
struct attr *const attr = args->attr;
|
struct attr *const attr = args->attr;
|
||||||
@ -2039,7 +2041,7 @@ static int bgp_attr_encap(uint8_t type, struct peer *peer, /* IN */
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
stlv_last->next = tlv;
|
stlv_last = tlv;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BGP_ATTR_ENCAP == type) {
|
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;
|
size_t sizep;
|
||||||
iana_afi_t pkt_afi;
|
iana_afi_t pkt_afi;
|
||||||
safi_t pkt_safi;
|
iana_safi_t pkt_safi;
|
||||||
afi_t nh_afi;
|
afi_t nh_afi;
|
||||||
|
|
||||||
/* Set extended bit always to encode the attribute length as 2 bytes */
|
/* 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;
|
unsigned long attrlen_pnt;
|
||||||
iana_afi_t pkt_afi;
|
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 */
|
/* Set extended bit always to encode the attribute length as 2 bytes */
|
||||||
stream_putc(s, BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_EXTLEN);
|
stream_putc(s, BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_EXTLEN);
|
||||||
|
@ -347,6 +347,8 @@ static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd,
|
|||||||
if (bgp == NULL) {
|
if (bgp == NULL) {
|
||||||
if (!use_json)
|
if (!use_json)
|
||||||
vty_out(vty, "No BGP process is configured\n");
|
vty_out(vty, "No BGP process is configured\n");
|
||||||
|
else
|
||||||
|
vty_out(vty, "{}\n");
|
||||||
return CMD_WARNING;
|
return CMD_WARNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -488,7 +488,7 @@ static int bgp_graceful_restart_timer_expire(struct thread *thread)
|
|||||||
|
|
||||||
/* NSF delete stale route */
|
/* NSF delete stale route */
|
||||||
for (afi = AFI_IP; afi < AFI_MAX; afi++)
|
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])
|
if (peer->nsf[afi][safi])
|
||||||
bgp_clear_stale_route(peer, 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 */
|
/* NSF delete stale route */
|
||||||
for (afi = AFI_IP; afi < AFI_MAX; afi++)
|
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])
|
if (peer->nsf[afi][safi])
|
||||||
bgp_clear_stale_route(peer, 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 (afi = AFI_IP; afi < AFI_MAX; afi++)
|
||||||
for (safi = SAFI_UNICAST;
|
for (safi = SAFI_UNICAST;
|
||||||
safi < SAFI_RESERVED_4; safi++)
|
safi <= SAFI_MPLS_VPN; safi++)
|
||||||
peer->nsf[afi][safi] = 0;
|
peer->nsf[afi][safi] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1425,7 +1425,7 @@ static int bgp_establish(struct peer *peer)
|
|||||||
/* graceful restart */
|
/* graceful restart */
|
||||||
UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT);
|
UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT);
|
||||||
for (afi = AFI_IP; afi < AFI_MAX; afi++)
|
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]
|
if (peer->afc_nego[afi][safi]
|
||||||
&& CHECK_FLAG(peer->cap, PEER_CAP_RESTART_ADV)
|
&& CHECK_FLAG(peer->cap, PEER_CAP_RESTART_ADV)
|
||||||
&& CHECK_FLAG(peer->af_cap[afi][safi],
|
&& CHECK_FLAG(peer->af_cap[afi][safi],
|
||||||
|
@ -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 bgp_info_nexthop_cmp(struct bgp_info *bi1, struct bgp_info *bi2)
|
||||||
{
|
{
|
||||||
int compare;
|
int compare;
|
||||||
|
struct in6_addr addr1, addr2;
|
||||||
|
|
||||||
compare = IPV4_ADDR_CMP(&bi1->attr->nexthop, &bi2->attr->nexthop);
|
compare = IPV4_ADDR_CMP(&bi1->attr->nexthop, &bi2->attr->nexthop);
|
||||||
if (!compare) {
|
if (!compare) {
|
||||||
@ -120,13 +121,18 @@ int bgp_info_nexthop_cmp(struct bgp_info *bi1, struct bgp_info *bi2)
|
|||||||
&bi2->attr->mp_nexthop_global);
|
&bi2->attr->mp_nexthop_global);
|
||||||
break;
|
break;
|
||||||
case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
|
case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
|
||||||
compare = IPV6_ADDR_CMP(
|
addr1 = (bi1->attr->mp_nexthop_prefer_global) ?
|
||||||
&bi1->attr->mp_nexthop_global,
|
bi1->attr->mp_nexthop_global
|
||||||
&bi2->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)
|
if (!compare)
|
||||||
compare = IPV6_ADDR_CMP(
|
compare = IPV6_ADDR_CMP(&addr1, &addr2);
|
||||||
&bi1->attr->mp_nexthop_local,
|
|
||||||
&bi2->attr->mp_nexthop_local);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -374,6 +374,8 @@ int bgp_show_mpls_vpn(struct vty *vty, afi_t afi, struct prefix_rd *prd,
|
|||||||
if (bgp == NULL) {
|
if (bgp == NULL) {
|
||||||
if (!use_json)
|
if (!use_json)
|
||||||
vty_out(vty, "No BGP process is configured\n");
|
vty_out(vty, "No BGP process is configured\n");
|
||||||
|
else
|
||||||
|
vty_out(vty, "{}\n");
|
||||||
return CMD_WARNING;
|
return CMD_WARNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,7 +298,8 @@ static int bgp_capability_orf_entry(struct peer *peer,
|
|||||||
u_char num;
|
u_char num;
|
||||||
iana_afi_t pkt_afi;
|
iana_afi_t pkt_afi;
|
||||||
afi_t afi;
|
afi_t afi;
|
||||||
safi_t pkt_safi, safi;
|
iana_safi_t pkt_safi;
|
||||||
|
safi_t safi;
|
||||||
u_char type;
|
u_char type;
|
||||||
u_char mode;
|
u_char mode;
|
||||||
u_int16_t sm_cap = 0; /* capability send-mode receive */
|
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;
|
afi_t afi;
|
||||||
safi_t safi;
|
safi_t safi;
|
||||||
iana_afi_t pkt_afi = stream_getw(s);
|
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);
|
u_char flag = stream_getc(s);
|
||||||
|
|
||||||
/* Convert AFI, SAFI to internal values, check. */
|
/* Convert AFI, SAFI to internal values, check. */
|
||||||
@ -543,7 +544,7 @@ static int bgp_capability_addpath(struct peer *peer,
|
|||||||
afi_t afi;
|
afi_t afi;
|
||||||
safi_t safi;
|
safi_t safi;
|
||||||
iana_afi_t pkt_afi = stream_getw(s);
|
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);
|
u_char send_receive = stream_getc(s);
|
||||||
|
|
||||||
if (bgp_debug_neighbor_events(peer))
|
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) {
|
while (stream_get_getp(s) + 6 <= end) {
|
||||||
iana_afi_t pkt_afi = stream_getw(s);
|
iana_afi_t pkt_afi = stream_getw(s);
|
||||||
afi_t afi;
|
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);
|
iana_afi_t pkt_nh_afi = stream_getw(s);
|
||||||
afi_t nh_afi;
|
afi_t nh_afi;
|
||||||
|
|
||||||
@ -1199,7 +1201,7 @@ static void bgp_open_capability_orf(struct stream *s, struct peer *peer,
|
|||||||
unsigned long numberp;
|
unsigned long numberp;
|
||||||
int number_of_orfs = 0;
|
int number_of_orfs = 0;
|
||||||
iana_afi_t pkt_afi;
|
iana_afi_t pkt_afi;
|
||||||
safi_t pkt_safi;
|
iana_safi_t pkt_safi;
|
||||||
|
|
||||||
/* Convert AFI, SAFI to values for packet. */
|
/* Convert AFI, SAFI to values for packet. */
|
||||||
bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi, &pkt_safi);
|
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;
|
unsigned long cp, capp, rcapp;
|
||||||
iana_afi_t pkt_afi;
|
iana_afi_t pkt_afi;
|
||||||
afi_t afi;
|
afi_t afi;
|
||||||
safi_t safi, pkt_safi;
|
safi_t safi;
|
||||||
|
iana_safi_t pkt_safi;
|
||||||
as_t local_as;
|
as_t local_as;
|
||||||
u_int32_t restart_time;
|
u_int32_t restart_time;
|
||||||
u_char afi_safi_count = 0;
|
u_char afi_safi_count = 0;
|
||||||
|
@ -29,9 +29,9 @@ struct capability_header {
|
|||||||
|
|
||||||
/* Generic MP capability data */
|
/* Generic MP capability data */
|
||||||
struct capability_mp_data {
|
struct capability_mp_data {
|
||||||
iana_afi_t afi;
|
uint16_t afi; /* iana_afi_t */
|
||||||
u_char reserved;
|
u_char reserved;
|
||||||
safi_t safi;
|
uint8_t safi; /* iana_safi_t */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct capability_as4 {
|
struct capability_as4 {
|
||||||
|
@ -142,7 +142,7 @@ static struct stream *bgp_update_packet_eor(struct peer *peer, afi_t afi,
|
|||||||
{
|
{
|
||||||
struct stream *s;
|
struct stream *s;
|
||||||
iana_afi_t pkt_afi;
|
iana_afi_t pkt_afi;
|
||||||
safi_t pkt_safi;
|
iana_safi_t pkt_safi;
|
||||||
|
|
||||||
if (DISABLE_BGP_ANNOUNCE)
|
if (DISABLE_BGP_ANNOUNCE)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -671,7 +671,7 @@ void bgp_route_refresh_send(struct peer *peer, afi_t afi, safi_t safi,
|
|||||||
struct bgp_filter *filter;
|
struct bgp_filter *filter;
|
||||||
int orf_refresh = 0;
|
int orf_refresh = 0;
|
||||||
iana_afi_t pkt_afi;
|
iana_afi_t pkt_afi;
|
||||||
safi_t pkt_safi;
|
iana_safi_t pkt_safi;
|
||||||
|
|
||||||
if (DISABLE_BGP_ANNOUNCE)
|
if (DISABLE_BGP_ANNOUNCE)
|
||||||
return;
|
return;
|
||||||
@ -761,7 +761,7 @@ void bgp_capability_send(struct peer *peer, afi_t afi, safi_t safi,
|
|||||||
{
|
{
|
||||||
struct stream *s;
|
struct stream *s;
|
||||||
iana_afi_t pkt_afi;
|
iana_afi_t pkt_afi;
|
||||||
safi_t pkt_safi;
|
iana_safi_t pkt_safi;
|
||||||
|
|
||||||
/* Convert AFI, SAFI to values for packet. */
|
/* Convert AFI, SAFI to values for packet. */
|
||||||
bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi, &pkt_safi);
|
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);
|
packet);
|
||||||
case SAFI_EVPN:
|
case SAFI_EVPN:
|
||||||
return bgp_nlri_parse_evpn(peer, attr, packet, mp_withdraw);
|
return bgp_nlri_parse_evpn(peer, attr, packet, mp_withdraw);
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse BGP Update packet and make attribute object. */
|
/* 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;
|
iana_afi_t pkt_afi;
|
||||||
afi_t afi;
|
afi_t afi;
|
||||||
safi_t pkt_safi, safi;
|
iana_safi_t pkt_safi;
|
||||||
|
safi_t safi;
|
||||||
struct stream *s;
|
struct stream *s;
|
||||||
struct peer_af *paf;
|
struct peer_af *paf;
|
||||||
struct update_group *updgrp;
|
struct update_group *updgrp;
|
||||||
@ -1965,7 +1967,8 @@ static int bgp_capability_msg_parse(struct peer *peer, u_char *pnt,
|
|||||||
u_char action;
|
u_char action;
|
||||||
iana_afi_t pkt_afi;
|
iana_afi_t pkt_afi;
|
||||||
afi_t afi;
|
afi_t afi;
|
||||||
safi_t pkt_safi, safi;
|
iana_safi_t pkt_safi;
|
||||||
|
safi_t safi;
|
||||||
|
|
||||||
end = pnt + length;
|
end = pnt + length;
|
||||||
|
|
||||||
|
@ -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_add_route(bgp, p, old_select);
|
||||||
vnc_import_bgp_exterior_add_route(bgp, p, old_select);
|
vnc_import_bgp_exterior_add_route(bgp, p, old_select);
|
||||||
#endif
|
#endif
|
||||||
if (bgp_fibupd_safi(safi) && !bgp->name
|
if (bgp_fibupd_safi(safi)
|
||||||
&& !bgp_option_check(BGP_OPT_NO_FIB)
|
&& !bgp_option_check(BGP_OPT_NO_FIB)
|
||||||
&& new_select->type == ZEBRA_ROUTE_BGP
|
&& new_select->type == ZEBRA_ROUTE_BGP
|
||||||
&& new_select->sub_type == BGP_ROUTE_NORMAL)
|
&& 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)
|
int always)
|
||||||
{
|
{
|
||||||
iana_afi_t pkt_afi;
|
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))
|
if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
|
||||||
return 0;
|
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 (bgp == NULL) {
|
||||||
if (!use_json)
|
if (!use_json)
|
||||||
vty_out(vty, "No BGP process is configured\n");
|
vty_out(vty, "No BGP process is configured\n");
|
||||||
|
else
|
||||||
|
vty_out(vty, "{}\n");
|
||||||
return CMD_WARNING;
|
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,
|
int prefix_check, enum bgp_path_type pathtype,
|
||||||
u_char use_json)
|
u_char use_json)
|
||||||
{
|
{
|
||||||
if (!bgp)
|
if (!bgp) {
|
||||||
bgp = bgp_get_default();
|
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 */
|
/* labeled-unicast routes live in the unicast table */
|
||||||
if (safi == SAFI_LABELED_UNICAST)
|
if (safi == SAFI_LABELED_UNICAST)
|
||||||
|
@ -700,6 +700,7 @@ struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp)
|
|||||||
int send_attr_printed = 0;
|
int send_attr_printed = 0;
|
||||||
int num_pfx = 0;
|
int num_pfx = 0;
|
||||||
int addpath_encode = 0;
|
int addpath_encode = 0;
|
||||||
|
int addpath_overhead = 0;
|
||||||
u_int32_t addpath_tx_id = 0;
|
u_int32_t addpath_tx_id = 0;
|
||||||
struct prefix_rd *prd = NULL;
|
struct prefix_rd *prd = NULL;
|
||||||
mpls_label_t label = MPLS_INVALID_LABEL;
|
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);
|
bpacket_attr_vec_arr_reset(&vecarr);
|
||||||
|
|
||||||
addpath_encode = bgp_addpath_encode_tx(peer, afi, safi);
|
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);
|
adv = BGP_ADV_FIFO_HEAD(&subgrp->sync->update);
|
||||||
while (adv) {
|
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))
|
space_remaining = STREAM_CONCAT_REMAIN(s, snlri, STREAM_SIZE(s))
|
||||||
- BGP_MAX_PACKET_SIZE_OVERFLOW;
|
- BGP_MAX_PACKET_SIZE_OVERFLOW;
|
||||||
space_needed = BGP_NLRI_LENGTH + bgp_packet_mpattr_prefix_size(
|
space_needed = BGP_NLRI_LENGTH + addpath_overhead +
|
||||||
afi, safi, &rn->p);
|
bgp_packet_mpattr_prefix_size(afi, safi, &rn->p);
|
||||||
|
|
||||||
/* When remaining space can't include NLRI and it's length. */
|
/* When remaining space can't include NLRI and it's length. */
|
||||||
if (space_remaining < space_needed)
|
if (space_remaining < space_needed)
|
||||||
@ -777,9 +779,9 @@ struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp)
|
|||||||
space_remaining =
|
space_remaining =
|
||||||
STREAM_CONCAT_REMAIN(s, snlri, STREAM_SIZE(s))
|
STREAM_CONCAT_REMAIN(s, snlri, STREAM_SIZE(s))
|
||||||
- BGP_MAX_PACKET_SIZE_OVERFLOW;
|
- BGP_MAX_PACKET_SIZE_OVERFLOW;
|
||||||
space_needed =
|
space_needed = BGP_NLRI_LENGTH + addpath_overhead +
|
||||||
BGP_NLRI_LENGTH + bgp_packet_mpattr_prefix_size(
|
bgp_packet_mpattr_prefix_size(afi, safi,
|
||||||
afi, safi, &rn->p);
|
&rn->p);
|
||||||
|
|
||||||
/* If the attributes alone do not leave any room for
|
/* If the attributes alone do not leave any room for
|
||||||
* NLRI then
|
* NLRI then
|
||||||
@ -843,7 +845,7 @@ struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp)
|
|||||||
send_attr_str);
|
send_attr_str);
|
||||||
if (!stream_empty(snlri)) {
|
if (!stream_empty(snlri)) {
|
||||||
iana_afi_t pkt_afi;
|
iana_afi_t pkt_afi;
|
||||||
safi_t pkt_safi;
|
iana_safi_t pkt_safi;
|
||||||
|
|
||||||
pkt_afi = afi_int2iana(afi);
|
pkt_afi = afi_int2iana(afi);
|
||||||
pkt_safi = safi_int2iana(safi);
|
pkt_safi = safi_int2iana(safi);
|
||||||
@ -936,6 +938,7 @@ struct bpacket *subgroup_withdraw_packet(struct update_subgroup *subgrp)
|
|||||||
int space_needed = 0;
|
int space_needed = 0;
|
||||||
int num_pfx = 0;
|
int num_pfx = 0;
|
||||||
int addpath_encode = 0;
|
int addpath_encode = 0;
|
||||||
|
int addpath_overhead = 0;
|
||||||
u_int32_t addpath_tx_id = 0;
|
u_int32_t addpath_tx_id = 0;
|
||||||
struct prefix_rd *prd = NULL;
|
struct prefix_rd *prd = NULL;
|
||||||
|
|
||||||
@ -952,6 +955,7 @@ struct bpacket *subgroup_withdraw_packet(struct update_subgroup *subgrp)
|
|||||||
s = subgrp->work;
|
s = subgrp->work;
|
||||||
stream_reset(s);
|
stream_reset(s);
|
||||||
addpath_encode = bgp_addpath_encode_tx(peer, afi, safi);
|
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) {
|
while ((adv = BGP_ADV_FIFO_HEAD(&subgrp->sync->withdraw)) != NULL) {
|
||||||
assert(adv->rn);
|
assert(adv->rn);
|
||||||
@ -962,7 +966,7 @@ struct bpacket *subgroup_withdraw_packet(struct update_subgroup *subgrp)
|
|||||||
space_remaining =
|
space_remaining =
|
||||||
STREAM_REMAIN(s) - BGP_MAX_PACKET_SIZE_OVERFLOW;
|
STREAM_REMAIN(s) - BGP_MAX_PACKET_SIZE_OVERFLOW;
|
||||||
space_needed =
|
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);
|
+ bgp_packet_mpattr_prefix_size(afi, safi, &rn->p);
|
||||||
|
|
||||||
if (space_remaining < space_needed)
|
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, format the MP_UNREACH header */
|
||||||
if (first_time) {
|
if (first_time) {
|
||||||
iana_afi_t pkt_afi;
|
iana_afi_t pkt_afi;
|
||||||
safi_t pkt_safi;
|
iana_safi_t pkt_safi;
|
||||||
|
|
||||||
pkt_afi = afi_int2iana(afi);
|
pkt_afi = afi_int2iana(afi);
|
||||||
pkt_safi = safi_int2iana(safi);
|
pkt_safi = safi_int2iana(safi);
|
||||||
|
@ -51,6 +51,8 @@ int show_adj_route_vpn(struct vty *vty, struct peer *peer,
|
|||||||
if (bgp == NULL) {
|
if (bgp == NULL) {
|
||||||
if (!use_json)
|
if (!use_json)
|
||||||
vty_out(vty, "No BGP process is configured\n");
|
vty_out(vty, "No BGP process is configured\n");
|
||||||
|
else
|
||||||
|
vty_out(vty, "{}\n");
|
||||||
return CMD_WARNING;
|
return CMD_WARNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,6 +78,10 @@ static enum node_type bgp_node_type(afi_t afi, safi_t safi)
|
|||||||
case SAFI_MPLS_VPN:
|
case SAFI_MPLS_VPN:
|
||||||
return BGP_VPNV4_NODE;
|
return BGP_VPNV4_NODE;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
/* not expected */
|
||||||
|
return BGP_IPV4_NODE;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case AFI_IP6:
|
case AFI_IP6:
|
||||||
@ -94,6 +98,10 @@ static enum node_type bgp_node_type(afi_t afi, safi_t safi)
|
|||||||
case SAFI_MPLS_VPN:
|
case SAFI_MPLS_VPN:
|
||||||
return BGP_VPNV6_NODE;
|
return BGP_VPNV6_NODE;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
/* not expected */
|
||||||
|
return BGP_IPV4_NODE;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case AFI_L2VPN:
|
case AFI_L2VPN:
|
||||||
@ -4201,8 +4209,15 @@ DEFUN (neighbor_attr_unchanged,
|
|||||||
"Med attribute\n")
|
"Med attribute\n")
|
||||||
{
|
{
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
char *peer = argv[1]->arg;
|
char *peer_str = argv[1]->arg;
|
||||||
|
struct peer *peer;
|
||||||
u_int16_t flags = 0;
|
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))
|
if (argv_find(argv, argc, "as-path", &idx))
|
||||||
SET_FLAG(flags, PEER_FLAG_AS_PATH_UNCHANGED);
|
SET_FLAG(flags, PEER_FLAG_AS_PATH_UNCHANGED);
|
||||||
@ -4213,15 +4228,35 @@ DEFUN (neighbor_attr_unchanged,
|
|||||||
if (argv_find(argv, argc, "med", &idx))
|
if (argv_find(argv, argc, "med", &idx))
|
||||||
SET_FLAG(flags, PEER_FLAG_MED_UNCHANGED);
|
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_AS_PATH_UNCHANGED);
|
||||||
SET_FLAG(flags, PEER_FLAG_NEXTHOP_UNCHANGED);
|
SET_FLAG(flags, PEER_FLAG_NEXTHOP_UNCHANGED);
|
||||||
SET_FLAG(flags, PEER_FLAG_MED_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),
|
return peer_af_flag_set_vty(vty, peer_str, afi, safi, flags);
|
||||||
bgp_node_safi(vty), flags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ALIAS_HIDDEN(
|
ALIAS_HIDDEN(
|
||||||
@ -7052,12 +7087,6 @@ static void bgp_show_summary_afi_safi(struct vty *vty, struct bgp *bgp, int afi,
|
|||||||
json);
|
json);
|
||||||
}
|
}
|
||||||
safi++;
|
safi++;
|
||||||
if (safi == SAFI_RESERVED_4
|
|
||||||
|| safi
|
|
||||||
== SAFI_RESERVED_5) /* handle special
|
|
||||||
cases to match
|
|
||||||
zebra.h */
|
|
||||||
safi++;
|
|
||||||
if (!safi_wildcard)
|
if (!safi_wildcard)
|
||||||
safi = SAFI_MAX;
|
safi = SAFI_MAX;
|
||||||
}
|
}
|
||||||
|
@ -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. */
|
if (!ifp) /* This may happen if we've just unregistered for a VRF. */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ifp->ifindex = IFINDEX_DELETED;
|
|
||||||
|
|
||||||
if (BGP_DEBUG(zebra, ZEBRA))
|
if (BGP_DEBUG(zebra, ZEBRA))
|
||||||
zlog_debug("Rx Intf del VRF %u IF %s", vrf_id, ifp->name);
|
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;
|
return 0;
|
||||||
|
|
||||||
bgp_update_interface_nbrs(bgp, ifp, NULL);
|
bgp_update_interface_nbrs(bgp, ifp, NULL);
|
||||||
|
|
||||||
|
ifp->ifindex = IFINDEX_DELETED;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
47
bgpd/bgpd.c
47
bgpd/bgpd.c
@ -611,8 +611,8 @@ int bgp_listen_limit_unset(struct bgp *bgp)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int bgp_map_afi_safi_iana2int(iana_afi_t pkt_afi, safi_t pkt_safi, afi_t *afi,
|
int bgp_map_afi_safi_iana2int(iana_afi_t pkt_afi, iana_safi_t pkt_safi,
|
||||||
safi_t *safi)
|
afi_t *afi, safi_t *safi)
|
||||||
{
|
{
|
||||||
/* Map from IANA values to internal values, return error if
|
/* Map from IANA values to internal values, return error if
|
||||||
* values are unrecognized.
|
* 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,
|
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
|
/* Map from internal values to IANA values, return error if
|
||||||
* internal values are bad (unexpected).
|
* internal values are bad (unexpected).
|
||||||
@ -746,7 +746,7 @@ static unsigned int peer_hash_key_make(void *p)
|
|||||||
return sockunion_hash(&peer->su);
|
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 *peer1 = p1;
|
||||||
const struct peer *peer2 = p2;
|
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);
|
UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_MODE);
|
||||||
|
|
||||||
for (afi = AFI_IP; afi < AFI_MAX; afi++)
|
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;
|
peer->nsf[afi][safi] = 0;
|
||||||
|
|
||||||
if (peer->t_gr_restart) {
|
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");
|
XSTRDUP(MTYPE_BGP_PEER_HOST, "Static announcement");
|
||||||
bgp->peer = list_new();
|
bgp->peer = list_new();
|
||||||
bgp->peer->cmp = (int (*)(void *, void *))peer_cmp;
|
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 = list_new();
|
||||||
bgp->group->cmp = (int (*)(void *, void *))peer_group_cmp;
|
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);
|
bgp_config_write_filter(vty, peer, afi, safi, write);
|
||||||
|
|
||||||
/* atribute-unchanged. */
|
/* atribute-unchanged. */
|
||||||
if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_AS_PATH_UNCHANGED)
|
if (peer_af_flag_check(peer, afi, safi, PEER_FLAG_AS_PATH_UNCHANGED) ||
|
||||||
|| CHECK_FLAG(peer->af_flags[afi][safi],
|
peer_af_flag_check(peer, afi, safi, PEER_FLAG_NEXTHOP_UNCHANGED) ||
|
||||||
PEER_FLAG_NEXTHOP_UNCHANGED)
|
peer_af_flag_check(peer, afi, safi, PEER_FLAG_MED_UNCHANGED)) {
|
||||||
|| CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MED_UNCHANGED)) {
|
|
||||||
if (peergroup_af_flag_check(peer, afi, safi,
|
if (!peer_group_active(peer) ||
|
||||||
PEER_FLAG_AS_PATH_UNCHANGED)
|
peergroup_af_flag_check(peer, afi, safi,
|
||||||
&& peergroup_af_flag_check(peer, afi, safi,
|
PEER_FLAG_AS_PATH_UNCHANGED) ||
|
||||||
PEER_FLAG_NEXTHOP_UNCHANGED)
|
peergroup_af_flag_check(peer, afi, safi,
|
||||||
&& peergroup_af_flag_check(peer, afi, safi,
|
PEER_FLAG_NEXTHOP_UNCHANGED) ||
|
||||||
PEER_FLAG_MED_UNCHANGED)) {
|
peergroup_af_flag_check(peer, afi, safi,
|
||||||
afi_header_vty_out(
|
PEER_FLAG_MED_UNCHANGED)) {
|
||||||
vty, afi, safi, write,
|
|
||||||
" neighbor %s attribute-unchanged\n", addr);
|
|
||||||
} else {
|
|
||||||
afi_header_vty_out(
|
afi_header_vty_out(
|
||||||
vty, afi, safi, write,
|
vty, afi, safi, write,
|
||||||
" neighbor %s attribute-unchanged%s%s%s\n",
|
" neighbor %s attribute-unchanged%s%s%s\n",
|
||||||
addr,
|
addr,
|
||||||
peergroup_af_flag_check(
|
peer_af_flag_check(
|
||||||
peer, afi, safi,
|
peer, afi, safi,
|
||||||
PEER_FLAG_AS_PATH_UNCHANGED)
|
PEER_FLAG_AS_PATH_UNCHANGED)
|
||||||
? " as-path"
|
? " as-path"
|
||||||
: "",
|
: "",
|
||||||
peergroup_af_flag_check(
|
peer_af_flag_check(
|
||||||
peer, afi, safi,
|
peer, afi, safi,
|
||||||
PEER_FLAG_NEXTHOP_UNCHANGED)
|
PEER_FLAG_NEXTHOP_UNCHANGED)
|
||||||
? " next-hop"
|
? " next-hop"
|
||||||
: "",
|
: "",
|
||||||
peergroup_af_flag_check(peer, afi, safi,
|
peer_af_flag_check(peer, afi, safi,
|
||||||
PEER_FLAG_MED_UNCHANGED)
|
PEER_FLAG_MED_UNCHANGED)
|
||||||
? " med"
|
? " med"
|
||||||
: "");
|
: "");
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#include "bitfield.h"
|
#include "bitfield.h"
|
||||||
|
|
||||||
#define BGP_MAX_HOSTNAME 64 /* Linux max, is larger than most other sys */
|
#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. */
|
/* Default interval for IPv6 RAs when triggered by BGP unnumbered neighbor. */
|
||||||
#define BGP_UNNUM_DEFAULT_RA_INTERVAL 10
|
#define BGP_UNNUM_DEFAULT_RA_INTERVAL 10
|
||||||
@ -922,10 +923,10 @@ DECLARE_QOBJ_TYPE(peer)
|
|||||||
stream. */
|
stream. */
|
||||||
struct bgp_nlri {
|
struct bgp_nlri {
|
||||||
/* AFI. */
|
/* AFI. */
|
||||||
afi_t afi;
|
uint16_t afi; /* iana_afi_t */
|
||||||
|
|
||||||
/* SAFI. */
|
/* SAFI. */
|
||||||
safi_t safi;
|
uint8_t safi; /* iana_safi_t */
|
||||||
|
|
||||||
/* Pointer to NLRI byte stream. */
|
/* Pointer to NLRI byte stream. */
|
||||||
u_char *nlri;
|
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 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);
|
afi_t *afi, safi_t *safi);
|
||||||
extern int bgp_map_afi_safi_int2iana(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_create(struct peer *, afi_t, safi_t);
|
||||||
extern struct peer_af *peer_af_find(struct peer *, afi_t, safi_t);
|
extern struct peer_af *peer_af_find(struct peer *, afi_t, safi_t);
|
||||||
|
@ -135,10 +135,10 @@ struct rfapi_nve_group_cfg *bgp_rfapi_cfg_match_group(struct rfapi_cfg *hc,
|
|||||||
|
|
||||||
switch (vn->family) {
|
switch (vn->family) {
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
rt_vn = &(hc->nve_groups_vn[AFI_IP]);
|
rt_vn = hc->nve_groups_vn[AFI_IP];
|
||||||
break;
|
break;
|
||||||
case AF_INET6:
|
case AF_INET6:
|
||||||
rt_vn = &(hc->nve_groups_vn[AFI_IP6]);
|
rt_vn = hc->nve_groups_vn[AFI_IP6];
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -146,10 +146,10 @@ struct rfapi_nve_group_cfg *bgp_rfapi_cfg_match_group(struct rfapi_cfg *hc,
|
|||||||
|
|
||||||
switch (un->family) {
|
switch (un->family) {
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
rt_un = &(hc->nve_groups_un[AFI_IP]);
|
rt_un = hc->nve_groups_un[AFI_IP];
|
||||||
break;
|
break;
|
||||||
case AF_INET6:
|
case AF_INET6:
|
||||||
rt_un = &(hc->nve_groups_un[AFI_IP6]);
|
rt_un = hc->nve_groups_un[AFI_IP6];
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -2503,7 +2503,7 @@ DEFUN (vnc_nve_group_prefix,
|
|||||||
VTY_DECLVAR_CONTEXT(bgp, bgp);
|
VTY_DECLVAR_CONTEXT(bgp, bgp);
|
||||||
VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
|
VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
|
||||||
struct prefix p;
|
struct prefix p;
|
||||||
int afi;
|
afi_t afi;
|
||||||
struct route_table *rt;
|
struct route_table *rt;
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
int is_un_prefix = 0;
|
int is_un_prefix = 0;
|
||||||
@ -2527,10 +2527,10 @@ DEFUN (vnc_nve_group_prefix,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (argv[1]->arg[0] == 'u') {
|
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;
|
is_un_prefix = 1;
|
||||||
} else {
|
} 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 */
|
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 *bgp_rfapi_cfg_new(struct rfapi_rfp_cfg *cfg)
|
||||||
{
|
{
|
||||||
struct rfapi_cfg *h;
|
struct rfapi_cfg *h;
|
||||||
int afi;
|
afi_t afi;
|
||||||
|
|
||||||
h = (struct rfapi_cfg *)XCALLOC(MTYPE_RFAPI_CFG,
|
h = (struct rfapi_cfg *)XCALLOC(MTYPE_RFAPI_CFG,
|
||||||
sizeof(struct 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();
|
h->nve_groups_sequential = list_new();
|
||||||
assert(h->nve_groups_sequential);
|
assert(h->nve_groups_sequential);
|
||||||
|
|
||||||
for (afi = AFI_IP; afi < AFI_MAX; afi++) {
|
for (afi = AFI_IP; afi < AFI_MAX; afi++) {
|
||||||
/* ugly, to deal with addition of delegates, part of 0.99.24.1
|
h->nve_groups_vn[afi] = route_table_init();
|
||||||
* merge */
|
h->nve_groups_un[afi] = route_table_init();
|
||||||
h->nve_groups_vn[afi].delegate =
|
|
||||||
route_table_get_default_delegate();
|
|
||||||
h->nve_groups_un[afi].delegate =
|
|
||||||
route_table_get_default_delegate();
|
|
||||||
}
|
}
|
||||||
h->default_response_lifetime =
|
h->default_response_lifetime =
|
||||||
BGP_VNC_DEFAULT_RESPONSE_LIFETIME_DEFAULT;
|
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)
|
void bgp_rfapi_cfg_destroy(struct bgp *bgp, struct rfapi_cfg *h)
|
||||||
{
|
{
|
||||||
|
afi_t afi;
|
||||||
if (h == NULL)
|
if (h == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -3901,6 +3897,10 @@ void bgp_rfapi_cfg_destroy(struct bgp *bgp, struct rfapi_cfg *h)
|
|||||||
ecommunity_free(&h->default_rt_import_list);
|
ecommunity_free(&h->default_rt_import_list);
|
||||||
if (h->default_rfp_cfg)
|
if (h->default_rfp_cfg)
|
||||||
XFREE(MTYPE_RFAPI_RFP_GROUP_CFG, 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);
|
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)
|
void bgp_rfapi_show_summary(struct bgp *bgp, struct vty *vty)
|
||||||
{
|
{
|
||||||
struct rfapi_cfg *hc = bgp->rfapi_cfg;
|
struct rfapi_cfg *hc = bgp->rfapi_cfg;
|
||||||
int afi, type, redist = 0;
|
afi_t afi;
|
||||||
|
int type, redist = 0;
|
||||||
char tmp[40];
|
char tmp[40];
|
||||||
if (hc == NULL)
|
if (hc == NULL)
|
||||||
return;
|
return;
|
||||||
|
@ -135,8 +135,8 @@ struct rfapi_cfg {
|
|||||||
struct list *l2_groups; /* rfapi_l2_group_cfg list */
|
struct list *l2_groups; /* rfapi_l2_group_cfg list */
|
||||||
/* three views into the same collection of rfapi_nve_group_cfg */
|
/* three views into the same collection of rfapi_nve_group_cfg */
|
||||||
struct list *nve_groups_sequential;
|
struct list *nve_groups_sequential;
|
||||||
struct route_table nve_groups_vn[AFI_MAX];
|
struct route_table *nve_groups_vn[AFI_MAX];
|
||||||
struct route_table nve_groups_un[AFI_MAX];
|
struct route_table *nve_groups_un[AFI_MAX];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For Single VRF export to ordinary routing protocols. This is
|
* For Single VRF export to ordinary routing protocols. This is
|
||||||
|
@ -205,7 +205,7 @@ static int rfapi_find_node(struct bgp *bgp, struct rfapi_ip_addr *vn_addr,
|
|||||||
struct prefix p;
|
struct prefix p;
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
int rc;
|
int rc;
|
||||||
int afi;
|
afi_t afi;
|
||||||
|
|
||||||
if (!bgp) {
|
if (!bgp) {
|
||||||
return ENXIO;
|
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)))
|
if ((rc = rfapiRaddr2Qprefix(un_addr, &p)))
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
rn = route_node_lookup(&h->un[afi], &p);
|
rn = route_node_lookup(h->un[afi], &p);
|
||||||
|
|
||||||
if (!rn)
|
if (!rn)
|
||||||
return ENOENT;
|
return ENOENT;
|
||||||
@ -1415,7 +1415,7 @@ int rfapi_init_and_open(struct bgp *bgp, struct rfapi_descriptor *rfd,
|
|||||||
assert(afi_vn && afi_un);
|
assert(afi_vn && afi_un);
|
||||||
assert(!rfapiRaddr2Qprefix(&rfd->un_addr, &pfx_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);
|
assert(rn);
|
||||||
rfd->next = rn->info;
|
rfd->next = rn->info;
|
||||||
rn->info = rfd;
|
rn->info = rfd;
|
||||||
@ -2367,7 +2367,7 @@ int rfapi_register(void *handle, struct rfapi_ip_prefix *prefix,
|
|||||||
struct prefix p;
|
struct prefix p;
|
||||||
struct prefix *pfx_ip = NULL;
|
struct prefix *pfx_ip = NULL;
|
||||||
struct prefix_rd prd;
|
struct prefix_rd prd;
|
||||||
int afi;
|
afi_t afi;
|
||||||
struct prefix pfx_mac_buf;
|
struct prefix pfx_mac_buf;
|
||||||
struct prefix *pfx_mac = NULL;
|
struct prefix *pfx_mac = NULL;
|
||||||
struct prefix pfx_vn_buf;
|
struct prefix pfx_vn_buf;
|
||||||
|
@ -3872,6 +3872,10 @@ rfapiBgpInfoFilteredImportFunction(safi_t safi)
|
|||||||
|
|
||||||
case SAFI_ENCAP:
|
case SAFI_ENCAP:
|
||||||
return rfapiBgpInfoFilteredImportEncap;
|
return rfapiBgpInfoFilteredImportEncap;
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* not expected */
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
zlog_err("%s: bad safi %d", __func__, safi);
|
zlog_err("%s: bad safi %d", __func__, safi);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -4248,7 +4252,7 @@ static void rfapiBgpTableFilteredImport(struct bgp *bgp,
|
|||||||
struct rfapi *bgp_rfapi_new(struct bgp *bgp)
|
struct rfapi *bgp_rfapi_new(struct bgp *bgp)
|
||||||
{
|
{
|
||||||
struct rfapi *h;
|
struct rfapi *h;
|
||||||
int afi;
|
afi_t afi;
|
||||||
struct rfapi_rfp_cfg *cfg = NULL;
|
struct rfapi_rfp_cfg *cfg = NULL;
|
||||||
struct rfapi_rfp_cb_methods *cbm = 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));
|
h = (struct rfapi *)XCALLOC(MTYPE_RFAPI, sizeof(struct rfapi));
|
||||||
|
|
||||||
for (afi = AFI_IP; afi < AFI_MAX; afi++) {
|
for (afi = AFI_IP; afi < AFI_MAX; afi++) {
|
||||||
/* ugly, to deal with addition of delegates, part of 0.99.24.1
|
h->un[afi] = route_table_init();
|
||||||
* merge */
|
|
||||||
h->un[afi].delegate = route_table_get_default_delegate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -4292,6 +4294,8 @@ struct rfapi *bgp_rfapi_new(struct bgp *bgp)
|
|||||||
|
|
||||||
void bgp_rfapi_destroy(struct bgp *bgp, struct rfapi *h)
|
void bgp_rfapi_destroy(struct bgp *bgp, struct rfapi *h)
|
||||||
{
|
{
|
||||||
|
afi_t afi;
|
||||||
|
|
||||||
if (bgp == NULL || h == NULL)
|
if (bgp == NULL || h == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -4327,6 +4331,11 @@ void bgp_rfapi_destroy(struct bgp *bgp, struct rfapi *h)
|
|||||||
|
|
||||||
if (h->rfp != NULL)
|
if (h->rfp != NULL)
|
||||||
rfp_stop(h->rfp);
|
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_IMPORTTABLE, h->it_ce);
|
||||||
XFREE(MTYPE_RFAPI, h);
|
XFREE(MTYPE_RFAPI, h);
|
||||||
}
|
}
|
||||||
|
@ -171,7 +171,7 @@ struct rfapi_global_stats {
|
|||||||
* check vn address to get exact match.
|
* check vn address to get exact match.
|
||||||
*/
|
*/
|
||||||
struct rfapi {
|
struct rfapi {
|
||||||
struct route_table un[AFI_MAX];
|
struct route_table *un[AFI_MAX];
|
||||||
struct rfapi_import_table *imports; /* IPv4, IPv6 */
|
struct rfapi_import_table *imports; /* IPv4, IPv6 */
|
||||||
struct list descriptors; /* debug & resolve-nve imports */
|
struct list descriptors; /* debug & resolve-nve imports */
|
||||||
|
|
||||||
|
@ -2236,9 +2236,12 @@ void rfapiRibShowResponsesSummary(void *stream)
|
|||||||
struct rfapi_descriptor *rfd;
|
struct rfapi_descriptor *rfd;
|
||||||
struct listnode *node;
|
struct listnode *node;
|
||||||
|
|
||||||
|
|
||||||
if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
|
if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
|
||||||
return;
|
return;
|
||||||
|
if (!bgp) {
|
||||||
|
fp(out, "Unable to find default BGP instance\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
fp(out, "%-24s ", "Responses: (Prefixes)");
|
fp(out, "%-24s ", "Responses: (Prefixes)");
|
||||||
fp(out, "%-8s %-8u ", "Active:", bgp->rfapi->rib_prefix_count_total);
|
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)
|
if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
|
||||||
return;
|
return;
|
||||||
|
if (!bgp) {
|
||||||
|
fp(out, "Unable to find default BGP instance\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* loop over NVEs
|
* loop over NVEs
|
||||||
*/
|
*/
|
||||||
|
38
common.am
38
common.am
@ -8,12 +8,21 @@ am__v_CLIPPY_ = $(am__v_CLIPPY_$(AM_DEFAULT_VERBOSITY))
|
|||||||
am__v_CLIPPY_0 = @echo " CLIPPY " $@;
|
am__v_CLIPPY_0 = @echo " CLIPPY " $@;
|
||||||
am__v_CLIPPY_1 =
|
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:
|
.c_clippy.c:
|
||||||
$(AM_V_at)$(MAKE) -C $(top_builddir)/$(CLIPPYDIR) clippy
|
@{ test -x $(top_builddir)/$(HOSTTOOLS)lib/clippy || $(MAKE) -C $(top_builddir)/$(HOSTTOOLS) lib/clippy; }
|
||||||
$(AM_V_CLIPPY)$(top_builddir)/$(CLIPPYDIR)/clippy $(top_srcdir)/python/clidef.py $< > $@.tmp
|
$(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 $@
|
@{ 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
|
if HAVE_PROTOBUF
|
||||||
|
|
||||||
# Uncomment to use an non-system version of libprotobuf-c.
|
# 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=protoc
|
||||||
Q_PROTOC_C=protoc-c
|
Q_PROTOC_C=protoc-c
|
||||||
|
|
||||||
Q_PROTOBUF_CFILES = $(filter %.pb-c.c,$(SOURCES))
|
|
||||||
|
|
||||||
Q_PROTOBUF_SRCS = $(Q_PROTOBUF_CFILES) $(Q_PROTOBUF_HFILES)
|
|
||||||
|
|
||||||
# Rules
|
# Rules
|
||||||
%.pb.h: %.proto
|
.proto.pb.h:
|
||||||
$(Q_PROTOC) $(PROTOBUF_INCLUDES) --cpp_out=$(top_srcdir) $(top_srcdir)/$(PROTOBUF_PACKAGE)/$^
|
$(Q_PROTOC) -I$(top_srcdir) --cpp_out=$(top_srcdir) $(top_srcdir)/$^
|
||||||
|
|
||||||
%.pb-c.c %.pb-c.h: %.proto
|
AM_V_PROTOC_C = $(am__v_PROTOC_C_$(V))
|
||||||
$(Q_PROTOC_C) $(PROTOBUF_INCLUDES) --c_out=$(top_srcdir) $(top_srcdir)/$(PROTOBUF_PACKAGE)/$^
|
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.
|
# 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)
|
Q_FPM_PB_CLIENT_LDOPTS = $(top_srcdir)/fpm/libfrrfpm_pb.la $(Q_FRR_PB_CLIENT_LDOPTS)
|
||||||
|
|
||||||
endif # HAVE_PROTOBUF
|
endif # HAVE_PROTOBUF
|
||||||
|
|
||||||
Q_CLEANFILES = $(Q_PROTOBUF_SRCS)
|
|
||||||
|
|
||||||
Q_BUILT_SRCS = $(Q_PROTOBUF_SRCS)
|
|
||||||
|
337
configure.ac
337
configure.ac
@ -46,12 +46,12 @@ AS_IF([test "$host" != "$build"], [
|
|||||||
AC_MSG_NOTICE([...])
|
AC_MSG_NOTICE([...])
|
||||||
|
|
||||||
build_clippy="false"
|
build_clippy="false"
|
||||||
CLIPPYDIR="hosttools/lib"
|
HOSTTOOLS="hosttools/"
|
||||||
], [
|
], [
|
||||||
build_clippy="true"
|
build_clippy="true"
|
||||||
CLIPPYDIR="lib"
|
HOSTTOOLS=""
|
||||||
])
|
])
|
||||||
AC_SUBST(CLIPPYDIR)
|
AC_SUBST(HOSTTOOLS)
|
||||||
AM_CONDITIONAL([BUILD_CLIPPY], [$build_clippy])
|
AM_CONDITIONAL([BUILD_CLIPPY], [$build_clippy])
|
||||||
|
|
||||||
# Disable portability warnings -- our automake code (in particular
|
# Disable portability warnings -- our automake code (in particular
|
||||||
@ -75,14 +75,13 @@ AC_SUBST(exampledir)
|
|||||||
|
|
||||||
dnl default is to match previous behavior
|
dnl default is to match previous behavior
|
||||||
pkgsrcrcdir=""
|
pkgsrcrcdir=""
|
||||||
pkgsrcdir=""
|
|
||||||
AC_ARG_ENABLE([pkgsrcrcdir],
|
AC_ARG_ENABLE([pkgsrcrcdir],
|
||||||
AS_HELP_STRING([--enable-pkgsrcrcdir],
|
AS_HELP_STRING([--enable-pkgsrcrcdir],
|
||||||
[specify directory for rc.d scripts]),
|
[specify directory for rc.d scripts]),
|
||||||
pkgsrcrcdir="$enableval"; pkgsrcdir="pkgsrc",)
|
pkgsrcrcdir="$enableval",)
|
||||||
dnl XXX add --pkgsrcrcdir to autoconf standard directory list somehow
|
dnl XXX add --pkgsrcrcdir to autoconf standard directory list somehow
|
||||||
AC_SUBST(pkgsrcdir)
|
|
||||||
AC_SUBST(pkgsrcrcdir)
|
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)])], [
|
AC_ARG_WITH([moduledir], [AS_HELP_STRING([--with-moduledir=DIR], [module directory (${libdir}/frr/modules)])], [
|
||||||
moduledir="$withval"
|
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)
|
AC_DEFINE(HAVE_V6_RR_SEMANTICS,, Compile in v6 Route Replacement Semantics)
|
||||||
fi
|
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
|
if test "${enable_datacenter}" = "yes" ; then
|
||||||
AC_DEFINE(HAVE_DATACENTER,,Compile extensions for a DataCenter)
|
AC_DEFINE(HAVE_DATACENTER,,Compile extensions for a DataCenter)
|
||||||
DFLT_NAME="datacenter"
|
DFLT_NAME="datacenter"
|
||||||
@ -850,50 +829,52 @@ FRR_INCLUDES
|
|||||||
|
|
||||||
dnl V6 headers are checked below, after we check for v6
|
dnl V6 headers are checked below, after we check for v6
|
||||||
|
|
||||||
dnl Some systems (Solaris 2.x) require libnsl (Network Services Library)
|
AC_MSG_CHECKING([which operating system interface to use])
|
||||||
case "$host" in
|
case "$host_os" in
|
||||||
[*-sunos5.[6-7]*] | [*-solaris2.[6-7]*])
|
sunos* | solaris2*)
|
||||||
opsys=sol2-6
|
AC_MSG_RESULT([Solaris])
|
||||||
AC_DEFINE(SUNOS_56, 1, SunOS 5.6 to 5.7)
|
|
||||||
AC_DEFINE(SUNOS_5, 1, SunOS 5)
|
AC_DEFINE(SUNOS_5, 1, [SunOS 5])
|
||||||
AC_CHECK_LIB(xnet, main)
|
AC_DEFINE(SOLARIS_IPV6, 1, Solaris IPv6)
|
||||||
CURSES=-lcurses
|
|
||||||
SOLARIS="solaris"
|
AC_CHECK_LIB(socket, main)
|
||||||
;;
|
AC_CHECK_LIB(nsl, main)
|
||||||
[*-sunos5.[8-9]] \
|
AC_CHECK_LIB(umem, main)
|
||||||
| [*-sunos5.1[0-9]] \
|
AC_CHECK_FUNCS([printstack], [
|
||||||
| [*-sunos5.1[0-9].[0-9]] \
|
AC_DEFINE([HAVE_PRINTSTACK],1,[Solaris printstack])
|
||||||
| [*-solaris2.[8-9]] \
|
AC_DEFINE([HAVE_STACK_TRACE],1,[Stack symbols decode functionality])
|
||||||
| [*-solaris2.1[0-9]] \
|
])
|
||||||
| [*-solaris2.1[0-9].[0-9]])
|
CURSES=-lcurses
|
||||||
opsys=sol8
|
SOLARIS="solaris"
|
||||||
AC_DEFINE(SUNOS_59, 1, [SunOS 5.8 up])
|
;;
|
||||||
AC_DEFINE(SUNOS_5, 1, [SunOS 5])
|
linux*)
|
||||||
AC_CHECK_LIB(socket, main)
|
AC_MSG_RESULT([Linux])
|
||||||
AC_CHECK_LIB(nsl, main)
|
|
||||||
AC_CHECK_LIB(umem, main)
|
AC_DEFINE(GNU_LINUX,,GNU Linux)
|
||||||
AC_CHECK_FUNCS([printstack],
|
AC_DEFINE(HAVE_NETLINK,,netlink)
|
||||||
[AC_DEFINE([HAVE_PRINTSTACK],1,[Solaris printstack])
|
AC_DEFINE(LINUX_IPV6,1,Linux IPv6 stack)
|
||||||
AC_DEFINE([HAVE_STACK_TRACE],1,[Stack symbols decode functionality])
|
|
||||||
])
|
dnl Linux has a compilation problem with mixing
|
||||||
CURSES=-lcurses
|
dnl netinet/in.h and linux/in6.h they are not
|
||||||
SOLARIS="solaris"
|
dnl compatible. There has been discussion on
|
||||||
;;
|
dnl how to fix it but no real progress on implementation
|
||||||
*-sunos5* | *-solaris2*)
|
dnl when they fix it, remove this
|
||||||
AC_DEFINE(SUNOS_5,,SunOS 5, Unknown SunOS)
|
AC_DEFINE(IPV6_MINHOPCOUNT, 73, Linux ipv6 Min Hop Count)
|
||||||
AC_CHECK_LIB(socket, main)
|
|
||||||
AC_CHECK_LIB(nsl, main)
|
AC_CHECK_DECLS([IFLA_INFO_SLAVE_KIND], [], [], [#include <linux/if_link.h>])
|
||||||
CURSES=-lcurses
|
;;
|
||||||
SOLARIS="solaris"
|
openbsd*)
|
||||||
;;
|
AC_MSG_RESULT([OpenBSD])
|
||||||
*-linux*)
|
|
||||||
opsys=gnu-linux
|
AC_DEFINE(OPEN_BSD,,OpenBSD)
|
||||||
AC_DEFINE(GNU_LINUX,,GNU Linux)
|
AC_DEFINE(KAME,1,KAME IPv6)
|
||||||
;;
|
;;
|
||||||
*-openbsd*)
|
*)
|
||||||
opsys=openbsd
|
AC_MSG_RESULT([BSD])
|
||||||
AC_DEFINE(OPEN_BSD,,OpenBSD)
|
|
||||||
;;
|
AC_DEFINE(HAVE_NET_RT_IFLIST,,NET_RT_IFLIST)
|
||||||
|
AC_DEFINE(KAME,1,KAME IPv6)
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
AC_SYS_LARGEFILE
|
AC_SYS_LARGEFILE
|
||||||
@ -1049,26 +1030,6 @@ AC_CHECK_HEADER([asm-generic/unistd.h],
|
|||||||
AC_CHECK_FUNCS(setns)]
|
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 --------------------------
|
||||||
dnl Determine IS-IS I/O method
|
dnl Determine IS-IS I/O method
|
||||||
dnl --------------------------
|
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(net/bpf.h)
|
||||||
AC_CHECK_HEADER(sys/dlpi.h)
|
AC_CHECK_HEADER(sys/dlpi.h)
|
||||||
AC_MSG_CHECKING(zebra IS-IS I/O method)
|
AC_MSG_CHECKING(zebra IS-IS I/O method)
|
||||||
if test x"$opsys" = x"gnu-linux"; then
|
|
||||||
AC_MSG_RESULT(pfpacket)
|
case "$host_os" in
|
||||||
ISIS_METHOD_MACRO="ISIS_METHOD_PFPACKET"
|
linux*)
|
||||||
elif test x"$opsys" = x"sol2-6" -o x"$opsys" = x"sol8"; then
|
AC_MSG_RESULT(pfpacket)
|
||||||
AC_MSG_RESULT(DLPI)
|
ISIS_METHOD_MACRO="ISIS_METHOD_PFPACKET"
|
||||||
ISIS_METHOD_MACRO="ISIS_METHOD_DLPI"
|
;;
|
||||||
else
|
solaris* | sunos*)
|
||||||
if test $ac_cv_header_net_bpf_h = no; then
|
AC_MSG_RESULT(DLPI)
|
||||||
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"
|
ISIS_METHOD_MACRO="ISIS_METHOD_DLPI"
|
||||||
else
|
;;
|
||||||
AC_MSG_RESULT(BPF)
|
*)
|
||||||
ISIS_METHOD_MACRO="ISIS_METHOD_BPF"
|
if test $ac_cv_header_net_bpf_h = no; then
|
||||||
fi
|
if test $ac_cv_header_sys_dlpi_h = no; then
|
||||||
fi
|
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 ])
|
AC_DEFINE_UNQUOTED(ISIS_METHOD, $ISIS_METHOD_MACRO, [ selected method for isis, == one of the constants ])
|
||||||
|
|
||||||
dnl ------------------------------------
|
dnl ------------------------------------
|
||||||
@ -1128,59 +1094,6 @@ main()
|
|||||||
}]])],[AC_MSG_RESULT(yes - using workaround) AC_DEFINE(HAVE_BROKEN_CMSG_FIRSTHDR,,Broken CMSG_FIRSTHDR)],
|
}]])],[AC_MSG_RESULT(yes - using workaround) AC_DEFINE(HAVE_BROKEN_CMSG_FIRSTHDR,,Broken CMSG_FIRSTHDR)],
|
||||||
[AC_MSG_RESULT(no)],[AC_MSG_RESULT(no)])
|
[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 ---------------------------------------------------------------
|
||||||
dnl figure out how to specify an interface in multicast sockets API
|
dnl figure out how to specify an interface in multicast sockets API
|
||||||
dnl ---------------------------------------------------------------
|
dnl ---------------------------------------------------------------
|
||||||
@ -1276,71 +1189,11 @@ if test $ac_cv_have_decl_TCP_MD5SIG = no; then
|
|||||||
AC_CHECK_DECLS([TCP_MD5SIG], [], [], MD5_INCLUDES)])
|
AC_CHECK_DECLS([TCP_MD5SIG], [], [], MD5_INCLUDES)])
|
||||||
fi
|
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 ----------------------------------------------------------------------------
|
||||||
dnl figure out if domainname is available in the utsname struct (GNU extension).
|
dnl figure out if domainname is available in the utsname struct (GNU extension).
|
||||||
dnl ----------------------------------------------------------------------------
|
dnl ----------------------------------------------------------------------------
|
||||||
AC_CHECK_MEMBERS([struct utsname.domainname], [], [], [#include <sys/utsname.h>])
|
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 ------------------
|
||||||
dnl IPv6 header checks
|
dnl IPv6 header checks
|
||||||
dnl ------------------
|
dnl ------------------
|
||||||
@ -1375,12 +1228,7 @@ fi
|
|||||||
dnl --------------------
|
dnl --------------------
|
||||||
dnl Daemon disable check
|
dnl Daemon disable check
|
||||||
dnl --------------------
|
dnl --------------------
|
||||||
if test "${enable_zebra}" = "no";then
|
AM_CONDITIONAL(ZEBRA, test "${enable_zebra}" != "no")
|
||||||
ZEBRA=""
|
|
||||||
else
|
|
||||||
ZEBRA="zebra"
|
|
||||||
fi
|
|
||||||
AM_CONDITIONAL(ZEBRA, test "x$ZEBRA" = "xzebra")
|
|
||||||
|
|
||||||
if test "${enable_bgpd}" = "no";then
|
if test "${enable_bgpd}" = "no";then
|
||||||
BGPD=""
|
BGPD=""
|
||||||
@ -1412,15 +1260,18 @@ fi
|
|||||||
AM_CONDITIONAL(LDPD, test "x$LDPD" = "xldpd")
|
AM_CONDITIONAL(LDPD, test "x$LDPD" = "xldpd")
|
||||||
|
|
||||||
NHRPD=""
|
NHRPD=""
|
||||||
if test "$opsys" = "gnu-linux"; then
|
case "$host_os" in
|
||||||
if test "${enable_nhrpd}" != "no"; then
|
linux*)
|
||||||
NHRPD="nhrpd"
|
if test "${enable_nhrpd}" != "no"; then
|
||||||
fi
|
NHRPD="nhrpd"
|
||||||
else
|
fi
|
||||||
if test "${enable_nhrpd}" = "yes"; then
|
;;
|
||||||
AC_MSG_ERROR([nhrpd requires kernel APIs that are only present on Linux.])
|
*)
|
||||||
fi
|
if test "${enable_nhrpd}" = "yes"; then
|
||||||
fi
|
AC_MSG_ERROR([nhrpd requires kernel APIs that are only present on Linux.])
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
AM_CONDITIONAL(NHRPD, test "x$NHRPD" = "xnhrpd")
|
AM_CONDITIONAL(NHRPD, test "x$NHRPD" = "xnhrpd")
|
||||||
|
|
||||||
if test "${enable_eigrpd}" = "no";then
|
if test "${enable_eigrpd}" = "no";then
|
||||||
@ -1506,7 +1357,6 @@ fi
|
|||||||
AM_CONDITIONAL([ENABLE_BGP_VNC], [test x${enable_bgp_vnc} != xno])
|
AM_CONDITIONAL([ENABLE_BGP_VNC], [test x${enable_bgp_vnc} != xno])
|
||||||
|
|
||||||
AC_SUBST(DOC)
|
AC_SUBST(DOC)
|
||||||
AC_SUBST(ZEBRA)
|
|
||||||
AC_SUBST(RFPTEST)
|
AC_SUBST(RFPTEST)
|
||||||
AC_SUBST(LIBRFP)
|
AC_SUBST(LIBRFP)
|
||||||
AC_SUBST(RFPINC)
|
AC_SUBST(RFPINC)
|
||||||
@ -1969,22 +1819,17 @@ AC_CACHE_VAL(ac_cv_htonl_works,
|
|||||||
)
|
)
|
||||||
AC_MSG_RESULT($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
|
ripngd/Makefile bgpd/Makefile ospfd/Makefile watchfrr/Makefile
|
||||||
ospf6d/Makefile ldpd/Makefile isisd/Makefile vtysh/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
|
bgpd/rfp-example/rfptest/Makefile bgpd/rfp-example/librfp/Makefile
|
||||||
babeld/Makefile
|
babeld/Makefile
|
||||||
pimd/Makefile
|
pimd/Makefile
|
||||||
eigrpd/Makefile
|
eigrpd/Makefile
|
||||||
nhrpd/Makefile
|
nhrpd/Makefile
|
||||||
redhat/Makefile
|
|
||||||
tools/Makefile
|
tools/Makefile
|
||||||
pkgsrc/Makefile
|
|
||||||
python/Makefile
|
|
||||||
fpm/Makefile
|
|
||||||
redhat/frr.spec
|
redhat/frr.spec
|
||||||
snapcraft/Makefile
|
|
||||||
snapcraft/snapcraft.yaml
|
snapcraft/snapcraft.yaml
|
||||||
lib/version.h
|
lib/version.h
|
||||||
tests/lib/cli/test_cli.refout
|
tests/lib/cli/test_cli.refout
|
||||||
|
@ -17,6 +17,9 @@ CentOS 6 restrictions:
|
|||||||
- Zebra is unable to detect what bridge/vrf an interface is associcated
|
- 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
|
with (IFLA_INFO_SLAVE_KIND does not exist in the kernel headers, you
|
||||||
can use a newer kernel + headers to get this functionality)
|
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
|
Install required packages
|
||||||
-------------------------
|
-------------------------
|
||||||
|
@ -179,8 +179,8 @@ The default is 4@dmn{s}.
|
|||||||
@node Babel redistribution, Show Babel information, Babel configuration, Babel
|
@node Babel redistribution, Show Babel information, Babel configuration, Babel
|
||||||
@section Babel redistribution
|
@section Babel redistribution
|
||||||
|
|
||||||
@deffn {Babel command} {redistribute @var{kind}}
|
@deffn {Babel command} {redistribute @var{<ipv4|ipv6>} @var{kind}}
|
||||||
@deffnx {Babel command} {no redistribute @var{kind}}
|
@deffnx {Babel command} {no redistribute @var{<ipv4|ipv6>} @var{kind}}
|
||||||
Specify which kind of routes should be redistributed into Babel.
|
Specify which kind of routes should be redistributed into Babel.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@
|
|||||||
#include "keychain.h"
|
#include "keychain.h"
|
||||||
#include "distribute.h"
|
#include "distribute.h"
|
||||||
#include "libfrr.h"
|
#include "libfrr.h"
|
||||||
//#include "routemap.h"
|
#include "routemap.h"
|
||||||
//#include "if_rmap.h"
|
//#include "if_rmap.h"
|
||||||
|
|
||||||
#include "eigrpd/eigrp_structs.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_add_hook(eigrp_distribute_update_all);
|
||||||
prefix_list_delete_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();
|
/*eigrp_route_map_init();
|
||||||
route_map_add_hook (eigrp_rmap_update);
|
route_map_add_hook (eigrp_rmap_update);
|
||||||
route_map_delete_hook (eigrp_rmap_update);*/
|
route_map_delete_hook (eigrp_rmap_update);*/
|
||||||
|
@ -237,6 +237,11 @@ DEFUN (no_router_eigrp,
|
|||||||
struct eigrp *eigrp;
|
struct eigrp *eigrp;
|
||||||
|
|
||||||
eigrp = eigrp_lookup();
|
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)) {
|
if (eigrp->AS != atoi(argv[3]->arg)) {
|
||||||
vty_out(vty, "%% Attempting to deconfigure non-existent AS\n");
|
vty_out(vty, "%% Attempting to deconfigure non-existent AS\n");
|
||||||
return CMD_WARNING_CONFIG_FAILED;
|
return CMD_WARNING_CONFIG_FAILED;
|
||||||
@ -1000,9 +1005,11 @@ DEFUN (eigrp_redistribute_source_metric,
|
|||||||
|
|
||||||
/* Get distribute source. */
|
/* Get distribute source. */
|
||||||
argv_find(argv, argc, "redistribute", &idx);
|
argv_find(argv, argc, "redistribute", &idx);
|
||||||
source = proto_redistnum(AFI_IP, argv[idx + 1]->arg);
|
source = proto_redistnum(AFI_IP, argv[idx + 1]->text);
|
||||||
if (source < 0)
|
if (source < 0) {
|
||||||
|
vty_out(vty, "%% Invalid route type\n");
|
||||||
return CMD_WARNING_CONFIG_FAILED;
|
return CMD_WARNING_CONFIG_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
/* Get metrics values */
|
/* Get metrics values */
|
||||||
|
|
||||||
@ -1029,9 +1036,11 @@ DEFUN (no_eigrp_redistribute_source_metric,
|
|||||||
|
|
||||||
/* Get distribute source. */
|
/* Get distribute source. */
|
||||||
argv_find(argv, argc, "redistribute", &idx);
|
argv_find(argv, argc, "redistribute", &idx);
|
||||||
source = proto_redistnum(AFI_IP, argv[idx + 1]->arg);
|
source = proto_redistnum(AFI_IP, argv[idx + 1]->text);
|
||||||
if (source < 0)
|
if (source < 0) {
|
||||||
|
vty_out(vty, "%% Invalid route type\n");
|
||||||
return CMD_WARNING_CONFIG_FAILED;
|
return CMD_WARNING_CONFIG_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
/* Get metrics values */
|
/* Get metrics values */
|
||||||
|
|
||||||
|
2
fpm/.gitignore
vendored
2
fpm/.gitignore
vendored
@ -1,4 +1,4 @@
|
|||||||
Makefile
|
!Makefile
|
||||||
Makefile.in
|
Makefile.in
|
||||||
*.o
|
*.o
|
||||||
tags
|
tags
|
||||||
|
10
fpm/Makefile
Normal file
10
fpm/Makefile
Normal 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:
|
@ -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
|
|
@ -20,6 +20,8 @@
|
|||||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
syntax = "proto2";
|
||||||
|
|
||||||
//
|
//
|
||||||
// Protobuf definitions pertaining to the Forwarding Plane Manager component.
|
// Protobuf definitions pertaining to the Forwarding Plane Manager component.
|
||||||
//
|
//
|
||||||
|
23
fpm/subdir.am
Normal file
23
fpm/subdir.am
Normal 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
1
ldpd/.gitignore
vendored
@ -15,3 +15,4 @@ TAGS
|
|||||||
.arch-ids
|
.arch-ids
|
||||||
*~
|
*~
|
||||||
*.loT
|
*.loT
|
||||||
|
ldp_vty_cmds_clippy.c
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
## Process this file with automake to produce Makefile.in.
|
## 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_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib
|
||||||
DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
|
DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
|
||||||
INSTALL_SDATA=@INSTALL@ -m 600
|
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 \
|
socket.c util.c ldp_vty_cmds.c ldp_vty_conf.c ldp_vty_exec.c \
|
||||||
ldp_debug.c ldp_zebra.c
|
ldp_debug.c ldp_zebra.c
|
||||||
|
|
||||||
|
ldp_vty_cmds.o: ldp_vty_cmds_clippy.c
|
||||||
|
|
||||||
noinst_HEADERS = \
|
noinst_HEADERS = \
|
||||||
control.h lde.h ldpd.h ldpe.h ldp.h log.h ldp_debug.h ldp_vty.h
|
control.h lde.h ldpd.h ldpe.h ldp.h log.h ldp_debug.h ldp_vty.h
|
||||||
|
|
||||||
|
@ -1328,7 +1328,6 @@ lde_nbr_addr_update(struct lde_nbr *ln, struct lde_addr *lde_addr, int removed)
|
|||||||
struct lde_map *me;
|
struct lde_map *me;
|
||||||
|
|
||||||
RB_FOREACH(fec, fec_tree, &ln->recv_map) {
|
RB_FOREACH(fec, fec_tree, &ln->recv_map) {
|
||||||
fn = (struct fec_node *)fec_find(&ft, fec);
|
|
||||||
switch (fec->type) {
|
switch (fec->type) {
|
||||||
case FEC_TYPE_IPV4:
|
case FEC_TYPE_IPV4:
|
||||||
if (lde_addr->af != AF_INET)
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn = (struct fec_node *)fec_find(&ft, fec);
|
||||||
|
if (fn == NULL)
|
||||||
|
/* shouldn't happen */
|
||||||
|
continue;
|
||||||
|
|
||||||
LIST_FOREACH(fnh, &fn->nexthops, entry) {
|
LIST_FOREACH(fnh, &fn->nexthops, entry) {
|
||||||
if (ldp_addrcmp(fnh->af, &fnh->nexthop,
|
if (ldp_addrcmp(fnh->af, &fnh->nexthop,
|
||||||
&lde_addr->addr))
|
&lde_addr->addr))
|
||||||
|
@ -38,31 +38,31 @@ struct cmd_node ldp_debug_node =
|
|||||||
};
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
ldp_vty_debug(struct vty *vty, int disable, const char *type_str,
|
ldp_vty_debug(struct vty *vty, const char *negate, const char *type_str,
|
||||||
const char *dir_str, int all)
|
const char *dir_str, const char *all)
|
||||||
{
|
{
|
||||||
if (strcmp(type_str, "discovery") == 0) {
|
if (strcmp(type_str, "discovery") == 0) {
|
||||||
if (dir_str == NULL)
|
if (dir_str == NULL)
|
||||||
return (CMD_WARNING_CONFIG_FAILED);
|
return (CMD_WARNING_CONFIG_FAILED);
|
||||||
|
|
||||||
if (dir_str[0] == 'r') {
|
if (dir_str[0] == 'r') {
|
||||||
if (disable)
|
if (negate)
|
||||||
DEBUG_OFF(hello, HELLO_RECV);
|
DEBUG_OFF(hello, HELLO_RECV);
|
||||||
else
|
else
|
||||||
DEBUG_ON(hello, HELLO_RECV);
|
DEBUG_ON(hello, HELLO_RECV);
|
||||||
} else {
|
} else {
|
||||||
if (disable)
|
if (negate)
|
||||||
DEBUG_OFF(hello, HELLO_SEND);
|
DEBUG_OFF(hello, HELLO_SEND);
|
||||||
else
|
else
|
||||||
DEBUG_ON(hello, HELLO_SEND);
|
DEBUG_ON(hello, HELLO_SEND);
|
||||||
}
|
}
|
||||||
} else if (strcmp(type_str, "errors") == 0) {
|
} else if (strcmp(type_str, "errors") == 0) {
|
||||||
if (disable)
|
if (negate)
|
||||||
DEBUG_OFF(errors, ERRORS);
|
DEBUG_OFF(errors, ERRORS);
|
||||||
else
|
else
|
||||||
DEBUG_ON(errors, ERRORS);
|
DEBUG_ON(errors, ERRORS);
|
||||||
} else if (strcmp(type_str, "event") == 0) {
|
} else if (strcmp(type_str, "event") == 0) {
|
||||||
if (disable)
|
if (negate)
|
||||||
DEBUG_OFF(event, EVENT);
|
DEBUG_OFF(event, EVENT);
|
||||||
else
|
else
|
||||||
DEBUG_ON(event, EVENT);
|
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);
|
return (CMD_WARNING_CONFIG_FAILED);
|
||||||
|
|
||||||
if (dir_str[0] == 'r') {
|
if (dir_str[0] == 'r') {
|
||||||
if (disable) {
|
if (negate) {
|
||||||
DEBUG_OFF(msg, MSG_RECV);
|
DEBUG_OFF(msg, MSG_RECV);
|
||||||
DEBUG_OFF(msg, MSG_RECV_ALL);
|
DEBUG_OFF(msg, MSG_RECV_ALL);
|
||||||
} else {
|
} else {
|
||||||
@ -80,7 +80,7 @@ ldp_vty_debug(struct vty *vty, int disable, const char *type_str,
|
|||||||
DEBUG_ON(msg, MSG_RECV_ALL);
|
DEBUG_ON(msg, MSG_RECV_ALL);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (disable) {
|
if (negate) {
|
||||||
DEBUG_OFF(msg, MSG_SEND);
|
DEBUG_OFF(msg, MSG_SEND);
|
||||||
DEBUG_OFF(msg, MSG_SEND_ALL);
|
DEBUG_OFF(msg, MSG_SEND_ALL);
|
||||||
} else {
|
} else {
|
||||||
@ -90,7 +90,7 @@ ldp_vty_debug(struct vty *vty, int disable, const char *type_str,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (strcmp(type_str, "zebra") == 0) {
|
} else if (strcmp(type_str, "zebra") == 0) {
|
||||||
if (disable)
|
if (negate)
|
||||||
DEBUG_OFF(zebra, ZEBRA);
|
DEBUG_OFF(zebra, ZEBRA);
|
||||||
else
|
else
|
||||||
DEBUG_ON(zebra, ZEBRA);
|
DEBUG_ON(zebra, ZEBRA);
|
||||||
|
@ -36,46 +36,46 @@ int ldp_get_address(const char *, int *, union ldpd_addr *);
|
|||||||
int ldp_config_write(struct vty *);
|
int ldp_config_write(struct vty *);
|
||||||
int ldp_l2vpn_config_write(struct vty *);
|
int ldp_l2vpn_config_write(struct vty *);
|
||||||
int ldp_debug_config_write(struct vty *);
|
int ldp_debug_config_write(struct vty *);
|
||||||
int ldp_vty_mpls_ldp (struct vty *, int);
|
int ldp_vty_mpls_ldp (struct vty *, const char *);
|
||||||
int ldp_vty_address_family (struct vty *, int, const char *);
|
int ldp_vty_address_family (struct vty *, const char *, const char *);
|
||||||
int ldp_vty_disc_holdtime(struct vty *, int, const char *, const char *);
|
int ldp_vty_disc_holdtime(struct vty *, const char *, const char *, long);
|
||||||
int ldp_vty_disc_interval(struct vty *, int, const char *, const char *);
|
int ldp_vty_disc_interval(struct vty *, const char *, const char *, long);
|
||||||
int ldp_vty_targeted_hello_accept(struct vty *, int, const char *);
|
int ldp_vty_targeted_hello_accept(struct vty *, const char *, const char *);
|
||||||
int ldp_vty_nbr_session_holdtime(struct vty *, int, 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 *, int, const char *);
|
int ldp_vty_af_session_holdtime(struct vty *, const char *, long);
|
||||||
int ldp_vty_interface(struct vty *, int, const char *);
|
int ldp_vty_interface(struct vty *, const char *, const char *);
|
||||||
int ldp_vty_trans_addr(struct vty *, int, const char *);
|
int ldp_vty_trans_addr(struct vty *, const char *, const char *);
|
||||||
int ldp_vty_neighbor_targeted(struct vty *, int, const char *);
|
int ldp_vty_neighbor_targeted(struct vty *, const char *, const char *);
|
||||||
int ldp_vty_label_advertise(struct vty *, int, const char *, const char *);
|
int ldp_vty_label_advertise(struct vty *, const char *, const char *, const char *);
|
||||||
int ldp_vty_label_allocate(struct vty *, int, int, const char *);
|
int ldp_vty_label_allocate(struct vty *, const char *, const char *, const char *);
|
||||||
int ldp_vty_label_expnull(struct vty *, int, const char *);
|
int ldp_vty_label_expnull(struct vty *, const char *, const char *);
|
||||||
int ldp_vty_label_accept(struct vty *, int, const char *, const char *);
|
int ldp_vty_label_accept(struct vty *, const char *, const char *, const char *);
|
||||||
int ldp_vty_ttl_security(struct vty *, int);
|
int ldp_vty_ttl_security(struct vty *, const char *);
|
||||||
int ldp_vty_router_id(struct vty *, int, const char *);
|
int ldp_vty_router_id(struct vty *, const char *, struct in_addr);
|
||||||
int ldp_vty_ds_cisco_interop(struct vty *, int);
|
int ldp_vty_ds_cisco_interop(struct vty *, const char *);
|
||||||
int ldp_vty_trans_pref_ipv4(struct vty *, int);
|
int ldp_vty_trans_pref_ipv4(struct vty *, const char *);
|
||||||
int ldp_vty_neighbor_password(struct vty *, int, const char *, const char *);
|
int ldp_vty_neighbor_password(struct vty *, const char *, struct in_addr, const char *);
|
||||||
int ldp_vty_neighbor_ttl_security(struct vty *, int, const char *, const char *);
|
int ldp_vty_neighbor_ttl_security(struct vty *, const char *, struct in_addr, const char *);
|
||||||
int ldp_vty_l2vpn(struct vty *, int, const char *);
|
int ldp_vty_l2vpn(struct vty *, const char *, const char *);
|
||||||
int ldp_vty_l2vpn_bridge(struct vty *, int, const char *);
|
int ldp_vty_l2vpn_bridge(struct vty *, const char *, const char *);
|
||||||
int ldp_vty_l2vpn_mtu(struct vty *, int, const char *);
|
int ldp_vty_l2vpn_mtu(struct vty *, const char *, long);
|
||||||
int ldp_vty_l2vpn_pwtype(struct vty *, int, const char *);
|
int ldp_vty_l2vpn_pwtype(struct vty *, const char *, const char *);
|
||||||
int ldp_vty_l2vpn_interface(struct vty *, int, const char *);
|
int ldp_vty_l2vpn_interface(struct vty *, const char *, const char *);
|
||||||
int ldp_vty_l2vpn_pseudowire(struct vty *, int, const char *);
|
int ldp_vty_l2vpn_pseudowire(struct vty *, const char *, const char *);
|
||||||
int ldp_vty_l2vpn_pw_cword(struct vty *, int, const char *);
|
int ldp_vty_l2vpn_pw_cword(struct vty *, const char *, const char *);
|
||||||
int ldp_vty_l2vpn_pw_nbr_addr(struct vty *, int, const char *);
|
int ldp_vty_l2vpn_pw_nbr_addr(struct vty *, const char *, const char *);
|
||||||
int ldp_vty_l2vpn_pw_nbr_id(struct vty *, int, const char *);
|
int ldp_vty_l2vpn_pw_nbr_id(struct vty *, const char *, struct in_addr);
|
||||||
int ldp_vty_l2vpn_pw_pwid(struct vty *, int, const char *);
|
int ldp_vty_l2vpn_pw_pwid(struct vty *, const char *, long);
|
||||||
int ldp_vty_l2vpn_pw_pwstatus(struct vty *, int);
|
int ldp_vty_l2vpn_pw_pwstatus(struct vty *, const char *);
|
||||||
int ldp_vty_clear_nbr(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_debug(struct vty *, const char *, const char *, const char *, const char *);
|
||||||
int ldp_vty_show_binding(struct vty *, const char *, int, int);
|
int ldp_vty_show_binding(struct vty *, const char *, const char *, const char *);
|
||||||
int ldp_vty_show_discovery(struct vty *, const char *, int, int);
|
int ldp_vty_show_discovery(struct vty *, const char *, const char *, const char *);
|
||||||
int ldp_vty_show_interface(struct vty *, const char *, int);
|
int ldp_vty_show_interface(struct vty *, const char *, const char *);
|
||||||
int ldp_vty_show_capabilities(struct vty *, int);
|
int ldp_vty_show_capabilities(struct vty *, const char *);
|
||||||
int ldp_vty_show_neighbor(struct vty *, int, int, int);
|
int ldp_vty_show_neighbor(struct vty *, int, const char *, const char *);
|
||||||
int ldp_vty_show_atom_binding(struct vty *, int);
|
int ldp_vty_show_atom_binding(struct vty *, const char *);
|
||||||
int ldp_vty_show_atom_vc(struct vty *, int);
|
int ldp_vty_show_atom_vc(struct vty *, const char *);
|
||||||
int ldp_vty_show_debugging(struct vty *);
|
int ldp_vty_show_debugging(struct vty *);
|
||||||
|
|
||||||
void ldp_vty_init(void);
|
void ldp_vty_init(void);
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -233,7 +233,7 @@ ldp_af_config_write(struct vty *vty, int af, struct ldpd_conf *conf,
|
|||||||
|
|
||||||
ldp_af_iface_config_write(vty, af);
|
ldp_af_iface_config_write(vty, af);
|
||||||
|
|
||||||
vty_out (vty, " !\n");
|
vty_out(vty, " exit-address-family\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -407,9 +407,9 @@ ldp_iface_is_configured(struct ldpd_conf *xconf, const char *ifname)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
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;
|
vty_conf->flags &= ~F_LDPD_ENABLED;
|
||||||
else {
|
else {
|
||||||
vty->node = LDP_NODE;
|
vty->node = LDP_NODE;
|
||||||
@ -422,7 +422,7 @@ ldp_vty_mpls_ldp(struct vty *vty, int disable)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
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;
|
struct ldpd_af_conf *af_conf;
|
||||||
int af;
|
int af;
|
||||||
@ -436,7 +436,7 @@ ldp_vty_address_family(struct vty *vty, int disable, const char *af_str)
|
|||||||
} else
|
} else
|
||||||
return (CMD_WARNING_CONFIG_FAILED);
|
return (CMD_WARNING_CONFIG_FAILED);
|
||||||
|
|
||||||
if (disable) {
|
if (negate) {
|
||||||
af_conf->flags &= ~F_LDPD_AF_ENABLED;
|
af_conf->flags &= ~F_LDPD_AF_ENABLED;
|
||||||
ldp_config_apply(vty, vty_conf);
|
ldp_config_apply(vty, vty_conf);
|
||||||
return (CMD_SUCCESS);
|
return (CMD_SUCCESS);
|
||||||
@ -460,23 +460,15 @@ ldp_vty_address_family(struct vty *vty, int disable, const char *af_str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ldp_vty_disc_holdtime(struct vty *vty, int disable, const char *hello_type_str,
|
ldp_vty_disc_holdtime(struct vty *vty, const char *negate,
|
||||||
const char *seconds_str)
|
const char *hello_type_str, long secs)
|
||||||
{
|
{
|
||||||
struct ldpd_af_conf *af_conf;
|
struct ldpd_af_conf *af_conf;
|
||||||
struct iface *iface;
|
struct iface *iface;
|
||||||
struct iface_af *ia;
|
struct iface_af *ia;
|
||||||
int af;
|
int af;
|
||||||
char *ep;
|
|
||||||
long int secs;
|
|
||||||
enum hello_type hello_type;
|
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')
|
if (hello_type_str[0] == 'h')
|
||||||
hello_type = HELLO_LINK;
|
hello_type = HELLO_LINK;
|
||||||
else
|
else
|
||||||
@ -484,7 +476,7 @@ ldp_vty_disc_holdtime(struct vty *vty, int disable, const char *hello_type_str,
|
|||||||
|
|
||||||
switch (vty->node) {
|
switch (vty->node) {
|
||||||
case LDP_NODE:
|
case LDP_NODE:
|
||||||
if (disable) {
|
if (negate) {
|
||||||
switch (hello_type) {
|
switch (hello_type) {
|
||||||
case HELLO_LINK:
|
case HELLO_LINK:
|
||||||
vty_conf->lhello_holdtime = LINK_DFLT_HOLDTIME;
|
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 = ldp_vty_get_af(vty);
|
||||||
af_conf = ldp_af_conf_get(vty_conf, af);
|
af_conf = ldp_af_conf_get(vty_conf, af);
|
||||||
|
|
||||||
if (disable) {
|
if (negate) {
|
||||||
switch (hello_type) {
|
switch (hello_type) {
|
||||||
case HELLO_LINK:
|
case HELLO_LINK:
|
||||||
af_conf->lhello_holdtime = 0;
|
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);
|
VTY_CHECK_CONTEXT(iface);
|
||||||
|
|
||||||
ia = iface_af_get(iface, af);
|
ia = iface_af_get(iface, af);
|
||||||
if (disable)
|
if (negate)
|
||||||
ia->hello_holdtime = 0;
|
ia->hello_holdtime = 0;
|
||||||
else
|
else
|
||||||
ia->hello_holdtime = secs;
|
ia->hello_holdtime = secs;
|
||||||
@ -554,24 +546,15 @@ ldp_vty_disc_holdtime(struct vty *vty, int disable, const char *hello_type_str,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ldp_vty_disc_interval(struct vty *vty, int disable, const char *hello_type_str,
|
ldp_vty_disc_interval(struct vty *vty, const char *negate,
|
||||||
const char *seconds_str)
|
const char *hello_type_str, long secs)
|
||||||
{
|
{
|
||||||
struct ldpd_af_conf *af_conf;
|
struct ldpd_af_conf *af_conf;
|
||||||
struct iface *iface;
|
struct iface *iface;
|
||||||
struct iface_af *ia;
|
struct iface_af *ia;
|
||||||
int af;
|
int af;
|
||||||
char *ep;
|
|
||||||
long int secs;
|
|
||||||
enum hello_type hello_type;
|
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')
|
if (hello_type_str[0] == 'h')
|
||||||
hello_type = HELLO_LINK;
|
hello_type = HELLO_LINK;
|
||||||
else
|
else
|
||||||
@ -579,14 +562,15 @@ ldp_vty_disc_interval(struct vty *vty, int disable, const char *hello_type_str,
|
|||||||
|
|
||||||
switch (vty->node) {
|
switch (vty->node) {
|
||||||
case LDP_NODE:
|
case LDP_NODE:
|
||||||
if (disable) {
|
if (negate) {
|
||||||
switch (hello_type) {
|
switch (hello_type) {
|
||||||
case HELLO_LINK:
|
case HELLO_LINK:
|
||||||
vty_conf->lhello_interval = LINK_DFLT_HOLDTIME;
|
vty_conf->lhello_interval =
|
||||||
|
DEFAULT_HELLO_INTERVAL;
|
||||||
break;
|
break;
|
||||||
case HELLO_TARGETED:
|
case HELLO_TARGETED:
|
||||||
vty_conf->thello_interval =
|
vty_conf->thello_interval =
|
||||||
TARGETED_DFLT_HOLDTIME;
|
DEFAULT_HELLO_INTERVAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} 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 = ldp_vty_get_af(vty);
|
||||||
af_conf = ldp_af_conf_get(vty_conf, af);
|
af_conf = ldp_af_conf_get(vty_conf, af);
|
||||||
|
|
||||||
if (disable) {
|
if (negate) {
|
||||||
switch (hello_type) {
|
switch (hello_type) {
|
||||||
case HELLO_LINK:
|
case HELLO_LINK:
|
||||||
af_conf->lhello_interval = 0;
|
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);
|
VTY_CHECK_CONTEXT(iface);
|
||||||
|
|
||||||
ia = iface_af_get(iface, af);
|
ia = iface_af_get(iface, af);
|
||||||
if (disable)
|
if (negate)
|
||||||
ia->hello_interval = 0;
|
ia->hello_interval = 0;
|
||||||
else
|
else
|
||||||
ia->hello_interval = secs;
|
ia->hello_interval = secs;
|
||||||
@ -649,7 +633,7 @@ ldp_vty_disc_interval(struct vty *vty, int disable, const char *hello_type_str,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
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)
|
const char *acl_from_str)
|
||||||
{
|
{
|
||||||
struct ldpd_af_conf *af_conf;
|
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 = ldp_vty_get_af(vty);
|
||||||
af_conf = ldp_af_conf_get(vty_conf, af);
|
af_conf = ldp_af_conf_get(vty_conf, af);
|
||||||
|
|
||||||
if (disable) {
|
if (negate) {
|
||||||
af_conf->flags &= ~F_LDPD_AF_THELLO_ACCEPT;
|
af_conf->flags &= ~F_LDPD_AF_THELLO_ACCEPT;
|
||||||
af_conf->acl_thello_accept_from[0] = '\0';
|
af_conf->acl_thello_accept_from[0] = '\0';
|
||||||
} else {
|
} else {
|
||||||
@ -676,29 +660,19 @@ ldp_vty_targeted_hello_accept(struct vty *vty, int disable,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ldp_vty_nbr_session_holdtime(struct vty *vty, int disable,
|
ldp_vty_nbr_session_holdtime(struct vty *vty, const char *negate,
|
||||||
const char *lsr_id_str, const char *seconds_str)
|
struct in_addr lsr_id, long secs)
|
||||||
{
|
{
|
||||||
char *ep;
|
|
||||||
long int secs;
|
|
||||||
struct in_addr lsr_id;
|
|
||||||
struct nbr_params *nbrp;
|
struct nbr_params *nbrp;
|
||||||
|
|
||||||
if (inet_pton(AF_INET, lsr_id_str, &lsr_id) != 1 ||
|
if (bad_addr_v4(lsr_id)) {
|
||||||
bad_addr_v4(lsr_id)) {
|
|
||||||
vty_out (vty, "%% Malformed address\n");
|
vty_out (vty, "%% Malformed address\n");
|
||||||
return (CMD_WARNING_CONFIG_FAILED);
|
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);
|
nbrp = nbr_params_find(vty_conf, lsr_id);
|
||||||
|
|
||||||
if (disable) {
|
if (negate) {
|
||||||
if (nbrp == NULL)
|
if (nbrp == NULL)
|
||||||
return (CMD_SUCCESS);
|
return (CMD_SUCCESS);
|
||||||
|
|
||||||
@ -722,24 +696,15 @@ ldp_vty_nbr_session_holdtime(struct vty *vty, int disable,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ldp_vty_af_session_holdtime(struct vty *vty, int disable,
|
ldp_vty_af_session_holdtime(struct vty *vty, const char *negate, long secs)
|
||||||
const char *seconds_str)
|
|
||||||
{
|
{
|
||||||
struct ldpd_af_conf *af_conf;
|
struct ldpd_af_conf *af_conf;
|
||||||
int af;
|
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 = ldp_vty_get_af(vty);
|
||||||
af_conf = ldp_af_conf_get(vty_conf, af);
|
af_conf = ldp_af_conf_get(vty_conf, af);
|
||||||
|
|
||||||
if (disable)
|
if (negate)
|
||||||
af_conf->keepalive = DEFAULT_KEEPALIVE;
|
af_conf->keepalive = DEFAULT_KEEPALIVE;
|
||||||
else
|
else
|
||||||
af_conf->keepalive = secs;
|
af_conf->keepalive = secs;
|
||||||
@ -750,7 +715,7 @@ ldp_vty_af_session_holdtime(struct vty *vty, int disable,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
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;
|
int af;
|
||||||
struct iface *iface;
|
struct iface *iface;
|
||||||
@ -759,7 +724,7 @@ ldp_vty_interface(struct vty *vty, int disable, const char *ifname)
|
|||||||
af = ldp_vty_get_af(vty);
|
af = ldp_vty_get_af(vty);
|
||||||
iface = if_lookup_name(vty_conf, ifname);
|
iface = if_lookup_name(vty_conf, ifname);
|
||||||
|
|
||||||
if (disable) {
|
if (negate) {
|
||||||
if (iface == NULL)
|
if (iface == NULL)
|
||||||
return (CMD_SUCCESS);
|
return (CMD_SUCCESS);
|
||||||
|
|
||||||
@ -812,7 +777,7 @@ ldp_vty_interface(struct vty *vty, int disable, const char *ifname)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
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;
|
struct ldpd_af_conf *af_conf;
|
||||||
int af;
|
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 = ldp_vty_get_af(vty);
|
||||||
af_conf = ldp_af_conf_get(vty_conf, af);
|
af_conf = ldp_af_conf_get(vty_conf, af);
|
||||||
|
|
||||||
if (disable)
|
if (negate)
|
||||||
memset(&af_conf->trans_addr, 0, sizeof(af_conf->trans_addr));
|
memset(&af_conf->trans_addr, 0, sizeof(af_conf->trans_addr));
|
||||||
else {
|
else {
|
||||||
if (inet_pton(af, addr_str, &af_conf->trans_addr) != 1 ||
|
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
|
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;
|
int af;
|
||||||
union ldpd_addr addr;
|
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);
|
tnbr = tnbr_find(vty_conf, af, &addr);
|
||||||
|
|
||||||
if (disable) {
|
if (negate) {
|
||||||
if (tnbr == NULL)
|
if (tnbr == NULL)
|
||||||
return (CMD_SUCCESS);
|
return (CMD_SUCCESS);
|
||||||
|
|
||||||
@ -883,7 +848,7 @@ ldp_vty_neighbor_targeted(struct vty *vty, int disable, const char *addr_str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
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)
|
const char *acl_for_str)
|
||||||
{
|
{
|
||||||
struct ldpd_af_conf *af_conf;
|
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 = ldp_vty_get_af(vty);
|
||||||
af_conf = ldp_af_conf_get(vty_conf, af);
|
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_to[0] = '\0';
|
||||||
af_conf->acl_label_advertise_for[0] = '\0';
|
af_conf->acl_label_advertise_for[0] = '\0';
|
||||||
} else {
|
} else {
|
||||||
@ -914,7 +879,7 @@ ldp_vty_label_advertise(struct vty *vty, int disable, const char *acl_to_str,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
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)
|
const char *acl_for_str)
|
||||||
{
|
{
|
||||||
struct ldpd_af_conf *af_conf;
|
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->flags &= ~F_LDPD_AF_ALLOCHOSTONLY;
|
||||||
af_conf->acl_label_allocate_for[0] = '\0';
|
af_conf->acl_label_allocate_for[0] = '\0';
|
||||||
if (!disable) {
|
if (!negate) {
|
||||||
if (host_routes)
|
if (host_routes)
|
||||||
af_conf->flags |= F_LDPD_AF_ALLOCHOSTONLY;
|
af_conf->flags |= F_LDPD_AF_ALLOCHOSTONLY;
|
||||||
else
|
else
|
||||||
@ -939,7 +904,7 @@ ldp_vty_label_allocate(struct vty *vty, int disable, int host_routes,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
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;
|
struct ldpd_af_conf *af_conf;
|
||||||
int af;
|
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 = ldp_vty_get_af(vty);
|
||||||
af_conf = ldp_af_conf_get(vty_conf, af);
|
af_conf = ldp_af_conf_get(vty_conf, af);
|
||||||
|
|
||||||
if (disable) {
|
if (negate) {
|
||||||
af_conf->flags &= ~F_LDPD_AF_EXPNULL;
|
af_conf->flags &= ~F_LDPD_AF_EXPNULL;
|
||||||
af_conf->acl_label_expnull_for[0] = '\0';
|
af_conf->acl_label_expnull_for[0] = '\0';
|
||||||
} else {
|
} else {
|
||||||
@ -965,7 +930,7 @@ ldp_vty_label_expnull(struct vty *vty, int disable, const char *acl_for_str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
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)
|
const char *acl_for_str)
|
||||||
{
|
{
|
||||||
struct ldpd_af_conf *af_conf;
|
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 = ldp_vty_get_af(vty);
|
||||||
af_conf = ldp_af_conf_get(vty_conf, af);
|
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_from[0] = '\0';
|
||||||
af_conf->acl_label_accept_for[0] = '\0';
|
af_conf->acl_label_accept_for[0] = '\0';
|
||||||
} else {
|
} else {
|
||||||
@ -996,7 +961,7 @@ ldp_vty_label_accept(struct vty *vty, int disable, const char *acl_from_str,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
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;
|
struct ldpd_af_conf *af_conf;
|
||||||
int af;
|
int af;
|
||||||
@ -1004,7 +969,7 @@ ldp_vty_ttl_security(struct vty *vty, int disable)
|
|||||||
af = ldp_vty_get_af(vty);
|
af = ldp_vty_get_af(vty);
|
||||||
af_conf = ldp_af_conf_get(vty_conf, af);
|
af_conf = ldp_af_conf_get(vty_conf, af);
|
||||||
|
|
||||||
if (disable)
|
if (negate)
|
||||||
af_conf->flags &= ~F_LDPD_AF_NO_GTSM;
|
af_conf->flags &= ~F_LDPD_AF_NO_GTSM;
|
||||||
else
|
else
|
||||||
af_conf->flags |= F_LDPD_AF_NO_GTSM;
|
af_conf->flags |= F_LDPD_AF_NO_GTSM;
|
||||||
@ -1015,16 +980,16 @@ ldp_vty_ttl_security(struct vty *vty, int disable)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
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;
|
vty_conf->rtr_id.s_addr = INADDR_ANY;
|
||||||
else {
|
else {
|
||||||
if (inet_pton(AF_INET, addr_str, &vty_conf->rtr_id) != 1 ||
|
if (bad_addr_v4(address)) {
|
||||||
bad_addr_v4(vty_conf->rtr_id)) {
|
|
||||||
vty_out (vty, "%% Malformed address\n");
|
vty_out (vty, "%% Malformed address\n");
|
||||||
return (CMD_SUCCESS);
|
return (CMD_SUCCESS);
|
||||||
}
|
}
|
||||||
|
vty_conf->rtr_id = address;
|
||||||
}
|
}
|
||||||
|
|
||||||
ldp_config_apply(vty, vty_conf);
|
ldp_config_apply(vty, vty_conf);
|
||||||
@ -1033,9 +998,9 @@ ldp_vty_router_id(struct vty *vty, int disable, const char *addr_str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
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;
|
vty_conf->flags &= ~F_LDPD_DS_CISCO_INTEROP;
|
||||||
else
|
else
|
||||||
vty_conf->flags |= F_LDPD_DS_CISCO_INTEROP;
|
vty_conf->flags |= F_LDPD_DS_CISCO_INTEROP;
|
||||||
@ -1046,9 +1011,9 @@ ldp_vty_ds_cisco_interop(struct vty *vty, int disable)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
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;
|
vty_conf->trans_pref = DUAL_STACK_LDPOV6;
|
||||||
else
|
else
|
||||||
vty_conf->trans_pref = DUAL_STACK_LDPOV4;
|
vty_conf->trans_pref = DUAL_STACK_LDPOV4;
|
||||||
@ -1059,22 +1024,20 @@ ldp_vty_trans_pref_ipv4(struct vty *vty, int disable)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
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)
|
const char *password_str)
|
||||||
{
|
{
|
||||||
struct in_addr lsr_id;
|
|
||||||
size_t password_len;
|
size_t password_len;
|
||||||
struct nbr_params *nbrp;
|
struct nbr_params *nbrp;
|
||||||
|
|
||||||
if (inet_pton(AF_INET, lsr_id_str, &lsr_id) != 1 ||
|
if (bad_addr_v4(lsr_id)) {
|
||||||
bad_addr_v4(lsr_id)) {
|
|
||||||
vty_out (vty, "%% Malformed address\n");
|
vty_out (vty, "%% Malformed address\n");
|
||||||
return (CMD_WARNING_CONFIG_FAILED);
|
return (CMD_WARNING_CONFIG_FAILED);
|
||||||
}
|
}
|
||||||
|
|
||||||
nbrp = nbr_params_find(vty_conf, lsr_id);
|
nbrp = nbr_params_find(vty_conf, lsr_id);
|
||||||
|
|
||||||
if (disable) {
|
if (negate) {
|
||||||
if (nbrp == NULL)
|
if (nbrp == NULL)
|
||||||
return (CMD_SUCCESS);
|
return (CMD_SUCCESS);
|
||||||
|
|
||||||
@ -1104,16 +1067,14 @@ ldp_vty_neighbor_password(struct vty *vty, int disable, const char *lsr_id_str,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ldp_vty_neighbor_ttl_security(struct vty *vty, int disable,
|
ldp_vty_neighbor_ttl_security(struct vty *vty, const char *negate,
|
||||||
const char *lsr_id_str, const char *hops_str)
|
struct in_addr lsr_id, const char *hops_str)
|
||||||
{
|
{
|
||||||
struct in_addr lsr_id;
|
|
||||||
struct nbr_params *nbrp;
|
struct nbr_params *nbrp;
|
||||||
long int hops = 0;
|
long int hops = 0;
|
||||||
char *ep;
|
char *ep;
|
||||||
|
|
||||||
if (inet_pton(AF_INET, lsr_id_str, &lsr_id) != 1 ||
|
if (bad_addr_v4(lsr_id)) {
|
||||||
bad_addr_v4(lsr_id)) {
|
|
||||||
vty_out (vty, "%% Malformed address\n");
|
vty_out (vty, "%% Malformed address\n");
|
||||||
return (CMD_WARNING_CONFIG_FAILED);
|
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);
|
nbrp = nbr_params_find(vty_conf, lsr_id);
|
||||||
|
|
||||||
if (disable) {
|
if (negate) {
|
||||||
if (nbrp == NULL)
|
if (nbrp == NULL)
|
||||||
return (CMD_SUCCESS);
|
return (CMD_SUCCESS);
|
||||||
|
|
||||||
@ -1158,7 +1119,7 @@ ldp_vty_neighbor_ttl_security(struct vty *vty, int disable,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
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 *l2vpn;
|
||||||
struct l2vpn_if *lif;
|
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);
|
l2vpn = l2vpn_find(vty_conf, name_str);
|
||||||
|
|
||||||
if (disable) {
|
if (negate) {
|
||||||
if (l2vpn == NULL)
|
if (l2vpn == NULL)
|
||||||
return (CMD_SUCCESS);
|
return (CMD_SUCCESS);
|
||||||
|
|
||||||
@ -1203,11 +1164,11 @@ ldp_vty_l2vpn(struct vty *vty, int disable, const char *name_str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
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);
|
VTY_DECLVAR_CONTEXT(l2vpn, l2vpn);
|
||||||
|
|
||||||
if (disable)
|
if (negate)
|
||||||
memset(l2vpn->br_ifname, 0, sizeof(l2vpn->br_ifname));
|
memset(l2vpn->br_ifname, 0, sizeof(l2vpn->br_ifname));
|
||||||
else
|
else
|
||||||
strlcpy(l2vpn->br_ifname, ifname, sizeof(l2vpn->br_ifname));
|
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
|
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);
|
VTY_DECLVAR_CONTEXT(l2vpn, l2vpn);
|
||||||
char *ep;
|
|
||||||
int mtu;
|
|
||||||
|
|
||||||
mtu = strtol(mtu_str, &ep, 10);
|
if (negate)
|
||||||
if (*ep != '\0' || mtu < MIN_L2VPN_MTU || mtu > MAX_L2VPN_MTU) {
|
|
||||||
vty_out (vty, "%% Invalid MTU\n");
|
|
||||||
return (CMD_WARNING_CONFIG_FAILED);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (disable)
|
|
||||||
l2vpn->mtu = DEFAULT_L2VPN_MTU;
|
l2vpn->mtu = DEFAULT_L2VPN_MTU;
|
||||||
else
|
else
|
||||||
l2vpn->mtu = mtu;
|
l2vpn->mtu = mtu;
|
||||||
@ -1241,7 +1194,7 @@ ldp_vty_l2vpn_mtu(struct vty *vty, int disable, const char *mtu_str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
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);
|
VTY_DECLVAR_CONTEXT(l2vpn, l2vpn);
|
||||||
int pw_type;
|
int pw_type;
|
||||||
@ -1251,7 +1204,7 @@ ldp_vty_l2vpn_pwtype(struct vty *vty, int disable, const char *type_str)
|
|||||||
else
|
else
|
||||||
pw_type = PW_TYPE_ETHERNET_TAGGED;
|
pw_type = PW_TYPE_ETHERNET_TAGGED;
|
||||||
|
|
||||||
if (disable)
|
if (negate)
|
||||||
l2vpn->pw_type = DEFAULT_PW_TYPE;
|
l2vpn->pw_type = DEFAULT_PW_TYPE;
|
||||||
else
|
else
|
||||||
l2vpn->pw_type = pw_type;
|
l2vpn->pw_type = pw_type;
|
||||||
@ -1262,14 +1215,14 @@ ldp_vty_l2vpn_pwtype(struct vty *vty, int disable, const char *type_str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
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);
|
VTY_DECLVAR_CONTEXT(l2vpn, l2vpn);
|
||||||
struct l2vpn_if *lif;
|
struct l2vpn_if *lif;
|
||||||
|
|
||||||
lif = l2vpn_if_find(l2vpn, ifname);
|
lif = l2vpn_if_find(l2vpn, ifname);
|
||||||
|
|
||||||
if (disable) {
|
if (negate) {
|
||||||
if (lif == NULL)
|
if (lif == NULL)
|
||||||
return (CMD_SUCCESS);
|
return (CMD_SUCCESS);
|
||||||
|
|
||||||
@ -1300,14 +1253,14 @@ ldp_vty_l2vpn_interface(struct vty *vty, int disable, const char *ifname)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
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);
|
VTY_DECLVAR_CONTEXT(l2vpn, l2vpn);
|
||||||
struct l2vpn_pw *pw;
|
struct l2vpn_pw *pw;
|
||||||
|
|
||||||
pw = l2vpn_pw_find(l2vpn, ifname);
|
pw = l2vpn_pw_find(l2vpn, ifname);
|
||||||
|
|
||||||
if (disable) {
|
if (negate) {
|
||||||
if (pw == NULL)
|
if (pw == NULL)
|
||||||
return (CMD_SUCCESS);
|
return (CMD_SUCCESS);
|
||||||
|
|
||||||
@ -1346,11 +1299,11 @@ ldp_vty_l2vpn_pseudowire(struct vty *vty, int disable, const char *ifname)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
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);
|
VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw, pw);
|
||||||
|
|
||||||
if (disable)
|
if (negate)
|
||||||
pw->flags |= F_PW_CWORD_CONF;
|
pw->flags |= F_PW_CWORD_CONF;
|
||||||
else {
|
else {
|
||||||
if (preference_str[0] == 'e')
|
if (preference_str[0] == 'e')
|
||||||
@ -1365,7 +1318,7 @@ ldp_vty_l2vpn_pw_cword(struct vty *vty, int disable, const char *preference_str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
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);
|
VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw, pw);
|
||||||
int af;
|
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);
|
return (CMD_WARNING_CONFIG_FAILED);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (disable) {
|
if (negate) {
|
||||||
pw->af = AF_UNSPEC;
|
pw->af = AF_UNSPEC;
|
||||||
memset(&pw->addr, 0, sizeof(pw->addr));
|
memset(&pw->addr, 0, sizeof(pw->addr));
|
||||||
pw->flags &= ~F_PW_STATIC_NBR_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
|
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);
|
VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw, pw);
|
||||||
struct in_addr lsr_id;
|
|
||||||
|
|
||||||
if (inet_pton(AF_INET, lsr_id_str, &lsr_id) != 1 ||
|
if (bad_addr_v4(lsr_id)) {
|
||||||
bad_addr_v4(lsr_id)) {
|
|
||||||
vty_out (vty, "%% Malformed address\n");
|
vty_out (vty, "%% Malformed address\n");
|
||||||
return (CMD_WARNING_CONFIG_FAILED);
|
return (CMD_WARNING_CONFIG_FAILED);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (disable)
|
if (negate)
|
||||||
pw->lsr_id.s_addr = INADDR_ANY;
|
pw->lsr_id.s_addr = INADDR_ANY;
|
||||||
else
|
else
|
||||||
pw->lsr_id = lsr_id;
|
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
|
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);
|
VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw, pw);
|
||||||
char *ep;
|
|
||||||
uint32_t pwid;
|
|
||||||
|
|
||||||
pwid = strtol(pwid_str, &ep, 10);
|
if (negate)
|
||||||
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)
|
|
||||||
pw->pwid = 0;
|
pw->pwid = 0;
|
||||||
else
|
else
|
||||||
pw->pwid = pwid;
|
pw->pwid = pwid;
|
||||||
@ -1438,11 +1381,11 @@ ldp_vty_l2vpn_pw_pwid(struct vty *vty, int disable, const char *pwid_str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
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);
|
VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw, pw);
|
||||||
|
|
||||||
if (disable)
|
if (negate)
|
||||||
pw->flags |= F_PW_STATUSTLV_CONF;
|
pw->flags |= F_PW_STATUSTLV_CONF;
|
||||||
else
|
else
|
||||||
pw->flags &= ~F_PW_STATUSTLV_CONF;
|
pw->flags &= ~F_PW_STATUSTLV_CONF;
|
||||||
|
@ -1565,7 +1565,7 @@ ldp_vty_get_af(const char *str, int *af)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
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 imsgbuf ibuf;
|
||||||
struct show_params params;
|
struct show_params params;
|
||||||
@ -1579,8 +1579,8 @@ ldp_vty_show_binding(struct vty *vty, const char *af_str, int detail, int json)
|
|||||||
|
|
||||||
memset(¶ms, 0, sizeof(params));
|
memset(¶ms, 0, sizeof(params));
|
||||||
params.family = af;
|
params.family = af;
|
||||||
params.detail = detail;
|
params.detail = (detail) ? 1 : 0;
|
||||||
params.json = json;
|
params.json = (json) ? 1 : 0;
|
||||||
|
|
||||||
if (!params.detail && !params.json)
|
if (!params.detail && !params.json)
|
||||||
vty_out (vty, "%-4s %-20s %-15s %-11s %-13s %6s\n", "AF",
|
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
|
int
|
||||||
ldp_vty_show_discovery(struct vty *vty, const char *af_str, int detail,
|
ldp_vty_show_discovery(struct vty *vty, const char *af_str, const char *detail,
|
||||||
int json)
|
const char *json)
|
||||||
{
|
{
|
||||||
struct imsgbuf ibuf;
|
struct imsgbuf ibuf;
|
||||||
struct show_params params;
|
struct show_params params;
|
||||||
@ -1607,8 +1607,8 @@ ldp_vty_show_discovery(struct vty *vty, const char *af_str, int detail,
|
|||||||
|
|
||||||
memset(¶ms, 0, sizeof(params));
|
memset(¶ms, 0, sizeof(params));
|
||||||
params.family = af;
|
params.family = af;
|
||||||
params.detail = detail;
|
params.detail = (detail) ? 1 : 0;
|
||||||
params.json = json;
|
params.json = (json) ? 1 : 0;
|
||||||
|
|
||||||
if (!params.detail && !params.json)
|
if (!params.detail && !params.json)
|
||||||
vty_out (vty, "%-4s %-15s %-8s %-15s %9s\n",
|
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
|
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 imsgbuf ibuf;
|
||||||
struct show_params params;
|
struct show_params params;
|
||||||
@ -1638,7 +1638,7 @@ ldp_vty_show_interface(struct vty *vty, const char *af_str, int json)
|
|||||||
|
|
||||||
memset(¶ms, 0, sizeof(params));
|
memset(¶ms, 0, sizeof(params));
|
||||||
params.family = af;
|
params.family = af;
|
||||||
params.json = json;
|
params.json = (json) ? 1 : 0;
|
||||||
|
|
||||||
/* header */
|
/* header */
|
||||||
if (!params.json) {
|
if (!params.json) {
|
||||||
@ -1652,7 +1652,7 @@ ldp_vty_show_interface(struct vty *vty, const char *af_str, int json)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ldp_vty_show_capabilities(struct vty *vty, int json)
|
ldp_vty_show_capabilities(struct vty *vty, const char *json)
|
||||||
{
|
{
|
||||||
if (json) {
|
if (json) {
|
||||||
json_object *json;
|
json_object *json;
|
||||||
@ -1703,7 +1703,7 @@ ldp_vty_show_capabilities(struct vty *vty, int json)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
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 imsgbuf ibuf;
|
||||||
struct show_params params;
|
struct show_params params;
|
||||||
@ -1713,8 +1713,8 @@ ldp_vty_show_neighbor(struct vty *vty, int capabilities, int detail, int json)
|
|||||||
|
|
||||||
memset(¶ms, 0, sizeof(params));
|
memset(¶ms, 0, sizeof(params));
|
||||||
params.capabilities = capabilities;
|
params.capabilities = capabilities;
|
||||||
params.detail = detail;
|
params.detail = (detail) ? 1 : 0;
|
||||||
params.json = json;
|
params.json = (json) ? 1 : 0;
|
||||||
|
|
||||||
if (params.capabilities)
|
if (params.capabilities)
|
||||||
params.detail = 1;
|
params.detail = 1;
|
||||||
@ -1728,7 +1728,7 @@ ldp_vty_show_neighbor(struct vty *vty, int capabilities, int detail, int json)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
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 imsgbuf ibuf;
|
||||||
struct show_params params;
|
struct show_params params;
|
||||||
@ -1737,14 +1737,14 @@ ldp_vty_show_atom_binding(struct vty *vty, int json)
|
|||||||
return (CMD_WARNING);
|
return (CMD_WARNING);
|
||||||
|
|
||||||
memset(¶ms, 0, sizeof(params));
|
memset(¶ms, 0, sizeof(params));
|
||||||
params.json = json;
|
params.json = (json) ? 1 : 0;
|
||||||
|
|
||||||
imsg_compose(&ibuf, IMSG_CTL_SHOW_L2VPN_BINDING, 0, 0, -1, NULL, 0);
|
imsg_compose(&ibuf, IMSG_CTL_SHOW_L2VPN_BINDING, 0, 0, -1, NULL, 0);
|
||||||
return (ldp_vty_dispatch(vty, &ibuf, SHOW_L2VPN_BINDING, ¶ms));
|
return (ldp_vty_dispatch(vty, &ibuf, SHOW_L2VPN_BINDING, ¶ms));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
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 imsgbuf ibuf;
|
||||||
struct show_params params;
|
struct show_params params;
|
||||||
@ -1753,7 +1753,7 @@ ldp_vty_show_atom_vc(struct vty *vty, int json)
|
|||||||
return (CMD_WARNING);
|
return (CMD_WARNING);
|
||||||
|
|
||||||
memset(¶ms, 0, sizeof(params));
|
memset(¶ms, 0, sizeof(params));
|
||||||
params.json = json;
|
params.json = (json) ? 1 : 0;
|
||||||
|
|
||||||
if (!params.json) {
|
if (!params.json) {
|
||||||
/* header */
|
/* header */
|
||||||
|
2
lib/.gitignore
vendored
2
lib/.gitignore
vendored
@ -1,4 +1,4 @@
|
|||||||
Makefile
|
!Makefile
|
||||||
Makefile.in
|
Makefile.in
|
||||||
*.o
|
*.o
|
||||||
*.lo
|
*.lo
|
||||||
|
10
lib/Makefile
Normal file
10
lib/Makefile
Normal 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:
|
155
lib/Makefile.am
155
lib/Makefile.am
@ -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
|
|
111
lib/command.c
111
lib/command.c
@ -47,6 +47,74 @@ DEFINE_MTYPE(LIB, HOST, "Host config")
|
|||||||
DEFINE_MTYPE(LIB, STRVEC, "String vector")
|
DEFINE_MTYPE(LIB, STRVEC, "String vector")
|
||||||
DEFINE_MTYPE(LIB, COMPLETION, "Completion item")
|
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
|
/* Command vector which includes some level of command lists. Normally
|
||||||
each daemon maintains each own cmdvec. */
|
each daemon maintains each own cmdvec. */
|
||||||
vector cmdvec = NULL;
|
vector cmdvec = NULL;
|
||||||
@ -2355,6 +2423,35 @@ DEFUN (no_banner_motd,
|
|||||||
return CMD_SUCCESS;
|
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 */
|
/* Set config filename. Called from vty.c */
|
||||||
void host_config_set(const char *filename)
|
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_end_cmd);
|
||||||
install_element(node, &config_help_cmd);
|
install_element(node, &config_help_cmd);
|
||||||
install_element(node, &config_list_cmd);
|
install_element(node, &config_list_cmd);
|
||||||
|
install_element(node, &find_cmd);
|
||||||
|
|
||||||
install_element(node, &config_write_cmd);
|
install_element(node, &config_write_cmd);
|
||||||
install_element(node, &show_running_config_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 */
|
* terminal = -1 -- watchfrr / no logging, but minimal config control */
|
||||||
void cmd_init(int terminal)
|
void cmd_init(int terminal)
|
||||||
{
|
{
|
||||||
|
if (array_size(node_names) != NODE_TYPE_MAX)
|
||||||
|
assert(!"Update the CLI node description array!");
|
||||||
|
|
||||||
qobj_init();
|
qobj_init();
|
||||||
|
|
||||||
varhandlers = list_new();
|
varhandlers = list_new();
|
||||||
@ -2416,6 +2517,8 @@ void cmd_init(int terminal)
|
|||||||
|
|
||||||
/* Each node's basic commands. */
|
/* Each node's basic commands. */
|
||||||
install_element(VIEW_NODE, &show_version_cmd);
|
install_element(VIEW_NODE, &show_version_cmd);
|
||||||
|
install_element(ENABLE_NODE, &show_startup_config_cmd);
|
||||||
|
|
||||||
if (terminal) {
|
if (terminal) {
|
||||||
install_element(VIEW_NODE, &config_list_cmd);
|
install_element(VIEW_NODE, &config_list_cmd);
|
||||||
install_element(VIEW_NODE, &config_exit_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, &show_commandtree_cmd);
|
||||||
install_element(VIEW_NODE, &echo_cmd);
|
install_element(VIEW_NODE, &echo_cmd);
|
||||||
install_element(VIEW_NODE, &autocomplete_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_end_cmd);
|
||||||
install_element(ENABLE_NODE, &config_disable_cmd);
|
install_element(ENABLE_NODE, &config_disable_cmd);
|
||||||
install_element(ENABLE_NODE, &config_terminal_cmd);
|
install_element(ENABLE_NODE, &config_terminal_cmd);
|
||||||
install_element(ENABLE_NODE, ©_runningconf_startupconf_cmd);
|
install_element(ENABLE_NODE, ©_runningconf_startupconf_cmd);
|
||||||
install_element(ENABLE_NODE, &config_write_cmd);
|
install_element(ENABLE_NODE, &config_write_cmd);
|
||||||
install_element(ENABLE_NODE, &show_running_config_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_element(ENABLE_NODE, &config_logmsg_cmd);
|
||||||
|
|
||||||
install_default(CONFIG_NODE);
|
install_default(CONFIG_NODE);
|
||||||
|
|
||||||
thread_cmd_init();
|
thread_cmd_init();
|
||||||
|
@ -68,7 +68,7 @@ struct host {
|
|||||||
char *motdfile;
|
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 {
|
enum node_type {
|
||||||
AUTH_NODE, /* Authentication mode of vty interface. */
|
AUTH_NODE, /* Authentication mode of vty interface. */
|
||||||
VIEW_NODE, /* View node. Default mode of vty interface. */
|
VIEW_NODE, /* View node. Default mode of vty interface. */
|
||||||
@ -135,8 +135,12 @@ enum node_type {
|
|||||||
VTY_NODE, /* Vty node. */
|
VTY_NODE, /* Vty node. */
|
||||||
LINK_PARAMS_NODE, /* Link-parameters node */
|
LINK_PARAMS_NODE, /* Link-parameters node */
|
||||||
BGP_EVPN_VNI_NODE, /* BGP EVPN VNI */
|
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
|
/* Node which has some commands and prompt string and configuration
|
||||||
function pointer . */
|
function pointer . */
|
||||||
struct cmd_node {
|
struct cmd_node {
|
||||||
|
@ -49,8 +49,8 @@ RANGE \({NUMBER}[ ]?\-[ ]?{NUMBER}\)
|
|||||||
%option noyywrap
|
%option noyywrap
|
||||||
%option nounput
|
%option nounput
|
||||||
%option noinput
|
%option noinput
|
||||||
%option outfile="command_lex.c"
|
%option outfile="lib/command_lex.c"
|
||||||
%option header-file="command_lex.h"
|
%option header-file="lib/command_lex.h"
|
||||||
%option prefix="cmd_yy"
|
%option prefix="cmd_yy"
|
||||||
%option reentrant
|
%option reentrant
|
||||||
%option bison-bridge
|
%option bison-bridge
|
||||||
|
@ -33,8 +33,8 @@
|
|||||||
/* define api.prefix {cmd_yy} */
|
/* define api.prefix {cmd_yy} */
|
||||||
|
|
||||||
/* names for generated header and parser files */
|
/* names for generated header and parser files */
|
||||||
%defines "command_parse.h"
|
%defines "lib/command_parse.h"
|
||||||
%output "command_parse.c"
|
%output "lib/command_parse.c"
|
||||||
|
|
||||||
/* note: code blocks are output in order, to both .c and .h:
|
/* note: code blocks are output in order, to both .c and .h:
|
||||||
* 1. %code requires
|
* 1. %code requires
|
||||||
|
@ -85,7 +85,7 @@ SPECIAL [(),]
|
|||||||
%option noyywrap
|
%option noyywrap
|
||||||
%option noinput
|
%option noinput
|
||||||
%option nounput
|
%option nounput
|
||||||
%option outfile="defun_lex.c"
|
%option outfile="lib/defun_lex.c"
|
||||||
%option prefix="def_yy"
|
%option prefix="def_yy"
|
||||||
%option 8bit
|
%option 8bit
|
||||||
|
|
||||||
|
25
lib/hash.c
25
lib/hash.c
@ -49,7 +49,6 @@ struct hash *hash_create_size(unsigned int size,
|
|||||||
hash->index =
|
hash->index =
|
||||||
XCALLOC(MTYPE_HASH_INDEX, sizeof(struct hash_backet *) * size);
|
XCALLOC(MTYPE_HASH_INDEX, sizeof(struct hash_backet *) * size);
|
||||||
hash->size = size;
|
hash->size = size;
|
||||||
hash->no_expand = 0;
|
|
||||||
hash->hash_key = hash_key;
|
hash->hash_key = hash_key;
|
||||||
hash->hash_cmp = hash_cmp;
|
hash->hash_cmp = hash_cmp;
|
||||||
hash->count = 0;
|
hash->count = 0;
|
||||||
@ -91,10 +90,14 @@ void *hash_alloc_intern(void *arg)
|
|||||||
/* Expand hash if the chain length exceeds the threshold. */
|
/* Expand hash if the chain length exceeds the threshold. */
|
||||||
static void hash_expand(struct hash *hash)
|
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;
|
struct hash_backet *hb, *hbnext, **new_index;
|
||||||
|
|
||||||
new_size = hash->size * 2;
|
new_size = hash->size * 2;
|
||||||
|
|
||||||
|
if (hash->max_size && new_size > hash->max_size)
|
||||||
|
return;
|
||||||
|
|
||||||
new_index = XCALLOC(MTYPE_HASH_INDEX,
|
new_index = XCALLOC(MTYPE_HASH_INDEX,
|
||||||
sizeof(struct hash_backet *) * new_size);
|
sizeof(struct hash_backet *) * new_size);
|
||||||
if (new_index == NULL)
|
if (new_index == NULL)
|
||||||
@ -128,22 +131,6 @@ static void hash_expand(struct hash *hash)
|
|||||||
XFREE(MTYPE_HASH_INDEX, hash->index);
|
XFREE(MTYPE_HASH_INDEX, hash->index);
|
||||||
hash->size = new_size;
|
hash->size = new_size;
|
||||||
hash->index = new_index;
|
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
|
/* 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)
|
if (newdata == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (len > HASH_THRESHOLD && !hash->no_expand) {
|
if (len > HASH_THRESHOLD) {
|
||||||
hash_expand(hash);
|
hash_expand(hash);
|
||||||
index = key & (hash->size - 1);
|
index = key & (hash->size - 1);
|
||||||
}
|
}
|
||||||
|
@ -64,8 +64,8 @@ struct hash {
|
|||||||
/* Hash table size. Must be power of 2 */
|
/* Hash table size. Must be power of 2 */
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
|
|
||||||
/* If expansion failed. */
|
/* If max_size is 0 there is no limit */
|
||||||
int no_expand;
|
unsigned int max_size;
|
||||||
|
|
||||||
/* Key make function. */
|
/* Key make function. */
|
||||||
unsigned int (*hash_key)(void *);
|
unsigned int (*hash_key)(void *);
|
||||||
|
@ -21,13 +21,14 @@
|
|||||||
#include "openbsd-queue.h"
|
#include "openbsd-queue.h"
|
||||||
#include "imsg.h"
|
#include "imsg.h"
|
||||||
|
|
||||||
int ibuf_realloc(struct ibuf *, size_t);
|
int ibuf_realloc(struct ibuf *, size_t);
|
||||||
void ibuf_enqueue(struct msgbuf *, struct ibuf *);
|
void ibuf_enqueue(struct msgbuf *, struct ibuf *);
|
||||||
void ibuf_dequeue(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)
|
if ((buf = calloc(1, sizeof(struct ibuf))) == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
@ -41,9 +42,10 @@ struct ibuf *ibuf_open(size_t len)
|
|||||||
return (buf);
|
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)
|
if (max < len)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
@ -57,9 +59,10 @@ struct ibuf *ibuf_dynamic(size_t len, size_t max)
|
|||||||
return (buf);
|
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 */
|
/* on static buffers max is eq size and so the following fails */
|
||||||
if (buf->wpos + len > buf->max) {
|
if (buf->wpos + len > buf->max) {
|
||||||
@ -76,7 +79,8 @@ int ibuf_realloc(struct ibuf *buf, size_t len)
|
|||||||
return (0);
|
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 (buf->wpos + len > buf->size)
|
||||||
if (ibuf_realloc(buf, len) == -1)
|
if (ibuf_realloc(buf, len) == -1)
|
||||||
@ -87,9 +91,10 @@ int ibuf_add(struct ibuf *buf, const void *data, size_t len)
|
|||||||
return (0);
|
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 (buf->wpos + len > buf->size)
|
||||||
if (ibuf_realloc(buf, len) == -1)
|
if (ibuf_realloc(buf, len) == -1)
|
||||||
@ -100,7 +105,8 @@ void *ibuf_reserve(struct ibuf *buf, size_t len)
|
|||||||
return (b);
|
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 */
|
/* only allowed to seek in already written parts */
|
||||||
if (pos + len > buf->wpos)
|
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);
|
return (buf->buf + pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ibuf_size(struct ibuf *buf)
|
size_t
|
||||||
|
ibuf_size(struct ibuf *buf)
|
||||||
{
|
{
|
||||||
return (buf->wpos);
|
return (buf->wpos);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ibuf_left(struct ibuf *buf)
|
size_t
|
||||||
|
ibuf_left(struct ibuf *buf)
|
||||||
{
|
{
|
||||||
return (buf->max - buf->wpos);
|
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);
|
ibuf_enqueue(msgbuf, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ibuf_write(struct msgbuf *msgbuf)
|
int
|
||||||
|
ibuf_write(struct msgbuf *msgbuf)
|
||||||
{
|
{
|
||||||
struct iovec iov[IOV_MAX];
|
struct iovec iov[IOV_MAX];
|
||||||
struct ibuf *buf;
|
struct ibuf *buf;
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
ssize_t n;
|
ssize_t n;
|
||||||
|
|
||||||
memset(&iov, 0, sizeof(iov));
|
memset(&iov, 0, sizeof(iov));
|
||||||
TAILQ_FOREACH(buf, &msgbuf->bufs, entry)
|
TAILQ_FOREACH(buf, &msgbuf->bufs, entry) {
|
||||||
{
|
|
||||||
if (i >= IOV_MAX)
|
if (i >= IOV_MAX)
|
||||||
break;
|
break;
|
||||||
iov[i].iov_base = buf->buf + buf->rpos;
|
iov[i].iov_base = buf->buf + buf->rpos;
|
||||||
@ -150,7 +159,7 @@ again:
|
|||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n == 0) { /* connection closed */
|
if (n == 0) { /* connection closed */
|
||||||
errno = 0;
|
errno = 0;
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -160,7 +169,8 @@ again:
|
|||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ibuf_free(struct ibuf *buf)
|
void
|
||||||
|
ibuf_free(struct ibuf *buf)
|
||||||
{
|
{
|
||||||
if (buf == NULL)
|
if (buf == NULL)
|
||||||
return;
|
return;
|
||||||
@ -168,19 +178,21 @@ void ibuf_free(struct ibuf *buf)
|
|||||||
free(buf);
|
free(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void msgbuf_init(struct msgbuf *msgbuf)
|
void
|
||||||
|
msgbuf_init(struct msgbuf *msgbuf)
|
||||||
{
|
{
|
||||||
msgbuf->queued = 0;
|
msgbuf->queued = 0;
|
||||||
msgbuf->fd = -1;
|
msgbuf->fd = -1;
|
||||||
TAILQ_INIT(&msgbuf->bufs);
|
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;
|
for (buf = TAILQ_FIRST(&msgbuf->bufs); buf != NULL && n > 0;
|
||||||
buf = next) {
|
buf = next) {
|
||||||
next = TAILQ_NEXT(buf, entry);
|
next = TAILQ_NEXT(buf, entry);
|
||||||
if (buf->rpos + n >= buf->wpos) {
|
if (buf->rpos + n >= buf->wpos) {
|
||||||
n -= buf->wpos - buf->rpos;
|
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)
|
while ((buf = TAILQ_FIRST(&msgbuf->bufs)) != NULL)
|
||||||
ibuf_dequeue(msgbuf, buf);
|
ibuf_dequeue(msgbuf, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
int msgbuf_write(struct msgbuf *msgbuf)
|
int
|
||||||
|
msgbuf_write(struct msgbuf *msgbuf)
|
||||||
{
|
{
|
||||||
struct iovec iov[IOV_MAX];
|
struct iovec iov[IOV_MAX];
|
||||||
struct ibuf *buf;
|
struct ibuf *buf;
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
ssize_t n;
|
ssize_t n;
|
||||||
struct msghdr msg;
|
struct msghdr msg;
|
||||||
struct cmsghdr *cmsg;
|
struct cmsghdr *cmsg;
|
||||||
union {
|
union {
|
||||||
struct cmsghdr hdr;
|
struct cmsghdr hdr;
|
||||||
char buf[CMSG_SPACE(sizeof(int))];
|
char buf[CMSG_SPACE(sizeof(int))];
|
||||||
} cmsgbuf;
|
} cmsgbuf;
|
||||||
|
|
||||||
memset(&iov, 0, sizeof(iov));
|
memset(&iov, 0, sizeof(iov));
|
||||||
memset(&msg, 0, sizeof(msg));
|
memset(&msg, 0, sizeof(msg));
|
||||||
memset(&cmsgbuf, 0, sizeof(cmsgbuf));
|
memset(&cmsgbuf, 0, sizeof(cmsgbuf));
|
||||||
TAILQ_FOREACH(buf, &msgbuf->bufs, entry)
|
TAILQ_FOREACH(buf, &msgbuf->bufs, entry) {
|
||||||
{
|
|
||||||
if (i >= IOV_MAX)
|
if (i >= IOV_MAX)
|
||||||
break;
|
break;
|
||||||
iov[i].iov_base = buf->buf + buf->rpos;
|
iov[i].iov_base = buf->buf + buf->rpos;
|
||||||
@ -249,7 +262,7 @@ again:
|
|||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n == 0) { /* connection closed */
|
if (n == 0) { /* connection closed */
|
||||||
errno = 0;
|
errno = 0;
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -268,13 +281,15 @@ again:
|
|||||||
return (1);
|
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);
|
TAILQ_INSERT_TAIL(&msgbuf->bufs, buf, entry);
|
||||||
msgbuf->queued++;
|
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);
|
TAILQ_REMOVE(&msgbuf->bufs, buf, entry);
|
||||||
|
|
||||||
|
117
lib/imsg.c
117
lib/imsg.c
@ -21,21 +21,22 @@
|
|||||||
#include "openbsd-queue.h"
|
#include "openbsd-queue.h"
|
||||||
#include "imsg.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__
|
#ifndef __OpenBSD__
|
||||||
/*
|
/*
|
||||||
* The original code calls getdtablecount() which is OpenBSD specific. Use
|
* The original code calls getdtablecount() which is OpenBSD specific. Use
|
||||||
* available_fds() from OpenSMTPD instead.
|
* available_fds() from OpenSMTPD instead.
|
||||||
*/
|
*/
|
||||||
static int available_fds(unsigned int n)
|
static int
|
||||||
|
available_fds(unsigned int n)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
int ret, fds[256];
|
int ret, fds[256];
|
||||||
|
|
||||||
if (n > (sizeof(fds) / sizeof(fds[0])))
|
if (n > (sizeof(fds)/sizeof(fds[0])))
|
||||||
return (1);
|
return (1);
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
@ -58,7 +59,8 @@ static int available_fds(unsigned int n)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void imsg_init(struct imsgbuf *ibuf, int fd)
|
void
|
||||||
|
imsg_init(struct imsgbuf *ibuf, int fd)
|
||||||
{
|
{
|
||||||
msgbuf_init(&ibuf->w);
|
msgbuf_init(&ibuf->w);
|
||||||
memset(&ibuf->r, 0, sizeof(ibuf->r));
|
memset(&ibuf->r, 0, sizeof(ibuf->r));
|
||||||
@ -68,18 +70,19 @@ void imsg_init(struct imsgbuf *ibuf, int fd)
|
|||||||
TAILQ_INIT(&ibuf->fds);
|
TAILQ_INIT(&ibuf->fds);
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t imsg_read(struct imsgbuf *ibuf)
|
ssize_t
|
||||||
|
imsg_read(struct imsgbuf *ibuf)
|
||||||
{
|
{
|
||||||
struct msghdr msg;
|
struct msghdr msg;
|
||||||
struct cmsghdr *cmsg;
|
struct cmsghdr *cmsg;
|
||||||
union {
|
union {
|
||||||
struct cmsghdr hdr;
|
struct cmsghdr hdr;
|
||||||
char buf[CMSG_SPACE(sizeof(int) * 1)];
|
char buf[CMSG_SPACE(sizeof(int) * 1)];
|
||||||
} cmsgbuf;
|
} cmsgbuf;
|
||||||
struct iovec iov;
|
struct iovec iov;
|
||||||
ssize_t n = -1;
|
ssize_t n = -1;
|
||||||
int fd;
|
int fd;
|
||||||
struct imsg_fd *ifd;
|
struct imsg_fd *ifd;
|
||||||
|
|
||||||
memset(&msg, 0, sizeof(msg));
|
memset(&msg, 0, sizeof(msg));
|
||||||
memset(&cmsgbuf, 0, sizeof(cmsgbuf));
|
memset(&cmsgbuf, 0, sizeof(cmsgbuf));
|
||||||
@ -96,14 +99,12 @@ ssize_t imsg_read(struct imsgbuf *ibuf)
|
|||||||
|
|
||||||
again:
|
again:
|
||||||
#ifdef __OpenBSD__
|
#ifdef __OpenBSD__
|
||||||
if (getdtablecount() + imsg_fd_overhead
|
if (getdtablecount() + imsg_fd_overhead +
|
||||||
+ (int)((CMSG_SPACE(sizeof(int)) - CMSG_SPACE(0))
|
(int)((CMSG_SPACE(sizeof(int))-CMSG_SPACE(0))/sizeof(int))
|
||||||
/ sizeof(int))
|
|
||||||
>= getdtablesize()) {
|
>= getdtablesize()) {
|
||||||
#else
|
#else
|
||||||
if (available_fds(imsg_fd_overhead
|
if (available_fds(imsg_fd_overhead +
|
||||||
+ (CMSG_SPACE(sizeof(int)) - CMSG_SPACE(0))
|
(CMSG_SPACE(sizeof(int))-CMSG_SPACE(0))/sizeof(int))) {
|
||||||
/ sizeof(int))) {
|
|
||||||
#endif
|
#endif
|
||||||
errno = EAGAIN;
|
errno = EAGAIN;
|
||||||
free(ifd);
|
free(ifd);
|
||||||
@ -119,9 +120,9 @@ again:
|
|||||||
ibuf->r.wpos += n;
|
ibuf->r.wpos += n;
|
||||||
|
|
||||||
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
|
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
|
||||||
cmsg = CMSG_NXTHDR(&msg, cmsg)) {
|
cmsg = CMSG_NXTHDR(&msg, cmsg)) {
|
||||||
if (cmsg->cmsg_level == SOL_SOCKET
|
if (cmsg->cmsg_level == SOL_SOCKET &&
|
||||||
&& cmsg->cmsg_type == SCM_RIGHTS) {
|
cmsg->cmsg_type == SCM_RIGHTS) {
|
||||||
int i;
|
int i;
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
@ -130,15 +131,14 @@ again:
|
|||||||
* padding rules, our control buffer might contain
|
* padding rules, our control buffer might contain
|
||||||
* more than one fd, and we must close them.
|
* more than one fd, and we must close them.
|
||||||
*/
|
*/
|
||||||
j = ((char *)cmsg + cmsg->cmsg_len
|
j = ((char *)cmsg + cmsg->cmsg_len -
|
||||||
- (char *)CMSG_DATA(cmsg))
|
(char *)CMSG_DATA(cmsg)) / sizeof(int);
|
||||||
/ sizeof(int);
|
|
||||||
for (i = 0; i < j; i++) {
|
for (i = 0; i < j; i++) {
|
||||||
fd = ((int *)CMSG_DATA(cmsg))[i];
|
fd = ((int *)CMSG_DATA(cmsg))[i];
|
||||||
if (ifd != NULL) {
|
if (ifd != NULL) {
|
||||||
ifd->fd = fd;
|
ifd->fd = fd;
|
||||||
TAILQ_INSERT_TAIL(&ibuf->fds, ifd,
|
TAILQ_INSERT_TAIL(&ibuf->fds, ifd,
|
||||||
entry);
|
entry);
|
||||||
ifd = NULL;
|
ifd = NULL;
|
||||||
} else
|
} else
|
||||||
close(fd);
|
close(fd);
|
||||||
@ -152,9 +152,10 @@ fail:
|
|||||||
return (n);
|
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;
|
av = ibuf->r.wpos;
|
||||||
|
|
||||||
@ -162,7 +163,8 @@ ssize_t imsg_get(struct imsgbuf *ibuf, struct imsg *imsg)
|
|||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
memcpy(&imsg->hdr, ibuf->r.buf, sizeof(imsg->hdr));
|
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;
|
errno = ERANGE;
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
@ -181,7 +183,7 @@ ssize_t imsg_get(struct imsgbuf *ibuf, struct imsg *imsg)
|
|||||||
imsg->fd = -1;
|
imsg->fd = -1;
|
||||||
|
|
||||||
if (imsg->data)
|
if (imsg->data)
|
||||||
memcpy(imsg->data, ibuf->r.rptr, datalen);
|
memcpy(imsg->data, ibuf->r.rptr, datalen);
|
||||||
|
|
||||||
if (imsg->hdr.len < av) {
|
if (imsg->hdr.len < av) {
|
||||||
left = av - imsg->hdr.len;
|
left = av - imsg->hdr.len;
|
||||||
@ -193,10 +195,11 @@ ssize_t imsg_get(struct imsgbuf *ibuf, struct imsg *imsg)
|
|||||||
return (datalen + IMSG_HEADER_SIZE);
|
return (datalen + IMSG_HEADER_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
int imsg_compose(struct imsgbuf *ibuf, u_int32_t type, u_int32_t peerid,
|
int
|
||||||
pid_t pid, int fd, const void *data, u_int16_t datalen)
|
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)
|
if ((wbuf = imsg_create(ibuf, type, peerid, pid, datalen)) == NULL)
|
||||||
return (-1);
|
return (-1);
|
||||||
@ -211,11 +214,12 @@ int imsg_compose(struct imsgbuf *ibuf, u_int32_t type, u_int32_t peerid,
|
|||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int imsg_composev(struct imsgbuf *ibuf, u_int32_t type, u_int32_t peerid,
|
int
|
||||||
pid_t pid, int fd, const struct iovec *iov, int iovcnt)
|
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;
|
struct ibuf *wbuf;
|
||||||
int i, datalen = 0;
|
int i, datalen = 0;
|
||||||
|
|
||||||
for (i = 0; i < iovcnt; i++)
|
for (i = 0; i < iovcnt; i++)
|
||||||
datalen += iov[i].iov_len;
|
datalen += iov[i].iov_len;
|
||||||
@ -235,11 +239,12 @@ int imsg_composev(struct imsgbuf *ibuf, u_int32_t type, u_int32_t peerid,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
struct ibuf *imsg_create(struct imsgbuf *ibuf, u_int32_t type, u_int32_t peerid,
|
struct ibuf *
|
||||||
pid_t pid, u_int16_t datalen)
|
imsg_create(struct imsgbuf *ibuf, u_int32_t type, u_int32_t peerid,
|
||||||
|
pid_t pid, u_int16_t datalen)
|
||||||
{
|
{
|
||||||
struct ibuf *wbuf;
|
struct ibuf *wbuf;
|
||||||
struct imsg_hdr hdr;
|
struct imsg_hdr hdr;
|
||||||
|
|
||||||
datalen += IMSG_HEADER_SIZE;
|
datalen += IMSG_HEADER_SIZE;
|
||||||
if (datalen > MAX_IMSGSIZE) {
|
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);
|
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 (datalen)
|
||||||
if (ibuf_add(msg, data, datalen) == -1) {
|
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);
|
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;
|
hdr = (struct imsg_hdr *)msg->buf;
|
||||||
|
|
||||||
@ -286,15 +293,17 @@ void imsg_close(struct imsgbuf *ibuf, struct ibuf *msg)
|
|||||||
ibuf_close(&ibuf->w, msg);
|
ibuf_close(&ibuf->w, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void imsg_free(struct imsg *imsg)
|
void
|
||||||
|
imsg_free(struct imsg *imsg)
|
||||||
{
|
{
|
||||||
free(imsg->data);
|
free(imsg->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
int imsg_get_fd(struct imsgbuf *ibuf)
|
int
|
||||||
|
imsg_get_fd(struct imsgbuf *ibuf)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
struct imsg_fd *ifd;
|
struct imsg_fd *ifd;
|
||||||
|
|
||||||
if ((ifd = TAILQ_FIRST(&ibuf->fds)) == NULL)
|
if ((ifd = TAILQ_FIRST(&ibuf->fds)) == NULL)
|
||||||
return (-1);
|
return (-1);
|
||||||
@ -306,7 +315,8 @@ int imsg_get_fd(struct imsgbuf *ibuf)
|
|||||||
return (fd);
|
return (fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
int imsg_flush(struct imsgbuf *ibuf)
|
int
|
||||||
|
imsg_flush(struct imsgbuf *ibuf)
|
||||||
{
|
{
|
||||||
while (ibuf->w.queued)
|
while (ibuf->w.queued)
|
||||||
if (msgbuf_write(&ibuf->w) <= 0)
|
if (msgbuf_write(&ibuf->w) <= 0)
|
||||||
@ -314,9 +324,10 @@ int imsg_flush(struct imsgbuf *ibuf)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void imsg_clear(struct imsgbuf *ibuf)
|
void
|
||||||
|
imsg_clear(struct imsgbuf *ibuf)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
msgbuf_clear(&ibuf->w);
|
msgbuf_clear(&ibuf->w);
|
||||||
while ((fd = imsg_get_fd(ibuf)) != -1)
|
while ((fd = imsg_get_fd(ibuf)) != -1)
|
||||||
|
110
lib/imsg.h
110
lib/imsg.h
@ -26,87 +26,87 @@
|
|||||||
#define MAX_IMSGSIZE 16384
|
#define MAX_IMSGSIZE 16384
|
||||||
|
|
||||||
struct ibuf {
|
struct ibuf {
|
||||||
TAILQ_ENTRY(ibuf) entry;
|
TAILQ_ENTRY(ibuf) entry;
|
||||||
u_char *buf;
|
u_char *buf;
|
||||||
size_t size;
|
size_t size;
|
||||||
size_t max;
|
size_t max;
|
||||||
size_t wpos;
|
size_t wpos;
|
||||||
size_t rpos;
|
size_t rpos;
|
||||||
int fd;
|
int fd;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct msgbuf {
|
struct msgbuf {
|
||||||
TAILQ_HEAD(, ibuf) bufs;
|
TAILQ_HEAD(, ibuf) bufs;
|
||||||
u_int32_t queued;
|
u_int32_t queued;
|
||||||
int fd;
|
int fd;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ibuf_read {
|
struct ibuf_read {
|
||||||
u_char buf[IBUF_READ_SIZE];
|
u_char buf[IBUF_READ_SIZE];
|
||||||
u_char *rptr;
|
u_char *rptr;
|
||||||
size_t wpos;
|
size_t wpos;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct imsg_fd {
|
struct imsg_fd {
|
||||||
TAILQ_ENTRY(imsg_fd) entry;
|
TAILQ_ENTRY(imsg_fd) entry;
|
||||||
int fd;
|
int fd;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct imsgbuf {
|
struct imsgbuf {
|
||||||
TAILQ_HEAD(, imsg_fd) fds;
|
TAILQ_HEAD(, imsg_fd) fds;
|
||||||
struct ibuf_read r;
|
struct ibuf_read r;
|
||||||
struct msgbuf w;
|
struct msgbuf w;
|
||||||
int fd;
|
int fd;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define IMSGF_HASFD 1
|
#define IMSGF_HASFD 1
|
||||||
|
|
||||||
struct imsg_hdr {
|
struct imsg_hdr {
|
||||||
u_int32_t type;
|
u_int32_t type;
|
||||||
u_int16_t len;
|
u_int16_t len;
|
||||||
u_int16_t flags;
|
u_int16_t flags;
|
||||||
u_int32_t peerid;
|
u_int32_t peerid;
|
||||||
u_int32_t pid;
|
u_int32_t pid;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct imsg {
|
struct imsg {
|
||||||
struct imsg_hdr hdr;
|
struct imsg_hdr hdr;
|
||||||
int fd;
|
int fd;
|
||||||
void *data;
|
void *data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* buffer.c */
|
/* buffer.c */
|
||||||
struct ibuf *ibuf_open(size_t);
|
struct ibuf *ibuf_open(size_t);
|
||||||
struct ibuf *ibuf_dynamic(size_t, size_t);
|
struct ibuf *ibuf_dynamic(size_t, size_t);
|
||||||
int ibuf_add(struct ibuf *, const void *, size_t);
|
int ibuf_add(struct ibuf *, const void *, size_t);
|
||||||
void *ibuf_reserve(struct ibuf *, size_t);
|
void *ibuf_reserve(struct ibuf *, size_t);
|
||||||
void *ibuf_seek(struct ibuf *, size_t, size_t);
|
void *ibuf_seek(struct ibuf *, size_t, size_t);
|
||||||
size_t ibuf_size(struct ibuf *);
|
size_t ibuf_size(struct ibuf *);
|
||||||
size_t ibuf_left(struct ibuf *);
|
size_t ibuf_left(struct ibuf *);
|
||||||
void ibuf_close(struct msgbuf *, struct ibuf *);
|
void ibuf_close(struct msgbuf *, struct ibuf *);
|
||||||
int ibuf_write(struct msgbuf *);
|
int ibuf_write(struct msgbuf *);
|
||||||
void ibuf_free(struct ibuf *);
|
void ibuf_free(struct ibuf *);
|
||||||
void msgbuf_init(struct msgbuf *);
|
void msgbuf_init(struct msgbuf *);
|
||||||
void msgbuf_clear(struct msgbuf *);
|
void msgbuf_clear(struct msgbuf *);
|
||||||
int msgbuf_write(struct msgbuf *);
|
int msgbuf_write(struct msgbuf *);
|
||||||
void msgbuf_drain(struct msgbuf *, size_t);
|
void msgbuf_drain(struct msgbuf *, size_t);
|
||||||
|
|
||||||
/* imsg.c */
|
/* imsg.c */
|
||||||
void imsg_init(struct imsgbuf *, int);
|
void imsg_init(struct imsgbuf *, int);
|
||||||
ssize_t imsg_read(struct imsgbuf *);
|
ssize_t imsg_read(struct imsgbuf *);
|
||||||
ssize_t imsg_get(struct imsgbuf *, struct imsg *);
|
ssize_t imsg_get(struct imsgbuf *, struct imsg *);
|
||||||
int imsg_compose(struct imsgbuf *, u_int32_t, u_int32_t, pid_t, int,
|
int imsg_compose(struct imsgbuf *, u_int32_t, u_int32_t, pid_t,
|
||||||
const void *, u_int16_t);
|
int, const void *, u_int16_t);
|
||||||
int imsg_composev(struct imsgbuf *, u_int32_t, u_int32_t, pid_t, int,
|
int imsg_composev(struct imsgbuf *, u_int32_t, u_int32_t, pid_t,
|
||||||
const struct iovec *, int);
|
int, const struct iovec *, int);
|
||||||
struct ibuf *imsg_create(struct imsgbuf *, u_int32_t, u_int32_t, pid_t,
|
struct ibuf *imsg_create(struct imsgbuf *, u_int32_t, u_int32_t, pid_t,
|
||||||
u_int16_t);
|
u_int16_t);
|
||||||
int imsg_add(struct ibuf *, const void *, u_int16_t);
|
int imsg_add(struct ibuf *, const void *, u_int16_t);
|
||||||
void imsg_close(struct imsgbuf *, struct ibuf *);
|
void imsg_close(struct imsgbuf *, struct ibuf *);
|
||||||
void imsg_free(struct imsg *);
|
void imsg_free(struct imsg *);
|
||||||
int imsg_flush(struct imsgbuf *);
|
int imsg_flush(struct imsgbuf *);
|
||||||
void imsg_clear(struct imsgbuf *);
|
void imsg_clear(struct imsgbuf *);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -133,17 +133,17 @@ void copy_nexthops(struct nexthop **tnh, struct nexthop *nh,
|
|||||||
|
|
||||||
for (nh1 = nh; nh1; nh1 = nh1->next) {
|
for (nh1 = nh; nh1; nh1 = nh1->next) {
|
||||||
nexthop = nexthop_new();
|
nexthop = nexthop_new();
|
||||||
nexthop->ifindex = nh->ifindex;
|
nexthop->ifindex = nh1->ifindex;
|
||||||
nexthop->type = nh->type;
|
nexthop->type = nh1->type;
|
||||||
nexthop->flags = nh->flags;
|
nexthop->flags = nh1->flags;
|
||||||
memcpy(&nexthop->gate, &nh->gate, sizeof(nh->gate));
|
memcpy(&nexthop->gate, &nh1->gate, sizeof(nh1->gate));
|
||||||
memcpy(&nexthop->src, &nh->src, sizeof(nh->src));
|
memcpy(&nexthop->src, &nh1->src, sizeof(nh1->src));
|
||||||
memcpy(&nexthop->rmap_src, &nh->rmap_src, sizeof(nh->rmap_src));
|
memcpy(&nexthop->rmap_src, &nh1->rmap_src, sizeof(nh1->rmap_src));
|
||||||
nexthop->rparent = rparent;
|
nexthop->rparent = rparent;
|
||||||
if (nh->nh_label)
|
if (nh1->nh_label)
|
||||||
nexthop_add_labels(nexthop, nh->nh_label_type,
|
nexthop_add_labels(nexthop, nh1->nh_label_type,
|
||||||
nh->nh_label->num_labels,
|
nh1->nh_label->num_labels,
|
||||||
&nh->nh_label->label[0]);
|
&nh1->nh_label->label[0]);
|
||||||
nexthop_add(tnh, nexthop);
|
nexthop_add(tnh, nexthop);
|
||||||
|
|
||||||
if (CHECK_FLAG(nh1->flags, NEXTHOP_FLAG_RECURSIVE))
|
if (CHECK_FLAG(nh1->flags, NEXTHOP_FLAG_RECURSIVE))
|
||||||
|
@ -45,14 +45,16 @@
|
|||||||
|
|
||||||
#include <lib/openbsd-tree.h>
|
#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;
|
unsigned long addr = (unsigned long)node;
|
||||||
|
|
||||||
return ((struct rb_entry *)(addr + t->t_offset));
|
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;
|
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
|
#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_PARENT(rbe) = parent;
|
||||||
RBE_LEFT(rbe) = RBE_RIGHT(rbe) = NULL;
|
RBE_LEFT(rbe) = RBE_RIGHT(rbe) = NULL;
|
||||||
RBE_COLOR(rbe) = RB_RED;
|
RBE_COLOR(rbe) = RB_RED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void rbe_set_blackred(struct rb_entry *black,
|
static inline void
|
||||||
struct rb_entry *red)
|
rbe_set_blackred(struct rb_entry *black, struct rb_entry *red)
|
||||||
{
|
{
|
||||||
RBE_COLOR(black) = RB_BLACK;
|
RBE_COLOR(black) = RB_BLACK;
|
||||||
RBE_COLOR(red) = RB_RED;
|
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));
|
(*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)
|
if (t->t_augment != NULL)
|
||||||
rbe_augment(t, rbe);
|
rbe_augment(t, rbe);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void rbe_rotate_left(const struct rb_type *t,
|
static inline void
|
||||||
struct rbt_tree *rbt, struct rb_entry *rbe)
|
rbe_rotate_left(const struct rb_type *t, struct rbt_tree *rbt,
|
||||||
|
struct rb_entry *rbe)
|
||||||
{
|
{
|
||||||
struct rb_entry *parent;
|
struct rb_entry *parent;
|
||||||
struct rb_entry *tmp;
|
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,
|
static inline void
|
||||||
struct rbt_tree *rbt, struct rb_entry *rbe)
|
rbe_rotate_right(const struct rb_type *t, struct rbt_tree *rbt,
|
||||||
|
struct rb_entry *rbe)
|
||||||
{
|
{
|
||||||
struct rb_entry *parent;
|
struct rb_entry *parent;
|
||||||
struct rb_entry *tmp;
|
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,
|
static inline void
|
||||||
struct rbt_tree *rbt, struct rb_entry *rbe)
|
rbe_insert_color(const struct rb_type *t, struct rbt_tree *rbt,
|
||||||
|
struct rb_entry *rbe)
|
||||||
{
|
{
|
||||||
struct rb_entry *parent, *gparent, *tmp;
|
struct rb_entry *parent, *gparent, *tmp;
|
||||||
|
|
||||||
while ((parent = RBE_PARENT(rbe)) != NULL
|
while ((parent = RBE_PARENT(rbe)) != NULL &&
|
||||||
&& RBE_COLOR(parent) == RB_RED) {
|
RBE_COLOR(parent) == RB_RED) {
|
||||||
gparent = RBE_PARENT(parent);
|
gparent = RBE_PARENT(parent);
|
||||||
|
|
||||||
if (parent == RBE_LEFT(gparent)) {
|
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;
|
RBE_COLOR(RBH_ROOT(rbt)) = RB_BLACK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void rbe_remove_color(const struct rb_type *t,
|
static inline void
|
||||||
struct rbt_tree *rbt,
|
rbe_remove_color(const struct rb_type *t, struct rbt_tree *rbt,
|
||||||
struct rb_entry *parent,
|
struct rb_entry *parent, struct rb_entry *rbe)
|
||||||
struct rb_entry *rbe)
|
|
||||||
{
|
{
|
||||||
struct rb_entry *tmp;
|
struct rb_entry *tmp;
|
||||||
|
|
||||||
/* Silence clang possible NULL deference warning. */
|
while ((rbe == NULL || RBE_COLOR(rbe) == RB_BLACK) &&
|
||||||
if (parent == NULL)
|
rbe != RBH_ROOT(rbt) && parent) {
|
||||||
return;
|
|
||||||
|
|
||||||
while ((rbe == NULL || RBE_COLOR(rbe) == RB_BLACK)
|
|
||||||
&& rbe != RBH_ROOT(rbt)) {
|
|
||||||
if (RBE_LEFT(parent) == rbe) {
|
if (RBE_LEFT(parent) == rbe) {
|
||||||
tmp = RBE_RIGHT(parent);
|
tmp = RBE_RIGHT(parent);
|
||||||
if (RBE_COLOR(tmp) == RB_RED) {
|
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);
|
rbe_rotate_left(t, rbt, parent);
|
||||||
tmp = RBE_RIGHT(parent);
|
tmp = RBE_RIGHT(parent);
|
||||||
}
|
}
|
||||||
if ((RBE_LEFT(tmp) == NULL
|
if ((RBE_LEFT(tmp) == NULL ||
|
||||||
|| RBE_COLOR(RBE_LEFT(tmp)) == RB_BLACK)
|
RBE_COLOR(RBE_LEFT(tmp)) == RB_BLACK) &&
|
||||||
&& (RBE_RIGHT(tmp) == NULL
|
(RBE_RIGHT(tmp) == NULL ||
|
||||||
|| RBE_COLOR(RBE_RIGHT(tmp)) == RB_BLACK)) {
|
RBE_COLOR(RBE_RIGHT(tmp)) == RB_BLACK)) {
|
||||||
RBE_COLOR(tmp) = RB_RED;
|
RBE_COLOR(tmp) = RB_RED;
|
||||||
rbe = parent;
|
rbe = parent;
|
||||||
parent = RBE_PARENT(rbe);
|
parent = RBE_PARENT(rbe);
|
||||||
} else {
|
} else {
|
||||||
if (RBE_RIGHT(tmp) == NULL
|
if (RBE_RIGHT(tmp) == NULL ||
|
||||||
|| RBE_COLOR(RBE_RIGHT(tmp)) == RB_BLACK) {
|
RBE_COLOR(RBE_RIGHT(tmp)) == RB_BLACK) {
|
||||||
struct rb_entry *oleft;
|
struct rb_entry *oleft;
|
||||||
|
|
||||||
oleft = RBE_LEFT(tmp);
|
oleft = RBE_LEFT(tmp);
|
||||||
@ -266,16 +269,16 @@ static inline void rbe_remove_color(const struct rb_type *t,
|
|||||||
tmp = RBE_LEFT(parent);
|
tmp = RBE_LEFT(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((RBE_LEFT(tmp) == NULL
|
if ((RBE_LEFT(tmp) == NULL ||
|
||||||
|| RBE_COLOR(RBE_LEFT(tmp)) == RB_BLACK)
|
RBE_COLOR(RBE_LEFT(tmp)) == RB_BLACK) &&
|
||||||
&& (RBE_RIGHT(tmp) == NULL
|
(RBE_RIGHT(tmp) == NULL ||
|
||||||
|| RBE_COLOR(RBE_RIGHT(tmp)) == RB_BLACK)) {
|
RBE_COLOR(RBE_RIGHT(tmp)) == RB_BLACK)) {
|
||||||
RBE_COLOR(tmp) = RB_RED;
|
RBE_COLOR(tmp) = RB_RED;
|
||||||
rbe = parent;
|
rbe = parent;
|
||||||
parent = RBE_PARENT(rbe);
|
parent = RBE_PARENT(rbe);
|
||||||
} else {
|
} else {
|
||||||
if (RBE_LEFT(tmp) == NULL
|
if (RBE_LEFT(tmp) == NULL ||
|
||||||
|| RBE_COLOR(RBE_LEFT(tmp)) == RB_BLACK) {
|
RBE_COLOR(RBE_LEFT(tmp)) == RB_BLACK) {
|
||||||
struct rb_entry *oright;
|
struct rb_entry *oright;
|
||||||
|
|
||||||
oright = RBE_RIGHT(tmp);
|
oright = RBE_RIGHT(tmp);
|
||||||
@ -385,7 +388,8 @@ color:
|
|||||||
return (old);
|
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 *rbe = rb_n2e(t, elm);
|
||||||
struct rb_entry *old;
|
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));
|
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 *rbe = rb_n2e(t, elm);
|
||||||
struct rb_entry *tmp;
|
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 */
|
/* 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);
|
struct rb_entry *tmp = RBH_ROOT(rbt);
|
||||||
void *node;
|
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 */
|
/* 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);
|
struct rb_entry *tmp = RBH_ROOT(rbt);
|
||||||
void *node;
|
void *node;
|
||||||
@ -478,7 +485,8 @@ void *_rb_nfind(const struct rb_type *t, struct rbt_tree *rbt, const void *key)
|
|||||||
return (res);
|
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);
|
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)
|
while (RBE_LEFT(rbe) != NULL)
|
||||||
rbe = RBE_LEFT(rbe);
|
rbe = RBE_LEFT(rbe);
|
||||||
} else {
|
} 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);
|
rbe = RBE_PARENT(rbe);
|
||||||
else {
|
else {
|
||||||
while (RBE_PARENT(rbe)
|
while (RBE_PARENT(rbe) &&
|
||||||
&& (rbe == RBE_RIGHT(RBE_PARENT(rbe))))
|
(rbe == RBE_RIGHT(RBE_PARENT(rbe))))
|
||||||
rbe = RBE_PARENT(rbe);
|
rbe = 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));
|
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);
|
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))
|
while (RBE_RIGHT(rbe))
|
||||||
rbe = RBE_RIGHT(rbe);
|
rbe = RBE_RIGHT(rbe);
|
||||||
} else {
|
} 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);
|
rbe = RBE_PARENT(rbe);
|
||||||
else {
|
else {
|
||||||
while (RBE_PARENT(rbe)
|
while (RBE_PARENT(rbe) &&
|
||||||
&& (rbe == RBE_LEFT(RBE_PARENT(rbe))))
|
(rbe == RBE_LEFT(RBE_PARENT(rbe))))
|
||||||
rbe = RBE_PARENT(rbe);
|
rbe = 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));
|
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);
|
struct rb_entry *rbe = RBH_ROOT(rbt);
|
||||||
|
|
||||||
return (rbe == NULL ? rbe : rb_e2n(t, rbe));
|
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 *rbe = RBH_ROOT(rbt);
|
||||||
struct rb_entry *parent = NULL;
|
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));
|
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 *rbe = RBH_ROOT(rbt);
|
||||||
struct rb_entry *parent = NULL;
|
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));
|
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);
|
struct rb_entry *rbe = rb_n2e(t, node);
|
||||||
rbe = RBE_LEFT(rbe);
|
rbe = RBE_LEFT(rbe);
|
||||||
return (rbe == NULL ? NULL : rb_e2n(t, 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);
|
struct rb_entry *rbe = rb_n2e(t, node);
|
||||||
rbe = RBE_RIGHT(rbe);
|
rbe = RBE_RIGHT(rbe);
|
||||||
return (rbe == NULL ? NULL : rb_e2n(t, 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);
|
struct rb_entry *rbe = rb_n2e(t, node);
|
||||||
rbe = RBE_PARENT(rbe);
|
rbe = RBE_PARENT(rbe);
|
||||||
return (rbe == NULL ? NULL : rb_e2n(t, 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 *rbe = rb_n2e(t, node);
|
||||||
struct rb_entry *rbl = (left == NULL) ? NULL : rb_n2e(t, left);
|
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;
|
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 *rbe = rb_n2e(t, node);
|
||||||
struct rb_entry *rbr = (right == NULL) ? NULL : rb_n2e(t, right);
|
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;
|
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 *rbe = rb_n2e(t, node);
|
||||||
struct rb_entry *rbp = (parent == NULL) ? NULL : rb_n2e(t, parent);
|
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;
|
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);
|
struct rb_entry *rbe = rb_n2e(t, node);
|
||||||
|
|
||||||
RBE_PARENT(rbe) = RBE_LEFT(rbe) = RBE_RIGHT(rbe) =
|
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);
|
struct rb_entry *rbe = rb_n2e(t, node);
|
||||||
|
|
||||||
return ((unsigned long)RBE_PARENT(rbe) == poison
|
return ((unsigned long)RBE_PARENT(rbe) == poison &&
|
||||||
&& (unsigned long)RBE_LEFT(rbe) == poison
|
(unsigned long)RBE_LEFT(rbe) == poison &&
|
||||||
&& (unsigned long)RBE_RIGHT(rbe) == poison);
|
(unsigned long)RBE_RIGHT(rbe) == poison);
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _SYS_TREE_H_
|
#ifndef _SYS_TREE_H_
|
||||||
#define _SYS_TREE_H_
|
#define _SYS_TREE_H_
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -54,26 +54,23 @@
|
|||||||
* The maximum height of a red-black tree is 2lg (n+1).
|
* The maximum height of a red-black tree is 2lg (n+1).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define SPLAY_HEAD(name, type) \
|
#define SPLAY_HEAD(name, type) \
|
||||||
struct name { \
|
struct name { \
|
||||||
struct type *sph_root; /* root of the tree */ \
|
struct type *sph_root; /* root of the tree */ \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SPLAY_INITIALIZER(root) \
|
#define SPLAY_INITIALIZER(root) \
|
||||||
{ \
|
{ NULL }
|
||||||
NULL \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define SPLAY_INIT(root) \
|
#define SPLAY_INIT(root) do { \
|
||||||
do { \
|
(root)->sph_root = NULL; \
|
||||||
(root)->sph_root = NULL; \
|
} while (0)
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define SPLAY_ENTRY(type) \
|
#define SPLAY_ENTRY(type) \
|
||||||
struct { \
|
struct { \
|
||||||
struct type *spe_left; /* left element */ \
|
struct type *spe_left; /* left element */ \
|
||||||
struct type *spe_right; /* right element */ \
|
struct type *spe_right; /* right element */ \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SPLAY_LEFT(elm, field) (elm)->field.spe_left
|
#define SPLAY_LEFT(elm, field) (elm)->field.spe_left
|
||||||
#define SPLAY_RIGHT(elm, field) (elm)->field.spe_right
|
#define SPLAY_RIGHT(elm, field) (elm)->field.spe_right
|
||||||
@ -81,220 +78,197 @@
|
|||||||
#define SPLAY_EMPTY(head) (SPLAY_ROOT(head) == NULL)
|
#define SPLAY_EMPTY(head) (SPLAY_ROOT(head) == NULL)
|
||||||
|
|
||||||
/* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */
|
/* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */
|
||||||
#define SPLAY_ROTATE_RIGHT(head, tmp, field) \
|
#define SPLAY_ROTATE_RIGHT(head, tmp, field) do { \
|
||||||
do { \
|
SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field); \
|
||||||
SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field); \
|
SPLAY_RIGHT(tmp, field) = (head)->sph_root; \
|
||||||
SPLAY_RIGHT(tmp, field) = (head)->sph_root; \
|
(head)->sph_root = tmp; \
|
||||||
(head)->sph_root = tmp; \
|
} while (0)
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define SPLAY_ROTATE_LEFT(head, tmp, field) \
|
#define SPLAY_ROTATE_LEFT(head, tmp, field) do { \
|
||||||
do { \
|
SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field); \
|
||||||
SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field); \
|
SPLAY_LEFT(tmp, field) = (head)->sph_root; \
|
||||||
SPLAY_LEFT(tmp, field) = (head)->sph_root; \
|
(head)->sph_root = tmp; \
|
||||||
(head)->sph_root = tmp; \
|
} while (0)
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define SPLAY_LINKLEFT(head, tmp, field) \
|
#define SPLAY_LINKLEFT(head, tmp, field) do { \
|
||||||
do { \
|
SPLAY_LEFT(tmp, field) = (head)->sph_root; \
|
||||||
SPLAY_LEFT(tmp, field) = (head)->sph_root; \
|
tmp = (head)->sph_root; \
|
||||||
tmp = (head)->sph_root; \
|
(head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \
|
||||||
(head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \
|
} while (0)
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define SPLAY_LINKRIGHT(head, tmp, field) \
|
#define SPLAY_LINKRIGHT(head, tmp, field) do { \
|
||||||
do { \
|
SPLAY_RIGHT(tmp, field) = (head)->sph_root; \
|
||||||
SPLAY_RIGHT(tmp, field) = (head)->sph_root; \
|
tmp = (head)->sph_root; \
|
||||||
tmp = (head)->sph_root; \
|
(head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \
|
||||||
(head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \
|
} while (0)
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define SPLAY_ASSEMBLE(head, node, left, right, field) \
|
#define SPLAY_ASSEMBLE(head, node, left, right, field) do { \
|
||||||
do { \
|
SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field); \
|
||||||
SPLAY_RIGHT(left, field) = \
|
SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field);\
|
||||||
SPLAY_LEFT((head)->sph_root, field); \
|
SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field); \
|
||||||
SPLAY_LEFT(right, field) = \
|
SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field); \
|
||||||
SPLAY_RIGHT((head)->sph_root, field); \
|
} while (0)
|
||||||
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 */
|
/* Generates prototypes and inline functions */
|
||||||
|
|
||||||
#define SPLAY_PROTOTYPE(name, type, field, cmp) \
|
#define SPLAY_PROTOTYPE(name, type, field, cmp) \
|
||||||
void name##_SPLAY(struct name *, struct type *); \
|
void name##_SPLAY(struct name *, struct type *); \
|
||||||
void name##_SPLAY_MINMAX(struct name *, int); \
|
void name##_SPLAY_MINMAX(struct name *, int); \
|
||||||
struct type *name##_SPLAY_INSERT(struct name *, struct type *); \
|
struct type *name##_SPLAY_INSERT(struct name *, struct type *); \
|
||||||
struct type *name##_SPLAY_REMOVE(struct name *, struct type *); \
|
struct type *name##_SPLAY_REMOVE(struct name *, struct type *); \
|
||||||
\
|
\
|
||||||
/* Finds the node with the same key as elm */ \
|
/* Finds the node with the same key as elm */ \
|
||||||
static __inline struct type *name##_SPLAY_FIND(struct name *head, \
|
static __inline struct type * \
|
||||||
struct type *elm) \
|
name##_SPLAY_FIND(struct name *head, struct type *elm) \
|
||||||
{ \
|
{ \
|
||||||
if (SPLAY_EMPTY(head)) \
|
if (SPLAY_EMPTY(head)) \
|
||||||
return (NULL); \
|
return(NULL); \
|
||||||
name##_SPLAY(head, elm); \
|
name##_SPLAY(head, elm); \
|
||||||
if ((cmp)(elm, (head)->sph_root) == 0) \
|
if ((cmp)(elm, (head)->sph_root) == 0) \
|
||||||
return (head->sph_root); \
|
return (head->sph_root); \
|
||||||
return (NULL); \
|
return (NULL); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static __inline struct type *name##_SPLAY_NEXT(struct name *head, \
|
static __inline struct type * \
|
||||||
struct type *elm) \
|
name##_SPLAY_NEXT(struct name *head, struct type *elm) \
|
||||||
{ \
|
{ \
|
||||||
name##_SPLAY(head, elm); \
|
name##_SPLAY(head, elm); \
|
||||||
if (SPLAY_RIGHT(elm, field) != NULL) { \
|
if (SPLAY_RIGHT(elm, field) != NULL) { \
|
||||||
elm = SPLAY_RIGHT(elm, field); \
|
elm = SPLAY_RIGHT(elm, field); \
|
||||||
while (SPLAY_LEFT(elm, field) != NULL) { \
|
while (SPLAY_LEFT(elm, field) != NULL) { \
|
||||||
elm = SPLAY_LEFT(elm, field); \
|
elm = SPLAY_LEFT(elm, field); \
|
||||||
} \
|
} \
|
||||||
} else \
|
} else \
|
||||||
elm = NULL; \
|
elm = NULL; \
|
||||||
return (elm); \
|
return (elm); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static __inline struct type *name##_SPLAY_MIN_MAX(struct name *head, \
|
static __inline struct type * \
|
||||||
int val) \
|
name##_SPLAY_MIN_MAX(struct name *head, int val) \
|
||||||
{ \
|
{ \
|
||||||
name##_SPLAY_MINMAX(head, val); \
|
name##_SPLAY_MINMAX(head, val); \
|
||||||
return (SPLAY_ROOT(head)); \
|
return (SPLAY_ROOT(head)); \
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Main splay operation.
|
/* Main splay operation.
|
||||||
* Moves node close to the key of elm to top
|
* Moves node close to the key of elm to top
|
||||||
*/
|
*/
|
||||||
#define SPLAY_GENERATE(name, type, field, cmp) \
|
#define SPLAY_GENERATE(name, type, field, cmp) \
|
||||||
struct type *name##_SPLAY_INSERT(struct name *head, struct type *elm) \
|
struct type * \
|
||||||
{ \
|
name##_SPLAY_INSERT(struct name *head, struct type *elm) \
|
||||||
if (SPLAY_EMPTY(head)) { \
|
{ \
|
||||||
SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = \
|
if (SPLAY_EMPTY(head)) { \
|
||||||
NULL; \
|
SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL; \
|
||||||
} else { \
|
} else { \
|
||||||
int __comp; \
|
int __comp; \
|
||||||
name##_SPLAY(head, elm); \
|
name##_SPLAY(head, elm); \
|
||||||
__comp = (cmp)(elm, (head)->sph_root); \
|
__comp = (cmp)(elm, (head)->sph_root); \
|
||||||
if (__comp < 0) { \
|
if(__comp < 0) { \
|
||||||
SPLAY_LEFT(elm, field) = \
|
SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field);\
|
||||||
SPLAY_LEFT((head)->sph_root, field); \
|
SPLAY_RIGHT(elm, field) = (head)->sph_root; \
|
||||||
SPLAY_RIGHT(elm, field) = (head)->sph_root; \
|
SPLAY_LEFT((head)->sph_root, field) = NULL; \
|
||||||
SPLAY_LEFT((head)->sph_root, field) = NULL; \
|
} else if (__comp > 0) { \
|
||||||
} else if (__comp > 0) { \
|
SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field);\
|
||||||
SPLAY_RIGHT(elm, field) = \
|
SPLAY_LEFT(elm, field) = (head)->sph_root; \
|
||||||
SPLAY_RIGHT((head)->sph_root, field); \
|
SPLAY_RIGHT((head)->sph_root, field) = NULL; \
|
||||||
SPLAY_LEFT(elm, field) = (head)->sph_root; \
|
} else \
|
||||||
SPLAY_RIGHT((head)->sph_root, field) = NULL; \
|
return ((head)->sph_root); \
|
||||||
} else \
|
} \
|
||||||
return ((head)->sph_root); \
|
(head)->sph_root = (elm); \
|
||||||
} \
|
return (NULL); \
|
||||||
(head)->sph_root = (elm); \
|
} \
|
||||||
return (NULL); \
|
\
|
||||||
} \
|
struct type * \
|
||||||
\
|
name##_SPLAY_REMOVE(struct name *head, struct type *elm) \
|
||||||
struct type *name##_SPLAY_REMOVE(struct name *head, struct type *elm) \
|
{ \
|
||||||
{ \
|
struct type *__tmp; \
|
||||||
struct type *__tmp; \
|
if (SPLAY_EMPTY(head)) \
|
||||||
if (SPLAY_EMPTY(head)) \
|
return (NULL); \
|
||||||
return (NULL); \
|
name##_SPLAY(head, elm); \
|
||||||
name##_SPLAY(head, elm); \
|
if ((cmp)(elm, (head)->sph_root) == 0) { \
|
||||||
if ((cmp)(elm, (head)->sph_root) == 0) { \
|
if (SPLAY_LEFT((head)->sph_root, field) == NULL) { \
|
||||||
if (SPLAY_LEFT((head)->sph_root, field) == NULL) { \
|
(head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);\
|
||||||
(head)->sph_root = \
|
} else { \
|
||||||
SPLAY_RIGHT((head)->sph_root, field); \
|
__tmp = SPLAY_RIGHT((head)->sph_root, field); \
|
||||||
} else { \
|
(head)->sph_root = SPLAY_LEFT((head)->sph_root, field);\
|
||||||
__tmp = SPLAY_RIGHT((head)->sph_root, field); \
|
name##_SPLAY(head, elm); \
|
||||||
(head)->sph_root = \
|
SPLAY_RIGHT((head)->sph_root, field) = __tmp; \
|
||||||
SPLAY_LEFT((head)->sph_root, field); \
|
} \
|
||||||
name##_SPLAY(head, elm); \
|
return (elm); \
|
||||||
SPLAY_RIGHT((head)->sph_root, field) = __tmp; \
|
} \
|
||||||
} \
|
return (NULL); \
|
||||||
return (elm); \
|
} \
|
||||||
} \
|
\
|
||||||
return (NULL); \
|
void \
|
||||||
} \
|
name##_SPLAY(struct name *head, struct type *elm) \
|
||||||
\
|
{ \
|
||||||
void name##_SPLAY(struct name *head, struct type *elm) \
|
struct type __node, *__left, *__right, *__tmp; \
|
||||||
{ \
|
int __comp; \
|
||||||
struct type __node, *__left, *__right, *__tmp; \
|
\
|
||||||
int __comp; \
|
SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\
|
||||||
\
|
__left = __right = &__node; \
|
||||||
SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = \
|
\
|
||||||
NULL; \
|
while ((__comp = (cmp)(elm, (head)->sph_root))) { \
|
||||||
__left = __right = &__node; \
|
if (__comp < 0) { \
|
||||||
\
|
__tmp = SPLAY_LEFT((head)->sph_root, field); \
|
||||||
while ((__comp = (cmp)(elm, (head)->sph_root))) { \
|
if (__tmp == NULL) \
|
||||||
if (__comp < 0) { \
|
break; \
|
||||||
__tmp = SPLAY_LEFT((head)->sph_root, field); \
|
if ((cmp)(elm, __tmp) < 0){ \
|
||||||
if (__tmp == NULL) \
|
SPLAY_ROTATE_RIGHT(head, __tmp, field); \
|
||||||
break; \
|
if (SPLAY_LEFT((head)->sph_root, field) == NULL)\
|
||||||
if ((cmp)(elm, __tmp) < 0) { \
|
break; \
|
||||||
SPLAY_ROTATE_RIGHT(head, __tmp, \
|
} \
|
||||||
field); \
|
SPLAY_LINKLEFT(head, __right, field); \
|
||||||
if (SPLAY_LEFT((head)->sph_root, \
|
} else if (__comp > 0) { \
|
||||||
field) \
|
__tmp = SPLAY_RIGHT((head)->sph_root, field); \
|
||||||
== NULL) \
|
if (__tmp == NULL) \
|
||||||
break; \
|
break; \
|
||||||
} \
|
if ((cmp)(elm, __tmp) > 0){ \
|
||||||
SPLAY_LINKLEFT(head, __right, field); \
|
SPLAY_ROTATE_LEFT(head, __tmp, field); \
|
||||||
} else if (__comp > 0) { \
|
if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\
|
||||||
__tmp = SPLAY_RIGHT((head)->sph_root, field); \
|
break; \
|
||||||
if (__tmp == NULL) \
|
} \
|
||||||
break; \
|
SPLAY_LINKRIGHT(head, __left, field); \
|
||||||
if ((cmp)(elm, __tmp) > 0) { \
|
} \
|
||||||
SPLAY_ROTATE_LEFT(head, __tmp, field); \
|
} \
|
||||||
if (SPLAY_RIGHT((head)->sph_root, \
|
SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \
|
||||||
field) \
|
} \
|
||||||
== NULL) \
|
\
|
||||||
break; \
|
/* Splay with either the minimum or the maximum element \
|
||||||
} \
|
* Used to find minimum or maximum element in tree. \
|
||||||
SPLAY_LINKRIGHT(head, __left, field); \
|
*/ \
|
||||||
} \
|
void name##_SPLAY_MINMAX(struct name *head, int __comp) \
|
||||||
} \
|
{ \
|
||||||
SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \
|
struct type __node, *__left, *__right, *__tmp; \
|
||||||
} \
|
\
|
||||||
\
|
SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\
|
||||||
/* Splay with either the minimum or the maximum element \
|
__left = __right = &__node; \
|
||||||
* Used to find minimum or maximum element in tree. \
|
\
|
||||||
*/ \
|
while (1) { \
|
||||||
void name##_SPLAY_MINMAX(struct name *head, int __comp) \
|
if (__comp < 0) { \
|
||||||
{ \
|
__tmp = SPLAY_LEFT((head)->sph_root, field); \
|
||||||
struct type __node, *__left, *__right, *__tmp; \
|
if (__tmp == NULL) \
|
||||||
\
|
break; \
|
||||||
SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = \
|
if (__comp < 0){ \
|
||||||
NULL; \
|
SPLAY_ROTATE_RIGHT(head, __tmp, field); \
|
||||||
__left = __right = &__node; \
|
if (SPLAY_LEFT((head)->sph_root, field) == NULL)\
|
||||||
\
|
break; \
|
||||||
while (1) { \
|
} \
|
||||||
if (__comp < 0) { \
|
SPLAY_LINKLEFT(head, __right, field); \
|
||||||
__tmp = SPLAY_LEFT((head)->sph_root, field); \
|
} else if (__comp > 0) { \
|
||||||
if (__tmp == NULL) \
|
__tmp = SPLAY_RIGHT((head)->sph_root, field); \
|
||||||
break; \
|
if (__tmp == NULL) \
|
||||||
if (__comp < 0) { \
|
break; \
|
||||||
SPLAY_ROTATE_RIGHT(head, __tmp, \
|
if (__comp > 0) { \
|
||||||
field); \
|
SPLAY_ROTATE_LEFT(head, __tmp, field); \
|
||||||
if (SPLAY_LEFT((head)->sph_root, \
|
if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\
|
||||||
field) \
|
break; \
|
||||||
== NULL) \
|
} \
|
||||||
break; \
|
SPLAY_LINKRIGHT(head, __left, field); \
|
||||||
} \
|
} \
|
||||||
SPLAY_LINKLEFT(head, __right, field); \
|
} \
|
||||||
} else if (__comp > 0) { \
|
SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \
|
||||||
__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_NEGINF -1
|
||||||
#define SPLAY_INF 1
|
#define SPLAY_INF 1
|
||||||
@ -303,13 +277,14 @@
|
|||||||
#define SPLAY_REMOVE(name, x, y) name##_SPLAY_REMOVE(x, y)
|
#define SPLAY_REMOVE(name, x, y) name##_SPLAY_REMOVE(x, y)
|
||||||
#define SPLAY_FIND(name, x, y) name##_SPLAY_FIND(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_NEXT(name, x, y) name##_SPLAY_NEXT(x, y)
|
||||||
#define SPLAY_MIN(name, x) \
|
#define SPLAY_MIN(name, x) (SPLAY_EMPTY(x) ? NULL \
|
||||||
(SPLAY_EMPTY(x) ? NULL : name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF))
|
: name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF))
|
||||||
#define SPLAY_MAX(name, x) \
|
#define SPLAY_MAX(name, x) (SPLAY_EMPTY(x) ? NULL \
|
||||||
(SPLAY_EMPTY(x) ? NULL : name##_SPLAY_MIN_MAX(x, SPLAY_INF))
|
: name##_SPLAY_MIN_MAX(x, SPLAY_INF))
|
||||||
|
|
||||||
#define SPLAY_FOREACH(x, name, head) \
|
#define SPLAY_FOREACH(x, name, head) \
|
||||||
for ((x) = SPLAY_MIN(name, head); (x) != NULL; \
|
for ((x) = SPLAY_MIN(name, head); \
|
||||||
|
(x) != NULL; \
|
||||||
(x) = SPLAY_NEXT(name, head, x))
|
(x) = SPLAY_NEXT(name, head, x))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -332,197 +307,203 @@
|
|||||||
#define RB_RED 1
|
#define RB_RED 1
|
||||||
|
|
||||||
struct rb_type {
|
struct rb_type {
|
||||||
int (*t_compare)(const void *, const void *);
|
int (*t_compare)(const void *, const void *);
|
||||||
void (*t_augment)(void *);
|
void (*t_augment)(void *);
|
||||||
unsigned int t_offset; /* offset of rb_entry in type */
|
unsigned int t_offset; /* offset of rb_entry in type */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rbt_tree {
|
struct rbt_tree {
|
||||||
struct rb_entry *rbt_root;
|
struct rb_entry *rbt_root;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rb_entry {
|
struct rb_entry {
|
||||||
struct rb_entry *rbt_parent;
|
struct rb_entry *rbt_parent;
|
||||||
struct rb_entry *rbt_left;
|
struct rb_entry *rbt_left;
|
||||||
struct rb_entry *rbt_right;
|
struct rb_entry *rbt_right;
|
||||||
unsigned int rbt_color;
|
unsigned int rbt_color;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define RB_HEAD(_name, _type) \
|
#define RB_HEAD(_name, _type) \
|
||||||
struct _name { \
|
struct _name { \
|
||||||
struct rbt_tree rbh_root; \
|
struct rbt_tree rbh_root; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define RB_ENTRY(_type) struct rb_entry
|
#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;
|
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);
|
return (rbt->rbt_root == NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *_rb_insert(const struct rb_type *, struct rbt_tree *, void *);
|
void *_rb_insert(const struct rb_type *, struct rbt_tree *, void *);
|
||||||
void *_rb_remove(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_find(const struct rb_type *, struct rbt_tree *, const void *);
|
||||||
void *_rb_nfind(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_root(const struct rb_type *, struct rbt_tree *);
|
||||||
void *_rb_min(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_max(const struct rb_type *, struct rbt_tree *);
|
||||||
void *_rb_next(const struct rb_type *, void *);
|
void *_rb_next(const struct rb_type *, void *);
|
||||||
void *_rb_prev(const struct rb_type *, void *);
|
void *_rb_prev(const struct rb_type *, void *);
|
||||||
void *_rb_left(const struct rb_type *, void *);
|
void *_rb_left(const struct rb_type *, void *);
|
||||||
void *_rb_right(const struct rb_type *, void *);
|
void *_rb_right(const struct rb_type *, void *);
|
||||||
void *_rb_parent(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_left(const struct rb_type *, void *, void *);
|
||||||
void _rb_set_right(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_set_parent(const struct rb_type *, void *, void *);
|
||||||
void _rb_poison(const struct rb_type *, void *, unsigned long);
|
void _rb_poison(const struct rb_type *, void *, unsigned long);
|
||||||
int _rb_check(const struct rb_type *, void *, unsigned long);
|
int _rb_check(const struct rb_type *, void *, unsigned long);
|
||||||
|
|
||||||
#define RB_INITIALIZER(_head) { { NULL } }
|
#define RB_INITIALIZER(_head) { { NULL } }
|
||||||
|
|
||||||
#define RB_PROTOTYPE(_name, _type, _field, _cmp) \
|
#define RB_PROTOTYPE(_name, _type, _field, _cmp) \
|
||||||
extern const struct rb_type *const _name##_RB_TYPE; \
|
extern const struct rb_type *const _name##_RB_TYPE; \
|
||||||
\
|
\
|
||||||
__attribute__((__unused__)) static inline void _name##_RB_INIT( \
|
__attribute__((__unused__)) static inline void \
|
||||||
struct _name *head) \
|
_name##_RB_INIT(struct _name *head) \
|
||||||
{ \
|
{ \
|
||||||
_rb_init(&head->rbh_root); \
|
_rb_init(&head->rbh_root); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
__attribute__((__unused__)) static inline struct _type \
|
__attribute__((__unused__)) static inline struct _type * \
|
||||||
*_name##_RB_INSERT(struct _name *head, struct _type *elm) \
|
_name##_RB_INSERT(struct _name *head, struct _type *elm) \
|
||||||
{ \
|
{ \
|
||||||
return _rb_insert(_name##_RB_TYPE, &head->rbh_root, elm); \
|
return _rb_insert(_name##_RB_TYPE, &head->rbh_root, elm); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
__attribute__((__unused__)) static inline struct _type \
|
__attribute__((__unused__)) static inline struct _type * \
|
||||||
*_name##_RB_REMOVE(struct _name *head, struct _type *elm) \
|
_name##_RB_REMOVE(struct _name *head, struct _type *elm) \
|
||||||
{ \
|
{ \
|
||||||
return _rb_remove(_name##_RB_TYPE, &head->rbh_root, elm); \
|
return _rb_remove(_name##_RB_TYPE, &head->rbh_root, elm); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
__attribute__((__unused__)) static inline struct _type \
|
__attribute__((__unused__)) static inline struct _type * \
|
||||||
*_name##_RB_FIND(struct _name *head, const struct _type *key) \
|
_name##_RB_FIND(struct _name *head, const struct _type *key) \
|
||||||
{ \
|
{ \
|
||||||
return _rb_find(_name##_RB_TYPE, &head->rbh_root, key); \
|
return _rb_find(_name##_RB_TYPE, &head->rbh_root, key); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
__attribute__((__unused__)) static inline struct _type \
|
__attribute__((__unused__)) static inline struct _type * \
|
||||||
*_name##_RB_NFIND(struct _name *head, const struct _type *key) \
|
_name##_RB_NFIND(struct _name *head, const struct _type *key) \
|
||||||
{ \
|
{ \
|
||||||
return _rb_nfind(_name##_RB_TYPE, &head->rbh_root, key); \
|
return _rb_nfind(_name##_RB_TYPE, &head->rbh_root, key); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
__attribute__((__unused__)) static inline struct _type \
|
__attribute__((__unused__)) static inline struct _type * \
|
||||||
*_name##_RB_ROOT(struct _name *head) \
|
_name##_RB_ROOT(struct _name *head) \
|
||||||
{ \
|
{ \
|
||||||
return _rb_root(_name##_RB_TYPE, &head->rbh_root); \
|
return _rb_root(_name##_RB_TYPE, &head->rbh_root); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
__attribute__((__unused__)) static inline int _name##_RB_EMPTY( \
|
__attribute__((__unused__)) static inline int \
|
||||||
struct _name *head) \
|
_name##_RB_EMPTY(struct _name *head) \
|
||||||
{ \
|
{ \
|
||||||
return _rb_empty(&head->rbh_root); \
|
return _rb_empty(&head->rbh_root); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
__attribute__((__unused__)) static inline struct _type \
|
__attribute__((__unused__)) static inline struct _type * \
|
||||||
*_name##_RB_MIN(struct _name *head) \
|
_name##_RB_MIN(struct _name *head) \
|
||||||
{ \
|
{ \
|
||||||
return _rb_min(_name##_RB_TYPE, &head->rbh_root); \
|
return _rb_min(_name##_RB_TYPE, &head->rbh_root); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
__attribute__((__unused__)) static inline struct _type \
|
__attribute__((__unused__)) static inline struct _type * \
|
||||||
*_name##_RB_MAX(struct _name *head) \
|
_name##_RB_MAX(struct _name *head) \
|
||||||
{ \
|
{ \
|
||||||
return _rb_max(_name##_RB_TYPE, &head->rbh_root); \
|
return _rb_max(_name##_RB_TYPE, &head->rbh_root); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
__attribute__((__unused__)) static inline struct _type \
|
__attribute__((__unused__)) static inline struct _type * \
|
||||||
*_name##_RB_NEXT(struct _type *elm) \
|
_name##_RB_NEXT(struct _type *elm) \
|
||||||
{ \
|
{ \
|
||||||
return _rb_next(_name##_RB_TYPE, elm); \
|
return _rb_next(_name##_RB_TYPE, elm); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
__attribute__((__unused__)) static inline struct _type \
|
__attribute__((__unused__)) static inline struct _type * \
|
||||||
*_name##_RB_PREV(struct _type *elm) \
|
_name##_RB_PREV(struct _type *elm) \
|
||||||
{ \
|
{ \
|
||||||
return _rb_prev(_name##_RB_TYPE, elm); \
|
return _rb_prev(_name##_RB_TYPE, elm); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
__attribute__((__unused__)) static inline struct _type \
|
__attribute__((__unused__)) static inline struct _type * \
|
||||||
*_name##_RB_LEFT(struct _type *elm) \
|
_name##_RB_LEFT(struct _type *elm) \
|
||||||
{ \
|
{ \
|
||||||
return _rb_left(_name##_RB_TYPE, elm); \
|
return _rb_left(_name##_RB_TYPE, elm); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
__attribute__((__unused__)) static inline struct _type \
|
__attribute__((__unused__)) static inline struct _type * \
|
||||||
*_name##_RB_RIGHT(struct _type *elm) \
|
_name##_RB_RIGHT(struct _type *elm) \
|
||||||
{ \
|
{ \
|
||||||
return _rb_right(_name##_RB_TYPE, elm); \
|
return _rb_right(_name##_RB_TYPE, elm); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
__attribute__((__unused__)) static inline struct _type \
|
__attribute__((__unused__)) static inline struct _type * \
|
||||||
*_name##_RB_PARENT(struct _type *elm) \
|
_name##_RB_PARENT(struct _type *elm) \
|
||||||
{ \
|
{ \
|
||||||
return _rb_parent(_name##_RB_TYPE, elm); \
|
return _rb_parent(_name##_RB_TYPE, elm); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
__attribute__((__unused__)) static inline void _name##_RB_SET_LEFT( \
|
__attribute__((__unused__)) static inline void \
|
||||||
struct _type *elm, struct _type *left) \
|
_name##_RB_SET_LEFT(struct _type *elm, struct _type *left) \
|
||||||
{ \
|
{ \
|
||||||
return _rb_set_left(_name##_RB_TYPE, elm, left); \
|
return _rb_set_left(_name##_RB_TYPE, elm, left); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
__attribute__((__unused__)) static inline void _name##_RB_SET_RIGHT( \
|
__attribute__((__unused__)) static inline void \
|
||||||
struct _type *elm, struct _type *right) \
|
_name##_RB_SET_RIGHT(struct _type *elm, struct _type *right) \
|
||||||
{ \
|
{ \
|
||||||
return _rb_set_right(_name##_RB_TYPE, elm, right); \
|
return _rb_set_right(_name##_RB_TYPE, elm, right); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
__attribute__((__unused__)) static inline void _name##_RB_SET_PARENT( \
|
__attribute__((__unused__)) static inline void \
|
||||||
struct _type *elm, struct _type *parent) \
|
_name##_RB_SET_PARENT(struct _type *elm, struct _type *parent) \
|
||||||
{ \
|
{ \
|
||||||
return _rb_set_parent(_name##_RB_TYPE, elm, parent); \
|
return _rb_set_parent(_name##_RB_TYPE, elm, parent); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
__attribute__((__unused__)) static inline void _name##_RB_POISON( \
|
__attribute__((__unused__)) static inline void \
|
||||||
struct _type *elm, unsigned long poison) \
|
_name##_RB_POISON(struct _type *elm, unsigned long poison) \
|
||||||
{ \
|
{ \
|
||||||
return _rb_poison(_name##_RB_TYPE, elm, poison); \
|
return _rb_poison(_name##_RB_TYPE, elm, poison); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
__attribute__((__unused__)) static inline int _name##_RB_CHECK( \
|
__attribute__((__unused__)) static inline int \
|
||||||
struct _type *elm, unsigned long poison) \
|
_name##_RB_CHECK(struct _type *elm, unsigned long poison) \
|
||||||
{ \
|
{ \
|
||||||
return _rb_check(_name##_RB_TYPE, elm, poison); \
|
return _rb_check(_name##_RB_TYPE, elm, poison); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define RB_GENERATE_INTERNAL(_name, _type, _field, _cmp, _aug) \
|
#define RB_GENERATE_INTERNAL(_name, _type, _field, _cmp, _aug) \
|
||||||
static int _name##_RB_COMPARE(const void *lptr, const void *rptr) \
|
static int \
|
||||||
{ \
|
_name##_RB_COMPARE(const void *lptr, const void *rptr) \
|
||||||
const struct _type *l = lptr, *r = rptr; \
|
{ \
|
||||||
return _cmp(l, r); \
|
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), \
|
static const struct rb_type _name##_RB_INFO = { \
|
||||||
}; \
|
_name##_RB_COMPARE, \
|
||||||
const struct rb_type *const _name##_RB_TYPE = &_name##_RB_INFO;
|
_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) \
|
#define RB_GENERATE_AUGMENT(_name, _type, _field, _cmp, _aug) \
|
||||||
static void _name##_RB_AUGMENT(void *ptr) \
|
static void \
|
||||||
{ \
|
_name##_RB_AUGMENT(void *ptr) \
|
||||||
struct _type *p = ptr; \
|
{ \
|
||||||
return _aug(p); \
|
struct _type *p = ptr; \
|
||||||
} \
|
return _aug(p); \
|
||||||
RB_GENERATE_INTERNAL(_name, _type, _field, _cmp, _name##_RB_AUGMENT)
|
} \
|
||||||
|
RB_GENERATE_INTERNAL(_name, _type, _field, _cmp, _name##_RB_AUGMENT)
|
||||||
|
|
||||||
#define RB_GENERATE(_name, _type, _field, _cmp) \
|
#define RB_GENERATE(_name, _type, _field, _cmp) \
|
||||||
RB_GENERATE_INTERNAL(_name, _type, _field, _cmp, NULL)
|
RB_GENERATE_INTERNAL(_name, _type, _field, _cmp, NULL)
|
||||||
|
|
||||||
#define RB_INIT(_name, _head) _name##_RB_INIT(_head)
|
#define RB_INIT(_name, _head) _name##_RB_INIT(_head)
|
||||||
#define RB_INSERT(_name, _head, _elm) _name##_RB_INSERT(_head, _elm)
|
#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_POISON(_name, _elm, _p) _name##_RB_POISON(_elm, _p)
|
||||||
#define RB_CHECK(_name, _elm, _p) _name##_RB_CHECK(_elm, _p)
|
#define RB_CHECK(_name, _elm, _p) _name##_RB_CHECK(_elm, _p)
|
||||||
|
|
||||||
#define RB_FOREACH(_e, _name, _head) \
|
#define RB_FOREACH(_e, _name, _head) \
|
||||||
for ((_e) = RB_MIN(_name, (_head)); (_e) != NULL; \
|
for ((_e) = RB_MIN(_name, (_head)); \
|
||||||
|
(_e) != NULL; \
|
||||||
(_e) = RB_NEXT(_name, (_e)))
|
(_e) = RB_NEXT(_name, (_e)))
|
||||||
|
|
||||||
#define RB_FOREACH_SAFE(_e, _name, _head, _n) \
|
#define RB_FOREACH_SAFE(_e, _name, _head, _n) \
|
||||||
for ((_e) = RB_MIN(_name, (_head)); \
|
for ((_e) = RB_MIN(_name, (_head)); \
|
||||||
(_e) != NULL && ((_n) = RB_NEXT(_name, (_e)), 1); (_e) = (_n))
|
(_e) != NULL && ((_n) = RB_NEXT(_name, (_e)), 1); \
|
||||||
|
(_e) = (_n))
|
||||||
|
|
||||||
#define RB_FOREACH_REVERSE(_e, _name, _head) \
|
#define RB_FOREACH_REVERSE(_e, _name, _head) \
|
||||||
for ((_e) = RB_MAX(_name, (_head)); (_e) != NULL; \
|
for ((_e) = RB_MAX(_name, (_head)); \
|
||||||
|
(_e) != NULL; \
|
||||||
(_e) = RB_PREV(_name, (_e)))
|
(_e) = RB_PREV(_name, (_e)))
|
||||||
|
|
||||||
#define RB_FOREACH_REVERSE_SAFE(_e, _name, _head, _n) \
|
#define RB_FOREACH_REVERSE_SAFE(_e, _name, _head, _n) \
|
||||||
for ((_e) = RB_MAX(_name, (_head)); \
|
for ((_e) = RB_MAX(_name, (_head)); \
|
||||||
(_e) != NULL && ((_n) = RB_PREV(_name, (_e)), 1); (_e) = (_n))
|
(_e) != NULL && ((_n) = RB_PREV(_name, (_e)), 1); \
|
||||||
|
(_e) = (_n))
|
||||||
|
|
||||||
#endif /* _SYS_TREE_H_ */
|
#endif /* _SYS_TREE_H_ */
|
||||||
|
@ -507,8 +507,9 @@ const char *safi2str(safi_t safi)
|
|||||||
return "evpn";
|
return "evpn";
|
||||||
case SAFI_LABELED_UNICAST:
|
case SAFI_LABELED_UNICAST:
|
||||||
return "labeled-unicast";
|
return "labeled-unicast";
|
||||||
|
default:
|
||||||
|
return "unknown";
|
||||||
}
|
}
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If n includes p prefix then return 1 else return 0. */
|
/* If n includes p prefix then return 1 else return 0. */
|
||||||
|
260
lib/subdir.am
Normal file
260
lib/subdir.am
Normal 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
|
102
lib/zebra.h
102
lib/zebra.h
@ -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;
|
typedef enum { AFI_IP = 1, AFI_IP6 = 2, AFI_L2VPN = 3, AFI_MAX = 4 } afi_t;
|
||||||
|
|
||||||
/* Subsequent Address Family Identifier. */
|
/* Subsequent Address Family Identifier. */
|
||||||
#define SAFI_UNICAST 1
|
typedef enum {
|
||||||
#define SAFI_MULTICAST 2
|
SAFI_UNICAST = 1,
|
||||||
#define SAFI_MPLS_VPN 3
|
SAFI_MULTICAST = 2,
|
||||||
#define SAFI_RESERVED_4 4
|
SAFI_MPLS_VPN = 3,
|
||||||
#define SAFI_ENCAP 5
|
SAFI_ENCAP = 4,
|
||||||
#define SAFI_RESERVED_5 5
|
SAFI_EVPN = 5,
|
||||||
#define SAFI_EVPN 6
|
SAFI_LABELED_UNICAST = 6,
|
||||||
#define SAFI_LABELED_UNICAST 7
|
SAFI_MAX = 7
|
||||||
#define SAFI_MAX 8
|
} safi_t;
|
||||||
|
|
||||||
#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
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The above AFI and SAFI definitions are for internal use. The protocol
|
* The above AFI and SAFI definitions are for internal use. The protocol
|
||||||
@ -451,12 +444,15 @@ typedef enum {
|
|||||||
IANA_AFI_IP6MR = 129
|
IANA_AFI_IP6MR = 129
|
||||||
} iana_afi_t;
|
} iana_afi_t;
|
||||||
|
|
||||||
#define IANA_SAFI_RESERVED 0
|
typedef enum {
|
||||||
#define IANA_SAFI_UNICAST 1
|
IANA_SAFI_RESERVED = 0,
|
||||||
#define IANA_SAFI_MULTICAST 2
|
IANA_SAFI_UNICAST = 1,
|
||||||
#define IANA_SAFI_ENCAP 7
|
IANA_SAFI_MULTICAST = 2,
|
||||||
#define IANA_SAFI_EVPN 70
|
IANA_SAFI_LABELED_UNICAST = 4,
|
||||||
#define IANA_SAFI_MPLS_VPN 128
|
IANA_SAFI_ENCAP = 7,
|
||||||
|
IANA_SAFI_EVPN = 70,
|
||||||
|
IANA_SAFI_MPLS_VPN = 128
|
||||||
|
} iana_safi_t;
|
||||||
|
|
||||||
/* Default Administrative Distance of each protocol. */
|
/* Default Administrative Distance of each protocol. */
|
||||||
#define ZEBRA_KERNEL_DISTANCE_DEFAULT 0
|
#define ZEBRA_KERNEL_DISTANCE_DEFAULT 0
|
||||||
@ -477,8 +473,6 @@ typedef enum {
|
|||||||
#define UNSET_FLAG(V,F) (V) &= ~(F)
|
#define UNSET_FLAG(V,F) (V) &= ~(F)
|
||||||
#define RESET_FLAG(V) (V) = 0
|
#define RESET_FLAG(V) (V) = 0
|
||||||
|
|
||||||
typedef u_int8_t safi_t;
|
|
||||||
|
|
||||||
/* Zebra types. Used in Zserv message header. */
|
/* Zebra types. Used in Zserv message header. */
|
||||||
typedef u_int16_t zebra_size_t;
|
typedef u_int16_t zebra_size_t;
|
||||||
typedef u_int16_t zebra_command_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)
|
static inline afi_t afi_iana2int(iana_afi_t afi)
|
||||||
{
|
{
|
||||||
if (afi == IANA_AFI_IPV4)
|
switch (afi) {
|
||||||
|
case IANA_AFI_IPV4:
|
||||||
return AFI_IP;
|
return AFI_IP;
|
||||||
if (afi == IANA_AFI_IPV6)
|
case IANA_AFI_IPV6:
|
||||||
return AFI_IP6;
|
return AFI_IP6;
|
||||||
if (afi == IANA_AFI_L2VPN)
|
case IANA_AFI_L2VPN:
|
||||||
return AFI_L2VPN;
|
return AFI_L2VPN;
|
||||||
return AFI_MAX;
|
default:
|
||||||
|
return AFI_MAX;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline iana_afi_t afi_int2iana(afi_t afi)
|
static inline iana_afi_t afi_int2iana(afi_t afi)
|
||||||
{
|
{
|
||||||
if (afi == AFI_IP)
|
switch (afi) {
|
||||||
|
case AFI_IP:
|
||||||
return IANA_AFI_IPV4;
|
return IANA_AFI_IPV4;
|
||||||
if (afi == AFI_IP6)
|
case AFI_IP6:
|
||||||
return IANA_AFI_IPV6;
|
return IANA_AFI_IPV6;
|
||||||
if (afi == AFI_L2VPN)
|
case AFI_L2VPN:
|
||||||
return IANA_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;
|
return SAFI_UNICAST;
|
||||||
if (safi == IANA_SAFI_MULTICAST)
|
case IANA_SAFI_MULTICAST:
|
||||||
return SAFI_MULTICAST;
|
return SAFI_MULTICAST;
|
||||||
if (safi == IANA_SAFI_MPLS_VPN)
|
case IANA_SAFI_MPLS_VPN:
|
||||||
return SAFI_MPLS_VPN;
|
return SAFI_MPLS_VPN;
|
||||||
if (safi == IANA_SAFI_ENCAP)
|
case IANA_SAFI_ENCAP:
|
||||||
return SAFI_ENCAP;
|
return SAFI_ENCAP;
|
||||||
if (safi == IANA_SAFI_EVPN)
|
case IANA_SAFI_EVPN:
|
||||||
return SAFI_EVPN;
|
return SAFI_EVPN;
|
||||||
if (safi == IANA_SAFI_LABELED_UNICAST)
|
case IANA_SAFI_LABELED_UNICAST:
|
||||||
return 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;
|
return IANA_SAFI_UNICAST;
|
||||||
if (safi == SAFI_MULTICAST)
|
case SAFI_MULTICAST:
|
||||||
return IANA_SAFI_MULTICAST;
|
return IANA_SAFI_MULTICAST;
|
||||||
if (safi == SAFI_MPLS_VPN)
|
case SAFI_MPLS_VPN:
|
||||||
return IANA_SAFI_MPLS_VPN;
|
return IANA_SAFI_MPLS_VPN;
|
||||||
if (safi == SAFI_ENCAP)
|
case SAFI_ENCAP:
|
||||||
return IANA_SAFI_ENCAP;
|
return IANA_SAFI_ENCAP;
|
||||||
if (safi == SAFI_EVPN)
|
case SAFI_EVPN:
|
||||||
return IANA_SAFI_EVPN;
|
return IANA_SAFI_EVPN;
|
||||||
if (safi == SAFI_LABELED_UNICAST)
|
case SAFI_LABELED_UNICAST:
|
||||||
return IANA_SAFI_LABELED_UNICAST;
|
return IANA_SAFI_LABELED_UNICAST;
|
||||||
return IANA_SAFI_RESERVED;
|
default:
|
||||||
|
return IANA_SAFI_RESERVED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* _ZEBRA_H */
|
#endif /* _ZEBRA_H */
|
||||||
|
@ -1 +0,0 @@
|
|||||||
EXTRA_DIST=Makefile.am README.txt
|
|
@ -1437,7 +1437,7 @@ static void ospf6_brouter_debug_print(struct ospf6_route *brouter)
|
|||||||
char brouter_name[16];
|
char brouter_name[16];
|
||||||
char area_name[16];
|
char area_name[16];
|
||||||
char destination[64];
|
char destination[64];
|
||||||
char installed[16], changed[16];
|
char installed[64], changed[64];
|
||||||
struct timeval now, res;
|
struct timeval now, res;
|
||||||
char id[16], adv_router[16];
|
char id[16], adv_router[16];
|
||||||
char capa[16], options[16];
|
char capa[16], options[16];
|
||||||
|
@ -467,7 +467,7 @@ void ospf6_lsa_show(struct vty *vty, struct ospf6_lsa *lsa)
|
|||||||
char adv_router[64], id[64];
|
char adv_router[64], id[64];
|
||||||
struct ospf6_lsa_handler *handler;
|
struct ospf6_lsa_handler *handler;
|
||||||
struct timeval now, res;
|
struct timeval now, res;
|
||||||
char duration[16];
|
char duration[64];
|
||||||
|
|
||||||
assert(lsa && lsa->header);
|
assert(lsa && lsa->header);
|
||||||
|
|
||||||
|
@ -582,10 +582,10 @@ int inactivity_timer(struct thread *thread)
|
|||||||
static void ospf6_neighbor_show(struct vty *vty, struct ospf6_neighbor *on)
|
static void ospf6_neighbor_show(struct vty *vty, struct ospf6_neighbor *on)
|
||||||
{
|
{
|
||||||
char router_id[16];
|
char router_id[16];
|
||||||
char duration[16];
|
char duration[64];
|
||||||
struct timeval res;
|
struct timeval res;
|
||||||
char nstate[16];
|
char nstate[16];
|
||||||
char deadtime[16];
|
char deadtime[64];
|
||||||
long h, m, s;
|
long h, m, s;
|
||||||
|
|
||||||
/* Router-ID (Name) */
|
/* Router-ID (Name) */
|
||||||
@ -640,7 +640,7 @@ static void ospf6_neighbor_show_drchoice(struct vty *vty,
|
|||||||
{
|
{
|
||||||
char router_id[16];
|
char router_id[16];
|
||||||
char drouter[16], bdrouter[16];
|
char drouter[16], bdrouter[16];
|
||||||
char duration[16];
|
char duration[64];
|
||||||
struct timeval now, res;
|
struct timeval now, res;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -945,7 +945,7 @@ void ospf6_route_show(struct vty *vty, struct ospf6_route *route)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
char destination[PREFIX2STR_BUFFER], nexthop[64];
|
char destination[PREFIX2STR_BUFFER], nexthop[64];
|
||||||
char duration[16];
|
char duration[64];
|
||||||
const char *ifname;
|
const char *ifname;
|
||||||
struct timeval now, res;
|
struct timeval now, res;
|
||||||
struct listnode *node;
|
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 destination[PREFIX2STR_BUFFER], nexthop[64];
|
||||||
char area_id[16], id[16], adv_router[16], capa[16], options[16];
|
char area_id[16], id[16], adv_router[16], capa[16], options[16];
|
||||||
struct timeval now, res;
|
struct timeval now, res;
|
||||||
char duration[16];
|
char duration[64];
|
||||||
struct listnode *node;
|
struct listnode *node;
|
||||||
struct ospf6_nexthop *nh;
|
struct ospf6_nexthop *nh;
|
||||||
|
|
||||||
|
@ -77,6 +77,44 @@
|
|||||||
((ntohs((lsahdr)->length) >= sizeof(struct lsa_header)) \
|
((ntohs((lsahdr)->length) >= sizeof(struct lsa_header)) \
|
||||||
&& ((ntohs((lsahdr)->length) % sizeof(u_int32_t)) == 0))
|
&& ((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. */
|
/* Prototypes. */
|
||||||
|
|
||||||
extern void ospf_opaque_init(void);
|
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 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_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_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_if(struct vty *vty, struct interface *ifp);
|
||||||
extern void ospf_opaque_config_write_debug(struct vty *vty);
|
extern void ospf_opaque_config_write_debug(struct vty *vty);
|
||||||
extern void show_opaque_info_detail(struct vty *vty, struct ospf_lsa *lsa);
|
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,
|
extern void ospf_opaque_lsa_originate_schedule(struct ospf_interface *oi,
|
||||||
int *init_delay);
|
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);
|
int rt_recalc);
|
||||||
extern struct ospf_lsa *ospf_opaque_lsa_refresh(struct ospf_lsa *lsa);
|
extern struct ospf_lsa *ospf_opaque_lsa_refresh(struct ospf_lsa *lsa);
|
||||||
|
|
||||||
|
275
ospfd/ospf_ri.c
275
ospfd/ospf_ri.c
@ -58,9 +58,9 @@
|
|||||||
#include "ospfd/ospf_ri.h"
|
#include "ospfd/ospf_ri.h"
|
||||||
#include "ospfd/ospf_te.h"
|
#include "ospfd/ospf_te.h"
|
||||||
|
|
||||||
|
/* Store Router Information PCE TLV and SubTLV in network byte order. */
|
||||||
struct ospf_pce_info {
|
struct ospf_pce_info {
|
||||||
|
bool enabled;
|
||||||
/* Store Router Information PCE TLV and SubTLV in network byte order. */
|
|
||||||
struct ri_tlv_pce pce_header;
|
struct ri_tlv_pce pce_header;
|
||||||
struct ri_pce_subtlv_address pce_address;
|
struct ri_pce_subtlv_address pce_address;
|
||||||
struct ri_pce_subtlv_path_scope pce_scope;
|
struct ri_pce_subtlv_path_scope pce_scope;
|
||||||
@ -71,15 +71,14 @@ struct ospf_pce_info {
|
|||||||
|
|
||||||
/* Following structure are internal use only. */
|
/* Following structure are internal use only. */
|
||||||
struct ospf_router_info {
|
struct ospf_router_info {
|
||||||
status_t status;
|
bool enabled;
|
||||||
|
|
||||||
u_int8_t registered;
|
u_int8_t registered;
|
||||||
u_int8_t scope;
|
u_int8_t scope;
|
||||||
|
|
||||||
/* Flags to manage this router information. */
|
/* Flags to manage this router information. */
|
||||||
#define RIFLG_LOOKUP_DONE 0x1
|
#define RIFLG_LSA_ENGAGED 0x1
|
||||||
#define RIFLG_LSA_ENGAGED 0x2
|
#define RIFLG_LSA_FORCED_REFRESH 0x2
|
||||||
#define RIFLG_LSA_FORCED_REFRESH 0x4
|
|
||||||
u_int32_t flags;
|
u_int32_t flags;
|
||||||
|
|
||||||
/* area pointer if flooding is Type 10 Null if flooding is AS scope */
|
/* 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 void ospf_router_info_show_info(struct vty *vty, struct ospf_lsa *lsa);
|
||||||
static int ospf_router_info_lsa_originate(void *arg);
|
static int ospf_router_info_lsa_originate(void *arg);
|
||||||
static struct ospf_lsa *ospf_router_info_lsa_refresh(struct ospf_lsa *lsa);
|
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 ospf_router_info_register_vty(void);
|
||||||
static void del_pce_info(void *val);
|
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));
|
memset(&OspfRI, 0, sizeof(struct ospf_router_info));
|
||||||
OspfRI.status = disabled;
|
OspfRI.enabled = false;
|
||||||
OspfRI.registered = 0;
|
OspfRI.registered = 0;
|
||||||
OspfRI.scope = OSPF_OPAQUE_AS_LSA;
|
OspfRI.scope = OSPF_OPAQUE_AS_LSA;
|
||||||
OspfRI.flags = 0;
|
OspfRI.flags = 0;
|
||||||
|
|
||||||
/* Initialize pce domain and neighbor list */
|
/* Initialize pce domain and neighbor list */
|
||||||
|
OspfRI.pce_info.enabled = false;
|
||||||
OspfRI.pce_info.pce_domain = list_new();
|
OspfRI.pce_info.pce_domain = list_new();
|
||||||
OspfRI.pce_info.pce_domain->del = del_pce_info;
|
OspfRI.pce_info.pce_domain->del = del_pce_info;
|
||||||
OspfRI.pce_info.pce_neighbor = list_new();
|
OspfRI.pce_info.pce_neighbor = list_new();
|
||||||
@ -141,7 +141,7 @@ static int ospf_router_info_register(u_int8_t scope)
|
|||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
if (OspfRI.registered)
|
if (OspfRI.registered)
|
||||||
return 0;
|
return rc;
|
||||||
|
|
||||||
zlog_info("Register Router Information with scope %s(%d)",
|
zlog_info("Register Router Information with scope %s(%d)",
|
||||||
scope == OSPF_OPAQUE_AREA_LSA ? "Area" : "AS", scope);
|
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.registered = 1;
|
||||||
OspfRI.scope = scope;
|
OspfRI.scope = scope;
|
||||||
return 0;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ospf_router_info_unregister()
|
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_domain = NULL;
|
||||||
OspfRI.pce_info.pce_neighbor = NULL;
|
OspfRI.pce_info.pce_neighbor = NULL;
|
||||||
OspfRI.status = disabled;
|
OspfRI.enabled = false;
|
||||||
|
|
||||||
ospf_router_info_unregister();
|
ospf_router_info_unregister();
|
||||||
|
|
||||||
@ -229,34 +229,36 @@ static int set_pce_header(struct ospf_pce_info *pce)
|
|||||||
|
|
||||||
/* PCE Address */
|
/* PCE Address */
|
||||||
if (ntohs(pce->pce_address.header.type) != 0)
|
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 */
|
/* PCE Path Scope */
|
||||||
if (ntohs(pce->pce_scope.header.type) != 0)
|
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 */
|
/* PCE Domain */
|
||||||
for (ALL_LIST_ELEMENTS_RO(pce->pce_domain, node, domain)) {
|
for (ALL_LIST_ELEMENTS_RO(pce->pce_domain, node, domain)) {
|
||||||
if (ntohs(domain->header.type) != 0)
|
if (ntohs(domain->header.type) != 0)
|
||||||
length += RI_TLV_SIZE(&domain->header);
|
length += TLV_SIZE(&domain->header);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* PCE Neighbor */
|
/* PCE Neighbor */
|
||||||
for (ALL_LIST_ELEMENTS_RO(pce->pce_neighbor, node, neighbor)) {
|
for (ALL_LIST_ELEMENTS_RO(pce->pce_neighbor, node, neighbor)) {
|
||||||
if (ntohs(neighbor->header.type) != 0)
|
if (ntohs(neighbor->header.type) != 0)
|
||||||
length += RI_TLV_SIZE(&neighbor->header);
|
length += TLV_SIZE(&neighbor->header);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* PCE Capabilities */
|
/* PCE Capabilities */
|
||||||
if (ntohs(pce->pce_cap_flag.header.type) != 0)
|
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) {
|
if (length != 0) {
|
||||||
pce->pce_header.header.type = htons(RI_TLV_PCE);
|
pce->pce_header.header.type = htons(RI_TLV_PCE);
|
||||||
pce->pce_header.header.length = htons(length);
|
pce->pce_header.header.length = htons(length);
|
||||||
|
pce->enabled = true;
|
||||||
} else {
|
} else {
|
||||||
pce->pce_header.header.type = 0;
|
pce->pce_header.header.type = 0;
|
||||||
pce->pce_header.header.length = 0;
|
pce->pce_header.header.length = 0;
|
||||||
|
pce->enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return length;
|
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)
|
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 */
|
/* Set PCE Scope */
|
||||||
pce->pce_scope.header.type = htons(RI_PCE_SUBTLV_PATH_SCOPE);
|
pce->pce_scope.header.type = htons(RI_PCE_SUBTLV_PATH_SCOPE);
|
||||||
pce->pce_scope.header.length = htons(RI_TLV_LENGTH);
|
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;
|
struct ri_pce_subtlv_domain *new;
|
||||||
|
|
||||||
/* Enable PCE Info */
|
|
||||||
pce->pce_header.header.type = htons(RI_TLV_PCE);
|
|
||||||
|
|
||||||
/* Create new domain info */
|
/* Create new domain info */
|
||||||
new = XCALLOC(MTYPE_OSPF_PCE_PARAMS,
|
new = XCALLOC(MTYPE_OSPF_PCE_PARAMS,
|
||||||
sizeof(struct ri_pce_subtlv_domain));
|
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;
|
struct ri_pce_subtlv_neighbor *new;
|
||||||
|
|
||||||
/* Enable PCE Info */
|
|
||||||
pce->pce_header.header.type = htons(RI_TLV_PCE);
|
|
||||||
|
|
||||||
/* Create new neighbor info */
|
/* Create new neighbor info */
|
||||||
new = XCALLOC(MTYPE_OSPF_PCE_PARAMS,
|
new = XCALLOC(MTYPE_OSPF_PCE_PARAMS,
|
||||||
sizeof(struct ri_pce_subtlv_neighbor));
|
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)
|
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 */
|
/* Set PCE Capabilities flag */
|
||||||
pce->pce_cap_flag.header.type = htons(RI_PCE_SUBTLV_CAP_FLAG);
|
pce->pce_cap_flag.header.type = htons(RI_PCE_SUBTLV_CAP_FLAG);
|
||||||
pce->pce_cap_flag.header.length = htons(RI_TLV_LENGTH);
|
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;
|
tlv->type = 0;
|
||||||
/* Fill the Value to 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;
|
tlv->length = 0;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -423,14 +415,13 @@ static void unset_param(struct ri_tlv_header *tlv)
|
|||||||
|
|
||||||
static void initialize_params(struct ospf_router_info *ori)
|
static void initialize_params(struct ospf_router_info *ori)
|
||||||
{
|
{
|
||||||
u_int32_t cap;
|
u_int32_t cap = 0;
|
||||||
struct ospf *top;
|
struct ospf *top;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize default Router Information Capabilities.
|
* Initialize default Router Information Capabilities.
|
||||||
*/
|
*/
|
||||||
cap = 0;
|
cap = RI_TE_SUPPORT;
|
||||||
cap = cap | RI_TE_SUPPORT;
|
|
||||||
|
|
||||||
set_router_info_capabilities(&ori->router_cap, cap);
|
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;
|
| PCE_CAP_ADDITIVE | PCE_CAP_MULTIPLE_REQ;
|
||||||
set_pce_cap_flag(cap, &ori->pce_info);
|
set_pce_cap_flag(cap, &ori->pce_info);
|
||||||
|
|
||||||
/* Finally compute PCE header */
|
|
||||||
set_pce_header(&ori->pce_info);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -473,16 +461,15 @@ static int is_mandated_params_set(struct ospf_router_info ori)
|
|||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
if (ntohs(ori.router_cap.header.type) == 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)
|
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_address.header.type) == 0)
|
||||||
&& (ntohs(ori.pce_info.pce_cap_flag.header.type) == 0))
|
&& (ntohs(ori.pce_info.pce_cap_flag.header.type) == 0))
|
||||||
goto out;
|
return rc;
|
||||||
|
|
||||||
rc = 1;
|
rc = 1;
|
||||||
|
|
||||||
out:
|
|
||||||
return rc;
|
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,
|
static void ospf_router_info_nsm_change(struct ospf_neighbor *nbr,
|
||||||
int old_state)
|
int old_state)
|
||||||
{
|
{
|
||||||
|
|
||||||
/* So far, nothing to do here. */
|
/* So far, nothing to do here. */
|
||||||
return;
|
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
|
* 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;
|
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) {
|
if (ntohs(tlvh->type) != 0) {
|
||||||
build_tlv_header(s, tlvh);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
@ -535,9 +521,11 @@ static void ospf_router_info_lsa_body_set(struct stream *s)
|
|||||||
/* Build Router Information TLV */
|
/* Build Router Information TLV */
|
||||||
build_tlv(s, &OspfRI.router_cap.header);
|
build_tlv(s, &OspfRI.router_cap.header);
|
||||||
|
|
||||||
/* Add RI PCE TLV if it is set */
|
|
||||||
/* Compute PCE Info header first */
|
/* 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 PCE TLV */
|
||||||
build_tlv_header(s, &OspfRI.pce_info.pce_header.header);
|
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. */
|
/* Create a stream for LSA. */
|
||||||
if ((s = stream_new(OSPF_MAX_LSA_SIZE)) == NULL) {
|
if ((s = stream_new(OSPF_MAX_LSA_SIZE)) == NULL) {
|
||||||
zlog_warn("ospf_router_info_lsa_new: stream_new() ?");
|
zlog_warn("ospf_router_info_lsa_new: stream_new() ?");
|
||||||
goto out;
|
return NULL;
|
||||||
}
|
}
|
||||||
lsah = (struct lsa_header *)STREAM_DATA(s);
|
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) {
|
if ((new = ospf_lsa_new()) == NULL) {
|
||||||
zlog_warn("ospf_router_info_lsa_new: ospf_lsa_new() ?");
|
zlog_warn("ospf_router_info_lsa_new: ospf_lsa_new() ?");
|
||||||
stream_free(s);
|
stream_free(s);
|
||||||
goto out;
|
return NULL;
|
||||||
}
|
}
|
||||||
if ((new->data = ospf_lsa_data_new(length)) == NULL) {
|
if ((new->data = ospf_lsa_data_new(length)) == NULL) {
|
||||||
zlog_warn("ospf_router_info_lsa_new: ospf_lsa_data_new() ?");
|
zlog_warn("ospf_router_info_lsa_new: ospf_lsa_data_new() ?");
|
||||||
ospf_lsa_unlock(&new);
|
ospf_lsa_unlock(&new);
|
||||||
new = NULL;
|
new = NULL;
|
||||||
stream_free(s);
|
stream_free(s);
|
||||||
goto out;
|
return new;
|
||||||
}
|
}
|
||||||
|
|
||||||
new->area = OspfRI.area; /* Area must be null if the Opaque type is AS
|
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);
|
memcpy(new->data, lsah, length);
|
||||||
stream_free(s);
|
stream_free(s);
|
||||||
|
|
||||||
out:
|
|
||||||
return new;
|
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) {
|
if (area->area_id.s_addr != OspfRI.area_id.s_addr) {
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"RI -> This is not the Router Information Area. Stop processing");
|
"RI -> This is not the Router Information Area. Stop processing");
|
||||||
goto out;
|
return rc;
|
||||||
}
|
}
|
||||||
OspfRI.area = area;
|
OspfRI.area = area;
|
||||||
}
|
}
|
||||||
@ -657,7 +644,7 @@ static int ospf_router_info_lsa_originate1(void *arg)
|
|||||||
if ((new = ospf_router_info_lsa_new()) == NULL) {
|
if ((new = ospf_router_info_lsa_new()) == NULL) {
|
||||||
zlog_warn(
|
zlog_warn(
|
||||||
"ospf_router_info_lsa_originate1: ospf_router_info_lsa_new() ?");
|
"ospf_router_info_lsa_originate1: ospf_router_info_lsa_new() ?");
|
||||||
goto out;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get ospf info */
|
/* Get ospf info */
|
||||||
@ -668,7 +655,7 @@ static int ospf_router_info_lsa_originate1(void *arg)
|
|||||||
zlog_warn(
|
zlog_warn(
|
||||||
"ospf_router_info_lsa_originate1: ospf_lsa_install() ?");
|
"ospf_router_info_lsa_originate1: ospf_lsa_install() ?");
|
||||||
ospf_lsa_unlock(&new);
|
ospf_lsa_unlock(&new);
|
||||||
goto out;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now this Router Info parameter entry has associated LSA. */
|
/* Now this Router Info parameter entry has associated LSA. */
|
||||||
@ -691,7 +678,6 @@ static int ospf_router_info_lsa_originate1(void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
rc = 0;
|
rc = 0;
|
||||||
out:
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -700,17 +686,17 @@ static int ospf_router_info_lsa_originate(void *arg)
|
|||||||
|
|
||||||
int rc = -1;
|
int rc = -1;
|
||||||
|
|
||||||
if (OspfRI.status == disabled) {
|
if (!OspfRI.enabled) {
|
||||||
zlog_info(
|
zlog_info(
|
||||||
"ospf_router_info_lsa_originate: ROUTER INFORMATION is disabled now.");
|
"ospf_router_info_lsa_originate: ROUTER INFORMATION is disabled now.");
|
||||||
rc = 0; /* This is not an error case. */
|
rc = 0; /* This is not an error case. */
|
||||||
goto out;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if Router Information LSA is already engaged */
|
/* Check if Router Information LSA is already engaged */
|
||||||
if (OspfRI.flags & RIFLG_LSA_ENGAGED) {
|
if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED)) {
|
||||||
if (OspfRI.flags & RIFLG_LSA_FORCED_REFRESH) {
|
if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_FORCED_REFRESH)) {
|
||||||
OspfRI.flags &= ~RIFLG_LSA_FORCED_REFRESH;
|
UNSET_FLAG(OspfRI.flags, RIFLG_LSA_FORCED_REFRESH);
|
||||||
ospf_router_info_lsa_schedule(REFRESH_THIS_LSA);
|
ospf_router_info_lsa_schedule(REFRESH_THIS_LSA);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -720,11 +706,10 @@ static int ospf_router_info_lsa_originate(void *arg)
|
|||||||
|
|
||||||
/* Ok, let's try to originate an LSA */
|
/* Ok, let's try to originate an LSA */
|
||||||
if (ospf_router_info_lsa_originate1(arg) != 0)
|
if (ospf_router_info_lsa_originate1(arg) != 0)
|
||||||
goto out;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = 0;
|
rc = 0;
|
||||||
out:
|
|
||||||
return rc;
|
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_lsa *new = NULL;
|
||||||
struct ospf *top;
|
struct ospf *top;
|
||||||
|
|
||||||
if (OspfRI.status == disabled) {
|
if (!OspfRI.enabled) {
|
||||||
/*
|
/*
|
||||||
* This LSA must have flushed before due to ROUTER INFORMATION
|
* This LSA must have flushed before due to ROUTER INFORMATION
|
||||||
* status change.
|
* 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) {
|
if (GET_OPAQUE_ID(ntohl(lsa->data->id.s_addr)) != 0) {
|
||||||
zlog_warn(
|
zlog_warn(
|
||||||
"ospf_router_info_lsa_refresh: Unsupported Router Information ID");
|
"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 the lsa's age reached to MaxAge, start flushing procedure. */
|
||||||
if (IS_LSA_MAXAGE(lsa)) {
|
if (IS_LSA_MAXAGE(lsa)) {
|
||||||
OspfRI.flags &= ~RIFLG_LSA_ENGAGED;
|
UNSET_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED);
|
||||||
ospf_opaque_lsa_flush_schedule(lsa);
|
ospf_opaque_lsa_flush_schedule(lsa);
|
||||||
goto out;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create new Opaque-LSA/ROUTER INFORMATION instance. */
|
/* Create new Opaque-LSA/ROUTER INFORMATION instance. */
|
||||||
if ((new = ospf_router_info_lsa_new()) == NULL) {
|
if ((new = ospf_router_info_lsa_new()) == NULL) {
|
||||||
zlog_warn(
|
zlog_warn(
|
||||||
"ospf_router_info_lsa_refresh: ospf_router_info_lsa_new() ?");
|
"ospf_router_info_lsa_refresh: ospf_router_info_lsa_new() ?");
|
||||||
goto out;
|
return NULL;
|
||||||
}
|
}
|
||||||
new->data->ls_seqnum = lsa_seqnum_increment(lsa);
|
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) {
|
if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) {
|
||||||
zlog_warn("ospf_router_info_lsa_refresh: ospf_lsa_install() ?");
|
zlog_warn("ospf_router_info_lsa_refresh: ospf_lsa_install() ?");
|
||||||
ospf_lsa_unlock(&new);
|
ospf_lsa_unlock(&new);
|
||||||
goto out;
|
return new;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Flood updated LSA through AS or AREA depending of OspfRI.scope. */
|
/* 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);
|
ospf_lsa_header_dump(new->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
|
||||||
return new;
|
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 ospf_lsa lsa;
|
||||||
struct lsa_header lsah;
|
struct lsa_header lsah;
|
||||||
@ -809,6 +793,13 @@ static void ospf_router_info_lsa_schedule(opcode_t opcode)
|
|||||||
opcode == REFRESH_THIS_LSA ? "Refresh" : "",
|
opcode == REFRESH_THIS_LSA ? "Refresh" : "",
|
||||||
opcode == FLUSH_THIS_LSA ? "Flush" : "");
|
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();
|
top = ospf_lookup();
|
||||||
if ((OspfRI.scope == OSPF_OPAQUE_AREA_LSA) && (OspfRI.area == NULL)) {
|
if ((OspfRI.scope == OSPF_OPAQUE_AREA_LSA) && (OspfRI.area == NULL)) {
|
||||||
zlog_warn(
|
zlog_warn(
|
||||||
@ -838,7 +829,7 @@ static void ospf_router_info_lsa_schedule(opcode_t opcode)
|
|||||||
ospf_opaque_lsa_refresh_schedule(&lsa);
|
ospf_opaque_lsa_refresh_schedule(&lsa);
|
||||||
break;
|
break;
|
||||||
case FLUSH_THIS_LSA:
|
case FLUSH_THIS_LSA:
|
||||||
OspfRI.flags &= ~RIFLG_LSA_ENGAGED;
|
UNSET_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED);
|
||||||
ospf_opaque_lsa_flush_schedule(&lsa);
|
ospf_opaque_lsa_flush_schedule(&lsa);
|
||||||
break;
|
break;
|
||||||
default:
|
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,
|
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;
|
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
|
else
|
||||||
zlog_debug(" Router Capabilities: 0x%x", ntohl(top->value));
|
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,
|
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 *top =
|
||||||
(struct ri_pce_subtlv_address *)tlvh;
|
(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));
|
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,
|
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 *top =
|
||||||
(struct ri_pce_subtlv_path_scope *)tlvh;
|
(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
|
else
|
||||||
zlog_debug(" PCE Path Scope: 0x%x", ntohl(top->value));
|
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,
|
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 ri_pce_subtlv_domain *top = (struct ri_pce_subtlv_domain *)tlvh;
|
||||||
struct in_addr tmp;
|
struct in_addr tmp;
|
||||||
@ -927,11 +918,11 @@ static u_int16_t show_vty_pce_subtlv_domain(struct vty *vty,
|
|||||||
else
|
else
|
||||||
zlog_debug(" PCE domain AS: %d", ntohl(top->value));
|
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,
|
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 =
|
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",
|
zlog_debug(" PCE neighbor AS: %d",
|
||||||
ntohl(top->value));
|
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,
|
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 *top =
|
||||||
(struct ri_pce_subtlv_cap_flag *)tlvh;
|
(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",
|
zlog_debug(" PCE Capabilities Flag: 0x%x",
|
||||||
ntohl(top->value));
|
ntohl(top->value));
|
||||||
|
|
||||||
return RI_TLV_SIZE(tlvh);
|
return TLV_SIZE(tlvh);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u_int16_t show_vty_unknown_tlv(struct vty *vty,
|
static u_int16_t show_vty_unknown_tlv(struct vty *vty,
|
||||||
struct ri_tlv_header *tlvh)
|
struct tlv_header *tlvh)
|
||||||
{
|
{
|
||||||
if (vty != NULL)
|
if (vty != NULL)
|
||||||
vty_out(vty, " Unknown TLV: [type(0x%x), length(0x%x)]\n",
|
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)]",
|
zlog_debug(" Unknown TLV: [type(0x%x), length(0x%x)]",
|
||||||
ntohs(tlvh->type), ntohs(tlvh->length));
|
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)
|
uint32_t total)
|
||||||
{
|
{
|
||||||
struct ri_tlv_header *tlvh;
|
struct tlv_header *tlvh;
|
||||||
u_int16_t sum = 0;
|
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)) {
|
switch (ntohs(tlvh->type)) {
|
||||||
case RI_PCE_SUBTLV_ADDRESS:
|
case RI_PCE_SUBTLV_ADDRESS:
|
||||||
sum += show_vty_pce_subtlv_address(vty, tlvh);
|
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)
|
static void ospf_router_info_show_info(struct vty *vty, struct ospf_lsa *lsa)
|
||||||
{
|
{
|
||||||
struct lsa_header *lsah = (struct lsa_header *)lsa->data;
|
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;
|
u_int16_t length = 0, sum = 0;
|
||||||
|
|
||||||
/* Initialize TLV browsing */
|
/* Initialize TLV browsing */
|
||||||
length = ntohs(lsah->length) - OSPF_LSA_HEADER_SIZE;
|
length = ntohs(lsah->length) - OSPF_LSA_HEADER_SIZE;
|
||||||
|
|
||||||
for (tlvh = RI_TLV_HDR_TOP(lsah); sum < length;
|
for (tlvh = TLV_HDR_TOP(lsah); sum < length;
|
||||||
tlvh = RI_TLV_HDR_NEXT(tlvh)) {
|
tlvh = TLV_HDR_NEXT(tlvh)) {
|
||||||
switch (ntohs(tlvh->type)) {
|
switch (ntohs(tlvh->type)) {
|
||||||
case RI_TLV_CAPABILITIES:
|
case RI_TLV_CAPABILITIES:
|
||||||
sum += show_vty_router_cap(vty, tlvh);
|
sum += show_vty_router_cap(vty, tlvh);
|
||||||
break;
|
break;
|
||||||
case RI_TLV_PCE:
|
case RI_TLV_PCE:
|
||||||
tlvh++;
|
tlvh++;
|
||||||
sum += RI_TLV_HDR_SIZE;
|
sum += TLV_HDR_SIZE;
|
||||||
sum += show_vty_pce_info(vty, tlvh, length - sum);
|
sum += show_vty_pce_info(vty, tlvh, length - sum);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -1053,50 +1044,53 @@ static void ospf_router_info_config_write_router(struct vty *vty)
|
|||||||
struct ri_pce_subtlv_neighbor *neighbor;
|
struct ri_pce_subtlv_neighbor *neighbor;
|
||||||
struct in_addr tmp;
|
struct in_addr tmp;
|
||||||
|
|
||||||
if (OspfRI.status == enabled) {
|
if (OspfRI.enabled) {
|
||||||
if (OspfRI.scope == OSPF_OPAQUE_AS_LSA)
|
if (OspfRI.scope == OSPF_OPAQUE_AS_LSA)
|
||||||
vty_out(vty, " router-info as\n");
|
vty_out(vty, " router-info as\n");
|
||||||
else
|
else
|
||||||
vty_out(vty, " router-info area %s\n",
|
vty_out(vty, " router-info area %s\n",
|
||||||
inet_ntoa(OspfRI.area_id));
|
inet_ntoa(OspfRI.area_id));
|
||||||
|
|
||||||
if (pce->pce_address.header.type != 0)
|
if (OspfRI.pce_info.enabled) {
|
||||||
vty_out(vty, " pce address %s\n",
|
|
||||||
inet_ntoa(pce->pce_address.address.value));
|
|
||||||
|
|
||||||
if (pce->pce_cap_flag.header.type != 0)
|
if (pce->pce_address.header.type != 0)
|
||||||
vty_out(vty, " pce flag 0x%x\n",
|
vty_out(vty, " pce address %s\n",
|
||||||
ntohl(pce->pce_cap_flag.value));
|
inet_ntoa(pce->pce_address.address.value));
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(pce->pce_domain, node, domain)) {
|
if (pce->pce_cap_flag.header.type != 0)
|
||||||
if (domain->header.type != 0) {
|
vty_out(vty, " pce flag 0x%x\n",
|
||||||
if (domain->type == PCE_DOMAIN_TYPE_AREA) {
|
ntohl(pce->pce_cap_flag.value));
|
||||||
tmp.s_addr = domain->value;
|
|
||||||
vty_out(vty, " pce domain area %s\n",
|
for (ALL_LIST_ELEMENTS_RO(pce->pce_domain, node, domain)) {
|
||||||
inet_ntoa(tmp));
|
if (domain->header.type != 0) {
|
||||||
} else {
|
if (domain->type == PCE_DOMAIN_TYPE_AREA) {
|
||||||
vty_out(vty, " pce domain as %d\n",
|
tmp.s_addr = domain->value;
|
||||||
ntohl(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)) {
|
for (ALL_LIST_ELEMENTS_RO(pce->pce_neighbor, node, neighbor)) {
|
||||||
if (neighbor->header.type != 0) {
|
if (neighbor->header.type != 0) {
|
||||||
if (neighbor->type == PCE_DOMAIN_TYPE_AREA) {
|
if (neighbor->type == PCE_DOMAIN_TYPE_AREA) {
|
||||||
tmp.s_addr = neighbor->value;
|
tmp.s_addr = neighbor->value;
|
||||||
vty_out(vty, " pce neighbor area %s\n",
|
vty_out(vty, " pce neighbor area %s\n",
|
||||||
inet_ntoa(tmp));
|
inet_ntoa(tmp));
|
||||||
} else {
|
} else {
|
||||||
vty_out(vty, " pce neighbor as %d\n",
|
vty_out(vty, " pce neighbor as %d\n",
|
||||||
ntohl(neighbor->value));
|
ntohl(neighbor->value));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (pce->pce_scope.header.type != 0)
|
if (pce->pce_scope.header.type != 0)
|
||||||
vty_out(vty, " pce scope 0x%x\n",
|
vty_out(vty, " pce scope 0x%x\n",
|
||||||
ntohl(OspfRI.pce_info.pce_scope.value));
|
ntohl(OspfRI.pce_info.pce_scope.value));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1118,7 +1112,7 @@ DEFUN (router_info,
|
|||||||
|
|
||||||
u_int8_t scope;
|
u_int8_t scope;
|
||||||
|
|
||||||
if (OspfRI.status == enabled)
|
if (OspfRI.enabled)
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
|
|
||||||
/* Check and get Area value if present */
|
/* Check and get Area value if present */
|
||||||
@ -1137,11 +1131,11 @@ DEFUN (router_info,
|
|||||||
/* First start to register Router Information callbacks */
|
/* First start to register Router Information callbacks */
|
||||||
if ((ospf_router_info_register(scope)) != 0) {
|
if ((ospf_router_info_register(scope)) != 0) {
|
||||||
zlog_warn(
|
zlog_warn(
|
||||||
"Enable to register Router Information callbacks. Abort!");
|
"Unable to register Router Information callbacks. Abort!");
|
||||||
return CMD_WARNING_CONFIG_FAILED;
|
return CMD_WARNING_CONFIG_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
OspfRI.status = enabled;
|
OspfRI.enabled = true;
|
||||||
|
|
||||||
if (IS_DEBUG_OSPF_EVENT)
|
if (IS_DEBUG_OSPF_EVENT)
|
||||||
zlog_debug("RI-> Router Information (%s flooding): OFF -> ON",
|
zlog_debug("RI-> Router Information (%s flooding): OFF -> ON",
|
||||||
@ -1160,7 +1154,10 @@ DEFUN (router_info,
|
|||||||
initialize_params(&OspfRI);
|
initialize_params(&OspfRI);
|
||||||
|
|
||||||
/* Refresh RI LSA if already engaged */
|
/* 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");
|
zlog_debug("RI-> Initial origination following configuration");
|
||||||
ospf_router_info_lsa_schedule(REORIGINATE_THIS_LSA);
|
ospf_router_info_lsa_schedule(REORIGINATE_THIS_LSA);
|
||||||
}
|
}
|
||||||
@ -1175,26 +1172,26 @@ DEFUN (no_router_info,
|
|||||||
"Disable the Router Information functionality\n")
|
"Disable the Router Information functionality\n")
|
||||||
{
|
{
|
||||||
|
|
||||||
if (OspfRI.status == disabled)
|
if (!OspfRI.enabled)
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
|
|
||||||
if (IS_DEBUG_OSPF_EVENT)
|
if (IS_DEBUG_OSPF_EVENT)
|
||||||
zlog_debug("RI-> Router Information: ON -> OFF");
|
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);
|
ospf_router_info_lsa_schedule(FLUSH_THIS_LSA);
|
||||||
|
|
||||||
/* Unregister the callbacks */
|
/* Unregister the callbacks */
|
||||||
ospf_router_info_unregister();
|
ospf_router_info_unregister();
|
||||||
|
|
||||||
OspfRI.status = disabled;
|
OspfRI.enabled = false;
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ospf_ri_enabled(struct vty *vty)
|
static int ospf_ri_enabled(struct vty *vty)
|
||||||
{
|
{
|
||||||
if (OspfRI.status == enabled)
|
if (OspfRI.enabled)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (vty)
|
if (vty)
|
||||||
@ -1229,7 +1226,7 @@ DEFUN (pce_address,
|
|||||||
set_pce_address(value, pi);
|
set_pce_address(value, pi);
|
||||||
|
|
||||||
/* Refresh RI LSA if already engaged */
|
/* 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);
|
ospf_router_info_lsa_schedule(REFRESH_THIS_LSA);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1248,7 +1245,7 @@ DEFUN (no_pce_address,
|
|||||||
unset_param(&OspfRI.pce_info.pce_address.header);
|
unset_param(&OspfRI.pce_info.pce_address.header);
|
||||||
|
|
||||||
/* Refresh RI LSA if already engaged */
|
/* 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);
|
ospf_router_info_lsa_schedule(REFRESH_THIS_LSA);
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
@ -1279,7 +1276,7 @@ DEFUN (pce_path_scope,
|
|||||||
set_pce_path_scope(scope, pi);
|
set_pce_path_scope(scope, pi);
|
||||||
|
|
||||||
/* Refresh RI LSA if already engaged */
|
/* 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);
|
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);
|
unset_param(&OspfRI.pce_info.pce_address.header);
|
||||||
|
|
||||||
/* Refresh RI LSA if already engaged */
|
/* 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);
|
ospf_router_info_lsa_schedule(REFRESH_THIS_LSA);
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
@ -1337,7 +1334,7 @@ DEFUN (pce_domain,
|
|||||||
set_pce_domain(PCE_DOMAIN_TYPE_AS, as, pce);
|
set_pce_domain(PCE_DOMAIN_TYPE_AS, as, pce);
|
||||||
|
|
||||||
/* Refresh RI LSA if already engaged */
|
/* 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);
|
ospf_router_info_lsa_schedule(REFRESH_THIS_LSA);
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
@ -1367,7 +1364,7 @@ DEFUN (no_pce_domain,
|
|||||||
unset_pce_domain(PCE_DOMAIN_TYPE_AS, as, pce);
|
unset_pce_domain(PCE_DOMAIN_TYPE_AS, as, pce);
|
||||||
|
|
||||||
/* Refresh RI LSA if already engaged */
|
/* 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);
|
ospf_router_info_lsa_schedule(REFRESH_THIS_LSA);
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
@ -1407,7 +1404,7 @@ DEFUN (pce_neigbhor,
|
|||||||
set_pce_neighbor(PCE_DOMAIN_TYPE_AS, as, pce);
|
set_pce_neighbor(PCE_DOMAIN_TYPE_AS, as, pce);
|
||||||
|
|
||||||
/* Refresh RI LSA if already engaged */
|
/* 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);
|
ospf_router_info_lsa_schedule(REFRESH_THIS_LSA);
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
@ -1437,7 +1434,7 @@ DEFUN (no_pce_neighbor,
|
|||||||
unset_pce_neighbor(PCE_DOMAIN_TYPE_AS, as, pce);
|
unset_pce_neighbor(PCE_DOMAIN_TYPE_AS, as, pce);
|
||||||
|
|
||||||
/* Refresh RI LSA if already engaged */
|
/* 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);
|
ospf_router_info_lsa_schedule(REFRESH_THIS_LSA);
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
@ -1469,7 +1466,7 @@ DEFUN (pce_cap_flag,
|
|||||||
set_pce_cap_flag(cap, pce);
|
set_pce_cap_flag(cap, pce);
|
||||||
|
|
||||||
/* Refresh RI LSA if already engaged */
|
/* 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);
|
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);
|
unset_param(&OspfRI.pce_info.pce_cap_flag.header);
|
||||||
|
|
||||||
/* Refresh RI LSA if already engaged */
|
/* 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);
|
ospf_router_info_lsa_schedule(REFRESH_THIS_LSA);
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
@ -1502,7 +1499,7 @@ DEFUN (show_ip_ospf_router_info,
|
|||||||
"Router Information\n")
|
"Router Information\n")
|
||||||
{
|
{
|
||||||
|
|
||||||
if (OspfRI.status == enabled) {
|
if (OspfRI.enabled) {
|
||||||
vty_out(vty, "--- Router Information parameters ---\n");
|
vty_out(vty, "--- Router Information parameters ---\n");
|
||||||
show_vty_router_cap(vty, &OspfRI.router_cap.header);
|
show_vty_router_cap(vty, &OspfRI.router_cap.header);
|
||||||
} else {
|
} else {
|
||||||
@ -1528,7 +1525,7 @@ DEFUN (show_ip_opsf_router_info_pce,
|
|||||||
struct ri_pce_subtlv_domain *domain;
|
struct ri_pce_subtlv_domain *domain;
|
||||||
struct ri_pce_subtlv_neighbor *neighbor;
|
struct ri_pce_subtlv_neighbor *neighbor;
|
||||||
|
|
||||||
if (OspfRI.status == enabled) {
|
if (OspfRI.enabled) {
|
||||||
vty_out(vty, "--- PCE parameters ---\n");
|
vty_out(vty, "--- PCE parameters ---\n");
|
||||||
|
|
||||||
if (pce->pce_address.header.type != 0)
|
if (pce->pce_address.header.type != 0)
|
||||||
|
@ -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.
|
* Following section defines TLV body parts.
|
||||||
*/
|
*/
|
||||||
@ -91,7 +76,7 @@ struct ri_tlv_header {
|
|||||||
#define RI_TLV_CAPABILITIES 1
|
#define RI_TLV_CAPABILITIES 1
|
||||||
|
|
||||||
struct ri_tlv_router_cap {
|
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;
|
u_int32_t value;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -109,23 +94,19 @@ struct ri_tlv_router_cap {
|
|||||||
#define RI_TLV_PCE 6
|
#define RI_TLV_PCE 6
|
||||||
|
|
||||||
struct ri_tlv_pce {
|
struct ri_tlv_pce {
|
||||||
struct ri_tlv_header header;
|
struct tlv_header header;
|
||||||
/* A set of PCE-sub-TLVs will follow. */
|
/* A set of PCE-sub-TLVs will follow. */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* PCE Address Sub-TLV */ /* Mandatory */
|
/* PCE Address Sub-TLV */ /* Mandatory */
|
||||||
#define RI_PCE_SUBTLV_ADDRESS 1
|
#define RI_PCE_SUBTLV_ADDRESS 1
|
||||||
struct ri_pce_subtlv_address {
|
struct ri_pce_subtlv_address {
|
||||||
struct ri_tlv_header
|
/* Type = 1; Length is 8 (IPv4) or 20 (IPv6) bytes. */
|
||||||
header; /* Type = 1; Length is 8 (IPv4) or 20 (IPv6) bytes. */
|
struct tlv_header header;
|
||||||
/* $FRR indent$ */
|
|
||||||
/* clang-format off */
|
|
||||||
#define PCE_ADDRESS_LENGTH_IPV4 8
|
#define PCE_ADDRESS_LENGTH_IPV4 8
|
||||||
#define PCE_ADDRESS_LENGTH_IPV6 20
|
#define PCE_ADDRESS_LENGTH_IPV6 20
|
||||||
struct {
|
struct {
|
||||||
u_int16_t type; /* Address type: 1 = IPv4, 2 = IPv6 */
|
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_IPV4 1
|
||||||
#define PCE_ADDRESS_TYPE_IPV6 2
|
#define PCE_ADDRESS_TYPE_IPV6 2
|
||||||
u_int16_t reserved;
|
u_int16_t reserved;
|
||||||
@ -136,9 +117,12 @@ struct ri_pce_subtlv_address {
|
|||||||
/* PCE Path-Scope Sub-TLV */ /* Mandatory */
|
/* PCE Path-Scope Sub-TLV */ /* Mandatory */
|
||||||
#define RI_PCE_SUBTLV_PATH_SCOPE 2
|
#define RI_PCE_SUBTLV_PATH_SCOPE 2
|
||||||
struct ri_pce_subtlv_path_scope {
|
struct ri_pce_subtlv_path_scope {
|
||||||
struct ri_tlv_header header; /* Type = 2; Length = 4 bytes. */
|
struct 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 */
|
* 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 */
|
/* PCE Domain Sub-TLV */ /* Optional */
|
||||||
@ -148,7 +132,7 @@ struct ri_pce_subtlv_path_scope {
|
|||||||
#define PCE_DOMAIN_TYPE_AS 2
|
#define PCE_DOMAIN_TYPE_AS 2
|
||||||
|
|
||||||
struct ri_pce_subtlv_domain {
|
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 type; /* Domain type: 1 = OSPF Area ID, 2 = AS Number */
|
||||||
u_int16_t reserved;
|
u_int16_t reserved;
|
||||||
u_int32_t value;
|
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 */
|
/* PCE Neighbor Sub-TLV */ /* Mandatory if R or S bit is set */
|
||||||
#define RI_PCE_SUBTLV_NEIGHBOR 4
|
#define RI_PCE_SUBTLV_NEIGHBOR 4
|
||||||
struct ri_pce_subtlv_neighbor {
|
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 type; /* Domain type: 1 = OSPF Area ID, 2 = AS Number */
|
||||||
u_int16_t reserved;
|
u_int16_t reserved;
|
||||||
u_int32_t value;
|
u_int32_t value;
|
||||||
@ -177,7 +161,7 @@ struct ri_pce_subtlv_neighbor {
|
|||||||
#define PCE_CAP_MULTIPLE_REQ 0x0100
|
#define PCE_CAP_MULTIPLE_REQ 0x0100
|
||||||
|
|
||||||
struct ri_pce_subtlv_cap_flag {
|
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;
|
u_int32_t value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
337
ospfd/ospf_te.c
337
ospfd/ospf_te.c
@ -68,9 +68,7 @@
|
|||||||
*/
|
*/
|
||||||
struct ospf_mpls_te OspfMplsTE;
|
struct ospf_mpls_te OspfMplsTE;
|
||||||
|
|
||||||
const char *mode2text[] = {"Disable", "AS", "Area", "Emulate"};
|
const char *mode2text[] = {"Off", "AS", "Area"};
|
||||||
|
|
||||||
enum oifstate { OI_ANY, OI_DOWN, OI_UP };
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*
|
/*------------------------------------------------------------------------*
|
||||||
* Followings are initialize/terminate functions for MPLS-TE handling.
|
* Followings are initialize/terminate functions for MPLS-TE handling.
|
||||||
@ -106,29 +104,28 @@ int ospf_mpls_te_init(void)
|
|||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
zlog_warn(
|
zlog_warn(
|
||||||
"ospf_mpls_te_init: Failed to register Traffic Engineering functions");
|
"ospf_mpls_te_init: Failed to register Traffic Engineering functions");
|
||||||
goto out;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&OspfMplsTE, 0, sizeof(struct ospf_mpls_te));
|
memset(&OspfMplsTE, 0, sizeof(struct ospf_mpls_te));
|
||||||
OspfMplsTE.status = disabled;
|
OspfMplsTE.enabled = false;
|
||||||
OspfMplsTE.inter_as = Disable;
|
OspfMplsTE.inter_as = Off;
|
||||||
OspfMplsTE.iflist = list_new();
|
OspfMplsTE.iflist = list_new();
|
||||||
OspfMplsTE.iflist->del = del_mpls_te_link;
|
OspfMplsTE.iflist->del = del_mpls_te_link;
|
||||||
|
|
||||||
ospf_mpls_te_register_vty();
|
ospf_mpls_te_register_vty();
|
||||||
|
|
||||||
out:
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Additional register for RFC5392 support */
|
/* Additional register for RFC5392 support */
|
||||||
static int ospf_mpls_te_register(enum inter_as_mode mode)
|
static int ospf_mpls_te_register(enum inter_as_mode mode)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc = 0;
|
||||||
u_int8_t scope;
|
u_int8_t scope;
|
||||||
|
|
||||||
if (OspfMplsTE.inter_as != Disable)
|
if (OspfMplsTE.inter_as != Off)
|
||||||
return 0;
|
return rc;
|
||||||
|
|
||||||
if (mode == AS)
|
if (mode == AS)
|
||||||
scope = OSPF_OPAQUE_AS_LSA;
|
scope = OSPF_OPAQUE_AS_LSA;
|
||||||
@ -147,14 +144,14 @@ static int ospf_mpls_te_register(enum inter_as_mode mode)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ospf_mpls_te_unregister()
|
static int ospf_mpls_te_unregister()
|
||||||
{
|
{
|
||||||
u_int8_t scope;
|
u_int8_t scope;
|
||||||
|
|
||||||
if (OspfMplsTE.inter_as == Disable)
|
if (OspfMplsTE.inter_as == Off)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (OspfMplsTE.inter_as == AS)
|
if (OspfMplsTE.inter_as == AS)
|
||||||
@ -174,10 +171,10 @@ void ospf_mpls_te_term(void)
|
|||||||
|
|
||||||
ospf_delete_opaque_functab(OSPF_OPAQUE_AREA_LSA,
|
ospf_delete_opaque_functab(OSPF_OPAQUE_AREA_LSA,
|
||||||
OPAQUE_TYPE_TRAFFIC_ENGINEERING_LSA);
|
OPAQUE_TYPE_TRAFFIC_ENGINEERING_LSA);
|
||||||
OspfMplsTE.status = disabled;
|
OspfMplsTE.enabled = false;
|
||||||
|
|
||||||
ospf_mpls_te_unregister();
|
ospf_mpls_te_unregister();
|
||||||
OspfMplsTE.inter_as = Disable;
|
OspfMplsTE.inter_as = Off;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -192,7 +189,7 @@ static void del_mpls_te_link(void *val)
|
|||||||
return;
|
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;
|
static u_int32_t seqno = 0;
|
||||||
|
|
||||||
@ -204,41 +201,6 @@ u_int32_t get_mpls_te_instance_value(void)
|
|||||||
return seqno;
|
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)
|
static struct mpls_te_link *lookup_linkparams_by_ifp(struct interface *ifp)
|
||||||
{
|
{
|
||||||
struct listnode *node, *nnode;
|
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,
|
static void ospf_mpls_te_foreach_area(void (*func)(struct mpls_te_link *lp,
|
||||||
opcode_t sched_opcode),
|
enum lsa_opcode sched_opcode),
|
||||||
opcode_t sched_opcode)
|
enum lsa_opcode sched_opcode)
|
||||||
{
|
{
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
struct listnode *node2;
|
struct listnode *node2;
|
||||||
@ -281,8 +243,8 @@ static void ospf_mpls_te_foreach_area(void (*func)(struct mpls_te_link *lp,
|
|||||||
continue;
|
continue;
|
||||||
if ((area = lp->area) == NULL)
|
if ((area = lp->area) == NULL)
|
||||||
continue;
|
continue;
|
||||||
if
|
if (CHECK_FLAG(lp->flags, LPFLG_LOOKUP_DONE))
|
||||||
CHECK_FLAG(lp->flags, LPFLG_LOOKUP_DONE) continue;
|
continue;
|
||||||
|
|
||||||
if (func != NULL)
|
if (func != NULL)
|
||||||
(*func)(lp, sched_opcode);
|
(*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)
|
static void initialize_linkparams(struct mpls_te_link *lp)
|
||||||
{
|
{
|
||||||
struct interface *ifp = lp->ifp;
|
struct interface *ifp = lp->ifp;
|
||||||
struct ospf_interface *oi;
|
struct ospf_interface *oi = NULL;
|
||||||
|
struct route_node *rn;
|
||||||
|
|
||||||
if (IS_DEBUG_OSPF_TE)
|
if (IS_DEBUG_OSPF_TE)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"MPLS-TE(initialize_linkparams) Initialize Link Parameters for interface %s",
|
"MPLS-TE(initialize_linkparams) Initialize Link Parameters for interface %s",
|
||||||
ifp->name);
|
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)
|
if (IS_DEBUG_OSPF_TE)
|
||||||
zlog_warn(
|
zlog_warn(
|
||||||
"MPLS-TE(initialize_linkparams) Could not find corresponding OSPF Interface for %s",
|
"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_linkparams_lclif_ipaddr(lp, oi->address->u.prefix4);
|
||||||
|
|
||||||
/* Set Remote IP addr if Point to Point Interface */
|
/* 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);
|
struct prefix *pref = CONNECTED_PREFIX(oi->connected);
|
||||||
if (pref != NULL)
|
if (pref != NULL)
|
||||||
set_linkparams_rmtif_ipaddr(lp, pref->u.prefix4);
|
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) {
|
if (ntohs(OspfMplsTE.router_addr.header.type) == 0) {
|
||||||
zlog_warn(
|
zlog_warn(
|
||||||
"MPLS-TE(is_mandated_params_set) Missing Router Address");
|
"MPLS-TE(is_mandated_params_set) Missing Router Address");
|
||||||
goto out;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ntohs(lp->link_type.header.type) == 0) {
|
if (ntohs(lp->link_type.header.type) == 0) {
|
||||||
zlog_warn("MPLS-TE(is_mandated_params_set) Missing Link Type");
|
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)) {
|
if (!IS_INTER_AS(lp->type) && (ntohs(lp->link_id.header.type) == 0)) {
|
||||||
zlog_warn("MPLS-TE(is_mandated_params_set) Missing Link ID");
|
zlog_warn("MPLS-TE(is_mandated_params_set) Missing Link ID");
|
||||||
goto out;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = 1;
|
rc = 1;
|
||||||
out:
|
|
||||||
return rc;
|
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?",
|
zlog_warn("ospf_mpls_te_new_if: ifp(%p) already in use?",
|
||||||
(void *)ifp);
|
(void *)ifp);
|
||||||
rc = 0; /* Do nothing here. */
|
rc = 0; /* Do nothing here. */
|
||||||
goto out;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
new = XCALLOC(MTYPE_OSPF_MPLS_TE, sizeof(struct mpls_te_link));
|
new = XCALLOC(MTYPE_OSPF_MPLS_TE, sizeof(struct mpls_te_link));
|
||||||
if (new == NULL) {
|
if (new == NULL) {
|
||||||
zlog_warn("ospf_mpls_te_new_if: XMALLOC: %s",
|
zlog_warn("ospf_mpls_te_new_if: XMALLOC: %s",
|
||||||
safe_strerror(errno));
|
safe_strerror(errno));
|
||||||
goto out;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
new->instance = get_mpls_te_instance_value();
|
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 */
|
/* Schedule Opaque-LSA refresh. */ /* XXX */
|
||||||
|
|
||||||
rc = 0;
|
rc = 0;
|
||||||
out:
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -934,7 +905,6 @@ static int ospf_mpls_te_del_if(struct interface *ifp)
|
|||||||
/* Schedule Opaque-LSA refresh. */ /* XXX */
|
/* Schedule Opaque-LSA refresh. */ /* XXX */
|
||||||
|
|
||||||
rc = 0;
|
rc = 0;
|
||||||
/*out:*/
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -952,10 +922,9 @@ void ospf_mpls_te_update_if(struct interface *ifp)
|
|||||||
|
|
||||||
/* Get Link context from interface */
|
/* Get Link context from interface */
|
||||||
if ((lp = lookup_linkparams_by_ifp(ifp)) == NULL) {
|
if ((lp = lookup_linkparams_by_ifp(ifp)) == NULL) {
|
||||||
if (IS_DEBUG_OSPF_TE)
|
zlog_warn(
|
||||||
zlog_warn(
|
"OSPF MPLS-TE Update: Did not find Link Parameters context for interface %s",
|
||||||
"OSPF MPLS-TE Update: Did not find Link Parameters context for interface %s",
|
ifp->name);
|
||||||
ifp->name);
|
|
||||||
return;
|
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
|
/* Finally Re-Originate or Refresh Opaque LSA if MPLS_TE is
|
||||||
* enabled */
|
* enabled */
|
||||||
if (OspfMplsTE.status == enabled)
|
if (OspfMplsTE.enabled)
|
||||||
if (lp->area != NULL) {
|
if (lp->area != NULL) {
|
||||||
if
|
if (CHECK_FLAG(lp->flags, LPFLG_LSA_ENGAGED))
|
||||||
CHECK_FLAG(lp->flags, LPFLG_LSA_ENGAGED)
|
ospf_mpls_te_lsa_schedule(lp, REFRESH_THIS_LSA);
|
||||||
ospf_mpls_te_lsa_schedule(lp, REFRESH_THIS_LSA);
|
else
|
||||||
else ospf_mpls_te_lsa_schedule(
|
ospf_mpls_te_lsa_schedule(lp, REORIGINATE_THIS_LSA);
|
||||||
lp, REORIGINATE_THIS_LSA);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* If MPLS TE is disable on this interface, flush LSA if it is
|
/* If MPLS TE is disable on this interface, flush LSA if it is
|
||||||
* already engaged */
|
* already engaged */
|
||||||
if
|
if (CHECK_FLAG(lp->flags, LPFLG_LSA_ENGAGED))
|
||||||
CHECK_FLAG(lp->flags, LPFLG_LSA_ENGAGED)
|
ospf_mpls_te_lsa_schedule(lp, FLUSH_THIS_LSA);
|
||||||
ospf_mpls_te_lsa_schedule(lp, FLUSH_THIS_LSA);
|
|
||||||
else
|
else
|
||||||
/* Reset Activity flag */
|
/* Reset Activity flag */
|
||||||
lp->flags = LPFLG_LSA_INACTIVE;
|
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(
|
zlog_warn(
|
||||||
"ospf_mpls_te_ism_change: Cannot get linkparams from OI(%s)?",
|
"ospf_mpls_te_ism_change: Cannot get linkparams from OI(%s)?",
|
||||||
IF_NAME(oi));
|
IF_NAME(oi));
|
||||||
goto out;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oi->area == NULL || oi->area->ospf == NULL) {
|
if (oi->area == NULL || oi->area->ospf == NULL) {
|
||||||
zlog_warn(
|
zlog_warn(
|
||||||
"ospf_mpls_te_ism_change: Cannot refer to OSPF from OI(%s)?",
|
"ospf_mpls_te_ism_change: Cannot refer to OSPF from OI(%s)?",
|
||||||
IF_NAME(oi));
|
IF_NAME(oi));
|
||||||
goto out;
|
return;
|
||||||
}
|
}
|
||||||
#ifdef notyet
|
#ifdef notyet
|
||||||
if ((lp->area != NULL
|
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)
|
!= ntohs(lp->link_id.header.type)
|
||||||
|| ntohl(old_id.value.s_addr)
|
|| ntohl(old_id.value.s_addr)
|
||||||
!= ntohl(lp->link_id.value.s_addr))) {
|
!= ntohl(lp->link_id.value.s_addr))) {
|
||||||
if
|
if (CHECK_FLAG(lp->flags, LPFLG_LSA_ENGAGED))
|
||||||
CHECK_FLAG(lp->flags, LPFLG_LSA_ENGAGED)
|
ospf_mpls_te_lsa_schedule(lp, REFRESH_THIS_LSA);
|
||||||
ospf_mpls_te_lsa_schedule(lp, REFRESH_THIS_LSA);
|
else
|
||||||
else ospf_mpls_te_lsa_schedule(lp,
|
ospf_mpls_te_lsa_schedule(lp, REORIGINATE_THIS_LSA);
|
||||||
REORIGINATE_THIS_LSA);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
lp->link_type.header.type = htons(0);
|
lp->link_type.header.type = htons(0);
|
||||||
lp->link_id.header.type = htons(0);
|
lp->link_id.header.type = htons(0);
|
||||||
|
|
||||||
if
|
if (CHECK_FLAG(lp->flags, LPFLG_LSA_ENGAGED))
|
||||||
CHECK_FLAG(lp->flags, LPFLG_LSA_ENGAGED)
|
ospf_mpls_te_lsa_schedule(lp, FLUSH_THIS_LSA);
|
||||||
ospf_mpls_te_lsa_schedule(lp, FLUSH_THIS_LSA);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
|
||||||
return;
|
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.
|
* 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void build_router_tlv(struct stream *s)
|
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) {
|
if (ntohs(tlvh->type) != 0) {
|
||||||
build_tlv_header(s, tlvh);
|
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;
|
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)) {
|
if ((tlvh != NULL) && (ntohs(tlvh->type) != 0)) {
|
||||||
build_tlv_header(s, tlvh);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
@ -1177,7 +1141,7 @@ static struct ospf_lsa *ospf_mpls_te_lsa_new(struct ospf_area *area,
|
|||||||
/* Create a stream for LSA. */
|
/* Create a stream for LSA. */
|
||||||
if ((s = stream_new(OSPF_MAX_LSA_SIZE)) == NULL) {
|
if ((s = stream_new(OSPF_MAX_LSA_SIZE)) == NULL) {
|
||||||
zlog_warn("ospf_mpls_te_lsa_new: stream_new() ?");
|
zlog_warn("ospf_mpls_te_lsa_new: stream_new() ?");
|
||||||
goto out;
|
return NULL;
|
||||||
}
|
}
|
||||||
lsah = (struct lsa_header *)STREAM_DATA(s);
|
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) {
|
if ((new = ospf_lsa_new()) == NULL) {
|
||||||
zlog_warn("ospf_mpls_te_lsa_new: ospf_lsa_new() ?");
|
zlog_warn("ospf_mpls_te_lsa_new: ospf_lsa_new() ?");
|
||||||
stream_free(s);
|
stream_free(s);
|
||||||
goto out;
|
return NULL;
|
||||||
}
|
}
|
||||||
if ((new->data = ospf_lsa_data_new(length)) == NULL) {
|
if ((new->data = ospf_lsa_data_new(length)) == NULL) {
|
||||||
zlog_warn("ospf_mpls_te_lsa_new: ospf_lsa_data_new() ?");
|
zlog_warn("ospf_mpls_te_lsa_new: ospf_lsa_data_new() ?");
|
||||||
ospf_lsa_unlock(&new);
|
ospf_lsa_unlock(&new);
|
||||||
new = NULL;
|
new = NULL;
|
||||||
stream_free(s);
|
stream_free(s);
|
||||||
goto out;
|
return new;
|
||||||
}
|
}
|
||||||
|
|
||||||
new->area = area;
|
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);
|
memcpy(new->data, lsah, length);
|
||||||
stream_free(s);
|
stream_free(s);
|
||||||
|
|
||||||
out:
|
|
||||||
return new;
|
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) {
|
if ((new = ospf_mpls_te_lsa_new(area, lp)) == NULL) {
|
||||||
zlog_warn(
|
zlog_warn(
|
||||||
"ospf_mpls_te_lsa_originate1: ospf_mpls_te_lsa_new() ?");
|
"ospf_mpls_te_lsa_originate1: ospf_mpls_te_lsa_new() ?");
|
||||||
goto out;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Install this LSA into LSDB. */
|
/* Install this LSA into LSDB. */
|
||||||
if (ospf_lsa_install(area->ospf, NULL /*oi*/, new) == NULL) {
|
if (ospf_lsa_install(area->ospf, NULL /*oi*/, new) == NULL) {
|
||||||
zlog_warn("ospf_mpls_te_lsa_originate1: ospf_lsa_install() ?");
|
zlog_warn("ospf_mpls_te_lsa_originate1: ospf_lsa_install() ?");
|
||||||
ospf_lsa_unlock(&new);
|
ospf_lsa_unlock(&new);
|
||||||
goto out;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now this link-parameter entry has associated LSA. */
|
/* 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;
|
rc = 0;
|
||||||
out:
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1302,11 +1264,11 @@ static int ospf_mpls_te_lsa_originate_area(void *arg)
|
|||||||
struct mpls_te_link *lp;
|
struct mpls_te_link *lp;
|
||||||
int rc = -1;
|
int rc = -1;
|
||||||
|
|
||||||
if (OspfMplsTE.status == disabled) {
|
if (!OspfMplsTE.enabled) {
|
||||||
zlog_info(
|
zlog_info(
|
||||||
"ospf_mpls_te_lsa_originate_area: MPLS-TE is disabled now.");
|
"ospf_mpls_te_lsa_originate_area: MPLS-TE is disabled now.");
|
||||||
rc = 0; /* This is not an error case. */
|
rc = 0; /* This is not an error case. */
|
||||||
goto out;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS(OspfMplsTE.iflist, node, nnode, lp)) {
|
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))
|
if (!IPV4_ADDR_SAME(&lp->area->area_id, &area->area_id))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if
|
if (CHECK_FLAG(lp->flags, LPFLG_LSA_ENGAGED)) {
|
||||||
CHECK_FLAG(lp->flags, LPFLG_LSA_ENGAGED)
|
if (CHECK_FLAG(lp->flags, LPFLG_LSA_FORCED_REFRESH)) {
|
||||||
{
|
UNSET_FLAG(lp->flags, LPFLG_LSA_FORCED_REFRESH);
|
||||||
if
|
zlog_warn(
|
||||||
CHECK_FLAG(lp->flags,
|
"OSPF MPLS-TE (ospf_mpls_te_lsa_originate_area): Refresh instead of Originate");
|
||||||
LPFLG_LSA_FORCED_REFRESH)
|
ospf_mpls_te_lsa_schedule(lp, REFRESH_THIS_LSA);
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (!is_mandated_params_set(lp)) {
|
if (!is_mandated_params_set(lp)) {
|
||||||
zlog_warn(
|
zlog_warn(
|
||||||
"ospf_mpls_te_lsa_originate_area: Link(%s) lacks some mandated MPLS-TE parameters.",
|
"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->instance, inet_ntoa(area->area_id),
|
||||||
lp->ifp ? lp->ifp->name : "?");
|
lp->ifp ? lp->ifp->name : "?");
|
||||||
if (ospf_mpls_te_lsa_originate1(area, lp) != 0)
|
if (ospf_mpls_te_lsa_originate1(area, lp) != 0)
|
||||||
goto out;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = 0;
|
rc = 0;
|
||||||
out:
|
|
||||||
return rc;
|
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) {
|
if ((new = ospf_mpls_te_lsa_new(NULL, lp)) == NULL) {
|
||||||
zlog_warn(
|
zlog_warn(
|
||||||
"ospf_mpls_te_lsa_originate2: ospf_router_info_lsa_new() ?");
|
"ospf_mpls_te_lsa_originate2: ospf_router_info_lsa_new() ?");
|
||||||
goto out;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Install this LSA into LSDB. */
|
/* Install this LSA into LSDB. */
|
||||||
if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) {
|
if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) {
|
||||||
zlog_warn("ospf_mpls_te_lsa_originate2: ospf_lsa_install() ?");
|
zlog_warn("ospf_mpls_te_lsa_originate2: ospf_lsa_install() ?");
|
||||||
ospf_lsa_unlock(&new);
|
ospf_lsa_unlock(&new);
|
||||||
goto out;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now this Router Info parameter entry has associated LSA. */
|
/* 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;
|
rc = 0;
|
||||||
out:
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1408,12 +1361,12 @@ static int ospf_mpls_te_lsa_originate_as(void *arg)
|
|||||||
struct mpls_te_link *lp;
|
struct mpls_te_link *lp;
|
||||||
int rc = -1;
|
int rc = -1;
|
||||||
|
|
||||||
if ((OspfMplsTE.status == disabled)
|
if ((!OspfMplsTE.enabled)
|
||||||
|| (OspfMplsTE.inter_as == Disable)) {
|
|| (OspfMplsTE.inter_as == Off)) {
|
||||||
zlog_info(
|
zlog_info(
|
||||||
"ospf_mpls_te_lsa_originate_as: MPLS-TE Inter-AS is disabled for now.");
|
"ospf_mpls_te_lsa_originate_as: MPLS-TE Inter-AS is disabled for now.");
|
||||||
rc = 0; /* This is not an error case. */
|
rc = 0; /* This is not an error case. */
|
||||||
goto out;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS(OspfMplsTE.iflist, node, nnode, lp)) {
|
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))
|
|| !IS_INTER_AS(lp->type))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if
|
if (CHECK_FLAG(lp->flags, LPFLG_LSA_ENGAGED)) {
|
||||||
CHECK_FLAG(lp->flags, LPFLG_LSA_ENGAGED)
|
if (CHECK_FLAG(lp->flags, LPFLG_LSA_FORCED_REFRESH)) {
|
||||||
{
|
UNSET_FLAG(lp->flags,LPFLG_LSA_FORCED_REFRESH);
|
||||||
if
|
ospf_mpls_te_lsa_schedule(lp, REFRESH_THIS_LSA);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (!is_mandated_params_set(lp)) {
|
if (!is_mandated_params_set(lp)) {
|
||||||
zlog_warn(
|
zlog_warn(
|
||||||
"ospf_mpls_te_lsa_originate_as: Link(%s) lacks some mandated MPLS-TE parameters.",
|
"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;
|
rc = 0;
|
||||||
out:
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1473,7 +1418,7 @@ static struct ospf_lsa *ospf_mpls_te_lsa_refresh(struct ospf_lsa *lsa)
|
|||||||
struct ospf *top;
|
struct ospf *top;
|
||||||
struct ospf_lsa *new = NULL;
|
struct ospf_lsa *new = NULL;
|
||||||
|
|
||||||
if (OspfMplsTE.status == disabled) {
|
if (!OspfMplsTE.enabled) {
|
||||||
/*
|
/*
|
||||||
* This LSA must have flushed before due to MPLS-TE status
|
* This LSA must have flushed before due to MPLS-TE status
|
||||||
* change.
|
* change.
|
||||||
@ -1504,13 +1449,13 @@ static struct ospf_lsa *ospf_mpls_te_lsa_refresh(struct ospf_lsa *lsa)
|
|||||||
if (lp)
|
if (lp)
|
||||||
UNSET_FLAG(lp->flags, LPFLG_LSA_ENGAGED);
|
UNSET_FLAG(lp->flags, LPFLG_LSA_ENGAGED);
|
||||||
ospf_opaque_lsa_flush_schedule(lsa);
|
ospf_opaque_lsa_flush_schedule(lsa);
|
||||||
goto out;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create new Opaque-LSA/MPLS-TE instance. */
|
/* Create new Opaque-LSA/MPLS-TE instance. */
|
||||||
if ((new = ospf_mpls_te_lsa_new(area, lp)) == NULL) {
|
if ((new = ospf_mpls_te_lsa_new(area, lp)) == NULL) {
|
||||||
zlog_warn("ospf_mpls_te_lsa_refresh: ospf_mpls_te_lsa_new() ?");
|
zlog_warn("ospf_mpls_te_lsa_refresh: ospf_mpls_te_lsa_new() ?");
|
||||||
goto out;
|
return NULL;
|
||||||
}
|
}
|
||||||
new->data->ls_seqnum = lsa_seqnum_increment(lsa);
|
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) {
|
if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) {
|
||||||
zlog_warn("ospf_mpls_te_lsa_refresh: ospf_lsa_install() ?");
|
zlog_warn("ospf_mpls_te_lsa_refresh: ospf_lsa_install() ?");
|
||||||
ospf_lsa_unlock(&new);
|
ospf_lsa_unlock(&new);
|
||||||
goto out;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Flood updated LSA through AS or Area depending of the RFC of the link
|
/* 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);
|
ospf_lsa_header_dump(new->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
|
||||||
return new;
|
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 ospf_lsa lsa;
|
||||||
struct lsa_header lsah;
|
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,
|
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;
|
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,
|
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;
|
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,
|
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;
|
struct te_link_subtlv_link_type *top;
|
||||||
const char *cp = "Unknown";
|
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,
|
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;
|
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,
|
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;
|
struct te_link_subtlv_lclif_ipaddr *top;
|
||||||
int i, n;
|
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,
|
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;
|
struct te_link_subtlv_rmtif_ipaddr *top;
|
||||||
int i, n;
|
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,
|
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;
|
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,
|
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;
|
struct te_link_subtlv_max_bw *top;
|
||||||
float fval;
|
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,
|
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;
|
struct te_link_subtlv_max_rsv_bw *top;
|
||||||
float fval;
|
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,
|
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;
|
struct te_link_subtlv_unrsv_bw *top;
|
||||||
float fval1, fval2;
|
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,
|
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;
|
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,
|
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;
|
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,
|
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;
|
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,
|
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;
|
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,
|
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;
|
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,
|
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;
|
struct te_link_subtlv_av_delay *top;
|
||||||
u_int32_t delay;
|
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,
|
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;
|
struct te_link_subtlv_mm_delay *top;
|
||||||
u_int32_t low, high;
|
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,
|
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;
|
struct te_link_subtlv_delay_var *top;
|
||||||
u_int32_t jitter;
|
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,
|
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;
|
struct te_link_subtlv_pkt_loss *top;
|
||||||
u_int32_t loss;
|
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,
|
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;
|
struct te_link_subtlv_res_bw *top;
|
||||||
float fval;
|
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,
|
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;
|
struct te_link_subtlv_ava_bw *top;
|
||||||
float fval;
|
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,
|
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;
|
struct te_link_subtlv_use_bw *top;
|
||||||
float fval;
|
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,
|
static u_int16_t show_vty_unknown_tlv(struct vty *vty,
|
||||||
struct te_tlv_header *tlvh)
|
struct tlv_header *tlvh)
|
||||||
{
|
{
|
||||||
if (vty != NULL)
|
if (vty != NULL)
|
||||||
vty_out(vty, " Unknown TLV: [type(0x%x), length(0x%x)]\n",
|
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,
|
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 subtotal,
|
||||||
u_int16_t total)
|
u_int16_t total)
|
||||||
{
|
{
|
||||||
struct te_tlv_header *tlvh, *next;
|
struct tlv_header *tlvh, *next;
|
||||||
u_int16_t sum = subtotal;
|
u_int16_t sum = subtotal;
|
||||||
|
|
||||||
for (tlvh = tlvh0; sum < total;
|
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)
|
static void ospf_mpls_te_show_info(struct vty *vty, struct ospf_lsa *lsa)
|
||||||
{
|
{
|
||||||
struct lsa_header *lsah = (struct lsa_header *)lsa->data;
|
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 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;
|
u_int16_t subtotal, u_int16_t total) = NULL;
|
||||||
|
|
||||||
sum = 0;
|
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))) {
|
tlvh = (next ? next : TLV_HDR_NEXT(tlvh))) {
|
||||||
if (subfunc != NULL) {
|
if (subfunc != NULL) {
|
||||||
sum = (*subfunc)(vty, tlvh, sum, total);
|
sum = (*subfunc)(vty, tlvh, sum, total);
|
||||||
next = (struct te_tlv_header *)((char *)tlvh + sum);
|
next = (struct tlv_header *)((char *)tlvh + sum);
|
||||||
subfunc = NULL;
|
subfunc = NULL;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -2197,7 +2141,7 @@ static void ospf_mpls_te_show_info(struct vty *vty, struct ospf_lsa *lsa)
|
|||||||
case TE_TLV_LINK:
|
case TE_TLV_LINK:
|
||||||
sum += show_vty_link_header(vty, tlvh);
|
sum += show_vty_link_header(vty, tlvh);
|
||||||
subfunc = ospf_mpls_te_show_link_subtlv;
|
subfunc = ospf_mpls_te_show_link_subtlv;
|
||||||
next = tlvh + 1;
|
next = TLV_DATA(tlvh);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
sum += show_vty_unknown_tlv(vty, tlvh);
|
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)
|
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 on\n");
|
||||||
vty_out(vty, " mpls-te router-address %s\n",
|
vty_out(vty, " mpls-te router-address %s\n",
|
||||||
inet_ntoa(OspfMplsTE.router_addr.value));
|
inet_ntoa(OspfMplsTE.router_addr.value));
|
||||||
@ -2239,20 +2183,20 @@ DEFUN (ospf_mpls_te_on,
|
|||||||
struct listnode *node;
|
struct listnode *node;
|
||||||
struct mpls_te_link *lp;
|
struct mpls_te_link *lp;
|
||||||
|
|
||||||
if (OspfMplsTE.status == enabled)
|
if (OspfMplsTE.enabled)
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
|
|
||||||
if (IS_DEBUG_OSPF_EVENT)
|
if (IS_DEBUG_OSPF_EVENT)
|
||||||
zlog_debug("MPLS-TE: OFF -> ON");
|
zlog_debug("MPLS-TE: OFF -> ON");
|
||||||
|
|
||||||
OspfMplsTE.status = enabled;
|
OspfMplsTE.enabled = true;
|
||||||
|
|
||||||
/* Reoriginate RFC3630 & RFC6827 Links */
|
/* Reoriginate RFC3630 & RFC6827 Links */
|
||||||
ospf_mpls_te_foreach_area(ospf_mpls_te_lsa_schedule,
|
ospf_mpls_te_foreach_area(ospf_mpls_te_lsa_schedule,
|
||||||
REORIGINATE_THIS_LSA);
|
REORIGINATE_THIS_LSA);
|
||||||
|
|
||||||
/* Reoriginate LSA if INTER-AS is always on */
|
/* 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)) {
|
for (ALL_LIST_ELEMENTS_RO(OspfMplsTE.iflist, node, lp)) {
|
||||||
if (IS_INTER_AS(lp->type)) {
|
if (IS_INTER_AS(lp->type)) {
|
||||||
ospf_mpls_te_lsa_schedule(lp,
|
ospf_mpls_te_lsa_schedule(lp,
|
||||||
@ -2275,18 +2219,17 @@ DEFUN (no_ospf_mpls_te,
|
|||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
struct mpls_te_link *lp;
|
struct mpls_te_link *lp;
|
||||||
|
|
||||||
if (OspfMplsTE.status == disabled)
|
if (!OspfMplsTE.enabled)
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
|
|
||||||
if (IS_DEBUG_OSPF_EVENT)
|
if (IS_DEBUG_OSPF_EVENT)
|
||||||
zlog_debug("MPLS-TE: ON -> OFF");
|
zlog_debug("MPLS-TE: ON -> OFF");
|
||||||
|
|
||||||
OspfMplsTE.status = disabled;
|
OspfMplsTE.enabled = false;
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS(OspfMplsTE.iflist, node, nnode, lp))
|
for (ALL_LIST_ELEMENTS(OspfMplsTE.iflist, node, nnode, lp))
|
||||||
if
|
if (CHECK_FLAG(lp->flags, LPFLG_LSA_ENGAGED))
|
||||||
CHECK_FLAG(lp->flags, LPFLG_LSA_ENGAGED)
|
ospf_mpls_te_lsa_schedule(lp, FLUSH_THIS_LSA);
|
||||||
ospf_mpls_te_lsa_schedule(lp, FLUSH_THIS_LSA);
|
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -2317,8 +2260,8 @@ DEFUN (ospf_mpls_te_router_addr,
|
|||||||
|
|
||||||
set_mpls_te_router_addr(value);
|
set_mpls_te_router_addr(value);
|
||||||
|
|
||||||
if (OspfMplsTE.status == disabled)
|
if (!OspfMplsTE.enabled)
|
||||||
goto out;
|
return CMD_SUCCESS;
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS(OspfMplsTE.iflist, node, nnode, lp)) {
|
for (ALL_LIST_ELEMENTS(OspfMplsTE.iflist, node, nnode, lp)) {
|
||||||
if ((lp->area == NULL) || IS_FLOOD_AS(lp->type))
|
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,
|
ospf_mpls_te_foreach_area(ospf_mpls_te_lsa_schedule,
|
||||||
REORIGINATE_THIS_LSA);
|
REORIGINATE_THIS_LSA);
|
||||||
}
|
}
|
||||||
out:
|
|
||||||
return CMD_SUCCESS;
|
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;
|
struct mpls_te_link *lp;
|
||||||
int format;
|
int format;
|
||||||
|
|
||||||
if (OspfMplsTE.status == enabled) {
|
if (OspfMplsTE.enabled) {
|
||||||
|
|
||||||
/* Read and Check inter_as mode */
|
/* Read and Check inter_as mode */
|
||||||
if (strcmp(mode_name, "as") == 0)
|
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 */
|
/* Enable mode and re-originate LSA if needed */
|
||||||
if ((OspfMplsTE.inter_as == Disable)
|
if ((OspfMplsTE.inter_as == Off)
|
||||||
&& (mode != OspfMplsTE.inter_as)) {
|
&& (mode != OspfMplsTE.inter_as)) {
|
||||||
OspfMplsTE.inter_as = mode;
|
OspfMplsTE.inter_as = mode;
|
||||||
/* Re-originate all InterAS-TEv2 LSA */
|
/* Re-originate all InterAS-TEv2 LSA */
|
||||||
@ -2451,9 +2394,9 @@ DEFUN (no_ospf_mpls_te_inter_as,
|
|||||||
if (IS_DEBUG_OSPF_EVENT)
|
if (IS_DEBUG_OSPF_EVENT)
|
||||||
zlog_debug("MPLS-TE: Inter-AS support OFF");
|
zlog_debug("MPLS-TE: Inter-AS support OFF");
|
||||||
|
|
||||||
if ((OspfMplsTE.status == enabled)
|
if ((OspfMplsTE.enabled)
|
||||||
&& (OspfMplsTE.inter_as != Disable)) {
|
&& (OspfMplsTE.inter_as != Off)) {
|
||||||
OspfMplsTE.inter_as = Disable;
|
OspfMplsTE.inter_as = Off;
|
||||||
/* Flush all Inter-AS LSA */
|
/* Flush all Inter-AS LSA */
|
||||||
for (ALL_LIST_ELEMENTS(OspfMplsTE.iflist, node, nnode, lp))
|
for (ALL_LIST_ELEMENTS(OspfMplsTE.iflist, node, nnode, lp))
|
||||||
if (IS_INTER_AS(lp->type)
|
if (IS_INTER_AS(lp->type)
|
||||||
@ -2476,7 +2419,7 @@ DEFUN (show_ip_ospf_mpls_te_router,
|
|||||||
"MPLS-TE information\n"
|
"MPLS-TE information\n"
|
||||||
"MPLS-TE Router parameters\n")
|
"MPLS-TE Router parameters\n")
|
||||||
{
|
{
|
||||||
if (OspfMplsTE.status == enabled) {
|
if (OspfMplsTE.enabled) {
|
||||||
vty_out(vty, "--- MPLS-TE router parameters ---\n");
|
vty_out(vty, "--- MPLS-TE router parameters ---\n");
|
||||||
|
|
||||||
if (ntohs(OspfMplsTE.router_addr.header.type) != 0)
|
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;
|
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)
|
&& !if_is_loopback(ifp) && if_is_up(ifp)
|
||||||
&& ((lp = lookup_linkparams_by_ifp(ifp)) != NULL)) {
|
&& ((lp = lookup_linkparams_by_ifp(ifp)) != NULL)) {
|
||||||
/* Continue only if interface is not passive or support Inter-AS
|
/* Continue only if interface is not passive or support Inter-AS
|
||||||
|
138
ospfd/ospf_te.h
138
ospfd/ospf_te.h
@ -78,7 +78,7 @@
|
|||||||
#define FLOOD_AS 0x20
|
#define FLOOD_AS 0x20
|
||||||
#define EMULATED 0x80
|
#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_PSEUDO_TE(x) (x & PSEUDO_TE)
|
||||||
#define IS_INTER_AS(x) (x & INTER_AS)
|
#define IS_INTER_AS(x) (x & INTER_AS)
|
||||||
#define IS_EMULATED(x) (x & EMULATED)
|
#define IS_EMULATED(x) (x & EMULATED)
|
||||||
@ -94,58 +94,32 @@
|
|||||||
#define LPFLG_LOOKUP_DONE 0x4
|
#define LPFLG_LOOKUP_DONE 0x4
|
||||||
#define LPFLG_LSA_FORCED_REFRESH 0x8
|
#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.
|
* Following section defines TLV body parts.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Router Address TLV */ /* Mandatory */
|
/* Router Address TLV */ /* Mandatory */
|
||||||
#define TE_TLV_ROUTER_ADDR 1
|
#define TE_TLV_ROUTER_ADDR 1
|
||||||
struct te_tlv_router_addr {
|
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;
|
struct in_addr value;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Link TLV */
|
/* Link TLV */
|
||||||
#define TE_TLV_LINK 2
|
#define TE_TLV_LINK 2
|
||||||
struct te_tlv_link {
|
struct te_tlv_link {
|
||||||
struct te_tlv_header header;
|
struct tlv_header header;
|
||||||
/* A set of link-sub-TLVs will follow. */
|
/* A set of link-sub-TLVs will follow. */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Default TE TLV size */
|
||||||
#define TE_LINK_SUBTLV_DEF_SIZE 4
|
#define TE_LINK_SUBTLV_DEF_SIZE 4
|
||||||
|
|
||||||
/* Link Type Sub-TLV */ /* Mandatory */
|
/* Link Type Sub-TLV */ /* Mandatory */
|
||||||
#define TE_LINK_SUBTLV_LINK_TYPE 1
|
#define TE_LINK_SUBTLV_LINK_TYPE 1
|
||||||
#define TE_LINK_SUBTLV_TYPE_SIZE 1
|
#define TE_LINK_SUBTLV_TYPE_SIZE 1
|
||||||
struct te_link_subtlv_link_type {
|
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 {
|
struct {
|
||||||
#define LINK_TYPE_SUBTLV_VALUE_PTP 1
|
#define LINK_TYPE_SUBTLV_VALUE_PTP 1
|
||||||
#define LINK_TYPE_SUBTLV_VALUE_MA 2
|
#define LINK_TYPE_SUBTLV_VALUE_MA 2
|
||||||
@ -157,42 +131,42 @@ struct te_link_subtlv_link_type {
|
|||||||
/* Link Sub-TLV: Link ID */ /* Mandatory */
|
/* Link Sub-TLV: Link ID */ /* Mandatory */
|
||||||
#define TE_LINK_SUBTLV_LINK_ID 2
|
#define TE_LINK_SUBTLV_LINK_ID 2
|
||||||
struct te_link_subtlv_link_id {
|
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. */
|
struct in_addr value; /* Same as router-lsa's link-id. */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Link Sub-TLV: Local Interface IP Address */ /* Optional */
|
/* Link Sub-TLV: Local Interface IP Address */ /* Optional */
|
||||||
#define TE_LINK_SUBTLV_LCLIF_IPADDR 3
|
#define TE_LINK_SUBTLV_LCLIF_IPADDR 3
|
||||||
struct te_link_subtlv_lclif_ipaddr {
|
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). */
|
struct in_addr value[1]; /* Local IP address(es). */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Link Sub-TLV: Remote Interface IP Address */ /* Optional */
|
/* Link Sub-TLV: Remote Interface IP Address */ /* Optional */
|
||||||
#define TE_LINK_SUBTLV_RMTIF_IPADDR 4
|
#define TE_LINK_SUBTLV_RMTIF_IPADDR 4
|
||||||
struct te_link_subtlv_rmtif_ipaddr {
|
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). */
|
struct in_addr value[1]; /* Neighbor's IP address(es). */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Link Sub-TLV: Traffic Engineering Metric */ /* Optional */
|
/* Link Sub-TLV: Traffic Engineering Metric */ /* Optional */
|
||||||
#define TE_LINK_SUBTLV_TE_METRIC 5
|
#define TE_LINK_SUBTLV_TE_METRIC 5
|
||||||
struct te_link_subtlv_te_metric {
|
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. */
|
u_int32_t value; /* Link metric for TE purpose. */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Link Sub-TLV: Maximum Bandwidth */ /* Optional */
|
/* Link Sub-TLV: Maximum Bandwidth */ /* Optional */
|
||||||
#define TE_LINK_SUBTLV_MAX_BW 6
|
#define TE_LINK_SUBTLV_MAX_BW 6
|
||||||
struct te_link_subtlv_max_bw {
|
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 */
|
float value; /* bytes/sec */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Link Sub-TLV: Maximum Reservable Bandwidth */ /* Optional */
|
/* Link Sub-TLV: Maximum Reservable Bandwidth */ /* Optional */
|
||||||
#define TE_LINK_SUBTLV_MAX_RSV_BW 7
|
#define TE_LINK_SUBTLV_MAX_RSV_BW 7
|
||||||
struct te_link_subtlv_max_rsv_bw {
|
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 */
|
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_BW 8
|
||||||
#define TE_LINK_SUBTLV_UNRSV_SIZE 32
|
#define TE_LINK_SUBTLV_UNRSV_SIZE 32
|
||||||
struct te_link_subtlv_unrsv_bw {
|
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. */
|
float value[MAX_CLASS_TYPE]; /* One for each priority level. */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Link Sub-TLV: Resource Class/Color */ /* Optional */
|
/* Link Sub-TLV: Resource Class/Color */ /* Optional */
|
||||||
#define TE_LINK_SUBTLV_RSC_CLSCLR 9
|
#define TE_LINK_SUBTLV_RSC_CLSCLR 9
|
||||||
struct te_link_subtlv_rsc_clsclr {
|
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. */
|
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 10
|
||||||
#define TE_LINK_SUBTLV_LRRID_SIZE 8
|
#define TE_LINK_SUBTLV_LRRID_SIZE 8
|
||||||
struct te_link_subtlv_lrrid {
|
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 local; /* Local TE Router Identifier */
|
||||||
struct in_addr remote; /* Remote 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 11
|
||||||
#define TE_LINK_SUBTLV_LLRI_SIZE 8
|
#define TE_LINK_SUBTLV_LLRI_SIZE 8
|
||||||
struct te_link_subtlv_llri {
|
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 local; /* Link Local Identifier */
|
||||||
u_int32_t remote; /* Link Remote Identifier */
|
u_int32_t remote; /* Link Remote Identifier */
|
||||||
};
|
};
|
||||||
@ -240,14 +214,14 @@ struct te_link_subtlv_llri {
|
|||||||
/* Remote AS Number sub-TLV */
|
/* Remote AS Number sub-TLV */
|
||||||
#define TE_LINK_SUBTLV_RAS 21
|
#define TE_LINK_SUBTLV_RAS 21
|
||||||
struct te_link_subtlv_ras {
|
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 */
|
u_int32_t value; /* Remote AS number */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* IPv4 Remote ASBR ID Sub-TLV */
|
/* IPv4 Remote ASBR ID Sub-TLV */
|
||||||
#define TE_LINK_SUBTLV_RIP 22
|
#define TE_LINK_SUBTLV_RIP 22
|
||||||
struct te_link_subtlv_rip {
|
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 */
|
struct in_addr value; /* Remote ASBR IP address */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -261,63 +235,69 @@ struct te_link_subtlv_rip {
|
|||||||
/* Link Sub-TLV: Average Link Delay */ /* Optional */
|
/* Link Sub-TLV: Average Link Delay */ /* Optional */
|
||||||
#define TE_LINK_SUBTLV_AV_DELAY 27
|
#define TE_LINK_SUBTLV_AV_DELAY 27
|
||||||
struct te_link_subtlv_av_delay {
|
struct te_link_subtlv_av_delay {
|
||||||
struct te_tlv_header header; /* Value length is 4 bytes. */
|
struct tlv_header header; /* Value length is 4 bytes. */
|
||||||
u_int32_t
|
/*
|
||||||
value; /* delay in micro-seconds only 24 bits => 0 ... 16777215
|
* delay in micro-seconds only 24 bits => 0 ... 16777215
|
||||||
with Anomalous Bit as Upper most bit */
|
* with Anomalous Bit as Upper most bit
|
||||||
|
*/
|
||||||
|
u_int32_t value;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Link Sub-TLV: Low/High Link Delay */
|
/* Link Sub-TLV: Low/High Link Delay */
|
||||||
#define TE_LINK_SUBTLV_MM_DELAY 28
|
#define TE_LINK_SUBTLV_MM_DELAY 28
|
||||||
#define TE_LINK_SUBTLV_MM_DELAY_SIZE 8
|
#define TE_LINK_SUBTLV_MM_DELAY_SIZE 8
|
||||||
struct te_link_subtlv_mm_delay {
|
struct te_link_subtlv_mm_delay {
|
||||||
struct te_tlv_header header; /* Value length is 8 bytes. */
|
struct tlv_header header; /* Value length is 8 bytes. */
|
||||||
u_int32_t low; /* low delay in micro-seconds only 24 bits => 0 ...
|
/*
|
||||||
16777215
|
* low delay in micro-seconds only 24 bits => 0 ... 16777215
|
||||||
with Anomalous Bit (A) as Upper most bit */
|
* with Anomalous Bit (A) as Upper most bit
|
||||||
u_int32_t high; /* high delay in micro-seconds only 24 bits => 0 ...
|
*/
|
||||||
16777215 */
|
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 */
|
/* Link Sub-TLV: Link Delay Variation i.e. Jitter */
|
||||||
#define TE_LINK_SUBTLV_DELAY_VAR 29
|
#define TE_LINK_SUBTLV_DELAY_VAR 29
|
||||||
struct te_link_subtlv_delay_var {
|
struct te_link_subtlv_delay_var {
|
||||||
struct te_tlv_header header; /* Value length is 4 bytes. */
|
struct tlv_header header; /* Value length is 4 bytes. */
|
||||||
u_int32_t value; /* interval in micro-seconds only 24 bits => 0 ...
|
/* interval in micro-seconds only 24 bits => 0 ... 16777215 */
|
||||||
16777215 */
|
u_int32_t value;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Link Sub-TLV: Routine Unidirectional Link Packet Loss */
|
/* Link Sub-TLV: Routine Unidirectional Link Packet Loss */
|
||||||
#define TE_LINK_SUBTLV_PKT_LOSS 30
|
#define TE_LINK_SUBTLV_PKT_LOSS 30
|
||||||
struct te_link_subtlv_pkt_loss {
|
struct te_link_subtlv_pkt_loss {
|
||||||
struct te_tlv_header header; /* Value length is 4 bytes. */
|
struct tlv_header header; /* Value length is 4 bytes. */
|
||||||
u_int32_t
|
/*
|
||||||
value; /* in percentage of total traffic only 24 bits (2^24 - 2)
|
* in percentage of total traffic only 24 bits (2^24 - 2)
|
||||||
with Anomalous Bit as Upper most bit */
|
* with Anomalous Bit as Upper most bit
|
||||||
|
*/
|
||||||
|
u_int32_t value;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Link Sub-TLV: Unidirectional Residual Bandwidth */ /* Optional */
|
/* Link Sub-TLV: Unidirectional Residual Bandwidth */ /* Optional */
|
||||||
#define TE_LINK_SUBTLV_RES_BW 31
|
#define TE_LINK_SUBTLV_RES_BW 31
|
||||||
struct te_link_subtlv_res_bw {
|
struct te_link_subtlv_res_bw {
|
||||||
struct te_tlv_header header; /* Value length is 4 bytes. */
|
struct tlv_header header; /* Value length is 4 bytes. */
|
||||||
float value; /* bandwidth in IEEE floating point format with units in
|
/* bandwidth in IEEE floating point format with units in bytes/second */
|
||||||
bytes per second */
|
float value;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Link Sub-TLV: Unidirectional Available Bandwidth */ /* Optional */
|
/* Link Sub-TLV: Unidirectional Available Bandwidth */ /* Optional */
|
||||||
#define TE_LINK_SUBTLV_AVA_BW 32
|
#define TE_LINK_SUBTLV_AVA_BW 32
|
||||||
struct te_link_subtlv_ava_bw {
|
struct te_link_subtlv_ava_bw {
|
||||||
struct te_tlv_header header; /* Value length is 4 octets. */
|
struct tlv_header header; /* Value length is 4 octets. */
|
||||||
float value; /* bandwidth in IEEE floating point format with units in
|
/* bandwidth in IEEE floating point format with units in bytes/second */
|
||||||
bytes per second */
|
float value;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Link Sub-TLV: Unidirectional Utilized Bandwidth */ /* Optional */
|
/* Link Sub-TLV: Unidirectional Utilized Bandwidth */ /* Optional */
|
||||||
#define TE_LINK_SUBTLV_USE_BW 33
|
#define TE_LINK_SUBTLV_USE_BW 33
|
||||||
struct te_link_subtlv_use_bw {
|
struct te_link_subtlv_use_bw {
|
||||||
struct te_tlv_header header; /* Value length is 4 octets. */
|
struct tlv_header header; /* Value length is 4 octets. */
|
||||||
float value; /* bandwidth in IEEE floating point format with units in
|
/* bandwidth in IEEE floating point format with units in bytes/second */
|
||||||
bytes per second */
|
float value;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define TE_LINK_SUBTLV_MAX 34 /* Last SUBTLV + 1 */
|
#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. */
|
/* Here are "non-official" architectural constants. */
|
||||||
#define MPLS_TE_MINIMUM_BANDWIDTH 1.0 /* Reasonable? *//* XXX */
|
#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 */
|
/* 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_link_subtlv {
|
||||||
struct te_tlv_header header;
|
struct tlv_header header;
|
||||||
union {
|
union {
|
||||||
u_int32_t link_type;
|
u_int32_t link_type;
|
||||||
struct in_addr link_id;
|
struct in_addr link_id;
|
||||||
@ -366,7 +337,7 @@ struct te_link_subtlv {
|
|||||||
/* Following structure are internal use only. */
|
/* Following structure are internal use only. */
|
||||||
struct ospf_mpls_te {
|
struct ospf_mpls_te {
|
||||||
/* Status of MPLS-TE: enable or disbale */
|
/* Status of MPLS-TE: enable or disbale */
|
||||||
status_t status;
|
bool enabled;
|
||||||
|
|
||||||
/* RFC5392 */
|
/* RFC5392 */
|
||||||
enum inter_as_mode inter_as;
|
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 void ospf_mpls_te_term(void);
|
||||||
extern struct ospf_mpls_te *get_ospf_mpls_te(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_update_if(struct interface *);
|
||||||
extern void ospf_mpls_te_lsa_schedule(struct mpls_te_link *, opcode_t);
|
extern void ospf_mpls_te_lsa_schedule(struct mpls_te_link *, enum lsa_opcode);
|
||||||
extern u_int32_t get_mpls_te_instance_value(void);
|
|
||||||
extern void set_linkparams_llri(struct mpls_te_link *, u_int32_t, u_int32_t);
|
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,
|
extern void set_linkparams_lrrid(struct mpls_te_link *, struct in_addr,
|
||||||
struct in_addr);
|
struct in_addr);
|
||||||
|
@ -4402,6 +4402,10 @@ static int show_ip_ospf_neighbor_id_common(struct vty *vty, struct ospf *ospf,
|
|||||||
if (!ret) {
|
if (!ret) {
|
||||||
if (!use_json)
|
if (!use_json)
|
||||||
vty_out(vty, "Please specify Neighbor ID by A.B.C.D\n");
|
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;
|
return CMD_WARNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4682,6 +4686,10 @@ static int show_ip_ospf_neighbor_int_detail_common(struct vty *vty,
|
|||||||
if (!ifp) {
|
if (!ifp) {
|
||||||
if (!use_json)
|
if (!use_json)
|
||||||
vty_out(vty, "No such interface.\n");
|
vty_out(vty, "No such interface.\n");
|
||||||
|
else {
|
||||||
|
vty_out(vty, "{}\n");
|
||||||
|
json_object_free(json);
|
||||||
|
}
|
||||||
return CMD_WARNING;
|
return CMD_WARNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -976,9 +976,13 @@ int ospf_network_unset(struct ospf *ospf, struct prefix_ipv4 *p,
|
|||||||
rn->info = NULL;
|
rn->info = NULL;
|
||||||
route_unlock_node(rn); /* initial reference */
|
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)) {
|
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. */
|
/* Update connected redistribute. */
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
rcdir=@pkgsrcrcdir@
|
|
||||||
|
|
||||||
rc_SCRIPTS = bgpd.sh ospf6d.sh ospfd.sh ripd.sh ripngd.sh zebra.sh
|
|
@ -1,3 +0,0 @@
|
|||||||
EXTRA_DIST = \
|
|
||||||
clidef.py \
|
|
||||||
clippy/__init__.py
|
|
2
qpb/.gitignore
vendored
2
qpb/.gitignore
vendored
@ -1,4 +1,4 @@
|
|||||||
Makefile
|
!Makefile
|
||||||
Makefile.in
|
Makefile.in
|
||||||
*.o
|
*.o
|
||||||
tags
|
tags
|
||||||
|
10
qpb/Makefile
Normal file
10
qpb/Makefile
Normal 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:
|
@ -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
|
|
@ -20,6 +20,8 @@
|
|||||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
syntax = "proto2";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Protobuf definitions pertaining to the Quagga/FRR Protobuf component.
|
* Protobuf definitions pertaining to the Quagga/FRR Protobuf component.
|
||||||
*/
|
*/
|
||||||
|
@ -42,8 +42,7 @@ static void _qpb_free(void *allocator_data, void *ptr)
|
|||||||
linear_allocator_free(allocator_data, ptr);
|
linear_allocator_free(allocator_data, ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ProtobufCAllocator allocator_template = {_qpb_alloc, _qpb_free, NULL,
|
static ProtobufCAllocator allocator_template = {_qpb_alloc, _qpb_free, NULL};
|
||||||
8192, NULL};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* qpb_allocator_init_linear
|
* qpb_allocator_init_linear
|
||||||
|
26
qpb/subdir.am
Normal file
26
qpb/subdir.am
Normal 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
|
@ -1,5 +0,0 @@
|
|||||||
|
|
||||||
EXTRA_DIST = frr.init frr.service daemons \
|
|
||||||
frr.logrotate frr.pam frr.spec \
|
|
||||||
README.rpm_build.md
|
|
||||||
|
|
@ -515,6 +515,18 @@ case "$1" in
|
|||||||
if [ -z "$dmn" -o "$dmn" = "zebra" ]; then
|
if [ -z "$dmn" -o "$dmn" = "zebra" ]; then
|
||||||
echo "Removing all routes made by zebra."
|
echo "Removing all routes made by zebra."
|
||||||
ip route flush proto 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
|
else
|
||||||
[ -n "$dmn" ] && eval "${dmn/-/_}=0"
|
[ -n "$dmn" ] && eval "${dmn/-/_}=0"
|
||||||
start_watchfrr
|
start_watchfrr
|
||||||
|
@ -66,7 +66,7 @@ DEFUN (debug_rip_events,
|
|||||||
"RIP events\n")
|
"RIP events\n")
|
||||||
{
|
{
|
||||||
rip_debug_event = RIP_DEBUG_EVENT;
|
rip_debug_event = RIP_DEBUG_EVENT;
|
||||||
return CMD_WARNING_CONFIG_FAILED;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFUN (debug_rip_packet,
|
DEFUN (debug_rip_packet,
|
||||||
@ -112,7 +112,7 @@ DEFUN (debug_rip_zebra,
|
|||||||
"RIP and ZEBRA communication\n")
|
"RIP and ZEBRA communication\n")
|
||||||
{
|
{
|
||||||
rip_debug_zebra = RIP_DEBUG_ZEBRA;
|
rip_debug_zebra = RIP_DEBUG_ZEBRA;
|
||||||
return CMD_WARNING_CONFIG_FAILED;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFUN (no_debug_rip_events,
|
DEFUN (no_debug_rip_events,
|
||||||
@ -177,7 +177,7 @@ DEFUN (no_debug_rip_zebra,
|
|||||||
"RIP and ZEBRA communication\n")
|
"RIP and ZEBRA communication\n")
|
||||||
{
|
{
|
||||||
rip_debug_zebra = 0;
|
rip_debug_zebra = 0;
|
||||||
return CMD_WARNING_CONFIG_FAILED;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Debug node. */
|
/* Debug node. */
|
||||||
|
@ -67,7 +67,7 @@ DEFUN (debug_ripng_events,
|
|||||||
"Debug option set for ripng events\n")
|
"Debug option set for ripng events\n")
|
||||||
{
|
{
|
||||||
ripng_debug_event = RIPNG_DEBUG_EVENT;
|
ripng_debug_event = RIPNG_DEBUG_EVENT;
|
||||||
return CMD_WARNING_CONFIG_FAILED;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFUN (debug_ripng_packet,
|
DEFUN (debug_ripng_packet,
|
||||||
@ -114,7 +114,7 @@ DEFUN (debug_ripng_zebra,
|
|||||||
"Debug option set for ripng and zebra communication\n")
|
"Debug option set for ripng and zebra communication\n")
|
||||||
{
|
{
|
||||||
ripng_debug_zebra = RIPNG_DEBUG_ZEBRA;
|
ripng_debug_zebra = RIPNG_DEBUG_ZEBRA;
|
||||||
return CMD_WARNING_CONFIG_FAILED;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFUN (no_debug_ripng_events,
|
DEFUN (no_debug_ripng_events,
|
||||||
@ -179,7 +179,7 @@ DEFUN (no_debug_ripng_zebra,
|
|||||||
"Debug option set for ripng and zebra communication\n")
|
"Debug option set for ripng and zebra communication\n")
|
||||||
{
|
{
|
||||||
ripng_debug_zebra = 0;
|
ripng_debug_zebra = 0;
|
||||||
return CMD_WARNING_CONFIG_FAILED;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Debug node. */
|
/* Debug node. */
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
EXTRA_DIST = snapcraft.yaml \
|
|
||||||
README.snap_build.md \
|
|
||||||
README.usage.md \
|
|
||||||
extra_version_info.txt \
|
|
||||||
scripts \
|
|
||||||
defaults \
|
|
||||||
helpers \
|
|
||||||
snap
|
|
@ -170,7 +170,7 @@ static struct test_segment mp_segments[] = {
|
|||||||
/* 8 */
|
/* 8 */
|
||||||
{
|
{
|
||||||
"MP6",
|
"MP6",
|
||||||
"MP IP4/MPLS-laveled VPN",
|
"MP IP4/MPLS-labeled VPN",
|
||||||
{CAPABILITY_CODE_MP, 0x4, 0x0, 0x1, 0x0, 0x80},
|
{CAPABILITY_CODE_MP, 0x4, 0x0, 0x1, 0x0, 0x80},
|
||||||
6,
|
6,
|
||||||
SHOULD_PARSE,
|
SHOULD_PARSE,
|
||||||
|
@ -8,7 +8,7 @@ TestCapability.okfail("MPv6: MP IPv6/Uni")
|
|||||||
TestCapability.okfail("MP2: MP IP/Multicast")
|
TestCapability.okfail("MP2: MP IP/Multicast")
|
||||||
TestCapability.okfail("MP3: MP IP6/MPLS-labeled VPN")
|
TestCapability.okfail("MP3: MP IP6/MPLS-labeled VPN")
|
||||||
TestCapability.okfail("MP5: MP IP6/MPLS-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("MP8: MP unknown AFI/SAFI")
|
||||||
TestCapability.okfail("MP-short: MP IP4/Unicast, length too short (< minimum)")
|
TestCapability.okfail("MP-short: MP IP4/Unicast, length too short (< minimum)")
|
||||||
TestCapability.okfail("MP-overflow: MP IP4/Unicast, length too long")
|
TestCapability.okfail("MP-overflow: MP IP4/Unicast, length too long")
|
||||||
|
@ -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);
|
parse_ret = bgp_mp_unreach_parse(&attr_args, &nlri);
|
||||||
if (!parse_ret) {
|
if (!parse_ret) {
|
||||||
iana_afi_t pkt_afi;
|
iana_afi_t pkt_afi;
|
||||||
safi_t pkt_safi;
|
iana_safi_t pkt_safi;
|
||||||
|
|
||||||
/* Convert AFI, SAFI to internal values, check. */
|
/* Convert AFI, SAFI to internal values, check. */
|
||||||
if (bgp_map_afi_safi_int2iana(nlri.afi, nlri.safi, &pkt_afi,
|
if (bgp_map_afi_safi_int2iana(nlri.afi, nlri.safi, &pkt_afi,
|
||||||
|
138
vtysh/vtysh.c
138
vtysh/vtysh.c
@ -303,7 +303,9 @@ static int vtysh_execute_func(const char *line, int pager)
|
|||||||
|| saved_node == BGP_IPV4L_NODE
|
|| saved_node == BGP_IPV4L_NODE
|
||||||
|| saved_node == BGP_IPV6L_NODE
|
|| saved_node == BGP_IPV6L_NODE
|
||||||
|| saved_node == BGP_IPV6M_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)) {
|
&& (tried == 1)) {
|
||||||
vtysh_execute("exit-address-family");
|
vtysh_execute("exit-address-family");
|
||||||
} else if ((saved_node == BGP_EVPN_VNI_NODE) && (tried == 1)) {
|
} 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);
|
strcpy(vty_buf_copy, vty->buf);
|
||||||
vty_buf_trimmed = trim(vty_buf_copy);
|
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] == '#') {
|
if (vty_buf_trimmed[0] == '!' || vty_buf_trimmed[0] == '#') {
|
||||||
fprintf(stdout, "%s", vty->buf);
|
fprintf(stdout, "%s", vty->buf);
|
||||||
continue;
|
continue;
|
||||||
@ -1268,6 +1293,14 @@ DEFUNSH(VTYSH_LDPD, ldp_address_family_ipv6, ldp_address_family_ipv6_cmd,
|
|||||||
return CMD_SUCCESS;
|
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,
|
DEFUNSH(VTYSH_LDPD, ldp_interface_ifname, ldp_interface_ifname_cmd,
|
||||||
"interface IFNAME",
|
"interface IFNAME",
|
||||||
"Enable LDP on an interface and enter interface submode\n"
|
"Enable LDP on an interface and enter interface submode\n"
|
||||||
@ -2420,7 +2453,7 @@ DEFUN (vtysh_show_daemons,
|
|||||||
|
|
||||||
/* Execute command in child process. */
|
/* Execute command in child process. */
|
||||||
static void execute_command(const char *command, int argc,
|
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;
|
pid_t pid;
|
||||||
int status;
|
int status;
|
||||||
@ -2465,7 +2498,10 @@ DEFUN (vtysh_ping,
|
|||||||
"Send echo messages\n"
|
"Send echo messages\n"
|
||||||
"Ping destination address or hostname\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;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2480,7 +2516,10 @@ DEFUN (vtysh_traceroute,
|
|||||||
"Trace route to destination\n"
|
"Trace route to destination\n"
|
||||||
"Trace route to destination address or hostname\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;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2496,7 +2535,7 @@ DEFUN (vtysh_ping6,
|
|||||||
"IPv6 echo\n"
|
"IPv6 echo\n"
|
||||||
"Ping destination address or hostname\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;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2507,7 +2546,7 @@ DEFUN (vtysh_traceroute6,
|
|||||||
"IPv6 trace\n"
|
"IPv6 trace\n"
|
||||||
"Trace route to destination address or hostname\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;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2518,7 +2557,7 @@ DEFUN (vtysh_telnet,
|
|||||||
"Open a telnet connection\n"
|
"Open a telnet connection\n"
|
||||||
"IP address or hostname of a remote system\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;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2529,7 +2568,7 @@ DEFUN (vtysh_telnet_port,
|
|||||||
"IP address or hostname of a remote system\n"
|
"IP address or hostname of a remote system\n"
|
||||||
"TCP Port number\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;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2539,7 +2578,7 @@ DEFUN (vtysh_ssh,
|
|||||||
"Open an ssh connection\n"
|
"Open an ssh connection\n"
|
||||||
"[user@]host\n")
|
"[user@]host\n")
|
||||||
{
|
{
|
||||||
execute_command("ssh", 1, argv[0], NULL);
|
execute_command("ssh", 1, argv[1]->arg, NULL);
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2582,9 +2621,39 @@ DEFUN (config_list,
|
|||||||
return cmd_list_cmds(vty, argc == 2);
|
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)
|
static void vtysh_install_default(enum node_type node)
|
||||||
{
|
{
|
||||||
install_element(node, &config_list_cmd);
|
install_element(node, &config_list_cmd);
|
||||||
|
install_element(node, &find_cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Making connection to protocol daemon. */
|
/* Making connection to protocol daemon. */
|
||||||
@ -2876,48 +2945,13 @@ void vtysh_init_vty(void)
|
|||||||
install_node(&isis_node, NULL);
|
install_node(&isis_node, NULL);
|
||||||
install_node(&vty_node, NULL);
|
install_node(&vty_node, NULL);
|
||||||
|
|
||||||
vtysh_install_default(VIEW_NODE);
|
struct cmd_node *node;
|
||||||
vtysh_install_default(CONFIG_NODE);
|
for (unsigned int i = 0; i < vector_active(cmdvec); i++) {
|
||||||
vtysh_install_default(BGP_NODE);
|
node = vector_slot(cmdvec, i);
|
||||||
vtysh_install_default(RIP_NODE);
|
if (!node || node->node == VIEW_NODE)
|
||||||
vtysh_install_default(INTERFACE_NODE);
|
continue;
|
||||||
vtysh_install_default(LINK_PARAMS_NODE);
|
vtysh_install_default(node->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);
|
|
||||||
|
|
||||||
install_element(VIEW_NODE, &vtysh_enable_cmd);
|
install_element(VIEW_NODE, &vtysh_enable_cmd);
|
||||||
install_element(ENABLE_NODE, &vtysh_config_terminal_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_NODE, &vtysh_quit_ldpd_cmd);
|
||||||
install_element(LDP_IPV4_NODE, &vtysh_exit_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, &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_exit_ldpd_cmd);
|
||||||
install_element(LDP_IPV6_NODE, &vtysh_quit_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_exit_ldpd_cmd);
|
||||||
install_element(LDP_IPV4_IFACE_NODE, &vtysh_quit_ldpd_cmd);
|
install_element(LDP_IPV4_IFACE_NODE, &vtysh_quit_ldpd_cmd);
|
||||||
install_element(LDP_IPV6_IFACE_NODE, &vtysh_exit_ldpd_cmd);
|
install_element(LDP_IPV6_IFACE_NODE, &vtysh_exit_ldpd_cmd);
|
||||||
|
@ -44,7 +44,7 @@ DECLARE_MGROUP(MVTYSH)
|
|||||||
* run on it (logging & co. should stay in a fixed/frozen config, and
|
* run on it (logging & co. should stay in a fixed/frozen config, and
|
||||||
* things like prefix lists are not even initialised) */
|
* 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_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_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_NS VTYSH_ZEBRA
|
||||||
#define VTYSH_VRF VTYSH_ZEBRA|VTYSH_PIMD
|
#define VTYSH_VRF VTYSH_ZEBRA|VTYSH_PIMD
|
||||||
|
3
zebra/.gitignore
vendored
3
zebra/.gitignore
vendored
@ -1,4 +1,4 @@
|
|||||||
Makefile
|
!Makefile
|
||||||
Makefile.in
|
Makefile.in
|
||||||
*.o
|
*.o
|
||||||
zebra
|
zebra
|
||||||
@ -13,3 +13,4 @@ TAGS
|
|||||||
.arch-ids
|
.arch-ids
|
||||||
*~
|
*~
|
||||||
*.loT
|
*.loT
|
||||||
|
zebra_vty_clippy.c
|
||||||
|
10
zebra/Makefile
Normal file
10
zebra/Makefile
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
all: ALWAYS
|
||||||
|
@$(MAKE) -s -C .. zebra/zebra
|
||||||
|
%: ALWAYS
|
||||||
|
@$(MAKE) -s -C .. zebra/$@
|
||||||
|
|
||||||
|
Makefile:
|
||||||
|
#nothing
|
||||||
|
ALWAYS:
|
||||||
|
.PHONY: ALWAYS makefiles
|
||||||
|
.SUFFIXES:
|
@ -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
|
|
135
zebra/debug.c
135
zebra/debug.c
@ -71,10 +71,10 @@ DEFUN (show_debugging_zebra,
|
|||||||
" Zebra kernel netlink message dumps (recv) are on\n");
|
" Zebra kernel netlink message dumps (recv) are on\n");
|
||||||
|
|
||||||
/* Check here using flags as the 'macro' does an OR */
|
/* Check here using flags as the 'macro' does an OR */
|
||||||
if (CHECK_FLAG(zebra_debug_rib, ZEBRA_DEBUG_RIB))
|
|
||||||
vty_out(vty, " Zebra RIB debugging is on\n");
|
|
||||||
if (CHECK_FLAG(zebra_debug_rib, ZEBRA_DEBUG_RIB_DETAILED))
|
if (CHECK_FLAG(zebra_debug_rib, ZEBRA_DEBUG_RIB_DETAILED))
|
||||||
vty_out(vty, " Zebra RIB detailed debugging is on\n");
|
vty_out(vty, " Zebra RIB detailed debugging is on\n");
|
||||||
|
else if (CHECK_FLAG(zebra_debug_rib, ZEBRA_DEBUG_RIB))
|
||||||
|
vty_out(vty, " Zebra RIB debugging is on\n");
|
||||||
|
|
||||||
if (IS_ZEBRA_DEBUG_FPM)
|
if (IS_ZEBRA_DEBUG_FPM)
|
||||||
vty_out(vty, " Zebra FPM debugging is on\n");
|
vty_out(vty, " Zebra FPM debugging is on\n");
|
||||||
@ -145,17 +145,16 @@ DEFUN (debug_zebra_packet,
|
|||||||
|
|
||||||
if (argv_find(argv, argc, "send", &idx))
|
if (argv_find(argv, argc, "send", &idx))
|
||||||
SET_FLAG(zebra_debug_packet, ZEBRA_DEBUG_SEND);
|
SET_FLAG(zebra_debug_packet, ZEBRA_DEBUG_SEND);
|
||||||
idx = 0;
|
else if (argv_find(argv, argc, "recv", &idx))
|
||||||
if (argv_find(argv, argc, "recv", &idx))
|
|
||||||
SET_FLAG(zebra_debug_packet, ZEBRA_DEBUG_RECV);
|
SET_FLAG(zebra_debug_packet, ZEBRA_DEBUG_RECV);
|
||||||
idx = 0;
|
else {
|
||||||
if (argv_find(argv, argc, "detail", &idx))
|
|
||||||
SET_FLAG(zebra_debug_packet, ZEBRA_DEBUG_DETAIL);
|
|
||||||
|
|
||||||
if (!(zebra_debug_packet & ZEBRA_DEBUG_SEND & ZEBRA_DEBUG_RECV)) {
|
|
||||||
SET_FLAG(zebra_debug_packet, ZEBRA_DEBUG_SEND);
|
SET_FLAG(zebra_debug_packet, ZEBRA_DEBUG_SEND);
|
||||||
SET_FLAG(zebra_debug_packet, ZEBRA_DEBUG_RECV);
|
SET_FLAG(zebra_debug_packet, ZEBRA_DEBUG_RECV);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (argv_find(argv, argc, "detail", &idx))
|
||||||
|
SET_FLAG(zebra_debug_packet, ZEBRA_DEBUG_DETAIL);
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,6 +166,13 @@ DEFUN (debug_zebra_kernel,
|
|||||||
"Debug option set for zebra between kernel interface\n")
|
"Debug option set for zebra between kernel interface\n")
|
||||||
{
|
{
|
||||||
SET_FLAG(zebra_debug_kernel, ZEBRA_DEBUG_KERNEL);
|
SET_FLAG(zebra_debug_kernel, ZEBRA_DEBUG_KERNEL);
|
||||||
|
|
||||||
|
if (IS_ZEBRA_DEBUG_KERNEL_MSGDUMP_RECV)
|
||||||
|
UNSET_FLAG(zebra_debug_kernel, ZEBRA_DEBUG_KERNEL_MSGDUMP_RECV);
|
||||||
|
|
||||||
|
if (IS_ZEBRA_DEBUG_KERNEL_MSGDUMP_SEND)
|
||||||
|
UNSET_FLAG(zebra_debug_kernel, ZEBRA_DEBUG_KERNEL_MSGDUMP_SEND);
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,34 +187,41 @@ DEFUN (debug_zebra_kernel_msgdump,
|
|||||||
"Dump raw netlink messages sent\n")
|
"Dump raw netlink messages sent\n")
|
||||||
{
|
{
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
if (argc == 4 || argv_find(argv, argc, "recv", &idx))
|
|
||||||
|
if (argv_find(argv, argc, "recv", &idx)) {
|
||||||
SET_FLAG(zebra_debug_kernel, ZEBRA_DEBUG_KERNEL_MSGDUMP_RECV);
|
SET_FLAG(zebra_debug_kernel, ZEBRA_DEBUG_KERNEL_MSGDUMP_RECV);
|
||||||
if (argc == 4 || argv_find(argv, argc, "send", &idx))
|
|
||||||
|
if (IS_ZEBRA_DEBUG_KERNEL_MSGDUMP_SEND)
|
||||||
|
UNSET_FLAG(zebra_debug_kernel, ZEBRA_DEBUG_KERNEL_MSGDUMP_SEND);
|
||||||
|
|
||||||
|
} else if (argv_find(argv, argc, "send", &idx)) {
|
||||||
SET_FLAG(zebra_debug_kernel, ZEBRA_DEBUG_KERNEL_MSGDUMP_SEND);
|
SET_FLAG(zebra_debug_kernel, ZEBRA_DEBUG_KERNEL_MSGDUMP_SEND);
|
||||||
|
|
||||||
|
if (IS_ZEBRA_DEBUG_KERNEL_MSGDUMP_RECV)
|
||||||
|
UNSET_FLAG(zebra_debug_kernel, ZEBRA_DEBUG_KERNEL_MSGDUMP_RECV);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
SET_FLAG(zebra_debug_kernel, ZEBRA_DEBUG_KERNEL_MSGDUMP_RECV);
|
||||||
|
SET_FLAG(zebra_debug_kernel, ZEBRA_DEBUG_KERNEL_MSGDUMP_SEND);
|
||||||
|
}
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFUN (debug_zebra_rib,
|
DEFUN (debug_zebra_rib,
|
||||||
debug_zebra_rib_cmd,
|
debug_zebra_rib_cmd,
|
||||||
"debug zebra rib",
|
"debug zebra rib [detailed]",
|
||||||
DEBUG_STR
|
|
||||||
"Zebra configuration\n"
|
|
||||||
"Debug RIB events\n")
|
|
||||||
{
|
|
||||||
SET_FLAG(zebra_debug_rib, ZEBRA_DEBUG_RIB);
|
|
||||||
return CMD_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFUN (debug_zebra_rib_detailed,
|
|
||||||
debug_zebra_rib_detailed_cmd,
|
|
||||||
"debug zebra rib detailed",
|
|
||||||
DEBUG_STR
|
DEBUG_STR
|
||||||
"Zebra configuration\n"
|
"Zebra configuration\n"
|
||||||
"Debug RIB events\n"
|
"Debug RIB events\n"
|
||||||
"Detailed debugs\n")
|
"Detailed debugs\n")
|
||||||
{
|
{
|
||||||
SET_FLAG(zebra_debug_rib, ZEBRA_DEBUG_RIB_DETAILED);
|
int idx = 0;
|
||||||
|
SET_FLAG(zebra_debug_rib, ZEBRA_DEBUG_RIB);
|
||||||
|
|
||||||
|
if (argv_find(argv, argc, "detailed", &idx))
|
||||||
|
SET_FLAG(zebra_debug_rib, ZEBRA_DEBUG_RIB_DETAILED);
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -273,19 +286,16 @@ DEFUN (no_debug_zebra_vxlan,
|
|||||||
|
|
||||||
DEFUN (no_debug_zebra_packet,
|
DEFUN (no_debug_zebra_packet,
|
||||||
no_debug_zebra_packet_cmd,
|
no_debug_zebra_packet_cmd,
|
||||||
"no debug zebra packet [<recv|send>]",
|
"no debug zebra packet [<recv|send>] [detail]",
|
||||||
NO_STR
|
NO_STR
|
||||||
DEBUG_STR
|
DEBUG_STR
|
||||||
"Zebra configuration\n"
|
"Zebra configuration\n"
|
||||||
"Debug option set for zebra packet\n"
|
"Debug option set for zebra packet\n"
|
||||||
"Debug option set for receive packet\n"
|
"Debug option set for receive packet\n"
|
||||||
"Debug option set for send packet\n")
|
"Debug option set for send packet\n"
|
||||||
|
"Debug option set for detailed info\n")
|
||||||
{
|
{
|
||||||
int idx = 0;
|
zebra_debug_packet = 0;
|
||||||
if (argc == 4 || argv_find(argv, argc, "send", &idx))
|
|
||||||
UNSET_FLAG(zebra_debug_packet, ZEBRA_DEBUG_SEND);
|
|
||||||
if (argc == 4 || argv_find(argv, argc, "recv", &idx))
|
|
||||||
UNSET_FLAG(zebra_debug_packet, ZEBRA_DEBUG_RECV);
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -297,7 +307,7 @@ DEFUN (no_debug_zebra_kernel,
|
|||||||
"Zebra configuration\n"
|
"Zebra configuration\n"
|
||||||
"Debug option set for zebra between kernel interface\n")
|
"Debug option set for zebra between kernel interface\n")
|
||||||
{
|
{
|
||||||
UNSET_FLAG(zebra_debug_kernel, ZEBRA_DEBUG_KERNEL);
|
zebra_debug_kernel = 0;
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,37 +322,20 @@ DEFUN (no_debug_zebra_kernel_msgdump,
|
|||||||
"Dump raw netlink messages received\n"
|
"Dump raw netlink messages received\n"
|
||||||
"Dump raw netlink messages sent\n")
|
"Dump raw netlink messages sent\n")
|
||||||
{
|
{
|
||||||
int idx = 0;
|
zebra_debug_kernel = 0;
|
||||||
if (argc == 5 || argv_find(argv, argc, "recv", &idx))
|
|
||||||
UNSET_FLAG(zebra_debug_kernel, ZEBRA_DEBUG_KERNEL_MSGDUMP_RECV);
|
|
||||||
if (argc == 5 || argv_find(argv, argc, "send", &idx))
|
|
||||||
UNSET_FLAG(zebra_debug_kernel, ZEBRA_DEBUG_KERNEL_MSGDUMP_SEND);
|
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFUN (no_debug_zebra_rib,
|
DEFUN (no_debug_zebra_rib,
|
||||||
no_debug_zebra_rib_cmd,
|
no_debug_zebra_rib_cmd,
|
||||||
"no debug zebra rib",
|
"no debug zebra rib [detailed]",
|
||||||
NO_STR
|
|
||||||
DEBUG_STR
|
|
||||||
"Zebra configuration\n"
|
|
||||||
"Debug zebra RIB\n")
|
|
||||||
{
|
|
||||||
zebra_debug_rib = 0;
|
|
||||||
return CMD_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFUN (no_debug_zebra_rib_detailed,
|
|
||||||
no_debug_zebra_rib_detailed_cmd,
|
|
||||||
"no debug zebra rib detailed",
|
|
||||||
NO_STR
|
NO_STR
|
||||||
DEBUG_STR
|
DEBUG_STR
|
||||||
"Zebra configuration\n"
|
"Zebra configuration\n"
|
||||||
"Debug zebra RIB\n"
|
"Debug zebra RIB\n"
|
||||||
"Detailed debugs\n")
|
"Detailed debugs\n")
|
||||||
{
|
{
|
||||||
UNSET_FLAG(zebra_debug_rib, ZEBRA_DEBUG_RIB_DETAILED);
|
zebra_debug_rib = 0;
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -385,27 +378,31 @@ static int config_write_debug(struct vty *vty)
|
|||||||
write++;
|
write++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_ZEBRA_DEBUG_KERNEL) {
|
if (IS_ZEBRA_DEBUG_KERNEL) {
|
||||||
vty_out(vty, "debug zebra kernel\n");
|
if (IS_ZEBRA_DEBUG_KERNEL_MSGDUMP_SEND && IS_ZEBRA_DEBUG_KERNEL_MSGDUMP_RECV) {
|
||||||
write++;
|
vty_out(vty, "debug zebra kernel msgdump\n");
|
||||||
}
|
write++;
|
||||||
if (IS_ZEBRA_DEBUG_KERNEL_MSGDUMP_RECV) {
|
} else if (IS_ZEBRA_DEBUG_KERNEL_MSGDUMP_RECV) {
|
||||||
vty_out(vty, "debug zebra kernel msgdump recv\n");
|
vty_out(vty, "debug zebra kernel msgdump recv\n");
|
||||||
write++;
|
write++;
|
||||||
}
|
} else if (IS_ZEBRA_DEBUG_KERNEL_MSGDUMP_SEND) {
|
||||||
if (IS_ZEBRA_DEBUG_KERNEL_MSGDUMP_SEND) {
|
vty_out(vty, "debug zebra kernel msgdump send\n");
|
||||||
vty_out(vty, "debug zebra kernel msgdump send\n");
|
write++;
|
||||||
write++;
|
} else {
|
||||||
}
|
vty_out(vty, "debug zebra kernel\n");
|
||||||
/* Check here using flags as the 'macro' does an OR */
|
write++;
|
||||||
if (CHECK_FLAG(zebra_debug_rib, ZEBRA_DEBUG_RIB)) {
|
}
|
||||||
vty_out(vty, "debug zebra rib\n");
|
|
||||||
write++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CHECK_FLAG(zebra_debug_rib, ZEBRA_DEBUG_RIB_DETAILED)) {
|
if (CHECK_FLAG(zebra_debug_rib, ZEBRA_DEBUG_RIB_DETAILED)) {
|
||||||
vty_out(vty, "debug zebra rib detailed\n");
|
vty_out(vty, "debug zebra rib detailed\n");
|
||||||
write++;
|
write++;
|
||||||
|
} else if (CHECK_FLAG(zebra_debug_rib, ZEBRA_DEBUG_RIB)) {
|
||||||
|
vty_out(vty, "debug zebra rib\n");
|
||||||
|
write++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_ZEBRA_DEBUG_FPM) {
|
if (IS_ZEBRA_DEBUG_FPM) {
|
||||||
vty_out(vty, "debug zebra fpm\n");
|
vty_out(vty, "debug zebra fpm\n");
|
||||||
write++;
|
write++;
|
||||||
@ -447,7 +444,6 @@ void zebra_debug_init(void)
|
|||||||
install_element(ENABLE_NODE, &debug_zebra_kernel_cmd);
|
install_element(ENABLE_NODE, &debug_zebra_kernel_cmd);
|
||||||
install_element(ENABLE_NODE, &debug_zebra_kernel_msgdump_cmd);
|
install_element(ENABLE_NODE, &debug_zebra_kernel_msgdump_cmd);
|
||||||
install_element(ENABLE_NODE, &debug_zebra_rib_cmd);
|
install_element(ENABLE_NODE, &debug_zebra_rib_cmd);
|
||||||
install_element(ENABLE_NODE, &debug_zebra_rib_detailed_cmd);
|
|
||||||
install_element(ENABLE_NODE, &debug_zebra_fpm_cmd);
|
install_element(ENABLE_NODE, &debug_zebra_fpm_cmd);
|
||||||
install_element(ENABLE_NODE, &no_debug_zebra_events_cmd);
|
install_element(ENABLE_NODE, &no_debug_zebra_events_cmd);
|
||||||
install_element(ENABLE_NODE, &no_debug_zebra_nht_cmd);
|
install_element(ENABLE_NODE, &no_debug_zebra_nht_cmd);
|
||||||
@ -457,7 +453,6 @@ void zebra_debug_init(void)
|
|||||||
install_element(ENABLE_NODE, &no_debug_zebra_kernel_cmd);
|
install_element(ENABLE_NODE, &no_debug_zebra_kernel_cmd);
|
||||||
install_element(ENABLE_NODE, &no_debug_zebra_kernel_msgdump_cmd);
|
install_element(ENABLE_NODE, &no_debug_zebra_kernel_msgdump_cmd);
|
||||||
install_element(ENABLE_NODE, &no_debug_zebra_rib_cmd);
|
install_element(ENABLE_NODE, &no_debug_zebra_rib_cmd);
|
||||||
install_element(ENABLE_NODE, &no_debug_zebra_rib_detailed_cmd);
|
|
||||||
install_element(ENABLE_NODE, &no_debug_zebra_fpm_cmd);
|
install_element(ENABLE_NODE, &no_debug_zebra_fpm_cmd);
|
||||||
|
|
||||||
install_element(CONFIG_NODE, &debug_zebra_events_cmd);
|
install_element(CONFIG_NODE, &debug_zebra_events_cmd);
|
||||||
@ -468,7 +463,6 @@ void zebra_debug_init(void)
|
|||||||
install_element(CONFIG_NODE, &debug_zebra_kernel_cmd);
|
install_element(CONFIG_NODE, &debug_zebra_kernel_cmd);
|
||||||
install_element(CONFIG_NODE, &debug_zebra_kernel_msgdump_cmd);
|
install_element(CONFIG_NODE, &debug_zebra_kernel_msgdump_cmd);
|
||||||
install_element(CONFIG_NODE, &debug_zebra_rib_cmd);
|
install_element(CONFIG_NODE, &debug_zebra_rib_cmd);
|
||||||
install_element(CONFIG_NODE, &debug_zebra_rib_detailed_cmd);
|
|
||||||
install_element(CONFIG_NODE, &debug_zebra_fpm_cmd);
|
install_element(CONFIG_NODE, &debug_zebra_fpm_cmd);
|
||||||
install_element(CONFIG_NODE, &no_debug_zebra_events_cmd);
|
install_element(CONFIG_NODE, &no_debug_zebra_events_cmd);
|
||||||
install_element(CONFIG_NODE, &no_debug_zebra_nht_cmd);
|
install_element(CONFIG_NODE, &no_debug_zebra_nht_cmd);
|
||||||
@ -478,6 +472,5 @@ void zebra_debug_init(void)
|
|||||||
install_element(CONFIG_NODE, &no_debug_zebra_kernel_cmd);
|
install_element(CONFIG_NODE, &no_debug_zebra_kernel_cmd);
|
||||||
install_element(CONFIG_NODE, &no_debug_zebra_kernel_msgdump_cmd);
|
install_element(CONFIG_NODE, &no_debug_zebra_kernel_msgdump_cmd);
|
||||||
install_element(CONFIG_NODE, &no_debug_zebra_rib_cmd);
|
install_element(CONFIG_NODE, &no_debug_zebra_rib_cmd);
|
||||||
install_element(CONFIG_NODE, &no_debug_zebra_rib_detailed_cmd);
|
|
||||||
install_element(CONFIG_NODE, &no_debug_zebra_fpm_cmd);
|
install_element(CONFIG_NODE, &no_debug_zebra_fpm_cmd);
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user