mirror of
https://github.com/bgp/bgpq4
synced 2025-02-28 08:53:11 +00:00
Compare commits
92 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4dd3b92b3c | ||
|
|
a97f7eb4ff | ||
|
|
4ab84255a4 | ||
|
|
424770be0b | ||
|
|
4bac9e7e53 | ||
|
|
2ec0ea3fbd | ||
|
|
0a83c7598d | ||
|
|
f44bf47b1f | ||
|
|
9ffc4f8ec6 | ||
|
|
a89ac75590 | ||
|
|
59f800f31f | ||
|
|
6c8bb871c0 | ||
|
|
26b0827813 | ||
|
|
36a54c9b41 | ||
|
|
e743be94b3 | ||
|
|
b631d43755 | ||
|
|
57a70da5a9 | ||
|
|
95d3a4c12b | ||
|
|
2e06d3c389 | ||
|
|
3d2eed555d | ||
|
|
a28752247c | ||
|
|
26d631b257 | ||
|
|
841840be68 | ||
|
|
8ae08b79b1 | ||
|
|
9fa14cc506 | ||
|
|
92561f43af | ||
|
|
aee7adb698 | ||
|
|
3c201684b6 | ||
|
|
b98ecd5d4d | ||
|
|
d14db9515f | ||
|
|
8883f13b74 | ||
|
|
31ce2e452f | ||
|
|
b85bea6324 | ||
|
|
6fdae48462 | ||
|
|
89ab54454e | ||
|
|
baddc22f15 | ||
|
|
0deb7f224c | ||
|
|
975b577b2e | ||
|
|
b785c02e37 | ||
|
|
017bae280f | ||
|
|
2921348a98 | ||
|
|
233380d4e9 | ||
|
|
509e2f0acf | ||
|
|
a6b41d9352 | ||
|
|
7ac2068879 | ||
|
|
fc79ff9242 | ||
|
|
277126f5ea | ||
|
|
08b81f7d19 | ||
|
|
24c3e08f0e | ||
|
|
30110bad46 | ||
|
|
5507267c63 | ||
|
|
ab683d75d5 | ||
|
|
fb955c0521 | ||
|
|
4661fab181 | ||
|
|
6484a9a40c | ||
|
|
3ec83e255a | ||
|
|
c01ebfc3cb | ||
|
|
8dfcfb3173 | ||
|
|
c2126343cf | ||
|
|
96079b8901 | ||
|
|
58521eb687 | ||
|
|
8b804f83fd | ||
|
|
f26a04e8dd | ||
|
|
392a44a536 | ||
|
|
2aed3f9e67 | ||
|
|
d285db3c81 | ||
|
|
5d27a24659 | ||
|
|
97d1f2acda | ||
|
|
61a7bcf671 | ||
|
|
e920d74007 | ||
|
|
b1074667e8 | ||
|
|
bdc455d72e | ||
|
|
8cc7ba2751 | ||
|
|
06b430b420 | ||
|
|
8c51669da9 | ||
|
|
dc1270f10f | ||
|
|
362f747f0f | ||
|
|
6c8c6cfec1 | ||
|
|
fb29cd54e1 | ||
|
|
903704ef3b | ||
|
|
b481111cf6 | ||
|
|
80b7dcf4de | ||
|
|
5ce7d7bfea | ||
|
|
8ec260f03f | ||
|
|
675155356d | ||
|
|
da750ed48f | ||
|
|
7fdb481130 | ||
|
|
fa84d146b3 | ||
|
|
c90c59dba8 | ||
|
|
5730525f11 | ||
|
|
78f57867cc | ||
|
|
2391fdb317 |
17
.github/images/alpine.Dockerfile
vendored
Normal file
17
.github/images/alpine.Dockerfile
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
ARG image=alpine:latest
|
||||
FROM $image
|
||||
|
||||
# Install dependencies
|
||||
RUN apk upgrade
|
||||
RUN apk add autoconf automake file gcc gzip libtool make musl-dev
|
||||
|
||||
# Add source code
|
||||
ADD . /src
|
||||
WORKDIR /src
|
||||
|
||||
# Run steps
|
||||
RUN ./bootstrap
|
||||
RUN ./configure
|
||||
RUN make
|
||||
RUN make check
|
||||
RUN make distcheck
|
||||
1
.github/images/alpine:3.19.Dockerfile
vendored
Symbolic link
1
.github/images/alpine:3.19.Dockerfile
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
alpine.Dockerfile
|
||||
24
.github/images/alpine:3.Dockerfile
vendored
Normal file
24
.github/images/alpine:3.Dockerfile
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
# to build the image locally tagged with the short commit hash:
|
||||
# docker build -t bgpq4:$(git rev-parse --short HEAD) -f .github/images/alpine:3.Dockerfile .
|
||||
ARG IMAGE=alpine:3
|
||||
FROM $IMAGE as builder
|
||||
|
||||
# Install dependencies
|
||||
RUN apk upgrade
|
||||
RUN apk add autoconf automake file gcc gzip libtool make musl-dev
|
||||
|
||||
# Add source code
|
||||
ADD . /src
|
||||
WORKDIR /src
|
||||
|
||||
# Run steps
|
||||
RUN ./bootstrap
|
||||
RUN ./configure
|
||||
RUN make
|
||||
RUN make check
|
||||
RUN make distcheck
|
||||
|
||||
FROM alpine:3
|
||||
COPY --from=builder /src/bgpq4 /bgp/
|
||||
WORKDIR /bgp
|
||||
ENTRYPOINT [ "./bgpq4" ]
|
||||
1
.github/images/alpine:edge.Dockerfile
vendored
Symbolic link
1
.github/images/alpine:edge.Dockerfile
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
alpine.Dockerfile
|
||||
10
.github/images/centos.Dockerfile
vendored
10
.github/images/centos.Dockerfile
vendored
@@ -1,10 +1,9 @@
|
||||
ARG image=centos:8
|
||||
FROM $image
|
||||
ARG image=centos/centos:latest
|
||||
FROM quay.io/$image
|
||||
|
||||
# Install dependencies
|
||||
RUN yum update -y
|
||||
RUN yum groupinstall -y 'Development Tools'
|
||||
RUN yum install -y autoconf automake findutils libtool
|
||||
RUN if command -v yum > /dev/null; then dnf=yum; fi; ${dnf:-dnf} update -y
|
||||
RUN if command -v yum > /dev/null; then dnf=yum; fi; ${dnf:-dnf} install -y autoconf automake gcc libtool make diffutils file gzip
|
||||
|
||||
# Add source code
|
||||
ADD . /src
|
||||
@@ -16,4 +15,3 @@ RUN ./configure
|
||||
RUN make
|
||||
RUN make check
|
||||
RUN make distcheck
|
||||
|
||||
|
||||
1
.github/images/centos/centos:7.Dockerfile
vendored
Symbolic link
1
.github/images/centos/centos:7.Dockerfile
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../centos.Dockerfile
|
||||
1
.github/images/centos/centos:stream8.Dockerfile
vendored
Symbolic link
1
.github/images/centos/centos:stream8.Dockerfile
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../centos.Dockerfile
|
||||
1
.github/images/centos/centos:stream9.Dockerfile
vendored
Symbolic link
1
.github/images/centos/centos:stream9.Dockerfile
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../centos.Dockerfile
|
||||
1
.github/images/centos:7.Dockerfile
vendored
1
.github/images/centos:7.Dockerfile
vendored
@@ -1 +0,0 @@
|
||||
centos.Dockerfile
|
||||
1
.github/images/centos:8.Dockerfile
vendored
1
.github/images/centos:8.Dockerfile
vendored
@@ -1 +0,0 @@
|
||||
centos.Dockerfile
|
||||
1
.github/images/debian:trixie.Dockerfile
vendored
Symbolic link
1
.github/images/debian:trixie.Dockerfile
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
debian.Dockerfile
|
||||
1
.github/images/fedora/fedora:38.Dockerfile
vendored
Symbolic link
1
.github/images/fedora/fedora:38.Dockerfile
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../centos.Dockerfile
|
||||
1
.github/images/fedora/fedora:39.Dockerfile
vendored
Symbolic link
1
.github/images/fedora/fedora:39.Dockerfile
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../centos.Dockerfile
|
||||
1
.github/images/fedora/fedora:40.Dockerfile
vendored
Symbolic link
1
.github/images/fedora/fedora:40.Dockerfile
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../centos.Dockerfile
|
||||
1
.github/images/fedora:30.Dockerfile
vendored
1
.github/images/fedora:30.Dockerfile
vendored
@@ -1 +0,0 @@
|
||||
centos.Dockerfile
|
||||
1
.github/images/fedora:31.Dockerfile
vendored
1
.github/images/fedora:31.Dockerfile
vendored
@@ -1 +0,0 @@
|
||||
centos.Dockerfile
|
||||
1
.github/images/rockylinux/rockylinux:8.Dockerfile
vendored
Symbolic link
1
.github/images/rockylinux/rockylinux:8.Dockerfile
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../centos.Dockerfile
|
||||
1
.github/images/rockylinux/rockylinux:9.Dockerfile
vendored
Symbolic link
1
.github/images/rockylinux/rockylinux:9.Dockerfile
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../centos.Dockerfile
|
||||
1
.github/images/ubuntu:focal.Dockerfile
vendored
Symbolic link
1
.github/images/ubuntu:focal.Dockerfile
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
debian.Dockerfile
|
||||
1
.github/images/ubuntu:jammy.Dockerfile
vendored
Symbolic link
1
.github/images/ubuntu:jammy.Dockerfile
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
debian.Dockerfile
|
||||
65
.github/workflows/build-container.yml
vendored
Normal file
65
.github/workflows/build-container.yml
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
name: Container build
|
||||
"on":
|
||||
push:
|
||||
tags:
|
||||
- "*" # Push events to any tag
|
||||
branches:
|
||||
- "main"
|
||||
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
tag:
|
||||
description: "Container tag to use for the build"
|
||||
required: true
|
||||
default: "test"
|
||||
|
||||
jobs:
|
||||
test:
|
||||
uses: ./.github/workflows/unit-tests.yml
|
||||
|
||||
build:
|
||||
name: Build container
|
||||
runs-on: ubuntu-22.04
|
||||
needs: test
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- # Add support for more platforms with QEMU
|
||||
# https://github.com/docker/setup-qemu-action
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: ghcr.io/${{ github.repository_owner }}/bgpq4
|
||||
tags: |
|
||||
# pick up tag provided from workflow_dispatch user's input
|
||||
type=raw,value=${{ inputs.tag }}
|
||||
type=ref,event=tag
|
||||
type=ref,event=branch
|
||||
# git short commit
|
||||
type=sha
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
if: github.repository_owner == 'bgp'
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
file: .github/images/alpine:3.Dockerfile
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: ${{ github.repository_owner == 'bgp' }}
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
13
.github/workflows/build.yml
vendored
13
.github/workflows/build.yml
vendored
@@ -1,12 +1,18 @@
|
||||
name: Build and test (single linux distro)
|
||||
name: Build and test (latest Ubuntu/macOS)
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest]
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/checkout@v4
|
||||
- name: install macOS autogen prerequisites
|
||||
run: brew install autoconf automake libtool
|
||||
if: runner.os == 'macOS'
|
||||
- name: bootstrap
|
||||
run: ./bootstrap
|
||||
- name: configure
|
||||
@@ -17,4 +23,5 @@ jobs:
|
||||
run: make check
|
||||
- name: make distcheck
|
||||
run: make distcheck
|
||||
if: runner.os == 'Linux'
|
||||
|
||||
|
||||
38
.github/workflows/codeql-analysis.yml
vendored
Normal file
38
.github/workflows/codeql-analysis.yml
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
name: CodeQL analysis
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
schedule:
|
||||
# build the main branch every Tuesday morning
|
||||
- cron: '15 6 * * 2'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ 'cpp' ]
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
- name: Build Application using script
|
||||
run: |
|
||||
./bootstrap
|
||||
./configure
|
||||
make
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v3
|
||||
with:
|
||||
category: "/language:${{matrix.language}}"
|
||||
26
.github/workflows/matrixbuild.yml
vendored
26
.github/workflows/matrixbuild.yml
vendored
@@ -9,15 +9,27 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
dockerenv:
|
||||
- debian:trixie
|
||||
- debian:bookworm
|
||||
- debian:bullseye
|
||||
- debian:buster
|
||||
- debian:stretch
|
||||
- ubuntu:jammy
|
||||
- ubuntu:focal
|
||||
- ubuntu:bionic
|
||||
- ubuntu:xenial
|
||||
- centos:8
|
||||
- centos:7
|
||||
- fedora:31
|
||||
- fedora:30
|
||||
- fedora/fedora:40
|
||||
- fedora/fedora:39
|
||||
- fedora/fedora:38
|
||||
- centos/centos:stream9
|
||||
- centos/centos:stream8
|
||||
- centos/centos:7
|
||||
- rockylinux/rockylinux:9
|
||||
- rockylinux/rockylinux:8
|
||||
- alpine:edge
|
||||
- alpine:3.19
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/checkout@v4
|
||||
- name: Work around Docker BuildKit regression
|
||||
# https://github.com/moby/buildkit/issues/2119: `DOCKER_BUILDKIT=1 docker build` fails if Dockerfile is a symlink
|
||||
run: cp --remove-destination $(readlink -f .github/images/${{matrix.dockerenv}}.Dockerfile) .github/images/${{matrix.dockerenv}}.Dockerfile
|
||||
- name: Run build on ${{matrix.dockerenv}}
|
||||
run: docker build . --file .github/images/${{matrix.dockerenv}}.Dockerfile --build-arg image=${{matrix.dockerenv}}
|
||||
|
||||
37
.github/workflows/unit-tests.yml
vendored
Normal file
37
.github/workflows/unit-tests.yml
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
name: basic unit tests
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types:
|
||||
- opened
|
||||
- edited
|
||||
- reopened
|
||||
- ready_for_review
|
||||
- synchronize
|
||||
workflow_call:
|
||||
|
||||
jobs:
|
||||
output-unit-tests:
|
||||
name: output unit tests
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: clone repo
|
||||
uses: actions/checkout@v4
|
||||
- name: install pre-reqs
|
||||
run: |
|
||||
sudo apt-get update
|
||||
DEBIAN_FRONTEND=noninteractive sudo apt-get -y --no-install-recommends install autoconf automake libtool make
|
||||
- name: build bgpq4
|
||||
run: |
|
||||
./bootstrap
|
||||
./configure
|
||||
make
|
||||
./bgpq4 -v
|
||||
- name: generate output
|
||||
run: ./tests/generate_outputs.sh ./bgpq4 /tmp
|
||||
- name: check output
|
||||
run: >
|
||||
for file in tests/reference/*.txt;
|
||||
do
|
||||
echo "$(sha256sum "${file}" | awk '{print $1}') /tmp/$(basename "${file}")" | sha256sum --check;
|
||||
done
|
||||
45
CHANGES
45
CHANGES
@@ -1,3 +1,48 @@
|
||||
1.14 (2024-05-14)
|
||||
- Small performance gain: set TCP_NODELAY on the socket
|
||||
|
||||
1.13 (2024-05-01)
|
||||
- Fixed a bug for Mac users by removing sx_maxsockbuf()
|
||||
- Fixed a comma printing bug in IOS XR as-path-set output
|
||||
|
||||
1.12 (2024-02-12)
|
||||
- Fix a bug in the mikrotik printer
|
||||
|
||||
1.11 (2023-06-20)
|
||||
- disallow AS 23456 as origin (can be bypassed via -p)
|
||||
|
||||
1.10 (2023-06-03)
|
||||
- Add support for Nokia SR Linux IP prefix lists / ACL filters
|
||||
- Accept -3 as a no-op for bgpq3 compatibility
|
||||
|
||||
1.9 (2023-03-05)
|
||||
- Bugfix for -S problem (bgpq4#83) by James Bensley
|
||||
|
||||
1.8 (2023-01-20)
|
||||
- Downgrade 'key not found' to DEBUG level to reduce noise
|
||||
- Re-introduce -p for private ASN support option
|
||||
|
||||
1.7 (2022-11-03)
|
||||
- Support SOURCE:: syntax (contributed by James Bensley)
|
||||
|
||||
1.6 (2022-09-07)
|
||||
- Fix a bug in address prefix range parsing
|
||||
|
||||
1.5 (2022-07-25)
|
||||
- Add support for the new Junos as-path-origins feature
|
||||
|
||||
1.4 (2021-08-20)
|
||||
- Fix BIRD aspath output
|
||||
|
||||
1.3 (2021-08-20)
|
||||
- Change versioning from X.Y.Z to Y.Z
|
||||
- The repository file hierachy has been reorganized (compat/ include/)
|
||||
- Man page has been extended
|
||||
- Large portions of code have been reformatted to adhere to OpenBSD's source
|
||||
file style guide to improve readability.
|
||||
- Refactor: replace two-dimensional array for ASN storage with Red-Black tree
|
||||
- Reduced memory usage
|
||||
|
||||
0.0.9 (2021-08-18)
|
||||
- Fix various memory errors
|
||||
|
||||
|
||||
29
IDEAS
Normal file
29
IDEAS
Normal file
@@ -0,0 +1,29 @@
|
||||
Ben Maddison taught me another aggregation trick:
|
||||
|
||||
route-set: AS37271:RS-EXAMPLE
|
||||
mp-members: 192.0.2.0/27
|
||||
mp-members: 192.0.2.32/27
|
||||
mp-members: 192.0.2.64/27
|
||||
mp-members: 192.0.2.96/27
|
||||
mp-members: 192.0.2.128/26
|
||||
mp-members: 192.0.2.128/27
|
||||
mp-members: 192.0.2.160/27
|
||||
mp-members: 192.0.2.192/27
|
||||
mp-members: 192.0.2.224/27
|
||||
descr: Example route-set
|
||||
mnt-by: MAINT-AS37271
|
||||
changed: benm@workonline.africa 20210819
|
||||
source: RADB
|
||||
|
||||
BGPQ4 produces the following:
|
||||
|
||||
$ bgpq4 -A AS37271:RS-EXAMPLE
|
||||
no ip prefix-list NN
|
||||
ip prefix-list NN permit 192.0.2.0/25 ge 27 le 27
|
||||
ip prefix-list NN permit 192.0.2.128/26 le 27
|
||||
ip prefix-list NN permit 192.0.2.192/26 ge 27 le 27
|
||||
|
||||
But the following aggregation also is valid, and shorter:
|
||||
|
||||
ip prefix-list NN permit 192.0.2.0/24 ge 27 le 27
|
||||
ip prefix-list NN permit 192.0.2.128/26
|
||||
10
Makefile.am
10
Makefile.am
@@ -17,7 +17,6 @@ bgpq4_LDADD += $(top_builddir)/compat/libcompat.la
|
||||
endif
|
||||
|
||||
bgpq4_SOURCES=main.c extern.h printer.c expander.c \
|
||||
sx_maxsockbuf.c \
|
||||
sx_prefix.c sx_prefix.h \
|
||||
sx_report.c sx_report.h \
|
||||
sx_slentry.c
|
||||
@@ -33,3 +32,12 @@ MAINTAINERCLEANFILES=configure aclocal.m4 compile \
|
||||
|
||||
maintainer-clean-local:
|
||||
-rm -rf m4 autom4te.cache
|
||||
|
||||
check:
|
||||
./bgpq4 -v
|
||||
@echo
|
||||
-if [ -s /etc/resolv.conf ]; then \
|
||||
./bgpq4 -ddd -6 AS15562:AS-SNIJDERS ; \
|
||||
else \
|
||||
echo "No or empty /etc/resolv.conf, skipping online test"; \
|
||||
fi
|
||||
|
||||
610
README.md
610
README.md
@@ -1,240 +1,252 @@
|
||||
NAME
|
||||
----
|
||||
[](https://github.com/bgp/bgpq4/actions/workflows/unit-tests.yml)
|
||||
|
||||
`bgpq4` - bgp filtering automation tool
|
||||
<a href="https://repology.org/project/bgpq4/versions">
|
||||
<img src="https://repology.org/badge/vertical-allrepos/bgpq4.svg" alt="Packaging status" align="right">
|
||||
</a>
|
||||
|
||||
The `bgpq4` utility queries IRRd and then generates IRR and/or RPKI based
|
||||
filters formatted for a wide assortment of BGP implementations.
|
||||
# NAME
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
**bgpq4** - bgp filtering automation tool
|
||||
|
||||
```
|
||||
bgpq4 [-h host[:port]] [-S sources] [-Ez] [-f asn | -F fmt | -G asn | -t] [-46ABbDdeJjNnpsUX] [-a asn] [-r len] [-R len] [-m max] [-W len] OBJECTS [...] EXCEPT OBJECTS
|
||||
```
|
||||
# SYNOPSIS
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
**bgpq4**
|
||||
\[**-h** *host\[:port]*]
|
||||
\[**-S** *sources*]
|
||||
\[**-EPz**]
|
||||
\[**-f** *asn* |
|
||||
**-F** *fmt* |
|
||||
**-G** *asn*
|
||||
**-H** *asn*
|
||||
**-t**]
|
||||
\[**-46ABbDdJjNnpsXU**]
|
||||
\[**-a** *asn*]
|
||||
\[**-r** *len*]
|
||||
\[**-R** *len*]
|
||||
\[**-m** *max*]
|
||||
\[**-W** *len*]
|
||||
*OBJECTS*
|
||||
\[...]
|
||||
\[EXCEPT OBJECTS]
|
||||
|
||||
The bgpq4 utility used to generate configuration (prefix-lists,
|
||||
extended access-lists, policy-statement terms and as-path lists)
|
||||
based on IRR routing data.
|
||||
# DESCRIPTION
|
||||
|
||||
The options are as follows:
|
||||
The
|
||||
**bgpq4**
|
||||
utility is used to generate configurations (prefix-lists, extended
|
||||
access-lists, policy-statement terms and as-path lists) based on IRR data.
|
||||
|
||||
#### -4
|
||||
It's options are as follows:
|
||||
|
||||
Generate IPv4 prefix/access-lists (default).
|
||||
**-4**
|
||||
|
||||
#### -6
|
||||
> generate IPv4 prefix/access-lists (default).
|
||||
|
||||
Generate IPv6 prefix/access-lists (IPv4 by default).
|
||||
**-6**
|
||||
|
||||
#### -A
|
||||
> generate IPv6 prefix/access-lists (IPv4 by default).
|
||||
|
||||
Try to aggregate generated filters as much as possible (not all output formats
|
||||
supported).
|
||||
**-A**
|
||||
|
||||
#### -a asn
|
||||
> try to aggregate prefix-lists as much as possible (not all output
|
||||
> formats supported).
|
||||
|
||||
Specify ASN that shall be denied in case of empty prefix-list (OpenBGPD).
|
||||
**-a** *asn*
|
||||
|
||||
#### -B
|
||||
> specify what asn shall be denied in case of empty prefix-list (OpenBGPD)
|
||||
|
||||
Generate output in OpenBGPD format.
|
||||
**-B**
|
||||
|
||||
#### -b
|
||||
> generate output in OpenBGPD format (default: Cisco)
|
||||
|
||||
Generate output in BIRD format.
|
||||
**-b**
|
||||
|
||||
#### -d
|
||||
> generate output in BIRD format (default: Cisco).
|
||||
|
||||
Enable some debugging output.
|
||||
**-d**
|
||||
|
||||
#### -E
|
||||
> enable some debugging output.
|
||||
|
||||
Generate extended access-list (Cisco) or policy-statement term using
|
||||
route-filters (Juniper), [ip|ipv6]-prefix-list (Nokia) or prefix-filter
|
||||
(OpenBGPD)
|
||||
**-e**
|
||||
|
||||
#### -e
|
||||
> generate output in Arista EOS format (default: Cisco).
|
||||
|
||||
Generate output in Arista EOS format.
|
||||
**-E**
|
||||
|
||||
#### -f `AS number`
|
||||
> generate extended access-list (Cisco), policy-statement term using
|
||||
> route-filters (Juniper), \[ip|ipv6]-prefix-list (Nokia) or prefix-sets
|
||||
> (OpenBGPd).
|
||||
|
||||
Generate input as-path access-list for adjacent as `AS number`.
|
||||
**-f** *number*
|
||||
|
||||
#### -F `fmt`
|
||||
> generate input as-path access-list.
|
||||
|
||||
Generate output in user-defined format.
|
||||
**-F** *fmt*
|
||||
|
||||
#### -G `number`
|
||||
> generate output in user-defined format.
|
||||
|
||||
Generate output as-path access-list.
|
||||
**-G** *number*
|
||||
|
||||
#### -h `host[:port]`
|
||||
> generate output as-path access-list.
|
||||
|
||||
Host running IRRD database (default: `rr.ntt.net`).
|
||||
**-H** *number*
|
||||
|
||||
#### -J
|
||||
> generate output as-list for JunOS 21.3R1+ `as-path-origin` filter (JunOS only)
|
||||
|
||||
Generate config for Juniper.
|
||||
**-h** *host\[:port]*
|
||||
|
||||
#### -j
|
||||
> host running IRRD database (default: rr.ntt.net).
|
||||
|
||||
Generate output in JSON format.
|
||||
**-J**
|
||||
|
||||
#### -K
|
||||
> generate config for Juniper (default: Cisco).
|
||||
|
||||
Generate config for MikroTik.
|
||||
**-j**
|
||||
|
||||
#### -m `length`
|
||||
> generate output in JSON format (default: Cisco).
|
||||
|
||||
Maximum length of accepted prefixes (default: `32` for IPv4, `128` for IPv6).
|
||||
**-K**
|
||||
|
||||
#### -M `match`
|
||||
> generate config for Mikrotik ROSv6 (default: Cisco).
|
||||
|
||||
Extra match conditions for Juniper route-filters. See the examples section.
|
||||
**-K7**
|
||||
|
||||
#### -n
|
||||
> generate config for Mikrotik ROSv7 (default: Cisco).
|
||||
|
||||
Generate config for Nokia SR OS (former Alcatel-Lucent) MD-CLI.
|
||||
**-l** *name*
|
||||
|
||||
#### -N
|
||||
> name of generated entry.
|
||||
|
||||
Generate config for Nokia SR OS (former Alcatel-Lucent) classic CLI.
|
||||
**-L** *limit*
|
||||
|
||||
#### -l `name`
|
||||
> limit recursion depth when expanding as-sets.
|
||||
|
||||
`Name` of generated configuration stanza.
|
||||
**-m** *len*
|
||||
|
||||
#### -L `limit`
|
||||
> maximum prefix-length of accepted prefixes (default: 32 for IPv4 and
|
||||
> 128 for IPv6).
|
||||
|
||||
Limit recursion depth when expanding. This slows `bgpq4` a bit, but sometimes
|
||||
is a useful feature to prevent generated filters from growing too big.
|
||||
**-M** *match*
|
||||
|
||||
#### -p
|
||||
> extra match conditions for Juniper route-filters.
|
||||
|
||||
Enable use of private ASNs and ASNs used for documentation purpose only
|
||||
(default: disabled).
|
||||
**-n**
|
||||
|
||||
#### -r `length`
|
||||
> generate config for Nokia SR OS MD-CLI (Cisco IOS by default)
|
||||
|
||||
Allow more-specific routes with masklen starting with specified length.
|
||||
**-n2**
|
||||
|
||||
#### -R `length`
|
||||
> generate config for Nokia SR Linux (Cisco IOS by default)
|
||||
|
||||
Allow more-specific routes up to specified masklen too. (Please, note: objects
|
||||
with prefix-length greater than specified length will be always allowed.)
|
||||
**-N**
|
||||
|
||||
#### -s
|
||||
> generate config for Nokia SR OS classic CLI (Cisco IOS by default).
|
||||
|
||||
Generate sequence numbers in IOS-style prefix-lists.
|
||||
**-p**
|
||||
|
||||
#### -S `sources`
|
||||
> emit prefixes where the origin ASN is in the private ASN range
|
||||
> (disabled by default).
|
||||
|
||||
Use specified sources only (recommended: RADB,RIPE,APNIC).
|
||||
**-r** *len*
|
||||
|
||||
#### -t
|
||||
> allow more specific routes starting with specified masklen too.
|
||||
|
||||
Generate as-sets for OpenBGPD (OpenBSD 6.4+), BIRD and JSON formats.
|
||||
**-R** *len*
|
||||
|
||||
#### -T
|
||||
> allow more specific routes up to specified masklen too.
|
||||
|
||||
Disable pipelining (not recommended).
|
||||
**-s**
|
||||
|
||||
#### -U
|
||||
> generate sequence numbers in IOS-style prefix-lists.
|
||||
|
||||
Generate output in Huawei format.
|
||||
**-S** *sources*
|
||||
|
||||
#### -W `length`
|
||||
> use specified sources only (recommended: RPKI,AFRINIC,ARIN,APNIC,LACNIC,RIPE).
|
||||
|
||||
Generate as-path strings of a given length maximum (0 for infinity).
|
||||
**-t**
|
||||
|
||||
#### -X
|
||||
> generate as-sets for OpenBGPd, BIRD and JSON formats.
|
||||
|
||||
Generate output in Cisco IOS XR format.
|
||||
**-T**
|
||||
|
||||
#### -z
|
||||
> disable pipelining (not recommended).
|
||||
|
||||
Generate Juniper route-filter-list (JunOS 16.2+).
|
||||
**-W** *len*
|
||||
|
||||
#### `OBJECTS`
|
||||
> generate as-path strings of no more than len items (use 0 for infinity).
|
||||
|
||||
`OBJECTS` means networks (in prefix format), autonomous systems, as-sets and
|
||||
route-sets. If multiple objects are specified they will be merged.
|
||||
**-U**
|
||||
|
||||
#### `EXCEPT OBJECTS`
|
||||
> generate config for Huawei devices (Cisco IOS by default)
|
||||
|
||||
You can exclude autonomous sets, as-sets and route-sets found during
|
||||
expansion from future expansion.
|
||||
**-u**
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
Generating prefix filter for MikroTik for `AS20597`:
|
||||
> generate output in Huawei XPL format.
|
||||
|
||||
$ ./bgpq4 -Kl eltel-v4 AS20597
|
||||
/routing filter add action=accept chain="eltel-v4" prefix=81.9.0.0/20
|
||||
/routing filter add action=accept chain="eltel-v4" prefix=81.9.32.0/20
|
||||
/routing filter add action=accept chain="eltel-v4" prefix=81.9.96.0/20
|
||||
/routing filter add action=accept chain="eltel-v4" prefix=81.222.128.0/20
|
||||
/routing filter add action=accept chain="eltel-v4" prefix=81.222.160.0/20
|
||||
/routing filter add action=accept chain="eltel-v4" prefix=81.222.192.0/18
|
||||
/routing filter add action=accept chain="eltel-v4" prefix=85.249.8.0/21
|
||||
/routing filter add action=accept chain="eltel-v4" prefix=85.249.224.0/19
|
||||
/routing filter add action=accept chain="eltel-v4" prefix=89.112.0.0/17
|
||||
/routing filter add action=accept chain="eltel-v4" prefix=217.170.64.0/19
|
||||
**-X**
|
||||
|
||||
Generating named Juniper prefix-filter for `AS20597`:
|
||||
> generate config for Cisco IOS XR devices (plain IOS by default).
|
||||
|
||||
$ bgpq4 -Jl eltel-v4 AS20597
|
||||
policy-options {
|
||||
replace:
|
||||
prefix-list eltel-v4 {
|
||||
81.9.0.0/20;
|
||||
81.9.32.0/20;
|
||||
81.9.96.0/20;
|
||||
81.222.128.0/20;
|
||||
81.222.192.0/18;
|
||||
85.249.8.0/21;
|
||||
85.249.224.0/19;
|
||||
89.112.0.0/19;
|
||||
89.112.4.0/22;
|
||||
89.112.32.0/19;
|
||||
89.112.64.0/19;
|
||||
217.170.64.0/20;
|
||||
217.170.80.0/20;
|
||||
}
|
||||
}
|
||||
**-z**
|
||||
|
||||
> generate route-filter-lists (JunOS 16.2+).
|
||||
|
||||
*OBJECTS*
|
||||
|
||||
> means networks (in prefix format), autonomous systems, as-sets and route-sets.
|
||||
|
||||
*EXCEPT OBJECTS*
|
||||
|
||||
> those objects will be excluded from expansion.
|
||||
|
||||
# EXAMPLES
|
||||
|
||||
Generating named juniper prefix-filter for AS20597:
|
||||
|
||||
$ bgpq4 -Jl eltel AS20597
|
||||
policy-options {
|
||||
replace:
|
||||
prefix-list eltel {
|
||||
81.9.0.0/20;
|
||||
81.9.32.0/20;
|
||||
81.9.96.0/20;
|
||||
81.222.128.0/20;
|
||||
81.222.192.0/18;
|
||||
85.249.8.0/21;
|
||||
85.249.224.0/19;
|
||||
89.112.0.0/19;
|
||||
89.112.4.0/22;
|
||||
89.112.32.0/19;
|
||||
89.112.64.0/19;
|
||||
217.170.64.0/20;
|
||||
217.170.80.0/20;
|
||||
}
|
||||
}
|
||||
|
||||
For Cisco we can use aggregation (-A) flag to make this prefix-filter
|
||||
more compact:
|
||||
|
||||
$ bgpq4 -Al eltel-v4 AS20597
|
||||
no ip prefix-list eltel-v4
|
||||
ip prefix-list eltel-v4 permit 81.9.0.0/20
|
||||
ip prefix-list eltel-v4 permit 81.9.32.0/20
|
||||
ip prefix-list eltel-v4 permit 81.9.96.0/20
|
||||
ip prefix-list eltel-v4 permit 81.222.128.0/20
|
||||
ip prefix-list eltel-v4 permit 81.222.192.0/18
|
||||
ip prefix-list eltel-v4 permit 85.249.8.0/21
|
||||
ip prefix-list eltel-v4 permit 85.249.224.0/19
|
||||
ip prefix-list eltel-v4 permit 89.112.0.0/18 ge 19 le 19
|
||||
ip prefix-list eltel-v4 permit 89.112.4.0/22
|
||||
ip prefix-list eltel-v4 permit 89.112.64.0/19
|
||||
ip prefix-list eltel-v4 permit 217.170.64.0/19 ge 20 le 20
|
||||
$ bgpq4 -Al eltel AS20597
|
||||
no ip prefix-list eltel
|
||||
ip prefix-list eltel permit 81.9.0.0/20
|
||||
ip prefix-list eltel permit 81.9.32.0/20
|
||||
ip prefix-list eltel permit 81.9.96.0/20
|
||||
ip prefix-list eltel permit 81.222.128.0/20
|
||||
ip prefix-list eltel permit 81.222.192.0/18
|
||||
ip prefix-list eltel permit 85.249.8.0/21
|
||||
ip prefix-list eltel permit 85.249.224.0/19
|
||||
ip prefix-list eltel permit 89.112.0.0/18 ge 19 le 19
|
||||
ip prefix-list eltel permit 89.112.4.0/22
|
||||
ip prefix-list eltel permit 89.112.64.0/19
|
||||
ip prefix-list eltel permit 217.170.64.0/19 ge 20 le 20
|
||||
|
||||
and, as you see, prefixes `89.112.0.0/19` and `89.112.32.0/19` now aggregated
|
||||
into single entry
|
||||
Prefixes 89.112.0.0/19 and 89.112.32.0/19 now aggregated
|
||||
into single entry 89.112.0.0/18 ge 19 le 19.
|
||||
|
||||
ip prefix-list eltel permit 89.112.0.0/18 ge 19 le 19.
|
||||
Well, for Juniper we can generate even more interesting policy-options,
|
||||
using -M <extra match conditions>, -R <len> and hierarchical names:
|
||||
|
||||
Well, for Juniper we can generate even more interesting policy-statement,
|
||||
using `-M <extra match conditions>`, `-r <len>`, `-R <len>` and hierarchical
|
||||
names:
|
||||
|
||||
$ bgpq4 -AJEl eltel/specifics -r 29 -R 32 -M "community blackhole" AS20597
|
||||
$ bgpq4 -AJEl eltel/specifics -r 29 -R 32 -M "community blackhole" AS20597
|
||||
policy-options {
|
||||
policy-statement eltel {
|
||||
term specifics {
|
||||
@@ -255,51 +267,83 @@ names:
|
||||
}
|
||||
}
|
||||
|
||||
generated policy-option term now allows all specifics with prefix-length
|
||||
between /29 and /32 for eltel networks if they match with special community
|
||||
blackhole (defined elsewhere in configuration).
|
||||
|
||||
generated policy-option term now allows more-specific routes in range
|
||||
/29 - /32 for eltel networks if they marked with community 'blackhole'
|
||||
(defined elsewhere in configuration).
|
||||
Of course, this version supports IPv6 (-6):
|
||||
|
||||
Of course, `bgpq4` supports IPv6 (-6):
|
||||
|
||||
$ bgpq4 -6l as-retn-v6 AS-RETN6
|
||||
no ipv6 prefix-list as-retn-v6
|
||||
ipv6 prefix-list as-retn-v6 permit 2001:7fb:fe00::/48
|
||||
ipv6 prefix-list as-retn-v6 permit 2001:7fb:fe01::/48
|
||||
[....]
|
||||
$ bgpq4 -6l as-retn-6 AS-RETN6
|
||||
no ipv6 prefix-list as-retn-6
|
||||
ipv6 prefix-list as-retn-6 permit 2001:7fb:fe00::/48
|
||||
ipv6 prefix-list as-retn-6 permit 2001:7fb:fe01::/48
|
||||
[....]
|
||||
|
||||
and assumes your device supports 32-bit ASNs
|
||||
|
||||
$ bgpq4 -Jf 112 AS-SPACENET
|
||||
policy-options {
|
||||
replace:
|
||||
as-path-group NN {
|
||||
as-path a0 "^112(112)*$";
|
||||
as-path a1 "^112(.)*(1898|5539|8495|8763|8878|12136|12931|15909)$";
|
||||
as-path a2 "^112(.)*(21358|23600|24151|25152|31529|34127|34906)$";
|
||||
as-path a3 "^112(.)*(35052|41720|43628|44450|196611)$";
|
||||
}
|
||||
}
|
||||
$ bgpq4 -Jf 112 AS-SPACENET
|
||||
policy-options {
|
||||
replace:
|
||||
as-path-group NN {
|
||||
as-path a0 "^112(112)*$";
|
||||
as-path a1 "^112(.)*(1898|5539|8495|8763|8878|12136|12931|15909)$";
|
||||
as-path a2 "^112(.)*(21358|23456|23600|24151|25152|31529|34127|34906)$";
|
||||
as-path a3 "^112(.)*(35052|41720|43628|44450|196611)$";
|
||||
}
|
||||
}
|
||||
|
||||
see `AS196611` in the end of the list ? That's a 32-bit ASN.
|
||||
see \`AS196611\` in the end of the list ? That's a 32-bit ASN.
|
||||
|
||||
USER-DEFINED FORMAT
|
||||
-------------------
|
||||
# USER-DEFINED FORMAT
|
||||
|
||||
If you want to generate configuration not for routers, but for some
|
||||
other programs/systems, you may use user-defined formatting, like in
|
||||
example below:
|
||||
|
||||
$ bgpq4 -F "ipfw add pass all from %n/%l to any\\n" as3254
|
||||
$ bgpq4 -F "ipfw add pass all from %n/%l to any\n" as3254
|
||||
ipfw add pass all from 62.244.0.0/18 to any
|
||||
ipfw add pass all from 91.219.29.0/24 to any
|
||||
ipfw add pass all from 91.219.30.0/24 to any
|
||||
ipfw add pass all from 193.193.192.0/19 to any
|
||||
|
||||
Recognized format characters: '%n' - network, '%l' - mask length,
|
||||
'%a' - aggregate low mask length, '%A' - aggregate high mask length,
|
||||
'%N' - object name, '%m' - object mask and '%i' - inversed mask.
|
||||
Recognized escape characters: '\n' - new line, '\t' - tabulation.
|
||||
Recognized format sequences are:
|
||||
|
||||
**%n**
|
||||
|
||||
> network
|
||||
|
||||
**%l**
|
||||
|
||||
> mask length
|
||||
|
||||
**%a**
|
||||
|
||||
> aggregate low mask length
|
||||
|
||||
**%A**
|
||||
|
||||
> aggregate high mask length
|
||||
|
||||
**%N**
|
||||
|
||||
> object name
|
||||
|
||||
**%m**
|
||||
|
||||
> object mask
|
||||
|
||||
**%i**
|
||||
|
||||
> inversed mask
|
||||
|
||||
**\n**
|
||||
|
||||
> new line
|
||||
|
||||
**\t**
|
||||
|
||||
> tabulation
|
||||
|
||||
Please note that no new lines inserted automatically after each sentence,
|
||||
you have to add them into format string manually, elsewhere output will
|
||||
be in one line (sometimes it makes sense):
|
||||
@@ -307,102 +351,192 @@ be in one line (sometimes it makes sense):
|
||||
$ bgpq4 -6F "%n/%l; " as-eltel
|
||||
2001:1b00::/32; 2620:4f:8000::/48; 2a04:bac0::/29; 2a05:3a80::/48;
|
||||
|
||||
DIAGNOSTICS
|
||||
-----------
|
||||
# NOTES ON SOURCES
|
||||
|
||||
When everything is OK, `bgpq4` generates result to standard output and
|
||||
exits with status == 0. In case of errors they are printed to stderr and
|
||||
program exits with non-zero status.
|
||||
By default *bgpq4* trusts data from all databases mirrored into NTT's IRR service.
|
||||
Unfortunately, not all these databases are equal in how much can we trust their
|
||||
data.
|
||||
RIR maintained databases (AFRINIC, ARIN, APNIC, LACNIC and RIPE)
|
||||
shall be trusted more than the others because they have the knowledge about
|
||||
which address space is allocated to each ASN, other databases lack this
|
||||
knowledge and can (and actually do) contain some stale data: nobody but RIRs
|
||||
care to remove outdated route-objects when address space is revoked from one
|
||||
ASN and allocated to another. In order to keep their filters both compact and
|
||||
current, *bgpq4 users* are encouraged to use one of two method to limit
|
||||
database sources to only ones they trust.
|
||||
|
||||
NOTES ON ULTRA-LARGE PREFIX-LISTS
|
||||
---------------------------------
|
||||
One option is to use the '-S' flag. This limits all queries to a specific data
|
||||
source. For example, the following command tells IIRd to only use data from
|
||||
the RIPE RIR DB to build the prefix list for the AS-SET:
|
||||
|
||||
To improve `bgpq4` performance when expanding extra-large AS-SETs you
|
||||
$./bgpq4 -S RIPE AS-VOSTRON
|
||||
no ip prefix-list NN
|
||||
ip prefix-list NN permit 89.21.224.0/19
|
||||
ip prefix-list NN permit 134.0.64.0/21
|
||||
|
||||
Be aware though, than an AS-SET may contain members from other data sources.
|
||||
In this case IRRd won't respond to the bgpq4 query will all the prefixes in the
|
||||
AS-SET tree. Make sure to use the '-S' flag with all the data sources required
|
||||
for the AS-SET being expanded:
|
||||
|
||||
$./bgpq4 -S RIPE,ARIN AS-VOSTRON
|
||||
no ip prefix-list NN
|
||||
ip prefix-list NN permit 89.21.224.0/19
|
||||
ip prefix-list NN permit 134.0.64.0/21
|
||||
ip prefix-list NN permit 208.86.232.0/24
|
||||
ip prefix-list NN permit 208.86.233.0/24
|
||||
ip prefix-list NN permit 208.86.234.0/24
|
||||
ip prefix-list NN permit 208.86.235.0/24
|
||||
|
||||
The other option is to specify a source for an AS-SET or Route Set using the
|
||||
"::" notation. When bgpq4 detects this, it will look for "::" in the specified
|
||||
AS-SET or RS on the CLI, and in all members of the AS-SET/RS, and for each
|
||||
member with a data source specified in "::" format, it will set the IRRd data
|
||||
source to the given value, query the AS-SET/RS, then reset the data sources back
|
||||
to the default list for the next object in the tree.
|
||||
|
||||
$./bgpq4 RIPE::AS-VOSTRON
|
||||
no ip prefix-list NN
|
||||
ip prefix-list NN permit 89.21.224.0/19
|
||||
ip prefix-list NN permit 134.0.64.0/21
|
||||
ip prefix-list NN permit 208.86.232.0/22
|
||||
ip prefix-list NN permit 208.86.232.0/24
|
||||
ip prefix-list NN permit 208.86.233.0/24
|
||||
ip prefix-list NN permit 208.86.234.0/24
|
||||
ip prefix-list NN permit 208.86.235.0/24
|
||||
|
||||
In comparison to the '-S' flag, this method return all the prefixes under the
|
||||
AS-SET, but the root of the tree "AS-VOSTRON" was queries from RIPE only. None
|
||||
of the member objects used the "::" notation so they were queries from the
|
||||
default source list (which is all sources).
|
||||
|
||||
|
||||
General recommendations:
|
||||
|
||||
Use minimal set of RIR databases (only those in which you and your
|
||||
customers have registered route-objects).
|
||||
|
||||
Avoid using ARIN-NONAUTH and RIPE-NONAUTH as trusted sources: these records
|
||||
were created in database but for address space allocated to different RIR,
|
||||
so the NONAUTH databases have no chance to confirm validity of this route
|
||||
object.
|
||||
|
||||
$ bgpq4 -S RIPE,RADB as-space
|
||||
no ip prefix-list NN
|
||||
ip prefix-list NN permit 195.190.32.0/19
|
||||
|
||||
$ bgpq4 -S RADB,RIPE as-space
|
||||
no ip prefix-list NN
|
||||
ip prefix-list NN permit 45.4.4.0/22
|
||||
ip prefix-list NN permit 45.4.132.0/22
|
||||
ip prefix-list NN permit 45.6.128.0/22
|
||||
ip prefix-list NN permit 45.65.184.0/22
|
||||
[...]
|
||||
|
||||
When known, use the "::" notation to speicy the authortative data source for
|
||||
an AS-SET or RS instead of the -S flag.
|
||||
|
||||
# PERFORMANCE
|
||||
|
||||
To improve \`bgpq4\` performance when expanding extra-large AS-SETs you
|
||||
shall tune OS settings to enlarge TCP send buffer.
|
||||
|
||||
FreeBSD can be tuned in the following way:
|
||||
|
||||
sysctl -w net.inet.tcp.sendbuf_max=2097152
|
||||
|
||||
sysctl -w net.inet.tcp.sendbuf_max=2097152
|
||||
|
||||
Linux can be tuned in the following way:
|
||||
|
||||
sysctl -w net.ipv4.tcp_window_scaling=1
|
||||
sysctl -w net.core.rmem_max=2097152
|
||||
sysctl -w net.core.wmem_max=2097152
|
||||
sysctl -w net.ipv4.tcp_rmem="4096 87380 2097152"
|
||||
sysctl -w net.ipv4.tcp_wmem="4096 65536 2097152"
|
||||
sysctl -w net.ipv4.tcp_window_scaling=1
|
||||
|
||||
BUILDING
|
||||
--------
|
||||
sysctl -w net.core.rmem_max=2097152
|
||||
|
||||
sysctl -w net.core.wmem_max=2097152
|
||||
|
||||
sysctl -w net.ipv4.tcp_rmem="4096 87380 2097152"
|
||||
|
||||
sysctl -w net.ipv4.tcp_wmem="4096 65536 2097152"
|
||||
|
||||
# CONTAINER IMAGE
|
||||
|
||||
A multi-arch (linux/amd64 and linux/arm64) container image is built automatically for all tagged releases and `main` branch. The image is based on Alpine Linux and is available on [GitHub Container Registry](https://github.com/bgp/bgpq4/pkgs/container/bgpq4).
|
||||
|
||||
Using the image is as simple as:
|
||||
|
||||
```
|
||||
docker run --rm ghcr.io/bgp/bgpq4:latest -Jl eltel AS20597
|
||||
policy-options {
|
||||
replace:
|
||||
prefix-list eltel {
|
||||
81.9.0.0/20;
|
||||
81.9.32.0/20;
|
||||
81.9.96.0/20;
|
||||
81.222.128.0/20;
|
||||
81.222.160.0/20;
|
||||
81.222.192.0/18;
|
||||
85.249.8.0/21;
|
||||
85.249.224.0/19;
|
||||
89.112.0.0/17;
|
||||
217.170.64.0/19;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
# BUILDING
|
||||
|
||||
This project uses autotools. If you are building from the repository,
|
||||
run the following command to prepare the build system:
|
||||
|
||||
./bootstrap
|
||||
./bootstrap
|
||||
|
||||
In order to compile the software, run:
|
||||
|
||||
./configure
|
||||
make
|
||||
make install
|
||||
./configure
|
||||
|
||||
make
|
||||
|
||||
make install
|
||||
|
||||
If you wish to remove the generated build system files from your
|
||||
working tree, run:
|
||||
|
||||
make maintainer-clean
|
||||
make maintainer-clean
|
||||
|
||||
In order to create a distribution archive, run:
|
||||
|
||||
make dist
|
||||
make dist
|
||||
|
||||
PACKAGE INSTALLATION
|
||||
--------------------
|
||||
# DIAGNOSTICS
|
||||
|
||||
In FreeBSD binary package can be installed using
|
||||
When everything is OK,
|
||||
**bgpq4**
|
||||
generates access-list to standard output and exits with status == 0.
|
||||
In case of errors they are printed to stderr and the program exits with
|
||||
non-zero status.
|
||||
|
||||
```shell
|
||||
pkg install bgpq4
|
||||
```
|
||||
# TESTS
|
||||
|
||||
Or from ports with `portmaster`
|
||||
The [tests/](tests/) folder contains reference output data in [text files](tests/reference/). The [generate_outputs.sh](tests/generate_outputs.sh) script is used in the [Github workflow](.github/workflows/unit-tests.yml) to generate the same output data, using the latest commit, and compare the output data to the stored "known-good" reference data, and check there are no changes.
|
||||
|
||||
```shell
|
||||
portmaster net-mgmt/bgpq4
|
||||
```
|
||||
To update the reference data (i.e. if the bgpq4 output is modified), simply run the script again (`./tests/generate_outputs.sh ./bgpq4 tests/reference`) and commit the changes.
|
||||
|
||||
On Arch Linux, BGPQ4 is [available in AUR](https://aur.archlinux.org/packages/bgpq4/):
|
||||
|
||||
```shell
|
||||
yay -S bgpq4
|
||||
```
|
||||
|
||||
On OpenBSD:
|
||||
|
||||
```shell
|
||||
pkg_add bgpq4
|
||||
```
|
||||
|
||||
MAILING LIST
|
||||
------------
|
||||
|
||||
Users and interested parties can subscribe to the BGPQ4 mailing list [bgpq4@tcp0.com](https://tcp0.com/cgi-bin/mailman/listinfo/bgpq4).
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
|
||||
NLNOG's [BGP Filter Guide](http://bgpfilterguide.nlnog.net/)
|
||||
|
||||
AUTHORS
|
||||
-------
|
||||
# AUTHORS
|
||||
|
||||
Alexandre Snarskii, Christian David, Claudio Jeker, Job Snijders,
|
||||
Massimiliano Stucchi, Michail Litvak, Peter Schoenmaker, Roelf Wichertjes,
|
||||
and contributions from many others.
|
||||
|
||||
Project
|
||||
-------
|
||||
# SEE ALSO
|
||||
|
||||
BGPQ4 is maintained by Job Snijders `<job@sobornost.net>`.
|
||||
**https://github.com/bgp/bgpq4**
|
||||
BGPQ4 on Github.
|
||||
|
||||
[https://github.com/bgp/bgpq4](https://github.com/bgp/bgpq4)
|
||||
**http://bgpfilterguide.nlnog.net/**
|
||||
NLNOG's BGP Filter Guide.
|
||||
|
||||
**https://tcp0.com/cgi-bin/mailman/listinfo/bgpq4**
|
||||
Users and interested parties can subscribe to the BGPQ4 mailing list bgpq4@tcp0.com
|
||||
|
||||
# PROJECT MAINTAINER
|
||||
|
||||
Job Snijders <job@sobornost.net>
|
||||
|
||||
148
bgpq4.8
148
bgpq4.8
@@ -37,9 +37,10 @@
|
||||
.Fl f Ar asn |
|
||||
.Fl F Ar fmt |
|
||||
.Fl G Ar asn
|
||||
.Fl H Ar asn
|
||||
.Fl t
|
||||
.Oc
|
||||
.Op Fl 46ABbDdJjNnsXU
|
||||
.Op Fl 46ABbDdJjNnpsXU
|
||||
.Op Fl a Ar asn
|
||||
.Op Fl r Ar len
|
||||
.Op Fl R Ar len
|
||||
@@ -52,7 +53,7 @@
|
||||
The
|
||||
.Nm
|
||||
utility used to generate configurations (prefix-lists, extended
|
||||
access-lists, policy-statement terms and as-path lists) based on RADB data.
|
||||
access-lists, policy-statement terms and as-path lists) based on IRR data.
|
||||
.Pp
|
||||
The options are as follows:
|
||||
.Bl -tag -width Ds
|
||||
@@ -83,6 +84,10 @@ generate input as-path access-list.
|
||||
generate output in user-defined format.
|
||||
.It Fl G Ar number
|
||||
generate output as-path access-list.
|
||||
.It Fl H Ar number
|
||||
generate output as-list for
|
||||
.Em as-path-origin
|
||||
filter (JunOS 21.3R1+)
|
||||
.It Fl h Ar host[:port]
|
||||
host running IRRD database (default: rr.ntt.net).
|
||||
.It Fl J
|
||||
@@ -90,7 +95,9 @@ generate config for Juniper (default: Cisco).
|
||||
.It Fl j
|
||||
generate output in JSON format (default: Cisco).
|
||||
.It Fl K
|
||||
generate config for Mikrotik (default: Cisco).
|
||||
generate config for Mikrotik ROSv6 (default: Cisco).
|
||||
.It Fl K7
|
||||
generate config for Mikrotik ROSv7 (default: Cisco).
|
||||
.It Fl l Ar name
|
||||
name of generated entry.
|
||||
.It Fl L Ar limit
|
||||
@@ -102,12 +109,13 @@ maximum prefix-length of accepted prefixes (default: 32 for IPv4 and
|
||||
extra match conditions for Juniper route-filters.
|
||||
.It Fl n
|
||||
generate config for Nokia SR OS MD-CLI (Cisco IOS by default)
|
||||
.It Fl n2
|
||||
generate config for Nokia SR Linux (Cisco IOS by default)
|
||||
.It Fl N
|
||||
generate config for Nokia SR OS classic CLI (Cisco IOS by default).
|
||||
.It Fl p
|
||||
accept routes registered for private ASNs (default: disabled)
|
||||
.It Fl P
|
||||
generate prefix-list (default, backward compatibility).
|
||||
emit prefixes where the origin ASN is 23456 or in the private ASN range
|
||||
(disabled by default).
|
||||
.It Fl r Ar len
|
||||
allow more specific routes starting with specified masklen too.
|
||||
.It Fl R Ar len
|
||||
@@ -115,15 +123,17 @@ allow more specific routes up to specified masklen too.
|
||||
.It Fl s
|
||||
generate sequence numbers in IOS-style prefix-lists.
|
||||
.It Fl S Ar sources
|
||||
use specified sources only (recommended: RADB,RIPE,APNIC).
|
||||
use specified sources only (recommended: RPKI,AFRINIC,APNIC,ARIN,LACNIC,RIPE).
|
||||
.It Fl t
|
||||
generate as-sets for OpenBGPd, BIRD and JSON formats.
|
||||
.It Fl T
|
||||
disable pipelining (not recommended).
|
||||
.It Fl W Ar len
|
||||
generate as-path strings of no more than len items (use 0 for inifinity).
|
||||
.It Fl U
|
||||
generate config for Huawei devices (Cisco IOS by default)
|
||||
.It Fl u
|
||||
generate config for Huawei devices in XPL format (Cisco IOS by default)
|
||||
.It Fl W Ar len
|
||||
generate as-path strings of no more than len items (use 0 for infinity).
|
||||
.It Fl X
|
||||
generate config for Cisco IOS XR devices (plain IOS by default).
|
||||
.It Fl z
|
||||
@@ -178,7 +188,8 @@ ip prefix-list eltel permit 89.112.64.0/19
|
||||
ip prefix-list eltel permit 217.170.64.0/19 ge 20 le 20
|
||||
.Ed
|
||||
.fi
|
||||
- you see, prefixes 89.112.0.0/19 and 89.112.32.0/19 now aggregated
|
||||
.Pp
|
||||
Prefixes 89.112.0.0/19 and 89.112.32.0/19 now aggregated
|
||||
into single entry 89.112.0.0/18 ge 19 le 19.
|
||||
.Pp
|
||||
Well, for Juniper we can generate even more interesting policy-options,
|
||||
@@ -251,27 +262,130 @@ ipfw add pass all from 193.193.192.0/19 to any
|
||||
.Ed
|
||||
.fi
|
||||
.Pp
|
||||
Recognized format characters: %n - network, %l - mask length,
|
||||
%a - aggregate low mask length, %A - aggregate high mask length,
|
||||
%N - object name, %m - object mask and %i - inversed mask.
|
||||
Recognized escape characters: \\n - new line, \\t - tabulation.
|
||||
Please note that no new lines inserted automatically after each sentence,
|
||||
you have to add them into format string manually, elsewhere output will
|
||||
be in one line (sometimes it makes sense):
|
||||
Recognized format sequences are:
|
||||
.Pp
|
||||
.Bl -tag -width Ds -offset indent -compact
|
||||
.It Cm %n
|
||||
network
|
||||
.It Cm %l
|
||||
mask length
|
||||
.It Cm %a
|
||||
aggregate low mask length
|
||||
.It Cm \&%A
|
||||
aggregate high mask length
|
||||
.It Cm \&%N
|
||||
object name
|
||||
.It Cm %m
|
||||
object mask
|
||||
.It Cm %i
|
||||
inversed mask
|
||||
.It Cm \en
|
||||
new line
|
||||
.It Cm \et
|
||||
tabulation
|
||||
.El
|
||||
.Pp
|
||||
Please note that no new lines are inserted automatically after each sentence.
|
||||
You have to add them into format string manually, otherwise the output will
|
||||
be in one single line (sometimes it makes sense):
|
||||
.nf
|
||||
.Bd -literal
|
||||
$ bgpq4 -6F "%n/%l; " as-eltel
|
||||
2001:1b00::/32; 2620:4f:8000::/48; 2a04:bac0::/29; 2a05:3a80::/48;
|
||||
.Ed
|
||||
.fi
|
||||
.Sh NOTES ON SOURCES
|
||||
By default
|
||||
.Em bgpq4
|
||||
trusts data from all the databases mirrored into NTT's IRR service.
|
||||
Unfortunately, not all these databases are equal in how much we can
|
||||
trust their data.
|
||||
RIR maintained databases (AFRINIC, ARIN, APNIC, LACNIC and RIPE)
|
||||
shall be trusted more than the others because they have the
|
||||
knowledge about who the rightful holders of resources are, while
|
||||
other databases lack this knowledge and can (and, actually do) contain
|
||||
stale data: no one but the RIRs care to remove outdated route-objects
|
||||
when address space is de-allocated or transferred.
|
||||
In order to keep their filters both compact and actual,
|
||||
.Em bgpq4 users
|
||||
are encouraged to use '-S' flag to limit database sources to only
|
||||
the ones they trust.
|
||||
.Pp
|
||||
General recommendations:
|
||||
.Pp
|
||||
Use a minimal set of RIR databases (only those in which you and your
|
||||
customers have registered route-objects).
|
||||
.Pp
|
||||
Avoid using ARIN-NONAUTH and RIPE-NONAUTH as trusted sources: these records
|
||||
were created in the database, but for address space allocated to different RIRs,
|
||||
so the NONAUTH databases have no chance to confirm validity of the route
|
||||
objects they contain.
|
||||
.Bd -literal
|
||||
$ bgpq4 -S RIPE,RADB as-space
|
||||
no ip prefix-list NN
|
||||
ip prefix-list NN permit 195.190.32.0/19
|
||||
|
||||
$ bgpq4 -S RADB,RIPE as-space
|
||||
no ip prefix-list NN
|
||||
ip prefix-list NN permit 45.4.4.0/22
|
||||
ip prefix-list NN permit 45.4.132.0/22
|
||||
ip prefix-list NN permit 45.6.128.0/22
|
||||
ip prefix-list NN permit 45.65.184.0/22
|
||||
[...]
|
||||
.Ed
|
||||
.Sh PERFORMANCE
|
||||
To improve `bgpq4` performance when expanding extra-large AS-SETs you
|
||||
shall tune OS settings to enlarge TCP send buffer.
|
||||
.Pp
|
||||
FreeBSD can be tuned in the following way:
|
||||
.Pp
|
||||
.Dl sysctl -w net.inet.tcp.sendbuf_max=2097152
|
||||
.Pp
|
||||
Linux can be tuned in the following way:
|
||||
.Pp
|
||||
.Dl sysctl -w net.ipv4.tcp_window_scaling=1
|
||||
.Dl sysctl -w net.core.rmem_max=2097152
|
||||
.Dl sysctl -w net.core.wmem_max=2097152
|
||||
.Dl sysctl -w net.ipv4.tcp_rmem="4096 87380 2097152"
|
||||
.Dl sysctl -w net.ipv4.tcp_wmem="4096 65536 2097152"
|
||||
.Sh BUILDING
|
||||
This project uses autotools. If you are building from the repository,
|
||||
run the following command to prepare the build system:
|
||||
.Pp
|
||||
.Dl ./bootstrap
|
||||
.Pp
|
||||
In order to compile the software, run:
|
||||
.Pp
|
||||
.Dl ./configure
|
||||
.Dl make
|
||||
.Dl make install
|
||||
.Pp
|
||||
If you wish to remove the generated build system files from your
|
||||
working tree, run:
|
||||
.Pp
|
||||
.Dl make maintainer-clean
|
||||
.Pp
|
||||
In order to create a distribution archive, run:
|
||||
.Pp
|
||||
.Dl make dist
|
||||
.Sh DIAGNOSTICS
|
||||
When everything is OK,
|
||||
.Nm
|
||||
generates access-list to standard output and exits with status == 0.
|
||||
In case of errors they are printed to stderr and program exits with
|
||||
non-zero status.
|
||||
.Sh AUTHORS
|
||||
Alexandre Snarskii, Christian David, Claudio Jeker, Job Snijders,
|
||||
Massimiliano Stucchi, Michail Litvak, Peter Schoenmaker, Roelf Wichertjes,
|
||||
and contributions from many others.
|
||||
.Sh SEE ALSO
|
||||
.Sy https://github.com/bgp/bgpq4
|
||||
BGPQ4 on Github.
|
||||
.Pp
|
||||
.Sy http://bgpfilterguide.nlnog.net/
|
||||
NLNOG's BGP Filter Guide.
|
||||
.Pp
|
||||
.Sy https://tcp0.com/cgi-bin/mailman/listinfo/bgpq4
|
||||
Users and interested parties can subscribe to the BGPQ4 mailing list bgpq4@tcp0.com
|
||||
.Sh PROJECT MAINTAINER
|
||||
.An Job Snijders Aq job@sobornost.net
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
bsd_environment() {
|
||||
# Based on https://github.com/rvm/rvm/blob/59fe3b39f0fb5ae01ed5b9aa187201080815ac16/scripts/functions/build_config_system#L123
|
||||
if [[ -z "${AUTOCONF_VERSION:-}" ]]
|
||||
if [ -z "${AUTOCONF_VERSION}" ]
|
||||
then
|
||||
export AUTOCONF_VERSION
|
||||
AUTOCONF_VERSION="$(
|
||||
@@ -17,7 +17,7 @@ bsd_environment() {
|
||||
echo "Using autoconf version: $AUTOCONF_VERSION"
|
||||
fi
|
||||
|
||||
if [[ -z "${AUTOMAKE_VERSION:-}" ]]
|
||||
if [ -z "${AUTOMAKE_VERSION}" ]
|
||||
then
|
||||
export AUTOMAKE_VERSION
|
||||
# FreeBSD might have automake-wrapper
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
AC_INIT([bgpq4], m4_esyscmd([tr -d '\n' < VERSION]), job@sobornost.net)
|
||||
AC_INIT([bgpq4], m4_esyscmd([tr -d '\n' < VERSION]), [job@sobornost.net])
|
||||
|
||||
AC_CANONICAL_HOST
|
||||
AM_INIT_AUTOMAKE([subdir-objects foreign])
|
||||
@@ -56,9 +56,8 @@ AM_CONDITIONAL([HOST_NETBSD], [test x$HOST_OS = xnetbsd])
|
||||
AM_CONDITIONAL([HOST_SOLARIS], [test x$HOST_OS = xsolaris])
|
||||
|
||||
AC_PROG_CC
|
||||
AC_PROG_CC_STDC
|
||||
AM_PROG_CC_C_O
|
||||
AC_PROG_LIBTOOL
|
||||
LT_INIT
|
||||
AC_PROG_INSTALL
|
||||
|
||||
AC_ARG_ENABLE(warnings,
|
||||
|
||||
681
expander.c
681
expander.c
File diff suppressed because it is too large
Load Diff
120
extern.h
120
extern.h
@@ -29,19 +29,24 @@
|
||||
|
||||
#include "sx_prefix.h"
|
||||
|
||||
struct sx_slentry {
|
||||
STAILQ_ENTRY(sx_slentry) entries;
|
||||
char* text;
|
||||
struct slentry {
|
||||
STAILQ_ENTRY(slentry) entry;
|
||||
char *text;
|
||||
};
|
||||
|
||||
struct sx_slentry* sx_slentry_new(char* text);
|
||||
struct slentry *sx_slentry_new(char *text);
|
||||
|
||||
struct sx_tentry {
|
||||
RB_ENTRY(sx_tentry) entries;
|
||||
char* text;
|
||||
RB_ENTRY(sx_tentry) entry;
|
||||
char *text;
|
||||
};
|
||||
|
||||
struct sx_tentry* sx_tentry_new(char* text);
|
||||
struct sx_tentry *sx_tentry_new(char *text);
|
||||
|
||||
struct asn_entry {
|
||||
RB_ENTRY(asn_entry) entry;
|
||||
uint32_t asn;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
V_CISCO = 0,
|
||||
@@ -53,15 +58,19 @@ typedef enum {
|
||||
V_FORMAT,
|
||||
V_NOKIA,
|
||||
V_HUAWEI,
|
||||
V_MIKROTIK,
|
||||
V_HUAWEI_XPL,
|
||||
V_MIKROTIK6,
|
||||
V_MIKROTIK7,
|
||||
V_NOKIA_MD,
|
||||
V_ARISTA
|
||||
V_ARISTA,
|
||||
V_NOKIA_SRL,
|
||||
} bgpq_vendor_t;
|
||||
|
||||
typedef enum {
|
||||
T_NONE = 0,
|
||||
T_ASPATH,
|
||||
T_OASPATH,
|
||||
T_ASLIST,
|
||||
T_ASSET,
|
||||
T_PREFIXLIST,
|
||||
T_EACL,
|
||||
@@ -70,44 +79,49 @@ typedef enum {
|
||||
|
||||
struct bgpq_expander;
|
||||
|
||||
struct bgpq_request {
|
||||
STAILQ_ENTRY(bgpq_request) next;
|
||||
char *request;
|
||||
int size, offset;
|
||||
void *udata;
|
||||
unsigned int depth;
|
||||
int (*callback)(char *, struct bgpq_expander *,
|
||||
struct bgpq_request *);
|
||||
struct request {
|
||||
STAILQ_ENTRY(request) next;
|
||||
char *request;
|
||||
int size, offset;
|
||||
void *udata;
|
||||
unsigned int depth;
|
||||
int (*callback)(char *, struct bgpq_expander *,
|
||||
struct request *);
|
||||
};
|
||||
|
||||
struct bgpq_expander {
|
||||
struct sx_radix_tree *tree;
|
||||
STAILQ_HEAD(sx_slentries, sx_slentry) macroses, rsets;
|
||||
RB_HEAD(tentree, sx_tentry) already, stoplist;
|
||||
int family;
|
||||
char *sources;
|
||||
uint32_t asnumber;
|
||||
int aswidth;
|
||||
char *name;
|
||||
bgpq_vendor_t vendor;
|
||||
bgpq_gen_t generation;
|
||||
int identify;
|
||||
int sequence;
|
||||
unsigned int maxdepth;
|
||||
unsigned int cdepth;
|
||||
int validate_asns;
|
||||
unsigned char *asn32s[65536];
|
||||
struct bgpq_prequest *firstpipe, *lastpipe;
|
||||
int piped;
|
||||
char *match;
|
||||
char *server;
|
||||
char *port;
|
||||
char *format;
|
||||
unsigned int maxlen;
|
||||
STAILQ_HEAD(bgpq_requests, bgpq_request) wq, rq;
|
||||
int fd;
|
||||
struct sx_radix_tree *tree;
|
||||
int family;
|
||||
char *sources;
|
||||
char *defaultsources;
|
||||
unsigned int usesource;
|
||||
uint32_t asnumber;
|
||||
int aswidth;
|
||||
char *name;
|
||||
bgpq_vendor_t vendor;
|
||||
bgpq_gen_t generation;
|
||||
int identify;
|
||||
int sequence;
|
||||
unsigned int maxdepth;
|
||||
unsigned int cdepth;
|
||||
int validate_asns;
|
||||
struct bgpq_prequest *firstpipe, *lastpipe;
|
||||
int piped;
|
||||
char *match;
|
||||
char *server;
|
||||
char *port;
|
||||
char *format;
|
||||
unsigned int maxlen;
|
||||
int fd;
|
||||
RB_HEAD(asn_tree, asn_entry) asnlist;
|
||||
STAILQ_HEAD(requests, request) wq, rq;
|
||||
STAILQ_HEAD(slentries, slentry) macroses, rsets;
|
||||
RB_HEAD(tentree, sx_tentry) already, stoplist;
|
||||
};
|
||||
|
||||
int asn_cmp(struct asn_entry *, struct asn_entry *);
|
||||
RB_PROTOTYPE(asn_tree, asn_entry, entry, asn_cmp);
|
||||
|
||||
int bgpq_expander_init(struct bgpq_expander *b, int af);
|
||||
int bgpq_expander_add_asset(struct bgpq_expander *b, char *set);
|
||||
int bgpq_expander_add_rset(struct bgpq_expander *b, char *set);
|
||||
@@ -116,23 +130,25 @@ int bgpq_expander_add_prefix(struct bgpq_expander *b, char *prefix);
|
||||
int bgpq_expander_add_prefix_range(struct bgpq_expander *b, char *prefix);
|
||||
int bgpq_expander_add_stop(struct bgpq_expander *b, char *object);
|
||||
|
||||
char* bgpq_get_asset(char *object);
|
||||
char* bgpq_get_rset(char *object);
|
||||
char* bgpq_get_source(char *object);
|
||||
|
||||
int bgpq_expand(struct bgpq_expander *b);
|
||||
|
||||
int bgpq4_print_prefixlist(FILE *f, struct bgpq_expander *b);
|
||||
int bgpq4_print_eacl(FILE *f, struct bgpq_expander *b);
|
||||
int bgpq4_print_aspath(FILE *f, struct bgpq_expander *b);
|
||||
int bgpq4_print_asset(FILE *f, struct bgpq_expander *b);
|
||||
int bgpq4_print_oaspath(FILE *f, struct bgpq_expander *b);
|
||||
int bgpq4_print_route_filter_list(FILE *f, struct bgpq_expander *b);
|
||||
void bgpq4_print_prefixlist(FILE *f, struct bgpq_expander *b);
|
||||
void bgpq4_print_eacl(FILE *f, struct bgpq_expander *b);
|
||||
void bgpq4_print_aspath(FILE *f, struct bgpq_expander *b);
|
||||
void bgpq4_print_asset(FILE *f, struct bgpq_expander *b);
|
||||
void bgpq4_print_oaspath(FILE *f, struct bgpq_expander *b);
|
||||
void bgpq4_print_aslist(FILE *f, struct bgpq_expander *b);
|
||||
void bgpq4_print_route_filter_list(FILE *f, struct bgpq_expander *b);
|
||||
|
||||
void sx_radix_node_freeall(struct sx_radix_node *n);
|
||||
void sx_radix_tree_freeall(struct sx_radix_tree *t);
|
||||
void bgpq_prequest_freeall(struct bgpq_prequest *bpr);
|
||||
void expander_freeall(struct bgpq_expander *expander);
|
||||
|
||||
/* s - number of opened socket, dir is either SO_SNDBUF or SO_RCVBUF */
|
||||
int sx_maxsockbuf(int s, int dir);
|
||||
|
||||
#ifndef HAVE_STRLCPY
|
||||
size_t strlcpy(char* dst, const char* src, size_t size);
|
||||
size_t strlcpy(char *dst, const char *src, size_t size);
|
||||
#endif
|
||||
|
||||
515
main.c
515
main.c
@@ -31,8 +31,6 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
@@ -52,19 +50,22 @@ extern int expand_special_asn;
|
||||
static int
|
||||
usage(int ecode)
|
||||
{
|
||||
printf("\nUsage: bgpq4 [-h host[:port]] [-S sources] [-E|G <num>"
|
||||
"|f <num>|t] [-46ABbdJjKNnwXz] [-R len] <OBJECTS> ... "
|
||||
printf("\nUsage: bgpq4 [-h host[:port]] [-S sources] [-E|G|H <num>"
|
||||
"|f <num>|t] [-46ABbdJjKNnpwXz] [-R len] <OBJECTS> ... "
|
||||
"[EXCEPT <OBJECTS> ...]\n");
|
||||
printf("\nVendor targets:\n");
|
||||
printf(" no option : Cisco IOS Classic (default)\n");
|
||||
printf(" -X : Cisco IOS XR\n");
|
||||
printf(" -U : Huawei\n");
|
||||
printf(" -u : Huawei XPL\n");
|
||||
printf(" -j : JSON\n");
|
||||
printf(" -J : Juniper Junos\n");
|
||||
printf(" -K : MikroTik RouterOS\n");
|
||||
printf(" -K : MikroTik RouterOSv6\n");
|
||||
printf(" -K7 : MikroTik RouterOSv7\n");
|
||||
printf(" -b : NIC.CZ BIRD\n");
|
||||
printf(" -N : Nokia SR OS (Classic CLI)\n");
|
||||
printf(" -n : Nokia SR OS (MD-CLI)\n");
|
||||
printf(" -n2 : Nokia SR Linux\n");
|
||||
printf(" -B : OpenBSD OpenBGPD\n");
|
||||
printf(" -e : Arista EOS\n");
|
||||
printf(" -F fmt : User defined format (example: '-F %%n/%%l')\n");
|
||||
@@ -81,6 +82,7 @@ usage(int ecode)
|
||||
"registered routes\n");
|
||||
|
||||
printf("\nOutput modifiers:\n");
|
||||
printf(" -3 : assume that your device is asn32-safe (default)\n");
|
||||
printf(" -A : try to aggregate prefix-lists/route-filters\n");
|
||||
printf(" -E : generate extended access-list (Cisco), "
|
||||
"route-filter (Juniper)\n"
|
||||
@@ -88,16 +90,18 @@ usage(int ecode)
|
||||
"(OpenBGPD)\n");
|
||||
printf(" -f number : generate input as-path access-list\n");
|
||||
printf(" -G number : generate output as-path access-list\n");
|
||||
printf(" -H number : generate origin as-lists (JunOS only)\n");
|
||||
printf(" -M match : extra match conditions for JunOS route-filters\n");
|
||||
printf(" -l name : use specified name for generated access/prefix/.."
|
||||
" list\n");
|
||||
printf(" -p : allow special ASNs like 23456 or in the private range\n");
|
||||
printf(" -R len : allow more specific routes up to specified masklen\n");
|
||||
printf(" -r len : allow more specific routes from masklen specified\n");
|
||||
printf(" -s : generate sequence numbers in prefix-lists (IOS only)\n");
|
||||
printf(" -t : generate as-sets for OpenBGPD (OpenBGPD 6.4+), BIRD "
|
||||
"and JSON formats\n");
|
||||
printf(" -z : generate route-filter-list (Junos only)\n");
|
||||
printf(" -W len : specify max-entries on as-path line (use 0 for "
|
||||
printf(" -W len : specify max-entries on as-path/as-list line (use 0 for "
|
||||
"infinity)\n");
|
||||
|
||||
printf("\nUtility operations:\n");
|
||||
@@ -124,8 +128,8 @@ version(void)
|
||||
static void
|
||||
exclusive(void)
|
||||
{
|
||||
fprintf(stderr,"-E, -f <asnum>, -G <asnum>, and -t are mutually "
|
||||
"exclusive\n");
|
||||
fprintf(stderr,"-E, -F, -K , -f <asnum>, -G <asnum>, and -t are mutually"
|
||||
" exclusive\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -133,9 +137,9 @@ static void
|
||||
vendor_exclusive(void)
|
||||
{
|
||||
fprintf(stderr, "-b (BIRD), -B (OpenBGPD), -F (formatted), -J (Junos),"
|
||||
" -j (JSON), -N (Nokia SR OS Classic), -n (Nokia SR OS MD-CLI),"
|
||||
" -U (Huawei), -e (Arista) and -X (IOS XR) options are mutually"
|
||||
" exclusive\n");
|
||||
" -j (JSON), -K[7] (Microtik ROS), -N (Nokia SR OS Classic),"
|
||||
" -n (Nokia SR OS MD-CLI), -U (Huawei), -u (Huawei XPL),"
|
||||
"-e (Arista) and -X (IOS XR) options are mutually exclusive\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -190,161 +194,175 @@ main(int argc, char* argv[])
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
bgpq_expander_init(&expander, af);
|
||||
|
||||
if (getenv("IRRD_SOURCES"))
|
||||
expander.sources=getenv("IRRD_SOURCES");
|
||||
|
||||
while ((c = getopt(argc, argv,
|
||||
"346a:AbBdDEeF:S:jJKf:l:L:m:M:NnW:pr:R:G:tTh:UwXsvz"))
|
||||
!=EOF) {
|
||||
"23467a:AbBdDEeF:S:jJKf:l:L:m:M:NnpW:r:R:G:H:tTh:UuwXsvz")) != EOF) {
|
||||
switch (c) {
|
||||
case '3':
|
||||
/*
|
||||
* No-op, left for backwards compatibility with bgpq3
|
||||
*/
|
||||
break;
|
||||
case '4':
|
||||
/* do nothing, expander already configured for IPv4 */
|
||||
if (expander.family == AF_INET6) {
|
||||
sx_report(SX_FATAL, "-4 and -6 are mutually "
|
||||
"exclusive\n");
|
||||
exit(1);
|
||||
case '2':
|
||||
if (expander.vendor != V_NOKIA_MD) {
|
||||
sx_report(SX_FATAL, "'2' can only be used after -n\n");
|
||||
exit(1);
|
||||
}
|
||||
expander.vendor = V_NOKIA_SRL;
|
||||
break;
|
||||
case '3':
|
||||
/* do nothing, 32-bit ASN support is assumed */
|
||||
break;
|
||||
case '4':
|
||||
/* do nothing, expander already configured for IPv4 */
|
||||
if (expander.family == AF_INET6) {
|
||||
sx_report(SX_FATAL, "-4 and -6 are mutually "
|
||||
"exclusive\n");
|
||||
exit(1);
|
||||
}
|
||||
selectedipv4 = 1;
|
||||
break;
|
||||
case '6':
|
||||
if (selectedipv4) {
|
||||
sx_report(SX_FATAL, "-4 and -6 are mutually "
|
||||
"exclusive\n");
|
||||
exit(1);
|
||||
}
|
||||
af = AF_INET6;
|
||||
expander.family = AF_INET6;
|
||||
expander.tree->family = AF_INET6;
|
||||
break;
|
||||
case '7':
|
||||
if (expander.vendor != V_MIKROTIK6) {
|
||||
sx_report(SX_FATAL, "'7' can only be used after -K\n");
|
||||
exit(1);
|
||||
}
|
||||
expander.vendor = V_MIKROTIK7;
|
||||
break;
|
||||
case 'a':
|
||||
parseasnumber(&expander, optarg);
|
||||
break;
|
||||
case 'A':
|
||||
if (aggregate)
|
||||
debug_aggregation++;
|
||||
aggregate = 1;
|
||||
break;
|
||||
case 'b':
|
||||
if (expander.vendor)
|
||||
vendor_exclusive();
|
||||
expander.vendor = V_BIRD;
|
||||
break;
|
||||
case 'B':
|
||||
if (expander.vendor)
|
||||
vendor_exclusive();
|
||||
expander.vendor = V_OPENBGPD;
|
||||
break;
|
||||
case 'd':
|
||||
debug_expander++;
|
||||
break;
|
||||
case 'E':
|
||||
if (expander.generation)
|
||||
exclusive();
|
||||
expander.generation = T_EACL;
|
||||
break;
|
||||
case 'e':
|
||||
if (expander.vendor)
|
||||
vendor_exclusive();
|
||||
expander.vendor = V_ARISTA;
|
||||
expander.sequence = 1;
|
||||
break;
|
||||
case 'F':
|
||||
if (expander.vendor)
|
||||
exclusive();
|
||||
expander.vendor = V_FORMAT;
|
||||
expander.format = optarg;
|
||||
break;
|
||||
case 'f':
|
||||
if (expander.generation)
|
||||
exclusive();
|
||||
expander.generation = T_ASPATH;
|
||||
parseasnumber(&expander, optarg);
|
||||
break;
|
||||
case 'G':
|
||||
if (expander.generation)
|
||||
exclusive();
|
||||
expander.generation = T_OASPATH;
|
||||
parseasnumber(&expander, optarg);
|
||||
break;
|
||||
case 'H':
|
||||
if (expander.generation)
|
||||
exclusive();
|
||||
expander.generation = T_ASLIST;
|
||||
parseasnumber(&expander, optarg);
|
||||
break;
|
||||
case 'h':
|
||||
{
|
||||
char *d = strchr(optarg, ':');
|
||||
expander.server = optarg;
|
||||
if (d) {
|
||||
*d = 0;
|
||||
expander.port = d + 1;
|
||||
}
|
||||
selectedipv4=1;
|
||||
break;
|
||||
case '6':
|
||||
if (selectedipv4) {
|
||||
sx_report(SX_FATAL, "-4 and -6 are mutually "
|
||||
"exclusive\n");
|
||||
exit(1);
|
||||
}
|
||||
af = AF_INET6;
|
||||
expander.family = AF_INET6;
|
||||
expander.tree->family = AF_INET6;
|
||||
break;
|
||||
case 'a':
|
||||
parseasnumber(&expander, optarg);
|
||||
break;
|
||||
case 'A':
|
||||
if (aggregate)
|
||||
debug_aggregation++;
|
||||
aggregate = 1;
|
||||
break;
|
||||
case 'b':
|
||||
if (expander.vendor)
|
||||
vendor_exclusive();
|
||||
expander.vendor = V_BIRD;
|
||||
break;
|
||||
case 'B':
|
||||
if (expander.vendor)
|
||||
vendor_exclusive();
|
||||
expander.vendor = V_OPENBGPD;
|
||||
break;
|
||||
case 'd':
|
||||
debug_expander++;
|
||||
break;
|
||||
case 'E':
|
||||
if (expander.generation)
|
||||
exclusive();
|
||||
expander.generation = T_EACL;
|
||||
break;
|
||||
case 'e':
|
||||
if (expander.vendor)
|
||||
vendor_exclusive();
|
||||
expander.vendor = V_ARISTA;
|
||||
expander.sequence = 1;
|
||||
break;
|
||||
case 'F':
|
||||
if (expander.vendor)
|
||||
exclusive();
|
||||
expander.vendor = V_FORMAT;
|
||||
expander.format = optarg;
|
||||
break;
|
||||
case 'f':
|
||||
if (expander.generation)
|
||||
exclusive();
|
||||
expander.generation = T_ASPATH;
|
||||
parseasnumber(&expander, optarg);
|
||||
break;
|
||||
case 'G':
|
||||
if (expander.generation)
|
||||
exclusive();
|
||||
expander.generation = T_OASPATH;
|
||||
parseasnumber(&expander, optarg);
|
||||
break;
|
||||
case 'h':
|
||||
{
|
||||
char* d = strchr(optarg, ':');
|
||||
expander.server = optarg;
|
||||
if (d) {
|
||||
*d = 0;
|
||||
expander.port = d + 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'J':
|
||||
if (expander.vendor)
|
||||
vendor_exclusive();
|
||||
expander.vendor = V_JUNIPER;
|
||||
break;
|
||||
case 'j':
|
||||
if (expander.vendor)
|
||||
vendor_exclusive();
|
||||
expander.vendor = V_JSON;
|
||||
break;
|
||||
case 'K':
|
||||
if (expander.vendor)
|
||||
vendor_exclusive();
|
||||
expander.vendor = V_MIKROTIK;
|
||||
break;
|
||||
case 'p':
|
||||
expand_special_asn = 1;
|
||||
break;
|
||||
case 'r':
|
||||
refineLow = strtoul(optarg, NULL, 10);
|
||||
if (!refineLow) {
|
||||
sx_report(SX_FATAL, "Invalid refineLow value:"
|
||||
" %s\n", optarg);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'R':
|
||||
refine = strtoul(optarg, NULL, 10);
|
||||
if (!refine) {
|
||||
sx_report(SX_FATAL,"Invalid refine length:"
|
||||
" %s\n", optarg);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'l':
|
||||
expander.name = optarg;
|
||||
break;
|
||||
case 'L':
|
||||
expander.maxdepth = strtol(optarg, NULL, 10);
|
||||
if (expander.maxdepth < 1) {
|
||||
sx_report(SX_FATAL, "Invalid maximum recursion"
|
||||
" (-L): %s\n", optarg);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'm':
|
||||
maxlen=strtoul(optarg, NULL, 10);
|
||||
if (!maxlen) {
|
||||
sx_report(SX_FATAL, "Invalid maxlen (-m): %s\n",
|
||||
optarg);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'M':
|
||||
{
|
||||
char *mc, *md;
|
||||
}
|
||||
break;
|
||||
case 'J':
|
||||
if (expander.vendor)
|
||||
vendor_exclusive();
|
||||
expander.vendor = V_JUNIPER;
|
||||
break;
|
||||
case 'j':
|
||||
if (expander.vendor)
|
||||
vendor_exclusive();
|
||||
expander.vendor = V_JSON;
|
||||
break;
|
||||
case 'K':
|
||||
if (expander.vendor)
|
||||
vendor_exclusive();
|
||||
expander.vendor = V_MIKROTIK6;
|
||||
break;
|
||||
case 'r':
|
||||
refineLow = strtoul(optarg, NULL, 10);
|
||||
if (!refineLow) {
|
||||
sx_report(SX_FATAL, "Invalid refineLow value:"
|
||||
" %s\n", optarg);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'R':
|
||||
refine = strtoul(optarg, NULL, 10);
|
||||
if (!refine) {
|
||||
sx_report(SX_FATAL,"Invalid refine length:"
|
||||
" %s\n", optarg);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'l':
|
||||
expander.name = optarg;
|
||||
break;
|
||||
case 'L':
|
||||
expander.maxdepth = strtol(optarg, NULL, 10);
|
||||
if (expander.maxdepth < 1) {
|
||||
sx_report(SX_FATAL, "Invalid maximum recursion"
|
||||
" (-L): %s\n", optarg);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'm':
|
||||
maxlen=strtoul(optarg, NULL, 10);
|
||||
if (!maxlen) {
|
||||
sx_report(SX_FATAL, "Invalid maxlen (-m): %s\n",
|
||||
optarg);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'M':
|
||||
{
|
||||
char *mc, *md;
|
||||
expander.match = strdup(optarg);
|
||||
mc = md = expander.match;
|
||||
while (*mc) {
|
||||
if (*mc == '\\') {
|
||||
if (*(mc+1) == '\n') {
|
||||
if (*(mc + 1) == '\n') {
|
||||
*md = '\n';
|
||||
md++;
|
||||
mc += 2;
|
||||
@@ -377,64 +395,71 @@ main(int argc, char* argv[])
|
||||
}
|
||||
}
|
||||
*md = 0;
|
||||
}
|
||||
break;
|
||||
case 'N':
|
||||
if (expander.vendor)
|
||||
vendor_exclusive();
|
||||
expander.vendor = V_NOKIA;
|
||||
break;
|
||||
case 'n':
|
||||
if (expander.vendor)
|
||||
vendor_exclusive();
|
||||
expander.vendor = V_NOKIA_MD;
|
||||
break;
|
||||
case 't':
|
||||
if (expander.generation)
|
||||
exclusive();
|
||||
expander.generation = T_ASSET;
|
||||
break;
|
||||
case 'T':
|
||||
pipelining = 0;
|
||||
break;
|
||||
case 's':
|
||||
expander.sequence = 1;
|
||||
break;
|
||||
case 'S':
|
||||
expander.sources = optarg;
|
||||
break;
|
||||
case 'U':
|
||||
if (expander.vendor)
|
||||
exclusive();
|
||||
expander.vendor = V_HUAWEI;
|
||||
break;
|
||||
case 'W':
|
||||
expander.aswidth = atoi(optarg);
|
||||
if (expander.aswidth < 0) {
|
||||
sx_report(SX_FATAL,"Invalid as-width: %s\n",
|
||||
optarg);
|
||||
exit(1);
|
||||
}
|
||||
widthSet = 1;
|
||||
break;
|
||||
case 'w':
|
||||
expander.validate_asns = 1;
|
||||
break;
|
||||
case 'X':
|
||||
if (expander.vendor)
|
||||
vendor_exclusive();
|
||||
expander.vendor = V_CISCO_XR;
|
||||
break;
|
||||
case 'v':
|
||||
version();
|
||||
break;
|
||||
case 'z':
|
||||
if (expander.generation)
|
||||
exclusive();
|
||||
expander.generation = T_ROUTE_FILTER_LIST;
|
||||
break;
|
||||
default:
|
||||
usage(1);
|
||||
}
|
||||
break;
|
||||
case 'N':
|
||||
if (expander.vendor)
|
||||
vendor_exclusive();
|
||||
expander.vendor = V_NOKIA;
|
||||
break;
|
||||
case 'n':
|
||||
if (expander.vendor)
|
||||
vendor_exclusive();
|
||||
expander.vendor = V_NOKIA_MD;
|
||||
break;
|
||||
case 'p':
|
||||
expand_special_asn = 1;
|
||||
break;
|
||||
case 't':
|
||||
if (expander.generation)
|
||||
exclusive();
|
||||
expander.generation = T_ASSET;
|
||||
break;
|
||||
case 'T':
|
||||
pipelining = 0;
|
||||
break;
|
||||
case 's':
|
||||
expander.sequence = 1;
|
||||
break;
|
||||
case 'S':
|
||||
expander.sources = optarg;
|
||||
break;
|
||||
case 'U':
|
||||
if (expander.vendor)
|
||||
exclusive();
|
||||
expander.vendor = V_HUAWEI;
|
||||
break;
|
||||
case 'u':
|
||||
if (expander.vendor)
|
||||
exclusive();
|
||||
expander.vendor = V_HUAWEI_XPL;
|
||||
break;
|
||||
case 'W':
|
||||
expander.aswidth = atoi(optarg);
|
||||
if (expander.aswidth < 0) {
|
||||
sx_report(SX_FATAL,"Invalid as-width: %s\n", optarg);
|
||||
exit(1);
|
||||
}
|
||||
widthSet = 1;
|
||||
break;
|
||||
case 'w':
|
||||
expander.validate_asns = 1;
|
||||
break;
|
||||
case 'X':
|
||||
if (expander.vendor)
|
||||
vendor_exclusive();
|
||||
expander.vendor = V_CISCO_XR;
|
||||
break;
|
||||
case 'v':
|
||||
version();
|
||||
break;
|
||||
case 'z':
|
||||
if (expander.generation)
|
||||
exclusive();
|
||||
expander.generation = T_ROUTE_FILTER_LIST;
|
||||
break;
|
||||
default:
|
||||
usage(1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -447,16 +472,22 @@ main(int argc, char* argv[])
|
||||
switch (vendor) {
|
||||
case V_ARISTA:
|
||||
case V_CISCO:
|
||||
case V_MIKROTIK:
|
||||
case V_MIKROTIK6:
|
||||
case V_MIKROTIK7:
|
||||
expander.aswidth = 4;
|
||||
break;
|
||||
case V_CISCO_XR:
|
||||
expander.aswidth = 6;
|
||||
break;
|
||||
case V_JUNIPER:
|
||||
case V_NOKIA:
|
||||
case V_NOKIA_MD:
|
||||
case V_NOKIA_SRL:
|
||||
expander.aswidth = 8;
|
||||
break;
|
||||
case V_BIRD:
|
||||
expander.aswidth = 10;
|
||||
break;
|
||||
}
|
||||
} else if (expander.generation == T_OASPATH) {
|
||||
int vendor = expander.vendor;
|
||||
@@ -464,12 +495,23 @@ main(int argc, char* argv[])
|
||||
case V_ARISTA:
|
||||
case V_CISCO:
|
||||
expander.aswidth = 5;
|
||||
break;
|
||||
case V_CISCO_XR:
|
||||
expander.aswidth = 7;
|
||||
break;
|
||||
case V_JUNIPER:
|
||||
case V_NOKIA:
|
||||
case V_NOKIA_MD:
|
||||
case V_NOKIA_SRL:
|
||||
expander.aswidth = 8;
|
||||
break;
|
||||
}
|
||||
} else if (expander.generation == T_ASLIST) {
|
||||
int vendor = expander.vendor;
|
||||
switch (vendor) {
|
||||
case V_JUNIPER:
|
||||
expander.aswidth = 8;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -533,7 +575,7 @@ main(int argc, char* argv[])
|
||||
}
|
||||
|
||||
if (aggregate
|
||||
&& (expander.vendor == V_NOKIA_MD || expander.vendor == V_NOKIA)
|
||||
&& (expander.vendor == V_NOKIA_MD || expander.vendor == V_NOKIA || expander.vendor == V_NOKIA_SRL)
|
||||
&& expander.generation != T_PREFIXLIST) {
|
||||
sx_report(SX_FATAL, "Sorry, aggregation (-A) is not supported with "
|
||||
"ip-prefix-lists (-E) on Nokia.\n");
|
||||
@@ -541,7 +583,7 @@ main(int argc, char* argv[])
|
||||
}
|
||||
|
||||
if (refine
|
||||
&& (expander.vendor == V_NOKIA_MD || expander.vendor == V_NOKIA)
|
||||
&& (expander.vendor == V_NOKIA_MD || expander.vendor == V_NOKIA || expander.vendor == V_NOKIA_SRL)
|
||||
&& expander.generation != T_PREFIXLIST) {
|
||||
sx_report(SX_FATAL, "Sorry, more-specifics (-R) is not supported with "
|
||||
"ip-prefix-lists (-E) on Nokia.\n");
|
||||
@@ -549,7 +591,7 @@ main(int argc, char* argv[])
|
||||
}
|
||||
|
||||
if (refineLow
|
||||
&& (expander.vendor == V_NOKIA_MD || expander.vendor == V_NOKIA)
|
||||
&& (expander.vendor == V_NOKIA_MD || expander.vendor == V_NOKIA || expander.vendor == V_NOKIA_SRL)
|
||||
&& expander.generation != T_PREFIXLIST) {
|
||||
sx_report(SX_FATAL, "Sorry, more-specifics (-r) is not supported with "
|
||||
"ip-prefix-lists (-E) on Nokia.\n");
|
||||
@@ -656,14 +698,18 @@ main(int argc, char* argv[])
|
||||
"only with Juniper route-filters\n");
|
||||
}
|
||||
|
||||
if ((expander.generation == T_ASPATH || expander.generation == T_OASPATH)
|
||||
if ((expander.generation == T_ASPATH
|
||||
|| expander.generation == T_OASPATH
|
||||
|| expander.generation == T_ASLIST)
|
||||
&& af != AF_INET && !expander.validate_asns) {
|
||||
sx_report(SX_FATAL, "Sorry, -6 makes no sense with as-path (-f/-G) "
|
||||
sx_report(SX_FATAL, "Sorry, -6 makes no sense with as-path (-f/-G) or as-list (-H) "
|
||||
"generation\n");
|
||||
}
|
||||
|
||||
if (expander.validate_asns && expander.generation != T_ASPATH
|
||||
&& expander.generation != T_OASPATH) {
|
||||
if (expander.validate_asns
|
||||
&& expander.generation != T_ASPATH
|
||||
&& expander.generation != T_OASPATH
|
||||
&& expander.generation != T_ASLIST) {
|
||||
sx_report(SX_FATAL, "Sorry, -w makes sense only for as-path "
|
||||
"(-f/-G) generation\n");
|
||||
}
|
||||
@@ -672,17 +718,23 @@ main(int argc, char* argv[])
|
||||
usage(1);
|
||||
|
||||
while (argv[0]) {
|
||||
char *obj = argv[0];
|
||||
char *delim = strstr(argv[0], "::");
|
||||
if (delim) {
|
||||
expander.usesource = 1;
|
||||
obj = delim + 2;
|
||||
}
|
||||
if (!strcmp(argv[0], "EXCEPT")) {
|
||||
exceptmode = 1;
|
||||
} else if (exceptmode) {
|
||||
bgpq_expander_add_stop(&expander, argv[0]);
|
||||
} else if (!strncasecmp(argv[0], "AS-", 3)) {
|
||||
} else if (!strncasecmp(obj, "AS-", 3)) {
|
||||
bgpq_expander_add_asset(&expander, argv[0]);
|
||||
} else if (!strncasecmp(argv[0], "RS-", 3)) {
|
||||
} else if (!strncasecmp(obj, "RS-", 3)) {
|
||||
bgpq_expander_add_rset(&expander, argv[0]);
|
||||
} else if (!strncasecmp(argv[0], "AS", 2)) {
|
||||
} else if (!strncasecmp(obj, "AS", 2)) {
|
||||
char *ec;
|
||||
if ((ec = strchr(argv[0], ':'))) {
|
||||
if ((ec = strchr(obj, ':'))) {
|
||||
if (!strncasecmp(ec + 1, "AS-", 3)) {
|
||||
bgpq_expander_add_asset(&expander, argv[0]);
|
||||
} else if (!strncasecmp(ec + 1, "RS-", 3)) {
|
||||
@@ -726,22 +778,25 @@ main(int argc, char* argv[])
|
||||
|
||||
switch (expander.generation) {
|
||||
case T_NONE:
|
||||
sx_report(SX_FATAL,"Unreachable point... call snar\n");
|
||||
sx_report(SX_FATAL,"Unreachable point");
|
||||
exit(1);
|
||||
case T_ASPATH:
|
||||
bgpq4_print_aspath(stdout,&expander);
|
||||
bgpq4_print_aspath(stdout, &expander);
|
||||
break;
|
||||
case T_OASPATH:
|
||||
bgpq4_print_oaspath(stdout,&expander);
|
||||
bgpq4_print_oaspath(stdout, &expander);
|
||||
break;
|
||||
case T_ASLIST:
|
||||
bgpq4_print_aslist(stdout, &expander);
|
||||
break;
|
||||
case T_ASSET:
|
||||
bgpq4_print_asset(stdout,&expander);
|
||||
bgpq4_print_asset(stdout, &expander);
|
||||
break;
|
||||
case T_PREFIXLIST:
|
||||
bgpq4_print_prefixlist(stdout,&expander);
|
||||
bgpq4_print_prefixlist(stdout, &expander);
|
||||
break;
|
||||
case T_EACL:
|
||||
bgpq4_print_eacl(stdout,&expander);
|
||||
bgpq4_print_eacl(stdout, &expander);
|
||||
break;
|
||||
case T_ROUTE_FILTER_LIST:
|
||||
bgpq4_print_route_filter_list(stdout, &expander);
|
||||
|
||||
137
sx_maxsockbuf.c
137
sx_maxsockbuf.c
@@ -1,137 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2020 Job Snijders <job@sobornost.net>
|
||||
* Copyright (c) 2007-2019 Alexandre Snarskii <snar@snar.spb.ru>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "extern.h"
|
||||
#include "sx_report.h"
|
||||
|
||||
#ifndef SX_MAXSOCKBUF_MAX
|
||||
#define SX_MAXSOCKBUF_MAX (2 * 1024 * 1024)
|
||||
#endif
|
||||
|
||||
int
|
||||
sx_maxsockbuf(int s, int dir)
|
||||
{
|
||||
int optval = 0, voptval;
|
||||
int hiconf = -1, loconf = -1;
|
||||
unsigned int voptlen;
|
||||
int phase = 0, iterations = 0;
|
||||
|
||||
if (s < 0) {
|
||||
sx_report(SX_FATAL,"Unable to maximize sockbuf on invalid "
|
||||
"socket %i\n", s);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
voptlen = sizeof(optval);
|
||||
|
||||
if (getsockopt(s, SOL_SOCKET, dir, (void*)&optval, &voptlen) == -1) {
|
||||
sx_report(SX_ERROR,"initial getsockopt failed: %s\n",
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
iterations++;
|
||||
|
||||
if (phase == 0)
|
||||
optval<<=1;
|
||||
else {
|
||||
if (optval == (hiconf + loconf) / 2)
|
||||
break;
|
||||
optval = (hiconf + loconf) / 2;
|
||||
}
|
||||
|
||||
if (optval > SX_MAXSOCKBUF_MAX && phase == 0)
|
||||
break;
|
||||
|
||||
if (setsockopt(s, SOL_SOCKET, dir, (void*)&optval,
|
||||
sizeof(optval)) == -1) {
|
||||
|
||||
if (phase == 0)
|
||||
phase = 1;
|
||||
|
||||
hiconf = optval;
|
||||
|
||||
continue;
|
||||
} else {
|
||||
loconf = optval;
|
||||
}
|
||||
|
||||
voptlen = sizeof(voptval);
|
||||
|
||||
if (getsockopt(s, SOL_SOCKET, dir, (void*)&voptval,
|
||||
&voptlen) == -1) {
|
||||
sx_report(SX_ERROR,"getsockopt failed: %s\n",
|
||||
strerror(errno));
|
||||
return -1;
|
||||
} else if (voptval < optval) {
|
||||
if (phase == 0) {
|
||||
phase = 1;
|
||||
optval >>= 1;
|
||||
continue;
|
||||
} else if (phase == 1) {
|
||||
phase = 2;
|
||||
optval -= 2048;
|
||||
continue;
|
||||
} else
|
||||
break;
|
||||
} else if (voptval >= SX_MAXSOCKBUF_MAX) {
|
||||
/*
|
||||
* ... and getsockopt not failed and voptval>=optval.
|
||||
* Do not allow to increase sockbuf too much even in
|
||||
* case OS permits it
|
||||
*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
voptlen = sizeof(voptval);
|
||||
if (getsockopt(s, SOL_SOCKET, dir, (void*)&voptval,
|
||||
&voptlen) == -1) {
|
||||
sx_report(SX_ERROR,"getsockopt(final stage) failed: %s\n",
|
||||
strerror(errno));
|
||||
return -1;
|
||||
} else {
|
||||
/*
|
||||
printf("Finally got %i bytes of recvspace in %i interations\n",
|
||||
voptval, iterations);
|
||||
*/
|
||||
}
|
||||
|
||||
return voptval;
|
||||
}
|
||||
135
sx_prefix.c
135
sx_prefix.c
@@ -26,6 +26,7 @@
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -38,13 +39,13 @@
|
||||
int debug_aggregation = 0;
|
||||
extern int debug_expander;
|
||||
|
||||
struct sx_prefix*
|
||||
struct sx_prefix *
|
||||
sx_prefix_alloc(struct sx_prefix *p)
|
||||
{
|
||||
struct sx_prefix *sp = malloc(sizeof(struct sx_prefix));
|
||||
struct sx_prefix *sp;
|
||||
|
||||
if (!sp)
|
||||
return NULL;
|
||||
if ((sp = malloc(sizeof(struct sx_prefix))) == NULL)
|
||||
err(1, NULL);
|
||||
|
||||
if (p)
|
||||
memcpy(sp, p, sizeof(struct sx_prefix));
|
||||
@@ -55,7 +56,7 @@ sx_prefix_alloc(struct sx_prefix *p)
|
||||
}
|
||||
|
||||
void
|
||||
sx_prefix_destroy(struct sx_prefix *p)
|
||||
sx_prefix_free(struct sx_prefix *p)
|
||||
{
|
||||
if (p)
|
||||
free(p);
|
||||
@@ -64,15 +65,16 @@ sx_prefix_destroy(struct sx_prefix *p)
|
||||
void
|
||||
sx_radix_node_destroy(struct sx_radix_node *n)
|
||||
{
|
||||
if (n) {
|
||||
if (n->payload)
|
||||
free(n->payload);
|
||||
if (!n)
|
||||
return;
|
||||
|
||||
if (n->prefix)
|
||||
free(n->prefix);
|
||||
if (n->payload)
|
||||
free(n->payload);
|
||||
|
||||
free(n);
|
||||
}
|
||||
if (n->prefix)
|
||||
free(n->prefix);
|
||||
|
||||
free(n);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -133,16 +135,16 @@ sx_prefix_parse(struct sx_prefix *p, int af, char *text)
|
||||
{
|
||||
char *c = NULL;
|
||||
int masklen, ret;
|
||||
char mtext[INET6_ADDRSTRLEN+5];
|
||||
char mtext[INET6_ADDRSTRLEN + 5];
|
||||
|
||||
strlcpy(mtext, text, sizeof(mtext));
|
||||
|
||||
c = strchr(mtext,'/');
|
||||
|
||||
if (c) {
|
||||
char* eod;
|
||||
char *eod;
|
||||
*c = 0;
|
||||
masklen = strtol(c+1, &eod, 10);
|
||||
masklen = strtol(c + 1, &eod, 10);
|
||||
if (eod && eod[0] && !isspace(eod[0])) {
|
||||
*c = '/';
|
||||
sx_report(SX_ERROR, "Invalid masklen in prefix %s\n",
|
||||
@@ -257,25 +259,19 @@ sx_prefix_setbit(struct sx_prefix *p, int n)
|
||||
|
||||
|
||||
static int
|
||||
sx_radix_tree_insert_specifics(struct sx_radix_tree *t, struct sx_prefix *p,
|
||||
sx_radix_tree_insert_specifics(struct sx_radix_tree *t, struct sx_prefix p,
|
||||
unsigned min, unsigned max)
|
||||
{
|
||||
struct sx_prefix *np;
|
||||
np = sx_prefix_alloc(p);
|
||||
if (p.masklen >= min)
|
||||
sx_radix_tree_insert(t, &p);
|
||||
|
||||
if (np->masklen >= min) {
|
||||
struct sx_radix_node *nn = sx_radix_tree_insert(t, np);
|
||||
sx_prefix_destroy(np);
|
||||
np = nn->prefix;
|
||||
}
|
||||
|
||||
if (np->masklen + 1 > max)
|
||||
if (p.masklen + 1 > max)
|
||||
return 1;
|
||||
|
||||
np->masklen += 1;
|
||||
sx_radix_tree_insert_specifics(t, np, min, max);
|
||||
sx_prefix_setbit(np, np->masklen);
|
||||
sx_radix_tree_insert_specifics(t, np, min, max);
|
||||
p.masklen += 1;
|
||||
sx_radix_tree_insert_specifics(t, p, min, max);
|
||||
sx_prefix_setbit(&p, p.masklen);
|
||||
sx_radix_tree_insert_specifics(t, p, min, max);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -284,46 +280,44 @@ int
|
||||
sx_prefix_range_parse(struct sx_radix_tree *tree, int af, unsigned int maxlen,
|
||||
char *text)
|
||||
{
|
||||
char *d = strchr(text, '^');
|
||||
struct sx_prefix *p;
|
||||
struct sx_prefix p;
|
||||
unsigned long min, max = 0;
|
||||
|
||||
p = sx_prefix_alloc(NULL);
|
||||
char *d = strchr(text, '^');
|
||||
|
||||
if (!d || !d[1])
|
||||
return 0;
|
||||
|
||||
*d = 0;
|
||||
|
||||
if (!sx_prefix_parse(p, 0, text)) {
|
||||
if (!sx_prefix_parse(&p, 0, text)) {
|
||||
sx_report(SX_ERROR, "Unable to parse prefix %s^%s\n", text,
|
||||
d+1);
|
||||
d + 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*d = '^';
|
||||
|
||||
if (af && p->family != af) {
|
||||
if (af && p.family != af) {
|
||||
sx_report(SX_ERROR, "Ignoring prefix %s, wrong af %i\n", text,
|
||||
p->family);
|
||||
p.family);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (maxlen && p->masklen > maxlen) {
|
||||
if (maxlen && p.masklen > maxlen) {
|
||||
SX_DEBUG(debug_expander, "Ignoring prefix %s, masklen %i > max"
|
||||
" masklen %u\n", text, p->masklen, maxlen);
|
||||
" masklen %u\n", text, p.masklen, maxlen);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (d[1] == '-') {
|
||||
min = p->masklen + 1;
|
||||
min = p.masklen + 1;
|
||||
max = maxlen;
|
||||
} else if (d[1] == '+') {
|
||||
min = p->masklen;
|
||||
min = p.masklen;
|
||||
max = maxlen;
|
||||
} else if (isdigit(d[1])) {
|
||||
char *dm = NULL;
|
||||
min = strtoul(d+1, &dm, 10);
|
||||
min = strtoul(d + 1, &dm, 10);
|
||||
if (dm && *dm == '-' && isdigit(dm[1])) {
|
||||
max = strtoul(dm + 1, NULL, 10);
|
||||
} else if (dm && *dm) {
|
||||
@@ -336,9 +330,9 @@ sx_prefix_range_parse(struct sx_radix_tree *tree, int af, unsigned int maxlen,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (min < p->masklen) {
|
||||
if (min < p.masklen) {
|
||||
sx_report(SX_ERROR, "Invalid prefix-range %s: min %lu < "
|
||||
"masklen %u\n", text, min, p->masklen);
|
||||
"masklen %u\n", text, min, p.masklen);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -377,7 +371,7 @@ sx_prefix_new(int af, char *text)
|
||||
return NULL;
|
||||
|
||||
if (!sx_prefix_parse(p, af, text)) {
|
||||
sx_prefix_destroy(p);
|
||||
sx_prefix_free(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -483,7 +477,7 @@ sx_prefix_snprintf_fmt(struct sx_prefix *p, FILE *f,
|
||||
}
|
||||
c += 2;
|
||||
} else if (*c == '\\') {
|
||||
switch(*(c+1)) {
|
||||
switch(*(c + 1)) {
|
||||
case 'n':
|
||||
fprintf(f, "\n");
|
||||
break;
|
||||
@@ -519,13 +513,13 @@ sx_prefix_jsnprintf(struct sx_prefix *p, char *rbuffer, int srb)
|
||||
return snprintf(rbuffer, srb, "%s\\/%i", buffer, p->masklen);
|
||||
}
|
||||
|
||||
struct sx_radix_tree*
|
||||
struct sx_radix_tree *
|
||||
sx_radix_tree_new(int af)
|
||||
{
|
||||
struct sx_radix_tree *rt = malloc(sizeof(struct sx_radix_tree));
|
||||
struct sx_radix_tree *rt;
|
||||
|
||||
if (!rt)
|
||||
return NULL;
|
||||
if ((rt = malloc(sizeof(struct sx_radix_tree))) == NULL)
|
||||
err(1, NULL);
|
||||
|
||||
memset(rt, 0, sizeof(struct sx_radix_tree));
|
||||
rt->family = af;
|
||||
@@ -539,13 +533,13 @@ sx_radix_tree_empty(struct sx_radix_tree *t)
|
||||
return t->head == NULL;
|
||||
}
|
||||
|
||||
struct sx_radix_node*
|
||||
struct sx_radix_node *
|
||||
sx_radix_node_new(struct sx_prefix *prefix)
|
||||
{
|
||||
struct sx_radix_node *rn = malloc(sizeof(struct sx_radix_node));
|
||||
struct sx_radix_node *rn;
|
||||
|
||||
if (!rn)
|
||||
return NULL;
|
||||
if ((rn = malloc(sizeof(struct sx_radix_node))) == NULL)
|
||||
err(1, NULL);
|
||||
|
||||
memset(rn, 0, sizeof(struct sx_radix_node));
|
||||
|
||||
@@ -582,7 +576,7 @@ sx_prefix_eqbits(struct sx_prefix *a, struct sx_prefix *b)
|
||||
return b->masklen;
|
||||
}
|
||||
|
||||
struct sx_prefix*
|
||||
struct sx_prefix *
|
||||
sx_prefix_overlay(struct sx_prefix *p, int n)
|
||||
{
|
||||
struct sx_prefix *sp = sx_prefix_alloc(p);
|
||||
@@ -668,7 +662,7 @@ next:
|
||||
}
|
||||
|
||||
|
||||
struct sx_radix_node*
|
||||
struct sx_radix_node *
|
||||
sx_radix_tree_lookup(struct sx_radix_tree *tree, struct sx_prefix *prefix)
|
||||
{
|
||||
unsigned int eb;
|
||||
@@ -725,18 +719,18 @@ next:
|
||||
char pbuffer[128], cbuffer[128];
|
||||
sx_prefix_snprintf(prefix, pbuffer, sizeof(pbuffer));
|
||||
sx_prefix_snprintf(chead->prefix, cbuffer, sizeof(cbuffer));
|
||||
printf("Unreachible point... eb=%i, prefix=%s, chead=%s\n",
|
||||
printf("Unreachable point... eb=%i, prefix=%s, chead=%s\n",
|
||||
eb, pbuffer, cbuffer);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct sx_radix_node*
|
||||
struct sx_radix_node *
|
||||
sx_radix_tree_insert(struct sx_radix_tree *tree, struct sx_prefix *prefix)
|
||||
{
|
||||
unsigned int eb;
|
||||
struct sx_radix_node **candidate=NULL, *chead;
|
||||
unsigned int eb;
|
||||
struct sx_radix_node *chead, **candidate = NULL;
|
||||
|
||||
if (!tree || !prefix)
|
||||
return NULL;
|
||||
@@ -752,7 +746,7 @@ sx_radix_tree_insert(struct sx_radix_tree *tree, struct sx_prefix *prefix)
|
||||
candidate = &tree->head;
|
||||
chead = tree->head;
|
||||
|
||||
next:
|
||||
next:
|
||||
eb = sx_prefix_eqbits(prefix, chead->prefix);
|
||||
if (eb < prefix->masklen && eb < chead->prefix->masklen) {
|
||||
struct sx_prefix *neoRoot = sx_prefix_alloc(prefix);
|
||||
@@ -761,7 +755,7 @@ next:
|
||||
neoRoot->masklen = eb;
|
||||
sx_prefix_adjust_masklen(neoRoot);
|
||||
rn=sx_radix_node_new(neoRoot);
|
||||
sx_prefix_destroy(neoRoot);
|
||||
sx_prefix_free(neoRoot);
|
||||
neoRoot = rn->prefix;
|
||||
if (!rn) {
|
||||
sx_report(SX_ERROR,"Unable to create node: %s\n",
|
||||
@@ -785,11 +779,10 @@ next:
|
||||
return ret;
|
||||
} else if (eb == prefix->masklen && eb < chead->prefix->masklen) {
|
||||
struct sx_radix_node *ret = sx_radix_node_new(prefix);
|
||||
if (sx_prefix_isbitset(chead->prefix, eb + 1)) {
|
||||
if (sx_prefix_isbitset(chead->prefix, eb + 1))
|
||||
ret->r = chead;
|
||||
} else {
|
||||
else
|
||||
ret->l = chead;
|
||||
}
|
||||
ret->parent = chead->parent;
|
||||
chead->parent = ret;
|
||||
*candidate = ret;
|
||||
@@ -826,7 +819,7 @@ next:
|
||||
char pbuffer[128], cbuffer[128];
|
||||
sx_prefix_snprintf(prefix, pbuffer, sizeof(pbuffer));
|
||||
sx_prefix_snprintf(chead->prefix, cbuffer, sizeof(cbuffer));
|
||||
printf("Unreachible point... eb=%i, prefix=%s, chead=%s\n", eb,
|
||||
printf("Unreachable point... eb=%i, prefix=%s, chead=%s\n", eb,
|
||||
pbuffer, cbuffer);
|
||||
abort();
|
||||
}
|
||||
@@ -848,7 +841,7 @@ sx_radix_node_fprintf(struct sx_radix_node *node, void *udata)
|
||||
|
||||
int
|
||||
sx_radix_node_foreach(struct sx_radix_node *node,
|
||||
void (*func)(struct sx_radix_node*, void*), void *udata)
|
||||
void (*func)(struct sx_radix_node *, void *), void *udata)
|
||||
{
|
||||
func(node, udata);
|
||||
|
||||
@@ -925,7 +918,7 @@ sx_radix_node_aggregate(struct sx_radix_node *node)
|
||||
if (!node->r->isAggregate && !node->l->isAggregate
|
||||
&& !node->r->isGlue && !node->l->isGlue
|
||||
&& node->r->prefix->masklen == node->l->prefix->masklen) {
|
||||
if (node->r->prefix->masklen == node->prefix->masklen+1) {
|
||||
if (node->r->prefix->masklen == node->prefix->masklen + 1) {
|
||||
node->isAggregate = 1;
|
||||
node->r->isGlue = 1;
|
||||
node->l->isGlue = 1;
|
||||
@@ -1019,7 +1012,7 @@ sx_radix_node_aggregate(struct sx_radix_node *node)
|
||||
&& node->l->aggregateHi == node->r->son->aggregateHi
|
||||
&& node->l->aggregateLow == node->r->son->aggregateLow) {
|
||||
if (node->l->prefix->masklen == node->prefix->masklen + 1
|
||||
&& node->r->prefix->masklen == node->prefix->masklen+1) {
|
||||
&& node->r->prefix->masklen == node->prefix->masklen + 1) {
|
||||
if (node->isGlue) {
|
||||
node->l->isGlue = 1;
|
||||
node->r->son->isGlue = 1;
|
||||
@@ -1055,7 +1048,7 @@ sx_radix_tree_aggregate(struct sx_radix_tree *tree)
|
||||
static void
|
||||
setGlueUpTo(struct sx_radix_node *node, void *udata)
|
||||
{
|
||||
unsigned refine = *(unsigned*)udata;
|
||||
unsigned refine = *(unsigned *)udata;
|
||||
|
||||
if (node && node->prefix->masklen <= refine)
|
||||
node->isGlue = 1;
|
||||
@@ -1115,7 +1108,7 @@ sx_radix_tree_refine(struct sx_radix_tree *tree, unsigned refine)
|
||||
static void
|
||||
setGlueFrom(struct sx_radix_node *node, void *udata)
|
||||
{
|
||||
unsigned refine = *(unsigned*)udata;
|
||||
unsigned refine = *(unsigned *)udata;
|
||||
|
||||
if (node && node->prefix->masklen <= refine)
|
||||
node->isGlue = 1;
|
||||
|
||||
@@ -68,7 +68,7 @@ struct sx_radix_node *sx_radix_tree_lookup_exact(struct sx_radix_tree *tree,
|
||||
struct sx_prefix *prefix);
|
||||
|
||||
struct sx_prefix *sx_prefix_alloc(struct sx_prefix *p);
|
||||
void sx_prefix_destroy(struct sx_prefix *p);
|
||||
void sx_prefix_free(struct sx_prefix *p);
|
||||
void sx_radix_node_destroy(struct sx_radix_node *p);
|
||||
void sx_prefix_adjust_masklen(struct sx_prefix *p);
|
||||
struct sx_prefix *sx_prefix_new(int af, char *text);
|
||||
|
||||
@@ -31,15 +31,15 @@
|
||||
|
||||
#include "extern.h"
|
||||
|
||||
struct sx_slentry *
|
||||
struct slentry *
|
||||
sx_slentry_new(char *t)
|
||||
{
|
||||
struct sx_slentry *e = malloc(sizeof(struct sx_slentry));
|
||||
struct slentry *e = malloc(sizeof(struct slentry));
|
||||
|
||||
if (!e)
|
||||
return NULL;
|
||||
|
||||
memset(e, 0, sizeof(struct sx_slentry));
|
||||
memset(e, 0, sizeof(struct slentry));
|
||||
|
||||
e->text = strdup(t);
|
||||
|
||||
|
||||
90
tests/generate_outputs.sh
Executable file
90
tests/generate_outputs.sh
Executable file
@@ -0,0 +1,90 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
if [ $# -ne 2 ]
|
||||
then
|
||||
echo "Usage: pass the following arguments in order:"
|
||||
echo ""
|
||||
echo "path to bgpq4 binary"
|
||||
echo "output directory path"
|
||||
echo ""
|
||||
echo "${0} ./bgpq4 /tmp"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
BGPQ4_PATH="${1}"
|
||||
TEST_ASN="112"
|
||||
TEST_AS_SET="AS-AS112"
|
||||
OUT_DIR="${2}"
|
||||
|
||||
if [ ! -f "${BGPQ4_PATH}" ]
|
||||
then
|
||||
echo "File ${BGPQ4_PATH} does't exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -e "${OUT_DIR}" ]
|
||||
then
|
||||
echo "Output directory ${OUT_DIR} does't exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Test the IPv4 output formatting for each supported NOS:
|
||||
"${BGPQ4_PATH}" -4 -b "AS${TEST_ASN}" > "${OUT_DIR}/bird--4.txt"
|
||||
"${BGPQ4_PATH}" -4 -e "AS${TEST_ASN}" > "${OUT_DIR}/eos--4.txt"
|
||||
"${BGPQ4_PATH}" -4 -F '%n/%l ' "AS${TEST_ASN}" > "${OUT_DIR}/formated--4.txt"
|
||||
"${BGPQ4_PATH}" -4 -U "AS${TEST_ASN}" > "${OUT_DIR}/huawei--4.txt"
|
||||
"${BGPQ4_PATH}" -4 -u "AS${TEST_ASN}" > "${OUT_DIR}/huawei-xpl--4.txt"
|
||||
"${BGPQ4_PATH}" -4 "AS${TEST_ASN}" > "${OUT_DIR}/ios--4.txt"
|
||||
"${BGPQ4_PATH}" -4 -X "AS${TEST_ASN}" > "${OUT_DIR}/ios-xr--4.txt"
|
||||
"${BGPQ4_PATH}" -4 -j "AS${TEST_ASN}" > "${OUT_DIR}/json--4.txt"
|
||||
"${BGPQ4_PATH}" -4 -J "AS${TEST_ASN}" > "${OUT_DIR}/junos--4.txt"
|
||||
"${BGPQ4_PATH}" -4 -B "AS${TEST_ASN}" > "${OUT_DIR}/openbgpd--4.txt"
|
||||
"${BGPQ4_PATH}" -4 -K "AS${TEST_ASN}" > "${OUT_DIR}/routeros6--4.txt"
|
||||
"${BGPQ4_PATH}" -4 -K7 "AS${TEST_ASN}" > "${OUT_DIR}/routeros7--4.txt"
|
||||
"${BGPQ4_PATH}" -4 -N "AS${TEST_ASN}" > "${OUT_DIR}/sros--4.txt"
|
||||
"${BGPQ4_PATH}" -4 -n "AS${TEST_ASN}" > "${OUT_DIR}/sros-mdcli--4.txt"
|
||||
"${BGPQ4_PATH}" -4 -n2 "AS${TEST_ASN}" > "${OUT_DIR}/srlinux--4.txt"
|
||||
|
||||
# Test the IPv6 prefix-list output formatting for each supported NOS:
|
||||
"${BGPQ4_PATH}" -6 -b "AS${TEST_ASN}" > "${OUT_DIR}/bird--6.txt"
|
||||
"${BGPQ4_PATH}" -6 -e "AS${TEST_ASN}" > "${OUT_DIR}/eos--6.txt"
|
||||
"${BGPQ4_PATH}" -6 -F '%n/%l ' "AS${TEST_ASN}" > "${OUT_DIR}/formated--6.txt"
|
||||
"${BGPQ4_PATH}" -6 -U "AS${TEST_ASN}" > "${OUT_DIR}/huawei--6.txt"
|
||||
"${BGPQ4_PATH}" -6 -u "AS${TEST_ASN}" > "${OUT_DIR}/huawei-xpl--6.txt"
|
||||
"${BGPQ4_PATH}" -6 "AS${TEST_ASN}" > "${OUT_DIR}/ios--6.txt"
|
||||
"${BGPQ4_PATH}" -6 -X "AS${TEST_ASN}" > "${OUT_DIR}/ios-xr--6.txt"
|
||||
"${BGPQ4_PATH}" -6 -j "AS${TEST_ASN}" > "${OUT_DIR}/json--6.txt"
|
||||
"${BGPQ4_PATH}" -6 -J "AS${TEST_ASN}" > "${OUT_DIR}/junos--6.txt"
|
||||
"${BGPQ4_PATH}" -6 -B "AS${TEST_ASN}" > "${OUT_DIR}/openbgpd--6.txt"
|
||||
"${BGPQ4_PATH}" -6 -K "AS${TEST_ASN}" > "${OUT_DIR}/routeros6--6.txt"
|
||||
"${BGPQ4_PATH}" -6 -K7 "AS${TEST_ASN}" > "${OUT_DIR}/routeros7--6.txt"
|
||||
"${BGPQ4_PATH}" -6 -N "AS${TEST_ASN}" > "${OUT_DIR}/sros--6.txt"
|
||||
"${BGPQ4_PATH}" -6 -n "AS${TEST_ASN}" > "${OUT_DIR}/sros-mdcli--6.txt"
|
||||
"${BGPQ4_PATH}" -6 -n2 "AS${TEST_ASN}" > "${OUT_DIR}/srlinux--6.txt"
|
||||
|
||||
# Test the AS path list output formatting for each supported NOS:
|
||||
"${BGPQ4_PATH}" "${TEST_AS_SET}" -f "${TEST_ASN}" -b > "${OUT_DIR}/bird--asp.txt"
|
||||
# "${BGPQ4_PATH}" "${TEST_AS_SET}" -f "${TEST_ASN}" -e > "${OUT_DIR}/eos--asp.txt" # Not supported
|
||||
"${BGPQ4_PATH}" "${TEST_AS_SET}" -f "${TEST_ASN}" -U > "${OUT_DIR}/huawei--asp.txt"
|
||||
"${BGPQ4_PATH}" "${TEST_AS_SET}" -f "${TEST_ASN}" -u > "${OUT_DIR}/huawei-xpl--asp.txt"
|
||||
"${BGPQ4_PATH}" "${TEST_AS_SET}" -f "${TEST_ASN}" > "${OUT_DIR}/ios--asp.txt"
|
||||
"${BGPQ4_PATH}" "${TEST_AS_SET}" -f "${TEST_ASN}" -X > "${OUT_DIR}/ios-xr--asp.txt"
|
||||
"${BGPQ4_PATH}" "${TEST_AS_SET}" -f "${TEST_ASN}" -j > "${OUT_DIR}/json--asp.txt"
|
||||
"${BGPQ4_PATH}" "${TEST_AS_SET}" -f "${TEST_ASN}" -J > "${OUT_DIR}/junos--asp.txt"
|
||||
"${BGPQ4_PATH}" "${TEST_AS_SET}" -f "${TEST_ASN}" -B > "${OUT_DIR}/openbgpd--asp.txt"
|
||||
# "${BGPQ4_PATH}" "${TEST_AS_SET}" -f "${TEST_ASN}" -K > "${OUT_DIR}/routeros6--asp.txt" # Not supported
|
||||
# "${BGPQ4_PATH}" "${TEST_AS_SET}" -f "${TEST_ASN}" -K7 > "${OUT_DIR}/routeros7--asp.txt" # Not supported
|
||||
"${BGPQ4_PATH}" "${TEST_AS_SET}" -f "${TEST_ASN}" -N > "${OUT_DIR}/sros--asp.txt"
|
||||
"${BGPQ4_PATH}" "${TEST_AS_SET}" -f "${TEST_ASN}" -n > "${OUT_DIR}/sros-mdcli--asp.txt"
|
||||
|
||||
# Test IRR source scopes
|
||||
# Limit ASN to valid source:
|
||||
"${BGPQ4_PATH}" "AS${TEST_ASN}" -S RIPE-NONAUTH > "${OUT_DIR}/as112-ripe-nonauth.txt"
|
||||
# Limit ASN to invalid sources:
|
||||
"${BGPQ4_PATH}" "AS${TEST_ASN}" -S APNIC,AFRINIC > "${OUT_DIR}/as112-apnic.txt"
|
||||
# Limit AS-SET using IRR prefix notation to valid source:
|
||||
"${BGPQ4_PATH}" "RIPE::${TEST_AS_SET}" > "${OUT_DIR}/as-as112-ripe-notation.txt"
|
||||
# Limit AS-SET using IRR prefix notation to invalid source:
|
||||
"${BGPQ4_PATH}" "APNIC::${TEST_AS_SET}" > "${OUT_DIR}/as-as112-apnic-notation.txt"
|
||||
3
tests/reference/as-as112-apnic-notation.txt
Normal file
3
tests/reference/as-as112-apnic-notation.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
no ip prefix-list NN
|
||||
! generated prefix-list NN is empty
|
||||
ip prefix-list NN deny 0.0.0.0/0
|
||||
3
tests/reference/as-as112-ripe-notation.txt
Normal file
3
tests/reference/as-as112-ripe-notation.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
no ip prefix-list NN
|
||||
ip prefix-list NN permit 192.31.196.0/24
|
||||
ip prefix-list NN permit 192.175.48.0/24
|
||||
3
tests/reference/as112-apnic.txt
Normal file
3
tests/reference/as112-apnic.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
no ip prefix-list NN
|
||||
! generated prefix-list NN is empty
|
||||
ip prefix-list NN deny 0.0.0.0/0
|
||||
3
tests/reference/as112-ripe-nonauth.txt
Normal file
3
tests/reference/as112-ripe-nonauth.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
no ip prefix-list NN
|
||||
ip prefix-list NN permit 192.31.196.0/24
|
||||
ip prefix-list NN permit 192.175.48.0/24
|
||||
4
tests/reference/bird--4.txt
Normal file
4
tests/reference/bird--4.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
NN = [
|
||||
192.31.196.0/24,
|
||||
192.175.48.0/24
|
||||
];
|
||||
4
tests/reference/bird--6.txt
Normal file
4
tests/reference/bird--6.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
NN = [
|
||||
2001:4:112::/48,
|
||||
2620:4f:8000::/48
|
||||
];
|
||||
3
tests/reference/bird--asp.txt
Normal file
3
tests/reference/bird--asp.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
NN = [
|
||||
112
|
||||
];
|
||||
4
tests/reference/eos--4.txt
Normal file
4
tests/reference/eos--4.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
no ip prefix-list NN
|
||||
ip prefix-list NN
|
||||
seq 1 permit 192.31.196.0/24
|
||||
seq 2 permit 192.175.48.0/24
|
||||
4
tests/reference/eos--6.txt
Normal file
4
tests/reference/eos--6.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
no ipv6 prefix-list NN
|
||||
ipv6 prefix-list NN
|
||||
seq 1 permit 2001:4:112::/48
|
||||
seq 2 permit 2620:4f:8000::/48
|
||||
1
tests/reference/formated--4.txt
Normal file
1
tests/reference/formated--4.txt
Normal file
@@ -0,0 +1 @@
|
||||
192.31.196.0/24 192.175.48.0/24
|
||||
1
tests/reference/formated--6.txt
Normal file
1
tests/reference/formated--6.txt
Normal file
@@ -0,0 +1 @@
|
||||
2001:4:112::/48 2620:4f:8000::/48
|
||||
3
tests/reference/huawei--4.txt
Normal file
3
tests/reference/huawei--4.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
undo ip ip-prefix NN
|
||||
ip ip-prefix NN permit 192.31.196.0 24
|
||||
ip ip-prefix NN permit 192.175.48.0 24
|
||||
3
tests/reference/huawei--6.txt
Normal file
3
tests/reference/huawei--6.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
undo ip ipv6-prefix NN
|
||||
ip ipv6-prefix NN permit 2001:4:112:: 48
|
||||
ip ipv6-prefix NN permit 2620:4f:8000:: 48
|
||||
2
tests/reference/huawei--asp.txt
Normal file
2
tests/reference/huawei--asp.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
undo ip as-path-filter NN
|
||||
ip as-path-filter NN permit ^112(_112)*$
|
||||
5
tests/reference/huawei-xpl--4.txt
Normal file
5
tests/reference/huawei-xpl--4.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
no xpl ip-prefix-list NN
|
||||
xpl ip-prefix-list NN
|
||||
192.31.196.0 24,
|
||||
192.175.48.0 24
|
||||
end-list
|
||||
5
tests/reference/huawei-xpl--6.txt
Normal file
5
tests/reference/huawei-xpl--6.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
no xpl ipv6-prefix-list NN
|
||||
xpl ipv6-prefix-list NN
|
||||
2001:4:112:: 48,
|
||||
2620:4f:8000:: 48
|
||||
end-list
|
||||
3
tests/reference/huawei-xpl--asp.txt
Normal file
3
tests/reference/huawei-xpl--asp.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
xpl as-path-list NN
|
||||
regular ^112(_112)*$
|
||||
end-list
|
||||
3
tests/reference/ios--4.txt
Normal file
3
tests/reference/ios--4.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
no ip prefix-list NN
|
||||
ip prefix-list NN permit 192.31.196.0/24
|
||||
ip prefix-list NN permit 192.175.48.0/24
|
||||
3
tests/reference/ios--6.txt
Normal file
3
tests/reference/ios--6.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
no ipv6 prefix-list NN
|
||||
ipv6 prefix-list NN permit 2001:4:112::/48
|
||||
ipv6 prefix-list NN permit 2620:4f:8000::/48
|
||||
2
tests/reference/ios--asp.txt
Normal file
2
tests/reference/ios--asp.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
no ip as-path access-list NN
|
||||
ip as-path access-list NN permit ^112(_112)*$
|
||||
5
tests/reference/ios-xr--4.txt
Normal file
5
tests/reference/ios-xr--4.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
no prefix-set NN
|
||||
prefix-set NN
|
||||
192.31.196.0/24,
|
||||
192.175.48.0/24
|
||||
end-set
|
||||
5
tests/reference/ios-xr--6.txt
Normal file
5
tests/reference/ios-xr--6.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
no prefix-set NN
|
||||
prefix-set NN
|
||||
2001:4:112::/48,
|
||||
2620:4f:8000::/48
|
||||
end-set
|
||||
3
tests/reference/ios-xr--asp.txt
Normal file
3
tests/reference/ios-xr--asp.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
as-path-set NN
|
||||
ios-regex '^112(_112)*$'
|
||||
end-set
|
||||
4
tests/reference/json--4.txt
Normal file
4
tests/reference/json--4.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
{ "NN": [
|
||||
{ "prefix": "192.31.196.0\/24", "exact": true },
|
||||
{ "prefix": "192.175.48.0\/24", "exact": true }
|
||||
] }
|
||||
4
tests/reference/json--6.txt
Normal file
4
tests/reference/json--6.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
{ "NN": [
|
||||
{ "prefix": "2001:4:112::\/48", "exact": true },
|
||||
{ "prefix": "2620:4f:8000::\/48", "exact": true }
|
||||
] }
|
||||
3
tests/reference/json--asp.txt
Normal file
3
tests/reference/json--asp.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
{"NN": [
|
||||
112
|
||||
]}
|
||||
7
tests/reference/junos--4.txt
Normal file
7
tests/reference/junos--4.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
policy-options {
|
||||
replace:
|
||||
prefix-list NN {
|
||||
192.31.196.0/24;
|
||||
192.175.48.0/24;
|
||||
}
|
||||
}
|
||||
7
tests/reference/junos--6.txt
Normal file
7
tests/reference/junos--6.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
policy-options {
|
||||
replace:
|
||||
prefix-list NN {
|
||||
2001:4:112::/48;
|
||||
2620:4f:8000::/48;
|
||||
}
|
||||
}
|
||||
6
tests/reference/junos--asp.txt
Normal file
6
tests/reference/junos--asp.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
policy-options {
|
||||
replace:
|
||||
as-path-group NN {
|
||||
as-path a0 "^112(112)*$";
|
||||
}
|
||||
}
|
||||
4
tests/reference/openbgpd--4.txt
Normal file
4
tests/reference/openbgpd--4.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
prefix {
|
||||
192.31.196.0/24
|
||||
192.175.48.0/24
|
||||
}
|
||||
4
tests/reference/openbgpd--6.txt
Normal file
4
tests/reference/openbgpd--6.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
prefix {
|
||||
2001:4:112::/48
|
||||
2620:4f:8000::/48
|
||||
}
|
||||
1
tests/reference/openbgpd--asp.txt
Normal file
1
tests/reference/openbgpd--asp.txt
Normal file
@@ -0,0 +1 @@
|
||||
allow from AS 112 AS 112
|
||||
2
tests/reference/routeros6--4.txt
Normal file
2
tests/reference/routeros6--4.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
/routing filter add action=accept chain="NN-V4" prefix=192.31.196.0/24
|
||||
/routing filter add action=accept chain="NN-V4" prefix=192.175.48.0/24
|
||||
2
tests/reference/routeros6--6.txt
Normal file
2
tests/reference/routeros6--6.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
/routing filter add action=accept chain="NN-V6" prefix=2001:4:112::/48
|
||||
/routing filter add action=accept chain="NN-V6" prefix=2620:4f:8000::/48
|
||||
2
tests/reference/routeros7--4.txt
Normal file
2
tests/reference/routeros7--4.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
/routing filter rule add chain="NN-V4" rule="if (dst==192.31.196.0/24) {accept}"
|
||||
/routing filter rule add chain="NN-V4" rule="if (dst==192.175.48.0/24) {accept}"
|
||||
2
tests/reference/routeros7--6.txt
Normal file
2
tests/reference/routeros7--6.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
/routing filter rule add chain="NN-V6" rule="if (dst==2001:4:112::/48) {accept}"
|
||||
/routing filter rule add chain="NN-V6" rule="if (dst==2620:4f:8000::/48) {accept}"
|
||||
6
tests/reference/srlinux--4.txt
Normal file
6
tests/reference/srlinux--4.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
/routing-policy
|
||||
delete prefix-set "NN"
|
||||
prefix-set "NN" {
|
||||
prefix 192.31.196.0/24 mask-length-range exact { }
|
||||
prefix 192.175.48.0/24 mask-length-range exact { }
|
||||
}
|
||||
6
tests/reference/srlinux--6.txt
Normal file
6
tests/reference/srlinux--6.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
/routing-policy
|
||||
delete prefix-set "NN"
|
||||
prefix-set "NN" {
|
||||
prefix 2001:4:112::/48 mask-length-range exact { }
|
||||
prefix 2620:4f:8000::/48 mask-length-range exact { }
|
||||
}
|
||||
8
tests/reference/sros--4.txt
Normal file
8
tests/reference/sros--4.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
configure router policy-options
|
||||
begin
|
||||
no prefix-list "NN"
|
||||
prefix-list "NN"
|
||||
prefix 192.31.196.0/24 exact
|
||||
prefix 192.175.48.0/24 exact
|
||||
exit
|
||||
commit
|
||||
8
tests/reference/sros--6.txt
Normal file
8
tests/reference/sros--6.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
configure router policy-options
|
||||
begin
|
||||
no prefix-list "NN"
|
||||
prefix-list "NN"
|
||||
prefix 2001:4:112::/48 exact
|
||||
prefix 2620:4f:8000::/48 exact
|
||||
exit
|
||||
commit
|
||||
7
tests/reference/sros--asp.txt
Normal file
7
tests/reference/sros--asp.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
configure router policy-options
|
||||
begin
|
||||
no as-path-group "NN"
|
||||
as-path-group "NN"
|
||||
entry 1 expression "112+"
|
||||
exit
|
||||
commit
|
||||
8
tests/reference/sros-mdcli--4.txt
Normal file
8
tests/reference/sros-mdcli--4.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
/configure policy-options
|
||||
delete prefix-list "NN"
|
||||
prefix-list "NN" {
|
||||
prefix 192.31.196.0/24 type exact {
|
||||
}
|
||||
prefix 192.175.48.0/24 type exact {
|
||||
}
|
||||
}
|
||||
8
tests/reference/sros-mdcli--6.txt
Normal file
8
tests/reference/sros-mdcli--6.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
/configure policy-options
|
||||
delete prefix-list "NN"
|
||||
prefix-list "NN" {
|
||||
prefix 2001:4:112::/48 type exact {
|
||||
}
|
||||
prefix 2620:4f:8000::/48 type exact {
|
||||
}
|
||||
}
|
||||
7
tests/reference/sros-mdcli--asp.txt
Normal file
7
tests/reference/sros-mdcli--asp.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
/configure policy-options
|
||||
delete as-path-group "NN"
|
||||
as-path-group "NN" {
|
||||
entry 1 {
|
||||
expression "112+"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user