30 Commits
1.9 ... 1.14

Author SHA1 Message Date
Job Snijders
4fe2500b45 Release 1.14 2024-05-14 12:55:45 +00:00
Job Snijders
a97f7eb4ff Update changelog 2024-05-13 12:19:19 +00:00
Robert Scheck
4ab84255a4 Work around broken Docker image by Rocky Linux (until CentOS 7 is EOL) (#114) 2024-05-10 12:16:04 +02:00
Job Snijders
424770be0b Set TCP_NODELAY on the socket
Nagle's algorithm probably serves no purpose with whois queries
often being tiny.
2024-05-10 09:41:28 +00:00
Robert Scheck
4bac9e7e53 Skip online test if no or empty /etc/resolv.conf (#113)
Downstream build systems, e.g. at Linux distributions like Fedora,
might be (sealed) offline (chroot) environments.
2024-05-05 22:33:12 +00:00
Robert Scheck
2ec0ea3fbd Don't try to login and push to GHCR on forks (#112) 2024-05-03 23:55:16 +02:00
Job Snijders
0a83c7598d Fix comma display in ingress IOS XR as-path-set printing 2024-05-01 12:26:30 +00:00
Job Snijders
f44bf47b1f Don't try to maximize the send buffer
Get rid of code that did a binary search to maximize the send buffer
via setsockopt SO_SNDBUF. It caused problems for modern Mac users.
2024-05-01 12:00:17 +00:00
Job Snijders
9ffc4f8ec6 Add missing newline 2024-05-01 12:00:09 +00:00
Job Snijders
a89ac75590 experiment 1 2024-05-01 11:45:59 +00:00
Job Snijders
59f800f31f Do not fiddle with the socket buffer size 2024-05-01 11:20:41 +00:00
Job Snijders
6c8bb871c0 fix path 2024-05-01 11:08:19 +00:00
Job Snijders
26b0827813 Add simple check target 2024-05-01 11:03:05 +00:00
Job Snijders
36a54c9b41 reference correct CI badge 2024-04-30 23:49:23 +00:00
Job Snijders
e743be94b3 add build imagery 2024-04-30 23:46:41 +00:00
Robert Scheck
b631d43755 Modernize usage of autoconf macros (#110) 2024-04-30 23:42:39 +00:00
Robert Scheck
57a70da5a9 Bump GitHub action versions in workflows (#106) 2024-04-30 23:41:45 +00:00
Job Snijders
95d3a4c12b Release 1.12 2024-02-12 16:57:03 +00:00
Robert Scheck
2e06d3c389 Update matrixbuild to current Linux distributions (#99) 2023-12-10 05:08:50 +01:00
Darshan Kowlaser
3d2eed555d fixed - mikrotik routerosv7 output (#103)
* fixed - mikrotik routerosv7 output

* fixed - mikrotik routerosv7 output

---------

Co-authored-by: dkayza-xxx <darshan@darshankowlaser.com>
2023-11-27 19:17:36 +01:00
Job Snijders
a28752247c update changelog 2023-06-20 12:24:28 +00:00
Job Snijders
26d631b257 By default disallow 23456 as origin
Can be bypassed with '-p'
2023-06-20 12:18:41 +00:00
Job Snijders
841840be68 whoops, forgot to bump version 2023-06-17 05:33:11 +00:00
J vanBemmel
8ae08b79b1 Update README.md - document -n2 option (#95) 2023-06-04 00:56:09 +02:00
Roman Dodin
9fa14cc506 Added container build workflow (#94)
* added container build workflow

* remove unneeded env var
2023-06-03 12:13:53 +02:00
J vanBemmel
92561f43af Add a line to usage (#92) 2023-05-26 13:03:59 +00:00
J vanBemmel
aee7adb698 Add support for Nokia SR Linux IP prefix lists / ACL filters (#91)
* Add support for Nokia SR Linux prefix sets

* Update tests

* Update docs

* Fix ACL prefix filter
2023-05-25 18:47:09 +02:00
Richard Laager
3c201684b6 Accept -3 as a no-op for bgpq3 compatibility (#90)
bgpq4 already assumes 32-bit ASN support.

Closes #89
2023-05-15 19:42:25 +02:00
Robert Scheck
b98ecd5d4d Add macOS to CI builds (#88) 2023-04-12 03:35:36 +09:00
James Bensley
d14db9515f Add github workflow for basic unit tests (#87)
Add github workflow for basic unit tests

authored-by: James Bensley <jwbensley@gmail.com>
2023-04-07 07:11:15 +09:00
67 changed files with 646 additions and 160 deletions

24
.github/images/alpine:3.Dockerfile vendored Normal file
View 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" ]

View File

@@ -2,8 +2,8 @@ ARG image=centos/centos:latest
FROM quay.io/$image
# Install dependencies
RUN yum update -y
RUN yum install -y autoconf automake gcc libtool make diffutils file gzip
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

1
.github/images/debian:trixie.Dockerfile vendored Symbolic link
View File

@@ -0,0 +1 @@
debian.Dockerfile

65
.github/workflows/build-container.yml vendored Normal file
View 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 }}

View File

@@ -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@v3
- 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'

View File

@@ -22,9 +22,9 @@ jobs:
language: [ 'cpp' ]
steps:
- name: Checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
- name: Build Application using script
@@ -33,6 +33,6 @@ jobs:
./configure
make
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
uses: github/codeql-action/analyze@v3
with:
category: "/language:${{matrix.language}}"

View File

@@ -9,23 +9,27 @@ jobs:
fail-fast: false
matrix:
dockerenv:
- debian:trixie
- debian:bookworm
- debian:bullseye
- debian:buster
- ubuntu:jammy
- ubuntu:focal
- ubuntu:bionic
- fedora/fedora:40
- fedora/fedora:39
- fedora/fedora:38
- fedora/fedora:37
- fedora/fedora:36
- centos/centos:stream9
- centos/centos:stream8
- centos/centos:7
- rockylinux/rockylinux:9
- rockylinux/rockylinux:8
- alpine:edge
- alpine:3.17
- alpine:3.19
steps:
- uses: actions/checkout@v3
- 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
View 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

17
CHANGES
View File

@@ -1,3 +1,20 @@
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

View File

@@ -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

View File

@@ -1,3 +1,9 @@
[![CI](https://github.com/bgp/bgpq4/actions/workflows/unit-tests.yml/badge.svg)](https://github.com/bgp/bgpq4/actions/workflows/unit-tests.yml)
<a href="https://repology.org/project/bgpq4/versions">
<img src="https://repology.org/badge/vertical-allrepos/bgpq4.svg" alt="Packaging status" align="right">
</a>
# NAME
**bgpq4** - bgp filtering automation tool
@@ -128,6 +134,10 @@ It's options are as follows:
> generate config for Nokia SR OS MD-CLI (Cisco IOS by default)
**-n2**
> generate config for Nokia SR Linux (Cisco IOS by default)
**-N**
> generate config for Nokia SR OS classic CLI (Cisco IOS by default).
@@ -447,6 +457,31 @@ Linux can be tuned in the following way:
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,
@@ -479,6 +514,12 @@ 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.
# TESTS
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.
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.
# AUTHORS
Alexandre Snarskii, Christian David, Claudio Jeker, Job Snijders,

View File

@@ -1 +1 @@
1.9
1.14

View File

@@ -109,10 +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
emit prefixes where the origin ASN is in the private ASN range (disabled by default).
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

View File

@@ -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,

View File

@@ -29,6 +29,7 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <netinet/tcp.h>
#include <assert.h>
#include <ctype.h>
@@ -183,7 +184,7 @@ int
bgpq_expander_add_as(struct bgpq_expander *b, char *as)
{
char *eoa;
uint32_t asno = 0;
uint32_t asno = 0;
struct asn_entry *asne;
if (!b || !as)
@@ -191,14 +192,14 @@ bgpq_expander_add_as(struct bgpq_expander *b, char *as)
asno = strtoul(as + 2, &eoa, 10);
if (eoa && *eoa != 0) {
sx_report(SX_ERROR,"Invalid symbol in AS number: '%c' in %s\n",
sx_report(SX_ERROR, "Invalid symbol in AS number: '%c' in %s\n",
*eoa, as);
return 0;
}
if (!expand_special_asn &&
(asno >= 4200000000ul || (asno >= 64496 && asno <= 65551))) {
sx_report(SX_ERROR,"Invalid AS number: %u\n", asno);
if (!expand_special_asn && (asno == 23456 || asno >= 4200000000ul
|| (asno >= 64496 && asno <= 65551))) {
sx_report(SX_ERROR, "Invalid AS number: %u\n", asno);
return 0;
}
@@ -1034,7 +1035,7 @@ bgpq_expand(struct bgpq_expander *b)
struct addrinfo hints, *res = NULL, *rp;
struct linger sl;
struct asn_entry *asne;
int fd = -1, err, ret, aquery = 0;
int fd = -1, err, ret, aquery = 0, nodelay = 0;
int slen;
sl.l_onoff = 1;
@@ -1074,15 +1075,20 @@ bgpq_expand(struct bgpq_expander *b)
fd = -1;
continue;
}
err = sx_maxsockbuf(fd, SO_SNDBUF);
if (err > 0) {
SX_DEBUG(debug_expander, "Acquired sendbuf of %i "
"bytes\n", err);
} else {
close(fd);
fd = -1;
continue;
}
socklen_t len = sizeof(nodelay);
getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &nodelay, &len);
SX_DEBUG(debug_expander, "TCP_NODELAY set to %i\n", nodelay);
nodelay = 0;
if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &nodelay,
sizeof(nodelay)) == -1)
SX_DEBUG(debug_expander, "Unable to set TCP_NODELAY on"
" socket: %s\n", strerror(errno));
getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &nodelay, &len);
SX_DEBUG(debug_expander, "TCP_NODELAY set to %i\n", nodelay);
break;
}

View File

@@ -62,7 +62,8 @@ typedef enum {
V_MIKROTIK6,
V_MIKROTIK7,
V_NOKIA_MD,
V_ARISTA
V_ARISTA,
V_NOKIA_SRL,
} bgpq_vendor_t;
typedef enum {
@@ -148,9 +149,6 @@ 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);
#endif

23
main.c
View File

@@ -65,6 +65,7 @@ usage(int ecode)
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"
@@ -92,6 +94,7 @@ usage(int ecode)
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");
@@ -198,8 +201,18 @@ main(int argc, char* argv[])
expander.sources=getenv("IRRD_SOURCES");
while ((c = getopt(argc, argv,
"467a:AbBdDEeF:S:jJKf:l:L:m:M:NnpW:r:R:G:H:tTh:UuwXsvz")) != EOF) {
"23467a:AbBdDEeF:S:jJKf:l:L:m:M:NnpW:r:R:G:H:tTh:UuwXsvz")) != EOF) {
switch (c) {
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) {
@@ -469,6 +482,7 @@ main(int argc, char* argv[])
case V_JUNIPER:
case V_NOKIA:
case V_NOKIA_MD:
case V_NOKIA_SRL:
expander.aswidth = 8;
break;
case V_BIRD:
@@ -488,6 +502,7 @@ main(int argc, char* argv[])
case V_JUNIPER:
case V_NOKIA:
case V_NOKIA_MD:
case V_NOKIA_SRL:
expander.aswidth = 8;
break;
}
@@ -560,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");
@@ -568,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");
@@ -576,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");

111
printer.c
View File

@@ -40,6 +40,13 @@
extern int debug_expander;
#define max(a,b) \
({ \
__typeof__ (a) _a = (a); \
__typeof__ (b) _b = (b); \
_a > _b ? _a : _b; \
})
static void
bgpq4_print_cisco_aspath(FILE *f, struct bgpq_expander *b)
{
@@ -82,7 +89,7 @@ bgpq4_print_cisco_aspath(FILE *f, struct bgpq_expander *b)
static void
bgpq4_print_cisco_xr_aspath(FILE *f, struct bgpq_expander *b)
{
int nc = 0, comma = 1;
int nc = 0, comma = 0;
struct asn_entry *asne, find, *res;
fprintf(f, "as-path-set %s", b->name);
@@ -91,6 +98,7 @@ bgpq4_print_cisco_xr_aspath(FILE *f, struct bgpq_expander *b)
if ((res = RB_FIND(asn_tree, &b->asnlist, &find)) != NULL) {
fprintf(f, "\n ios-regex '^%u(_%u)*$'", res->asn, res->asn);
RB_REMOVE(asn_tree, &b->asnlist, res);
comma = 1;
}
RB_FOREACH(asne, asn_tree, &b->asnlist) {
@@ -1370,6 +1378,60 @@ checkSon:
}
static void
bgpq4_print_nokia_srl_prefix(struct sx_radix_node *n, void *ff)
{
char prefix[128];
FILE *f = (FILE*)ff;
if (n->isGlue)
goto checkSon;
if (!f)
f = stdout;
sx_prefix_snprintf(n->prefix, prefix, sizeof(prefix));
if (!n->isAggregate) {
fprintf(f, " prefix %s mask-length-range exact { }\n", prefix);
} else {
fprintf(f, " prefix %s mask-length-range %u..%u { }\n", prefix,
max(n->aggregateLow,n->prefix->masklen), n->aggregateHi);
}
checkSon:
if (n->son)
bgpq4_print_nokia_srl_prefix(n->son, ff);
}
typedef struct {
FILE *f;
int seq;
} NOKIA_SRL_IPFILTER_PARAMS;
static void
bgpq4_print_nokia_srl_ipfilter(struct sx_radix_node *n, void *ff)
{
char prefix[128];
NOKIA_SRL_IPFILTER_PARAMS *params = (NOKIA_SRL_IPFILTER_PARAMS*) ff;
if (n->isGlue)
goto checkSon;
if (!params->f)
params->f = stdout;
sx_prefix_snprintf(n->prefix, prefix, sizeof(prefix));
fprintf(params->f, " entry %d {\n action { accept { } }\n match { source-ip { prefix %s } } }\n", params->seq, prefix);
params->seq += 10;
checkSon:
if (n->son) {
bgpq4_print_nokia_srl_ipfilter(n->son, ff);
}
}
static void
bgpq4_print_juniper_prefixlist(FILE *f, struct bgpq_expander *b)
{
@@ -1716,6 +1778,45 @@ bgpq4_print_nokia_md_ipprefixlist(FILE *f, struct bgpq_expander *b)
fprintf(f,"}\n");
}
static void
bgpq4_print_nokia_srl_prefixset(FILE *f, struct bgpq_expander *b)
{
bname = b->name ? b->name : "NN";
fprintf(f, "/routing-policy\ndelete prefix-set \"%s\"\n",
bname);
fprintf(f, "prefix-set \"%s\" {\n", bname);
if (!sx_radix_tree_empty(b->tree)) {
sx_radix_tree_foreach(b->tree, bgpq4_print_nokia_srl_prefix, f);
}
fprintf(f,"}\n");
}
static void
bgpq4_print_nokia_srl_aclipfilter(FILE *f, struct bgpq_expander *b)
{
bname = b->name ? b->name : "NN";
fprintf(f,"/acl \ndelete ipv%c-filter \"%s\"\n",
b->tree->family == AF_INET ? '4' : '6', bname);
fprintf(f,"ipv%c-filter \"%s\" {\n",
b->tree->family == AF_INET ? '4' : '6', bname);
if (!sx_radix_tree_empty(b->tree)) {
NOKIA_SRL_IPFILTER_PARAMS params = { f, 10 };
sx_radix_tree_foreach(b->tree, bgpq4_print_nokia_srl_ipfilter, &params);
} else {
fprintf(f,"# generated ipv%c-filter '%s' is empty\n",
b->tree->family == AF_INET ? '4' : '6', bname);
}
fprintf(f,"}\n");
}
static void
bgpq4_print_k6prefix(struct sx_radix_node *n, void *ff)
{
@@ -1770,7 +1871,7 @@ bgpq4_print_k7prefix(struct sx_radix_node *n, void *ff)
prefix, n->aggregateLow, n->aggregateHi);
else
fprintf(f,"/routing filter rule add chain=\""
"%s-%s\" rule=\"if (dst=%s) {accept}\"\n",
"%s-%s\" rule=\"if (dst==%s) {accept}\"\n",
bname ? bname : "NN",
n->prefix->family == AF_INET ? "V4" : "V6",
prefix);
@@ -1827,6 +1928,9 @@ bgpq4_print_prefixlist(FILE *f, struct bgpq_expander *b)
case V_NOKIA_MD:
bgpq4_print_nokia_md_ipprefixlist(f, b);
break;
case V_NOKIA_SRL:
bgpq4_print_nokia_srl_prefixset(f, b);
break;
case V_HUAWEI:
bgpq4_print_huawei_prefixlist(f, b);
break;
@@ -1863,6 +1967,9 @@ bgpq4_print_eacl(FILE *f, struct bgpq_expander *b)
case V_NOKIA_MD:
bgpq4_print_nokia_md_prefixlist(f, b);
break;
case V_NOKIA_SRL:
bgpq4_print_nokia_srl_aclipfilter(f, b);
break;
default:
sx_report(SX_FATAL, "unreachable point\n");
}

View File

@@ -1,117 +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"
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 (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;
}
}
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
return voptval;
}

90
tests/generate_outputs.sh Executable file
View 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"

View 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

View 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

View 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

View 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

View File

@@ -0,0 +1,4 @@
NN = [
192.31.196.0/24,
192.175.48.0/24
];

View File

@@ -0,0 +1,4 @@
NN = [
2001:4:112::/48,
2620:4f:8000::/48
];

View File

@@ -0,0 +1,3 @@
NN = [
112
];

View 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

View 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

View File

@@ -0,0 +1 @@
192.31.196.0/24 192.175.48.0/24

View File

@@ -0,0 +1 @@
2001:4:112::/48 2620:4f:8000::/48

View 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

View 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

View File

@@ -0,0 +1,2 @@
undo ip as-path-filter NN
ip as-path-filter NN permit ^112(_112)*$

View 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

View 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

View File

@@ -0,0 +1,3 @@
xpl as-path-list NN
regular ^112(_112)*$
end-list

View 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

View 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

View File

@@ -0,0 +1,2 @@
no ip as-path access-list NN
ip as-path access-list NN permit ^112(_112)*$

View File

@@ -0,0 +1,5 @@
no prefix-set NN
prefix-set NN
192.31.196.0/24,
192.175.48.0/24
end-set

View File

@@ -0,0 +1,5 @@
no prefix-set NN
prefix-set NN
2001:4:112::/48,
2620:4f:8000::/48
end-set

View File

@@ -0,0 +1,3 @@
as-path-set NN
ios-regex '^112(_112)*$'
end-set

View File

@@ -0,0 +1,4 @@
{ "NN": [
{ "prefix": "192.31.196.0\/24", "exact": true },
{ "prefix": "192.175.48.0\/24", "exact": true }
] }

View File

@@ -0,0 +1,4 @@
{ "NN": [
{ "prefix": "2001:4:112::\/48", "exact": true },
{ "prefix": "2620:4f:8000::\/48", "exact": true }
] }

View File

@@ -0,0 +1,3 @@
{"NN": [
112
]}

View File

@@ -0,0 +1,7 @@
policy-options {
replace:
prefix-list NN {
192.31.196.0/24;
192.175.48.0/24;
}
}

View File

@@ -0,0 +1,7 @@
policy-options {
replace:
prefix-list NN {
2001:4:112::/48;
2620:4f:8000::/48;
}
}

View File

@@ -0,0 +1,6 @@
policy-options {
replace:
as-path-group NN {
as-path a0 "^112(112)*$";
}
}

View File

@@ -0,0 +1,4 @@
prefix {
192.31.196.0/24
192.175.48.0/24
}

View File

@@ -0,0 +1,4 @@
prefix {
2001:4:112::/48
2620:4f:8000::/48
}

View File

@@ -0,0 +1 @@
allow from AS 112 AS 112

View 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

View 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

View 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}"

View 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}"

View 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 { }
}

View 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 { }
}

View 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

View 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

View 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

View 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 {
}
}

View 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 {
}
}

View File

@@ -0,0 +1,7 @@
/configure policy-options
delete as-path-group "NN"
as-path-group "NN" {
entry 1 {
expression "112+"
}
}