mirror of
https://git.FreeBSD.org/ports.git
synced 2025-01-06 06:30:19 +00:00
net/openbgpd: revert upgrade from 6.5p0 to 5.2.20121209
- openbgpd version 6.5p0 was the "portable" version, which specifically does *not* support kernel routing updates. - Therefore this is only suitable for route servers/collectors, not for production use in routers. This significantly violates POLA :) PR: 213445 Submitted by: Oliver H <oliver@watershed.co.uk>
This commit is contained in:
parent
21a86ae3be
commit
713c2289b8
Notes:
svn2git
2021-03-31 03:12:20 +00:00
svn path=/head/; revision=503421
@ -1,9 +1,13 @@
|
||||
# $FreeBSD$
|
||||
|
||||
PORTNAME= openbgpd
|
||||
PORTVERSION= 6.5p0
|
||||
PORTVERSION= 5.2.20121209
|
||||
PORTREVISION= 3
|
||||
PORTEPOCH= 1
|
||||
CATEGORIES= net
|
||||
MASTER_SITES= OPENBSD/OpenBGPD
|
||||
DISTNAME= ${PORTNAME}-4.6
|
||||
DIST_SUBDIR= ${PORTNAME}
|
||||
|
||||
MAINTAINER= hrs@FreeBSD.org
|
||||
COMMENT= Free implementation of the Border Gateway Protocol, Version 4
|
||||
@ -11,21 +15,27 @@ COMMENT= Free implementation of the Border Gateway Protocol, Version 4
|
||||
LICENSE= ISCL
|
||||
LICENSE_FILE= ${FILESDIR}/COPYING
|
||||
|
||||
USES= autoreconf libtool uidfix
|
||||
CONFLICTS= zebra-[0-9]* quagga-[0-9]*
|
||||
|
||||
USES= tar:tgz uidfix
|
||||
USE_RC_SUBR= ${PORTNAME}
|
||||
|
||||
GNU_CONFIGURE= yes
|
||||
|
||||
NO_WRKSUBDIR= yes
|
||||
PLIST_FILES= sbin/bgpctl sbin/bgpd man/man5/bgpd.conf.5.gz \
|
||||
man/man8/bgpctl.8.gz man/man8/bgpd.8.gz
|
||||
SUB_FILES= pkg-message
|
||||
|
||||
USERS= _bgpd
|
||||
GROUPS= _bgpd
|
||||
|
||||
CONFLICTS= zebra-[0-9]* quagga-[0-9]*
|
||||
|
||||
OPTIONS_DEFINE= IPV6LLPEER
|
||||
OPTIONS_DEFAULT= IPV6LLPEER
|
||||
IPV6LLPEER_DESC= Support nexthop using IPv6 link-local address
|
||||
OPTIONS_DEFINE= IPV6LLPEER
|
||||
OPTIONS_DEFAULT=IPV6LLPEER
|
||||
IPV6LLPEER_DESC=Support nexthop using IPv6 link-local address
|
||||
IPV6LLPEER_MAKE_ARGS= -DIPV6_LINKLOCAL_PEER
|
||||
|
||||
post-patch:
|
||||
@${REINPLACE_CMD} -e "s|%%PREFIX%%|${PREFIX}|g" \
|
||||
${WRKSRC}/bgpd/bgpd.8 \
|
||||
${WRKSRC}/bgpd/bgpd.conf.5 \
|
||||
${WRKSRC}/bgpctl/bgpctl.8
|
||||
|
||||
.include <bsd.port.mk>
|
||||
|
@ -1,3 +1,3 @@
|
||||
TIMESTAMP = 1556692508
|
||||
SHA256 (openbgpd-6.5p0.tar.gz) = 20c1a40bafcbbea60c4ecc6dd2e87fcba6847bfad62739b705a3806b6b442a56
|
||||
SIZE (openbgpd-6.5p0.tar.gz) = 677691
|
||||
SHA256 (openbgpd/openbgpd-4.6.tgz) = d9a0a3542e5ec744889ca12871f01aa1d86f12844e093010f37d0601796e15cf
|
||||
SIZE (openbgpd/openbgpd-4.6.tgz) = 168197
|
||||
|
12
net/openbgpd/files/patch-Makefile
Normal file
12
net/openbgpd/files/patch-Makefile
Normal file
@ -0,0 +1,12 @@
|
||||
Index: Makefile
|
||||
===================================================================
|
||||
RCS file: Makefile
|
||||
diff -N Makefile
|
||||
--- /dev/null 1 Jan 1970 00:00:00 -0000
|
||||
+++ Makefile 30 Jun 2009 07:07:55 -0000 1.2
|
||||
@@ -0,0 +1,5 @@
|
||||
+# $hrs: openbgpd/Makefile,v 1.2 2009/06/30 07:07:55 hrs Exp $
|
||||
+
|
||||
+SUBDIR= bgpd bgpctl
|
||||
+
|
||||
+.include <bsd.subdir.mk>
|
@ -1,20 +0,0 @@
|
||||
--- Makefile.am.orig 2019-05-01 11:22:14 UTC
|
||||
+++ Makefile.am
|
||||
@@ -19,13 +19,14 @@
|
||||
EXTRA_DIST = README.md VERSION bgpd.conf
|
||||
|
||||
install-data-hook:
|
||||
- @if [ ! -d "$(DESTDIR)$(localstatedir)/run" ]; then \
|
||||
+ if [ ! -d "$(DESTDIR)$(localstatedir)/run" ]; then \
|
||||
$(INSTALL) -m 755 -d "$(DESTDIR)$(localstatedir)/run"; \
|
||||
fi
|
||||
- @if [ ! -d "$(DESTDIR)$(sysconfdir)" ]; then \
|
||||
+ if [ ! -d "$(DESTDIR)$(sysconfdir)" ]; then \
|
||||
$(INSTALL) -m 755 -d "$(DESTDIR)$(sysconfdir)"; \
|
||||
fi
|
||||
- @if [ ! -f "$(DESTDIR)$(sysconfdir)/bgpd.conf" ]; then \
|
||||
+ $(INSTALL) -m 644 "$(srcdir)/bgpd.conf" "$(DESTDIR)$(sysconfdir)/bgpd.conf.sample"; \
|
||||
+ if [ ! -f "$(DESTDIR)$(sysconfdir)/bgpd.conf" ]; then \
|
||||
$(INSTALL) -m 644 "$(srcdir)/bgpd.conf" "$(DESTDIR)$(sysconfdir)/bgpd.conf"; \
|
||||
else \
|
||||
echo; \
|
12
net/openbgpd/files/patch-Makefile.inc
Normal file
12
net/openbgpd/files/patch-Makefile.inc
Normal file
@ -0,0 +1,12 @@
|
||||
Index: Makefile.inc
|
||||
===================================================================
|
||||
RCS file: Makefile.inc
|
||||
diff -N Makefile.inc
|
||||
--- /dev/null 1 Jan 1970 00:00:00 -0000
|
||||
+++ Makefile.inc 16 May 2014 01:06:14 -0000 1.5
|
||||
@@ -0,0 +1,5 @@
|
||||
+# $hrs: openbgpd/Makefile.inc,v 1.5 2014/05/16 01:06:14 hrs Exp $
|
||||
+
|
||||
+PREFIX?= /usr/local
|
||||
+BINDIR?= ${PREFIX}/sbin
|
||||
+MANDIR?= ${PREFIX}/man/man
|
31
net/openbgpd/files/patch-bgpctl_Makefile
Normal file
31
net/openbgpd/files/patch-bgpctl_Makefile
Normal file
@ -0,0 +1,31 @@
|
||||
Index: bgpctl/Makefile
|
||||
===================================================================
|
||||
RCS file: /home/cvs/private/hrs/openbgpd/bgpctl/Makefile,v
|
||||
retrieving revision 1.1.1.1
|
||||
retrieving revision 1.4
|
||||
diff -u -p -r1.1.1.1 -r1.4
|
||||
--- bgpctl/Makefile 30 Jun 2009 05:46:15 -0000 1.1.1.1
|
||||
+++ bgpctl/Makefile 13 Oct 2012 18:35:56 -0000 1.4
|
||||
@@ -1,17 +1,18 @@
|
||||
# $OpenBSD: Makefile,v 1.10 2007/12/20 17:08:48 henning Exp $
|
||||
|
||||
-.PATH: ${.CURDIR}/../bgpd
|
||||
+.PATH: ${.CURDIR}/../bgpd ${.CURDIR}/../openbsd-compat
|
||||
|
||||
PROG= bgpctl
|
||||
-SRCS= bgpctl.c parser.c buffer.c imsg.c util.c timer.c
|
||||
+SRCS= bgpctl.c parser.c util.c timer.c
|
||||
SRCS+= irrfilter.c whois.c irr_asset.c irr_prefix.c irr_output.c
|
||||
-SRCS+= irr_parser.c
|
||||
+SRCS+= irr_parser.c mrtparser.c
|
||||
+SRCS+= fmt_scaled.c imsg.c imsg-buffer.c
|
||||
CFLAGS+= -Wall
|
||||
CFLAGS+= -Wstrict-prototypes -Wmissing-prototypes
|
||||
CFLAGS+= -Wmissing-declarations
|
||||
CFLAGS+= -Wshadow -Wpointer-arith -Wcast-qual
|
||||
CFLAGS+= -Wsign-compare
|
||||
-CFLAGS+= -I${.CURDIR} -I${.CURDIR}/../bgpd
|
||||
+CFLAGS+= -I${.CURDIR} -I${.CURDIR}/../bgpd -I${.CURDIR}/../openbsd-compat
|
||||
MAN= bgpctl.8
|
||||
LDADD= -lutil
|
||||
DPADD+= ${LIBUTIL}
|
287
net/openbgpd/files/patch-bgpctl_bgpctl.8
Normal file
287
net/openbgpd/files/patch-bgpctl_bgpctl.8
Normal file
@ -0,0 +1,287 @@
|
||||
Index: bgpctl/bgpctl.8
|
||||
===================================================================
|
||||
RCS file: /home/cvs/private/hrs/openbgpd/bgpctl/bgpctl.8,v
|
||||
retrieving revision 1.1.1.6
|
||||
retrieving revision 1.6
|
||||
diff -u -p -r1.1.1.6 -r1.6
|
||||
--- bgpctl/bgpctl.8 14 Feb 2010 20:20:13 -0000 1.1.1.6
|
||||
+++ bgpctl/bgpctl.8 13 Oct 2012 18:35:56 -0000 1.6
|
||||
@@ -1,4 +1,4 @@
|
||||
-.\" $OpenBSD: bgpctl.8,v 1.49 2009/06/06 06:11:17 claudio Exp $
|
||||
+.\" $OpenBSD: bgpctl.8,v 1.59 2012/05/27 20:49:42 jmc Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2003 Henning Brauer <henning@openbsd.org>
|
||||
.\"
|
||||
@@ -14,7 +14,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
-.Dd $Mdocdate: June 6 2009 $
|
||||
+.Dd $Mdocdate: May 27 2012 $
|
||||
.Dt BGPCTL 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@@ -32,8 +32,7 @@ The
|
||||
program controls the
|
||||
.Xr bgpd 8
|
||||
daemon.
|
||||
-Commands to switch between displays may be abbreviated to the
|
||||
-minimum unambiguous prefix; for example,
|
||||
+Commands may be abbreviated to the minimum unambiguous prefix; for example,
|
||||
.Cm s s
|
||||
for
|
||||
.Cm show summary .
|
||||
@@ -53,11 +52,19 @@ to communicate with
|
||||
.Pp
|
||||
The commands are as follows:
|
||||
.Bl -tag -width xxxxxx
|
||||
-.It Cm fib couple
|
||||
-Insert the learned routes into the Forwarding Information Base
|
||||
+.It Xo
|
||||
+.Cm fib
|
||||
+.Op Cm table Ar number
|
||||
+.Cm couple
|
||||
+.Xc
|
||||
+Insert the learned routes into the specified Forwarding Information Base
|
||||
a.k.a. the kernel routing table.
|
||||
-.It Cm fib decouple
|
||||
-Remove the learned routes from the Forwarding Information Base
|
||||
+.It Xo
|
||||
+.Cm fib
|
||||
+.Op Cm table Ar number
|
||||
+.Cm decouple
|
||||
+.Xc
|
||||
+Remove the learned routes from the specified Forwarding Information Base
|
||||
a.k.a. the kernel routing table.
|
||||
.It Xo
|
||||
.Cm irrfilter
|
||||
@@ -79,7 +86,15 @@ The options are as follows:
|
||||
Use
|
||||
.Ar directory
|
||||
to write the filter files to.
|
||||
+.It Fl 4
|
||||
+Fetch only IPv4 prefixes from the registry.
|
||||
+.It Fl 6
|
||||
+Fetch only IPv6 prefixes from the registry.
|
||||
.El
|
||||
+.It Cm log brief
|
||||
+Disable verbose debug logging.
|
||||
+.It Cm log verbose
|
||||
+Enable verbose debug logging.
|
||||
.It Cm neighbor Ar peer Cm up
|
||||
Take the BGP session to the specified neighbor up.
|
||||
.Ar peer
|
||||
@@ -98,12 +113,21 @@ Note that the neighbor is not obliged to
|
||||
all, even if it announced the route refresh capability.
|
||||
.Ar peer
|
||||
may be the neighbor's address or description.
|
||||
-.It Cm network add Ar prefix
|
||||
+.It Cm network add Ar prefix Op Ar arguments
|
||||
Add the specified prefix to the list of announced networks.
|
||||
+It is possible to set various path attributes with additional
|
||||
+.Ar arguments .
|
||||
.It Cm network delete Ar prefix
|
||||
Remove the specified prefix from the list of announced networks.
|
||||
.It Cm network flush
|
||||
Remove all dynamically added prefixes from the list of announced networks.
|
||||
+.It Cm network mrt file Ar file filter
|
||||
+Import networks from an MRT table dump for debugging purposes.
|
||||
+.Ar filter
|
||||
+can be specified similarly to the
|
||||
+.Ar show mrt
|
||||
+command.
|
||||
+Only networks matching the filter will be imported.
|
||||
.It Cm network show Ar family
|
||||
Show all announced networks.
|
||||
.Ar family ,
|
||||
@@ -122,7 +146,7 @@ view of the Forwarding Information Base.
|
||||
can be an IP address, in which case the route to this address is shown,
|
||||
or a flag:
|
||||
.Pp
|
||||
-.Bl -tag -width connected -compact
|
||||
+.Bl -tag -width tableXnumber -compact
|
||||
.It Cm connected
|
||||
Show only connected routes.
|
||||
.It Cm static
|
||||
@@ -133,9 +157,81 @@ Show only routes originating from
|
||||
itself.
|
||||
.It Cm nexthop
|
||||
Show only routes required to reach a BGP nexthop.
|
||||
+.It Cm inet
|
||||
+Show only IPv4 routes.
|
||||
+.It Cm inet6
|
||||
+Show only IPv6 routes.
|
||||
+.It Cm table Ar number
|
||||
+Show the routing table with ID
|
||||
+.Ar number
|
||||
+instead of the default routing table with ID 0.
|
||||
.El
|
||||
.It Cm show interfaces
|
||||
Show the interface states.
|
||||
+.It Xo
|
||||
+.Cm show mrt
|
||||
+.Op Ar options
|
||||
+.Ar filter
|
||||
+.Xc
|
||||
+Show routes from an MRT table dump file.
|
||||
+.Ar filter
|
||||
+can be an IP address, a CIDR prefix, an AS filter, a combination or nothing:
|
||||
+.Pp
|
||||
+.Bl -tag -width "address/len all" -compact
|
||||
+.It Ar address
|
||||
+Show best matching route for address.
|
||||
+.It Ar address Ns Li / Ns Ar len
|
||||
+Show RIB entry for this CIDR prefix.
|
||||
+.It Xo
|
||||
+.Ar address Ns Li / Ns Ar len
|
||||
+.Cm all
|
||||
+.Xc
|
||||
+Show all entries in the specified range.
|
||||
+.\".It Ar address/len Cm longer-prefixes
|
||||
+.It Cm as Ar as
|
||||
+Show all entries with
|
||||
+.Ar as
|
||||
+anywhere in the AS path.
|
||||
+.It Cm empty-as
|
||||
+Show all entries that are internal routes with no AS's in the AS path.
|
||||
+.It Cm neighbor Ar ip
|
||||
+Show only entries from the specified peer.
|
||||
+.It Cm peer-as Ar as
|
||||
+Show all entries with
|
||||
+.Ar as
|
||||
+as leftmost AS.
|
||||
+.It Cm source-as Ar as
|
||||
+Show all entries with
|
||||
+.Ar as
|
||||
+as rightmost AS.
|
||||
+.It Cm transit-as Ar as
|
||||
+Show all entries with
|
||||
+.Ar as
|
||||
+anywhere but rightmost.
|
||||
+.El
|
||||
+.Pp
|
||||
+Additionally, the following
|
||||
+.Ar options
|
||||
+are defined:
|
||||
+.Pp
|
||||
+.Bl -tag -width "file name" -compact
|
||||
+.It Cm detail
|
||||
+Show more detailed output for matching routes.
|
||||
+.It Ar family
|
||||
+Limit the output to the given address family.
|
||||
+.It Cm file Ar name
|
||||
+Read the MRT dump from file
|
||||
+.Ar name
|
||||
+instead of using stdin.
|
||||
+.El
|
||||
+.Pp
|
||||
+Multiple options and filters can be used at the same time.
|
||||
+.It Cm show summary
|
||||
+Show a list of all neighbors, including information about the session state
|
||||
+and message counters.
|
||||
+.It Cm show summary terse
|
||||
+Show a list of all neighbors, including information about the session state,
|
||||
+in a terse format.
|
||||
.It Cm show neighbor Ar peer modifier
|
||||
Show detailed information about the neighbor identified by
|
||||
.Ar peer ,
|
||||
@@ -183,33 +279,33 @@ Show all entries in the specified range.
|
||||
Show all entries with
|
||||
.Ar as
|
||||
anywhere in the AS path.
|
||||
-.It Cm source-as Ar as
|
||||
-Show all entries with
|
||||
-.Ar as
|
||||
-as rightmost AS.
|
||||
-.It Cm transit-as Ar as
|
||||
-Show all entries with
|
||||
-.Ar as
|
||||
-anywhere but rightmost.
|
||||
-.It Cm peer-as Ar as
|
||||
-Show all entries with
|
||||
-.Ar as
|
||||
-as leftmost AS.
|
||||
-.It Cm empty-as
|
||||
-Show all entries that are internal routes with no AS's in the AS path.
|
||||
.It Cm community Ar community
|
||||
Show all entries with community
|
||||
.Ar community .
|
||||
+.It Cm empty-as
|
||||
+Show all entries that are internal routes with no AS's in the AS path.
|
||||
+.It Cm memory
|
||||
+Show RIB memory statistics.
|
||||
.It Cm neighbor Ar peer
|
||||
Show only entries from the specified peer.
|
||||
-.It Cm table Ar rib
|
||||
-Show only entries from the specified RIB table.
|
||||
+.It Cm peer-as Ar as
|
||||
+Show all entries with
|
||||
+.Ar as
|
||||
+as leftmost AS.
|
||||
+.It Cm source-as Ar as
|
||||
+Show all entries with
|
||||
+.Ar as
|
||||
+as rightmost AS.
|
||||
.It Cm summary
|
||||
This is the same as the
|
||||
.Ic show summary
|
||||
command.
|
||||
-.It Cm memory
|
||||
-Show RIB memory statistics.
|
||||
+.It Cm table Ar rib
|
||||
+Show only entries from the specified RIB table.
|
||||
+.It Cm transit-as Ar as
|
||||
+Show all entries with
|
||||
+.Ar as
|
||||
+anywhere but rightmost.
|
||||
.El
|
||||
.Pp
|
||||
Additionally, the following
|
||||
@@ -217,8 +313,10 @@ Additionally, the following
|
||||
are defined:
|
||||
.Pp
|
||||
.Bl -tag -width "detail" -compact
|
||||
+.It Cm selected
|
||||
+Show only selected routes.
|
||||
.It Cm detail
|
||||
-Show more detailed output for matched routes.
|
||||
+Show more detailed output for matching routes.
|
||||
.It Ar family
|
||||
Limit the output to the given address family.
|
||||
.It Cm in
|
||||
@@ -243,10 +341,12 @@ and message counters.
|
||||
.It Cm show summary terse
|
||||
Show a list of all neighbors, including information about the session state,
|
||||
in a terse format.
|
||||
+.It Cm show tables
|
||||
+Show a list of all currently loaded fib routing tables.
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -width "/var/run/bgpd.sockXXX" -compact
|
||||
-.It Pa /etc/bgpd.conf
|
||||
+.It Pa %%PREFIX%%/etc/bgpd.conf
|
||||
default
|
||||
.Xr bgpd 8
|
||||
configuration file
|
||||
@@ -260,10 +360,19 @@ control socket
|
||||
.Xr bgpd 8 ,
|
||||
.Xr bgplg 8 ,
|
||||
.Xr bgplgsh 8
|
||||
+.Sh STANDARDS
|
||||
.Rs
|
||||
-.%R RFC 2622
|
||||
-.%T "Routing Policy Specification Language (RPSL)"
|
||||
+.%A C. Alaettinoglu
|
||||
+.%A C. Villamizar
|
||||
+.%A E. Gerich
|
||||
+.%A D. Kessens
|
||||
+.%A D. Meyer
|
||||
+.%A T. Bates
|
||||
+.%A D. Karrenberg
|
||||
+.%A M. Terpstra
|
||||
.%D June 1999
|
||||
+.%R RFC 2622
|
||||
+.%T Routing Policy Specification Language (RPSL)
|
||||
.Re
|
||||
.Sh HISTORY
|
||||
The
|
1529
net/openbgpd/files/patch-bgpctl_bgpctl.c
Normal file
1529
net/openbgpd/files/patch-bgpctl_bgpctl.c
Normal file
File diff suppressed because it is too large
Load Diff
14
net/openbgpd/files/patch-bgpctl_irr_asset.c
Normal file
14
net/openbgpd/files/patch-bgpctl_irr_asset.c
Normal file
@ -0,0 +1,14 @@
|
||||
Index: bgpctl/irr_asset.c
|
||||
===================================================================
|
||||
RCS file: /home/cvs/private/hrs/openbgpd/bgpctl/irr_asset.c,v
|
||||
retrieving revision 1.1.1.2
|
||||
retrieving revision 1.1.1.3
|
||||
diff -u -p -r1.1.1.2 -r1.1.1.3
|
||||
--- bgpctl/irr_asset.c 9 Jul 2009 16:49:55 -0000 1.1.1.2
|
||||
+++ bgpctl/irr_asset.c 13 Oct 2012 18:22:52 -0000 1.1.1.3
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* $OpenBSD: irr_asset.c,v 1.8 2009/04/14 21:10:54 jj Exp $ */
|
||||
+/* $OpenBSD: irr_asset.c,v 1.7 2007/03/31 12:46:55 henning Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Henning Brauer <henning@openbsd.org>
|
14
net/openbgpd/files/patch-bgpctl_irr_output.c
Normal file
14
net/openbgpd/files/patch-bgpctl_irr_output.c
Normal file
@ -0,0 +1,14 @@
|
||||
Index: bgpctl/irr_output.c
|
||||
===================================================================
|
||||
RCS file: /home/cvs/private/hrs/openbgpd/bgpctl/irr_output.c,v
|
||||
retrieving revision 1.1.1.1
|
||||
retrieving revision 1.1.1.2
|
||||
diff -u -p -r1.1.1.1 -r1.1.1.2
|
||||
--- bgpctl/irr_output.c 30 Jun 2009 05:46:15 -0000 1.1.1.1
|
||||
+++ bgpctl/irr_output.c 13 Oct 2012 18:22:52 -0000 1.1.1.2
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* $OpenBSD: irr_output.c,v 1.13 2007/03/05 17:28:21 henning Exp $ */
|
||||
+/* $OpenBSD: irr_output.c,v 1.12 2007/03/05 15:02:05 henning Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Henning Brauer <henning@openbsd.org>
|
48
net/openbgpd/files/patch-bgpctl_irr_parser.c
Normal file
48
net/openbgpd/files/patch-bgpctl_irr_parser.c
Normal file
@ -0,0 +1,48 @@
|
||||
Index: bgpctl/irr_parser.c
|
||||
===================================================================
|
||||
RCS file: /home/cvs/private/hrs/openbgpd/bgpctl/irr_parser.c,v
|
||||
retrieving revision 1.1.1.5
|
||||
retrieving revision 1.5
|
||||
diff -u -p -r1.1.1.5 -r1.5
|
||||
--- bgpctl/irr_parser.c 14 Feb 2010 20:20:14 -0000 1.1.1.5
|
||||
+++ bgpctl/irr_parser.c 13 Oct 2012 18:35:56 -0000 1.5
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* $OpenBSD: irr_parser.c,v 1.8 2007/03/05 22:34:08 henning Exp $ */
|
||||
+/* $OpenBSD: irr_parser.c,v 1.9 2009/09/08 15:40:25 claudio Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Henning Brauer <henning@openbsd.org>
|
||||
@@ -81,6 +81,7 @@ parse_response(FILE *f, enum qtype qtype
|
||||
return (-1);
|
||||
break;
|
||||
case QTYPE_ROUTE:
|
||||
+ case QTYPE_ROUTE6:
|
||||
if ((n = parse_route(key, val)) == -1)
|
||||
return (-1);
|
||||
break;
|
||||
@@ -281,7 +282,7 @@ parse_policy(char *key, char *val)
|
||||
!isdigit(tok[2]))
|
||||
errx(1, "peering spec \"%s\": format "
|
||||
"error, AS expected", tok);
|
||||
- pi->peer_as = strtonum(tok + 2, 1, USHRT_MAX,
|
||||
+ pi->peer_as = strtonum(tok + 2, 1, UINT_MAX,
|
||||
&errstr);
|
||||
if (errstr)
|
||||
errx(1, "peering spec \"%s\": format "
|
||||
@@ -407,11 +408,13 @@ parse_asset(char *key, char *val)
|
||||
int
|
||||
parse_route(char *key, char *val)
|
||||
{
|
||||
- if (strcmp(key, "route")) /* ignore everything else */
|
||||
+ if (strcmp(key, "route") && strcmp(key, "route6"))
|
||||
+ /* ignore everything else */
|
||||
return (0);
|
||||
|
||||
- /* route is single-value, but seen trailing , in the wild */
|
||||
- if (strlen(val) > 0 && val[strlen(val) - 1] == ',')
|
||||
+ /* route is single-value, but seen trailing , and \r in the wild */
|
||||
+ if (strlen(val) > 0 && (val[strlen(val) - 1] == ',' ||
|
||||
+ val[strlen(val) - 1] == '\r'))
|
||||
val[strlen(val) - 1] = '\0';
|
||||
|
||||
return (prefixset_addmember(val));
|
157
net/openbgpd/files/patch-bgpctl_irr_prefix.c
Normal file
157
net/openbgpd/files/patch-bgpctl_irr_prefix.c
Normal file
@ -0,0 +1,157 @@
|
||||
Index: bgpctl/irr_prefix.c
|
||||
===================================================================
|
||||
RCS file: /home/cvs/private/hrs/openbgpd/bgpctl/irr_prefix.c,v
|
||||
retrieving revision 1.1.1.5
|
||||
retrieving revision 1.1.1.8
|
||||
diff -u -p -r1.1.1.5 -r1.1.1.8
|
||||
--- bgpctl/irr_prefix.c 14 Feb 2010 20:20:14 -0000 1.1.1.5
|
||||
+++ bgpctl/irr_prefix.c 13 Oct 2012 18:22:52 -0000 1.1.1.8
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* $OpenBSD: irr_prefix.c,v 1.15 2007/05/27 18:54:25 henning Exp $ */
|
||||
+/* $OpenBSD: irr_prefix.c,v 1.17 2009/09/08 16:11:36 sthen Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Henning Brauer <henning@openbsd.org>
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "irrfilter.h"
|
||||
+#include "bgpd.h"
|
||||
|
||||
void prefixset_aggregate(struct prefix_set *);
|
||||
int prefix_aggregate(struct irr_prefix *, const struct irr_prefix *);
|
||||
@@ -63,7 +64,11 @@ prefixset_get(char *as)
|
||||
fflush(stdout);
|
||||
}
|
||||
curpfxs = pfxs;
|
||||
- if (whois(as, QTYPE_ROUTE) == -1)
|
||||
+ if ((irrflags & F_IPV4) && whois(as, QTYPE_ROUTE) == -1)
|
||||
+ errx(1, "whois error, prefixset_get %s", as);
|
||||
+ if ((irrflags & F_IPV6) && whois(as, QTYPE_ROUTE6) == -1)
|
||||
+ errx(1, "whois error, prefixset_get %s", as);
|
||||
+ if (whois(as, QTYPE_ROUTE6) == -1)
|
||||
errx(1, "whois error, prefixset_get %s", as);
|
||||
curpfxs = NULL;
|
||||
if (irrverbose >= 3)
|
||||
@@ -80,9 +85,11 @@ prefixset_addmember(char *s)
|
||||
void *p;
|
||||
u_int i;
|
||||
struct irr_prefix *pfx;
|
||||
- int len;
|
||||
+ int len, ret;
|
||||
+ char *slash;
|
||||
+ const char *errstr;
|
||||
|
||||
- if (strchr(s, '/') == NULL) {
|
||||
+ if ((slash = strchr(s, '/')) == NULL) {
|
||||
fprintf(stderr, "%s: prefix %s does not have the len "
|
||||
"specified, ignoring\n", curpfxs->as, s);
|
||||
return (0);
|
||||
@@ -92,17 +99,26 @@ prefixset_addmember(char *s)
|
||||
err(1, "prefixset_addmember calloc");
|
||||
|
||||
if ((len = inet_net_pton(AF_INET, s, &pfx->addr.in,
|
||||
- sizeof(pfx->addr.in))) == -1) {
|
||||
- if (errno == ENOENT) {
|
||||
- fprintf(stderr, "%s: prefix \"%s\": parse error\n",
|
||||
+ sizeof(pfx->addr.in))) != -1) {
|
||||
+ pfx->af = AF_INET;
|
||||
+ } else {
|
||||
+ len = strtonum(slash + 1, 0, 128, &errstr);
|
||||
+ if (errstr)
|
||||
+ errx(1, "prefixset_addmember %s prefix %s: prefixlen "
|
||||
+ "is %s", curpfxs->as, s, errstr);
|
||||
+ *slash = '\0';
|
||||
+
|
||||
+ if ((ret = inet_pton(AF_INET6, s, &pfx->addr.in6)) == -1)
|
||||
+ err(1, "prefixset_addmember %s prefix \"%s\"",
|
||||
curpfxs->as, s);
|
||||
+ else if (ret == 0) {
|
||||
+ fprintf(stderr, "prefixset_addmember %s prefix \"%s\": "
|
||||
+ "No matching address family found", curpfxs->as, s);
|
||||
+ free(pfx);
|
||||
return (0);
|
||||
- } else
|
||||
- err(1, "prefixset_addmember %s inet_net_pton \"%s\"",
|
||||
- curpfxs->as, s);
|
||||
+ }
|
||||
+ pfx->af = AF_INET6;
|
||||
}
|
||||
-
|
||||
- pfx->af = AF_INET;
|
||||
pfx->len = pfx->maxlen = len;
|
||||
|
||||
/* yes, there are dupes... e. g. from multiple sources */
|
||||
@@ -175,24 +191,47 @@ prefixset_aggregate(struct prefix_set *p
|
||||
int
|
||||
prefix_aggregate(struct irr_prefix *a, const struct irr_prefix *b)
|
||||
{
|
||||
- in_addr_t mask;
|
||||
+ in_addr_t mask;
|
||||
+ struct in6_addr ma;
|
||||
+ struct in6_addr mb;
|
||||
|
||||
if (a->len == 0)
|
||||
return (1);
|
||||
|
||||
- mask = htonl(0xffffffff << (32 - a->len));
|
||||
+ if (a->af != b->af)
|
||||
+ /* We cannot aggregate addresses of different families. */
|
||||
+ return (0);
|
||||
|
||||
- if ((a->addr.in.s_addr & mask) == (b->addr.in.s_addr & mask))
|
||||
- return (1);
|
||||
+ if (a->af == AF_INET) {
|
||||
+ mask = htonl(prefixlen2mask(a->len));
|
||||
+ if ((a->addr.in.s_addr & mask) == (b->addr.in.s_addr & mask))
|
||||
+ return (1);
|
||||
+ } else if (a->af == AF_INET6) {
|
||||
+ inet6applymask(&ma, &a->addr.in6, a->len);
|
||||
+ inet6applymask(&mb, &b->addr.in6, a->len);
|
||||
+ if (IN6_ARE_ADDR_EQUAL(&ma, &mb))
|
||||
+ return (1);
|
||||
+ }
|
||||
|
||||
- /* see wether we can fold them in one */
|
||||
+ /* see whether we can fold them in one */
|
||||
if (a->len == b->len && a->len > 1) {
|
||||
- mask = htonl(0xffffffff << (32 - (a->len - 1)));
|
||||
- if ((a->addr.in.s_addr & mask) ==
|
||||
- (b->addr.in.s_addr & mask)) {
|
||||
- a->len--;
|
||||
- a->addr.in.s_addr &= mask;
|
||||
- return (1);
|
||||
+ if (a->af == AF_INET) {
|
||||
+ mask = htonl(prefixlen2mask(a->len - 1));
|
||||
+ if ((a->addr.in.s_addr & mask) ==
|
||||
+ (b->addr.in.s_addr & mask)) {
|
||||
+ a->len--;
|
||||
+ a->addr.in.s_addr &= mask;
|
||||
+ return (1);
|
||||
+ }
|
||||
+ } else if (a->af == AF_INET6) {
|
||||
+ inet6applymask(&ma, &a->addr.in6, a->len - 1);
|
||||
+ inet6applymask(&mb, &b->addr.in6, a->len - 1);
|
||||
+
|
||||
+ if (IN6_ARE_ADDR_EQUAL(&ma, &mb)) {
|
||||
+ a->len--;
|
||||
+ memcpy(&a->addr.in6, &ma, sizeof(ma));
|
||||
+ return (1);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,6 +258,13 @@ irr_prefix_cmp(const void *a, const void
|
||||
if (ntohl(pa->addr.in.s_addr) >
|
||||
ntohl(pb->addr.in.s_addr))
|
||||
return (1);
|
||||
+ } else if (pa->af == AF_INET6) {
|
||||
+ for (r = 0; r < 16; r++) {
|
||||
+ if (pa->addr.in6.s6_addr[r] < pb->addr.in6.s6_addr[r])
|
||||
+ return (-1);
|
||||
+ if (pa->addr.in6.s6_addr[r] > pb->addr.in6.s6_addr[r])
|
||||
+ return (1);
|
||||
+ }
|
||||
} else
|
||||
errx(1, "irr_prefix_cmp unknown af %u", pa->af);
|
||||
|
24
net/openbgpd/files/patch-bgpctl_irrfilter.c
Normal file
24
net/openbgpd/files/patch-bgpctl_irrfilter.c
Normal file
@ -0,0 +1,24 @@
|
||||
Index: bgpctl/irrfilter.c
|
||||
===================================================================
|
||||
RCS file: /home/cvs/private/hrs/openbgpd/bgpctl/irrfilter.c,v
|
||||
retrieving revision 1.1.1.1
|
||||
retrieving revision 1.3
|
||||
diff -u -p -r1.1.1.1 -r1.3
|
||||
--- bgpctl/irrfilter.c 30 Jun 2009 05:46:15 -0000 1.1.1.1
|
||||
+++ bgpctl/irrfilter.c 13 Oct 2012 18:35:56 -0000 1.3
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* $OpenBSD: irrfilter.c,v 1.4 2007/05/28 23:31:53 henning Exp $ */
|
||||
+/* $OpenBSD: irrfilter.c,v 1.3 2007/03/06 16:45:34 henning Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Henning Brauer <henning@openbsd.org>
|
||||
@@ -15,6 +15,9 @@
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
+#if defined(__FreeBSD__) /* compat */
|
||||
+#include "openbsd-compat.h"
|
||||
+#endif /* defined(__FreeBSD__) */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
59
net/openbgpd/files/patch-bgpctl_irrfilter.h
Normal file
59
net/openbgpd/files/patch-bgpctl_irrfilter.h
Normal file
@ -0,0 +1,59 @@
|
||||
Index: bgpctl/irrfilter.h
|
||||
===================================================================
|
||||
RCS file: /home/cvs/private/hrs/openbgpd/bgpctl/irrfilter.h,v
|
||||
retrieving revision 1.1.1.5
|
||||
retrieving revision 1.4
|
||||
diff -u -p -r1.1.1.5 -r1.4
|
||||
--- bgpctl/irrfilter.h 14 Feb 2010 20:20:14 -0000 1.1.1.5
|
||||
+++ bgpctl/irrfilter.h 13 Oct 2012 18:35:56 -0000 1.4
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* $OpenBSD: irrfilter.h,v 1.7 2007/03/06 16:45:34 henning Exp $ */
|
||||
+/* $OpenBSD: irrfilter.h,v 1.8 2009/09/08 15:40:25 claudio Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Henning Brauer <henning@openbsd.org>
|
||||
@@ -16,11 +16,17 @@
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
+#if defined(__FreeBSD__) /* compat */
|
||||
+#include "openbsd-compat.h"
|
||||
+#endif /* defined(__FreeBSD__) */
|
||||
+
|
||||
#include <sys/queue.h>
|
||||
#include <sys/tree.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#define F_IMPORTONLY 0x01 /* skip export: items */
|
||||
+#define F_IPV4 0x02 /* use IPv4 items */
|
||||
+#define F_IPV6 0x04 /* use IPv6 items */
|
||||
|
||||
int irrflags;
|
||||
int irrverbose;
|
||||
@@ -37,7 +43,7 @@ struct policy_item {
|
||||
char *action;
|
||||
char *filter;
|
||||
enum pdir dir;
|
||||
- u_int16_t peer_as;
|
||||
+ u_int32_t peer_as;
|
||||
};
|
||||
|
||||
TAILQ_HEAD(policy_head, policy_item);
|
||||
@@ -55,7 +61,8 @@ enum qtype {
|
||||
QTYPE_NONE,
|
||||
QTYPE_OWNAS,
|
||||
QTYPE_ASSET,
|
||||
- QTYPE_ROUTE
|
||||
+ QTYPE_ROUTE,
|
||||
+ QTYPE_ROUTE6
|
||||
};
|
||||
|
||||
struct as_set {
|
||||
@@ -72,6 +79,7 @@ struct as_set {
|
||||
struct irr_prefix {
|
||||
union {
|
||||
struct in_addr in;
|
||||
+ struct in6_addr in6;
|
||||
} addr;
|
||||
sa_family_t af;
|
||||
u_int8_t len;
|
977
net/openbgpd/files/patch-bgpctl_mrtparser.c
Normal file
977
net/openbgpd/files/patch-bgpctl_mrtparser.c
Normal file
@ -0,0 +1,977 @@
|
||||
Index: bgpctl/mrtparser.c
|
||||
===================================================================
|
||||
RCS file: bgpctl/mrtparser.c
|
||||
diff -N bgpctl/mrtparser.c
|
||||
--- /dev/null 1 Jan 1970 00:00:00 -0000
|
||||
+++ bgpctl/mrtparser.c 13 Oct 2012 18:22:53 -0000 1.1.1.1
|
||||
@@ -0,0 +1,970 @@
|
||||
+/* $OpenBSD: mrtparser.c,v 1.2 2012/03/06 07:52:32 claudio Exp $ */
|
||||
+/*
|
||||
+ * Copyright (c) 2011 Claudio Jeker <claudio@openbsd.org>
|
||||
+ *
|
||||
+ * Permission to use, copy, modify, and distribute this software for any
|
||||
+ * purpose with or without fee is hereby granted, provided that the above
|
||||
+ * copyright notice and this permission notice appear in all copies.
|
||||
+ *
|
||||
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
+ */
|
||||
+#include <sys/types.h>
|
||||
+#include <sys/socket.h>
|
||||
+#include <netinet/in.h>
|
||||
+#include <err.h>
|
||||
+#include <errno.h>
|
||||
+#include <limits.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <stdio.h>
|
||||
+#include <string.h>
|
||||
+#include <unistd.h>
|
||||
+
|
||||
+#include "mrt.h"
|
||||
+#include "mrtparser.h"
|
||||
+
|
||||
+void *mrt_read_msg(int, struct mrt_hdr *);
|
||||
+size_t mrt_read_buf(int, void *, size_t);
|
||||
+
|
||||
+struct mrt_peer *mrt_parse_v2_peer(struct mrt_hdr *, void *);
|
||||
+struct mrt_rib *mrt_parse_v2_rib(struct mrt_hdr *, void *);
|
||||
+int mrt_parse_dump(struct mrt_hdr *, void *, struct mrt_peer **,
|
||||
+ struct mrt_rib **);
|
||||
+int mrt_parse_dump_mp(struct mrt_hdr *, void *, struct mrt_peer **,
|
||||
+ struct mrt_rib **);
|
||||
+int mrt_extract_attr(struct mrt_rib_entry *, u_char *, int, sa_family_t,
|
||||
+ int);
|
||||
+
|
||||
+void mrt_free_peers(struct mrt_peer *);
|
||||
+void mrt_free_rib(struct mrt_rib *);
|
||||
+void mrt_free_bgp_state(struct mrt_bgp_state *);
|
||||
+void mrt_free_bgp_msg(struct mrt_bgp_msg *);
|
||||
+
|
||||
+u_char *mrt_aspath_inflate(void *, u_int16_t, u_int16_t *);
|
||||
+int mrt_extract_addr(void *, u_int, union mrt_addr *, sa_family_t);
|
||||
+
|
||||
+void *
|
||||
+mrt_read_msg(int fd, struct mrt_hdr *hdr)
|
||||
+{
|
||||
+ void *buf;
|
||||
+
|
||||
+ bzero(hdr, sizeof(*hdr));
|
||||
+ if (mrt_read_buf(fd, hdr, sizeof(*hdr)) != sizeof(*hdr))
|
||||
+ return (NULL);
|
||||
+
|
||||
+ if ((buf = malloc(ntohl(hdr->length))) == NULL)
|
||||
+ err(1, "malloc(%d)", hdr->length);
|
||||
+
|
||||
+ if (mrt_read_buf(fd, buf, ntohl(hdr->length)) != ntohl(hdr->length)) {
|
||||
+ free(buf);
|
||||
+ return (NULL);
|
||||
+ }
|
||||
+ return (buf);
|
||||
+}
|
||||
+
|
||||
+size_t
|
||||
+mrt_read_buf(int fd, void *buf, size_t len)
|
||||
+{
|
||||
+ char *b = buf;
|
||||
+ ssize_t n;
|
||||
+
|
||||
+ while (len > 0) {
|
||||
+ if ((n = read(fd, b, len)) == -1) {
|
||||
+ if (errno == EINTR)
|
||||
+ continue;
|
||||
+ err(1, "read");
|
||||
+ }
|
||||
+ if (n == 0)
|
||||
+ break;
|
||||
+ b += n;
|
||||
+ len -= n;
|
||||
+ }
|
||||
+
|
||||
+ return (b - (char *)buf);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+mrt_parse(int fd, struct mrt_parser *p, int verbose)
|
||||
+{
|
||||
+ struct mrt_hdr h;
|
||||
+ struct mrt_peer *pctx = NULL;
|
||||
+ struct mrt_rib *r;
|
||||
+ void *msg;
|
||||
+
|
||||
+ while ((msg = mrt_read_msg(fd, &h))) {
|
||||
+ switch (ntohs(h.type)) {
|
||||
+ case MSG_NULL:
|
||||
+ case MSG_START:
|
||||
+ case MSG_DIE:
|
||||
+ case MSG_I_AM_DEAD:
|
||||
+ case MSG_PEER_DOWN:
|
||||
+ case MSG_PROTOCOL_BGP:
|
||||
+ case MSG_PROTOCOL_IDRP:
|
||||
+ case MSG_PROTOCOL_BGP4PLUS:
|
||||
+ case MSG_PROTOCOL_BGP4PLUS1:
|
||||
+ if (verbose)
|
||||
+ printf("deprecated MRT type %d\n",
|
||||
+ ntohs(h.type));
|
||||
+ break;
|
||||
+ case MSG_PROTOCOL_RIP:
|
||||
+ case MSG_PROTOCOL_RIPNG:
|
||||
+ case MSG_PROTOCOL_OSPF:
|
||||
+ case MSG_PROTOCOL_ISIS_ET:
|
||||
+ case MSG_PROTOCOL_ISIS:
|
||||
+ case MSG_PROTOCOL_OSPFV3_ET:
|
||||
+ case MSG_PROTOCOL_OSPFV3:
|
||||
+ if (verbose)
|
||||
+ printf("unsuported MRT type %d\n",
|
||||
+ ntohs(h.type));
|
||||
+ break;
|
||||
+ case MSG_TABLE_DUMP:
|
||||
+ switch (ntohs(h.subtype)) {
|
||||
+ case MRT_DUMP_AFI_IP:
|
||||
+ case MRT_DUMP_AFI_IPv6:
|
||||
+ if (p->dump == NULL)
|
||||
+ break;
|
||||
+ if (mrt_parse_dump(&h, msg, &pctx, &r) == 0) {
|
||||
+ p->dump(r, pctx, p->arg);
|
||||
+ mrt_free_rib(r);
|
||||
+ }
|
||||
+ break;
|
||||
+ default:
|
||||
+ if (verbose)
|
||||
+ printf("unknown AFI %d in table dump\n",
|
||||
+ ntohs(h.subtype));
|
||||
+ break;
|
||||
+ }
|
||||
+ break;
|
||||
+ case MSG_TABLE_DUMP_V2:
|
||||
+ switch (ntohs(h.subtype)) {
|
||||
+ case MRT_DUMP_V2_PEER_INDEX_TABLE:
|
||||
+ if (p->dump == NULL)
|
||||
+ break;
|
||||
+ if (pctx)
|
||||
+ mrt_free_peers(pctx);
|
||||
+ pctx = mrt_parse_v2_peer(&h, msg);
|
||||
+ break;
|
||||
+ case MRT_DUMP_V2_RIB_IPV4_UNICAST:
|
||||
+ case MRT_DUMP_V2_RIB_IPV4_MULTICAST:
|
||||
+ case MRT_DUMP_V2_RIB_IPV6_UNICAST:
|
||||
+ case MRT_DUMP_V2_RIB_IPV6_MULTICAST:
|
||||
+ case MRT_DUMP_V2_RIB_GENERIC:
|
||||
+ if (p->dump == NULL)
|
||||
+ break;
|
||||
+ r = mrt_parse_v2_rib(&h, msg);
|
||||
+ if (r) {
|
||||
+ p->dump(r, pctx, p->arg);
|
||||
+ mrt_free_rib(r);
|
||||
+ }
|
||||
+ break;
|
||||
+ default:
|
||||
+ if (verbose)
|
||||
+ printf("unhandled BGP4MP subtype %d\n",
|
||||
+ ntohs(h.subtype));
|
||||
+ break;
|
||||
+ }
|
||||
+ break;
|
||||
+ case MSG_PROTOCOL_BGP4MP_ET:
|
||||
+ /* currently just ignore the microsec field */
|
||||
+ msg = (char *)msg + sizeof(u_int32_t);
|
||||
+ h.length -= sizeof(u_int32_t);
|
||||
+ /* FALLTHROUGH */
|
||||
+ case MSG_PROTOCOL_BGP4MP:
|
||||
+ switch (ntohs(h.subtype)) {
|
||||
+ case BGP4MP_STATE_CHANGE:
|
||||
+ case BGP4MP_STATE_CHANGE_AS4:
|
||||
+ /* XXX p->state(s, p->arg); */
|
||||
+ errx(1, "BGP4MP subtype not yet implemented");
|
||||
+ break;
|
||||
+ case BGP4MP_MESSAGE:
|
||||
+ case BGP4MP_MESSAGE_AS4:
|
||||
+ case BGP4MP_MESSAGE_LOCAL:
|
||||
+ case BGP4MP_MESSAGE_AS4_LOCAL:
|
||||
+ /* XXX p->message(m, p->arg); */
|
||||
+ errx(1, "BGP4MP subtype not yet implemented");
|
||||
+ break;
|
||||
+ case BGP4MP_ENTRY:
|
||||
+ if (p->dump == NULL)
|
||||
+ break;
|
||||
+ if (mrt_parse_dump_mp(&h, msg, &pctx, &r) ==
|
||||
+ 0) {
|
||||
+ p->dump(r, pctx, p->arg);
|
||||
+ mrt_free_rib(r);
|
||||
+ }
|
||||
+ break;
|
||||
+ default:
|
||||
+ if (verbose)
|
||||
+ printf("unhandled BGP4MP subtype %d\n",
|
||||
+ ntohs(h.subtype));
|
||||
+ break;
|
||||
+ }
|
||||
+ break;
|
||||
+ default:
|
||||
+ if (verbose)
|
||||
+ printf("unknown MRT type %d\n", ntohs(h.type));
|
||||
+ break;
|
||||
+ }
|
||||
+ free(msg);
|
||||
+ }
|
||||
+ if (pctx)
|
||||
+ mrt_free_peers(pctx);
|
||||
+}
|
||||
+
|
||||
+struct mrt_peer *
|
||||
+mrt_parse_v2_peer(struct mrt_hdr *hdr, void *msg)
|
||||
+{
|
||||
+ struct mrt_peer_entry *peers;
|
||||
+ struct mrt_peer *p;
|
||||
+ u_int8_t *b = msg;
|
||||
+ u_int32_t bid, as4;
|
||||
+ u_int16_t cnt, i, as2;
|
||||
+ u_int len = ntohl(hdr->length);
|
||||
+
|
||||
+ if (len < 8) /* min msg size */
|
||||
+ return NULL;
|
||||
+
|
||||
+ p = calloc(1, sizeof(struct mrt_peer));
|
||||
+ if (p == NULL)
|
||||
+ err(1, "calloc");
|
||||
+
|
||||
+ /* collector bgp id */
|
||||
+ memcpy(&bid, b, sizeof(bid));
|
||||
+ b += sizeof(bid);
|
||||
+ len -= sizeof(bid);
|
||||
+ p->bgp_id = ntohl(bid);
|
||||
+
|
||||
+ /* view name length */
|
||||
+ memcpy(&cnt, b, sizeof(cnt));
|
||||
+ b += sizeof(cnt);
|
||||
+ len -= sizeof(cnt);
|
||||
+ cnt = ntohs(cnt);
|
||||
+
|
||||
+ /* view name */
|
||||
+ if (cnt > len)
|
||||
+ goto fail;
|
||||
+ if (cnt != 0) {
|
||||
+ if ((p->view = malloc(cnt + 1)) == NULL)
|
||||
+ err(1, "malloc");
|
||||
+ memcpy(p->view, b, cnt);
|
||||
+ p->view[cnt] = 0;
|
||||
+ } else
|
||||
+ if ((p->view = strdup("")) == NULL)
|
||||
+ err(1, "strdup");
|
||||
+ b += cnt;
|
||||
+ len -= cnt;
|
||||
+
|
||||
+ /* peer_count */
|
||||
+ if (len < sizeof(cnt))
|
||||
+ goto fail;
|
||||
+ memcpy(&cnt, b, sizeof(cnt));
|
||||
+ b += sizeof(cnt);
|
||||
+ len -= sizeof(cnt);
|
||||
+ cnt = ntohs(cnt);
|
||||
+
|
||||
+ /* peer entries */
|
||||
+ if ((peers = calloc(cnt, sizeof(struct mrt_peer_entry))) == NULL)
|
||||
+ err(1, "calloc");
|
||||
+ for (i = 0; i < cnt; i++) {
|
||||
+ u_int8_t type;
|
||||
+
|
||||
+ if (len < sizeof(u_int8_t) + sizeof(u_int32_t))
|
||||
+ goto fail;
|
||||
+ type = *b++;
|
||||
+ len -= 1;
|
||||
+ memcpy(&bid, b, sizeof(bid));
|
||||
+ b += sizeof(bid);
|
||||
+ len -= sizeof(bid);
|
||||
+ peers[i].bgp_id = ntohl(bid);
|
||||
+
|
||||
+ if (type & MRT_DUMP_V2_PEER_BIT_I) {
|
||||
+ if (mrt_extract_addr(b, len, &peers[i].addr,
|
||||
+ AF_INET6) == -1)
|
||||
+ goto fail;
|
||||
+ b += sizeof(struct in6_addr);
|
||||
+ len -= sizeof(struct in6_addr);
|
||||
+ } else {
|
||||
+ if (mrt_extract_addr(b, len, &peers[i].addr,
|
||||
+ AF_INET) == -1)
|
||||
+ goto fail;
|
||||
+ b += sizeof(struct in_addr);
|
||||
+ len -= sizeof(struct in_addr);
|
||||
+ }
|
||||
+
|
||||
+ if (type & MRT_DUMP_V2_PEER_BIT_A) {
|
||||
+ memcpy(&as4, b, sizeof(as4));
|
||||
+ b += sizeof(as4);
|
||||
+ len -= sizeof(as4);
|
||||
+ as4 = ntohl(as4);
|
||||
+ } else {
|
||||
+ memcpy(&as2, b, sizeof(as2));
|
||||
+ b += sizeof(as2);
|
||||
+ len -= sizeof(as2);
|
||||
+ as4 = ntohs(as2);
|
||||
+ }
|
||||
+ peers[i].asnum = as4;
|
||||
+ }
|
||||
+ p->peers = peers;
|
||||
+ p->npeers = cnt;
|
||||
+ return (p);
|
||||
+fail:
|
||||
+ mrt_free_peers(p);
|
||||
+ return (NULL);
|
||||
+}
|
||||
+
|
||||
+struct mrt_rib *
|
||||
+mrt_parse_v2_rib(struct mrt_hdr *hdr, void *msg)
|
||||
+{
|
||||
+ struct mrt_rib_entry *entries;
|
||||
+ struct mrt_rib *r;
|
||||
+ u_int8_t *b = msg;
|
||||
+ u_int len = ntohl(hdr->length);
|
||||
+ u_int32_t snum;
|
||||
+ u_int16_t cnt, i;
|
||||
+ u_int8_t plen;
|
||||
+
|
||||
+ if (len < sizeof(snum) + 1)
|
||||
+ return NULL;
|
||||
+
|
||||
+ r = calloc(1, sizeof(struct mrt_rib));
|
||||
+ if (r == NULL)
|
||||
+ err(1, "calloc");
|
||||
+
|
||||
+ /* seq_num */
|
||||
+ memcpy(&snum, b, sizeof(snum));
|
||||
+ b += sizeof(snum);
|
||||
+ len -= sizeof(snum);
|
||||
+ r->seqnum = ntohl(snum);
|
||||
+
|
||||
+ switch (ntohs(hdr->subtype)) {
|
||||
+ case MRT_DUMP_V2_RIB_IPV4_UNICAST:
|
||||
+ case MRT_DUMP_V2_RIB_IPV4_MULTICAST:
|
||||
+ plen = *b++;
|
||||
+ len -= 1;
|
||||
+ if (len < MRT_PREFIX_LEN(plen))
|
||||
+ goto fail;
|
||||
+ r->prefix.sin.sin_family = AF_INET;
|
||||
+ r->prefix.sin.sin_len = sizeof(struct sockaddr_in);
|
||||
+ memcpy(&r->prefix.sin.sin_addr, b, MRT_PREFIX_LEN(plen));
|
||||
+ b += MRT_PREFIX_LEN(plen);
|
||||
+ len -= MRT_PREFIX_LEN(plen);
|
||||
+ r->prefixlen = plen;
|
||||
+ break;
|
||||
+ case MRT_DUMP_V2_RIB_IPV6_UNICAST:
|
||||
+ case MRT_DUMP_V2_RIB_IPV6_MULTICAST:
|
||||
+ plen = *b++;
|
||||
+ len -= 1;
|
||||
+ if (len < MRT_PREFIX_LEN(plen))
|
||||
+ goto fail;
|
||||
+ r->prefix.sin6.sin6_family = AF_INET6;
|
||||
+ r->prefix.sin6.sin6_len = sizeof(struct sockaddr_in6);
|
||||
+ memcpy(&r->prefix.sin6.sin6_addr, b, MRT_PREFIX_LEN(plen));
|
||||
+ b += MRT_PREFIX_LEN(plen);
|
||||
+ len -= MRT_PREFIX_LEN(plen);
|
||||
+ r->prefixlen = plen;
|
||||
+ break;
|
||||
+ case MRT_DUMP_V2_RIB_GENERIC:
|
||||
+ /* XXX unhandled */
|
||||
+ errx(1, "MRT_DUMP_V2_RIB_GENERIC subtype not yet implemented");
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ /* entries count */
|
||||
+ if (len < sizeof(cnt))
|
||||
+ goto fail;
|
||||
+ memcpy(&cnt, b, sizeof(cnt));
|
||||
+ b += sizeof(cnt);
|
||||
+ len -= sizeof(cnt);
|
||||
+ cnt = ntohs(cnt);
|
||||
+ r->nentries = cnt;
|
||||
+
|
||||
+ /* entries */
|
||||
+ if ((entries = calloc(cnt, sizeof(struct mrt_rib_entry))) == NULL)
|
||||
+ err(1, "calloc");
|
||||
+ for (i = 0; i < cnt; i++) {
|
||||
+ u_int32_t otm;
|
||||
+ u_int16_t pix, alen;
|
||||
+ if (len < 2 * sizeof(u_int16_t) + sizeof(u_int32_t))
|
||||
+ goto fail;
|
||||
+ /* peer index */
|
||||
+ memcpy(&pix, b, sizeof(pix));
|
||||
+ b += sizeof(pix);
|
||||
+ len -= sizeof(pix);
|
||||
+ entries[i].peer_idx = ntohs(pix);
|
||||
+
|
||||
+ /* originated */
|
||||
+ memcpy(&otm, b, sizeof(otm));
|
||||
+ b += sizeof(otm);
|
||||
+ len -= sizeof(otm);
|
||||
+ entries[i].originated = ntohl(otm);
|
||||
+
|
||||
+ /* attr_len */
|
||||
+ memcpy(&alen, b, sizeof(alen));
|
||||
+ b += sizeof(alen);
|
||||
+ len -= sizeof(alen);
|
||||
+ alen = ntohs(alen);
|
||||
+
|
||||
+ /* attr */
|
||||
+ if (len < alen)
|
||||
+ goto fail;
|
||||
+ if (mrt_extract_attr(&entries[i], b, alen,
|
||||
+ r->prefix.sa.sa_family, 1) == -1)
|
||||
+ goto fail;
|
||||
+ b += alen;
|
||||
+ len -= alen;
|
||||
+ }
|
||||
+ r->entries = entries;
|
||||
+ return (r);
|
||||
+fail:
|
||||
+ mrt_free_rib(r);
|
||||
+ return (NULL);
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+mrt_parse_dump(struct mrt_hdr *hdr, void *msg, struct mrt_peer **pp,
|
||||
+ struct mrt_rib **rp)
|
||||
+{
|
||||
+ struct mrt_peer *p;
|
||||
+ struct mrt_rib *r;
|
||||
+ struct mrt_rib_entry *re;
|
||||
+ u_int8_t *b = msg;
|
||||
+ u_int len = ntohl(hdr->length);
|
||||
+ u_int16_t asnum, alen;
|
||||
+
|
||||
+ if (*pp == NULL) {
|
||||
+ *pp = calloc(1, sizeof(struct mrt_peer));
|
||||
+ if (*pp == NULL)
|
||||
+ err(1, "calloc");
|
||||
+ (*pp)->peers = calloc(1, sizeof(struct mrt_peer_entry));
|
||||
+ if ((*pp)->peers == NULL)
|
||||
+ err(1, "calloc");
|
||||
+ (*pp)->npeers = 1;
|
||||
+ }
|
||||
+ p = *pp;
|
||||
+
|
||||
+ *rp = r = calloc(1, sizeof(struct mrt_rib));
|
||||
+ if (r == NULL)
|
||||
+ err(1, "calloc");
|
||||
+ re = calloc(1, sizeof(struct mrt_rib_entry));
|
||||
+ if (re == NULL)
|
||||
+ err(1, "calloc");
|
||||
+ r->nentries = 1;
|
||||
+ r->entries = re;
|
||||
+
|
||||
+ if (len < 2 * sizeof(u_int16_t))
|
||||
+ goto fail;
|
||||
+ /* view */
|
||||
+ b += sizeof(u_int16_t);
|
||||
+ len -= sizeof(u_int16_t);
|
||||
+ /* seqnum */
|
||||
+ memcpy(&r->seqnum, b, sizeof(u_int16_t));
|
||||
+ b += sizeof(u_int16_t);
|
||||
+ len -= sizeof(u_int16_t);
|
||||
+ r->seqnum = ntohs(r->seqnum);
|
||||
+
|
||||
+ switch (ntohs(hdr->subtype)) {
|
||||
+ case MRT_DUMP_AFI_IP:
|
||||
+ if (mrt_extract_addr(b, len, &r->prefix, AF_INET) == -1)
|
||||
+ goto fail;
|
||||
+ b += sizeof(struct in_addr);
|
||||
+ len -= sizeof(struct in_addr);
|
||||
+ break;
|
||||
+ case MRT_DUMP_AFI_IPv6:
|
||||
+ if (mrt_extract_addr(b, len, &r->prefix, AF_INET6) == -1)
|
||||
+ goto fail;
|
||||
+ b += sizeof(struct in6_addr);
|
||||
+ len -= sizeof(struct in6_addr);
|
||||
+ break;
|
||||
+ }
|
||||
+ if (len < 2 * sizeof(u_int32_t) + 2 * sizeof(u_int16_t) + 2)
|
||||
+ goto fail;
|
||||
+ r->prefixlen = *b++;
|
||||
+ len -= 1;
|
||||
+ /* status */
|
||||
+ b += 1;
|
||||
+ len -= 1;
|
||||
+ /* originated */
|
||||
+ memcpy(&re->originated, b, sizeof(u_int32_t));
|
||||
+ b += sizeof(u_int32_t);
|
||||
+ len -= sizeof(u_int32_t);
|
||||
+ re->originated = ntohl(re->originated);
|
||||
+ /* peer ip */
|
||||
+ switch (ntohs(hdr->subtype)) {
|
||||
+ case MRT_DUMP_AFI_IP:
|
||||
+ if (mrt_extract_addr(b, len, &p->peers->addr, AF_INET) == -1)
|
||||
+ goto fail;
|
||||
+ b += sizeof(struct in_addr);
|
||||
+ len -= sizeof(struct in_addr);
|
||||
+ break;
|
||||
+ case MRT_DUMP_AFI_IPv6:
|
||||
+ if (mrt_extract_addr(b, len, &p->peers->addr, AF_INET6) == -1)
|
||||
+ goto fail;
|
||||
+ b += sizeof(struct in6_addr);
|
||||
+ len -= sizeof(struct in6_addr);
|
||||
+ break;
|
||||
+ }
|
||||
+ memcpy(&asnum, b, sizeof(asnum));
|
||||
+ b += sizeof(asnum);
|
||||
+ len -= sizeof(asnum);
|
||||
+ p->peers->asnum = ntohs(asnum);
|
||||
+
|
||||
+ memcpy(&alen, b, sizeof(alen));
|
||||
+ b += sizeof(alen);
|
||||
+ len -= sizeof(alen);
|
||||
+ alen = ntohs(alen);
|
||||
+
|
||||
+ /* attr */
|
||||
+ if (len < alen)
|
||||
+ goto fail;
|
||||
+ if (mrt_extract_attr(re, b, alen, r->prefix.sa.sa_family, 0) == -1)
|
||||
+ goto fail;
|
||||
+ b += alen;
|
||||
+ len -= alen;
|
||||
+
|
||||
+ return (0);
|
||||
+fail:
|
||||
+ mrt_free_rib(r);
|
||||
+ return (-1);
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+mrt_parse_dump_mp(struct mrt_hdr *hdr, void *msg, struct mrt_peer **pp,
|
||||
+ struct mrt_rib **rp)
|
||||
+{
|
||||
+ struct mrt_peer *p;
|
||||
+ struct mrt_rib *r;
|
||||
+ struct mrt_rib_entry *re;
|
||||
+ u_int8_t *b = msg;
|
||||
+ u_int len = ntohl(hdr->length);
|
||||
+ u_int16_t asnum, alen, afi;
|
||||
+ u_int8_t safi, nhlen;
|
||||
+ sa_family_t af;
|
||||
+
|
||||
+ if (*pp == NULL) {
|
||||
+ *pp = calloc(1, sizeof(struct mrt_peer));
|
||||
+ if (*pp == NULL)
|
||||
+ err(1, "calloc");
|
||||
+ (*pp)->peers = calloc(1, sizeof(struct mrt_peer_entry));
|
||||
+ if ((*pp)->peers == NULL)
|
||||
+ err(1, "calloc");
|
||||
+ (*pp)->npeers = 1;
|
||||
+ }
|
||||
+ p = *pp;
|
||||
+
|
||||
+ *rp = r = calloc(1, sizeof(struct mrt_rib));
|
||||
+ if (r == NULL)
|
||||
+ err(1, "calloc");
|
||||
+ re = calloc(1, sizeof(struct mrt_rib_entry));
|
||||
+ if (re == NULL)
|
||||
+ err(1, "calloc");
|
||||
+ r->nentries = 1;
|
||||
+ r->entries = re;
|
||||
+
|
||||
+ if (len < 4 * sizeof(u_int16_t))
|
||||
+ goto fail;
|
||||
+ /* source AS */
|
||||
+ b += sizeof(u_int16_t);
|
||||
+ len -= sizeof(u_int16_t);
|
||||
+ /* dest AS */
|
||||
+ memcpy(&asnum, b, sizeof(asnum));
|
||||
+ b += sizeof(asnum);
|
||||
+ len -= sizeof(asnum);
|
||||
+ p->peers->asnum = ntohs(asnum);
|
||||
+ /* iface index */
|
||||
+ b += sizeof(u_int16_t);
|
||||
+ len -= sizeof(u_int16_t);
|
||||
+ /* afi */
|
||||
+ memcpy(&afi, b, sizeof(afi));
|
||||
+ b += sizeof(afi);
|
||||
+ len -= sizeof(afi);
|
||||
+ afi = ntohs(afi);
|
||||
+
|
||||
+ /* source + dest ip */
|
||||
+ switch (afi) {
|
||||
+ case MRT_DUMP_AFI_IP:
|
||||
+ if (len < 2 * sizeof(struct in_addr))
|
||||
+ goto fail;
|
||||
+ /* source IP */
|
||||
+ b += sizeof(struct in_addr);
|
||||
+ len -= sizeof(struct in_addr);
|
||||
+ /* dest IP */
|
||||
+ if (mrt_extract_addr(b, len, &p->peers->addr, AF_INET) == -1)
|
||||
+ goto fail;
|
||||
+ b += sizeof(struct in_addr);
|
||||
+ len -= sizeof(struct in_addr);
|
||||
+ break;
|
||||
+ case MRT_DUMP_AFI_IPv6:
|
||||
+ if (len < 2 * sizeof(struct in6_addr))
|
||||
+ goto fail;
|
||||
+ /* source IP */
|
||||
+ b += sizeof(struct in6_addr);
|
||||
+ len -= sizeof(struct in6_addr);
|
||||
+ /* dest IP */
|
||||
+ if (mrt_extract_addr(b, len, &p->peers->addr, AF_INET6) == -1)
|
||||
+ goto fail;
|
||||
+ b += sizeof(struct in6_addr);
|
||||
+ len -= sizeof(struct in6_addr);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (len < 2 * sizeof(u_int16_t) + 2 * sizeof(u_int32_t))
|
||||
+ goto fail;
|
||||
+ /* view + status */
|
||||
+ b += 2 * sizeof(u_int16_t);
|
||||
+ len -= 2 * sizeof(u_int16_t);
|
||||
+ /* originated */
|
||||
+ memcpy(&re->originated, b, sizeof(u_int32_t));
|
||||
+ b += sizeof(u_int32_t);
|
||||
+ len -= sizeof(u_int32_t);
|
||||
+ re->originated = ntohl(re->originated);
|
||||
+
|
||||
+ /* afi */
|
||||
+ memcpy(&afi, b, sizeof(afi));
|
||||
+ b += sizeof(afi);
|
||||
+ len -= sizeof(afi);
|
||||
+ afi = ntohs(afi);
|
||||
+
|
||||
+ /* safi */
|
||||
+ safi = *b++;
|
||||
+ len -= 1;
|
||||
+
|
||||
+ switch (afi) {
|
||||
+ case MRT_DUMP_AFI_IP:
|
||||
+ if (safi == 1 || safi == 2) {
|
||||
+ af = AF_INET;
|
||||
+ break;
|
||||
+ } else if (safi == 128) {
|
||||
+ af = AF_VPNv4;
|
||||
+ break;
|
||||
+ }
|
||||
+ goto fail;
|
||||
+ case MRT_DUMP_AFI_IPv6:
|
||||
+ if (safi != 1 && safi != 2)
|
||||
+ goto fail;
|
||||
+ af = AF_INET6;
|
||||
+ break;
|
||||
+ default:
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ /* nhlen */
|
||||
+ nhlen = *b++;
|
||||
+ len -= 1;
|
||||
+
|
||||
+ /* nexthop */
|
||||
+ if (mrt_extract_addr(b, len, &re->nexthop, af) == -1)
|
||||
+ goto fail;
|
||||
+ if (len < nhlen)
|
||||
+ goto fail;
|
||||
+ b += nhlen;
|
||||
+ len -= nhlen;
|
||||
+
|
||||
+ if (len < 1)
|
||||
+ goto fail;
|
||||
+ r->prefixlen = *b++;
|
||||
+ len -= 1;
|
||||
+
|
||||
+ /* prefix */
|
||||
+ switch (af) {
|
||||
+ case AF_INET:
|
||||
+ if (len < MRT_PREFIX_LEN(r->prefixlen))
|
||||
+ goto fail;
|
||||
+ r->prefix.sin.sin_family = AF_INET;
|
||||
+ r->prefix.sin.sin_len = sizeof(struct sockaddr_in);
|
||||
+ memcpy(&r->prefix.sin.sin_addr, b,
|
||||
+ MRT_PREFIX_LEN(r->prefixlen));
|
||||
+ b += MRT_PREFIX_LEN(r->prefixlen);
|
||||
+ len -= MRT_PREFIX_LEN(r->prefixlen);
|
||||
+ break;
|
||||
+ case AF_INET6:
|
||||
+ if (len < MRT_PREFIX_LEN(r->prefixlen))
|
||||
+ goto fail;
|
||||
+ r->prefix.sin6.sin6_family = AF_INET6;
|
||||
+ r->prefix.sin6.sin6_len = sizeof(struct sockaddr_in6);
|
||||
+ memcpy(&r->prefix.sin6.sin6_addr, b,
|
||||
+ MRT_PREFIX_LEN(r->prefixlen));
|
||||
+ b += MRT_PREFIX_LEN(r->prefixlen);
|
||||
+ len -= MRT_PREFIX_LEN(r->prefixlen);
|
||||
+ break;
|
||||
+ case AF_VPNv4:
|
||||
+ if (len < MRT_PREFIX_LEN(r->prefixlen))
|
||||
+ goto fail;
|
||||
+ errx(1, "AF_VPNv4 handling not yet implemented");
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ memcpy(&alen, b, sizeof(alen));
|
||||
+ b += sizeof(alen);
|
||||
+ len -= sizeof(alen);
|
||||
+ alen = ntohs(alen);
|
||||
+
|
||||
+ /* attr */
|
||||
+ if (len < alen)
|
||||
+ goto fail;
|
||||
+ if (mrt_extract_attr(re, b, alen, r->prefix.sa.sa_family, 0) == -1)
|
||||
+ goto fail;
|
||||
+ b += alen;
|
||||
+ len -= alen;
|
||||
+
|
||||
+ return (0);
|
||||
+fail:
|
||||
+ mrt_free_rib(r);
|
||||
+ return (-1);
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+mrt_extract_attr(struct mrt_rib_entry *re, u_char *a, int alen, sa_family_t af,
|
||||
+ int as4)
|
||||
+{
|
||||
+ struct mrt_attr *ap;
|
||||
+ u_int32_t tmp;
|
||||
+ u_int16_t attr_len;
|
||||
+ u_int8_t type, flags, *attr;
|
||||
+
|
||||
+ do {
|
||||
+ if (alen < 3)
|
||||
+ return (-1);
|
||||
+ attr = a;
|
||||
+ flags = *a++;
|
||||
+ alen -= 1;
|
||||
+ type = *a++;
|
||||
+ alen -= 1;
|
||||
+
|
||||
+ if (flags & MRT_ATTR_EXTLEN) {
|
||||
+ if (alen < 2)
|
||||
+ return (-1);
|
||||
+ memcpy(&attr_len, a, sizeof(attr_len));
|
||||
+ attr_len = ntohs(attr_len);
|
||||
+ a += sizeof(attr_len);
|
||||
+ alen -= sizeof(attr_len);
|
||||
+ } else {
|
||||
+ attr_len = *a++;
|
||||
+ alen -= 1;
|
||||
+ }
|
||||
+ switch (type) {
|
||||
+ case MRT_ATTR_ORIGIN:
|
||||
+ if (attr_len != 1)
|
||||
+ return (-1);
|
||||
+ re->origin = *a;
|
||||
+ break;
|
||||
+ case MRT_ATTR_ASPATH:
|
||||
+ if (as4) {
|
||||
+ re->aspath_len = attr_len;
|
||||
+ if ((re->aspath = malloc(attr_len)) == NULL)
|
||||
+ err(1, "malloc");
|
||||
+ memcpy(re->aspath, a, attr_len);
|
||||
+ } else {
|
||||
+ re->aspath = mrt_aspath_inflate(a, attr_len,
|
||||
+ &re->aspath_len);
|
||||
+ if (re->aspath == NULL)
|
||||
+ return (-1);
|
||||
+ }
|
||||
+ break;
|
||||
+ case MRT_ATTR_NEXTHOP:
|
||||
+ if (attr_len != 4)
|
||||
+ return (-1);
|
||||
+ if (af != AF_INET)
|
||||
+ break;
|
||||
+ memcpy(&tmp, a, sizeof(tmp));
|
||||
+ re->nexthop.sin.sin_len = sizeof(struct sockaddr_in);
|
||||
+ re->nexthop.sin.sin_family = AF_INET;
|
||||
+ re->nexthop.sin.sin_addr.s_addr = tmp;
|
||||
+ break;
|
||||
+ case MRT_ATTR_MED:
|
||||
+ if (attr_len != 4)
|
||||
+ return (-1);
|
||||
+ memcpy(&tmp, a, sizeof(tmp));
|
||||
+ re->med = ntohl(tmp);
|
||||
+ break;
|
||||
+ case MRT_ATTR_LOCALPREF:
|
||||
+ if (attr_len != 4)
|
||||
+ return (-1);
|
||||
+ memcpy(&tmp, a, sizeof(tmp));
|
||||
+ re->local_pref = ntohl(tmp);
|
||||
+ break;
|
||||
+ case MRT_ATTR_MP_REACH_NLRI:
|
||||
+ /*
|
||||
+ * XXX horrible hack:
|
||||
+ * Once again IETF and the real world differ in the
|
||||
+ * implementation. In short the abbreviated MP_NLRI
|
||||
+ * hack in the standard is not used in real life.
|
||||
+ * Detect the two cases by looking at the first byte
|
||||
+ * of the payload (either the nexthop addr length (RFC)
|
||||
+ * or the high byte of the AFI (old form)). If the
|
||||
+ * first byte matches the expected nexthop length it
|
||||
+ * is expected to be the RFC 6396 encoding.
|
||||
+ */
|
||||
+ if (*a != attr_len - 1) {
|
||||
+ a += 3;
|
||||
+ alen -= 3;
|
||||
+ attr_len -= 3;
|
||||
+ }
|
||||
+ switch (af) {
|
||||
+ case AF_INET6:
|
||||
+ if (attr_len < sizeof(struct in6_addr) + 1)
|
||||
+ return (-1);
|
||||
+ re->nexthop.sin6.sin6_len =
|
||||
+ sizeof(struct sockaddr_in6);
|
||||
+ re->nexthop.sin6.sin6_family = AF_INET6;
|
||||
+ memcpy(&re->nexthop.sin6.sin6_addr, a + 1,
|
||||
+ sizeof(struct in6_addr));
|
||||
+ break;
|
||||
+ case AF_VPNv4:
|
||||
+ if (attr_len < sizeof(u_int64_t) +
|
||||
+ sizeof(struct in_addr))
|
||||
+ return (-1);
|
||||
+ re->nexthop.svpn4.sv_len =
|
||||
+ sizeof(struct sockaddr_vpn4);
|
||||
+ re->nexthop.svpn4.sv_family = AF_VPNv4;
|
||||
+ memcpy(&tmp, a + 1 + sizeof(u_int64_t),
|
||||
+ sizeof(tmp));
|
||||
+ re->nexthop.svpn4.sv_addr.s_addr = tmp;
|
||||
+ break;
|
||||
+ }
|
||||
+ break;
|
||||
+ case MRT_ATTR_AS4PATH:
|
||||
+ if (!as4) {
|
||||
+ if (re->aspath)
|
||||
+ free(re->aspath);
|
||||
+ re->aspath_len = attr_len;
|
||||
+ if ((re->aspath = malloc(attr_len)) == NULL)
|
||||
+ err(1, "malloc");
|
||||
+ memcpy(re->aspath, a, attr_len);
|
||||
+ break;
|
||||
+ }
|
||||
+ /* FALLTHROUGH */
|
||||
+ default:
|
||||
+ re->nattrs++;
|
||||
+ if (re->nattrs >= UCHAR_MAX)
|
||||
+ err(1, "too many attributes");
|
||||
+ ap = realloc(re->attrs,
|
||||
+ re->nattrs * sizeof(struct mrt_attr));
|
||||
+ if (ap == NULL)
|
||||
+ err(1, "realloc");
|
||||
+ re->attrs = ap;
|
||||
+ ap = re->attrs + re->nattrs - 1;
|
||||
+ ap->attr_len = a + attr_len - attr;
|
||||
+ if ((ap->attr = malloc(ap->attr_len)) == NULL)
|
||||
+ err(1, "malloc");
|
||||
+ memcpy(ap->attr, attr, ap->attr_len);
|
||||
+ break;
|
||||
+ }
|
||||
+ a += attr_len;
|
||||
+ alen -= attr_len;
|
||||
+ } while (alen > 0);
|
||||
+
|
||||
+ return (0);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+mrt_free_peers(struct mrt_peer *p)
|
||||
+{
|
||||
+ free(p->peers);
|
||||
+ free(p->view);
|
||||
+ free(p);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+mrt_free_rib(struct mrt_rib *r)
|
||||
+{
|
||||
+ u_int16_t i, j;
|
||||
+
|
||||
+ for (i = 0; i < r->nentries && r->entries; i++) {
|
||||
+ for (j = 0; j < r->entries[i].nattrs; j++)
|
||||
+ free(r->entries[i].attrs[j].attr);
|
||||
+ free(r->entries[i].attrs);
|
||||
+ free(r->entries[i].aspath);
|
||||
+ }
|
||||
+
|
||||
+ free(r->entries);
|
||||
+ free(r);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+mrt_free_bgp_state(struct mrt_bgp_state *s)
|
||||
+{
|
||||
+ free(s);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+mrt_free_bgp_msg(struct mrt_bgp_msg *m)
|
||||
+{
|
||||
+ free(m->msg);
|
||||
+ free(m);
|
||||
+}
|
||||
+
|
||||
+u_char *
|
||||
+mrt_aspath_inflate(void *data, u_int16_t len, u_int16_t *newlen)
|
||||
+{
|
||||
+ u_int8_t *seg, *nseg, *ndata;
|
||||
+ u_int16_t seg_size, olen, nlen;
|
||||
+ u_int8_t seg_len;
|
||||
+
|
||||
+ /* first calculate the length of the aspath */
|
||||
+ seg = data;
|
||||
+ nlen = 0;
|
||||
+ for (olen = len; olen > 0; olen -= seg_size, seg += seg_size) {
|
||||
+ seg_len = seg[1];
|
||||
+ seg_size = 2 + sizeof(u_int16_t) * seg_len;
|
||||
+ nlen += 2 + sizeof(u_int32_t) * seg_len;
|
||||
+
|
||||
+ if (seg_size > olen)
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ *newlen = nlen;
|
||||
+ if ((ndata = malloc(nlen)) == NULL)
|
||||
+ err(1, "malloc");
|
||||
+
|
||||
+ /* then copy the aspath */
|
||||
+ seg = data;
|
||||
+ for (nseg = ndata; nseg < ndata + nlen; ) {
|
||||
+ *nseg++ = *seg++;
|
||||
+ *nseg++ = seg_len = *seg++;
|
||||
+ for (; seg_len > 0; seg_len--) {
|
||||
+ *nseg++ = 0;
|
||||
+ *nseg++ = 0;
|
||||
+ *nseg++ = *seg++;
|
||||
+ *nseg++ = *seg++;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return (ndata);
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+mrt_extract_addr(void *msg, u_int len, union mrt_addr *addr, sa_family_t af)
|
||||
+{
|
||||
+ u_int8_t *b = msg;
|
||||
+
|
||||
+ switch (af) {
|
||||
+ case AF_INET:
|
||||
+ if (len < sizeof(struct in_addr))
|
||||
+ return (-1);
|
||||
+ addr->sin.sin_family = AF_INET;
|
||||
+ addr->sin.sin_len = sizeof(struct sockaddr_in);
|
||||
+ memcpy(&addr->sin.sin_addr, b, sizeof(struct in_addr));
|
||||
+ return sizeof(struct in_addr);
|
||||
+ case AF_INET6:
|
||||
+ if (len < sizeof(struct in6_addr))
|
||||
+ return (-1);
|
||||
+ addr->sin6.sin6_family = AF_INET6;
|
||||
+ addr->sin6.sin6_len = sizeof(struct sockaddr_in6);
|
||||
+ memcpy(&addr->sin6.sin6_addr, b, sizeof(struct in6_addr));
|
||||
+ return sizeof(struct in6_addr);
|
||||
+ case AF_VPNv4:
|
||||
+ if (len < sizeof(u_int64_t) + sizeof(struct in_addr))
|
||||
+ return (-1);
|
||||
+ addr->svpn4.sv_len = sizeof(struct sockaddr_vpn4);
|
||||
+ addr->svpn4.sv_family = AF_VPNv4;
|
||||
+ memcpy(&addr->svpn4.sv_addr, b + sizeof(u_int64_t),
|
||||
+ sizeof(struct in_addr));
|
||||
+ return (sizeof(u_int64_t) + sizeof(struct in_addr));
|
||||
+ default:
|
||||
+ return (-1);
|
||||
+ }
|
||||
+}
|
122
net/openbgpd/files/patch-bgpctl_mrtparser.h
Normal file
122
net/openbgpd/files/patch-bgpctl_mrtparser.h
Normal file
@ -0,0 +1,122 @@
|
||||
Index: bgpctl/mrtparser.h
|
||||
===================================================================
|
||||
RCS file: bgpctl/mrtparser.h
|
||||
diff -N bgpctl/mrtparser.h
|
||||
--- /dev/null 1 Jan 1970 00:00:00 -0000
|
||||
+++ bgpctl/mrtparser.h 13 Oct 2012 18:22:53 -0000 1.1.1.1
|
||||
@@ -0,0 +1,115 @@
|
||||
+/* $OpenBSD$ */
|
||||
+/*
|
||||
+ * Copyright (c) 2011 Claudio Jeker <claudio@openbsd.org>
|
||||
+ *
|
||||
+ * Permission to use, copy, modify, and distribute this software for any
|
||||
+ * purpose with or without fee is hereby granted, provided that the above
|
||||
+ * copyright notice and this permission notice appear in all copies.
|
||||
+ *
|
||||
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
+ */
|
||||
+
|
||||
+struct sockaddr_vpn4 {
|
||||
+ u_int8_t sv_len;
|
||||
+ sa_family_t sv_family;
|
||||
+ u_int8_t sv_labellen;
|
||||
+ u_int8_t sv_pad;
|
||||
+ struct in_addr sv_addr;
|
||||
+ u_int64_t sv_rd;
|
||||
+ u_int8_t sv_label[21];
|
||||
+ u_int8_t sv_pad2[3];
|
||||
+};
|
||||
+
|
||||
+#define AF_VPNv4 250 /* XXX high enough to not cause issues */
|
||||
+
|
||||
+union mrt_addr {
|
||||
+ struct sockaddr_in6 sin6;
|
||||
+ struct sockaddr_in sin;
|
||||
+ struct sockaddr_vpn4 svpn4;
|
||||
+ struct sockaddr sa;
|
||||
+};
|
||||
+
|
||||
+/* data structures for the MSG_TABLE_DUMP_V2 format */
|
||||
+struct mrt_peer_entry {
|
||||
+ union mrt_addr addr;
|
||||
+ u_int32_t bgp_id;
|
||||
+ u_int32_t asnum;
|
||||
+};
|
||||
+
|
||||
+struct mrt_peer {
|
||||
+ char *view;
|
||||
+ struct mrt_peer_entry *peers;
|
||||
+ u_int32_t bgp_id;
|
||||
+ u_int16_t npeers;
|
||||
+};
|
||||
+
|
||||
+struct mrt_attr {
|
||||
+ void *attr;
|
||||
+ size_t attr_len;
|
||||
+};
|
||||
+
|
||||
+struct mrt_rib_entry {
|
||||
+ void *aspath;
|
||||
+ struct mrt_attr *attrs;
|
||||
+ union mrt_addr nexthop;
|
||||
+ time_t originated;
|
||||
+ u_int32_t local_pref;
|
||||
+ u_int32_t med;
|
||||
+ u_int16_t peer_idx;
|
||||
+ u_int16_t aspath_len;
|
||||
+ u_int16_t nattrs;
|
||||
+ u_int8_t origin;
|
||||
+};
|
||||
+
|
||||
+struct mrt_rib {
|
||||
+ struct mrt_rib_entry *entries;
|
||||
+ union mrt_addr prefix;
|
||||
+ u_int32_t seqnum;
|
||||
+ u_int16_t nentries;
|
||||
+ u_int8_t prefixlen;
|
||||
+};
|
||||
+
|
||||
+/* data structures for the BGP4MP MESSAGE and STATE types */
|
||||
+struct mrt_bgp_state {
|
||||
+ union mrt_addr src;
|
||||
+ union mrt_addr dst;
|
||||
+ u_int32_t src_as;
|
||||
+ u_int32_t dst_as;
|
||||
+ u_int16_t old_state;
|
||||
+ u_int16_t new_state;
|
||||
+};
|
||||
+
|
||||
+struct mrt_bgp_msg {
|
||||
+ union mrt_addr src;
|
||||
+ union mrt_addr dst;
|
||||
+ u_int32_t src_as;
|
||||
+ u_int32_t dst_as;
|
||||
+ u_int16_t msg_len;
|
||||
+ void *msg;
|
||||
+};
|
||||
+
|
||||
+#define MRT_ATTR_ORIGIN 1
|
||||
+#define MRT_ATTR_ASPATH 2
|
||||
+#define MRT_ATTR_NEXTHOP 3
|
||||
+#define MRT_ATTR_MED 4
|
||||
+#define MRT_ATTR_LOCALPREF 5
|
||||
+#define MRT_ATTR_MP_REACH_NLRI 14
|
||||
+#define MRT_ATTR_AS4PATH 17
|
||||
+#define MRT_ATTR_EXTLEN 0x10
|
||||
+
|
||||
+#define MRT_PREFIX_LEN(x) ((((u_int)x) + 7) / 8)
|
||||
+
|
||||
+struct mrt_parser {
|
||||
+ void (*dump)(struct mrt_rib *, struct mrt_peer *, void *);
|
||||
+ void (*state)(struct mrt_bgp_state *, void *);
|
||||
+ void (*message)(struct mrt_bgp_msg *, void *);
|
||||
+ void *arg;
|
||||
+};
|
||||
+
|
||||
+void mrt_parse(int, struct mrt_parser *, int);
|
400
net/openbgpd/files/patch-bgpctl_parser.c
Normal file
400
net/openbgpd/files/patch-bgpctl_parser.c
Normal file
@ -0,0 +1,400 @@
|
||||
Index: bgpctl/parser.c
|
||||
===================================================================
|
||||
RCS file: /home/cvs/private/hrs/openbgpd/bgpctl/parser.c,v
|
||||
retrieving revision 1.1.1.6
|
||||
retrieving revision 1.7
|
||||
diff -u -p -r1.1.1.6 -r1.7
|
||||
--- bgpctl/parser.c 14 Feb 2010 20:20:14 -0000 1.1.1.6
|
||||
+++ bgpctl/parser.c 13 Oct 2012 18:35:56 -0000 1.7
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* $OpenBSD: parser.c,v 1.54 2009/06/12 16:44:02 claudio Exp $ */
|
||||
+/* $OpenBSD: parser.c,v 1.64 2012/03/27 18:24:11 claudio Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
|
||||
@@ -16,11 +16,16 @@
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
+#if defined(__FreeBSD__) /* compat */
|
||||
+#include "openbsd-compat.h"
|
||||
+#endif /* defined(__FreeBSD__) */
|
||||
+
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
+#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
@@ -52,7 +57,9 @@ enum token_type {
|
||||
PREPSELF,
|
||||
WEIGHT,
|
||||
FAMILY,
|
||||
- GETOPT
|
||||
+ GETOPT,
|
||||
+ RTABLE,
|
||||
+ FILENAME
|
||||
};
|
||||
|
||||
enum getopts {
|
||||
@@ -72,14 +79,18 @@ static const struct token t_show[];
|
||||
static const struct token t_show_summary[];
|
||||
static const struct token t_show_fib[];
|
||||
static const struct token t_show_rib[];
|
||||
+static const struct token t_show_mrt[];
|
||||
+static const struct token t_show_mrt_file[];
|
||||
static const struct token t_show_rib_neigh[];
|
||||
+static const struct token t_show_mrt_neigh[];
|
||||
static const struct token t_show_rib_rib[];
|
||||
static const struct token t_show_neighbor[];
|
||||
static const struct token t_show_neighbor_modifiers[];
|
||||
static const struct token t_fib[];
|
||||
static const struct token t_neighbor[];
|
||||
static const struct token t_neighbor_modifiers[];
|
||||
-static const struct token t_show_as[];
|
||||
+static const struct token t_show_rib_as[];
|
||||
+static const struct token t_show_mrt_as[];
|
||||
static const struct token t_show_prefix[];
|
||||
static const struct token t_show_ip[];
|
||||
static const struct token t_show_community[];
|
||||
@@ -97,6 +108,9 @@ static const struct token t_prepself[];
|
||||
static const struct token t_weight[];
|
||||
static const struct token t_irrfilter[];
|
||||
static const struct token t_irrfilter_opts[];
|
||||
+static const struct token t_log[];
|
||||
+static const struct token t_fib_table[];
|
||||
+static const struct token t_show_fib_table[];
|
||||
|
||||
static const struct token t_main[] = {
|
||||
{ KEYWORD, "reload", RELOAD, NULL},
|
||||
@@ -105,6 +119,7 @@ static const struct token t_main[] = {
|
||||
{ KEYWORD, "neighbor", NEIGHBOR, t_neighbor},
|
||||
{ KEYWORD, "network", NONE, t_network},
|
||||
{ KEYWORD, "irrfilter", IRRFILTER, t_irrfilter},
|
||||
+ { KEYWORD, "log", NONE, t_log},
|
||||
{ ENDTOKEN, "", NONE, NULL}
|
||||
};
|
||||
|
||||
@@ -116,8 +131,10 @@ static const struct token t_show[] = {
|
||||
{ KEYWORD, "network", NETWORK_SHOW, t_network_show},
|
||||
{ KEYWORD, "nexthop", SHOW_NEXTHOP, NULL},
|
||||
{ KEYWORD, "rib", SHOW_RIB, t_show_rib},
|
||||
+ { KEYWORD, "tables", SHOW_FIB_TABLES, NULL},
|
||||
{ KEYWORD, "ip", NONE, t_show_ip},
|
||||
{ KEYWORD, "summary", SHOW_SUMMARY, t_show_summary},
|
||||
+ { KEYWORD, "mrt", SHOW_MRT, t_show_mrt},
|
||||
{ ENDTOKEN, "", NONE, NULL}
|
||||
};
|
||||
|
||||
@@ -128,24 +145,26 @@ static const struct token t_show_summary
|
||||
};
|
||||
|
||||
static const struct token t_show_fib[] = {
|
||||
- { NOTOKEN, "", NONE, NULL},
|
||||
- { FLAG, "connected", F_CONNECTED, t_show_fib},
|
||||
- { FLAG, "static", F_STATIC, t_show_fib},
|
||||
- { FLAG, "bgp", F_BGPD_INSERTED, t_show_fib},
|
||||
- { FLAG, "nexthop", F_NEXTHOP, t_show_fib},
|
||||
- { FAMILY, "", NONE, t_show_fib},
|
||||
- { ADDRESS, "", NONE, NULL},
|
||||
- { ENDTOKEN, "", NONE, NULL}
|
||||
+ { NOTOKEN, "", NONE, NULL},
|
||||
+ { FLAG, "connected", F_CONNECTED, t_show_fib},
|
||||
+ { FLAG, "static", F_STATIC, t_show_fib},
|
||||
+ { FLAG, "bgp", F_BGPD_INSERTED, t_show_fib},
|
||||
+ { FLAG, "nexthop", F_NEXTHOP, t_show_fib},
|
||||
+ { KEYWORD, "table", NONE, t_show_fib_table},
|
||||
+ { FAMILY, "", NONE, t_show_fib},
|
||||
+ { ADDRESS, "", NONE, NULL},
|
||||
+ { ENDTOKEN, "", NONE, NULL}
|
||||
};
|
||||
|
||||
static const struct token t_show_rib[] = {
|
||||
{ NOTOKEN, "", NONE, NULL},
|
||||
- { ASTYPE, "as", AS_ALL, t_show_as},
|
||||
- { ASTYPE, "source-as", AS_SOURCE, t_show_as},
|
||||
- { ASTYPE, "transit-as", AS_TRANSIT, t_show_as},
|
||||
- { ASTYPE, "peer-as", AS_PEER, t_show_as},
|
||||
+ { ASTYPE, "as", AS_ALL, t_show_rib_as},
|
||||
+ { ASTYPE, "source-as", AS_SOURCE, t_show_rib_as},
|
||||
+ { ASTYPE, "transit-as", AS_TRANSIT, t_show_rib_as},
|
||||
+ { ASTYPE, "peer-as", AS_PEER, t_show_rib_as},
|
||||
{ ASTYPE, "empty-as", AS_EMPTY, t_show_rib},
|
||||
{ KEYWORD, "community", NONE, t_show_community},
|
||||
+ { FLAG, "selected", F_CTL_ACTIVE, t_show_rib},
|
||||
{ FLAG, "detail", F_CTL_DETAIL, t_show_rib},
|
||||
{ FLAG, "in", F_CTL_ADJ_IN, t_show_rib},
|
||||
{ FLAG, "out", F_CTL_ADJ_OUT, t_show_rib},
|
||||
@@ -158,12 +177,38 @@ static const struct token t_show_rib[] =
|
||||
{ ENDTOKEN, "", NONE, NULL}
|
||||
};
|
||||
|
||||
+
|
||||
+static const struct token t_show_mrt[] = {
|
||||
+ { NOTOKEN, "", NONE, NULL},
|
||||
+ { ASTYPE, "as", AS_ALL, t_show_mrt_as},
|
||||
+ { ASTYPE, "source-as", AS_SOURCE, t_show_mrt_as},
|
||||
+ { ASTYPE, "transit-as", AS_TRANSIT, t_show_mrt_as},
|
||||
+ { ASTYPE, "peer-as", AS_PEER, t_show_mrt_as},
|
||||
+ { ASTYPE, "empty-as", AS_EMPTY, t_show_mrt},
|
||||
+ { FLAG, "detail", F_CTL_DETAIL, t_show_mrt},
|
||||
+ { KEYWORD, "neighbor", NONE, t_show_mrt_neigh},
|
||||
+ { KEYWORD, "file", NONE, t_show_mrt_file},
|
||||
+ { FAMILY, "", NONE, t_show_mrt},
|
||||
+ { PREFIX, "", NONE, t_show_prefix},
|
||||
+ { ENDTOKEN, "", NONE, NULL}
|
||||
+};
|
||||
+
|
||||
+static const struct token t_show_mrt_file[] = {
|
||||
+ { FILENAME, "", NONE, t_show_mrt},
|
||||
+ { ENDTOKEN, "", NONE, NULL}
|
||||
+};
|
||||
+
|
||||
static const struct token t_show_rib_neigh[] = {
|
||||
{ PEERADDRESS, "", NONE, t_show_rib},
|
||||
{ PEERDESC, "", NONE, t_show_rib},
|
||||
{ ENDTOKEN, "", NONE, NULL}
|
||||
};
|
||||
|
||||
+static const struct token t_show_mrt_neigh[] = {
|
||||
+ { PEERADDRESS, "", NONE, t_show_mrt},
|
||||
+ { ENDTOKEN, "", NONE, NULL}
|
||||
+};
|
||||
+
|
||||
static const struct token t_show_rib_rib[] = {
|
||||
{ RIBNAME, "", NONE, t_show_rib},
|
||||
{ ENDTOKEN, "", NONE, NULL}
|
||||
@@ -187,6 +232,7 @@ static const struct token t_show_neighbo
|
||||
static const struct token t_fib[] = {
|
||||
{ KEYWORD, "couple", FIB_COUPLE, NULL},
|
||||
{ KEYWORD, "decouple", FIB_DECOUPLE, NULL},
|
||||
+ { KEYWORD, "table", NONE, t_fib_table},
|
||||
{ ENDTOKEN, "", NONE, NULL}
|
||||
};
|
||||
|
||||
@@ -204,11 +250,16 @@ static const struct token t_neighbor_mod
|
||||
{ ENDTOKEN, "", NONE, NULL}
|
||||
};
|
||||
|
||||
-static const struct token t_show_as[] = {
|
||||
+static const struct token t_show_rib_as[] = {
|
||||
{ ASNUM, "", NONE, t_show_rib},
|
||||
{ ENDTOKEN, "", NONE, NULL}
|
||||
};
|
||||
|
||||
+static const struct token t_show_mrt_as[] = {
|
||||
+ { ASNUM, "", NONE, t_show_mrt},
|
||||
+ { ENDTOKEN, "", NONE, NULL}
|
||||
+};
|
||||
+
|
||||
static const struct token t_show_prefix[] = {
|
||||
{ NOTOKEN, "", NONE, NULL},
|
||||
{ FLAG, "all", F_LONGER, NULL},
|
||||
@@ -231,6 +282,7 @@ static const struct token t_network[] =
|
||||
{ KEYWORD, "delete", NETWORK_REMOVE, t_prefix},
|
||||
{ KEYWORD, "flush", NETWORK_FLUSH, NULL},
|
||||
{ KEYWORD, "show", NETWORK_SHOW, t_network_show},
|
||||
+ { KEYWORD, "mrt", NETWORK_MRT, t_show_mrt},
|
||||
{ ENDTOKEN, "", NONE, NULL}
|
||||
};
|
||||
|
||||
@@ -311,6 +363,22 @@ static const struct token t_irrfilter_op
|
||||
{ ENDTOKEN, "", NONE, NULL}
|
||||
};
|
||||
|
||||
+static const struct token t_log[] = {
|
||||
+ { KEYWORD, "verbose", LOG_VERBOSE, NULL},
|
||||
+ { KEYWORD, "brief", LOG_BRIEF, NULL},
|
||||
+ { ENDTOKEN, "", NONE, NULL}
|
||||
+};
|
||||
+
|
||||
+static const struct token t_fib_table[] = {
|
||||
+ { RTABLE, "", NONE, t_fib},
|
||||
+ { ENDTOKEN, "", NONE, NULL}
|
||||
+};
|
||||
+
|
||||
+static const struct token t_show_fib_table[] = {
|
||||
+ { RTABLE, "", NONE, t_show_fib},
|
||||
+ { ENDTOKEN, "", NONE, NULL}
|
||||
+};
|
||||
+
|
||||
static struct parse_result res;
|
||||
|
||||
const struct token *match_token(int *argc, char **argv[],
|
||||
@@ -404,15 +472,22 @@ match_token(int *argc, char **argv[], co
|
||||
case FAMILY:
|
||||
if (word == NULL)
|
||||
break;
|
||||
- if (!strcmp(word, "inet") || !strcmp(word, "IPv4")) {
|
||||
+ if (!strcmp(word, "inet") ||
|
||||
+ !strcasecmp(word, "IPv4")) {
|
||||
match++;
|
||||
t = &table[i];
|
||||
- res.af = AF_INET;
|
||||
+ res.aid = AID_INET;
|
||||
}
|
||||
- if (!strcmp(word, "inet6") || !strcmp(word, "IPv6")) {
|
||||
+ if (!strcmp(word, "inet6") ||
|
||||
+ !strcasecmp(word, "IPv6")) {
|
||||
match++;
|
||||
t = &table[i];
|
||||
- res.af = AF_INET6;
|
||||
+ res.aid = AID_INET6;
|
||||
+ }
|
||||
+ if (!strcasecmp(word, "VPNv4")) {
|
||||
+ match++;
|
||||
+ t = &table[i];
|
||||
+ res.aid = AID_VPN_IPv4;
|
||||
}
|
||||
break;
|
||||
case ADDRESS:
|
||||
@@ -485,6 +560,7 @@ match_token(int *argc, char **argv[], co
|
||||
case PREPNBR:
|
||||
case PREPSELF:
|
||||
case WEIGHT:
|
||||
+ case RTABLE:
|
||||
if (word != NULL && strlen(word) > 0 &&
|
||||
parse_number(word, &res, table[i].type)) {
|
||||
match++;
|
||||
@@ -518,6 +594,23 @@ match_token(int *argc, char **argv[], co
|
||||
t = &table[i];
|
||||
}
|
||||
break;
|
||||
+ case FILENAME:
|
||||
+ if (word != NULL && strlen(word) > 0) {
|
||||
+ if ((res.mrtfd = open(word, O_RDONLY)) == -1) {
|
||||
+ /*
|
||||
+ * ignore error if path has no / and
|
||||
+ * does not exist. In hope to print
|
||||
+ * usage.
|
||||
+ */
|
||||
+ if (errno == ENOENT &&
|
||||
+ !strchr(word, '/'))
|
||||
+ break;
|
||||
+ err(1, "mrt open(%s)", word);
|
||||
+ }
|
||||
+ match++;
|
||||
+ t = &table[i];
|
||||
+ }
|
||||
+ break;
|
||||
case ENDTOKEN:
|
||||
break;
|
||||
}
|
||||
@@ -577,6 +670,9 @@ show_valid_args(const struct token table
|
||||
case WEIGHT:
|
||||
fprintf(stderr, " <number>\n");
|
||||
break;
|
||||
+ case RTABLE:
|
||||
+ fprintf(stderr, " <rtableid>\n");
|
||||
+ break;
|
||||
case NEXTHOP:
|
||||
fprintf(stderr, " <address>\n");
|
||||
break;
|
||||
@@ -584,11 +680,14 @@ show_valid_args(const struct token table
|
||||
fprintf(stderr, " <pftable>\n");
|
||||
break;
|
||||
case FAMILY:
|
||||
- fprintf(stderr, " [ inet | inet6 | IPv4 | IPv6 ]\n");
|
||||
+ fprintf(stderr, " [ inet | inet6 | IPv4 | IPv6 | VPNv4 ]\n");
|
||||
break;
|
||||
case GETOPT:
|
||||
fprintf(stderr, " <options>\n");
|
||||
break;
|
||||
+ case FILENAME:
|
||||
+ fprintf(stderr, " <filename>\n");
|
||||
+ break;
|
||||
case ENDTOKEN:
|
||||
break;
|
||||
}
|
||||
@@ -608,7 +707,7 @@ parse_addr(const char *word, struct bgpd
|
||||
bzero(&ina, sizeof(ina));
|
||||
|
||||
if (inet_net_pton(AF_INET, word, &ina, sizeof(ina)) != -1) {
|
||||
- addr->af = AF_INET;
|
||||
+ addr->aid = AID_INET;
|
||||
addr->v4 = ina;
|
||||
return (1);
|
||||
}
|
||||
@@ -618,13 +717,7 @@ parse_addr(const char *word, struct bgpd
|
||||
hints.ai_socktype = SOCK_DGRAM; /*dummy*/
|
||||
hints.ai_flags = AI_NUMERICHOST;
|
||||
if (getaddrinfo(word, "0", &hints, &r) == 0) {
|
||||
- addr->af = AF_INET6;
|
||||
- memcpy(&addr->v6,
|
||||
- &((struct sockaddr_in6 *)r->ai_addr)->sin6_addr,
|
||||
- sizeof(addr->v6));
|
||||
- addr->scope_id =
|
||||
- ((struct sockaddr_in6 *)r->ai_addr)->sin6_scope_id;
|
||||
-
|
||||
+ sa2addr(r->ai_addr, addr);
|
||||
freeaddrinfo(r);
|
||||
return (1);
|
||||
}
|
||||
@@ -647,7 +740,7 @@ parse_prefix(const char *word, struct bg
|
||||
if ((p = strrchr(word, '/')) != NULL) {
|
||||
mask = strtonum(p + 1, 0, 128, &errstr);
|
||||
if (errstr)
|
||||
- errx(1, "invalid netmask: %s", errstr);
|
||||
+ errx(1, "netmask %s", errstr);
|
||||
|
||||
if ((ps = malloc(strlen(word) - strlen(p) + 1)) == NULL)
|
||||
err(1, "parse_prefix: malloc");
|
||||
@@ -663,15 +756,15 @@ parse_prefix(const char *word, struct bg
|
||||
if (parse_addr(word, addr) == 0)
|
||||
return (0);
|
||||
|
||||
- switch (addr->af) {
|
||||
- case AF_INET:
|
||||
+ switch (addr->aid) {
|
||||
+ case AID_INET:
|
||||
if (mask == -1)
|
||||
mask = 32;
|
||||
if (mask > 32)
|
||||
errx(1, "invalid netmask: too large");
|
||||
addr->v4.s_addr = addr->v4.s_addr & htonl(prefixlen2mask(mask));
|
||||
break;
|
||||
- case AF_INET6:
|
||||
+ case AID_INET6:
|
||||
if (mask == -1)
|
||||
mask = 128;
|
||||
inet6applymask(&addr->v6, &addr->v6, mask);
|
||||
@@ -706,7 +799,7 @@ parse_asnum(const char *word, u_int32_t
|
||||
if (errstr)
|
||||
errx(1, "AS number is %s: %s", errstr, word);
|
||||
} else {
|
||||
- uval = strtonum(word, 0, ASNUM_MAX - 1, &errstr);
|
||||
+ uval = strtonum(word, 0, UINT_MAX, &errstr);
|
||||
if (errstr)
|
||||
errx(1, "AS number is %s: %s", errstr, word);
|
||||
}
|
||||
@@ -730,6 +823,11 @@ parse_number(const char *word, struct pa
|
||||
errx(1, "number is %s: %s", errstr, word);
|
||||
|
||||
/* number was parseable */
|
||||
+ if (type == RTABLE) {
|
||||
+ r->rtableid = uval;
|
||||
+ return (1);
|
||||
+ }
|
||||
+
|
||||
if ((fs = calloc(1, sizeof(struct filter_set))) == NULL)
|
||||
err(1, NULL);
|
||||
switch (type) {
|
||||
@@ -882,8 +980,14 @@ bgpctl_getopt(int *argc, char **argv[],
|
||||
int ch;
|
||||
|
||||
optind = optreset = 1;
|
||||
- while ((ch = getopt((*argc) + 1, (*argv) - 1, "o:")) != -1) {
|
||||
+ while ((ch = getopt((*argc) + 1, (*argv) - 1, "46o:")) != -1) {
|
||||
switch (ch) {
|
||||
+ case '4':
|
||||
+ res.flags = (res.flags | F_IPV4) & ~F_IPV6;
|
||||
+ break;
|
||||
+ case '6':
|
||||
+ res.flags = (res.flags | F_IPV6) & ~F_IPV4;
|
||||
+ break;
|
||||
case 'o':
|
||||
res.irr_outdir = optarg;
|
||||
break;
|
55
net/openbgpd/files/patch-bgpctl_parser.h
Normal file
55
net/openbgpd/files/patch-bgpctl_parser.h
Normal file
@ -0,0 +1,55 @@
|
||||
Index: bgpctl/parser.h
|
||||
===================================================================
|
||||
RCS file: /home/cvs/private/hrs/openbgpd/bgpctl/parser.h,v
|
||||
retrieving revision 1.1.1.6
|
||||
retrieving revision 1.1.1.9
|
||||
diff -u -p -r1.1.1.6 -r1.1.1.9
|
||||
--- bgpctl/parser.h 14 Feb 2010 20:20:14 -0000 1.1.1.6
|
||||
+++ bgpctl/parser.h 13 Oct 2012 18:22:53 -0000 1.1.1.9
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* $OpenBSD: parser.h,v 1.19 2009/06/06 06:05:41 claudio Exp $ */
|
||||
+/* $OpenBSD: parser.h,v 1.23 2011/09/21 10:37:51 claudio Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
|
||||
@@ -29,7 +29,9 @@ enum actions {
|
||||
SHOW_NEIGHBOR_TIMERS,
|
||||
SHOW_NEIGHBOR_TERSE,
|
||||
SHOW_FIB,
|
||||
+ SHOW_FIB_TABLES,
|
||||
SHOW_RIB,
|
||||
+ SHOW_MRT,
|
||||
SHOW_RIB_MEM,
|
||||
SHOW_NEXTHOP,
|
||||
SHOW_INTERFACE,
|
||||
@@ -37,6 +39,8 @@ enum actions {
|
||||
FIB,
|
||||
FIB_COUPLE,
|
||||
FIB_DECOUPLE,
|
||||
+ LOG_VERBOSE,
|
||||
+ LOG_BRIEF,
|
||||
NEIGHBOR,
|
||||
NEIGHBOR_UP,
|
||||
NEIGHBOR_DOWN,
|
||||
@@ -46,6 +50,7 @@ enum actions {
|
||||
NETWORK_REMOVE,
|
||||
NETWORK_FLUSH,
|
||||
NETWORK_SHOW,
|
||||
+ NETWORK_MRT,
|
||||
IRRFILTER
|
||||
};
|
||||
|
||||
@@ -59,9 +64,11 @@ struct parse_result {
|
||||
char rib[PEER_DESCR_LEN];
|
||||
char *irr_outdir;
|
||||
int flags;
|
||||
- enum actions action;
|
||||
+ u_int rtableid;
|
||||
+ enum actions action;
|
||||
u_int8_t prefixlen;
|
||||
- sa_family_t af;
|
||||
+ u_int8_t aid;
|
||||
+ int mrtfd;
|
||||
};
|
||||
|
||||
__dead void usage(void);
|
18
net/openbgpd/files/patch-bgpctl_whois.c
Normal file
18
net/openbgpd/files/patch-bgpctl_whois.c
Normal file
@ -0,0 +1,18 @@
|
||||
Index: bgpctl/whois.c
|
||||
===================================================================
|
||||
RCS file: /home/cvs/private/hrs/openbgpd/bgpctl/whois.c,v
|
||||
retrieving revision 1.1.1.5
|
||||
retrieving revision 1.1.1.7
|
||||
diff -u -p -r1.1.1.5 -r1.1.1.7
|
||||
--- bgpctl/whois.c 14 Feb 2010 20:20:14 -0000 1.1.1.5
|
||||
+++ bgpctl/whois.c 13 Oct 2012 18:22:54 -0000 1.1.1.7
|
||||
@@ -68,7 +68,8 @@ char *qtype_opts[] = {
|
||||
"",
|
||||
"-T aut-num",
|
||||
"-K -T as-set",
|
||||
- "-K -T route -i origin"
|
||||
+ "-K -T route -i origin",
|
||||
+ "-K -T route6 -i origin"
|
||||
};
|
||||
|
||||
char *server = "whois.radb.net";
|
30
net/openbgpd/files/patch-bgpd_Makefile
Normal file
30
net/openbgpd/files/patch-bgpd_Makefile
Normal file
@ -0,0 +1,30 @@
|
||||
--- bgpd/Makefile.orig 2013-02-21 19:20:05.000000000 +0000
|
||||
+++ bgpd/Makefile 2013-02-21 19:20:54.000000000 +0000
|
||||
@@ -1,15 +1,25 @@
|
||||
# $OpenBSD: Makefile,v 1.28 2009/06/25 14:14:54 deraadt Exp $
|
||||
|
||||
+.PATH: ${.CURDIR}/.. ${.CURDIR}/../openbsd-compat
|
||||
+
|
||||
+CONFFILE?= ${PREFIX}/etc/bgpd.conf
|
||||
+
|
||||
PROG= bgpd
|
||||
-SRCS= bgpd.c buffer.c session.c log.c parse.y config.c imsg.c \
|
||||
+SRCS= bgpd.c session.c log.c parse.y config.c \
|
||||
rde.c rde_rib.c rde_decide.c rde_prefix.c mrt.c kroute.c \
|
||||
control.c pfkey.c rde_update.c rde_attr.c printconf.c \
|
||||
- rde_filter.c pftable.c name2id.c util.c carp.c timer.c
|
||||
+ rde_filter.c pftable.c name2id.c util.c carp.c timer.c \
|
||||
+ imsg.c imsg-buffer.c
|
||||
CFLAGS+= -Wall -I${.CURDIR}
|
||||
+CFLAGS+= -I${.CURDIR}/../openbsd-compat
|
||||
CFLAGS+= -Wstrict-prototypes -Wmissing-prototypes
|
||||
CFLAGS+= -Wmissing-declarations
|
||||
CFLAGS+= -Wshadow -Wpointer-arith -Wcast-qual
|
||||
CFLAGS+= -Wsign-compare
|
||||
+CFLAGS+= -DCONFFILE=\"${CONFFILE}\"
|
||||
+.if defined(IPV6_LINKLOCAL_PEER)
|
||||
+CFLAGS+= -DIPV6_LINKLOCAL_PEER
|
||||
+.endif
|
||||
YFLAGS=
|
||||
MAN= bgpd.8 bgpd.conf.5
|
||||
|
348
net/openbgpd/files/patch-bgpd_bgpd.8
Normal file
348
net/openbgpd/files/patch-bgpd_bgpd.8
Normal file
@ -0,0 +1,348 @@
|
||||
Index: bgpd/bgpd.8
|
||||
===================================================================
|
||||
RCS file: /home/cvs/private/hrs/openbgpd/bgpd/bgpd.8,v
|
||||
retrieving revision 1.1.1.8
|
||||
retrieving revision 1.10
|
||||
diff -u -p -r1.1.1.8 -r1.10
|
||||
--- bgpd/bgpd.8 14 Feb 2010 20:19:57 -0000 1.1.1.8
|
||||
+++ bgpd/bgpd.8 13 Oct 2012 18:36:00 -0000 1.10
|
||||
@@ -1,4 +1,4 @@
|
||||
-.\" $OpenBSD: bgpd.8,v 1.28 2009/01/13 23:01:36 sthen Exp $
|
||||
+.\" $OpenBSD: bgpd.8,v 1.45 2012/08/24 20:13:03 jmc Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
|
||||
.\"
|
||||
@@ -14,7 +14,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
-.Dd $Mdocdate: January 13 2009 $
|
||||
+.Dd $Mdocdate: August 24 2012 $
|
||||
.Dt BGPD 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@@ -24,12 +24,8 @@
|
||||
.Nm bgpd
|
||||
.Bk -words
|
||||
.Op Fl cdnv
|
||||
-.Oo Xo
|
||||
-.Fl D Ar macro Ns = Ns Ar value Oc
|
||||
-.Xc
|
||||
+.Op Fl D Ar macro Ns = Ns Ar value
|
||||
.Op Fl f Ar file
|
||||
-.Op Fl r Ar path
|
||||
-.Op Fl s Ar path
|
||||
.Ek
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
@@ -42,15 +38,106 @@ concerning
|
||||
with other BGP systems.
|
||||
.Nm
|
||||
uses the Border Gateway Protocol, Version 4,
|
||||
-as described in RFC 1771.
|
||||
-Please refer to that document for more information about BGP.
|
||||
+as described in RFC 4271.
|
||||
+.Pp
|
||||
+BGP is an exterior gateway protocol using a multiple step decision process
|
||||
+to find the best path.
|
||||
+Advanced filtering can be used to influence the route
|
||||
+decision for traffic engineering.
|
||||
+The session engine of
|
||||
+.Nm
|
||||
+is responsible for maintaining the TCP session with each neighbor.
|
||||
+Updates are passed to the Route Decision Engine (RDE) where the paths
|
||||
+are filtered and used to compute a Routing Information Base (RIB).
|
||||
+The parent process is responsible for keeping the RIB in sync with
|
||||
+the kernel routing table.
|
||||
+.Pp
|
||||
+The route decision process selects the best path by evaluating all paths to
|
||||
+the same destination.
|
||||
+The decision process continues to the next step if paths have equal attributes.
|
||||
+Paths that are less preferred are taken out of consideration until there is
|
||||
+only one path left.
|
||||
+.Bl -enum -width 42 -offset bula
|
||||
+.It
|
||||
+All paths with errors or loops are not eligible.
|
||||
+.It
|
||||
+Paths with an unreachable nexthop are not eligible.
|
||||
+After this step all remaining paths are valid.
|
||||
+.It
|
||||
+The path with the highest
|
||||
+.Em LOCAL_PREF
|
||||
+is selected.
|
||||
+.It
|
||||
+The path with the shortest
|
||||
+.Em AS path
|
||||
+attribute is selected.
|
||||
+.It
|
||||
+The
|
||||
+.Em ORIGIN
|
||||
+attribute is compared.
|
||||
+The order is IGP before EGP before incomplete origins.
|
||||
+.It
|
||||
+The path with the lowest
|
||||
+.Em MULTI_EXIT_DISC
|
||||
+metric is selected.
|
||||
+Normally, this value is only considered when choosing between multiple
|
||||
+routes sent by the same neighbouring AS.
|
||||
+However, if
|
||||
+.Dq Li rde med compare always
|
||||
+is set in the configuration, the metric is compared for routes sent by any AS.
|
||||
+.It
|
||||
+Comparison of the BGP session type.
|
||||
+Paths learned over an external (EBGP) session are preferred over those
|
||||
+learned via an internal (IBGP) session.
|
||||
+.It
|
||||
+The path with the lowest local
|
||||
+.Em weight
|
||||
+is selected.
|
||||
+.It
|
||||
+If
|
||||
+.Dq Li rde route-age evaluate
|
||||
+is set then the oldest path is selected.
|
||||
+.It
|
||||
+The path coming from the neighbor with the lowest
|
||||
+.Em BGP ID
|
||||
+wins.
|
||||
+If the
|
||||
+.Em ORIGINATOR_ID
|
||||
+attribute is present that value will be used in the comparison instead.
|
||||
+.It
|
||||
+The path with the shortest
|
||||
+.Em CLUSTER_LIST
|
||||
+attribute is selected.
|
||||
+If it is not present then a length of 0 is used in the comparison.
|
||||
+.It
|
||||
+The path coming from the peer with the lowest IP address is selected.
|
||||
+IPv4 sessions will be preferred over IPv6 ones.
|
||||
+.It
|
||||
+In case of locally announced prefixes
|
||||
+.Nm
|
||||
+will prefer statically set prefixes over dynamically inserted ones.
|
||||
+.El
|
||||
+.Pp
|
||||
+Attributes set by filters can be used to tip the decision process to prefer
|
||||
+particular paths over others.
|
||||
+This can be achieved by changing the
|
||||
+.Em localpref ,
|
||||
+.Em med ,
|
||||
+or
|
||||
+.Em weight
|
||||
+attributes.
|
||||
+AS path prepending or changing the
|
||||
+.Em med
|
||||
+or
|
||||
+.Em origin
|
||||
+attribute can be used to influencing the routing behaviour on remote systems.
|
||||
.Pp
|
||||
.Nm
|
||||
is usually started at boot time, and can be enabled by
|
||||
setting the following in
|
||||
-.Pa /etc/rc.conf.local :
|
||||
+.Pa /etc/rc.conf :
|
||||
.Pp
|
||||
-.Dl bgpd_flags=\&"\&"
|
||||
+.Dl openbgpd_enable=\&"YES\&"
|
||||
.Pp
|
||||
See
|
||||
.Xr rc 8
|
||||
@@ -117,25 +204,16 @@ Use
|
||||
.Ar file
|
||||
as the configuration file,
|
||||
instead of the default
|
||||
-.Pa /etc/bgpd.conf .
|
||||
+.Pa %%PREFIX%%/etc/bgpd.conf .
|
||||
.It Fl n
|
||||
Configtest mode.
|
||||
Only check the configuration file for validity.
|
||||
-.It Fl r Ar path
|
||||
-Open a second, restricted, control socket that
|
||||
-.Xr bgpctl 8
|
||||
-can use.
|
||||
-Only
|
||||
-.Em show
|
||||
-requests are allowed on this socket.
|
||||
-.It Fl s Ar path
|
||||
-Use an alternate location for the default control socket.
|
||||
.It Fl v
|
||||
Produce more verbose output.
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -width "/var/run/bgpd.sockXXX" -compact
|
||||
-.It Pa /etc/bgpd.conf
|
||||
+.It Pa %%PREFIX%%/etc/bgpd.conf
|
||||
default
|
||||
.Nm
|
||||
configuration file
|
||||
@@ -149,55 +227,144 @@ control socket
|
||||
.Xr bgpctl 8 ,
|
||||
.Xr bgplg 8 ,
|
||||
.Xr bgplgsh 8
|
||||
+.Sh STANDARDS
|
||||
.Rs
|
||||
-.%R RFC 1771
|
||||
-.%T "A Border Gateway Protocol 4 (BGP-4)"
|
||||
-.%D March 1995
|
||||
-.Re
|
||||
-.Rs
|
||||
-.%R RFC 1997
|
||||
-.%T "BGP Communities Attribute"
|
||||
+.%A R. Chandra
|
||||
+.%A P. Traina
|
||||
+.%A "T. Li"
|
||||
.%D August 1996
|
||||
+.%R RFC 1997
|
||||
+.%T BGP Communities Attribute
|
||||
.Re
|
||||
+.Pp
|
||||
.Rs
|
||||
-.%R RFC 2385
|
||||
-.%T "Protection of BGP Sessions via the TCP MD5 Signature Option"
|
||||
+.%A A. Heffernan
|
||||
.%D August 1998
|
||||
+.%R RFC 2385
|
||||
+.%T Protection of BGP Sessions via the TCP MD5 Signature Option
|
||||
.Re
|
||||
+.Pp
|
||||
.Rs
|
||||
-.%R RFC 2796
|
||||
-.%T "BGP Route Reflection - An Alternative to Full Mesh IBGP"
|
||||
-.%D April 2000
|
||||
+.%A P. Marques
|
||||
+.%A F. Dupont
|
||||
+.%D March 1999
|
||||
+.%R RFC 2545
|
||||
+.%T Use of BGP-4 Multiprotocol Extensions for IPv6 Inter-Domain Routing
|
||||
.Re
|
||||
+.Pp
|
||||
.Rs
|
||||
-.%R RFC 2918
|
||||
-.%T "Route Refresh Capability for BGP-4"
|
||||
+.%A E. Chen
|
||||
.%D September 2000
|
||||
+.%R RFC 2918
|
||||
+.%T Route Refresh Capability for BGP-4
|
||||
.Re
|
||||
+.Pp
|
||||
.Rs
|
||||
-.%R RFC 3392
|
||||
-.%T "Capabilities Advertisement with BGP-4"
|
||||
-.%D January 1999
|
||||
+.%A G. Huston
|
||||
+.%D April 2004
|
||||
+.%R RFC 3765
|
||||
+.%T NOPEER Community for Border Gateway Protocol (BGP) Route Scope Control
|
||||
.Re
|
||||
+.Pp
|
||||
.Rs
|
||||
-.%R RFC 3682
|
||||
-.%T "The Generalized TTL Security Mechanism (GTSM)"
|
||||
-.%D February 2004
|
||||
+.%A Y. Rekhter
|
||||
+.%A "T. Li"
|
||||
+.%A S. Hares
|
||||
+.%D January 2006
|
||||
+.%R RFC 4271
|
||||
+.%T A Border Gateway Protocol 4 (BGP-4)
|
||||
.Re
|
||||
+.Pp
|
||||
.Rs
|
||||
-.%R RFC 3765
|
||||
-.%T "NOPEER Community for Border Gateway Protocol"
|
||||
-.%D April 2004
|
||||
+.%A S. Sangli
|
||||
+.%A D. Tappan
|
||||
+.%A Y. Rekhter
|
||||
+.%D February 2006
|
||||
+.%R RFC 4360
|
||||
+.%T BGP Extended Communities Attribute
|
||||
.Re
|
||||
+.Pp
|
||||
.Rs
|
||||
-.%R RFC 4760
|
||||
-.%T "Multiprotocol Extensions for BGP-4"
|
||||
+.%A E. Rosen
|
||||
+.%A Y. Rekhter
|
||||
+.%D February 2006
|
||||
+.%R RFC 4364
|
||||
+.%T BGP/MPLS IP Virtual Private Networks (VPNs)
|
||||
+.Re
|
||||
+.Pp
|
||||
+.Rs
|
||||
+.%A T. Bates
|
||||
+.%A E. Chen
|
||||
+.%A R. Chandra
|
||||
+.%D April 2006
|
||||
+.%R RFC 4456
|
||||
+.%T "BGP Route Reflection: An Alternative to Full Mesh Internal BGP (IBGP)"
|
||||
+.Re
|
||||
+.Pp
|
||||
+.Rs
|
||||
+.%A E. Chen
|
||||
+.%A V. Gillet
|
||||
+.%D April 2006
|
||||
+.%R RFC 4486
|
||||
+.%T Subcodes for BGP Cease Notification Message
|
||||
+.Re
|
||||
+.Pp
|
||||
+.Rs
|
||||
+.%A T. Bates
|
||||
+.%A R. Chandra
|
||||
+.%A D. Katz
|
||||
+.%A Y. Rekhter
|
||||
.%D January 2007
|
||||
+.%R RFC 4760
|
||||
+.%T Multiprotocol Extensions for BGP-4
|
||||
.Re
|
||||
+.Pp
|
||||
.Rs
|
||||
-.%R RFC 4893
|
||||
-.%T "BGP Support for Four-octet AS Number Space"
|
||||
+.%A Q. Vohra
|
||||
+.%A E. Chen
|
||||
.%D May 2007
|
||||
+.%R RFC 4893
|
||||
+.%T BGP Support for Four-octet AS Number Space
|
||||
+.Re
|
||||
+.Pp
|
||||
+.Rs
|
||||
+.%A V. Gill
|
||||
+.%A J. Heasley
|
||||
+.%A D. Meyer
|
||||
+.%A P. Savola
|
||||
+.%A C. Pignatoro
|
||||
+.%D October 2007
|
||||
+.%R RFC 5082
|
||||
+.%T The Generalized TTL Security Mechanism (GTSM)
|
||||
+.Re
|
||||
+.Pp
|
||||
+.Rs
|
||||
+.%A J. Scudder
|
||||
+.%A R. Chandra
|
||||
+.%D February 2009
|
||||
+.%R RFC 5492
|
||||
+.%T Capabilities Advertisement with BGP-4
|
||||
+.Re
|
||||
+.Pp
|
||||
+.Rs
|
||||
+.%D April 2009
|
||||
+.%R draft-ietf-idr-optional-transitive-00
|
||||
+.%T Error Handling for Optional Transitive BGP Attributes
|
||||
+.Re
|
||||
+.Pp
|
||||
+.Rs
|
||||
+.%D August 2011
|
||||
+.%R draft-ietf-grow-mrt-17
|
||||
+.%T MRT routing information export format
|
||||
+.Re
|
||||
+.Pp
|
||||
+.Rs
|
||||
+.%A J. Dong
|
||||
+.%A M. Chen
|
||||
+.%A A. Suryanarayana
|
||||
+.%D May 2012
|
||||
+.%R RFC 6608
|
||||
+.%T Subcodes for BGP Finite State Machine Error
|
||||
.Re
|
||||
.Sh HISTORY
|
||||
The
|
693
net/openbgpd/files/patch-bgpd_bgpd.c
Normal file
693
net/openbgpd/files/patch-bgpd_bgpd.c
Normal file
@ -0,0 +1,693 @@
|
||||
Index: bgpd/bgpd.c
|
||||
===================================================================
|
||||
RCS file: /home/cvs/private/hrs/openbgpd/bgpd/bgpd.c,v
|
||||
retrieving revision 1.1.1.7
|
||||
retrieving revision 1.1.1.12
|
||||
diff -u -p -r1.1.1.7 -r1.1.1.12
|
||||
--- bgpd/bgpd.c 14 Feb 2010 20:19:57 -0000 1.1.1.7
|
||||
+++ bgpd/bgpd.c 8 Dec 2012 10:37:08 -0000 1.1.1.12
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* $OpenBSD: bgpd.c,v 1.148 2009/06/07 00:30:23 claudio Exp $ */
|
||||
+/* $OpenBSD: bgpd.c,v 1.169 2012/09/18 09:45:51 claudio Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
|
||||
@@ -32,8 +32,8 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
-#include "mrt.h"
|
||||
#include "bgpd.h"
|
||||
+#include "mrt.h"
|
||||
#include "session.h"
|
||||
|
||||
void sighdlr(int);
|
||||
@@ -42,23 +42,23 @@ int main(int, char *[]);
|
||||
int check_child(pid_t, const char *);
|
||||
int send_filterset(struct imsgbuf *, struct filter_set_head *);
|
||||
int reconfigure(char *, struct bgpd_config *, struct mrt_head *,
|
||||
- struct peer **, struct filter_head *);
|
||||
+ struct peer **);
|
||||
int dispatch_imsg(struct imsgbuf *, int);
|
||||
+int control_setup(struct bgpd_config *);
|
||||
|
||||
int rfd = -1;
|
||||
-int cflags = 0;
|
||||
-struct filter_set_head *connectset;
|
||||
-struct filter_set_head *connectset6;
|
||||
-struct filter_set_head *staticset;
|
||||
-struct filter_set_head *staticset6;
|
||||
-volatile sig_atomic_t mrtdump = 0;
|
||||
-volatile sig_atomic_t quit = 0;
|
||||
-volatile sig_atomic_t sigchld = 0;
|
||||
-volatile sig_atomic_t reconfig = 0;
|
||||
-pid_t reconfpid = 0;
|
||||
+int cflags;
|
||||
+volatile sig_atomic_t mrtdump;
|
||||
+volatile sig_atomic_t quit;
|
||||
+volatile sig_atomic_t sigchld;
|
||||
+volatile sig_atomic_t reconfig;
|
||||
+pid_t reconfpid;
|
||||
+int reconfpending;
|
||||
struct imsgbuf *ibuf_se;
|
||||
struct imsgbuf *ibuf_rde;
|
||||
struct rib_names ribnames = SIMPLEQ_HEAD_INITIALIZER(ribnames);
|
||||
+char *cname;
|
||||
+char *rcname;
|
||||
|
||||
void
|
||||
sighdlr(int sig)
|
||||
@@ -86,8 +86,8 @@ usage(void)
|
||||
{
|
||||
extern char *__progname;
|
||||
|
||||
- fprintf(stderr, "usage: %s [-cdnv] ", __progname);
|
||||
- fprintf(stderr, "[-D macro=value] [-f file] [-r path] [-s path]\n");
|
||||
+ fprintf(stderr, "usage: %s [-cdnv] [-D macro=value] [-f file]\n",
|
||||
+ __progname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -101,15 +101,10 @@ int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
struct bgpd_config conf;
|
||||
- struct peer *peer_l, *p;
|
||||
struct mrt_head mrt_l;
|
||||
- struct network_head net_l;
|
||||
- struct filter_head *rules_l;
|
||||
- struct network *net;
|
||||
- struct filter_rule *r;
|
||||
+ struct peer *peer_l, *p;
|
||||
struct mrt *m;
|
||||
struct listen_addr *la;
|
||||
- struct rde_rib *rr;
|
||||
struct pollfd pfd[POLL_MAX];
|
||||
pid_t io_pid = 0, rde_pid = 0, pid;
|
||||
char *conffile;
|
||||
@@ -124,18 +119,13 @@ main(int argc, char *argv[])
|
||||
bgpd_process = PROC_MAIN;
|
||||
|
||||
log_init(1); /* log to stderr until daemonized */
|
||||
-
|
||||
- if ((rules_l = calloc(1, sizeof(struct filter_head))) == NULL)
|
||||
- err(1, NULL);
|
||||
+ log_verbose(1);
|
||||
|
||||
bzero(&conf, sizeof(conf));
|
||||
LIST_INIT(&mrt_l);
|
||||
- TAILQ_INIT(&net_l);
|
||||
- TAILQ_INIT(rules_l);
|
||||
peer_l = NULL;
|
||||
- conf.csock = SOCKET_NAME;
|
||||
|
||||
- while ((ch = getopt(argc, argv, "cdD:f:nr:s:v")) != -1) {
|
||||
+ while ((ch = getopt(argc, argv, "cdD:f:nv")) != -1) {
|
||||
switch (ch) {
|
||||
case 'c':
|
||||
conf.opts |= BGPD_OPT_FORCE_DEMOTE;
|
||||
@@ -158,12 +148,7 @@ main(int argc, char *argv[])
|
||||
if (conf.opts & BGPD_OPT_VERBOSE)
|
||||
conf.opts |= BGPD_OPT_VERBOSE2;
|
||||
conf.opts |= BGPD_OPT_VERBOSE;
|
||||
- break;
|
||||
- case 'r':
|
||||
- conf.rcsock = optarg;
|
||||
- break;
|
||||
- case 's':
|
||||
- conf.csock = optarg;
|
||||
+ log_verbose(1);
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
@@ -176,24 +161,22 @@ main(int argc, char *argv[])
|
||||
if (argc > 0)
|
||||
usage();
|
||||
|
||||
- if (parse_config(conffile, &conf, &mrt_l, &peer_l, &net_l, rules_l)) {
|
||||
- free(rules_l);
|
||||
- exit(1);
|
||||
- }
|
||||
-
|
||||
if (conf.opts & BGPD_OPT_NOACTION) {
|
||||
+ struct network_head net_l;
|
||||
+ struct rdomain_head rdom_l;
|
||||
+ struct filter_head rules_l;
|
||||
+
|
||||
+ if (parse_config(conffile, &conf, &mrt_l, &peer_l, &net_l,
|
||||
+ &rules_l, &rdom_l))
|
||||
+ exit(1);
|
||||
+
|
||||
if (conf.opts & BGPD_OPT_VERBOSE)
|
||||
- print_config(&conf, &ribnames, &net_l, peer_l, rules_l,
|
||||
- &mrt_l);
|
||||
+ print_config(&conf, &ribnames, &net_l, peer_l, &rules_l,
|
||||
+ &mrt_l, &rdom_l);
|
||||
else
|
||||
fprintf(stderr, "configuration OK\n");
|
||||
exit(0);
|
||||
}
|
||||
- cflags = conf.flags;
|
||||
- connectset = &conf.connectset;
|
||||
- staticset = &conf.staticset;
|
||||
- connectset6 = &conf.connectset6;
|
||||
- staticset6 = &conf.staticset6;
|
||||
|
||||
if (geteuid())
|
||||
errx(1, "need root privileges");
|
||||
@@ -202,6 +185,7 @@ main(int argc, char *argv[])
|
||||
errx(1, "unknown user %s", BGPD_USER);
|
||||
|
||||
log_init(debug);
|
||||
+ log_verbose(conf.opts & BGPD_OPT_VERBOSE);
|
||||
|
||||
if (!debug)
|
||||
daemon(1, 0);
|
||||
@@ -225,13 +209,9 @@ main(int argc, char *argv[])
|
||||
session_socket_blockmode(pipe_s2r_c[0], BM_NONBLOCK);
|
||||
session_socket_blockmode(pipe_s2r_c[1], BM_NONBLOCK);
|
||||
|
||||
- prepare_listeners(&conf);
|
||||
-
|
||||
/* fork children */
|
||||
- rde_pid = rde_main(&conf, peer_l, &net_l, rules_l, &mrt_l, &ribnames,
|
||||
- pipe_m2r, pipe_s2r, pipe_m2s, pipe_s2r_c, debug);
|
||||
- io_pid = session_main(&conf, peer_l, &net_l, rules_l, &mrt_l, &ribnames,
|
||||
- pipe_m2s, pipe_s2r, pipe_m2r, pipe_s2r_c);
|
||||
+ rde_pid = rde_main(pipe_m2r, pipe_s2r, pipe_m2s, pipe_s2r_c, debug);
|
||||
+ io_pid = session_main(pipe_m2s, pipe_s2r, pipe_m2r, pipe_s2r_c);
|
||||
|
||||
setproctitle("parent");
|
||||
|
||||
@@ -254,33 +234,12 @@ main(int argc, char *argv[])
|
||||
imsg_init(ibuf_se, pipe_m2s[0]);
|
||||
imsg_init(ibuf_rde, pipe_m2r[0]);
|
||||
mrt_init(ibuf_rde, ibuf_se);
|
||||
- if ((rfd = kr_init(!(conf.flags & BGPD_FLAG_NO_FIB_UPDATE),
|
||||
- conf.rtableid)) == -1)
|
||||
+ if ((rfd = kr_init()) == -1)
|
||||
quit = 1;
|
||||
+ quit = reconfigure(conffile, &conf, &mrt_l, &peer_l);
|
||||
if (pftable_clear_all() != 0)
|
||||
quit = 1;
|
||||
|
||||
- while ((net = TAILQ_FIRST(&net_l)) != NULL) {
|
||||
- TAILQ_REMOVE(&net_l, net, entry);
|
||||
- filterset_free(&net->net.attrset);
|
||||
- free(net);
|
||||
- }
|
||||
-
|
||||
- while ((r = TAILQ_FIRST(rules_l)) != NULL) {
|
||||
- TAILQ_REMOVE(rules_l, r, entry);
|
||||
- free(r);
|
||||
- }
|
||||
- TAILQ_FOREACH(la, conf.listen_addrs, entry) {
|
||||
- close(la->fd);
|
||||
- la->fd = -1;
|
||||
- }
|
||||
- while ((rr = SIMPLEQ_FIRST(&ribnames))) {
|
||||
- SIMPLEQ_REMOVE_HEAD(&ribnames, entry);
|
||||
- free(rr);
|
||||
- }
|
||||
-
|
||||
- mrt_reconfigure(&mrt_l);
|
||||
-
|
||||
while (quit == 0) {
|
||||
bzero(pfd, sizeof(pfd));
|
||||
pfd[PFD_PIPE_SESSION].fd = ibuf_se->fd;
|
||||
@@ -335,15 +294,16 @@ main(int argc, char *argv[])
|
||||
u_int error;
|
||||
|
||||
reconfig = 0;
|
||||
- log_info("rereading config");
|
||||
- switch (reconfigure(conffile, &conf, &mrt_l, &peer_l,
|
||||
- rules_l)) {
|
||||
+ switch (reconfigure(conffile, &conf, &mrt_l, &peer_l)) {
|
||||
case -1: /* fatal error */
|
||||
quit = 1;
|
||||
break;
|
||||
case 0: /* all OK */
|
||||
error = 0;
|
||||
break;
|
||||
+ case 2:
|
||||
+ error = CTL_RES_PENDING;
|
||||
+ break;
|
||||
default: /* parse error */
|
||||
error = CTL_RES_PARSE_ERROR;
|
||||
break;
|
||||
@@ -389,13 +349,13 @@ main(int argc, char *argv[])
|
||||
LIST_REMOVE(m, entry);
|
||||
free(m);
|
||||
}
|
||||
- while ((la = TAILQ_FIRST(conf.listen_addrs)) != NULL) {
|
||||
- TAILQ_REMOVE(conf.listen_addrs, la, entry);
|
||||
- close(la->fd);
|
||||
- free(la);
|
||||
- }
|
||||
+ if (conf.listen_addrs)
|
||||
+ while ((la = TAILQ_FIRST(conf.listen_addrs)) != NULL) {
|
||||
+ TAILQ_REMOVE(conf.listen_addrs, la, entry);
|
||||
+ close(la->fd);
|
||||
+ free(la);
|
||||
+ }
|
||||
|
||||
- free(rules_l);
|
||||
control_cleanup(conf.csock);
|
||||
control_cleanup(conf.rcsock);
|
||||
carp_demote_shutdown();
|
||||
@@ -413,6 +373,8 @@ main(int argc, char *argv[])
|
||||
free(ibuf_se);
|
||||
msgbuf_clear(&ibuf_rde->w);
|
||||
free(ibuf_rde);
|
||||
+ free(rcname);
|
||||
+ free(cname);
|
||||
|
||||
log_info("Terminating");
|
||||
return (0);
|
||||
@@ -452,27 +414,33 @@ send_filterset(struct imsgbuf *i, struct
|
||||
|
||||
int
|
||||
reconfigure(char *conffile, struct bgpd_config *conf, struct mrt_head *mrt_l,
|
||||
- struct peer **peer_l, struct filter_head *rules_l)
|
||||
+ struct peer **peer_l)
|
||||
{
|
||||
struct network_head net_l;
|
||||
- struct network *n;
|
||||
+ struct rdomain_head rdom_l;
|
||||
+ struct filter_head rules_l;
|
||||
struct peer *p;
|
||||
struct filter_rule *r;
|
||||
struct listen_addr *la;
|
||||
struct rde_rib *rr;
|
||||
+ struct rdomain *rd;
|
||||
|
||||
- if (parse_config(conffile, conf, mrt_l, peer_l, &net_l, rules_l)) {
|
||||
+ if (reconfpending) {
|
||||
+ log_info("previous reload still running");
|
||||
+ return (2);
|
||||
+ }
|
||||
+ reconfpending = 2; /* one per child */
|
||||
+
|
||||
+ log_info("rereading config");
|
||||
+ if (parse_config(conffile, conf, mrt_l, peer_l, &net_l, &rules_l,
|
||||
+ &rdom_l)) {
|
||||
log_warnx("config file %s has errors, not reloading",
|
||||
conffile);
|
||||
+ reconfpending = 0;
|
||||
return (1);
|
||||
}
|
||||
|
||||
cflags = conf->flags;
|
||||
- connectset = &conf->connectset;
|
||||
- staticset = &conf->staticset;
|
||||
- connectset6 = &conf->connectset6;
|
||||
- staticset6 = &conf->staticset6;
|
||||
-
|
||||
prepare_listeners(conf);
|
||||
|
||||
/* start reconfiguration */
|
||||
@@ -483,12 +451,6 @@ reconfigure(char *conffile, struct bgpd_
|
||||
conf, sizeof(struct bgpd_config)) == -1)
|
||||
return (-1);
|
||||
|
||||
- /* send peer list and listeners to the SE */
|
||||
- for (p = *peer_l; p != NULL; p = p->next)
|
||||
- if (imsg_compose(ibuf_se, IMSG_RECONF_PEER, p->conf.id, 0, -1,
|
||||
- &p->conf, sizeof(struct peer_config)) == -1)
|
||||
- return (-1);
|
||||
-
|
||||
TAILQ_FOREACH(la, conf->listen_addrs, entry) {
|
||||
if (imsg_compose(ibuf_se, IMSG_RECONF_LISTENER, 0, 0, la->fd,
|
||||
la, sizeof(struct listen_addr)) == -1)
|
||||
@@ -496,51 +458,104 @@ reconfigure(char *conffile, struct bgpd_
|
||||
la->fd = -1;
|
||||
}
|
||||
|
||||
+ if (control_setup(conf) == -1)
|
||||
+ return (-1);
|
||||
+
|
||||
+ /* adjust fib syncing on reload */
|
||||
+ ktable_preload();
|
||||
+
|
||||
/* RIBs for the RDE */
|
||||
while ((rr = SIMPLEQ_FIRST(&ribnames))) {
|
||||
SIMPLEQ_REMOVE_HEAD(&ribnames, entry);
|
||||
+ if (ktable_update(rr->rtableid, rr->name, NULL,
|
||||
+ rr->flags) == -1) {
|
||||
+ log_warnx("failed to load rdomain %d",
|
||||
+ rr->rtableid);
|
||||
+ return (-1);
|
||||
+ }
|
||||
if (imsg_compose(ibuf_rde, IMSG_RECONF_RIB, 0, 0, -1,
|
||||
rr, sizeof(struct rde_rib)) == -1)
|
||||
return (-1);
|
||||
free(rr);
|
||||
}
|
||||
|
||||
- /* networks for the RDE */
|
||||
- while ((n = TAILQ_FIRST(&net_l)) != NULL) {
|
||||
- if (imsg_compose(ibuf_rde, IMSG_NETWORK_ADD, 0, 0, -1,
|
||||
- &n->net, sizeof(struct network_config)) == -1)
|
||||
- return (-1);
|
||||
- if (send_filterset(ibuf_rde, &n->net.attrset) == -1)
|
||||
- return (-1);
|
||||
- if (imsg_compose(ibuf_rde, IMSG_NETWORK_DONE, 0, 0, -1,
|
||||
- NULL, 0) == -1)
|
||||
- return (-1);
|
||||
- TAILQ_REMOVE(&net_l, n, entry);
|
||||
- filterset_free(&n->net.attrset);
|
||||
- free(n);
|
||||
+ /* send peer list and listeners to the SE and RDE */
|
||||
+ for (p = *peer_l; p != NULL; p = p->next) {
|
||||
+ if (imsg_compose(ibuf_se, IMSG_RECONF_PEER, p->conf.id, 0, -1,
|
||||
+ &p->conf, sizeof(struct peer_config)) == -1)
|
||||
+ return (-1);
|
||||
+ if (imsg_compose(ibuf_rde, IMSG_RECONF_PEER, p->conf.id, 0, -1,
|
||||
+ &p->conf, sizeof(struct peer_config)) == -1)
|
||||
+ return (-1);
|
||||
}
|
||||
|
||||
- /* redistribute list needs to be reloaded too */
|
||||
- if (kr_reload() == -1)
|
||||
+ /* networks go via kroute to the RDE */
|
||||
+ if (kr_net_reload(0, &net_l))
|
||||
return (-1);
|
||||
|
||||
/* filters for the RDE */
|
||||
- while ((r = TAILQ_FIRST(rules_l)) != NULL) {
|
||||
+ while ((r = TAILQ_FIRST(&rules_l)) != NULL) {
|
||||
+ TAILQ_REMOVE(&rules_l, r, entry);
|
||||
if (imsg_compose(ibuf_rde, IMSG_RECONF_FILTER, 0, 0, -1,
|
||||
r, sizeof(struct filter_rule)) == -1)
|
||||
return (-1);
|
||||
if (send_filterset(ibuf_rde, &r->set) == -1)
|
||||
return (-1);
|
||||
- TAILQ_REMOVE(rules_l, r, entry);
|
||||
filterset_free(&r->set);
|
||||
free(r);
|
||||
}
|
||||
|
||||
+ while ((rd = SIMPLEQ_FIRST(&rdom_l)) != NULL) {
|
||||
+ SIMPLEQ_REMOVE_HEAD(&rdom_l, entry);
|
||||
+ if (ktable_update(rd->rtableid, rd->descr, rd->ifmpe,
|
||||
+ rd->flags) == -1) {
|
||||
+ log_warnx("failed to load rdomain %d",
|
||||
+ rd->rtableid);
|
||||
+ return (-1);
|
||||
+ }
|
||||
+ /* networks go via kroute to the RDE */
|
||||
+ if (kr_net_reload(rd->rtableid, &rd->net_l))
|
||||
+ return (-1);
|
||||
+
|
||||
+ if (imsg_compose(ibuf_rde, IMSG_RECONF_RDOMAIN, 0, 0, -1,
|
||||
+ rd, sizeof(*rd)) == -1)
|
||||
+ return (-1);
|
||||
+
|
||||
+ /* export targets */
|
||||
+ if (imsg_compose(ibuf_rde, IMSG_RECONF_RDOMAIN_EXPORT, 0, 0,
|
||||
+ -1, NULL, 0) == -1)
|
||||
+ return (-1);
|
||||
+ if (send_filterset(ibuf_rde, &rd->export) == -1)
|
||||
+ return (-1);
|
||||
+ filterset_free(&rd->export);
|
||||
+
|
||||
+ /* import targets */
|
||||
+ if (imsg_compose(ibuf_rde, IMSG_RECONF_RDOMAIN_IMPORT, 0, 0,
|
||||
+ -1, NULL, 0) == -1)
|
||||
+ return (-1);
|
||||
+ if (send_filterset(ibuf_rde, &rd->import) == -1)
|
||||
+ return (-1);
|
||||
+ filterset_free(&rd->import);
|
||||
+
|
||||
+ if (imsg_compose(ibuf_rde, IMSG_RECONF_RDOMAIN_DONE, 0, 0,
|
||||
+ -1, NULL, 0) == -1)
|
||||
+ return (-1);
|
||||
+
|
||||
+ free(rd);
|
||||
+ }
|
||||
+
|
||||
/* signal both childs to replace their config */
|
||||
if (imsg_compose(ibuf_se, IMSG_RECONF_DONE, 0, 0, -1, NULL, 0) == -1 ||
|
||||
imsg_compose(ibuf_rde, IMSG_RECONF_DONE, 0, 0, -1, NULL, 0) == -1)
|
||||
return (-1);
|
||||
|
||||
+ /* fix kroute information */
|
||||
+ ktable_postload();
|
||||
+
|
||||
+ /* redistribute list needs to be reloaded too */
|
||||
+ if (kr_reload() == -1)
|
||||
+ return (-1);
|
||||
+
|
||||
/* mrt changes can be sent out of bound */
|
||||
mrt_reconfigure(mrt_l);
|
||||
return (0);
|
||||
@@ -550,8 +565,8 @@ int
|
||||
dispatch_imsg(struct imsgbuf *ibuf, int idx)
|
||||
{
|
||||
struct imsg imsg;
|
||||
- int n;
|
||||
- int rv;
|
||||
+ ssize_t n;
|
||||
+ int rv, verbose;
|
||||
|
||||
if ((n = imsg_read(ibuf)) == -1)
|
||||
return (-1);
|
||||
@@ -573,46 +588,39 @@ dispatch_imsg(struct imsgbuf *ibuf, int
|
||||
case IMSG_KROUTE_CHANGE:
|
||||
if (idx != PFD_PIPE_ROUTE)
|
||||
log_warnx("route request not from RDE");
|
||||
- else if (kr_change(imsg.data))
|
||||
+ else if (imsg.hdr.len != IMSG_HEADER_SIZE +
|
||||
+ sizeof(struct kroute_full))
|
||||
+ log_warnx("wrong imsg len");
|
||||
+ else if (kr_change(imsg.hdr.peerid, imsg.data))
|
||||
rv = -1;
|
||||
break;
|
||||
case IMSG_KROUTE_DELETE:
|
||||
if (idx != PFD_PIPE_ROUTE)
|
||||
log_warnx("route request not from RDE");
|
||||
- else if (kr_delete(imsg.data))
|
||||
- rv = -1;
|
||||
- break;
|
||||
- case IMSG_KROUTE6_CHANGE:
|
||||
- if (idx != PFD_PIPE_ROUTE)
|
||||
- log_warnx("route request not from RDE");
|
||||
- else if (kr6_change(imsg.data))
|
||||
- rv = -1;
|
||||
- break;
|
||||
- case IMSG_KROUTE6_DELETE:
|
||||
- if (idx != PFD_PIPE_ROUTE)
|
||||
- log_warnx("route request not from RDE");
|
||||
- else if (kr6_delete(imsg.data))
|
||||
+ else if (imsg.hdr.len != IMSG_HEADER_SIZE +
|
||||
+ sizeof(struct kroute_full))
|
||||
+ log_warnx("wrong imsg len");
|
||||
+ else if (kr_delete(imsg.hdr.peerid, imsg.data))
|
||||
rv = -1;
|
||||
break;
|
||||
case IMSG_NEXTHOP_ADD:
|
||||
if (idx != PFD_PIPE_ROUTE)
|
||||
log_warnx("nexthop request not from RDE");
|
||||
- else
|
||||
- if (imsg.hdr.len != IMSG_HEADER_SIZE +
|
||||
- sizeof(struct bgpd_addr))
|
||||
- log_warnx("wrong imsg len");
|
||||
- else if (kr_nexthop_add(imsg.data) == -1)
|
||||
- rv = -1;
|
||||
+ else if (imsg.hdr.len != IMSG_HEADER_SIZE +
|
||||
+ sizeof(struct bgpd_addr))
|
||||
+ log_warnx("wrong imsg len");
|
||||
+ else if (kr_nexthop_add(imsg.hdr.peerid, imsg.data) ==
|
||||
+ -1)
|
||||
+ rv = -1;
|
||||
break;
|
||||
case IMSG_NEXTHOP_REMOVE:
|
||||
if (idx != PFD_PIPE_ROUTE)
|
||||
log_warnx("nexthop request not from RDE");
|
||||
+ else if (imsg.hdr.len != IMSG_HEADER_SIZE +
|
||||
+ sizeof(struct bgpd_addr))
|
||||
+ log_warnx("wrong imsg len");
|
||||
else
|
||||
- if (imsg.hdr.len != IMSG_HEADER_SIZE +
|
||||
- sizeof(struct bgpd_addr))
|
||||
- log_warnx("wrong imsg len");
|
||||
- else
|
||||
- kr_nexthop_delete(imsg.data);
|
||||
+ kr_nexthop_delete(imsg.hdr.peerid, imsg.data);
|
||||
break;
|
||||
case IMSG_PFTABLE_ADD:
|
||||
if (idx != PFD_PIPE_ROUTE)
|
||||
@@ -646,26 +654,28 @@ dispatch_imsg(struct imsgbuf *ibuf, int
|
||||
case IMSG_CTL_RELOAD:
|
||||
if (idx != PFD_PIPE_SESSION)
|
||||
log_warnx("reload request not from SE");
|
||||
- else
|
||||
+ else {
|
||||
reconfig = 1;
|
||||
reconfpid = imsg.hdr.pid;
|
||||
+ }
|
||||
break;
|
||||
case IMSG_CTL_FIB_COUPLE:
|
||||
if (idx != PFD_PIPE_SESSION)
|
||||
log_warnx("couple request not from SE");
|
||||
else
|
||||
- kr_fib_couple();
|
||||
+ kr_fib_couple(imsg.hdr.peerid);
|
||||
break;
|
||||
case IMSG_CTL_FIB_DECOUPLE:
|
||||
if (idx != PFD_PIPE_SESSION)
|
||||
log_warnx("decouple request not from SE");
|
||||
else
|
||||
- kr_fib_decouple();
|
||||
+ kr_fib_decouple(imsg.hdr.peerid);
|
||||
break;
|
||||
case IMSG_CTL_KROUTE:
|
||||
case IMSG_CTL_KROUTE_ADDR:
|
||||
case IMSG_CTL_SHOW_NEXTHOP:
|
||||
case IMSG_CTL_SHOW_INTERFACE:
|
||||
+ case IMSG_CTL_SHOW_FIB_TABLES:
|
||||
if (idx != PFD_PIPE_SESSION)
|
||||
log_warnx("kroute request not from SE");
|
||||
else
|
||||
@@ -692,6 +702,16 @@ dispatch_imsg(struct imsgbuf *ibuf, int
|
||||
carp_demote_set(msg->demote_group, msg->level);
|
||||
}
|
||||
break;
|
||||
+ case IMSG_CTL_LOG_VERBOSE:
|
||||
+ /* already checked by SE */
|
||||
+ memcpy(&verbose, imsg.data, sizeof(verbose));
|
||||
+ log_verbose(verbose);
|
||||
+ break;
|
||||
+ case IMSG_RECONF_DONE:
|
||||
+ if (reconfpending == 0)
|
||||
+ log_warnx("unexpected RECONF_DONE received");
|
||||
+ reconfpending--;
|
||||
+ break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -707,7 +727,7 @@ send_nexthop_update(struct kroute_nextho
|
||||
{
|
||||
char *gw = NULL;
|
||||
|
||||
- if (msg->gateway.af)
|
||||
+ if (msg->gateway.aid)
|
||||
if (asprintf(&gw, ": via %s",
|
||||
log_addr(&msg->gateway)) == -1) {
|
||||
log_warn("send_nexthop_update");
|
||||
@@ -717,7 +737,7 @@ send_nexthop_update(struct kroute_nextho
|
||||
log_info("nexthop %s now %s%s%s", log_addr(&msg->nexthop),
|
||||
msg->valid ? "valid" : "invalid",
|
||||
msg->connected ? ": directly connected" : "",
|
||||
- msg->gateway.af ? gw : "");
|
||||
+ msg->gateway.aid ? gw : "");
|
||||
|
||||
free(gw);
|
||||
|
||||
@@ -733,56 +753,20 @@ send_imsg_session(int type, pid_t pid, v
|
||||
}
|
||||
|
||||
int
|
||||
-bgpd_redistribute(int type, struct kroute *kr, struct kroute6 *kr6)
|
||||
+send_network(int type, struct network_config *net, struct filter_set_head *h)
|
||||
{
|
||||
- struct network_config net;
|
||||
- struct filter_set_head *h;
|
||||
-
|
||||
- if ((cflags & BGPD_FLAG_REDIST_CONNECTED) && kr &&
|
||||
- (kr->flags & F_CONNECTED))
|
||||
- h = connectset;
|
||||
- else if ((cflags & BGPD_FLAG_REDIST_STATIC) && kr &&
|
||||
- (kr->flags & F_STATIC))
|
||||
- h = staticset;
|
||||
- else if ((cflags & BGPD_FLAG_REDIST6_CONNECTED) && kr6 &&
|
||||
- (kr6->flags & F_CONNECTED))
|
||||
- h = connectset6;
|
||||
- else if ((cflags & BGPD_FLAG_REDIST6_STATIC) && kr6 &&
|
||||
- (kr6->flags & F_STATIC))
|
||||
- h = staticset6;
|
||||
- else
|
||||
- return (0);
|
||||
-
|
||||
- bzero(&net, sizeof(net));
|
||||
- if (kr && kr6)
|
||||
- fatalx("bgpd_redistribute: unable to redistribute v4 and v6"
|
||||
- "together");
|
||||
- if (kr != NULL) {
|
||||
- net.prefix.af = AF_INET;
|
||||
- net.prefix.v4.s_addr = kr->prefix.s_addr;
|
||||
- net.prefixlen = kr->prefixlen;
|
||||
- }
|
||||
- if (kr6 != NULL) {
|
||||
- net.prefix.af = AF_INET6;
|
||||
- memcpy(&net.prefix.v6, &kr6->prefix, sizeof(struct in6_addr));
|
||||
- net.prefixlen = kr6->prefixlen;
|
||||
- }
|
||||
-
|
||||
-
|
||||
- if (imsg_compose(ibuf_rde, type, 0, 0, -1, &net,
|
||||
+ if (imsg_compose(ibuf_rde, type, 0, 0, -1, net,
|
||||
sizeof(struct network_config)) == -1)
|
||||
return (-1);
|
||||
-
|
||||
/* networks that get deleted don't need to send the filter set */
|
||||
if (type == IMSG_NETWORK_REMOVE)
|
||||
- return (1);
|
||||
-
|
||||
+ return (0);
|
||||
if (send_filterset(ibuf_rde, h) == -1)
|
||||
return (-1);
|
||||
if (imsg_compose(ibuf_rde, IMSG_NETWORK_DONE, 0, 0, -1, NULL, 0) == -1)
|
||||
return (-1);
|
||||
|
||||
- return (1);
|
||||
+ return (0);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -810,3 +794,45 @@ bgpd_filternexthop(struct kroute *kr, st
|
||||
|
||||
return (1);
|
||||
}
|
||||
+
|
||||
+int
|
||||
+control_setup(struct bgpd_config *conf)
|
||||
+{
|
||||
+ int fd, restricted;
|
||||
+
|
||||
+ /* control socket is outside chroot */
|
||||
+ if (!cname || strcmp(cname, conf->csock)) {
|
||||
+ if (cname) {
|
||||
+ control_cleanup(cname);
|
||||
+ free(cname);
|
||||
+ }
|
||||
+ if ((cname = strdup(conf->csock)) == NULL)
|
||||
+ fatal("strdup");
|
||||
+ if ((fd = control_init(0, cname)) == -1)
|
||||
+ fatalx("control socket setup failed");
|
||||
+ restricted = 0;
|
||||
+ if (imsg_compose(ibuf_se, IMSG_RECONF_CTRL, 0, 0, fd,
|
||||
+ &restricted, sizeof(restricted)) == -1)
|
||||
+ return (-1);
|
||||
+ }
|
||||
+ if (!conf->rcsock) {
|
||||
+ /* remove restricted socket */
|
||||
+ control_cleanup(rcname);
|
||||
+ free(rcname);
|
||||
+ rcname = NULL;
|
||||
+ } else if (!rcname || strcmp(rcname, conf->rcsock)) {
|
||||
+ if (rcname) {
|
||||
+ control_cleanup(rcname);
|
||||
+ free(rcname);
|
||||
+ }
|
||||
+ if ((rcname = strdup(conf->rcsock)) == NULL)
|
||||
+ fatal("strdup");
|
||||
+ if ((fd = control_init(1, rcname)) == -1)
|
||||
+ fatalx("control socket setup failed");
|
||||
+ restricted = 1;
|
||||
+ if (imsg_compose(ibuf_se, IMSG_RECONF_CTRL, 0, 0, fd,
|
||||
+ &restricted, sizeof(restricted)) == -1)
|
||||
+ return (-1);
|
||||
+ }
|
||||
+ return (0);
|
||||
+}
|
746
net/openbgpd/files/patch-bgpd_bgpd.conf.5
Normal file
746
net/openbgpd/files/patch-bgpd_bgpd.conf.5
Normal file
@ -0,0 +1,746 @@
|
||||
Index: bgpd/bgpd.conf.5
|
||||
===================================================================
|
||||
RCS file: /home/cvs/private/hrs/openbgpd/bgpd/bgpd.conf.5,v
|
||||
retrieving revision 1.1.1.7
|
||||
retrieving revision 1.10
|
||||
diff -u -p -r1.1.1.7 -r1.10
|
||||
--- bgpd/bgpd.conf.5 14 Feb 2010 20:19:57 -0000 1.1.1.7
|
||||
+++ bgpd/bgpd.conf.5 8 Dec 2012 20:17:59 -0000 1.10
|
||||
@@ -1,4 +1,4 @@
|
||||
-.\" $OpenBSD: bgpd.conf.5,v 1.94 2009/06/07 00:31:22 claudio Exp $
|
||||
+.\" $OpenBSD: bgpd.conf.5,v 1.122 2012/11/13 09:47:20 claudio Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
|
||||
.\" Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
|
||||
@@ -16,7 +16,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
-.Dd $Mdocdate: June 7 2009 $
|
||||
+.Dd $Mdocdate: November 13 2012 $
|
||||
.Dt BGPD.CONF 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
@@ -26,11 +26,11 @@
|
||||
The
|
||||
.Xr bgpd 8
|
||||
daemon implements the Border Gateway Protocol version 4 as described
|
||||
-in RFC 1771.
|
||||
+in RFC 4271.
|
||||
.Sh SECTIONS
|
||||
The
|
||||
.Nm
|
||||
-config file is divided into four main sections.
|
||||
+config file is divided into five main sections.
|
||||
.Bl -tag -width xxxx
|
||||
.It Sy Macros
|
||||
User-defined variables may be defined and used later, simplifying the
|
||||
@@ -38,6 +38,8 @@ configuration file.
|
||||
.It Sy Global Configuration
|
||||
Global settings for
|
||||
.Xr bgpd 8 .
|
||||
+.It Sy Routing Domain Configuration
|
||||
+The definition and properties for BGP MPLS VPNs are set in this section.
|
||||
.It Sy Neighbors and Groups
|
||||
.Xr bgpd 8
|
||||
establishes sessions with
|
||||
@@ -54,9 +56,16 @@ the sections should be grouped and appea
|
||||
.Nm
|
||||
in the order shown above.
|
||||
.Pp
|
||||
+The current line can be extended over multiple lines using a backslash
|
||||
+.Pq Sq \e .
|
||||
Comments can be put anywhere in the file using a hash mark
|
||||
.Pq Sq # ,
|
||||
and extend to the end of the current line.
|
||||
+Care should be taken when commenting out multi-line text:
|
||||
+the comment is effective until the end of the entire block.
|
||||
+.Pp
|
||||
+Argument names not beginning with a letter, digit, or underscore
|
||||
+must be quoted.
|
||||
.Pp
|
||||
Additional configuration files can be included with the
|
||||
.Ic include
|
||||
@@ -66,8 +75,8 @@ include "/etc/bgpd/bgpd-10.0.0.1.filter"
|
||||
.Ed
|
||||
.Sh MACROS
|
||||
Macros can be defined that will later be expanded in context.
|
||||
-Macro names must start with a letter, and may contain letters, digits
|
||||
-and underscores.
|
||||
+Macro names must start with a letter, digit, or underscore,
|
||||
+and may contain any of those characters.
|
||||
Macro names may not be reserved words (for example,
|
||||
.Ic AS ,
|
||||
.Ic neighbor ,
|
||||
@@ -93,7 +102,7 @@ Set the local
|
||||
.Em autonomous system
|
||||
number to
|
||||
.Ar as-number .
|
||||
-If the first AS number is a 4-byte AS it is possible to specifiy a secondary
|
||||
+If the first AS number is a 4-byte AS it is possible to specify a secondary
|
||||
2-byte AS number which is used for neighbors which do not support 4-byte AS
|
||||
numbers.
|
||||
The default for the secondary AS is 23456.
|
||||
@@ -143,29 +152,33 @@ The default is 120 seconds.
|
||||
.It Xo
|
||||
.Ic dump
|
||||
.Op Ic rib Ar name
|
||||
-.Pq Ic table Ns \&| Ns Ic table-mp
|
||||
+.Pq Ic table Ns | Ns Ic table-mp Ns | Ns Ic table-v2
|
||||
.Ar file Op Ar timeout
|
||||
.Xc
|
||||
.It Xo
|
||||
.Ic dump
|
||||
-.Pq Ic all Ns \&| Ns Ic updates
|
||||
-.Pq Ic in Ns \&| Ns Ic out
|
||||
+.Pq Ic all Ns | Ns Ic updates
|
||||
+.Pq Ic in Ns | Ns Ic out
|
||||
.Ar file Op Ar timeout
|
||||
.Xc
|
||||
Dump the RIB, a.k.a. the
|
||||
.Em routing information base ,
|
||||
and all BGP messages in Multi-threaded Routing Toolkit (MRT) format.
|
||||
-Dumping the RIB is normally an expensive operation,
|
||||
-but it should not influence the session handling.
|
||||
It is possible to dump alternate RIB with the use of
|
||||
.Ar name .
|
||||
.Pp
|
||||
For example, the following will dump the entire table to the
|
||||
.Xr strftime 3 Ns -expanded
|
||||
filename.
|
||||
-The
|
||||
+Only the
|
||||
+.Ic table-v2
|
||||
+format is able to dump a multi-protocol RIB correctly.
|
||||
+Both
|
||||
+.Ic table
|
||||
+and
|
||||
.Ic table-mp
|
||||
-format is multi-protocol capable but often not supported by 3rd-party tools.
|
||||
+formats are more or less limited when handling multi-protocol entries and
|
||||
+are only left around to support 3rd party tools not handling the new format.
|
||||
The timeout is optional:
|
||||
.Bd -literal -offset indent
|
||||
dump table "/tmp/rib-dump-%H%M" 300
|
||||
@@ -195,7 +208,7 @@ dump updates out "/tmp/updates-out-%H%M"
|
||||
.Pp
|
||||
.It Xo
|
||||
.Ic fib-update
|
||||
-.Pq Ic yes Ns \&| Ns Ic no
|
||||
+.Pq Ic yes Ns | Ns Ic no
|
||||
.Xc
|
||||
If set to
|
||||
.Ic no ,
|
||||
@@ -242,12 +255,12 @@ Log received and sent updates.
|
||||
.Xc
|
||||
.It Xo
|
||||
.Ic network
|
||||
-.Pq Ic inet Ns \&| Ns Ic inet6
|
||||
+.Pq Ic inet Ns | Ns Ic inet6
|
||||
.Ic static Op Ic set ...\&
|
||||
.Xc
|
||||
.It Xo
|
||||
.Ic network
|
||||
-.Pq Ic inet Ns \&| Ns Ic inet6
|
||||
+.Pq Ic inet Ns | Ns Ic inet6
|
||||
.Ic connected Op Ic set ...\&
|
||||
.Xc
|
||||
Announce the specified network as belonging to our AS.
|
||||
@@ -278,7 +291,7 @@ section.
|
||||
.Ic nexthop
|
||||
.Ic qualify
|
||||
.Ic via
|
||||
-.Pq Ic bgp Ns \&| Ns Ic default
|
||||
+.Pq Ic bgp Ns | Ns Ic default
|
||||
.Xc
|
||||
If set to
|
||||
.Ic bgp ,
|
||||
@@ -295,38 +308,47 @@ daemons like
|
||||
.Ic rde
|
||||
.Ic med
|
||||
.Ic compare
|
||||
-.Pq Ic always Ns \&| Ns Ic strict
|
||||
+.Pq Ic always Ns | Ns Ic strict
|
||||
.Xc
|
||||
If set to
|
||||
.Ic always ,
|
||||
the
|
||||
-.Em MED
|
||||
+.Em MULTI_EXIT_DISC
|
||||
attributes will always be compared.
|
||||
The default is
|
||||
.Ic strict ,
|
||||
-where the
|
||||
-.Em MED
|
||||
-is only compared between peers belonging to the same AS.
|
||||
+where the metric is only compared between peers belonging to the same AS.
|
||||
.Pp
|
||||
.It Xo
|
||||
.Ic rde
|
||||
.Ic rib Ar name
|
||||
.Op Ic no Ic evaluate
|
||||
.Xc
|
||||
-Creat an additional RIB named
|
||||
+.It Xo
|
||||
+.Ic rde
|
||||
+.Ic rib Ar name
|
||||
+.Op Ic rtable Ar number
|
||||
+.Xc
|
||||
+Create an additional RIB named
|
||||
.Ar name .
|
||||
It is possible to disable the decision process per RIB with the
|
||||
.Ic no Ic evaluate
|
||||
flag.
|
||||
+If a
|
||||
+.Ic rtable
|
||||
+is specified, routes will be exported to the given kernel routing table.
|
||||
+Currently the routing table must belong to the default routing domain and
|
||||
+nexthop verification happens on table 0.
|
||||
+Routes in the specified table will not be considered for nexthop verification.
|
||||
.Ic Adj-RIB-In
|
||||
and
|
||||
.Ic Loc-RIB
|
||||
-are created automaticaly and used as default.
|
||||
+are created automatically and used as default.
|
||||
.Pp
|
||||
.It Xo
|
||||
.Ic rde
|
||||
.Ic route-age
|
||||
-.Pq Ic ignore Ns \&| Ns Ic evaluate
|
||||
+.Pq Ic ignore Ns | Ns Ic evaluate
|
||||
.Xc
|
||||
If set to
|
||||
.Ic evaluate ,
|
||||
@@ -339,7 +361,7 @@ The default is
|
||||
.Pp
|
||||
.It Xo
|
||||
.Ic route-collector
|
||||
-.Pq Ic yes Ns \&| Ns Ic no
|
||||
+.Pq Ic yes Ns | Ns Ic no
|
||||
.Xc
|
||||
If set to
|
||||
.Ic yes ,
|
||||
@@ -361,13 +383,24 @@ to the local machine.
|
||||
Work with the given kernel routing table
|
||||
instead of the default table,
|
||||
.Ar 0 .
|
||||
-Note that this table is used for nexthop verification as well.
|
||||
-Directly connected networks are always taken into account, even though
|
||||
-their routes live in table 0.
|
||||
+Note that table 0 is used for nexthop verification.
|
||||
+Routes in the specified table will not be considered for nexthop verification.
|
||||
+This is the same as using the following syntax:
|
||||
+.Bd -literal -offset indent
|
||||
+rde rib Loc-RIB rtable number
|
||||
+.Ed
|
||||
+.Pp
|
||||
+.It Ic socket Qo Ar path Qc Op Ic restricted
|
||||
+Set the control socket location to
|
||||
+.Ar path .
|
||||
+If
|
||||
+.Ic restricted
|
||||
+is specified a restricted control socket will be created.
|
||||
+By default /var/run/bgpd.sock is used and no restricted socket is created.
|
||||
.Pp
|
||||
.It Xo
|
||||
.Ic transparent-as
|
||||
-.Pq Ic yes Ns \&| Ns Ic no
|
||||
+.Pq Ic yes Ns | Ns Ic no
|
||||
.Xc
|
||||
If set to
|
||||
.Ic yes ,
|
||||
@@ -376,6 +409,110 @@ to EBGP neighbors are not prepended with
|
||||
The default is
|
||||
.Ic no .
|
||||
.El
|
||||
+.Sh ROUTING DOMAIN CONFIGURATION
|
||||
+.Xr bgpd 8
|
||||
+supports the setup and distribution of Virtual Private Networks.
|
||||
+It is possible to import and export prefixes between routing domains.
|
||||
+Each routing domain is specified by an
|
||||
+.Ic rdomain
|
||||
+section, which allows properties to be set specifically for that rdomain:
|
||||
+.Bd -literal -offset indent
|
||||
+rdomain 1 {
|
||||
+ descr "a rdomain"
|
||||
+ rd 65002:1
|
||||
+ import-target rt 65002:42
|
||||
+ export-target rt 65002:42
|
||||
+ network 192.168.1/24
|
||||
+ depend on mpe0
|
||||
+}
|
||||
+.Ed
|
||||
+.Pp
|
||||
+There are several routing domain properties:
|
||||
+.Pp
|
||||
+.Bl -tag -width Ds -compact
|
||||
+.It Ic depend on Ar interface
|
||||
+Routes added to the rdomain will use this interface as the outgoing interface.
|
||||
+Normally this will be an MPLS Provider Edge,
|
||||
+.Xr mpe 4 ,
|
||||
+interface that is part of the rdomain.
|
||||
+Local networks will be announced with the MPLS label specified on the interface.
|
||||
+.Pp
|
||||
+.It Ic descr Ar description
|
||||
+Add a description.
|
||||
+The description is used when logging but has no further meaning to
|
||||
+.Xr bgpd 8 .
|
||||
+.Pp
|
||||
+.It Ic export-target Ar subtype Ar as-number Ns Li : Ns Ar local
|
||||
+.It Ic export-target Ar subtype Ar IP Ns Li : Ns Ar local
|
||||
+Specify an extended community which will be attached to announced networks.
|
||||
+More than one
|
||||
+.Ic export-target
|
||||
+can be specified.
|
||||
+See also the
|
||||
+.Sx ATTRIBUTE SET
|
||||
+section for further information about the encoding.
|
||||
+The
|
||||
+.Ar subtype
|
||||
+should be set to
|
||||
+.Ar rt
|
||||
+for best compatibility with other implementations.
|
||||
+.Pp
|
||||
+.It Xo
|
||||
+.Ic fib-update
|
||||
+.Pq Ic yes Ns | Ns Ic no
|
||||
+.Xc
|
||||
+If set to
|
||||
+.Ic no ,
|
||||
+do not update the Forwarding Information Base, a.k.a. the kernel
|
||||
+routing table.
|
||||
+The default is
|
||||
+.Ic yes .
|
||||
+.Pp
|
||||
+.It Ic import-target Ar subtype Ar as-number Ns Li : Ns Ar local
|
||||
+.It Ic import-target Ar subtype Ar IP Ns Li : Ns Ar local
|
||||
+Only prefixes matching one of the specified
|
||||
+.Ic import-targets
|
||||
+will be imported into the rdomain.
|
||||
+More than one
|
||||
+.Ic import-target
|
||||
+can be specified.
|
||||
+See also the
|
||||
+.Sx ATTRIBUTE SET
|
||||
+section for further information about the encoding of extended communities.
|
||||
+The
|
||||
+.Ar subtype
|
||||
+should be set to
|
||||
+.Ar rt
|
||||
+for best compatibility with other implementations.
|
||||
+.Pp
|
||||
+.It Ic network Ar arguments ...
|
||||
+Define which networks should be exported into this VPN.
|
||||
+See also the
|
||||
+.Ic nexthop
|
||||
+section in
|
||||
+.Sx GLOBAL CONFIGURATION
|
||||
+for further information about the arguments.
|
||||
+.Pp
|
||||
+.It Ic rd Ar as-number Ns Li : Ns Ar local
|
||||
+.It Ic rd Ar IP Ns Li : Ns Ar local
|
||||
+The sole purpose of the Route Distinguisher
|
||||
+.Ic rd
|
||||
+is to ensure that possible common prefixes are destinct between VPNs.
|
||||
+The
|
||||
+.Ic rd
|
||||
+is neither used to identify the origin of the prefix nor to control into
|
||||
+which VPNs the prefix is distributed to.
|
||||
+The
|
||||
+.Ar as-number
|
||||
+or
|
||||
+.Ar IP
|
||||
+of a
|
||||
+.Ic rd
|
||||
+should be set to a number or IP that was assigned by an appropriate authority.
|
||||
+Whereas
|
||||
+.Ar local
|
||||
+can be chosen by the local operator.
|
||||
+.El
|
||||
.Sh NEIGHBORS AND GROUPS
|
||||
.Xr bgpd 8
|
||||
establishes TCP connections to other BGP speakers called
|
||||
@@ -470,21 +607,35 @@ The default for IBGP peers is
|
||||
.Pp
|
||||
.It Xo
|
||||
.Ic announce
|
||||
-.Pq Ic IPv4 Ns \&| Ns Ic IPv6
|
||||
-.Pq Ic none Ns \&| Ns Ic unicast
|
||||
+.Pq Ic IPv4 Ns | Ns Ic IPv6
|
||||
+.Pq Ic none Ns | Ns Ic unicast Ns | Ns Ic vpn
|
||||
.Xc
|
||||
For the given address family, control which subsequent address families
|
||||
(at the moment, only
|
||||
.Em none ,
|
||||
-which disables the announcement of that address family, and
|
||||
-.Em unicast
|
||||
-are supported) are announced during the capabilities negotiation.
|
||||
+which disables the announcement of that address family,
|
||||
+.Em unicast ,
|
||||
+and
|
||||
+.Em vpn ,
|
||||
+which allows the distribution of BGP MPLS VPNs, are supported) are announced
|
||||
+during the capabilities negotiation.
|
||||
Only routes for that address family and subsequent address family will be
|
||||
announced and processed.
|
||||
.Pp
|
||||
.It Xo
|
||||
+.Ic announce as-4byte
|
||||
+.Pq Ic yes Ns | Ns Ic no
|
||||
+.Xc
|
||||
+If set to
|
||||
+.Ic no ,
|
||||
+the 4-byte AS capability is not announced and so native 4-byte AS support is
|
||||
+disabled.
|
||||
+The default is
|
||||
+.Ic yes .
|
||||
+.Pp
|
||||
+.It Xo
|
||||
.Ic announce capabilities
|
||||
-.Pq Ic yes Ns \&| Ns Ic no
|
||||
+.Pq Ic yes Ns | Ns Ic no
|
||||
.Xc
|
||||
If set to
|
||||
.Ic no ,
|
||||
@@ -493,6 +644,29 @@ This can be helpful to connect to old or
|
||||
The default is
|
||||
.Ic yes .
|
||||
.Pp
|
||||
+.It Xo
|
||||
+.Ic announce refresh
|
||||
+.Pq Ic yes Ns | Ns Ic no
|
||||
+.Xc
|
||||
+If set to
|
||||
+.Ic no ,
|
||||
+the route refresh capability is not announced.
|
||||
+The default is
|
||||
+.Ic yes .
|
||||
+.Pp
|
||||
+.It Xo
|
||||
+.Ic announce restart
|
||||
+.Pq Ic yes Ns | Ns Ic no
|
||||
+.Xc
|
||||
+If set to
|
||||
+.Ic yes ,
|
||||
+the graceful restart capability is announced.
|
||||
+Currently only the End-of-RIB marker is supported and announced by the
|
||||
+.Ic restart
|
||||
+capability.
|
||||
+The default is
|
||||
+.Ic no .
|
||||
+.Pp
|
||||
.It Ic demote Ar group
|
||||
Increase the
|
||||
.Xr carp 4
|
||||
@@ -504,7 +678,7 @@ The demotion counter will be increased a
|
||||
.Xr bgpd 8
|
||||
starts and decreased
|
||||
60 seconds after the session went to state
|
||||
-.Em ESTABLISHED.
|
||||
+.Em ESTABLISHED .
|
||||
For neighbors added at runtime, the demotion counter is only increased after
|
||||
the session has been
|
||||
.Em ESTABLISHED
|
||||
@@ -548,8 +722,8 @@ Do not start the session when bgpd comes
|
||||
.Pp
|
||||
.It Xo
|
||||
.Ic dump
|
||||
-.Pq Ic all Ns \&| Ns Ic updates
|
||||
-.Pq Ic in Ns \&| Ns Ic out
|
||||
+.Pq Ic all Ns | Ns Ic updates
|
||||
+.Pq Ic in Ns | Ns Ic out
|
||||
.Ar file Op Ar timeout
|
||||
.Xc
|
||||
Do a peer specific MRT dump.
|
||||
@@ -564,7 +738,7 @@ section in
|
||||
.Pp
|
||||
.It Xo
|
||||
.Ic enforce neighbor-as
|
||||
-.Pq Ic yes Ns \&| Ns Ic no
|
||||
+.Pq Ic yes Ns | Ns Ic no
|
||||
.Xc
|
||||
If set to
|
||||
.Ic yes ,
|
||||
@@ -589,10 +763,16 @@ Inherited from the global configuration
|
||||
Set the minimal acceptable holdtime.
|
||||
Inherited from the global configuration if not given.
|
||||
.Pp
|
||||
+.It Ic interface Ar interface
|
||||
+Set an interface used for a nexthop with a link-local IPv6 address.
|
||||
+Note that if this is not specified and a link-local IPv6 address is
|
||||
+received as nexthop of the peer, it will be marked as invalid and
|
||||
+ignored.
|
||||
+.Pp
|
||||
.It Xo
|
||||
.Ic ipsec
|
||||
-.Pq Ic ah Ns \&| Ns Ic esp
|
||||
-.Pq Ic in Ns \&| Ns Ic out
|
||||
+.Pq Ic ah Ns | Ns Ic esp
|
||||
+.Pq Ic in Ns | Ns Ic out
|
||||
.Ic spi Ar spi-number authspec Op Ar encspec
|
||||
.Xc
|
||||
Enable IPsec with static keying.
|
||||
@@ -627,7 +807,7 @@ Keys must be given in hexadecimal format
|
||||
.Pp
|
||||
.It Xo
|
||||
.Ic ipsec
|
||||
-.Pq Ic ah Ns \&| Ns Ic esp
|
||||
+.Pq Ic ah Ns | Ns Ic esp
|
||||
.Ic ike
|
||||
.Xc
|
||||
Enable IPsec with dynamic keying.
|
||||
@@ -639,11 +819,11 @@ is responsible for managing the session
|
||||
With
|
||||
.Xr isakmpd 8 ,
|
||||
it is sufficient to copy the peer's public key, found in
|
||||
-.Pa /etc/isakmpd/local.pub ,
|
||||
+.Pa %%PREFIX%%/etc/isakmpd/private/local.pub ,
|
||||
to the local machine.
|
||||
It must be stored in a file
|
||||
named after the peer's IP address and must be stored in
|
||||
-.Pa /etc/isakmpd/pubkeys/ipv4/ .
|
||||
+.Pa %%PREFIX%%/etc/isakmpd/pubkeys/ipv4/ .
|
||||
The local public key must be copied to the peer in the same way.
|
||||
As
|
||||
.Xr bgpd 8
|
||||
@@ -698,11 +878,11 @@ Do not attempt to actively open a TCP co
|
||||
.It Ic remote-as Ar as-number
|
||||
Set the AS number of the remote system.
|
||||
.Pp
|
||||
-.It rib .Ar name
|
||||
+.It Ic rib Ar name
|
||||
Bind the neighbor to the specified RIB.
|
||||
.Pp
|
||||
.It Ic route-reflector Op Ar address
|
||||
-Act as an RFC 2796
|
||||
+Act as an RFC 4456
|
||||
.Em route-reflector
|
||||
for this neighbor.
|
||||
An optional cluster ID can be specified; otherwise the BGP ID will be used.
|
||||
@@ -732,8 +912,8 @@ These sets are rewritten into filter rul
|
||||
.Pp
|
||||
.It Xo
|
||||
.Ic softreconfig
|
||||
-.Pq Ic in Ns \&| Ns Ic out
|
||||
-.Pq Ic yes Ns \&| Ns Ic no
|
||||
+.Pq Ic in Ns | Ns Ic out
|
||||
+.Pq Ic yes Ns | Ns Ic no
|
||||
.Xc
|
||||
Turn soft reconfiguration on or off for the specified direction.
|
||||
If soft reconfiguration is turned on, filter changes will be applied on
|
||||
@@ -760,7 +940,7 @@ tcp md5sig key deadbeef
|
||||
.Pp
|
||||
.It Xo
|
||||
.Ic transparent-as
|
||||
-.Pq Ic yes Ns \&| Ns Ic no
|
||||
+.Pq Ic yes Ns | Ns Ic no
|
||||
.Xc
|
||||
If set to
|
||||
.Ic yes ,
|
||||
@@ -772,7 +952,7 @@ setting.
|
||||
.Pp
|
||||
.It Xo
|
||||
.Ic ttl-security
|
||||
-.Pq Ic yes Ns \&| Ns Ic no
|
||||
+.Pq Ic yes Ns | Ns Ic no
|
||||
.Xc
|
||||
Enable or disable ttl-security.
|
||||
When enabled,
|
||||
@@ -849,6 +1029,10 @@ is matched against a part of the
|
||||
.Em AS path
|
||||
specified by the
|
||||
.Ar as-type .
|
||||
+.Ar as-number
|
||||
+may be set to
|
||||
+.Ic neighbor-as ,
|
||||
+which is expanded to the current neighbor remote AS number.
|
||||
.Ar as-type
|
||||
is one of the following operators:
|
||||
.Pp
|
||||
@@ -917,7 +1101,32 @@ may be set to
|
||||
which is expanded to the current neighbor remote AS number.
|
||||
.Pp
|
||||
.It Xo
|
||||
-.Pq Ic from Ns \&| Ns Ic to
|
||||
+.Ic ext-community
|
||||
+.Ar subtype Ar as-number Ns Li : Ns Ar local
|
||||
+.Xc
|
||||
+.It Xo
|
||||
+.Ic ext-community
|
||||
+.Ar subtype Ar IP Ns Li : Ns Ar local
|
||||
+.Xc
|
||||
+.It Xo
|
||||
+.Ic ext-community
|
||||
+.Ar subtype Ar numvalue
|
||||
+.Xc
|
||||
+This rule applies only to
|
||||
+.Em UPDATES
|
||||
+where the
|
||||
+.Em extended community
|
||||
+path attribute is present and matches.
|
||||
+Extended Communities are specified by a
|
||||
+.Ar subtype
|
||||
+and normally two values, a globally unique part (e.g. the AS number) and a
|
||||
+local part.
|
||||
+See also the
|
||||
+.Sx ATTRIBUTE SET
|
||||
+section for further information about the encoding.
|
||||
+.Pp
|
||||
+.It Xo
|
||||
+.Pq Ic from Ns | Ns Ic to
|
||||
.Ar peer
|
||||
.Xc
|
||||
This rule applies only to
|
||||
@@ -945,7 +1154,7 @@ if enclosed in curly brackets:
|
||||
deny from { 128.251.16.1, 251.128.16.2, group hojo }
|
||||
.Ed
|
||||
.Pp
|
||||
-.It Pq Ic inet Ns \&| Ns Ic inet6
|
||||
+.It Pq Ic inet Ns | Ns Ic inet6
|
||||
This rule applies only to routes matching the stated address family.
|
||||
The address family needs to be set only in rules that use
|
||||
.Ic prefixlen
|
||||
@@ -953,6 +1162,37 @@ without specifying a
|
||||
.Ic prefix
|
||||
beforehand.
|
||||
.Pp
|
||||
+.It Ic max-as-len Ar len
|
||||
+This rule applies only to
|
||||
+.Em UPDATES
|
||||
+where the
|
||||
+.Em AS path
|
||||
+has more than
|
||||
+.Ar len
|
||||
+elements.
|
||||
+.Pp
|
||||
+.It Ic max-as-seq Ar len
|
||||
+This rule applies only to
|
||||
+.Em UPDATES
|
||||
+where a single
|
||||
+.Em AS number
|
||||
+is repeated more than
|
||||
+.Ar len
|
||||
+times.
|
||||
+.Pp
|
||||
+.It Ic nexthop Ar address
|
||||
+This rule applies only to
|
||||
+.Em UPDATES
|
||||
+where the nexthop is equal to
|
||||
+.Ar address .
|
||||
+The
|
||||
+.Ar address
|
||||
+can be set to
|
||||
+.Em neighbor
|
||||
+in which case the nexthop is compared against the address of the neighbor.
|
||||
+Nexthop filtering is not supported on locally announced networks and one must
|
||||
+take into consideration previous rules overwriting nexthops.
|
||||
+.Pp
|
||||
.It Xo
|
||||
.Ic prefix
|
||||
.Ar address Ns Li / Ns Ar len
|
||||
@@ -1028,6 +1268,12 @@ matches a rule which has the
|
||||
option set, this rule is considered the last matching rule, and evaluation
|
||||
of subsequent rules is skipped.
|
||||
.Pp
|
||||
+.It Ic rib Ar name
|
||||
+Apply rule only to the specified RIB.
|
||||
+This only applies for received updates, so not for rules using the
|
||||
+.Ar to peer
|
||||
+parameter.
|
||||
+.Pp
|
||||
.It Ic set Ar attribute ...
|
||||
All matching rules can set the
|
||||
.Em AS path attributes
|
||||
@@ -1079,6 +1325,48 @@ Alternately, well-known communities may
|
||||
or
|
||||
.Ic NO_PEER .
|
||||
.Pp
|
||||
+.It Xo
|
||||
+.Ic ext-community Op Ar delete
|
||||
+.Ar subtype Ar as-number Ns Li : Ns Ar local
|
||||
+.Xc
|
||||
+.It Xo
|
||||
+.Ic ext-community Op Ar delete
|
||||
+.Ar subtype Ar IP Ns Li : Ns Ar local
|
||||
+.Xc
|
||||
+.It Xo
|
||||
+.Ic ext-community Op Ar delete
|
||||
+.Ar subtype Ar numvalue
|
||||
+.Xc
|
||||
+Set or delete the
|
||||
+.Em Extended Community
|
||||
+AS path attribute.
|
||||
+Extended Communities are specified by a
|
||||
+.Ar subtype
|
||||
+and normally two values, a globally unique part (e.g. the AS number) and a
|
||||
+local part.
|
||||
+The type is selected depending on the encoding of the global part.
|
||||
+Two-octet AS Specific Extended Communities and Four-octet AS Specific Extended
|
||||
+Communities are encoded as
|
||||
+.Ar as-number Ns Li : Ns Ar local .
|
||||
+Four-octet encoding is used if the
|
||||
+.Ar as-number
|
||||
+is bigger then 65535 or if the AS_DOT encoding is used.
|
||||
+IPv4 Address Specific Extended Communities are encoded as
|
||||
+.Ar IP Ns Li : Ns Ar local .
|
||||
+Opaque Extended Communities are encoded with a single numeric value.
|
||||
+Currently the following subtypes are supported:
|
||||
+.Bd -literal -offset indent
|
||||
+rt Route Target
|
||||
+soo Source of Origin
|
||||
+odi OSPF Domain Identifier
|
||||
+ort OSPF Route Type
|
||||
+ori OSPF Router ID
|
||||
+bdc BGP Data Collection
|
||||
+.Ed
|
||||
+.Pp
|
||||
+Not all type and subtype value pairs are allowed by IANA and the parser
|
||||
+will ensure that no invalid combination is created.
|
||||
+.Pp
|
||||
.It Ic localpref Ar number
|
||||
Set the
|
||||
.Em LOCAL_PREF
|
||||
@@ -1108,6 +1396,20 @@ otherwise it will be set to
|
||||
.Ar number .
|
||||
.Pp
|
||||
.It Xo
|
||||
+.Ic origin
|
||||
+.Sm off
|
||||
+.Po Ic igp \*(Ba
|
||||
+.Ic egp \*(Ba
|
||||
+.Ic incomplete Pc
|
||||
+.Sm on
|
||||
+.Xc
|
||||
+Set the
|
||||
+.Em ORIGIN
|
||||
+AS path attribute to mark the source of this
|
||||
+route as being injected from an igp protocol, an egp protocol
|
||||
+or being an aggregated route.
|
||||
+.Pp
|
||||
+.It Xo
|
||||
.Ic nexthop
|
||||
.Sm off
|
||||
.Po Ar address \*(Ba
|
||||
@@ -1157,9 +1459,8 @@ times to the
|
||||
.Em AS path .
|
||||
.Pp
|
||||
.It Ic rtlabel Ar label
|
||||
-Add the prefix with the specified
|
||||
-.Ar label
|
||||
-to the kernel routing table.
|
||||
+Add the prefix to the kernel routing table with the specified
|
||||
+.Ar label .
|
||||
.Pp
|
||||
.It Ic weight Ar number
|
||||
The
|
||||
@@ -1181,8 +1482,8 @@ For prefixes with equally long paths, th
|
||||
is selected.
|
||||
.El
|
||||
.Sh FILES
|
||||
-.Bl -tag -width "/etc/bgpd.conf" -compact
|
||||
-.It Pa /etc/bgpd.conf
|
||||
+.Bl -tag -width "%%PREFIX%%/etc/bgpd.conf" -compact
|
||||
+.It Pa %%PREFIX%%/etc/bgpd.conf
|
||||
.Xr bgpd 8
|
||||
configuration file
|
||||
.El
|
872
net/openbgpd/files/patch-bgpd_bgpd.h
Normal file
872
net/openbgpd/files/patch-bgpd_bgpd.h
Normal file
@ -0,0 +1,872 @@
|
||||
Index: bgpd/bgpd.h
|
||||
===================================================================
|
||||
RCS file: /home/cvs/private/hrs/openbgpd/bgpd/bgpd.h,v
|
||||
retrieving revision 1.1.1.8
|
||||
retrieving revision 1.15
|
||||
diff -u -p -r1.1.1.8 -r1.15
|
||||
--- bgpd/bgpd.h 14 Feb 2010 20:19:57 -0000 1.1.1.8
|
||||
+++ bgpd/bgpd.h 16 May 2014 00:36:26 -0000 1.15
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* $OpenBSD: bgpd.h,v 1.241 2009/06/12 16:42:53 claudio Exp $ */
|
||||
+/* $OpenBSD: bgpd.h,v 1.273 2012/09/18 10:10:00 claudio Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/queue.h>
|
||||
+#include <sys/tree.h>
|
||||
#include <net/route.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
@@ -30,11 +31,16 @@
|
||||
#include <poll.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
-#include <imsg.h>
|
||||
+#if defined(__FreeBSD__) /* compat */
|
||||
+#include "openbsd-compat.h"
|
||||
+#endif /* defined(__FreeBSD__) */
|
||||
+#include "imsg.h"
|
||||
|
||||
#define BGP_VERSION 4
|
||||
#define BGP_PORT 179
|
||||
+#ifndef CONFFILE
|
||||
#define CONFFILE "/etc/bgpd.conf"
|
||||
+#endif /* !CONFFILE */
|
||||
#define BGPD_USER "_bgpd"
|
||||
#define PEER_DESCR_LEN 32
|
||||
#define PFTABLE_LEN 16
|
||||
@@ -42,8 +48,6 @@
|
||||
#define IPSEC_ENC_KEY_LEN 32
|
||||
#define IPSEC_AUTH_KEY_LEN 20
|
||||
|
||||
-#define ASNUM_MAX 0xffffffff
|
||||
-
|
||||
#define MAX_PKTSIZE 4096
|
||||
#define MIN_HOLDTIME 3
|
||||
#define READ_BUF_SIZE 65535
|
||||
@@ -55,13 +59,8 @@
|
||||
#define BGPD_OPT_NOACTION 0x0004
|
||||
#define BGPD_OPT_FORCE_DEMOTE 0x0008
|
||||
|
||||
-#define BGPD_FLAG_NO_FIB_UPDATE 0x0001
|
||||
#define BGPD_FLAG_NO_EVALUATE 0x0002
|
||||
#define BGPD_FLAG_REFLECTOR 0x0004
|
||||
-#define BGPD_FLAG_REDIST_STATIC 0x0008
|
||||
-#define BGPD_FLAG_REDIST_CONNECTED 0x0010
|
||||
-#define BGPD_FLAG_REDIST6_STATIC 0x0020
|
||||
-#define BGPD_FLAG_REDIST6_CONNECTED 0x0040
|
||||
#define BGPD_FLAG_NEXTHOP_BGP 0x0080
|
||||
#define BGPD_FLAG_NEXTHOP_DEFAULT 0x1000
|
||||
#define BGPD_FLAG_DECISION_MASK 0x0f00
|
||||
@@ -83,9 +82,12 @@
|
||||
#define F_REJECT 0x0080
|
||||
#define F_BLACKHOLE 0x0100
|
||||
#define F_LONGER 0x0200
|
||||
+#define F_MPLS 0x0400
|
||||
+#define F_REDISTRIBUTED 0x0800
|
||||
#define F_CTL_DETAIL 0x1000 /* only used by bgpctl */
|
||||
#define F_CTL_ADJ_IN 0x2000
|
||||
#define F_CTL_ADJ_OUT 0x4000
|
||||
+#define F_CTL_ACTIVE 0x8000
|
||||
|
||||
/*
|
||||
* Limit the number of control messages generated by the RDE and queued in
|
||||
@@ -109,18 +111,75 @@ enum reconf_action {
|
||||
RECONF_DELETE
|
||||
};
|
||||
|
||||
+/* Address Family Numbers as per RFC 1700 */
|
||||
+#define AFI_UNSPEC 0
|
||||
+#define AFI_IPv4 1
|
||||
+#define AFI_IPv6 2
|
||||
+
|
||||
+/* Subsequent Address Family Identifier as per RFC 4760 */
|
||||
+#define SAFI_NONE 0
|
||||
+#define SAFI_UNICAST 1
|
||||
+#define SAFI_MULTICAST 2
|
||||
+#define SAFI_MPLS 4
|
||||
+#define SAFI_MPLSVPN 128
|
||||
+
|
||||
+struct aid {
|
||||
+ u_int16_t afi;
|
||||
+ sa_family_t af;
|
||||
+ u_int8_t safi;
|
||||
+ char *name;
|
||||
+};
|
||||
+
|
||||
+extern const struct aid aid_vals[];
|
||||
+
|
||||
+#define AID_UNSPEC 0
|
||||
+#define AID_INET 1
|
||||
+#define AID_INET6 2
|
||||
+#define AID_VPN_IPv4 3
|
||||
+#define AID_MAX 4
|
||||
+#define AID_MIN 1 /* skip AID_UNSPEC since that is a dummy */
|
||||
+
|
||||
+#define AID_VALS { \
|
||||
+ /* afi, af, safii, name */ \
|
||||
+ { AFI_UNSPEC, AF_UNSPEC, SAFI_NONE, "unspec"}, \
|
||||
+ { AFI_IPv4, AF_INET, SAFI_UNICAST, "IPv4 unicast" }, \
|
||||
+ { AFI_IPv6, AF_INET6, SAFI_UNICAST, "IPv6 unicast" }, \
|
||||
+ { AFI_IPv4, AF_INET, SAFI_MPLSVPN, "IPv4 vpn" } \
|
||||
+}
|
||||
+
|
||||
+#define AID_PTSIZE { \
|
||||
+ 0, \
|
||||
+ sizeof(struct pt_entry4), \
|
||||
+ sizeof(struct pt_entry6), \
|
||||
+ sizeof(struct pt_entry_vpn4) \
|
||||
+}
|
||||
+
|
||||
+struct vpn4_addr {
|
||||
+ u_int64_t rd;
|
||||
+ struct in_addr addr;
|
||||
+ u_int8_t labelstack[21]; /* max that makes sense */
|
||||
+ u_int8_t labellen;
|
||||
+ u_int8_t pad1;
|
||||
+ u_int8_t pad2;
|
||||
+};
|
||||
+
|
||||
+#define BGP_MPLS_BOS 0x01
|
||||
+
|
||||
struct bgpd_addr {
|
||||
- sa_family_t af;
|
||||
union {
|
||||
struct in_addr v4;
|
||||
struct in6_addr v6;
|
||||
- u_int8_t addr8[16];
|
||||
- u_int16_t addr16[8];
|
||||
- u_int32_t addr32[4];
|
||||
+ struct vpn4_addr vpn4;
|
||||
+ /* maximum size for a prefix is 256 bits */
|
||||
+ u_int8_t addr8[32];
|
||||
+ u_int16_t addr16[16];
|
||||
+ u_int32_t addr32[8];
|
||||
} ba; /* 128-bit address */
|
||||
u_int32_t scope_id; /* iface scope id for v6 */
|
||||
+ u_int8_t aid;
|
||||
#define v4 ba.v4
|
||||
#define v6 ba.v6
|
||||
+#define vpn4 ba.vpn4
|
||||
#define addr8 ba.addr8
|
||||
#define addr16 ba.addr16
|
||||
#define addr32 ba.addr32
|
||||
@@ -141,17 +200,12 @@ TAILQ_HEAD(listen_addrs, listen_addr);
|
||||
TAILQ_HEAD(filter_set_head, filter_set);
|
||||
|
||||
struct bgpd_config {
|
||||
- struct filter_set_head connectset;
|
||||
- struct filter_set_head connectset6;
|
||||
- struct filter_set_head staticset;
|
||||
- struct filter_set_head staticset6;
|
||||
struct listen_addrs *listen_addrs;
|
||||
char *csock;
|
||||
char *rcsock;
|
||||
int opts;
|
||||
int flags;
|
||||
int log;
|
||||
- u_int rtableid;
|
||||
u_int32_t bgpid;
|
||||
u_int32_t clusterid;
|
||||
u_int32_t as;
|
||||
@@ -205,12 +259,24 @@ struct peer_auth {
|
||||
};
|
||||
|
||||
struct capabilities {
|
||||
- u_int8_t mp_v4; /* multiprotocol extensions, RFC 4760 */
|
||||
- u_int8_t mp_v6;
|
||||
- u_int8_t refresh; /* route refresh, RFC 2918 */
|
||||
- u_int8_t restart; /* graceful restart, RFC 4724 */
|
||||
- u_int8_t as4byte; /* draft-ietf-idr-as4bytes-13 */
|
||||
-};
|
||||
+ struct {
|
||||
+ int16_t timeout; /* graceful restart timeout */
|
||||
+ int8_t flags[AID_MAX]; /* graceful restart per AID flags */
|
||||
+ int8_t restart; /* graceful restart, RFC 4724 */
|
||||
+ } grestart;
|
||||
+ int8_t mp[AID_MAX]; /* multiprotocol extensions, RFC 4760 */
|
||||
+ int8_t refresh; /* route refresh, RFC 2918 */
|
||||
+ int8_t as4byte; /* 4-byte ASnum, RFC 4893 */
|
||||
+};
|
||||
+
|
||||
+#define CAPA_GR_PRESENT 0x01
|
||||
+#define CAPA_GR_RESTART 0x02
|
||||
+#define CAPA_GR_FORWARD 0x04
|
||||
+#define CAPA_GR_RESTARTING 0x08
|
||||
+
|
||||
+#define CAPA_GR_TIMEMASK 0x0fff
|
||||
+#define CAPA_GR_R_FLAG 0x8000
|
||||
+#define CAPA_GR_F_FLAG 0x80
|
||||
|
||||
struct peer_config {
|
||||
struct bgpd_addr remote_addr;
|
||||
@@ -237,7 +303,7 @@ struct peer_config {
|
||||
u_int8_t template;
|
||||
u_int8_t remote_masklen;
|
||||
u_int8_t cloned;
|
||||
- u_int8_t ebgp; /* 1 = ebgp, 0 = ibgp */
|
||||
+ u_int8_t ebgp; /* 0 = ibgp else ebgp */
|
||||
u_int8_t distance; /* 1 = direct, >1 = multihop */
|
||||
u_int8_t passive;
|
||||
u_int8_t down;
|
||||
@@ -248,21 +314,33 @@ struct peer_config {
|
||||
u_int8_t ttlsec; /* TTL security hack */
|
||||
u_int8_t flags;
|
||||
u_int8_t pad[3];
|
||||
+ char lliface[IFNAMSIZ];
|
||||
};
|
||||
|
||||
#define PEERFLAG_TRANS_AS 0x01
|
||||
|
||||
+enum network_type {
|
||||
+ NETWORK_DEFAULT,
|
||||
+ NETWORK_STATIC,
|
||||
+ NETWORK_CONNECTED,
|
||||
+ NETWORK_MRTCLONE
|
||||
+};
|
||||
+
|
||||
struct network_config {
|
||||
- struct bgpd_addr prefix;
|
||||
- struct filter_set_head attrset;
|
||||
- u_int8_t prefixlen;
|
||||
+ struct bgpd_addr prefix;
|
||||
+ struct filter_set_head attrset;
|
||||
+ struct rde_aspath *asp;
|
||||
+ u_int rtableid;
|
||||
+ enum network_type type;
|
||||
+ u_int8_t prefixlen;
|
||||
+ u_int8_t old; /* used for reloading */
|
||||
};
|
||||
|
||||
TAILQ_HEAD(network_head, network);
|
||||
|
||||
struct network {
|
||||
- struct network_config net;
|
||||
- TAILQ_ENTRY(network) entry;
|
||||
+ struct network_config net;
|
||||
+ TAILQ_ENTRY(network) entry;
|
||||
};
|
||||
|
||||
enum imsg_type {
|
||||
@@ -276,7 +354,6 @@ enum imsg_type {
|
||||
IMSG_CTL_NEIGHBOR_CLEAR,
|
||||
IMSG_CTL_NEIGHBOR_RREFRESH,
|
||||
IMSG_CTL_KROUTE,
|
||||
- IMSG_CTL_KROUTE6,
|
||||
IMSG_CTL_KROUTE_ADDR,
|
||||
IMSG_CTL_RESULT,
|
||||
IMSG_CTL_SHOW_NEIGHBOR,
|
||||
@@ -288,11 +365,14 @@ enum imsg_type {
|
||||
IMSG_CTL_SHOW_RIB_ATTR,
|
||||
IMSG_CTL_SHOW_RIB_COMMUNITY,
|
||||
IMSG_CTL_SHOW_NETWORK,
|
||||
- IMSG_CTL_SHOW_NETWORK6,
|
||||
IMSG_CTL_SHOW_RIB_MEM,
|
||||
IMSG_CTL_SHOW_TERSE,
|
||||
IMSG_CTL_SHOW_TIMER,
|
||||
+ IMSG_CTL_LOG_VERBOSE,
|
||||
+ IMSG_CTL_SHOW_FIB_TABLES,
|
||||
IMSG_NETWORK_ADD,
|
||||
+ IMSG_NETWORK_ASPATH,
|
||||
+ IMSG_NETWORK_ATTR,
|
||||
IMSG_NETWORK_REMOVE,
|
||||
IMSG_NETWORK_FLUSH,
|
||||
IMSG_NETWORK_DONE,
|
||||
@@ -302,19 +382,25 @@ enum imsg_type {
|
||||
IMSG_RECONF_PEER,
|
||||
IMSG_RECONF_FILTER,
|
||||
IMSG_RECONF_LISTENER,
|
||||
+ IMSG_RECONF_CTRL,
|
||||
+ IMSG_RECONF_RDOMAIN,
|
||||
+ IMSG_RECONF_RDOMAIN_EXPORT,
|
||||
+ IMSG_RECONF_RDOMAIN_IMPORT,
|
||||
+ IMSG_RECONF_RDOMAIN_DONE,
|
||||
IMSG_RECONF_DONE,
|
||||
IMSG_UPDATE,
|
||||
IMSG_UPDATE_ERR,
|
||||
IMSG_SESSION_ADD,
|
||||
IMSG_SESSION_UP,
|
||||
IMSG_SESSION_DOWN,
|
||||
+ IMSG_SESSION_STALE,
|
||||
+ IMSG_SESSION_FLUSH,
|
||||
+ IMSG_SESSION_RESTARTED,
|
||||
IMSG_MRT_OPEN,
|
||||
IMSG_MRT_REOPEN,
|
||||
IMSG_MRT_CLOSE,
|
||||
IMSG_KROUTE_CHANGE,
|
||||
IMSG_KROUTE_DELETE,
|
||||
- IMSG_KROUTE6_CHANGE,
|
||||
- IMSG_KROUTE6_DELETE,
|
||||
IMSG_NEXTHOP_ADD,
|
||||
IMSG_NEXTHOP_REMOVE,
|
||||
IMSG_NEXTHOP_UPDATE,
|
||||
@@ -337,6 +423,7 @@ enum ctl_results {
|
||||
CTL_RES_DENIED,
|
||||
CTL_RES_NOCAP,
|
||||
CTL_RES_PARSE_ERROR,
|
||||
+ CTL_RES_PENDING,
|
||||
CTL_RES_NOMEM
|
||||
};
|
||||
|
||||
@@ -379,9 +466,43 @@ enum suberr_cease {
|
||||
ERR_CEASE_RSRC_EXHAUST
|
||||
};
|
||||
|
||||
+struct kroute_node;
|
||||
+struct kroute6_node;
|
||||
+struct knexthop_node;
|
||||
+RB_HEAD(kroute_tree, kroute_node);
|
||||
+RB_HEAD(kroute6_tree, kroute6_node);
|
||||
+RB_HEAD(knexthop_tree, knexthop_node);
|
||||
+
|
||||
+struct ktable {
|
||||
+ char descr[PEER_DESCR_LEN];
|
||||
+ char ifmpe[IFNAMSIZ];
|
||||
+ struct kroute_tree krt;
|
||||
+ struct kroute6_tree krt6;
|
||||
+ struct knexthop_tree knt;
|
||||
+ struct network_head krn;
|
||||
+ u_int rtableid;
|
||||
+ u_int nhtableid; /* rdomain id for nexthop lookup */
|
||||
+ u_int ifindex; /* ifindex of ifmpe */
|
||||
+ int nhrefcnt; /* refcnt for nexthop table */
|
||||
+ enum reconf_action state;
|
||||
+ u_int8_t fib_conf; /* configured FIB sync flag */
|
||||
+ u_int8_t fib_sync; /* is FIB synced with kernel? */
|
||||
+};
|
||||
+
|
||||
+struct kroute_full {
|
||||
+ struct bgpd_addr prefix;
|
||||
+ struct bgpd_addr nexthop;
|
||||
+ char label[RTLABEL_LEN];
|
||||
+ u_int16_t flags;
|
||||
+ u_short ifindex;
|
||||
+ u_int8_t prefixlen;
|
||||
+ u_int8_t priority;
|
||||
+};
|
||||
+
|
||||
struct kroute {
|
||||
struct in_addr prefix;
|
||||
struct in_addr nexthop;
|
||||
+ u_int32_t mplslabel;
|
||||
u_int16_t flags;
|
||||
u_int16_t labelid;
|
||||
u_short ifindex;
|
||||
@@ -400,14 +521,12 @@ struct kroute6 {
|
||||
};
|
||||
|
||||
struct kroute_nexthop {
|
||||
- union {
|
||||
- struct kroute kr4;
|
||||
- struct kroute6 kr6;
|
||||
- } kr;
|
||||
struct bgpd_addr nexthop;
|
||||
struct bgpd_addr gateway;
|
||||
+ struct bgpd_addr net;
|
||||
u_int8_t valid;
|
||||
u_int8_t connected;
|
||||
+ u_int8_t netlen;
|
||||
};
|
||||
|
||||
struct kif {
|
||||
@@ -423,8 +542,7 @@ struct kif {
|
||||
struct session_up {
|
||||
struct bgpd_addr local_addr;
|
||||
struct bgpd_addr remote_addr;
|
||||
- struct capabilities capa_announced;
|
||||
- struct capabilities capa_received;
|
||||
+ struct capabilities capa;
|
||||
u_int32_t remote_bgpid;
|
||||
u_int16_t short_as;
|
||||
};
|
||||
@@ -437,8 +555,13 @@ struct pftable_msg {
|
||||
|
||||
struct ctl_show_nexthop {
|
||||
struct bgpd_addr addr;
|
||||
- u_int8_t valid;
|
||||
struct kif kif;
|
||||
+ union {
|
||||
+ struct kroute kr4;
|
||||
+ struct kroute6 kr6;
|
||||
+ } kr;
|
||||
+ u_int8_t valid;
|
||||
+ u_int8_t krvalid;
|
||||
};
|
||||
|
||||
struct ctl_neighbor {
|
||||
@@ -447,20 +570,11 @@ struct ctl_neighbor {
|
||||
int show_timers;
|
||||
};
|
||||
|
||||
-struct kroute_label {
|
||||
- struct kroute kr;
|
||||
- char label[RTLABEL_LEN];
|
||||
-};
|
||||
-
|
||||
-struct kroute6_label {
|
||||
- struct kroute6 kr;
|
||||
- char label[RTLABEL_LEN];
|
||||
-};
|
||||
-
|
||||
-#define F_RIB_ELIGIBLE 0x01
|
||||
-#define F_RIB_ACTIVE 0x02
|
||||
-#define F_RIB_INTERNAL 0x04
|
||||
-#define F_RIB_ANNOUNCE 0x08
|
||||
+#define F_PREF_ELIGIBLE 0x01
|
||||
+#define F_PREF_ACTIVE 0x02
|
||||
+#define F_PREF_INTERNAL 0x04
|
||||
+#define F_PREF_ANNOUNCE 0x08
|
||||
+#define F_PREF_STALE 0x10
|
||||
|
||||
struct ctl_show_rib {
|
||||
struct bgpd_addr true_nexthop;
|
||||
@@ -472,9 +586,7 @@ struct ctl_show_rib {
|
||||
u_int32_t remote_id;
|
||||
u_int32_t local_pref;
|
||||
u_int32_t med;
|
||||
- u_int32_t prefix_cnt;
|
||||
- u_int32_t active_cnt;
|
||||
- u_int32_t rib_cnt;
|
||||
+ u_int32_t weight;
|
||||
u_int16_t aspath_len;
|
||||
u_int16_t flags;
|
||||
u_int8_t prefixlen;
|
||||
@@ -482,13 +594,6 @@ struct ctl_show_rib {
|
||||
/* plus a aspath_len bytes long aspath */
|
||||
};
|
||||
|
||||
-struct ctl_show_rib_prefix {
|
||||
- struct bgpd_addr prefix;
|
||||
- time_t lastchange;
|
||||
- u_int16_t flags;
|
||||
- u_int8_t prefixlen;
|
||||
-};
|
||||
-
|
||||
enum as_spec {
|
||||
AS_NONE,
|
||||
AS_ALL,
|
||||
@@ -498,16 +603,52 @@ enum as_spec {
|
||||
AS_EMPTY
|
||||
};
|
||||
|
||||
+enum aslen_spec {
|
||||
+ ASLEN_NONE,
|
||||
+ ASLEN_MAX,
|
||||
+ ASLEN_SEQ
|
||||
+};
|
||||
+
|
||||
struct filter_as {
|
||||
- enum as_spec type;
|
||||
u_int32_t as;
|
||||
+ u_int16_t flags;
|
||||
+ enum as_spec type;
|
||||
};
|
||||
|
||||
+struct filter_aslen {
|
||||
+ u_int aslen;
|
||||
+ enum aslen_spec type;
|
||||
+};
|
||||
+
|
||||
+#define AS_FLAG_NEIGHBORAS 0x01
|
||||
+
|
||||
struct filter_community {
|
||||
- int as;
|
||||
- int type;
|
||||
+ int as;
|
||||
+ int type;
|
||||
};
|
||||
|
||||
+struct filter_extcommunity {
|
||||
+ u_int16_t flags;
|
||||
+ u_int8_t type;
|
||||
+ u_int8_t subtype; /* if extended type */
|
||||
+ union {
|
||||
+ struct ext_as {
|
||||
+ u_int16_t as;
|
||||
+ u_int32_t val;
|
||||
+ } ext_as;
|
||||
+ struct ext_as4 {
|
||||
+ u_int32_t as4;
|
||||
+ u_int16_t val;
|
||||
+ } ext_as4;
|
||||
+ struct ext_ip {
|
||||
+ struct in_addr addr;
|
||||
+ u_int16_t val;
|
||||
+ } ext_ip;
|
||||
+ u_int64_t ext_opaq; /* only 48 bits */
|
||||
+ } data;
|
||||
+};
|
||||
+
|
||||
+
|
||||
struct ctl_show_rib_request {
|
||||
char rib[PEER_DESCR_LEN];
|
||||
struct ctl_neighbor neighbor;
|
||||
@@ -518,8 +659,8 @@ struct ctl_show_rib_request {
|
||||
pid_t pid;
|
||||
u_int16_t flags;
|
||||
enum imsg_type type;
|
||||
- sa_family_t af;
|
||||
u_int8_t prefixlen;
|
||||
+ u_int8_t aid;
|
||||
};
|
||||
|
||||
enum filter_actions {
|
||||
@@ -585,6 +726,28 @@ struct filter_peers {
|
||||
#define EXT_COMMUNITY_OSPF_RTR_TYPE 6 /* RFC 4577 */
|
||||
#define EXT_COMMUNITY_OSPF_RTR_ID 7 /* RFC 4577 */
|
||||
#define EXT_COMMUNITY_BGP_COLLECT 8 /* RFC 4384 */
|
||||
+/* other handy defines */
|
||||
+#define EXT_COMMUNITY_OPAQUE_MAX 0xffffffffffffULL
|
||||
+#define EXT_COMMUNITY_FLAG_VALID 0x01
|
||||
+
|
||||
+struct ext_comm_pairs {
|
||||
+ u_int8_t type;
|
||||
+ u_int8_t subtype;
|
||||
+ u_int8_t transitive; /* transitive bit needs to be set */
|
||||
+};
|
||||
+
|
||||
+#define IANA_EXT_COMMUNITIES { \
|
||||
+ { EXT_COMMUNITY_TWO_AS, EXT_COMMUNITY_ROUTE_TGT, 0 }, \
|
||||
+ { EXT_COMMUNITY_TWO_AS, EXT_CUMMUNITY_ROUTE_ORIG, 0 }, \
|
||||
+ { EXT_COMMUNITY_TWO_AS, EXT_COMMUNITY_OSPF_DOM_ID, 0 }, \
|
||||
+ { EXT_COMMUNITY_TWO_AS, EXT_COMMUNITY_BGP_COLLECT, 0 }, \
|
||||
+ { EXT_COMMUNITY_FOUR_AS, EXT_COMMUNITY_ROUTE_TGT, 0 }, \
|
||||
+ { EXT_COMMUNITY_FOUR_AS, EXT_CUMMUNITY_ROUTE_ORIG, 0 }, \
|
||||
+ { EXT_COMMUNITY_IPV4, EXT_COMMUNITY_ROUTE_TGT, 0 }, \
|
||||
+ { EXT_COMMUNITY_IPV4, EXT_CUMMUNITY_ROUTE_ORIG, 0 }, \
|
||||
+ { EXT_COMMUNITY_IPV4, EXT_COMMUNITY_OSPF_RTR_ID, 0 }, \
|
||||
+ { EXT_COMMUNITY_OPAQUE, EXT_COMMUNITY_OSPF_RTR_TYPE, 0 } \
|
||||
+}
|
||||
|
||||
|
||||
struct filter_prefix {
|
||||
@@ -592,18 +755,28 @@ struct filter_prefix {
|
||||
u_int8_t len;
|
||||
};
|
||||
|
||||
+struct filter_nexthop {
|
||||
+ struct bgpd_addr addr;
|
||||
+ u_int8_t flags;
|
||||
+#define FILTER_NEXTHOP_ADDR 1
|
||||
+#define FILTER_NEXTHOP_NEIGHBOR 2
|
||||
+};
|
||||
+
|
||||
struct filter_prefixlen {
|
||||
enum comp_ops op;
|
||||
- sa_family_t af;
|
||||
+ u_int8_t aid;
|
||||
u_int8_t len_min;
|
||||
u_int8_t len_max;
|
||||
};
|
||||
|
||||
struct filter_match {
|
||||
- struct filter_prefix prefix;
|
||||
- struct filter_prefixlen prefixlen;
|
||||
- struct filter_as as;
|
||||
- struct filter_community community;
|
||||
+ struct filter_prefix prefix;
|
||||
+ struct filter_prefixlen prefixlen;
|
||||
+ struct filter_nexthop nexthop;
|
||||
+ struct filter_as as;
|
||||
+ struct filter_aslen aslen;
|
||||
+ struct filter_community community;
|
||||
+ struct filter_extcommunity ext_community;
|
||||
};
|
||||
|
||||
TAILQ_HEAD(filter_head, filter_rule);
|
||||
@@ -635,10 +808,13 @@ enum action_types {
|
||||
ACTION_SET_NEXTHOP_SELF,
|
||||
ACTION_SET_COMMUNITY,
|
||||
ACTION_DEL_COMMUNITY,
|
||||
+ ACTION_SET_EXT_COMMUNITY,
|
||||
+ ACTION_DEL_EXT_COMMUNITY,
|
||||
ACTION_PFTABLE,
|
||||
ACTION_PFTABLE_ID,
|
||||
ACTION_RTLABEL,
|
||||
- ACTION_RTLABEL_ID
|
||||
+ ACTION_RTLABEL_ID,
|
||||
+ ACTION_SET_ORIGIN
|
||||
};
|
||||
|
||||
struct filter_set {
|
||||
@@ -650,23 +826,53 @@ struct filter_set {
|
||||
int32_t relative;
|
||||
struct bgpd_addr nexthop;
|
||||
struct filter_community community;
|
||||
+ struct filter_extcommunity ext_community;
|
||||
char pftable[PFTABLE_LEN];
|
||||
char rtlabel[RTLABEL_LEN];
|
||||
+ u_int8_t origin;
|
||||
} action;
|
||||
enum action_types type;
|
||||
};
|
||||
|
||||
-struct rrefresh {
|
||||
- u_int16_t afi;
|
||||
- u_int8_t safi;
|
||||
+struct rdomain {
|
||||
+ SIMPLEQ_ENTRY(rdomain) entry;
|
||||
+ char descr[PEER_DESCR_LEN];
|
||||
+ char ifmpe[IFNAMSIZ];
|
||||
+ struct filter_set_head import;
|
||||
+ struct filter_set_head export;
|
||||
+ struct network_head net_l;
|
||||
+ u_int64_t rd;
|
||||
+ u_int rtableid;
|
||||
+ u_int label;
|
||||
+ int flags;
|
||||
};
|
||||
+SIMPLEQ_HEAD(rdomain_head, rdomain);
|
||||
+
|
||||
+struct rde_rib {
|
||||
+ SIMPLEQ_ENTRY(rde_rib) entry;
|
||||
+ char name[PEER_DESCR_LEN];
|
||||
+ u_int rtableid;
|
||||
+ u_int16_t id;
|
||||
+ u_int16_t flags;
|
||||
+};
|
||||
+SIMPLEQ_HEAD(rib_names, rde_rib);
|
||||
+extern struct rib_names ribnames;
|
||||
+
|
||||
+/* rde_rib flags */
|
||||
+#define F_RIB_ENTRYLOCK 0x0001
|
||||
+#define F_RIB_NOEVALUATE 0x0002
|
||||
+#define F_RIB_NOFIB 0x0004
|
||||
+#define F_RIB_NOFIBSYNC 0x0008
|
||||
+#define F_RIB_HASNOFIB (F_RIB_NOFIB | F_RIB_NOEVALUATE)
|
||||
+
|
||||
+/* 4-byte magic AS number */
|
||||
+#define AS_TRANS 23456
|
||||
|
||||
struct rde_memstats {
|
||||
int64_t path_cnt;
|
||||
int64_t prefix_cnt;
|
||||
int64_t rib_cnt;
|
||||
- int64_t pt4_cnt;
|
||||
- int64_t pt6_cnt;
|
||||
+ int64_t pt_cnt[AID_MAX];
|
||||
int64_t nexthop_cnt;
|
||||
int64_t aspath_cnt;
|
||||
int64_t aspath_size;
|
||||
@@ -677,82 +883,117 @@ struct rde_memstats {
|
||||
int64_t attr_dcnt;
|
||||
};
|
||||
|
||||
-struct rde_rib {
|
||||
- SIMPLEQ_ENTRY(rde_rib) entry;
|
||||
- char name[PEER_DESCR_LEN];
|
||||
- u_int16_t id;
|
||||
- u_int16_t flags;
|
||||
+/* macros for IPv6 link-local address */
|
||||
+#ifdef __KAME__
|
||||
+#define IN6_LINKLOCAL_IFINDEX(addr) \
|
||||
+ ((addr).s6_addr[2] << 8 | (addr).s6_addr[3])
|
||||
+
|
||||
+#define SET_IN6_LINKLOCAL_IFINDEX(addr, index) \
|
||||
+ do { \
|
||||
+ (addr).s6_addr[2] = ((index) >> 8) & 0xff; \
|
||||
+ (addr).s6_addr[3] = (index) & 0xff; \
|
||||
+ } while (0)
|
||||
+#endif
|
||||
+
|
||||
+#define MRT_FILE_LEN 512
|
||||
+#define MRT2MC(x) ((struct mrt_config *)(x))
|
||||
+#define MRT_MAX_TIMEOUT 7200
|
||||
+
|
||||
+enum mrt_type {
|
||||
+ MRT_NONE,
|
||||
+ MRT_TABLE_DUMP,
|
||||
+ MRT_TABLE_DUMP_MP,
|
||||
+ MRT_TABLE_DUMP_V2,
|
||||
+ MRT_ALL_IN,
|
||||
+ MRT_ALL_OUT,
|
||||
+ MRT_UPDATE_IN,
|
||||
+ MRT_UPDATE_OUT
|
||||
+};
|
||||
+
|
||||
+enum mrt_state {
|
||||
+ MRT_STATE_RUNNING,
|
||||
+ MRT_STATE_OPEN,
|
||||
+ MRT_STATE_REOPEN,
|
||||
+ MRT_STATE_REMOVE
|
||||
};
|
||||
-SIMPLEQ_HEAD(rib_names, rde_rib);
|
||||
-extern struct rib_names ribnames;
|
||||
|
||||
-/* Address Family Numbers as per RFC 1700 */
|
||||
-#define AFI_IPv4 1
|
||||
-#define AFI_IPv6 2
|
||||
-#define AFI_ALL 0xffff
|
||||
-
|
||||
-/* Subsequent Address Family Identifier as per RFC 4760 */
|
||||
-#define SAFI_NONE 0x00
|
||||
-#define SAFI_UNICAST 0x01
|
||||
-#define SAFI_MULTICAST 0x02
|
||||
-#define SAFI_ALL 0xff
|
||||
+struct mrt {
|
||||
+ char rib[PEER_DESCR_LEN];
|
||||
+ struct msgbuf wbuf;
|
||||
+ LIST_ENTRY(mrt) entry;
|
||||
+ u_int32_t peer_id;
|
||||
+ u_int32_t group_id;
|
||||
+ enum mrt_type type;
|
||||
+ enum mrt_state state;
|
||||
+ u_int16_t seqnum;
|
||||
+};
|
||||
|
||||
-/* 4-byte magic AS number */
|
||||
-#define AS_TRANS 23456
|
||||
+struct mrt_config {
|
||||
+ struct mrt conf;
|
||||
+ char name[MRT_FILE_LEN]; /* base file name */
|
||||
+ char file[MRT_FILE_LEN]; /* actual file name */
|
||||
+ time_t ReopenTimer;
|
||||
+ time_t ReopenTimerInterval;
|
||||
+};
|
||||
|
||||
/* prototypes */
|
||||
/* bgpd.c */
|
||||
void send_nexthop_update(struct kroute_nexthop *);
|
||||
void send_imsg_session(int, pid_t, void *, u_int16_t);
|
||||
-int bgpd_redistribute(int, struct kroute *, struct kroute6 *);
|
||||
+int send_network(int, struct network_config *,
|
||||
+ struct filter_set_head *);
|
||||
int bgpd_filternexthop(struct kroute *, struct kroute6 *);
|
||||
|
||||
-/* log.c */
|
||||
-void log_init(int);
|
||||
-void vlog(int, const char *, va_list);
|
||||
-void log_peer_warn(const struct peer_config *, const char *, ...);
|
||||
-void log_peer_warnx(const struct peer_config *, const char *, ...);
|
||||
-void log_warn(const char *, ...);
|
||||
-void log_warnx(const char *, ...);
|
||||
-void log_info(const char *, ...);
|
||||
-void log_debug(const char *, ...);
|
||||
-void fatal(const char *) __dead;
|
||||
-void fatalx(const char *) __dead;
|
||||
-
|
||||
-/* parse.y */
|
||||
-int cmdline_symset(char *);
|
||||
+/* control.c */
|
||||
+void control_cleanup(const char *);
|
||||
+int control_imsg_relay(struct imsg *);
|
||||
|
||||
/* config.c */
|
||||
int host(const char *, struct bgpd_addr *, u_int8_t *);
|
||||
|
||||
/* kroute.c */
|
||||
-int kr_init(int, u_int);
|
||||
-int kr_change(struct kroute_label *);
|
||||
-int kr_delete(struct kroute_label *);
|
||||
-int kr6_change(struct kroute6_label *);
|
||||
-int kr6_delete(struct kroute6_label *);
|
||||
+int kr_init(void);
|
||||
+int ktable_update(u_int, char *, char *, int);
|
||||
+void ktable_preload(void);
|
||||
+void ktable_postload(void);
|
||||
+int ktable_exists(u_int, u_int *);
|
||||
+int kr_change(u_int, struct kroute_full *);
|
||||
+int kr_delete(u_int, struct kroute_full *);
|
||||
void kr_shutdown(void);
|
||||
-void kr_fib_couple(void);
|
||||
-void kr_fib_decouple(void);
|
||||
+void kr_fib_couple(u_int);
|
||||
+void kr_fib_decouple(u_int);
|
||||
int kr_dispatch_msg(void);
|
||||
-int kr_nexthop_add(struct bgpd_addr *);
|
||||
-void kr_nexthop_delete(struct bgpd_addr *);
|
||||
+int kr_nexthop_add(u_int32_t, struct bgpd_addr *);
|
||||
+void kr_nexthop_delete(u_int32_t, struct bgpd_addr *);
|
||||
void kr_show_route(struct imsg *);
|
||||
void kr_ifinfo(char *);
|
||||
+int kr_net_reload(u_int, struct network_head *);
|
||||
int kr_reload(void);
|
||||
struct in6_addr *prefixlen2mask6(u_int8_t prefixlen);
|
||||
|
||||
-/* control.c */
|
||||
-void control_cleanup(const char *);
|
||||
-int control_imsg_relay(struct imsg *);
|
||||
+/* log.c */
|
||||
+void log_init(int);
|
||||
+void log_verbose(int);
|
||||
+void vlog(int, const char *, va_list);
|
||||
+void log_peer_warn(const struct peer_config *, const char *, ...);
|
||||
+void log_peer_warnx(const struct peer_config *, const char *, ...);
|
||||
+void log_warn(const char *, ...);
|
||||
+void log_warnx(const char *, ...);
|
||||
+void log_info(const char *, ...);
|
||||
+void log_debug(const char *, ...);
|
||||
+void fatal(const char *) __dead;
|
||||
+void fatalx(const char *) __dead;
|
||||
|
||||
-/* pftable.c */
|
||||
-int pftable_exists(const char *);
|
||||
-int pftable_add(const char *);
|
||||
-int pftable_clear_all(void);
|
||||
-int pftable_addr_add(struct pftable_msg *);
|
||||
-int pftable_addr_remove(struct pftable_msg *);
|
||||
-int pftable_commit(void);
|
||||
+/* mrt.c */
|
||||
+void mrt_clear_seq(void);
|
||||
+void mrt_write(struct mrt *);
|
||||
+void mrt_clean(struct mrt *);
|
||||
+void mrt_init(struct imsgbuf *, struct imsgbuf *);
|
||||
+int mrt_timeout(struct mrt_head *);
|
||||
+void mrt_reconfigure(struct mrt_head *);
|
||||
+void mrt_handler(struct mrt_head *);
|
||||
+struct mrt *mrt_get(struct mrt_head *, struct mrt *);
|
||||
+int mrt_mergeconfig(struct mrt_head *, struct mrt_head *);
|
||||
|
||||
/* name2id.c */
|
||||
u_int16_t rib_name2id(const char *);
|
||||
@@ -768,10 +1009,22 @@ const char *pftable_id2name(u_int16_t);
|
||||
void pftable_unref(u_int16_t);
|
||||
void pftable_ref(u_int16_t);
|
||||
|
||||
+/* parse.y */
|
||||
+int cmdline_symset(char *);
|
||||
+
|
||||
+/* pftable.c */
|
||||
+int pftable_exists(const char *);
|
||||
+int pftable_add(const char *);
|
||||
+int pftable_clear_all(void);
|
||||
+int pftable_addr_add(struct pftable_msg *);
|
||||
+int pftable_addr_remove(struct pftable_msg *);
|
||||
+int pftable_commit(void);
|
||||
|
||||
/* rde_filter.c */
|
||||
void filterset_free(struct filter_set_head *);
|
||||
int filterset_cmp(struct filter_set *, struct filter_set *);
|
||||
+void filterset_move(struct filter_set_head *,
|
||||
+ struct filter_set_head *);
|
||||
const char *filterset_name(enum action_types);
|
||||
|
||||
/* util.c */
|
||||
@@ -779,11 +1032,24 @@ const char *log_addr(const struct bgpd_a
|
||||
const char *log_in6addr(const struct in6_addr *);
|
||||
const char *log_sockaddr(struct sockaddr *);
|
||||
const char *log_as(u_int32_t);
|
||||
+const char *log_rd(u_int64_t);
|
||||
+const char *log_ext_subtype(u_int8_t);
|
||||
int aspath_snprint(char *, size_t, void *, u_int16_t);
|
||||
int aspath_asprint(char **, void *, u_int16_t);
|
||||
size_t aspath_strlen(void *, u_int16_t);
|
||||
+int aspath_match(void *, u_int16_t, enum as_spec, u_int32_t);
|
||||
+u_int32_t aspath_extract(const void *, int);
|
||||
+int prefix_compare(const struct bgpd_addr *,
|
||||
+ const struct bgpd_addr *, int);
|
||||
in_addr_t prefixlen2mask(u_int8_t);
|
||||
void inet6applymask(struct in6_addr *, const struct in6_addr *,
|
||||
int);
|
||||
+const char *aid2str(u_int8_t);
|
||||
+int aid2afi(u_int8_t, u_int16_t *, u_int8_t *);
|
||||
+int afi2aid(u_int16_t, u_int8_t, u_int8_t *);
|
||||
+sa_family_t aid2af(u_int8_t);
|
||||
+int af2aid(sa_family_t, u_int8_t, u_int8_t *);
|
||||
+struct sockaddr *addr2sa(struct bgpd_addr *, u_int16_t);
|
||||
+void sa2addr(struct sockaddr *, struct bgpd_addr *);
|
||||
|
||||
#endif /* __BGPD_H__ */
|
104
net/openbgpd/files/patch-bgpd_buffer.c
Normal file
104
net/openbgpd/files/patch-bgpd_buffer.c
Normal file
@ -0,0 +1,104 @@
|
||||
Index: bgpd/buffer.c
|
||||
===================================================================
|
||||
RCS file: /home/cvs/private/hrs/openbgpd/bgpd/buffer.c,v
|
||||
retrieving revision 1.1.1.7
|
||||
retrieving revision 1.3
|
||||
diff -u -p -r1.1.1.7 -r1.3
|
||||
--- bgpd/buffer.c 14 Feb 2010 20:19:57 -0000 1.1.1.7
|
||||
+++ bgpd/buffer.c 8 Dec 2012 20:17:59 -0000 1.3
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* $OpenBSD: buffer.c,v 1.43 2009/06/06 06:33:15 eric Exp $ */
|
||||
+/* $OpenBSD: buffer.c,v 1.44 2009/07/23 18:58:42 eric Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
|
||||
@@ -144,7 +144,7 @@ int
|
||||
buf_write(struct msgbuf *msgbuf)
|
||||
{
|
||||
struct iovec iov[IOV_MAX];
|
||||
- struct buf *buf, *next;
|
||||
+ struct buf *buf;
|
||||
unsigned int i = 0;
|
||||
ssize_t n;
|
||||
|
||||
@@ -153,7 +153,7 @@ buf_write(struct msgbuf *msgbuf)
|
||||
if (i >= IOV_MAX)
|
||||
break;
|
||||
iov[i].iov_base = buf->buf + buf->rpos;
|
||||
- iov[i].iov_len = buf->size - buf->rpos;
|
||||
+ iov[i].iov_len = buf->wpos - buf->rpos;
|
||||
i++;
|
||||
}
|
||||
|
||||
@@ -170,17 +170,7 @@ buf_write(struct msgbuf *msgbuf)
|
||||
return (-2);
|
||||
}
|
||||
|
||||
- for (buf = TAILQ_FIRST(&msgbuf->bufs); buf != NULL && n > 0;
|
||||
- buf = next) {
|
||||
- next = TAILQ_NEXT(buf, entry);
|
||||
- if (buf->rpos + n >= buf->size) {
|
||||
- n -= buf->size - buf->rpos;
|
||||
- buf_dequeue(msgbuf, buf);
|
||||
- } else {
|
||||
- buf->rpos += n;
|
||||
- n = 0;
|
||||
- }
|
||||
- }
|
||||
+ msgbuf_drain(msgbuf, n);
|
||||
|
||||
return (0);
|
||||
}
|
||||
@@ -201,6 +191,24 @@ msgbuf_init(struct msgbuf *msgbuf)
|
||||
}
|
||||
|
||||
void
|
||||
+msgbuf_drain(struct msgbuf *msgbuf, size_t n)
|
||||
+{
|
||||
+ struct buf *buf, *next;
|
||||
+
|
||||
+ for (buf = TAILQ_FIRST(&msgbuf->bufs); buf != NULL && n > 0;
|
||||
+ buf = next) {
|
||||
+ next = TAILQ_NEXT(buf, entry);
|
||||
+ if (buf->rpos + n >= buf->wpos) {
|
||||
+ n -= buf->wpos - buf->rpos;
|
||||
+ buf_dequeue(msgbuf, buf);
|
||||
+ } else {
|
||||
+ buf->rpos += n;
|
||||
+ n = 0;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void
|
||||
msgbuf_clear(struct msgbuf *msgbuf)
|
||||
{
|
||||
struct buf *buf;
|
||||
@@ -213,7 +221,7 @@ int
|
||||
msgbuf_write(struct msgbuf *msgbuf)
|
||||
{
|
||||
struct iovec iov[IOV_MAX];
|
||||
- struct buf *buf, *next;
|
||||
+ struct buf *buf;
|
||||
unsigned int i = 0;
|
||||
ssize_t n;
|
||||
struct msghdr msg;
|
||||
@@ -270,17 +278,7 @@ msgbuf_write(struct msgbuf *msgbuf)
|
||||
buf->fd = -1;
|
||||
}
|
||||
|
||||
- for (buf = TAILQ_FIRST(&msgbuf->bufs); buf != NULL && n > 0;
|
||||
- buf = next) {
|
||||
- next = TAILQ_NEXT(buf, entry);
|
||||
- if (buf->rpos + n >= buf->wpos) {
|
||||
- n -= buf->wpos - buf->rpos;
|
||||
- buf_dequeue(msgbuf, buf);
|
||||
- } else {
|
||||
- buf->rpos += n;
|
||||
- n = 0;
|
||||
- }
|
||||
- }
|
||||
+ msgbuf_drain(msgbuf, n);
|
||||
|
||||
return (0);
|
||||
}
|
54
net/openbgpd/files/patch-bgpd_carp.c
Normal file
54
net/openbgpd/files/patch-bgpd_carp.c
Normal file
@ -0,0 +1,54 @@
|
||||
Index: bgpd/carp.c
|
||||
===================================================================
|
||||
RCS file: /home/cvs/private/hrs/openbgpd/bgpd/carp.c,v
|
||||
retrieving revision 1.1.1.6
|
||||
retrieving revision 1.4
|
||||
diff -u -p -r1.1.1.6 -r1.4
|
||||
--- bgpd/carp.c 14 Feb 2010 20:19:57 -0000 1.1.1.6
|
||||
+++ bgpd/carp.c 22 Oct 2009 15:10:02 -0000 1.4
|
||||
@@ -93,9 +93,8 @@ carp_demote_shutdown(void)
|
||||
|
||||
while ((c = TAILQ_FIRST(&carpgroups)) != NULL) {
|
||||
TAILQ_REMOVE(&carpgroups, c, entry);
|
||||
- for (; c->changed_by > 0; c->changed_by--)
|
||||
- if (c->do_demote)
|
||||
- carp_demote_ioctl(c->group, -1);
|
||||
+ if (c->do_demote && c->changed_by > 0)
|
||||
+ carp_demote_ioctl(c->group, -c->changed_by);
|
||||
|
||||
free(c->group);
|
||||
free(c);
|
||||
@@ -105,6 +104,9 @@ carp_demote_shutdown(void)
|
||||
int
|
||||
carp_demote_get(char *group)
|
||||
{
|
||||
+#if defined(__FreeBSD__) /* FreeBSD does not have support for CARP */
|
||||
+ return (-1);
|
||||
+#else
|
||||
int s;
|
||||
struct ifgroupreq ifgr;
|
||||
|
||||
@@ -127,6 +129,7 @@ carp_demote_get(char *group)
|
||||
|
||||
close(s);
|
||||
return ((int)ifgr.ifgr_attrib.ifg_carp_demoted);
|
||||
+#endif /* defined(__FreeBSD__) */
|
||||
}
|
||||
|
||||
int
|
||||
@@ -159,6 +162,9 @@ carp_demote_set(char *group, int demote)
|
||||
int
|
||||
carp_demote_ioctl(char *group, int demote)
|
||||
{
|
||||
+#if defined(__FreeBSD__) /* FreeBSD does not have support for CARP */
|
||||
+ return (-1);
|
||||
+#else
|
||||
int s, res;
|
||||
struct ifgroupreq ifgr;
|
||||
|
||||
@@ -181,4 +187,5 @@ carp_demote_ioctl(char *group, int demot
|
||||
|
||||
close(s);
|
||||
return (res);
|
||||
+#endif /* defined(__FreeBSD__) */
|
||||
}
|
109
net/openbgpd/files/patch-bgpd_config.c
Normal file
109
net/openbgpd/files/patch-bgpd_config.c
Normal file
@ -0,0 +1,109 @@
|
||||
Index: bgpd/config.c
|
||||
===================================================================
|
||||
RCS file: /home/cvs/private/hrs/openbgpd/bgpd/config.c,v
|
||||
retrieving revision 1.1.1.6
|
||||
retrieving revision 1.3
|
||||
diff -u -p -r1.1.1.6 -r1.3
|
||||
--- bgpd/config.c 14 Feb 2010 20:19:57 -0000 1.1.1.6
|
||||
+++ bgpd/config.c 13 Oct 2012 18:36:00 -0000 1.3
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* $OpenBSD: config.c,v 1.51 2009/01/26 23:10:02 claudio Exp $ */
|
||||
+/* $OpenBSD: config.c,v 1.55 2010/09/02 14:03:21 sobrado Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003, 2004, 2005 Henning Brauer <henning@openbsd.org>
|
||||
@@ -20,6 +20,11 @@
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
+#include <sys/ioctl.h>
|
||||
+
|
||||
+#if !defined(__FreeBSD__) /* FreeBSD has no mpls support. */
|
||||
+#include <netmpls/mpls.h>
|
||||
+#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <ifaddrs.h>
|
||||
@@ -47,8 +52,6 @@ merge_config(struct bgpd_config *xconf,
|
||||
|
||||
/* preserve cmd line opts */
|
||||
conf->opts = xconf->opts;
|
||||
- conf->csock = xconf->csock;
|
||||
- conf->rcsock = xconf->rcsock;
|
||||
|
||||
if (!conf->as) {
|
||||
log_warnx("configuration error: AS not given");
|
||||
@@ -64,6 +67,9 @@ merge_config(struct bgpd_config *xconf,
|
||||
if ((conf->flags & BGPD_FLAG_REFLECTOR) && conf->clusterid == 0)
|
||||
conf->clusterid = conf->bgpid;
|
||||
|
||||
+ free(xconf->csock);
|
||||
+ free(xconf->rcsock);
|
||||
+
|
||||
conf->listen_addrs = xconf->listen_addrs;
|
||||
memcpy(xconf, conf, sizeof(struct bgpd_config));
|
||||
|
||||
@@ -74,7 +80,7 @@ merge_config(struct bgpd_config *xconf,
|
||||
nla->reconf = RECONF_REINIT;
|
||||
|
||||
} else {
|
||||
- /*
|
||||
+ /*
|
||||
* merge new listeners:
|
||||
* -flag all existing ones as to be deleted
|
||||
* -those that are in both new and old: flag to keep
|
||||
@@ -208,7 +214,7 @@ host_v4(const char *s, struct bgpd_addr
|
||||
return (0);
|
||||
}
|
||||
|
||||
- h->af = AF_INET;
|
||||
+ h->aid = AID_INET;
|
||||
h->v4.s_addr = ina.s_addr;
|
||||
*len = bits;
|
||||
|
||||
@@ -225,13 +231,7 @@ host_v6(const char *s, struct bgpd_addr
|
||||
hints.ai_socktype = SOCK_DGRAM; /*dummy*/
|
||||
hints.ai_flags = AI_NUMERICHOST;
|
||||
if (getaddrinfo(s, "0", &hints, &res) == 0) {
|
||||
- h->af = AF_INET6;
|
||||
- memcpy(&h->v6,
|
||||
- &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr,
|
||||
- sizeof(h->v6));
|
||||
- h->scope_id =
|
||||
- ((struct sockaddr_in6 *)res->ai_addr)->sin6_scope_id;
|
||||
-
|
||||
+ sa2addr(res->ai_addr, h);
|
||||
freeaddrinfo(res);
|
||||
return (1);
|
||||
}
|
||||
@@ -317,3 +317,30 @@ prepare_listeners(struct bgpd_config *co
|
||||
}
|
||||
}
|
||||
}
|
||||
+
|
||||
+int
|
||||
+get_mpe_label(struct rdomain *r)
|
||||
+{
|
||||
+#if !defined(__FreeBSD__) /* FreeBSD has no mpls support. */
|
||||
+ struct ifreq ifr;
|
||||
+ struct shim_hdr shim;
|
||||
+ int s;
|
||||
+
|
||||
+ s = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
+ if (s == -1)
|
||||
+ return (-1);
|
||||
+
|
||||
+ bzero(&shim, sizeof(shim));
|
||||
+ bzero(&ifr, sizeof(ifr));
|
||||
+ strlcpy(ifr.ifr_name, r->ifmpe, sizeof(ifr.ifr_name));
|
||||
+ ifr.ifr_data = (caddr_t)&shim;
|
||||
+
|
||||
+ if (ioctl(s, SIOCGETLABEL, (caddr_t)&ifr) == -1) {
|
||||
+ close(s);
|
||||
+ return (-1);
|
||||
+ }
|
||||
+ close(s);
|
||||
+ r->label = shim.shim_label;
|
||||
+#endif
|
||||
+ return (0);
|
||||
+}
|
171
net/openbgpd/files/patch-bgpd_control.c
Normal file
171
net/openbgpd/files/patch-bgpd_control.c
Normal file
@ -0,0 +1,171 @@
|
||||
Index: bgpd/control.c
|
||||
===================================================================
|
||||
RCS file: /home/cvs/private/hrs/openbgpd/bgpd/control.c,v
|
||||
retrieving revision 1.1.1.7
|
||||
retrieving revision 1.1.1.10
|
||||
diff -u -p -r1.1.1.7 -r1.1.1.10
|
||||
--- bgpd/control.c 14 Feb 2010 20:19:57 -0000 1.1.1.7
|
||||
+++ bgpd/control.c 13 Oct 2012 18:22:41 -0000 1.1.1.10
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* $OpenBSD: control.c,v 1.61 2009/05/05 20:09:19 sthen Exp $ */
|
||||
+/* $OpenBSD: control.c,v 1.71 2012/04/12 17:26:09 claudio Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
|
||||
@@ -53,7 +53,7 @@ control_init(int restricted, char *path)
|
||||
|
||||
if (unlink(path) == -1)
|
||||
if (errno != ENOENT) {
|
||||
- log_warn("unlink %s", path);
|
||||
+ log_warn("control_init: unlink %s", path);
|
||||
close(fd);
|
||||
return (-1);
|
||||
}
|
||||
@@ -122,15 +122,18 @@ control_accept(int listenfd, int restric
|
||||
len = sizeof(sun);
|
||||
if ((connfd = accept(listenfd,
|
||||
(struct sockaddr *)&sun, &len)) == -1) {
|
||||
- if (errno != EWOULDBLOCK && errno != EINTR)
|
||||
- log_warn("session_control_accept");
|
||||
+ if (errno == ENFILE || errno == EMFILE) {
|
||||
+ pauseaccept = getmonotime();
|
||||
+ return (0);
|
||||
+ } else if (errno != EWOULDBLOCK && errno != EINTR)
|
||||
+ log_warn("control_accept: accept");
|
||||
return (0);
|
||||
}
|
||||
|
||||
session_socket_blockmode(connfd, BM_NONBLOCK);
|
||||
|
||||
- if ((ctl_conn = malloc(sizeof(struct ctl_conn))) == NULL) {
|
||||
- log_warn("session_control_accept");
|
||||
+ if ((ctl_conn = calloc(1, sizeof(struct ctl_conn))) == NULL) {
|
||||
+ log_warn("control_accept");
|
||||
close(connfd);
|
||||
return (0);
|
||||
}
|
||||
@@ -182,7 +185,7 @@ control_close(int fd)
|
||||
|
||||
close(c->ibuf.fd);
|
||||
free(c);
|
||||
-
|
||||
+ pauseaccept = 0;
|
||||
return (1);
|
||||
}
|
||||
|
||||
@@ -191,7 +194,8 @@ control_dispatch_msg(struct pollfd *pfd,
|
||||
{
|
||||
struct imsg imsg;
|
||||
struct ctl_conn *c;
|
||||
- int n;
|
||||
+ ssize_t n;
|
||||
+ int verbose;
|
||||
struct peer *p;
|
||||
struct ctl_neighbor *neighbor;
|
||||
struct ctl_show_rib_request *ribreq;
|
||||
@@ -305,7 +309,8 @@ control_dispatch_msg(struct pollfd *pfd,
|
||||
break;
|
||||
case IMSG_CTL_FIB_COUPLE:
|
||||
case IMSG_CTL_FIB_DECOUPLE:
|
||||
- imsg_compose_parent(imsg.hdr.type, 0, NULL, 0);
|
||||
+ imsg_compose_parent(imsg.hdr.type, imsg.hdr.peerid,
|
||||
+ 0, NULL, 0);
|
||||
break;
|
||||
case IMSG_CTL_NEIGHBOR_UP:
|
||||
case IMSG_CTL_NEIGHBOR_DOWN:
|
||||
@@ -328,13 +333,19 @@ control_dispatch_msg(struct pollfd *pfd,
|
||||
control_result(c, CTL_RES_OK);
|
||||
break;
|
||||
case IMSG_CTL_NEIGHBOR_DOWN:
|
||||
- bgp_fsm(p, EVNT_STOP);
|
||||
+ session_stop(p, ERR_CEASE_ADMIN_DOWN);
|
||||
control_result(c, CTL_RES_OK);
|
||||
break;
|
||||
case IMSG_CTL_NEIGHBOR_CLEAR:
|
||||
- bgp_fsm(p, EVNT_STOP);
|
||||
- timer_set(p, Timer_IdleHold,
|
||||
- SESSION_CLEAR_DELAY);
|
||||
+ if (!p->conf.down) {
|
||||
+ session_stop(p,
|
||||
+ ERR_CEASE_ADMIN_RESET);
|
||||
+ timer_set(p, Timer_IdleHold,
|
||||
+ SESSION_CLEAR_DELAY);
|
||||
+ } else {
|
||||
+ session_stop(p,
|
||||
+ ERR_CEASE_ADMIN_DOWN);
|
||||
+ }
|
||||
control_result(c, CTL_RES_OK);
|
||||
break;
|
||||
case IMSG_CTL_NEIGHBOR_RREFRESH:
|
||||
@@ -352,13 +363,19 @@ control_dispatch_msg(struct pollfd *pfd,
|
||||
"wrong length");
|
||||
break;
|
||||
case IMSG_CTL_RELOAD:
|
||||
+ case IMSG_CTL_SHOW_INTERFACE:
|
||||
+ case IMSG_CTL_SHOW_FIB_TABLES:
|
||||
+ c->ibuf.pid = imsg.hdr.pid;
|
||||
+ imsg_compose_parent(imsg.hdr.type, 0, imsg.hdr.pid,
|
||||
+ imsg.data, imsg.hdr.len - IMSG_HEADER_SIZE);
|
||||
+ break;
|
||||
case IMSG_CTL_KROUTE:
|
||||
case IMSG_CTL_KROUTE_ADDR:
|
||||
case IMSG_CTL_SHOW_NEXTHOP:
|
||||
- case IMSG_CTL_SHOW_INTERFACE:
|
||||
c->ibuf.pid = imsg.hdr.pid;
|
||||
- imsg_compose_parent(imsg.hdr.type, imsg.hdr.pid,
|
||||
- imsg.data, imsg.hdr.len - IMSG_HEADER_SIZE);
|
||||
+ imsg_compose_parent(imsg.hdr.type, imsg.hdr.peerid,
|
||||
+ imsg.hdr.pid, imsg.data, imsg.hdr.len -
|
||||
+ IMSG_HEADER_SIZE);
|
||||
break;
|
||||
case IMSG_CTL_SHOW_RIB:
|
||||
case IMSG_CTL_SHOW_RIB_AS:
|
||||
@@ -370,7 +387,7 @@ control_dispatch_msg(struct pollfd *pfd,
|
||||
neighbor->descr[PEER_DESCR_LEN - 1] = 0;
|
||||
ribreq->peerid = 0;
|
||||
p = NULL;
|
||||
- if (neighbor->addr.af) {
|
||||
+ if (neighbor->addr.aid) {
|
||||
p = getpeerbyaddr(&neighbor->addr);
|
||||
if (p == NULL) {
|
||||
control_result(c,
|
||||
@@ -397,8 +414,7 @@ control_dispatch_msg(struct pollfd *pfd,
|
||||
break;
|
||||
}
|
||||
if ((imsg.hdr.type == IMSG_CTL_SHOW_RIB_PREFIX)
|
||||
- && (ribreq->prefix.af != AF_INET)
|
||||
- && (ribreq->prefix.af != AF_INET6)) {
|
||||
+ && (ribreq->prefix.aid == AID_UNSPEC)) {
|
||||
/* malformed request, must specify af */
|
||||
control_result(c, CTL_RES_PARSE_ERROR);
|
||||
break;
|
||||
@@ -418,6 +434,8 @@ control_dispatch_msg(struct pollfd *pfd,
|
||||
imsg.data, imsg.hdr.len - IMSG_HEADER_SIZE);
|
||||
break;
|
||||
case IMSG_NETWORK_ADD:
|
||||
+ case IMSG_NETWORK_ASPATH:
|
||||
+ case IMSG_NETWORK_ATTR:
|
||||
case IMSG_NETWORK_REMOVE:
|
||||
case IMSG_NETWORK_FLUSH:
|
||||
case IMSG_NETWORK_DONE:
|
||||
@@ -425,6 +443,20 @@ control_dispatch_msg(struct pollfd *pfd,
|
||||
imsg_compose_rde(imsg.hdr.type, 0,
|
||||
imsg.data, imsg.hdr.len - IMSG_HEADER_SIZE);
|
||||
break;
|
||||
+ case IMSG_CTL_LOG_VERBOSE:
|
||||
+ if (imsg.hdr.len != IMSG_HEADER_SIZE +
|
||||
+ sizeof(verbose))
|
||||
+ break;
|
||||
+
|
||||
+ /* forward to other processes */
|
||||
+ imsg_compose_parent(imsg.hdr.type, 0, imsg.hdr.pid,
|
||||
+ imsg.data, imsg.hdr.len - IMSG_HEADER_SIZE);
|
||||
+ imsg_compose_rde(imsg.hdr.type, 0,
|
||||
+ imsg.data, imsg.hdr.len - IMSG_HEADER_SIZE);
|
||||
+
|
||||
+ memcpy(&verbose, imsg.data, sizeof(verbose));
|
||||
+ log_verbose(verbose);
|
||||
+ break;
|
||||
default:
|
||||
break;
|
||||
}
|
275
net/openbgpd/files/patch-bgpd_imsg.c
Normal file
275
net/openbgpd/files/patch-bgpd_imsg.c
Normal file
@ -0,0 +1,275 @@
|
||||
Index: bgpd/imsg.c
|
||||
===================================================================
|
||||
RCS file: bgpd/imsg.c
|
||||
diff -N bgpd/imsg.c
|
||||
--- bgpd/imsg.c 14 Feb 2010 20:19:57 -0000 1.1.1.6
|
||||
+++ /dev/null 1 Jan 1970 00:00:00 -0000
|
||||
@@ -1,268 +0,0 @@
|
||||
-/* $OpenBSD: imsg.c,v 1.47 2009/06/08 08:30:06 dlg Exp $ */
|
||||
-
|
||||
-/*
|
||||
- * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
|
||||
- *
|
||||
- * Permission to use, copy, modify, and distribute this software for any
|
||||
- * purpose with or without fee is hereby granted, provided that the above
|
||||
- * copyright notice and this permission notice appear in all copies.
|
||||
- *
|
||||
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
- */
|
||||
-
|
||||
-#include <sys/param.h>
|
||||
-#include <sys/queue.h>
|
||||
-#include <sys/socket.h>
|
||||
-#include <sys/uio.h>
|
||||
-
|
||||
-#include <errno.h>
|
||||
-#include <stdlib.h>
|
||||
-#include <string.h>
|
||||
-#include <unistd.h>
|
||||
-
|
||||
-#include "imsg.h"
|
||||
-
|
||||
-int imsg_get_fd(struct imsgbuf *);
|
||||
-
|
||||
-void
|
||||
-imsg_init(struct imsgbuf *ibuf, int fd)
|
||||
-{
|
||||
- msgbuf_init(&ibuf->w);
|
||||
- bzero(&ibuf->r, sizeof(ibuf->r));
|
||||
- ibuf->fd = fd;
|
||||
- ibuf->w.fd = fd;
|
||||
- ibuf->pid = getpid();
|
||||
- TAILQ_INIT(&ibuf->fds);
|
||||
-}
|
||||
-
|
||||
-ssize_t
|
||||
-imsg_read(struct imsgbuf *ibuf)
|
||||
-{
|
||||
- struct msghdr msg;
|
||||
- struct cmsghdr *cmsg;
|
||||
- union {
|
||||
- struct cmsghdr hdr;
|
||||
- char buf[CMSG_SPACE(sizeof(int) * 16)];
|
||||
- } cmsgbuf;
|
||||
- struct iovec iov;
|
||||
- ssize_t n;
|
||||
- int fd;
|
||||
- struct imsg_fd *ifd;
|
||||
-
|
||||
- bzero(&msg, sizeof(msg));
|
||||
-
|
||||
- iov.iov_base = ibuf->r.buf + ibuf->r.wpos;
|
||||
- iov.iov_len = sizeof(ibuf->r.buf) - ibuf->r.wpos;
|
||||
- msg.msg_iov = &iov;
|
||||
- msg.msg_iovlen = 1;
|
||||
- msg.msg_control = &cmsgbuf.buf;
|
||||
- msg.msg_controllen = sizeof(cmsgbuf.buf);
|
||||
-
|
||||
- if ((n = recvmsg(ibuf->fd, &msg, 0)) == -1) {
|
||||
- if (errno != EINTR && errno != EAGAIN) {
|
||||
- return (-1);
|
||||
- }
|
||||
- return (-2);
|
||||
- }
|
||||
-
|
||||
- ibuf->r.wpos += n;
|
||||
-
|
||||
- for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
|
||||
- cmsg = CMSG_NXTHDR(&msg, cmsg)) {
|
||||
- if (cmsg->cmsg_level == SOL_SOCKET &&
|
||||
- cmsg->cmsg_type == SCM_RIGHTS) {
|
||||
- fd = (*(int *)CMSG_DATA(cmsg));
|
||||
- if ((ifd = calloc(1, sizeof(struct imsg_fd))) == NULL) {
|
||||
- /* XXX: this return can leak */
|
||||
- return (-1);
|
||||
- }
|
||||
- ifd->fd = fd;
|
||||
- TAILQ_INSERT_TAIL(&ibuf->fds, ifd, entry);
|
||||
- }
|
||||
- /* we do not handle other ctl data level */
|
||||
- }
|
||||
-
|
||||
- return (n);
|
||||
-}
|
||||
-
|
||||
-ssize_t
|
||||
-imsg_get(struct imsgbuf *ibuf, struct imsg *imsg)
|
||||
-{
|
||||
- size_t av, left, datalen;
|
||||
-
|
||||
- av = ibuf->r.wpos;
|
||||
-
|
||||
- if (IMSG_HEADER_SIZE > av)
|
||||
- return (0);
|
||||
-
|
||||
- memcpy(&imsg->hdr, ibuf->r.buf, sizeof(imsg->hdr));
|
||||
- if (imsg->hdr.len < IMSG_HEADER_SIZE ||
|
||||
- imsg->hdr.len > MAX_IMSGSIZE) {
|
||||
- errno = ERANGE;
|
||||
- return (-1);
|
||||
- }
|
||||
- if (imsg->hdr.len > av)
|
||||
- return (0);
|
||||
- datalen = imsg->hdr.len - IMSG_HEADER_SIZE;
|
||||
- ibuf->r.rptr = ibuf->r.buf + IMSG_HEADER_SIZE;
|
||||
- if ((imsg->data = malloc(datalen)) == NULL)
|
||||
- return (-1);
|
||||
-
|
||||
- if (imsg->hdr.flags & IMSGF_HASFD)
|
||||
- imsg->fd = imsg_get_fd(ibuf);
|
||||
- else
|
||||
- imsg->fd = -1;
|
||||
-
|
||||
- memcpy(imsg->data, ibuf->r.rptr, datalen);
|
||||
-
|
||||
- if (imsg->hdr.len < av) {
|
||||
- left = av - imsg->hdr.len;
|
||||
- memmove(&ibuf->r.buf, ibuf->r.buf + imsg->hdr.len, left);
|
||||
- ibuf->r.wpos = left;
|
||||
- } else
|
||||
- ibuf->r.wpos = 0;
|
||||
-
|
||||
- return (datalen + IMSG_HEADER_SIZE);
|
||||
-}
|
||||
-
|
||||
-int
|
||||
-imsg_compose(struct imsgbuf *ibuf, u_int32_t type, u_int32_t peerid,
|
||||
- pid_t pid, int fd, void *data, u_int16_t datalen)
|
||||
-{
|
||||
- struct buf *wbuf;
|
||||
-
|
||||
- if ((wbuf = imsg_create(ibuf, type, peerid, pid, datalen)) == NULL)
|
||||
- return (-1);
|
||||
-
|
||||
- if (imsg_add(wbuf, data, datalen) == -1)
|
||||
- return (-1);
|
||||
-
|
||||
- wbuf->fd = fd;
|
||||
-
|
||||
- imsg_close(ibuf, wbuf);
|
||||
-
|
||||
- return (1);
|
||||
-}
|
||||
-
|
||||
-int
|
||||
-imsg_composev(struct imsgbuf *ibuf, u_int32_t type, u_int32_t peerid,
|
||||
- pid_t pid, int fd, const struct iovec *iov, int iovcnt)
|
||||
-{
|
||||
- struct buf *wbuf;
|
||||
- int i, datalen = 0;
|
||||
-
|
||||
- for (i = 0; i < iovcnt; i++)
|
||||
- datalen += iov[i].iov_len;
|
||||
-
|
||||
- if ((wbuf = imsg_create(ibuf, type, peerid, pid, datalen)) == NULL)
|
||||
- return (-1);
|
||||
-
|
||||
- for (i = 0; i < iovcnt; i++)
|
||||
- if (imsg_add(wbuf, iov[i].iov_base, iov[i].iov_len) == -1)
|
||||
- return (-1);
|
||||
-
|
||||
- wbuf->fd = fd;
|
||||
-
|
||||
- imsg_close(ibuf, wbuf);
|
||||
-
|
||||
- return (1);
|
||||
-}
|
||||
-
|
||||
-/* ARGSUSED */
|
||||
-struct buf *
|
||||
-imsg_create(struct imsgbuf *ibuf, u_int32_t type, u_int32_t peerid,
|
||||
- pid_t pid, u_int16_t datalen)
|
||||
-{
|
||||
- struct buf *wbuf;
|
||||
- struct imsg_hdr hdr;
|
||||
-
|
||||
- datalen += IMSG_HEADER_SIZE;
|
||||
- if (datalen > MAX_IMSGSIZE) {
|
||||
- errno = ERANGE;
|
||||
- return (NULL);
|
||||
- }
|
||||
-
|
||||
- hdr.type = type;
|
||||
- hdr.flags = 0;
|
||||
- hdr.peerid = peerid;
|
||||
- if ((hdr.pid = pid) == 0)
|
||||
- hdr.pid = ibuf->pid;
|
||||
- if ((wbuf = buf_dynamic(datalen, MAX_IMSGSIZE)) == NULL) {
|
||||
- return (NULL);
|
||||
- }
|
||||
- if (imsg_add(wbuf, &hdr, sizeof(hdr)) == -1)
|
||||
- return (NULL);
|
||||
-
|
||||
- return (wbuf);
|
||||
-}
|
||||
-
|
||||
-int
|
||||
-imsg_add(struct buf *msg, void *data, u_int16_t datalen)
|
||||
-{
|
||||
- if (datalen)
|
||||
- if (buf_add(msg, data, datalen) == -1) {
|
||||
- buf_free(msg);
|
||||
- return (-1);
|
||||
- }
|
||||
- return (datalen);
|
||||
-}
|
||||
-
|
||||
-void
|
||||
-imsg_close(struct imsgbuf *ibuf, struct buf *msg)
|
||||
-{
|
||||
- struct imsg_hdr *hdr;
|
||||
-
|
||||
- hdr = (struct imsg_hdr *)msg->buf;
|
||||
-
|
||||
- hdr->flags &= ~IMSGF_HASFD;
|
||||
- if (msg->fd != -1)
|
||||
- hdr->flags |= IMSGF_HASFD;
|
||||
-
|
||||
- hdr->len = (u_int16_t)msg->wpos;
|
||||
-
|
||||
- buf_close(&ibuf->w, msg);
|
||||
-}
|
||||
-
|
||||
-void
|
||||
-imsg_free(struct imsg *imsg)
|
||||
-{
|
||||
- free(imsg->data);
|
||||
-}
|
||||
-
|
||||
-int
|
||||
-imsg_get_fd(struct imsgbuf *ibuf)
|
||||
-{
|
||||
- int fd;
|
||||
- struct imsg_fd *ifd;
|
||||
-
|
||||
- if ((ifd = TAILQ_FIRST(&ibuf->fds)) == NULL)
|
||||
- return (-1);
|
||||
-
|
||||
- fd = ifd->fd;
|
||||
- TAILQ_REMOVE(&ibuf->fds, ifd, entry);
|
||||
- free(ifd);
|
||||
-
|
||||
- return (fd);
|
||||
-}
|
||||
-
|
||||
-int
|
||||
-imsg_flush(struct imsgbuf *ibuf)
|
||||
-{
|
||||
- while (ibuf->w.queued)
|
||||
- if (msgbuf_write(&ibuf->w) < 0)
|
||||
- return (-1);
|
||||
- return (0);
|
||||
-}
|
||||
-
|
||||
-void
|
||||
-imsg_clear(struct imsgbuf *ibuf)
|
||||
-{
|
||||
- while (ibuf->w.queued)
|
||||
- msgbuf_clear(&ibuf->w);
|
||||
-}
|
115
net/openbgpd/files/patch-bgpd_imsg.h
Normal file
115
net/openbgpd/files/patch-bgpd_imsg.h
Normal file
@ -0,0 +1,115 @@
|
||||
Index: bgpd/imsg.h
|
||||
===================================================================
|
||||
RCS file: bgpd/imsg.h
|
||||
diff -N bgpd/imsg.h
|
||||
--- bgpd/imsg.h 14 Feb 2010 20:19:57 -0000 1.1.1.5
|
||||
+++ /dev/null 1 Jan 1970 00:00:00 -0000
|
||||
@@ -1,108 +0,0 @@
|
||||
-/* $OpenBSD: imsg.h,v 1.3 2009/06/07 05:56:24 eric Exp $ */
|
||||
-
|
||||
-/*
|
||||
- * Copyright (c) 2006, 2007 Pierre-Yves Ritschard <pyr@openbsd.org>
|
||||
- * Copyright (c) 2006, 2007, 2008 Reyk Floeter <reyk@openbsd.org>
|
||||
- * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
|
||||
- *
|
||||
- * Permission to use, copy, modify, and distribute this software for any
|
||||
- * purpose with or without fee is hereby granted, provided that the above
|
||||
- * copyright notice and this permission notice appear in all copies.
|
||||
- *
|
||||
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
- */
|
||||
-
|
||||
-#include <sys/tree.h>
|
||||
-
|
||||
-#define READ_BUF_SIZE 65535
|
||||
-#define IMSG_HEADER_SIZE sizeof(struct imsg_hdr)
|
||||
-#define MAX_IMSGSIZE 16384
|
||||
-
|
||||
-struct buf {
|
||||
- TAILQ_ENTRY(buf) entry;
|
||||
- u_char *buf;
|
||||
- size_t size;
|
||||
- size_t max;
|
||||
- size_t wpos;
|
||||
- size_t rpos;
|
||||
- int fd;
|
||||
-};
|
||||
-
|
||||
-struct msgbuf {
|
||||
- TAILQ_HEAD(, buf) bufs;
|
||||
- u_int32_t queued;
|
||||
- int fd;
|
||||
-};
|
||||
-
|
||||
-struct buf_read {
|
||||
- u_char buf[READ_BUF_SIZE];
|
||||
- u_char *rptr;
|
||||
- size_t wpos;
|
||||
-};
|
||||
-
|
||||
-struct imsg_fd {
|
||||
- TAILQ_ENTRY(imsg_fd) entry;
|
||||
- int fd;
|
||||
-};
|
||||
-
|
||||
-struct imsgbuf {
|
||||
- TAILQ_HEAD(, imsg_fd) fds;
|
||||
- struct buf_read r;
|
||||
- struct msgbuf w;
|
||||
- int fd;
|
||||
- pid_t pid;
|
||||
-};
|
||||
-
|
||||
-#define IMSGF_HASFD 1
|
||||
-
|
||||
-struct imsg_hdr {
|
||||
- u_int32_t type;
|
||||
- u_int16_t len;
|
||||
- u_int16_t flags;
|
||||
- u_int32_t peerid;
|
||||
- u_int32_t pid;
|
||||
-};
|
||||
-
|
||||
-struct imsg {
|
||||
- struct imsg_hdr hdr;
|
||||
- int fd;
|
||||
- void *data;
|
||||
-};
|
||||
-
|
||||
-
|
||||
-/* buffer.c */
|
||||
-struct buf *buf_open(size_t);
|
||||
-struct buf *buf_dynamic(size_t, size_t);
|
||||
-int buf_add(struct buf *, const void *, size_t);
|
||||
-void *buf_reserve(struct buf *, size_t);
|
||||
-void *buf_seek(struct buf *, size_t, size_t);
|
||||
-size_t buf_size(struct buf *);
|
||||
-size_t buf_left(struct buf *);
|
||||
-void buf_close(struct msgbuf *, struct buf *);
|
||||
-int buf_write(struct msgbuf *);
|
||||
-void buf_free(struct buf *);
|
||||
-void msgbuf_init(struct msgbuf *);
|
||||
-void msgbuf_clear(struct msgbuf *);
|
||||
-int msgbuf_write(struct msgbuf *);
|
||||
-
|
||||
-/* imsg.c */
|
||||
-void imsg_init(struct imsgbuf *, int);
|
||||
-ssize_t imsg_read(struct imsgbuf *);
|
||||
-ssize_t imsg_get(struct imsgbuf *, struct imsg *);
|
||||
-int imsg_compose(struct imsgbuf *, u_int32_t, u_int32_t, pid_t,
|
||||
- int, void *, u_int16_t);
|
||||
-int imsg_composev(struct imsgbuf *, u_int32_t, u_int32_t, pid_t,
|
||||
- int, const struct iovec *, int);
|
||||
-struct buf *imsg_create(struct imsgbuf *, u_int32_t, u_int32_t, pid_t,
|
||||
- u_int16_t);
|
||||
-int imsg_add(struct buf *, void *, u_int16_t);
|
||||
-void imsg_close(struct imsgbuf *, struct buf *);
|
||||
-void imsg_free(struct imsg *);
|
||||
-int imsg_flush(struct imsgbuf *);
|
||||
-void imsg_clear(struct imsgbuf *);
|
3140
net/openbgpd/files/patch-bgpd_kroute.c
Normal file
3140
net/openbgpd/files/patch-bgpd_kroute.c
Normal file
File diff suppressed because it is too large
Load Diff
117
net/openbgpd/files/patch-bgpd_log.c
Normal file
117
net/openbgpd/files/patch-bgpd_log.c
Normal file
@ -0,0 +1,117 @@
|
||||
Index: bgpd/log.c
|
||||
===================================================================
|
||||
RCS file: /home/cvs/private/hrs/openbgpd/bgpd/log.c,v
|
||||
retrieving revision 1.1.1.5
|
||||
retrieving revision 1.1.1.8
|
||||
diff -u -p -r1.1.1.5 -r1.1.1.8
|
||||
--- bgpd/log.c 14 Feb 2010 20:19:57 -0000 1.1.1.5
|
||||
+++ bgpd/log.c 13 Oct 2012 18:22:43 -0000 1.1.1.8
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* $OpenBSD: log.c,v 1.50 2007/04/23 13:04:24 claudio Exp $ */
|
||||
+/* $OpenBSD: log.c,v 1.55 2011/08/20 19:02:28 sthen Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "log.h"
|
||||
|
||||
int debug;
|
||||
+int verbose;
|
||||
|
||||
void logit(int, const char *, ...);
|
||||
|
||||
@@ -42,8 +43,9 @@ log_fmt_peer(const struct peer_config *p
|
||||
char *pfmt, *p;
|
||||
|
||||
ip = log_addr(&peer->remote_addr);
|
||||
- if ((peer->remote_addr.af == AF_INET && peer->remote_masklen != 32) ||
|
||||
- (peer->remote_addr.af == AF_INET6 && peer->remote_masklen != 128)) {
|
||||
+ if ((peer->remote_addr.aid == AID_INET && peer->remote_masklen != 32) ||
|
||||
+ (peer->remote_addr.aid == AID_INET6 &&
|
||||
+ peer->remote_masklen != 128)) {
|
||||
if (asprintf(&p, "%s/%u", ip, peer->remote_masklen) == -1)
|
||||
fatal(NULL);
|
||||
} else {
|
||||
@@ -77,6 +79,12 @@ log_init(int n_debug)
|
||||
}
|
||||
|
||||
void
|
||||
+log_verbose(int v)
|
||||
+{
|
||||
+ verbose = v;
|
||||
+}
|
||||
+
|
||||
+void
|
||||
logit(int pri, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
@@ -193,7 +201,7 @@ log_debug(const char *emsg, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
- if (debug) {
|
||||
+ if (verbose) {
|
||||
va_start(ap, emsg);
|
||||
vlog(LOG_DEBUG, emsg, ap);
|
||||
va_end(ap);
|
||||
@@ -250,7 +258,7 @@ log_statechange(struct peer *peer, enum
|
||||
|
||||
void
|
||||
log_notification(const struct peer *peer, u_int8_t errcode, u_int8_t subcode,
|
||||
- u_char *data, u_int16_t datalen)
|
||||
+ u_char *data, u_int16_t datalen, const char *dir)
|
||||
{
|
||||
char *p;
|
||||
const char *suberrname = NULL;
|
||||
@@ -283,27 +291,31 @@ log_notification(const struct peer *peer
|
||||
suberrname = suberr_cease_names[subcode];
|
||||
break;
|
||||
case ERR_HOLDTIMEREXPIRED:
|
||||
- case ERR_FSM:
|
||||
uk = 1;
|
||||
break;
|
||||
+ case ERR_FSM:
|
||||
+ if (subcode >= sizeof(suberr_fsm_names)/sizeof(char *))
|
||||
+ uk = 1;
|
||||
+ else
|
||||
+ suberrname = suberr_fsm_names[subcode];
|
||||
+ break;
|
||||
default:
|
||||
- logit(LOG_CRIT, "%s: received notification, unknown errcode "
|
||||
- "%u, subcode %u", p, errcode, subcode);
|
||||
+ logit(LOG_CRIT, "%s: %s notification, unknown errcode "
|
||||
+ "%u, subcode %u", p, dir, errcode, subcode);
|
||||
free(p);
|
||||
return;
|
||||
}
|
||||
|
||||
if (uk)
|
||||
- logit(LOG_CRIT,
|
||||
- "%s: received notification: %s, unknown subcode %u",
|
||||
- p, errnames[errcode], subcode);
|
||||
+ logit(LOG_CRIT, "%s: %s notification: %s, unknown subcode %u",
|
||||
+ p, dir, errnames[errcode], subcode);
|
||||
else {
|
||||
if (suberrname == NULL)
|
||||
- logit(LOG_CRIT, "%s: received notification: %s",
|
||||
- p, errnames[errcode]);
|
||||
+ logit(LOG_CRIT, "%s: %s notification: %s", p,
|
||||
+ dir, errnames[errcode]);
|
||||
else
|
||||
- logit(LOG_CRIT, "%s: received notification: %s, %s",
|
||||
- p, errnames[errcode], suberrname);
|
||||
+ logit(LOG_CRIT, "%s: %s notification: %s, %s",
|
||||
+ p, dir, errnames[errcode], suberrname);
|
||||
}
|
||||
free(p);
|
||||
}
|
||||
@@ -318,6 +330,9 @@ log_conn_attempt(const struct peer *peer
|
||||
b = log_sockaddr(sa);
|
||||
logit(LOG_INFO, "connection from non-peer %s refused", b);
|
||||
} else {
|
||||
+ /* only log if there is a chance that the session may come up */
|
||||
+ if (peer->conf.down && peer->state == STATE_IDLE)
|
||||
+ return;
|
||||
p = log_fmt_peer(&peer->conf);
|
||||
logit(LOG_INFO, "Connection attempt from %s while session is "
|
||||
"in state %s", p, statenames[peer->state]);
|
39
net/openbgpd/files/patch-bgpd_log.h
Normal file
39
net/openbgpd/files/patch-bgpd_log.h
Normal file
@ -0,0 +1,39 @@
|
||||
Index: bgpd/log.h
|
||||
===================================================================
|
||||
RCS file: /home/cvs/private/hrs/openbgpd/bgpd/log.h,v
|
||||
retrieving revision 1.1.1.2
|
||||
retrieving revision 1.1.1.3
|
||||
diff -u -p -r1.1.1.2 -r1.1.1.3
|
||||
--- bgpd/log.h 9 Jul 2009 16:49:54 -0000 1.1.1.2
|
||||
+++ bgpd/log.h 13 Oct 2012 18:22:43 -0000 1.1.1.3
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* $OpenBSD: log.h,v 1.11 2008/09/11 14:49:58 henning Exp $ */
|
||||
+/* $OpenBSD: log.h,v 1.13 2012/06/10 11:16:08 claudio Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
|
||||
@@ -71,6 +71,13 @@ static const char * const suberr_open_na
|
||||
"unsupported capability"
|
||||
};
|
||||
|
||||
+static const char * const suberr_fsm_names[] = {
|
||||
+ "unspecified error",
|
||||
+ "received unexpected message in OpenSent",
|
||||
+ "received unexpected message in OpenConfirm",
|
||||
+ "received unexpected message in Established"
|
||||
+};
|
||||
+
|
||||
static const char * const suberr_update_names[] = {
|
||||
"none",
|
||||
"attribute list error",
|
||||
@@ -109,7 +116,9 @@ static const char * const ctl_res_strerr
|
||||
"no such neighbor",
|
||||
"permission denied",
|
||||
"neighbor does not have this capability",
|
||||
- "config file has errors, reload failed"
|
||||
+ "config file has errors, reload failed",
|
||||
+ "previous reload still running",
|
||||
+ "out of memory"
|
||||
};
|
||||
|
||||
static const char * const timernames[] = {
|
864
net/openbgpd/files/patch-bgpd_mrt.c
Normal file
864
net/openbgpd/files/patch-bgpd_mrt.c
Normal file
@ -0,0 +1,864 @@
|
||||
Index: bgpd/mrt.c
|
||||
===================================================================
|
||||
RCS file: /home/cvs/private/hrs/openbgpd/bgpd/mrt.c,v
|
||||
retrieving revision 1.1.1.7
|
||||
retrieving revision 1.1.1.11
|
||||
diff -u -p -r1.1.1.7 -r1.1.1.11
|
||||
--- bgpd/mrt.c 14 Feb 2010 20:19:57 -0000 1.1.1.7
|
||||
+++ bgpd/mrt.c 8 Dec 2012 10:37:09 -0000 1.1.1.11
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* $OpenBSD: mrt.c,v 1.63 2009/06/29 12:22:16 claudio Exp $ */
|
||||
+/* $OpenBSD: mrt.c,v 1.72 2011/11/06 10:29:05 guenther Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org>
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
+#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
@@ -32,20 +33,22 @@
|
||||
|
||||
#include "mrt.h"
|
||||
|
||||
-int mrt_attr_dump(struct buf *, struct rde_aspath *, struct bgpd_addr *);
|
||||
+int mrt_attr_dump(struct ibuf *, struct rde_aspath *, struct bgpd_addr *, int);
|
||||
int mrt_dump_entry_mp(struct mrt *, struct prefix *, u_int16_t,
|
||||
struct rde_peer*);
|
||||
int mrt_dump_entry(struct mrt *, struct prefix *, u_int16_t, struct rde_peer*);
|
||||
-int mrt_dump_hdr_se(struct buf **, struct peer *, u_int16_t, u_int16_t,
|
||||
+int mrt_dump_entry_v2(struct mrt *, struct rib_entry *, u_int32_t);
|
||||
+int mrt_dump_peer(struct ibuf *, struct rde_peer *);
|
||||
+int mrt_dump_hdr_se(struct ibuf **, struct peer *, u_int16_t, u_int16_t,
|
||||
u_int32_t, int);
|
||||
-int mrt_dump_hdr_rde(struct buf **, u_int16_t type, u_int16_t, u_int32_t);
|
||||
+int mrt_dump_hdr_rde(struct ibuf **, u_int16_t type, u_int16_t, u_int32_t);
|
||||
int mrt_open(struct mrt *, time_t);
|
||||
|
||||
#define DUMP_BYTE(x, b) \
|
||||
do { \
|
||||
u_char t = (b); \
|
||||
- if (buf_add((x), &t, sizeof(t)) == -1) { \
|
||||
- log_warnx("mrt_dump1: buf_add error"); \
|
||||
+ if (ibuf_add((x), &t, sizeof(t)) == -1) { \
|
||||
+ log_warn("mrt_dump1: ibuf_add error"); \
|
||||
goto fail; \
|
||||
} \
|
||||
} while (0)
|
||||
@@ -54,8 +57,8 @@ int mrt_open(struct mrt *, time_t);
|
||||
do { \
|
||||
u_int16_t t; \
|
||||
t = htons((s)); \
|
||||
- if (buf_add((x), &t, sizeof(t)) == -1) { \
|
||||
- log_warnx("mrt_dump2: buf_add error"); \
|
||||
+ if (ibuf_add((x), &t, sizeof(t)) == -1) { \
|
||||
+ log_warn("mrt_dump2: ibuf_add error"); \
|
||||
goto fail; \
|
||||
} \
|
||||
} while (0)
|
||||
@@ -64,8 +67,8 @@ int mrt_open(struct mrt *, time_t);
|
||||
do { \
|
||||
u_int32_t t; \
|
||||
t = htonl((l)); \
|
||||
- if (buf_add((x), &t, sizeof(t)) == -1) { \
|
||||
- log_warnx("mrt_dump3: buf_add error"); \
|
||||
+ if (ibuf_add((x), &t, sizeof(t)) == -1) { \
|
||||
+ log_warn("mrt_dump3: ibuf_add error"); \
|
||||
goto fail; \
|
||||
} \
|
||||
} while (0)
|
||||
@@ -73,8 +76,8 @@ int mrt_open(struct mrt *, time_t);
|
||||
#define DUMP_NLONG(x, l) \
|
||||
do { \
|
||||
u_int32_t t = (l); \
|
||||
- if (buf_add((x), &t, sizeof(t)) == -1) { \
|
||||
- log_warnx("mrt_dump4: buf_add error"); \
|
||||
+ if (ibuf_add((x), &t, sizeof(t)) == -1) { \
|
||||
+ log_warn("mrt_dump4: ibuf_add error"); \
|
||||
goto fail; \
|
||||
} \
|
||||
} while (0)
|
||||
@@ -83,55 +86,64 @@ void
|
||||
mrt_dump_bgp_msg(struct mrt *mrt, void *pkg, u_int16_t pkglen,
|
||||
struct peer *peer)
|
||||
{
|
||||
- struct buf *buf;
|
||||
+ struct ibuf *buf;
|
||||
int incoming = 0;
|
||||
+ u_int16_t subtype = BGP4MP_MESSAGE;
|
||||
+
|
||||
+ if (peer->capa.neg.as4byte)
|
||||
+ subtype = BGP4MP_MESSAGE_AS4;
|
||||
|
||||
/* get the direction of the message to swap address and AS fields */
|
||||
if (mrt->type == MRT_ALL_IN || mrt->type == MRT_UPDATE_IN)
|
||||
incoming = 1;
|
||||
|
||||
- if (mrt_dump_hdr_se(&buf, peer, MSG_PROTOCOL_BGP4MP, BGP4MP_MESSAGE,
|
||||
+ if (mrt_dump_hdr_se(&buf, peer, MSG_PROTOCOL_BGP4MP, subtype,
|
||||
pkglen, incoming) == -1)
|
||||
return;
|
||||
|
||||
- if (buf_add(buf, pkg, pkglen) == -1) {
|
||||
- log_warnx("mrt_dump_bgp_msg: buf_add error");
|
||||
- buf_free(buf);
|
||||
+ if (ibuf_add(buf, pkg, pkglen) == -1) {
|
||||
+ log_warn("mrt_dump_bgp_msg: ibuf_add error");
|
||||
+ ibuf_free(buf);
|
||||
return;
|
||||
}
|
||||
|
||||
- buf_close(&mrt->wbuf, buf);
|
||||
+ ibuf_close(&mrt->wbuf, buf);
|
||||
}
|
||||
|
||||
void
|
||||
mrt_dump_state(struct mrt *mrt, u_int16_t old_state, u_int16_t new_state,
|
||||
struct peer *peer)
|
||||
{
|
||||
- struct buf *buf;
|
||||
+ struct ibuf *buf;
|
||||
+ u_int16_t subtype = BGP4MP_STATE_CHANGE;
|
||||
+
|
||||
+ if (peer->capa.neg.as4byte)
|
||||
+ subtype = BGP4MP_STATE_CHANGE_AS4;
|
||||
|
||||
- if (mrt_dump_hdr_se(&buf, peer, MSG_PROTOCOL_BGP4MP, BGP4MP_MESSAGE,
|
||||
+ if (mrt_dump_hdr_se(&buf, peer, MSG_PROTOCOL_BGP4MP, subtype,
|
||||
2 * sizeof(short), 0) == -1)
|
||||
return;
|
||||
|
||||
DUMP_SHORT(buf, old_state);
|
||||
DUMP_SHORT(buf, new_state);
|
||||
|
||||
- buf_close(&mrt->wbuf, buf);
|
||||
+ ibuf_close(&mrt->wbuf, buf);
|
||||
return;
|
||||
|
||||
fail:
|
||||
- buf_free(buf);
|
||||
+ ibuf_free(buf);
|
||||
}
|
||||
|
||||
int
|
||||
-mrt_attr_dump(struct buf *buf, struct rde_aspath *a, struct bgpd_addr *nexthop)
|
||||
+mrt_attr_dump(struct ibuf *buf, struct rde_aspath *a, struct bgpd_addr *nexthop,
|
||||
+ int v2)
|
||||
{
|
||||
struct attr *oa;
|
||||
u_char *pdata;
|
||||
u_int32_t tmp;
|
||||
int neednewpath = 0;
|
||||
- u_int16_t plen;
|
||||
- u_int8_t l;
|
||||
+ u_int16_t plen, afi;
|
||||
+ u_int8_t l, safi;
|
||||
|
||||
/* origin */
|
||||
if (attr_writebuf(buf, ATTR_WELL_KNOWN, ATTR_ORIGIN,
|
||||
@@ -140,12 +152,16 @@ mrt_attr_dump(struct buf *buf, struct rd
|
||||
|
||||
/* aspath */
|
||||
pdata = aspath_prepend(a->aspath, rde_local_as(), 0, &plen);
|
||||
- pdata = aspath_deflate(pdata, &plen, &neednewpath);
|
||||
- if (attr_writebuf(buf, ATTR_WELL_KNOWN, ATTR_ASPATH, pdata, plen) == -1)
|
||||
+ if (!v2)
|
||||
+ pdata = aspath_deflate(pdata, &plen, &neednewpath);
|
||||
+ if (attr_writebuf(buf, ATTR_WELL_KNOWN, ATTR_ASPATH, pdata,
|
||||
+ plen) == -1) {
|
||||
+ free(pdata);
|
||||
return (-1);
|
||||
+ }
|
||||
free(pdata);
|
||||
|
||||
- if (nexthop) {
|
||||
+ if (nexthop && nexthop->aid == AID_INET) {
|
||||
/* nexthop, already network byte order */
|
||||
if (attr_writebuf(buf, ATTR_WELL_KNOWN, ATTR_NEXTHOP,
|
||||
&nexthop->v4.s_addr, 4) == -1)
|
||||
@@ -159,7 +175,7 @@ mrt_attr_dump(struct buf *buf, struct rd
|
||||
return (-1);
|
||||
}
|
||||
|
||||
- /* local preference, only valid for ibgp */
|
||||
+ /* local preference */
|
||||
tmp = htonl(a->lpref);
|
||||
if (attr_writebuf(buf, ATTR_WELL_KNOWN, ATTR_LOCALPREF, &tmp, 4) == -1)
|
||||
return (-1);
|
||||
@@ -173,12 +189,51 @@ mrt_attr_dump(struct buf *buf, struct rd
|
||||
return (-1);
|
||||
}
|
||||
|
||||
+ if (nexthop && nexthop->aid != AID_INET) {
|
||||
+ struct ibuf *nhbuf;
|
||||
+
|
||||
+ if ((nhbuf = ibuf_dynamic(0, UCHAR_MAX)) == NULL)
|
||||
+ return (-1);
|
||||
+ if (!v2) {
|
||||
+ if (aid2afi(nexthop->aid, &afi, &safi))
|
||||
+ return (-1);
|
||||
+ DUMP_SHORT(nhbuf, afi);
|
||||
+ DUMP_BYTE(nhbuf, safi);
|
||||
+ }
|
||||
+ switch (nexthop->aid) {
|
||||
+ case AID_INET6:
|
||||
+ DUMP_BYTE(nhbuf, sizeof(struct in6_addr));
|
||||
+ if (ibuf_add(nhbuf, &nexthop->v6,
|
||||
+ sizeof(struct in6_addr)) == -1) {
|
||||
+ }
|
||||
+ break;
|
||||
+ case AID_VPN_IPv4:
|
||||
+ DUMP_BYTE(nhbuf, sizeof(u_int64_t) +
|
||||
+ sizeof(struct in_addr));
|
||||
+ DUMP_NLONG(nhbuf, 0); /* set RD to 0 */
|
||||
+ DUMP_NLONG(nhbuf, 0);
|
||||
+ DUMP_NLONG(nhbuf, nexthop->v4.s_addr);
|
||||
+ break;
|
||||
+ }
|
||||
+ if (!v2)
|
||||
+ DUMP_BYTE(nhbuf, 0);
|
||||
+ if (attr_writebuf(buf, ATTR_OPTIONAL, ATTR_MP_REACH_NLRI,
|
||||
+ nhbuf->buf, ibuf_size(nhbuf)) == -1) {
|
||||
+fail:
|
||||
+ ibuf_free(nhbuf);
|
||||
+ return (-1);
|
||||
+ }
|
||||
+ ibuf_free(nhbuf);
|
||||
+ }
|
||||
+
|
||||
if (neednewpath) {
|
||||
pdata = aspath_prepend(a->aspath, rde_local_as(), 0, &plen);
|
||||
if (plen != 0)
|
||||
if (attr_writebuf(buf, ATTR_OPTIONAL|ATTR_TRANSITIVE,
|
||||
- ATTR_AS4_PATH, pdata, plen) == -1)
|
||||
+ ATTR_AS4_PATH, pdata, plen) == -1) {
|
||||
+ free(pdata);
|
||||
return (-1);
|
||||
+ }
|
||||
free(pdata);
|
||||
}
|
||||
|
||||
@@ -189,28 +244,26 @@ int
|
||||
mrt_dump_entry_mp(struct mrt *mrt, struct prefix *p, u_int16_t snum,
|
||||
struct rde_peer *peer)
|
||||
{
|
||||
- struct buf *buf, *hbuf = NULL, *h2buf = NULL;
|
||||
- void *bptr;
|
||||
+ struct ibuf *buf, *hbuf = NULL, *h2buf = NULL;
|
||||
struct bgpd_addr addr, nexthop, *nh;
|
||||
u_int16_t len;
|
||||
- u_int8_t p_len;
|
||||
- sa_family_t af;
|
||||
+ u_int8_t aid;
|
||||
|
||||
- if ((buf = buf_dynamic(0, MAX_PKTSIZE)) == NULL) {
|
||||
- log_warn("mrt_dump_entry_mp: buf_dynamic");
|
||||
+ if ((buf = ibuf_dynamic(0, MAX_PKTSIZE)) == NULL) {
|
||||
+ log_warn("mrt_dump_entry_mp: ibuf_dynamic");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
- if (mrt_attr_dump(buf, p->aspath, NULL) == -1) {
|
||||
+ if (mrt_attr_dump(buf, p->aspath, NULL, 0) == -1) {
|
||||
log_warnx("mrt_dump_entry_mp: mrt_attr_dump error");
|
||||
goto fail;
|
||||
}
|
||||
- len = buf_size(buf);
|
||||
+ len = ibuf_size(buf);
|
||||
|
||||
- if ((h2buf = buf_dynamic(MRT_BGP4MP_IPv4_HEADER_SIZE +
|
||||
+ if ((h2buf = ibuf_dynamic(MRT_BGP4MP_IPv4_HEADER_SIZE +
|
||||
MRT_BGP4MP_IPv4_ENTRY_SIZE, MRT_BGP4MP_IPv6_HEADER_SIZE +
|
||||
MRT_BGP4MP_IPv6_ENTRY_SIZE + MRT_BGP4MP_MAX_PREFIXLEN)) == NULL) {
|
||||
- log_warn("mrt_dump_entry_mp: buf_dynamic");
|
||||
+ log_warn("mrt_dump_entry_mp: ibuf_dynamic");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@@ -219,25 +272,26 @@ mrt_dump_entry_mp(struct mrt *mrt, struc
|
||||
DUMP_SHORT(h2buf, /* ifindex */ 0);
|
||||
|
||||
/* XXX is this for peer self? */
|
||||
- af = peer->remote_addr.af == 0 ? p->prefix->af : peer->remote_addr.af;
|
||||
- switch (af) {
|
||||
- case AF_INET:
|
||||
+ aid = peer->remote_addr.aid == AID_UNSPEC ? p->prefix->aid :
|
||||
+ peer->remote_addr.aid;
|
||||
+ switch (aid) {
|
||||
+ case AID_INET:
|
||||
DUMP_SHORT(h2buf, AFI_IPv4);
|
||||
DUMP_NLONG(h2buf, peer->local_v4_addr.v4.s_addr);
|
||||
DUMP_NLONG(h2buf, peer->remote_addr.v4.s_addr);
|
||||
break;
|
||||
- case AF_INET6:
|
||||
+ case AID_INET6:
|
||||
DUMP_SHORT(h2buf, AFI_IPv6);
|
||||
- if (buf_add(h2buf, &peer->local_v6_addr.v6,
|
||||
+ if (ibuf_add(h2buf, &peer->local_v6_addr.v6,
|
||||
sizeof(struct in6_addr)) == -1 ||
|
||||
- buf_add(h2buf, &peer->remote_addr.v6,
|
||||
+ ibuf_add(h2buf, &peer->remote_addr.v6,
|
||||
sizeof(struct in6_addr)) == -1) {
|
||||
- log_warnx("mrt_dump_entry_mp: buf_add error");
|
||||
+ log_warn("mrt_dump_entry_mp: ibuf_add error");
|
||||
goto fail;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
- log_warnx("king bula found new AF %d in mrt_dump_entry_mp", af);
|
||||
+ log_warnx("king bula found new AF in mrt_dump_entry_mp");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@@ -247,25 +301,25 @@ mrt_dump_entry_mp(struct mrt *mrt, struc
|
||||
|
||||
if (p->aspath->nexthop == NULL) {
|
||||
bzero(&nexthop, sizeof(struct bgpd_addr));
|
||||
- nexthop.af = addr.af;
|
||||
+ nexthop.aid = addr.aid;
|
||||
nh = &nexthop;
|
||||
} else
|
||||
nh = &p->aspath->nexthop->exit_nexthop;
|
||||
|
||||
pt_getaddr(p->prefix, &addr);
|
||||
- switch (addr.af) {
|
||||
- case AF_INET:
|
||||
+ switch (addr.aid) {
|
||||
+ case AID_INET:
|
||||
DUMP_SHORT(h2buf, AFI_IPv4); /* afi */
|
||||
DUMP_BYTE(h2buf, SAFI_UNICAST); /* safi */
|
||||
DUMP_BYTE(h2buf, 4); /* nhlen */
|
||||
DUMP_NLONG(h2buf, nh->v4.s_addr); /* nexthop */
|
||||
break;
|
||||
- case AF_INET6:
|
||||
+ case AID_INET6:
|
||||
DUMP_SHORT(h2buf, AFI_IPv6); /* afi */
|
||||
DUMP_BYTE(h2buf, SAFI_UNICAST); /* safi */
|
||||
DUMP_BYTE(h2buf, 16); /* nhlen */
|
||||
- if (buf_add(h2buf, &nh->v6, sizeof(struct in6_addr)) == -1) {
|
||||
- log_warnx("mrt_dump_entry_mp: buf_add error");
|
||||
+ if (ibuf_add(h2buf, &nh->v6, sizeof(struct in6_addr)) == -1) {
|
||||
+ log_warn("mrt_dump_entry_mp: ibuf_add error");
|
||||
goto fail;
|
||||
}
|
||||
break;
|
||||
@@ -274,35 +328,30 @@ mrt_dump_entry_mp(struct mrt *mrt, struc
|
||||
goto fail;
|
||||
}
|
||||
|
||||
- p_len = PREFIX_SIZE(p->prefix->prefixlen);
|
||||
- if ((bptr = buf_reserve(h2buf, p_len)) == NULL) {
|
||||
- log_warnx("mrt_dump_entry_mp: buf_reserve error");
|
||||
- goto fail;
|
||||
- }
|
||||
- if (prefix_write(bptr, p_len, &addr, p->prefix->prefixlen) == -1) {
|
||||
- log_warnx("mrt_dump_entry_mp: prefix_write error");
|
||||
+ if (prefix_writebuf(h2buf, &addr, p->prefix->prefixlen) == -1) {
|
||||
+ log_warn("mrt_dump_entry_mp: prefix_writebuf error");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
DUMP_SHORT(h2buf, len);
|
||||
- len += buf_size(h2buf);
|
||||
+ len += ibuf_size(h2buf);
|
||||
|
||||
if (mrt_dump_hdr_rde(&hbuf, MSG_PROTOCOL_BGP4MP, BGP4MP_ENTRY,
|
||||
len) == -1)
|
||||
goto fail;
|
||||
|
||||
- buf_close(&mrt->wbuf, hbuf);
|
||||
- buf_close(&mrt->wbuf, h2buf);
|
||||
- buf_close(&mrt->wbuf, buf);
|
||||
+ ibuf_close(&mrt->wbuf, hbuf);
|
||||
+ ibuf_close(&mrt->wbuf, h2buf);
|
||||
+ ibuf_close(&mrt->wbuf, buf);
|
||||
|
||||
return (len + MRT_HEADER_SIZE);
|
||||
|
||||
fail:
|
||||
if (hbuf)
|
||||
- buf_free(hbuf);
|
||||
- if (h2buf);
|
||||
- buf_free(h2buf);
|
||||
- buf_free(buf);
|
||||
+ ibuf_free(hbuf);
|
||||
+ if (h2buf)
|
||||
+ ibuf_free(h2buf);
|
||||
+ ibuf_free(buf);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
@@ -310,34 +359,37 @@ int
|
||||
mrt_dump_entry(struct mrt *mrt, struct prefix *p, u_int16_t snum,
|
||||
struct rde_peer *peer)
|
||||
{
|
||||
- struct buf *buf, *hbuf;
|
||||
+ struct ibuf *buf, *hbuf;
|
||||
struct bgpd_addr addr, *nh;
|
||||
size_t len;
|
||||
+ u_int16_t subtype;
|
||||
+ u_int8_t dummy;
|
||||
|
||||
- if (p->prefix->af != AF_INET && peer->remote_addr.af == AF_INET)
|
||||
- /* only able to dump IPv4 */
|
||||
+ if (p->prefix->aid != peer->remote_addr.aid &&
|
||||
+ p->prefix->aid != AID_INET && p->prefix->aid != AID_INET6)
|
||||
+ /* only able to dump pure IPv4/IPv6 */
|
||||
return (0);
|
||||
|
||||
- if ((buf = buf_dynamic(0, MAX_PKTSIZE)) == NULL) {
|
||||
- log_warnx("mrt_dump_entry: buf_dynamic");
|
||||
+ if ((buf = ibuf_dynamic(0, MAX_PKTSIZE)) == NULL) {
|
||||
+ log_warn("mrt_dump_entry: ibuf_dynamic");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (p->aspath->nexthop == NULL) {
|
||||
bzero(&addr, sizeof(struct bgpd_addr));
|
||||
- addr.af = AF_INET;
|
||||
+ addr.aid = p->prefix->aid;
|
||||
nh = &addr;
|
||||
} else
|
||||
nh = &p->aspath->nexthop->exit_nexthop;
|
||||
- if (mrt_attr_dump(buf, p->aspath, nh) == -1) {
|
||||
+ if (mrt_attr_dump(buf, p->aspath, nh, 0) == -1) {
|
||||
log_warnx("mrt_dump_entry: mrt_attr_dump error");
|
||||
- buf_free(buf);
|
||||
+ ibuf_free(buf);
|
||||
return (-1);
|
||||
}
|
||||
- len = buf_size(buf);
|
||||
-
|
||||
- if (mrt_dump_hdr_rde(&hbuf, MSG_TABLE_DUMP, AFI_IPv4, len) == -1) {
|
||||
- buf_free(buf);
|
||||
+ len = ibuf_size(buf);
|
||||
+ aid2afi(p->prefix->aid, &subtype, &dummy);
|
||||
+ if (mrt_dump_hdr_rde(&hbuf, MSG_TABLE_DUMP, subtype, len) == -1) {
|
||||
+ ibuf_free(buf);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
@@ -345,23 +397,241 @@ mrt_dump_entry(struct mrt *mrt, struct p
|
||||
DUMP_SHORT(hbuf, snum);
|
||||
|
||||
pt_getaddr(p->prefix, &addr);
|
||||
- DUMP_NLONG(hbuf, addr.v4.s_addr);
|
||||
+ switch (p->prefix->aid) {
|
||||
+ case AID_INET:
|
||||
+ DUMP_NLONG(hbuf, addr.v4.s_addr);
|
||||
+ break;
|
||||
+ case AID_INET6:
|
||||
+ if (ibuf_add(hbuf, &addr.v6, sizeof(struct in6_addr)) == -1) {
|
||||
+ log_warn("mrt_dump_entry: ibuf_add error");
|
||||
+ goto fail;
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
DUMP_BYTE(hbuf, p->prefix->prefixlen);
|
||||
|
||||
DUMP_BYTE(hbuf, 1); /* state */
|
||||
DUMP_LONG(hbuf, p->lastchange); /* originated */
|
||||
- DUMP_NLONG(hbuf, peer->remote_addr.v4.s_addr);
|
||||
+ switch (p->prefix->aid) {
|
||||
+ case AID_INET:
|
||||
+ DUMP_NLONG(hbuf, peer->remote_addr.v4.s_addr);
|
||||
+ break;
|
||||
+ case AID_INET6:
|
||||
+ if (ibuf_add(hbuf, &peer->remote_addr.v6,
|
||||
+ sizeof(struct in6_addr)) == -1) {
|
||||
+ log_warn("mrt_dump_entry: ibuf_add error");
|
||||
+ goto fail;
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
DUMP_SHORT(hbuf, peer->short_as);
|
||||
DUMP_SHORT(hbuf, len);
|
||||
|
||||
- buf_close(&mrt->wbuf, hbuf);
|
||||
- buf_close(&mrt->wbuf, buf);
|
||||
+ ibuf_close(&mrt->wbuf, hbuf);
|
||||
+ ibuf_close(&mrt->wbuf, buf);
|
||||
|
||||
return (len + MRT_HEADER_SIZE);
|
||||
|
||||
fail:
|
||||
- buf_free(hbuf);
|
||||
- buf_free(buf);
|
||||
+ ibuf_free(hbuf);
|
||||
+ ibuf_free(buf);
|
||||
+ return (-1);
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+mrt_dump_entry_v2(struct mrt *mrt, struct rib_entry *re, u_int32_t snum)
|
||||
+{
|
||||
+ struct ibuf *buf, *hbuf = NULL;
|
||||
+ struct prefix *p;
|
||||
+ struct bgpd_addr addr;
|
||||
+ size_t len, off;
|
||||
+ u_int16_t subtype, nump;
|
||||
+
|
||||
+ switch (re->prefix->aid) {
|
||||
+ case AID_INET:
|
||||
+ subtype = MRT_DUMP_V2_RIB_IPV4_UNICAST;
|
||||
+ break;
|
||||
+ case AID_INET6:
|
||||
+ subtype = MRT_DUMP_V2_RIB_IPV6_UNICAST;
|
||||
+ break;
|
||||
+ default:
|
||||
+ subtype = MRT_DUMP_V2_RIB_GENERIC;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if ((buf = ibuf_dynamic(0, UINT_MAX)) == NULL) {
|
||||
+ log_warn("mrt_dump_entry: ibuf_dynamic");
|
||||
+ return (-1);
|
||||
+ }
|
||||
+
|
||||
+ DUMP_LONG(buf, snum);
|
||||
+ pt_getaddr(re->prefix, &addr);
|
||||
+ if (subtype == MRT_DUMP_V2_RIB_GENERIC) {
|
||||
+ u_int16_t afi;
|
||||
+ u_int8_t safi;
|
||||
+
|
||||
+ aid2afi(re->prefix->aid, &afi, &safi);
|
||||
+ DUMP_SHORT(buf, afi);
|
||||
+ DUMP_BYTE(buf, safi);
|
||||
+ }
|
||||
+ if (prefix_writebuf(buf, &addr, re->prefix->prefixlen) == -1) {
|
||||
+ log_warn("mrt_dump_entry_mp: prefix_writebuf error");
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ off = ibuf_size(buf);
|
||||
+ if (ibuf_reserve(buf, sizeof(nump)) == NULL) {
|
||||
+ log_warn("mrt_dump_v2_hdr: ibuf_reserve error");
|
||||
+ goto fail;
|
||||
+ }
|
||||
+ nump = 0;
|
||||
+ LIST_FOREACH(p, &re->prefix_h, rib_l) {
|
||||
+ struct bgpd_addr *nh;
|
||||
+ struct ibuf *tbuf;
|
||||
+
|
||||
+ if (p->aspath->nexthop == NULL) {
|
||||
+ bzero(&addr, sizeof(struct bgpd_addr));
|
||||
+ addr.aid = p->prefix->aid;
|
||||
+ nh = &addr;
|
||||
+ } else
|
||||
+ nh = &p->aspath->nexthop->exit_nexthop;
|
||||
+
|
||||
+ DUMP_SHORT(buf, p->aspath->peer->mrt_idx);
|
||||
+ DUMP_LONG(buf, p->lastchange); /* originated */
|
||||
+
|
||||
+ if ((tbuf = ibuf_dynamic(0, MAX_PKTSIZE)) == NULL) {
|
||||
+ log_warn("mrt_dump_entry_v2: ibuf_dynamic");
|
||||
+ return (-1);
|
||||
+ }
|
||||
+ if (mrt_attr_dump(tbuf, p->aspath, nh, 1) == -1) {
|
||||
+ log_warnx("mrt_dump_entry_v2: mrt_attr_dump error");
|
||||
+ ibuf_free(buf);
|
||||
+ return (-1);
|
||||
+ }
|
||||
+ len = ibuf_size(tbuf);
|
||||
+ DUMP_SHORT(buf, (u_int16_t)len);
|
||||
+ if (ibuf_add(buf, tbuf->buf, ibuf_size(tbuf)) == -1) {
|
||||
+ log_warn("mrt_dump_entry_v2: ibuf_add error");
|
||||
+ ibuf_free(tbuf);
|
||||
+ return (-1);
|
||||
+ }
|
||||
+ ibuf_free(tbuf);
|
||||
+ nump++;
|
||||
+ }
|
||||
+ nump = htons(nump);
|
||||
+ memcpy(ibuf_seek(buf, off, sizeof(nump)), &nump, sizeof(nump));
|
||||
+
|
||||
+ len = ibuf_size(buf);
|
||||
+ if (mrt_dump_hdr_rde(&hbuf, MSG_TABLE_DUMP_V2, subtype, len) == -1) {
|
||||
+ ibuf_free(buf);
|
||||
+ return (-1);
|
||||
+ }
|
||||
+
|
||||
+ ibuf_close(&mrt->wbuf, hbuf);
|
||||
+ ibuf_close(&mrt->wbuf, buf);
|
||||
+
|
||||
+ return (0);
|
||||
+fail:
|
||||
+ if (hbuf)
|
||||
+ ibuf_free(hbuf);
|
||||
+ ibuf_free(buf);
|
||||
+ return (-1);
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+mrt_dump_v2_hdr(struct mrt *mrt, struct bgpd_config *conf,
|
||||
+ struct rde_peer_head *ph)
|
||||
+{
|
||||
+ struct rde_peer *peer;
|
||||
+ struct ibuf *buf, *hbuf = NULL;
|
||||
+ size_t len, off;
|
||||
+ u_int16_t nlen, nump;
|
||||
+
|
||||
+ if ((buf = ibuf_dynamic(0, UINT_MAX)) == NULL) {
|
||||
+ log_warn("mrt_dump_v2_hdr: ibuf_dynamic");
|
||||
+ return (-1);
|
||||
+ }
|
||||
+
|
||||
+ DUMP_NLONG(buf, conf->bgpid);
|
||||
+ nlen = strlen(mrt->rib);
|
||||
+ if (nlen > 0)
|
||||
+ nlen += 1;
|
||||
+ DUMP_SHORT(buf, nlen);
|
||||
+ if (ibuf_add(buf, mrt->rib, nlen) == -1) {
|
||||
+ log_warn("mrt_dump_v2_hdr: ibuf_add error");
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ off = ibuf_size(buf);
|
||||
+ if (ibuf_reserve(buf, sizeof(nump)) == NULL) {
|
||||
+ log_warn("mrt_dump_v2_hdr: ibuf_reserve error");
|
||||
+ goto fail;
|
||||
+ }
|
||||
+ nump = 0;
|
||||
+ LIST_FOREACH(peer, ph, peer_l) {
|
||||
+ peer->mrt_idx = nump;
|
||||
+ if (mrt_dump_peer(buf, peer) == -1)
|
||||
+ goto fail;
|
||||
+ nump++;
|
||||
+ }
|
||||
+ nump = htons(nump);
|
||||
+ memcpy(ibuf_seek(buf, off, sizeof(nump)), &nump, sizeof(nump));
|
||||
+
|
||||
+ len = ibuf_size(buf);
|
||||
+ if (mrt_dump_hdr_rde(&hbuf, MSG_TABLE_DUMP_V2,
|
||||
+ MRT_DUMP_V2_PEER_INDEX_TABLE, len) == -1)
|
||||
+ goto fail;
|
||||
+
|
||||
+ ibuf_close(&mrt->wbuf, hbuf);
|
||||
+ ibuf_close(&mrt->wbuf, buf);
|
||||
+
|
||||
+ return (0);
|
||||
+fail:
|
||||
+ if (hbuf)
|
||||
+ ibuf_free(hbuf);
|
||||
+ ibuf_free(buf);
|
||||
+ return (-1);
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+mrt_dump_peer(struct ibuf *buf, struct rde_peer *peer)
|
||||
+{
|
||||
+ u_int8_t type = 0;
|
||||
+
|
||||
+ if (peer->capa.as4byte)
|
||||
+ type |= MRT_DUMP_V2_PEER_BIT_A;
|
||||
+ if (peer->remote_addr.aid == AID_INET6)
|
||||
+ type |= MRT_DUMP_V2_PEER_BIT_I;
|
||||
+
|
||||
+ DUMP_BYTE(buf, type);
|
||||
+ DUMP_LONG(buf, peer->remote_bgpid);
|
||||
+
|
||||
+ switch (peer->remote_addr.aid) {
|
||||
+ case AID_INET:
|
||||
+ DUMP_NLONG(buf, peer->remote_addr.v4.s_addr);
|
||||
+ break;
|
||||
+ case AID_INET6:
|
||||
+ if (ibuf_add(buf, &peer->remote_addr.v6,
|
||||
+ sizeof(struct in6_addr)) == -1) {
|
||||
+ log_warn("mrt_dump_peer: ibuf_add error");
|
||||
+ goto fail;
|
||||
+ }
|
||||
+ break;
|
||||
+ case AID_UNSPEC: /* XXX special handling for peer_self? */
|
||||
+ DUMP_NLONG(buf, 0);
|
||||
+ break;
|
||||
+ default:
|
||||
+ log_warnx("king bula found new AF in mrt_dump_entry_mp");
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ if (peer->capa.as4byte)
|
||||
+ DUMP_LONG(buf, peer->conf.remote_as);
|
||||
+ else
|
||||
+ DUMP_SHORT(buf, peer->short_as);
|
||||
+
|
||||
+ return (0);
|
||||
+fail:
|
||||
return (-1);
|
||||
}
|
||||
|
||||
@@ -371,6 +641,11 @@ mrt_dump_upcall(struct rib_entry *re, vo
|
||||
struct mrt *mrtbuf = ptr;
|
||||
struct prefix *p;
|
||||
|
||||
+ if (mrtbuf->type == MRT_TABLE_DUMP_V2) {
|
||||
+ mrt_dump_entry_v2(mrtbuf, re, mrtbuf->seqnum++);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
/*
|
||||
* dump all prefixes even the inactive ones. That is the way zebra
|
||||
* dumps the table so we do the same. If only the active route should
|
||||
@@ -387,7 +662,7 @@ mrt_dump_upcall(struct rib_entry *re, vo
|
||||
}
|
||||
|
||||
void
|
||||
-mrt_dump_done(void *ptr)
|
||||
+mrt_done(void *ptr)
|
||||
{
|
||||
struct mrt *mrtbuf = ptr;
|
||||
|
||||
@@ -395,14 +670,14 @@ mrt_dump_done(void *ptr)
|
||||
}
|
||||
|
||||
int
|
||||
-mrt_dump_hdr_se(struct buf ** bp, struct peer *peer, u_int16_t type,
|
||||
+mrt_dump_hdr_se(struct ibuf ** bp, struct peer *peer, u_int16_t type,
|
||||
u_int16_t subtype, u_int32_t len, int swap)
|
||||
{
|
||||
time_t now;
|
||||
|
||||
- if ((*bp = buf_dynamic(MRT_HEADER_SIZE, MRT_HEADER_SIZE +
|
||||
+ if ((*bp = ibuf_dynamic(MRT_HEADER_SIZE, MRT_HEADER_SIZE +
|
||||
MRT_BGP4MP_AS4_IPv6_HEADER_SIZE + len)) == NULL) {
|
||||
- log_warnx("mrt_dump_hdr_se: buf_open error");
|
||||
+ log_warn("mrt_dump_hdr_se: ibuf_dynamic error");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
@@ -468,23 +743,23 @@ mrt_dump_hdr_se(struct buf ** bp, struct
|
||||
case AF_INET6:
|
||||
DUMP_SHORT(*bp, AFI_IPv6);
|
||||
if (!swap)
|
||||
- if (buf_add(*bp, &((struct sockaddr_in6 *)
|
||||
+ if (ibuf_add(*bp, &((struct sockaddr_in6 *)
|
||||
&peer->sa_local)->sin6_addr,
|
||||
sizeof(struct in6_addr)) == -1) {
|
||||
- log_warnx("mrt_dump_hdr_se: buf_add error");
|
||||
+ log_warn("mrt_dump_hdr_se: ibuf_add error");
|
||||
goto fail;
|
||||
}
|
||||
- if (buf_add(*bp,
|
||||
+ if (ibuf_add(*bp,
|
||||
&((struct sockaddr_in6 *)&peer->sa_remote)->sin6_addr,
|
||||
sizeof(struct in6_addr)) == -1) {
|
||||
- log_warnx("mrt_dump_hdr_se: buf_add error");
|
||||
+ log_warn("mrt_dump_hdr_se: ibuf_add error");
|
||||
goto fail;
|
||||
}
|
||||
if (swap)
|
||||
- if (buf_add(*bp, &((struct sockaddr_in6 *)
|
||||
+ if (ibuf_add(*bp, &((struct sockaddr_in6 *)
|
||||
&peer->sa_local)->sin6_addr,
|
||||
sizeof(struct in6_addr)) == -1) {
|
||||
- log_warnx("mrt_dump_hdr_se: buf_add error");
|
||||
+ log_warn("mrt_dump_hdr_se: ibuf_add error");
|
||||
goto fail;
|
||||
}
|
||||
break;
|
||||
@@ -493,20 +768,20 @@ mrt_dump_hdr_se(struct buf ** bp, struct
|
||||
return (0);
|
||||
|
||||
fail:
|
||||
- buf_free(*bp);
|
||||
+ ibuf_free(*bp);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
int
|
||||
-mrt_dump_hdr_rde(struct buf **bp, u_int16_t type, u_int16_t subtype,
|
||||
+mrt_dump_hdr_rde(struct ibuf **bp, u_int16_t type, u_int16_t subtype,
|
||||
u_int32_t len)
|
||||
{
|
||||
time_t now;
|
||||
|
||||
- if ((*bp = buf_dynamic(MRT_HEADER_SIZE, MRT_HEADER_SIZE +
|
||||
+ if ((*bp = ibuf_dynamic(MRT_HEADER_SIZE, MRT_HEADER_SIZE +
|
||||
MRT_BGP4MP_AS4_IPv6_HEADER_SIZE + MRT_BGP4MP_IPv6_ENTRY_SIZE)) ==
|
||||
NULL) {
|
||||
- log_warnx("mrt_dump_hdr_rde: buf_dynamic error");
|
||||
+ log_warn("mrt_dump_hdr_rde: ibuf_dynamic error");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
@@ -517,19 +792,28 @@ mrt_dump_hdr_rde(struct buf **bp, u_int1
|
||||
|
||||
switch (type) {
|
||||
case MSG_TABLE_DUMP:
|
||||
- DUMP_LONG(*bp, MRT_DUMP_HEADER_SIZE + len);
|
||||
+ switch (subtype) {
|
||||
+ case AFI_IPv4:
|
||||
+ len += MRT_DUMP_HEADER_SIZE;
|
||||
+ break;
|
||||
+ case AFI_IPv6:
|
||||
+ len += MRT_DUMP_HEADER_SIZE_V6;
|
||||
+ break;
|
||||
+ }
|
||||
+ DUMP_LONG(*bp, len);
|
||||
break;
|
||||
case MSG_PROTOCOL_BGP4MP:
|
||||
+ case MSG_TABLE_DUMP_V2:
|
||||
DUMP_LONG(*bp, len);
|
||||
break;
|
||||
default:
|
||||
log_warnx("mrt_dump_hdr_rde: unsupported type");
|
||||
goto fail;
|
||||
- }
|
||||
+ }
|
||||
return (0);
|
||||
|
||||
fail:
|
||||
- buf_free(*bp);
|
||||
+ ibuf_free(*bp);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
@@ -538,21 +822,22 @@ mrt_write(struct mrt *mrt)
|
||||
{
|
||||
int r;
|
||||
|
||||
- if ((r = buf_write(&mrt->wbuf)) < 0) {
|
||||
+ if ((r = ibuf_write(&mrt->wbuf)) < 0) {
|
||||
log_warn("mrt dump aborted, mrt_write");
|
||||
mrt_clean(mrt);
|
||||
+ mrt_done(mrt);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mrt_clean(struct mrt *mrt)
|
||||
{
|
||||
- struct buf *b;
|
||||
+ struct ibuf *b;
|
||||
|
||||
close(mrt->wbuf.fd);
|
||||
while ((b = TAILQ_FIRST(&mrt->wbuf.bufs))) {
|
||||
TAILQ_REMOVE(&mrt->wbuf.bufs, b, entry);
|
||||
- buf_free(b);
|
||||
+ ibuf_free(b);
|
||||
}
|
||||
mrt->wbuf.queued = 0;
|
||||
}
|
||||
@@ -590,7 +875,8 @@ mrt_open(struct mrt *mrt, time_t now)
|
||||
else
|
||||
type = IMSG_MRT_REOPEN;
|
||||
|
||||
- if (mrt->type == MRT_TABLE_DUMP || mrt->type == MRT_TABLE_DUMP_MP)
|
||||
+ if (mrt->type == MRT_TABLE_DUMP || mrt->type == MRT_TABLE_DUMP_MP ||
|
||||
+ mrt->type == MRT_TABLE_DUMP_V2)
|
||||
i = 0;
|
||||
|
||||
if (imsg_compose(mrt_imsgbuf[i], type, 0, 0, fd,
|
||||
@@ -659,7 +945,9 @@ mrt_handler(struct mrt_head *mrt)
|
||||
LIST_FOREACH(m, mrt, entry) {
|
||||
if (m->state == MRT_STATE_RUNNING &&
|
||||
(MRT2MC(m)->ReopenTimerInterval != 0 ||
|
||||
- m->type == MRT_TABLE_DUMP)) {
|
||||
+ m->type == MRT_TABLE_DUMP ||
|
||||
+ m->type == MRT_TABLE_DUMP_MP ||
|
||||
+ m->type == MRT_TABLE_DUMP_V2)) {
|
||||
if (mrt_open(m, now) == -1)
|
||||
continue;
|
||||
MRT2MC(m)->ReopenTimer =
|
287
net/openbgpd/files/patch-bgpd_mrt.h
Normal file
287
net/openbgpd/files/patch-bgpd_mrt.h
Normal file
@ -0,0 +1,287 @@
|
||||
Index: bgpd/mrt.h
|
||||
===================================================================
|
||||
RCS file: /home/cvs/private/hrs/openbgpd/bgpd/mrt.h,v
|
||||
retrieving revision 1.1.1.6
|
||||
retrieving revision 1.1.1.9
|
||||
diff -u -p -r1.1.1.6 -r1.1.1.9
|
||||
--- bgpd/mrt.h 14 Feb 2010 20:19:57 -0000 1.1.1.6
|
||||
+++ bgpd/mrt.h 13 Oct 2012 18:22:43 -0000 1.1.1.9
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* $OpenBSD: mrt.h,v 1.23 2009/06/29 12:22:16 claudio Exp $ */
|
||||
+/* $OpenBSD: mrt.h,v 1.30 2011/09/18 09:31:25 claudio Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org>
|
||||
@@ -18,12 +18,10 @@
|
||||
#ifndef __MRT_H__
|
||||
#define __MRT_H__
|
||||
|
||||
-#include "bgpd.h"
|
||||
-
|
||||
/*
|
||||
* MRT binary packet format
|
||||
* For more info see:
|
||||
- * draft-ietf-grow-mrt-04.txt, "MRT routing information export format"
|
||||
+ * draft-ietf-grow-mrt-11.txt, "MRT routing information export format"
|
||||
* http://www.quagga.net/docs/docs-multi/Packet-Binary-Dump-Format.html
|
||||
*/
|
||||
|
||||
@@ -37,11 +35,18 @@
|
||||
* | length | length of packet excluding this header
|
||||
* +--------+--------+--------+--------+
|
||||
*
|
||||
- * ET types include an additional 32bit microsecond field comming after the
|
||||
- * length field.
|
||||
+ * ET types include an additional 32bit microsecond field coming after the
|
||||
+ * length field. Which is accounted in the length field.
|
||||
*/
|
||||
#define MRT_HEADER_SIZE 12
|
||||
|
||||
+struct mrt_hdr {
|
||||
+ u_int32_t timestamp;
|
||||
+ u_int16_t type;
|
||||
+ u_int16_t subtype;
|
||||
+ u_int32_t length;
|
||||
+} __packed;
|
||||
+
|
||||
enum MRT_MSG_TYPES {
|
||||
MSG_NULL, /* 0 empty msg (deprecated) */
|
||||
MSG_START, /* 1 sender is starting up */
|
||||
@@ -70,13 +75,15 @@ enum MRT_MSG_TYPES {
|
||||
* that are normaly saved as MSG_TABLE_DUMP.
|
||||
* In most cases this is the format to choose to dump updates et al.
|
||||
*/
|
||||
-enum MRT_BGP4MP_TYPES {
|
||||
+enum MRT_BGP4MP_SUBTYPES {
|
||||
BGP4MP_STATE_CHANGE, /* state change */
|
||||
BGP4MP_MESSAGE, /* bgp message */
|
||||
BGP4MP_ENTRY, /* table dumps (deprecated) */
|
||||
BGP4MP_SNAPSHOT, /* file name for dump (deprecated) */
|
||||
+ BGP4MP_MESSAGE_AS4, /* same as BGP4MP_MESSAGE with 4byte AS */
|
||||
BGP4MP_STATE_CHANGE_AS4,
|
||||
- BGP4MP_MESSAGE_AS4 /* same as BGP4MP_MESSAGE with 4byte AS */
|
||||
+ BGP4MP_MESSAGE_LOCAL, /* same as BGP4MP_MESSAGE but for self */
|
||||
+ BGP4MP_MESSAGE_AS4_LOCAL /* originated updates. Not implemented */
|
||||
};
|
||||
|
||||
/* size of the BGP4MP headers without payload */
|
||||
@@ -104,6 +111,7 @@ enum MRT_BGP4MP_TYPES {
|
||||
*
|
||||
* The source_ip and dest_ip are dependant of the afi type. For IPv6 source_ip
|
||||
* and dest_ip are both 16 bytes long.
|
||||
+ * For the AS4 types the source_as and dest_as numbers are both 4 bytes long.
|
||||
*
|
||||
* Payload of a BGP4MP_STATE_CHANGE packet:
|
||||
*
|
||||
@@ -155,6 +163,98 @@ enum MRT_BGP4MP_TYPES {
|
||||
*/
|
||||
|
||||
/*
|
||||
+ * New MRT dump format MSG_TABLE_DUMP_V2, the dump is implemented with
|
||||
+ * sub-tables for peers and NLRI entries just use the index into the peer
|
||||
+ * table.
|
||||
+ */
|
||||
+enum MRT_DUMP_V2_SUBTYPES {
|
||||
+ MRT_DUMP_V2_PEER_INDEX_TABLE=1,
|
||||
+ MRT_DUMP_V2_RIB_IPV4_UNICAST=2,
|
||||
+ MRT_DUMP_V2_RIB_IPV4_MULTICAST=3,
|
||||
+ MRT_DUMP_V2_RIB_IPV6_UNICAST=4,
|
||||
+ MRT_DUMP_V2_RIB_IPV6_MULTICAST=5,
|
||||
+ MRT_DUMP_V2_RIB_GENERIC=6
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ * Format of the MRT_DUMP_V2_PEER_INDEX_TABLE:
|
||||
+ * If there is no view_name, view_name_len must be set to 0
|
||||
+ *
|
||||
+ * +--------+--------+--------+--------+
|
||||
+ * | collector_bgp_id |
|
||||
+ * +--------+--------+--------+--------+
|
||||
+ * | view_name_len | view_name
|
||||
+ * +--------+--------+--------+--------+
|
||||
+ * view_name (variable) ... |
|
||||
+ * +--------+--------+--------+--------+
|
||||
+ * | peer_count | peer_entries
|
||||
+ * +--------+--------+--------+--------+
|
||||
+ * peer_entries (variable) ...
|
||||
+ * +--------+--------+--------+--------+
|
||||
+ *
|
||||
+ * The format of a peer_entry is the following:
|
||||
+ *
|
||||
+ * +--------+
|
||||
+ * | type |
|
||||
+ * +--------+--------+--------+--------+
|
||||
+ * | peer_bgp_id |
|
||||
+ * +--------+--------+--------+--------+
|
||||
+ * | peer_ip_addr (variable) |
|
||||
+ * +--------+--------+--------+--------+
|
||||
+ * | peer_as (variable) |
|
||||
+ * +--------+--------+--------+--------+
|
||||
+ *
|
||||
+ * The message is packed a bit strangely. The type byte defines what size
|
||||
+ * the peer addr and peer AS have.
|
||||
+ * The position of a peer in the PEER_INDEX_TABLE is used as the index for
|
||||
+ * the other messages.
|
||||
+ */
|
||||
+#define MRT_DUMP_V2_PEER_BIT_I 0x1 /* set for IPv6 addrs */
|
||||
+#define MRT_DUMP_V2_PEER_BIT_A 0x2 /* set for 32 bits AS number */
|
||||
+
|
||||
+/*
|
||||
+ * AFI/SAFI specific RIB Subtypes are special to save a few bytes.
|
||||
+ *
|
||||
+ * +--------+--------+--------+--------+
|
||||
+ * | seq_num |
|
||||
+ * +--------+--------+--------+--------+
|
||||
+ * | plen | prefix (variable)
|
||||
+ * +--------+--------+--------+--------+
|
||||
+ * | #entry | rib entries (variable)
|
||||
+ * +--------+--------+--------+--------+
|
||||
+ *
|
||||
+ * The RIB_GENERIC subtype is needed for the less common AFI/SAFI pairs
|
||||
+ *
|
||||
+ * +--------+--------+--------+--------+
|
||||
+ * | seq_num |
|
||||
+ * +--------+--------+--------+--------+
|
||||
+ * | AFI | SAFI | NLRI
|
||||
+ * +--------+--------+--------+--------+
|
||||
+ * NLRI (variable) ...
|
||||
+ * +--------+--------+--------+--------+
|
||||
+ * | #entry | rib entries (variable)
|
||||
+ * +--------+--------+--------+--------+
|
||||
+ */
|
||||
+
|
||||
+/*
|
||||
+ * The RIB entries have the following form.
|
||||
+ *
|
||||
+ * +--------+--------+
|
||||
+ * | peer index |
|
||||
+ * +--------+--------+--------+--------+
|
||||
+ * | originated_time |
|
||||
+ * +--------+--------+--------+--------+
|
||||
+ * | attr_len | bgp_attrs
|
||||
+ * +--------+--------+--------+--------+
|
||||
+ * bgp_attrs (variable) ...
|
||||
+ * +--------+--------+--------+--------+
|
||||
+ *
|
||||
+ * Some BGP path attributes need special encoding:
|
||||
+ * - the AS_PATH attribute MUST be encoded as 4-Byte AS
|
||||
+ * - the MP_REACH_NLRI only consists of the nexthop len and nexthop address
|
||||
+ */
|
||||
+
|
||||
+/*
|
||||
* Format for routing table dumps in "old" mrt format.
|
||||
* Type MSG_TABLE_DUMP and subtype is AFI_IPv4 (1) for IPv4 and AFI_IPv6 (2)
|
||||
* for IPv6. In the IPv6 case prefix and peer_ip are both 16 bytes long.
|
||||
@@ -182,8 +282,14 @@ enum MRT_BGP4MP_TYPES {
|
||||
* The status field is unused and should be set to 1.
|
||||
*/
|
||||
|
||||
+enum MRT_DUMP_SUBTYPES {
|
||||
+ MRT_DUMP_AFI_IP=1,
|
||||
+ MRT_DUMP_AFI_IPv6=2
|
||||
+};
|
||||
+
|
||||
/* size of the dump header until attr_len */
|
||||
#define MRT_DUMP_HEADER_SIZE 22
|
||||
+#define MRT_DUMP_HEADER_SIZE_V6 46
|
||||
|
||||
/*
|
||||
* OLD MRT message headers. These structs are here for completion but
|
||||
@@ -192,7 +298,7 @@ enum MRT_BGP4MP_TYPES {
|
||||
* Only for bgp messages (type 5, 9 and 10)
|
||||
* Nota bene for bgp dumps MSG_PROTOCOL_BGP4MP should be used.
|
||||
*/
|
||||
-enum MRT_BGP_TYPES {
|
||||
+enum MRT_BGP_SUBTYPES {
|
||||
MSG_BGP_NULL,
|
||||
MSG_BGP_UPDATE, /* raw update packet (contains both withdraws
|
||||
and announcements) */
|
||||
@@ -221,10 +327,8 @@ enum MRT_BGP_TYPES {
|
||||
*
|
||||
* For IPv6 the type is MSG_PROTOCOL_BGP4PLUS and the subtype remains
|
||||
* MSG_BGP_UPDATE. The source_ip and dest_ip are again extended to 16 bytes.
|
||||
- */
|
||||
-
|
||||
-/*
|
||||
- * For subtype MSG_BGP_STATECHANGE (for all BGP types or just for the
|
||||
+ *
|
||||
+ * For subtype MSG_BGP_STATE_CHANGE (for all BGP types or just for the
|
||||
* MSG_PROTOCOL_BGP4PLUS case? Unclear.)
|
||||
*
|
||||
* +--------+--------+--------+--------+
|
||||
@@ -235,7 +339,7 @@ enum MRT_BGP_TYPES {
|
||||
* | new_state |
|
||||
* +--------+--------+
|
||||
*
|
||||
- * State are defined in RFC 1771.
|
||||
+ * States are defined in RFC 1771/4271.
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -251,66 +355,4 @@ enum MRT_BGP_TYPES {
|
||||
* terminated ... | 0 |
|
||||
* +--------+--------+--------+
|
||||
*/
|
||||
-
|
||||
-#define MRT_FILE_LEN 512
|
||||
-enum mrt_type {
|
||||
- MRT_NONE,
|
||||
- MRT_TABLE_DUMP,
|
||||
- MRT_TABLE_DUMP_MP,
|
||||
- MRT_ALL_IN,
|
||||
- MRT_ALL_OUT,
|
||||
- MRT_UPDATE_IN,
|
||||
- MRT_UPDATE_OUT
|
||||
-};
|
||||
-
|
||||
-enum mrt_state {
|
||||
- MRT_STATE_RUNNING,
|
||||
- MRT_STATE_OPEN,
|
||||
- MRT_STATE_REOPEN,
|
||||
- MRT_STATE_REMOVE
|
||||
-};
|
||||
-
|
||||
-struct mrt {
|
||||
- char rib[PEER_DESCR_LEN];
|
||||
- struct msgbuf wbuf;
|
||||
- LIST_ENTRY(mrt) entry;
|
||||
- u_int32_t peer_id;
|
||||
- u_int32_t group_id;
|
||||
- enum mrt_type type;
|
||||
- enum mrt_state state;
|
||||
- u_int16_t seqnum;
|
||||
-};
|
||||
-
|
||||
-struct mrt_config {
|
||||
- struct mrt conf;
|
||||
- char name[MRT_FILE_LEN]; /* base file name */
|
||||
- char file[MRT_FILE_LEN]; /* actual file name */
|
||||
- time_t ReopenTimer;
|
||||
- time_t ReopenTimerInterval;
|
||||
-};
|
||||
-
|
||||
-#define MRT2MC(x) ((struct mrt_config *)(x))
|
||||
-#define MRT_MAX_TIMEOUT 7200
|
||||
-
|
||||
-struct peer;
|
||||
-struct prefix;
|
||||
-struct rib_entry;
|
||||
-
|
||||
-/* prototypes */
|
||||
-void mrt_dump_bgp_msg(struct mrt *, void *, u_int16_t,
|
||||
- struct peer *);
|
||||
-void mrt_dump_state(struct mrt *, u_int16_t, u_int16_t,
|
||||
- struct peer *);
|
||||
-void mrt_clear_seq(void);
|
||||
-void mrt_dump_upcall(struct rib_entry *, void *);
|
||||
-void mrt_dump_done(void *);
|
||||
-void mrt_write(struct mrt *);
|
||||
-void mrt_clean(struct mrt *);
|
||||
-void mrt_init(struct imsgbuf *, struct imsgbuf *);
|
||||
-int mrt_timeout(struct mrt_head *);
|
||||
-void mrt_reconfigure(struct mrt_head *);
|
||||
-void mrt_handler(struct mrt_head *);
|
||||
-struct mrt *mrt_get(struct mrt_head *, struct mrt *);
|
||||
-int mrt_mergeconfig(struct mrt_head *, struct mrt_head *);
|
||||
-
|
||||
#endif
|
14
net/openbgpd/files/patch-bgpd_name2id.c
Normal file
14
net/openbgpd/files/patch-bgpd_name2id.c
Normal file
@ -0,0 +1,14 @@
|
||||
Index: bgpd/name2id.c
|
||||
===================================================================
|
||||
RCS file: /home/cvs/private/hrs/openbgpd/bgpd/name2id.c,v
|
||||
retrieving revision 1.1.1.2
|
||||
retrieving revision 1.1.1.3
|
||||
diff -u -p -r1.1.1.2 -r1.1.1.3
|
||||
--- bgpd/name2id.c 9 Jul 2009 16:49:54 -0000 1.1.1.2
|
||||
+++ bgpd/name2id.c 13 Oct 2012 18:22:43 -0000 1.1.1.3
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* $OpenBSD: name2id.c,v 1.9 2009/06/04 04:46:42 claudio Exp $ */
|
||||
+/* $OpenBSD: name2id.c,v 1.8 2009/05/17 12:25:15 claudio Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004, 2005 Henning Brauer <henning@openbsd.org>
|
1626
net/openbgpd/files/patch-bgpd_parse.y
Normal file
1626
net/openbgpd/files/patch-bgpd_parse.y
Normal file
File diff suppressed because it is too large
Load Diff
471
net/openbgpd/files/patch-bgpd_pfkey.c
Normal file
471
net/openbgpd/files/patch-bgpd_pfkey.c
Normal file
@ -0,0 +1,471 @@
|
||||
diff -ur bgpd.orig/pfkey.c bgpd/pfkey.c
|
||||
--- bgpd.orig/pfkey.c 2013-03-15 12:07:16.000000000 +0000
|
||||
+++ bgpd/pfkey.c 2013-03-15 12:07:47.000000000 +0000
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* $OpenBSD: pfkey.c,v 1.37 2009/04/21 15:25:52 henning Exp $ */
|
||||
+/* $OpenBSD: pfkey.c,v 1.40 2009/12/14 17:38:18 claudio Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
|
||||
@@ -21,7 +21,7 @@
|
||||
#include <sys/socket.h>
|
||||
#include <sys/uio.h>
|
||||
#include <net/pfkeyv2.h>
|
||||
-#include <netinet/ip_ipsp.h>
|
||||
+//#include <netinet/ip_ipsp.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
@@ -65,15 +65,15 @@
|
||||
{
|
||||
struct sadb_msg smsg;
|
||||
struct sadb_sa sa;
|
||||
- struct sadb_address sa_src, sa_dst, sa_peer, sa_smask, sa_dmask;
|
||||
+ struct sadb_address sa_src, sa_dst;
|
||||
struct sadb_key sa_akey, sa_ekey;
|
||||
struct sadb_spirange sa_spirange;
|
||||
- struct sadb_protocol sa_flowtype, sa_protocol;
|
||||
struct iovec iov[IOV_CNT];
|
||||
ssize_t n;
|
||||
int len = 0;
|
||||
int iov_cnt;
|
||||
- struct sockaddr_storage ssrc, sdst, speer, smask, dmask;
|
||||
+ struct sockaddr_storage ssrc, sdst, smask, dmask;
|
||||
+ struct sockaddr *saptr;
|
||||
|
||||
if (!pid)
|
||||
pid = getpid();
|
||||
@@ -81,22 +81,17 @@
|
||||
/* we need clean sockaddr... no ports set */
|
||||
bzero(&ssrc, sizeof(ssrc));
|
||||
bzero(&smask, sizeof(smask));
|
||||
- switch (src->af) {
|
||||
- case AF_INET:
|
||||
- ((struct sockaddr_in *)&ssrc)->sin_addr = src->v4;
|
||||
- ssrc.ss_len = sizeof(struct sockaddr_in);
|
||||
- ssrc.ss_family = AF_INET;
|
||||
+ if ((saptr = addr2sa(src, 0)))
|
||||
+ memcpy(&ssrc, saptr, sizeof(ssrc));
|
||||
+ switch (src->aid) {
|
||||
+ case AID_INET:
|
||||
memset(&((struct sockaddr_in *)&smask)->sin_addr, 0xff, 32/8);
|
||||
break;
|
||||
- case AF_INET6:
|
||||
- memcpy(&((struct sockaddr_in6 *)&ssrc)->sin6_addr,
|
||||
- &src->v6, sizeof(struct in6_addr));
|
||||
- ssrc.ss_len = sizeof(struct sockaddr_in6);
|
||||
- ssrc.ss_family = AF_INET6;
|
||||
+ case AID_INET6:
|
||||
memset(&((struct sockaddr_in6 *)&smask)->sin6_addr, 0xff,
|
||||
128/8);
|
||||
break;
|
||||
- case 0:
|
||||
+ case AID_UNSPEC:
|
||||
ssrc.ss_len = sizeof(struct sockaddr);
|
||||
break;
|
||||
default:
|
||||
@@ -107,22 +102,17 @@
|
||||
|
||||
bzero(&sdst, sizeof(sdst));
|
||||
bzero(&dmask, sizeof(dmask));
|
||||
- switch (dst->af) {
|
||||
- case AF_INET:
|
||||
- ((struct sockaddr_in *)&sdst)->sin_addr = dst->v4;
|
||||
- sdst.ss_len = sizeof(struct sockaddr_in);
|
||||
- sdst.ss_family = AF_INET;
|
||||
+ if ((saptr = addr2sa(dst, 0)))
|
||||
+ memcpy(&sdst, saptr, sizeof(sdst));
|
||||
+ switch (dst->aid) {
|
||||
+ case AID_INET:
|
||||
memset(&((struct sockaddr_in *)&dmask)->sin_addr, 0xff, 32/8);
|
||||
break;
|
||||
- case AF_INET6:
|
||||
- memcpy(&((struct sockaddr_in6 *)&sdst)->sin6_addr,
|
||||
- &dst->v6, sizeof(struct in6_addr));
|
||||
- sdst.ss_len = sizeof(struct sockaddr_in6);
|
||||
- sdst.ss_family = AF_INET6;
|
||||
+ case AID_INET6:
|
||||
memset(&((struct sockaddr_in6 *)&dmask)->sin6_addr, 0xff,
|
||||
128/8);
|
||||
break;
|
||||
- case 0:
|
||||
+ case AID_UNSPEC:
|
||||
sdst.ss_len = sizeof(struct sockaddr);
|
||||
break;
|
||||
default:
|
||||
@@ -135,7 +125,7 @@
|
||||
smsg.sadb_msg_version = PF_KEY_V2;
|
||||
smsg.sadb_msg_seq = ++sadb_msg_seq;
|
||||
smsg.sadb_msg_pid = pid;
|
||||
- smsg.sadb_msg_len = sizeof(smsg) / 8;
|
||||
+ smsg.sadb_msg_len = PFKEY_UNIT64(sizeof(smsg));
|
||||
smsg.sadb_msg_type = mtype;
|
||||
smsg.sadb_msg_satype = satype;
|
||||
|
||||
@@ -143,7 +133,7 @@
|
||||
case SADB_GETSPI:
|
||||
bzero(&sa_spirange, sizeof(sa_spirange));
|
||||
sa_spirange.sadb_spirange_exttype = SADB_EXT_SPIRANGE;
|
||||
- sa_spirange.sadb_spirange_len = sizeof(sa_spirange) / 8;
|
||||
+ sa_spirange.sadb_spirange_len = PFKEY_UNIT64(sizeof(sa_spirange));
|
||||
sa_spirange.sadb_spirange_min = 0x100;
|
||||
sa_spirange.sadb_spirange_max = 0xffffffff;
|
||||
sa_spirange.sadb_spirange_reserved = 0;
|
||||
@@ -153,11 +143,12 @@
|
||||
case SADB_DELETE:
|
||||
bzero(&sa, sizeof(sa));
|
||||
sa.sadb_sa_exttype = SADB_EXT_SA;
|
||||
- sa.sadb_sa_len = sizeof(sa) / 8;
|
||||
+ sa.sadb_sa_len = PFKEY_UNIT64(sizeof(sa));
|
||||
sa.sadb_sa_replay = 0;
|
||||
sa.sadb_sa_spi = spi;
|
||||
sa.sadb_sa_state = SADB_SASTATE_MATURE;
|
||||
break;
|
||||
+#if 0
|
||||
case SADB_X_ADDFLOW:
|
||||
case SADB_X_DELFLOW:
|
||||
bzero(&sa_flowtype, sizeof(sa_flowtype));
|
||||
@@ -172,35 +163,37 @@
|
||||
sa_protocol.sadb_protocol_direction = 0;
|
||||
sa_protocol.sadb_protocol_proto = 6;
|
||||
break;
|
||||
+#endif
|
||||
}
|
||||
|
||||
bzero(&sa_src, sizeof(sa_src));
|
||||
sa_src.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
|
||||
- sa_src.sadb_address_len = (sizeof(sa_src) + ROUNDUP(ssrc.ss_len)) / 8;
|
||||
+ sa_src.sadb_address_len = PFKEY_UNIT64(sizeof(sa_src) + ROUNDUP(ssrc.ss_len));
|
||||
|
||||
bzero(&sa_dst, sizeof(sa_dst));
|
||||
sa_dst.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
|
||||
- sa_dst.sadb_address_len = (sizeof(sa_dst) + ROUNDUP(sdst.ss_len)) / 8;
|
||||
+ sa_dst.sadb_address_len = PFKEY_UNIT64(sizeof(sa_dst) + ROUNDUP(sdst.ss_len));
|
||||
|
||||
sa.sadb_sa_auth = aalg;
|
||||
- sa.sadb_sa_encrypt = SADB_X_EALG_AES; /* XXX */
|
||||
+ sa.sadb_sa_encrypt = ealg; /* XXX */
|
||||
|
||||
switch (mtype) {
|
||||
case SADB_ADD:
|
||||
case SADB_UPDATE:
|
||||
bzero(&sa_akey, sizeof(sa_akey));
|
||||
sa_akey.sadb_key_exttype = SADB_EXT_KEY_AUTH;
|
||||
- sa_akey.sadb_key_len = (sizeof(sa_akey) +
|
||||
- ((alen + 7) / 8) * 8) / 8;
|
||||
+ sa_akey.sadb_key_len = PFKEY_UNIT64(sizeof(sa_akey) +
|
||||
+ (PFKEY_ALIGN8(alen)));
|
||||
sa_akey.sadb_key_bits = 8 * alen;
|
||||
|
||||
bzero(&sa_ekey, sizeof(sa_ekey));
|
||||
sa_ekey.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT;
|
||||
- sa_ekey.sadb_key_len = (sizeof(sa_ekey) +
|
||||
- ((elen + 7) / 8) * 8) / 8;
|
||||
+ sa_ekey.sadb_key_len = PFKEY_UNIT64(sizeof(sa_ekey) +
|
||||
+ (PFKEY_ALIGN8(elen)));
|
||||
sa_ekey.sadb_key_bits = 8 * elen;
|
||||
|
||||
break;
|
||||
+#if 0
|
||||
case SADB_X_ADDFLOW:
|
||||
case SADB_X_DELFLOW:
|
||||
/* sa_peer always points to the remote machine */
|
||||
@@ -220,8 +213,8 @@
|
||||
sa_dst.sadb_address_exttype = SADB_X_EXT_DST_FLOW;
|
||||
|
||||
bzero(&smask, sizeof(smask));
|
||||
- switch (src->af) {
|
||||
- case AF_INET:
|
||||
+ switch (src->aid) {
|
||||
+ case AID_INET:
|
||||
smask.ss_len = sizeof(struct sockaddr_in);
|
||||
smask.ss_family = AF_INET;
|
||||
memset(&((struct sockaddr_in *)&smask)->sin_addr,
|
||||
@@ -233,7 +226,7 @@
|
||||
htons(0xffff);
|
||||
}
|
||||
break;
|
||||
- case AF_INET6:
|
||||
+ case AID_INET6:
|
||||
smask.ss_len = sizeof(struct sockaddr_in6);
|
||||
smask.ss_family = AF_INET6;
|
||||
memset(&((struct sockaddr_in6 *)&smask)->sin6_addr,
|
||||
@@ -247,8 +240,8 @@
|
||||
break;
|
||||
}
|
||||
bzero(&dmask, sizeof(dmask));
|
||||
- switch (dst->af) {
|
||||
- case AF_INET:
|
||||
+ switch (dst->aid) {
|
||||
+ case AID_INET:
|
||||
dmask.ss_len = sizeof(struct sockaddr_in);
|
||||
dmask.ss_family = AF_INET;
|
||||
memset(&((struct sockaddr_in *)&dmask)->sin_addr,
|
||||
@@ -260,7 +253,7 @@
|
||||
htons(0xffff);
|
||||
}
|
||||
break;
|
||||
- case AF_INET6:
|
||||
+ case AID_INET6:
|
||||
dmask.ss_len = sizeof(struct sockaddr_in6);
|
||||
dmask.ss_family = AF_INET6;
|
||||
memset(&((struct sockaddr_in6 *)&dmask)->sin6_addr,
|
||||
@@ -284,6 +277,7 @@
|
||||
sa_dmask.sadb_address_len =
|
||||
(sizeof(sa_dmask) + ROUNDUP(dmask.ss_len)) / 8;
|
||||
break;
|
||||
+#endif
|
||||
}
|
||||
|
||||
iov_cnt = 0;
|
||||
@@ -310,6 +304,7 @@
|
||||
smsg.sadb_msg_len += sa_spirange.sadb_spirange_len;
|
||||
iov_cnt++;
|
||||
break;
|
||||
+#if 0
|
||||
case SADB_X_ADDFLOW:
|
||||
/* sa_peer always points to the remote machine */
|
||||
iov[iov_cnt].iov_base = &sa_peer;
|
||||
@@ -351,6 +346,7 @@
|
||||
smsg.sadb_msg_len += sa_dmask.sadb_address_len;
|
||||
iov_cnt++;
|
||||
break;
|
||||
+#endif
|
||||
}
|
||||
|
||||
/* dest addr */
|
||||
@@ -380,7 +376,7 @@
|
||||
iov[iov_cnt].iov_len = sizeof(sa_akey);
|
||||
iov_cnt++;
|
||||
iov[iov_cnt].iov_base = akey;
|
||||
- iov[iov_cnt].iov_len = ((alen + 7) / 8) * 8;
|
||||
+ iov[iov_cnt].iov_len = PFKEY_ALIGN8(alen);
|
||||
smsg.sadb_msg_len += sa_akey.sadb_key_len;
|
||||
iov_cnt++;
|
||||
}
|
||||
@@ -390,14 +386,14 @@
|
||||
iov[iov_cnt].iov_len = sizeof(sa_ekey);
|
||||
iov_cnt++;
|
||||
iov[iov_cnt].iov_base = ekey;
|
||||
- iov[iov_cnt].iov_len = ((elen + 7) / 8) * 8;
|
||||
+ iov[iov_cnt].iov_len = PFKEY_ALIGN8(elen);
|
||||
smsg.sadb_msg_len += sa_ekey.sadb_key_len;
|
||||
iov_cnt++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
- len = smsg.sadb_msg_len * 8;
|
||||
+ len = PFKEY_UNUNIT64(smsg.sadb_msg_len);
|
||||
do {
|
||||
n = writev(sd, iov, iov_cnt);
|
||||
} while (n == -1 && (errno == EAGAIN || errno == EINTR));
|
||||
@@ -411,6 +407,33 @@
|
||||
}
|
||||
|
||||
int
|
||||
+pfkey_read(int sd, struct sadb_msg *h)
|
||||
+{
|
||||
+ struct sadb_msg hdr;
|
||||
+
|
||||
+ if (recv(sd, &hdr, sizeof(hdr), MSG_PEEK) != sizeof(hdr)) {
|
||||
+ log_warn("pfkey peek");
|
||||
+ return (-1);
|
||||
+ }
|
||||
+
|
||||
+ /* XXX: Only one message can be outstanding. */
|
||||
+ if (hdr.sadb_msg_seq == sadb_msg_seq &&
|
||||
+ hdr.sadb_msg_pid == pid) {
|
||||
+ if (h)
|
||||
+ bcopy(&hdr, h, sizeof(hdr));
|
||||
+ return (0);
|
||||
+ }
|
||||
+
|
||||
+ /* not ours, discard */
|
||||
+ if (read(sd, &hdr, sizeof(hdr)) == -1) {
|
||||
+ log_warn("pfkey read");
|
||||
+ return (-1);
|
||||
+ }
|
||||
+
|
||||
+ return (1);
|
||||
+}
|
||||
+
|
||||
+int
|
||||
pfkey_reply(int sd, u_int32_t *spip)
|
||||
{
|
||||
struct sadb_msg hdr, *msg;
|
||||
@@ -418,27 +441,17 @@
|
||||
struct sadb_sa *sa;
|
||||
u_int8_t *data;
|
||||
ssize_t len;
|
||||
+ int rv;
|
||||
|
||||
- for (;;) {
|
||||
- if (recv(sd, &hdr, sizeof(hdr), MSG_PEEK) != sizeof(hdr)) {
|
||||
- log_warn("pfkey peek");
|
||||
- return (-1);
|
||||
- }
|
||||
-
|
||||
- if (hdr.sadb_msg_seq == sadb_msg_seq &&
|
||||
- hdr.sadb_msg_pid == pid)
|
||||
- break;
|
||||
-
|
||||
- /* not ours, discard */
|
||||
- if (read(sd, &hdr, sizeof(hdr)) == -1) {
|
||||
- log_warn("pfkey read");
|
||||
+ do {
|
||||
+ rv = pfkey_read(sd, &hdr);
|
||||
+ if (rv == -1)
|
||||
return (-1);
|
||||
- }
|
||||
- }
|
||||
+ } while (rv);
|
||||
|
||||
if (hdr.sadb_msg_errno != 0) {
|
||||
errno = hdr.sadb_msg_errno;
|
||||
- if (errno == ESRCH)
|
||||
+ if (errno == ESRCH || errno == EEXIST)
|
||||
return (0);
|
||||
else {
|
||||
log_warn("pfkey");
|
||||
@@ -486,13 +499,8 @@
|
||||
pfkey_sa_add(struct bgpd_addr *src, struct bgpd_addr *dst, u_int8_t keylen,
|
||||
char *key, u_int32_t *spi)
|
||||
{
|
||||
- if (pfkey_send(fd, SADB_X_SATYPE_TCPSIGNATURE, SADB_GETSPI, 0,
|
||||
- src, dst, 0, 0, 0, NULL, 0, 0, NULL, 0, 0) < 0)
|
||||
- return (-1);
|
||||
- if (pfkey_reply(fd, spi) < 0)
|
||||
- return (-1);
|
||||
- if (pfkey_send(fd, SADB_X_SATYPE_TCPSIGNATURE, SADB_UPDATE, 0,
|
||||
- src, dst, *spi, 0, keylen, key, 0, 0, NULL, 0, 0) < 0)
|
||||
+ if (pfkey_send(fd, SADB_X_SATYPE_TCPSIGNATURE, SADB_ADD, 0,
|
||||
+ src, dst, *spi, SADB_X_AALG_TCP_MD5, keylen, key, SADB_EALG_NONE, 0, NULL, 0, 0) < 0)
|
||||
return (-1);
|
||||
if (pfkey_reply(fd, NULL) < 0)
|
||||
return (-1);
|
||||
@@ -503,7 +511,7 @@
|
||||
pfkey_sa_remove(struct bgpd_addr *src, struct bgpd_addr *dst, u_int32_t *spi)
|
||||
{
|
||||
if (pfkey_send(fd, SADB_X_SATYPE_TCPSIGNATURE, SADB_DELETE, 0,
|
||||
- src, dst, *spi, 0, 0, NULL, 0, 0, NULL, 0, 0) < 0)
|
||||
+ src, dst, *spi, SADB_X_AALG_TCP_MD5, 0, NULL, 0, 0, NULL, 0, 0) < 0)
|
||||
return (-1);
|
||||
if (pfkey_reply(fd, NULL) < 0)
|
||||
return (-1);
|
||||
@@ -511,37 +519,37 @@
|
||||
return (0);
|
||||
}
|
||||
|
||||
+#define TCP_SIG_SPI 0x1000
|
||||
int
|
||||
pfkey_md5sig_establish(struct peer *p)
|
||||
{
|
||||
sleep(1);
|
||||
|
||||
- if (!p->auth.spi_out)
|
||||
- if (pfkey_sa_add(&p->auth.local_addr, &p->conf.remote_addr,
|
||||
- p->conf.auth.md5key_len, p->conf.auth.md5key,
|
||||
- &p->auth.spi_out) == -1)
|
||||
- return (-1);
|
||||
- if (!p->auth.spi_in)
|
||||
- if (pfkey_sa_add(&p->conf.remote_addr, &p->auth.local_addr,
|
||||
- p->conf.auth.md5key_len, p->conf.auth.md5key,
|
||||
- &p->auth.spi_in) == -1)
|
||||
- return (-1);
|
||||
+ p->auth.spi_out = htonl(TCP_SIG_SPI);
|
||||
+ if (pfkey_sa_add(&p->auth.local_addr, &p->conf.remote_addr,
|
||||
+ p->conf.auth.md5key_len, p->conf.auth.md5key,
|
||||
+ &p->auth.spi_out) == -1)
|
||||
+ return (-1);
|
||||
+ p->auth.spi_in = htonl(TCP_SIG_SPI);
|
||||
+ if (pfkey_sa_add(&p->conf.remote_addr, &p->auth.local_addr,
|
||||
+ p->conf.auth.md5key_len, p->conf.auth.md5key,
|
||||
+ &p->auth.spi_out) == -1)
|
||||
+ return (-1);
|
||||
|
||||
p->auth.established = 1;
|
||||
return (0);
|
||||
}
|
||||
+#undef TCP_SIG_SPI
|
||||
|
||||
int
|
||||
pfkey_md5sig_remove(struct peer *p)
|
||||
{
|
||||
- if (p->auth.spi_out)
|
||||
- if (pfkey_sa_remove(&p->auth.local_addr, &p->conf.remote_addr,
|
||||
- &p->auth.spi_out) == -1)
|
||||
- return (-1);
|
||||
- if (p->auth.spi_in)
|
||||
- if (pfkey_sa_remove(&p->conf.remote_addr, &p->auth.local_addr,
|
||||
- &p->auth.spi_in) == -1)
|
||||
- return (-1);
|
||||
+ if (pfkey_sa_remove(&p->auth.local_addr, &p->conf.remote_addr,
|
||||
+ &p->auth.spi_out) == -1)
|
||||
+ return (-1);
|
||||
+ if (pfkey_sa_remove(&p->conf.remote_addr, &p->auth.local_addr,
|
||||
+ &p->auth.spi_in) == -1)
|
||||
+ return (-1);
|
||||
|
||||
p->auth.established = 0;
|
||||
return (0);
|
||||
@@ -550,6 +558,7 @@
|
||||
int
|
||||
pfkey_ipsec_establish(struct peer *p)
|
||||
{
|
||||
+#if 0
|
||||
uint8_t satype = SADB_SATYPE_ESP;
|
||||
|
||||
switch (p->auth.method) {
|
||||
@@ -621,6 +630,9 @@
|
||||
|
||||
p->auth.established = 1;
|
||||
return (0);
|
||||
+#else
|
||||
+ return (-1);
|
||||
+#endif
|
||||
}
|
||||
|
||||
int
|
||||
@@ -660,6 +672,7 @@
|
||||
break;
|
||||
}
|
||||
|
||||
+#if 0
|
||||
if (pfkey_flow(fd, satype, SADB_X_DELFLOW, IPSP_DIRECTION_OUT,
|
||||
&p->auth.local_addr, &p->conf.remote_addr, 0, BGP_PORT) < 0)
|
||||
return (-1);
|
||||
@@ -681,6 +694,7 @@
|
||||
if (pfkey_flow(fd, satype, SADB_X_DELFLOW, IPSP_DIRECTION_IN,
|
||||
&p->conf.remote_addr, &p->auth.local_addr, BGP_PORT, 0) < 0)
|
||||
return (-1);
|
||||
+#endif
|
||||
if (pfkey_reply(fd, NULL) < 0)
|
||||
return (-1);
|
||||
|
||||
@@ -715,9 +729,7 @@
|
||||
int
|
||||
pfkey_remove(struct peer *p)
|
||||
{
|
||||
- if (!p->auth.established)
|
||||
- return (0);
|
||||
- else if (p->auth.method == AUTH_MD5SIG)
|
||||
+ if (p->auth.method == AUTH_MD5SIG)
|
||||
return (pfkey_md5sig_remove(p));
|
||||
else
|
||||
return (pfkey_ipsec_remove(p));
|
||||
@@ -730,11 +742,9 @@
|
||||
if (errno == EPROTONOSUPPORT) {
|
||||
log_warnx("PF_KEY not available, disabling ipsec");
|
||||
sysdep->no_pfkey = 1;
|
||||
- return (0);
|
||||
- } else {
|
||||
- log_warn("PF_KEY socket");
|
||||
return (-1);
|
||||
- }
|
||||
+ } else
|
||||
+ fatal("pfkey setup failed");
|
||||
}
|
||||
- return (0);
|
||||
+ return (fd);
|
||||
}
|
17
net/openbgpd/files/patch-bgpd_pftable.c
Normal file
17
net/openbgpd/files/patch-bgpd_pftable.c
Normal file
@ -0,0 +1,17 @@
|
||||
Index: bgpd/pftable.c
|
||||
===================================================================
|
||||
RCS file: /home/cvs/private/hrs/openbgpd/bgpd/pftable.c,v
|
||||
retrieving revision 1.1.1.5
|
||||
retrieving revision 1.1.1.7
|
||||
diff -u -p -r1.1.1.5 -r1.1.1.7
|
||||
--- bgpd/pftable.c 14 Feb 2010 20:19:57 -0000 1.1.1.5
|
||||
+++ bgpd/pftable.c 13 Oct 2012 18:22:44 -0000 1.1.1.7
|
||||
@@ -214,7 +214,7 @@ pftable_add_work(const char *table, stru
|
||||
|
||||
bzero(pfa, sizeof(*pfa));
|
||||
memcpy(&pfa->pfra_u, &addr->ba, (len + 7U) / 8);
|
||||
- pfa->pfra_af = addr->af;
|
||||
+ pfa->pfra_af = aid2af(addr->aid);
|
||||
pfa->pfra_net = len;
|
||||
|
||||
pft->naddrs++;
|
439
net/openbgpd/files/patch-bgpd_printconf.c
Normal file
439
net/openbgpd/files/patch-bgpd_printconf.c
Normal file
@ -0,0 +1,439 @@
|
||||
Index: bgpd/printconf.c
|
||||
===================================================================
|
||||
RCS file: /home/cvs/private/hrs/openbgpd/bgpd/printconf.c,v
|
||||
retrieving revision 1.1.1.7
|
||||
retrieving revision 1.11
|
||||
diff -u -p -r1.1.1.7 -r1.11
|
||||
--- bgpd/printconf.c 14 Feb 2010 20:19:57 -0000 1.1.1.7
|
||||
+++ bgpd/printconf.c 16 May 2014 00:36:26 -0000 1.11
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* $OpenBSD: printconf.c,v 1.70 2009/06/06 01:10:29 claudio Exp $ */
|
||||
+/* $OpenBSD: printconf.c,v 1.88 2012/09/23 09:39:18 claudio Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
|
||||
@@ -16,9 +16,13 @@
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
+#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
+#if defined(__FreeBSD__) /* limits.h */
|
||||
+#include <limits.h>
|
||||
+#endif
|
||||
|
||||
#include "bgpd.h"
|
||||
#include "mrt.h"
|
||||
@@ -27,14 +31,19 @@
|
||||
|
||||
void print_op(enum comp_ops);
|
||||
void print_community(int, int);
|
||||
+void print_extcommunity(struct filter_extcommunity *);
|
||||
+void print_origin(u_int8_t);
|
||||
void print_set(struct filter_set_head *);
|
||||
void print_mainconf(struct bgpd_config *);
|
||||
+void print_rdomain_targets(struct filter_set_head *, const char *);
|
||||
+void print_rdomain(struct rdomain *);
|
||||
+const char *print_af(u_int8_t);
|
||||
void print_network(struct network_config *);
|
||||
void print_peer(struct peer_config *, struct bgpd_config *,
|
||||
const char *);
|
||||
const char *print_auth_alg(u_int8_t);
|
||||
const char *print_enc_alg(u_int8_t);
|
||||
-const char *print_safi(u_int8_t);
|
||||
+void print_announce(struct peer_config *, const char *);
|
||||
void print_rule(struct peer *, struct filter_rule *);
|
||||
const char * mrt_type(enum mrt_type);
|
||||
void print_mrt(u_int32_t, u_int32_t, const char *, const char *);
|
||||
@@ -94,6 +103,45 @@ print_community(int as, int type)
|
||||
}
|
||||
|
||||
void
|
||||
+print_extcommunity(struct filter_extcommunity *c)
|
||||
+{
|
||||
+ switch (c->type & EXT_COMMUNITY_VALUE) {
|
||||
+ case EXT_COMMUNITY_TWO_AS:
|
||||
+ printf("%s %i:%i ", log_ext_subtype(c->subtype),
|
||||
+ c->data.ext_as.as, c->data.ext_as.val);
|
||||
+ break;
|
||||
+ case EXT_COMMUNITY_IPV4:
|
||||
+ printf("%s %s:%i ", log_ext_subtype(c->subtype),
|
||||
+ inet_ntoa(c->data.ext_ip.addr), c->data.ext_ip.val);
|
||||
+ break;
|
||||
+ case EXT_COMMUNITY_FOUR_AS:
|
||||
+ printf("%s %s:%i ", log_ext_subtype(c->subtype),
|
||||
+ log_as(c->data.ext_as4.as4), c->data.ext_as.val);
|
||||
+ break;
|
||||
+ case EXT_COMMUNITY_OPAQUE:
|
||||
+ printf("%s 0x%llx ", log_ext_subtype(c->subtype),
|
||||
+ (long long unsigned int)c->data.ext_opaq);
|
||||
+ break;
|
||||
+ default:
|
||||
+ printf("0x%x 0x%llx ", c->type, (long long unsigned int)c->data.ext_opaq);
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+print_origin(u_int8_t o)
|
||||
+{
|
||||
+ if (o == ORIGIN_IGP)
|
||||
+ printf("igp ");
|
||||
+ else if (o == ORIGIN_EGP)
|
||||
+ printf("egp ");
|
||||
+ else if (o == ORIGIN_INCOMPLETE)
|
||||
+ printf("incomplete ");
|
||||
+ else
|
||||
+ printf("%u ", o);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
print_set(struct filter_set_head *set)
|
||||
{
|
||||
struct filter_set *s;
|
||||
@@ -161,11 +209,23 @@ print_set(struct filter_set_head *set)
|
||||
case ACTION_RTLABEL:
|
||||
printf("rtlabel %s ", s->action.rtlabel);
|
||||
break;
|
||||
+ case ACTION_SET_ORIGIN:
|
||||
+ printf("origin ");
|
||||
+ print_origin(s->action.origin);
|
||||
+ break;
|
||||
case ACTION_RTLABEL_ID:
|
||||
case ACTION_PFTABLE_ID:
|
||||
/* not possible */
|
||||
printf("king bula saiz: config broken");
|
||||
break;
|
||||
+ case ACTION_SET_EXT_COMMUNITY:
|
||||
+ printf("ext-community ");
|
||||
+ print_extcommunity(&s->action.ext_community);
|
||||
+ break;
|
||||
+ case ACTION_DEL_EXT_COMMUNITY:
|
||||
+ printf("ext-community delete ");
|
||||
+ print_extcommunity(&s->action.ext_community);
|
||||
+ break;
|
||||
}
|
||||
}
|
||||
printf("}");
|
||||
@@ -182,6 +242,10 @@ print_mainconf(struct bgpd_config *conf)
|
||||
printf(" %u", conf->short_as);
|
||||
ina.s_addr = conf->bgpid;
|
||||
printf("\nrouter-id %s\n", inet_ntoa(ina));
|
||||
+
|
||||
+ printf("socket \"%s\"\n", conf->csock);
|
||||
+ if (conf->rcsock)
|
||||
+ printf("socket \"%s\" restricted\n", conf->rcsock);
|
||||
if (conf->holdtime)
|
||||
printf("holdtime %u\n", conf->holdtime);
|
||||
if (conf->min_holdtime)
|
||||
@@ -189,11 +253,6 @@ print_mainconf(struct bgpd_config *conf)
|
||||
if (conf->connectretry)
|
||||
printf("connect-retry %u\n", conf->connectretry);
|
||||
|
||||
- if (conf->flags & BGPD_FLAG_NO_FIB_UPDATE)
|
||||
- printf("fib-update no\n");
|
||||
- else
|
||||
- printf("fib-update yes\n");
|
||||
-
|
||||
if (conf->flags & BGPD_FLAG_NO_EVALUATE)
|
||||
printf("route-collector yes\n");
|
||||
|
||||
@@ -214,43 +273,67 @@ print_mainconf(struct bgpd_config *conf)
|
||||
printf("nexthop qualify via bgp\n");
|
||||
if (conf->flags & BGPD_FLAG_NEXTHOP_DEFAULT)
|
||||
printf("nexthop qualify via default\n");
|
||||
+}
|
||||
|
||||
- if (conf->flags & BGPD_FLAG_REDIST_CONNECTED) {
|
||||
- printf("network inet connected");
|
||||
- if (!TAILQ_EMPTY(&conf->connectset))
|
||||
- printf(" ");
|
||||
- print_set(&conf->connectset);
|
||||
- printf("\n");
|
||||
- }
|
||||
- if (conf->flags & BGPD_FLAG_REDIST_STATIC) {
|
||||
- printf("network inet static");
|
||||
- if (!TAILQ_EMPTY(&conf->staticset))
|
||||
- printf(" ");
|
||||
- print_set(&conf->staticset);
|
||||
- printf("\n");
|
||||
- }
|
||||
- if (conf->flags & BGPD_FLAG_REDIST6_CONNECTED) {
|
||||
- printf("network inet6 connected");
|
||||
- if (!TAILQ_EMPTY(&conf->connectset6))
|
||||
- printf(" ");
|
||||
- print_set(&conf->connectset6);
|
||||
- printf("\n");
|
||||
- }
|
||||
- if (conf->flags & BGPD_FLAG_REDIST_STATIC) {
|
||||
- printf("network inet6 static");
|
||||
- if (!TAILQ_EMPTY(&conf->staticset6))
|
||||
- printf(" ");
|
||||
- print_set(&conf->staticset6);
|
||||
+void
|
||||
+print_rdomain_targets(struct filter_set_head *set, const char *tgt)
|
||||
+{
|
||||
+ struct filter_set *s;
|
||||
+ TAILQ_FOREACH(s, set, entry) {
|
||||
+ printf("\t%s ", tgt);
|
||||
+ print_extcommunity(&s->action.ext_community);
|
||||
printf("\n");
|
||||
}
|
||||
- if (conf->rtableid)
|
||||
- printf("rtable %u\n", conf->rtableid);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+print_rdomain(struct rdomain *r)
|
||||
+{
|
||||
+ printf("rdomain %u {\n", r->rtableid);
|
||||
+ printf("\tdescr \"%s\"\n", r->descr);
|
||||
+ if (r->flags & F_RIB_NOFIBSYNC)
|
||||
+ printf("\tfib-update no\n");
|
||||
+ else
|
||||
+ printf("\tfib-update yes\n");
|
||||
+ printf("\tdepend on %s\n", r->ifmpe);
|
||||
+
|
||||
+ printf("\n\t%s\n", log_rd(r->rd));
|
||||
+
|
||||
+ print_rdomain_targets(&r->export, "export-target");
|
||||
+ print_rdomain_targets(&r->import, "import-target");
|
||||
+
|
||||
+ printf("}\n");
|
||||
+}
|
||||
+
|
||||
+const char *
|
||||
+print_af(u_int8_t aid)
|
||||
+{
|
||||
+ /*
|
||||
+ * Hack around the fact that aid2str() will return "IPv4 unicast"
|
||||
+ * for AID_INET. AID_INET and AID_INET6 need special handling and
|
||||
+ * the other AID should never end up here (at least for now).
|
||||
+ */
|
||||
+ if (aid == AID_INET)
|
||||
+ return ("inet");
|
||||
+ if (aid == AID_INET6)
|
||||
+ return ("inet6");
|
||||
+ return (aid2str(aid));
|
||||
}
|
||||
|
||||
void
|
||||
print_network(struct network_config *n)
|
||||
{
|
||||
- printf("network %s/%u", log_addr(&n->prefix), n->prefixlen);
|
||||
+ switch (n->type) {
|
||||
+ case NETWORK_STATIC:
|
||||
+ printf("network %s static", print_af(n->prefix.aid));
|
||||
+ break;
|
||||
+ case NETWORK_CONNECTED:
|
||||
+ printf("network %s connected", print_af(n->prefix.aid));
|
||||
+ break;
|
||||
+ default:
|
||||
+ printf("network %s/%u", log_addr(&n->prefix), n->prefixlen);
|
||||
+ break;
|
||||
+ }
|
||||
if (!TAILQ_EMPTY(&n->attrset))
|
||||
printf(" ");
|
||||
print_set(&n->attrset);
|
||||
@@ -263,8 +346,8 @@ print_peer(struct peer_config *p, struct
|
||||
char *method;
|
||||
struct in_addr ina;
|
||||
|
||||
- if ((p->remote_addr.af == AF_INET && p->remote_masklen != 32) ||
|
||||
- (p->remote_addr.af == AF_INET6 && p->remote_masklen != 128))
|
||||
+ if ((p->remote_addr.aid == AID_INET && p->remote_masklen != 32) ||
|
||||
+ (p->remote_addr.aid == AID_INET6 && p->remote_masklen != 128))
|
||||
printf("%sneighbor %s/%u {\n", c, log_addr(&p->remote_addr),
|
||||
p->remote_masklen);
|
||||
else
|
||||
@@ -281,7 +364,7 @@ print_peer(struct peer_config *p, struct
|
||||
printf("%s\tmultihop %u\n", c, p->distance);
|
||||
if (p->passive)
|
||||
printf("%s\tpassive\n", c);
|
||||
- if (p->local_addr.af)
|
||||
+ if (p->local_addr.aid)
|
||||
printf("%s\tlocal-address %s\n", c, log_addr(&p->local_addr));
|
||||
if (p->max_prefix) {
|
||||
printf("%s\tmax-prefix %u", c, p->max_prefix);
|
||||
@@ -295,6 +378,12 @@ print_peer(struct peer_config *p, struct
|
||||
printf("%s\tholdtime min %u\n", c, p->min_holdtime);
|
||||
if (p->announce_capa == 0)
|
||||
printf("%s\tannounce capabilities no\n", c);
|
||||
+ if (p->capabilities.refresh == 0)
|
||||
+ printf("%s\tannounce refresh no\n", c);
|
||||
+ if (p->capabilities.grestart.restart == 0)
|
||||
+ printf("%s\tannounce restart no\n", c);
|
||||
+ if (p->capabilities.as4byte == 0)
|
||||
+ printf("%s\tannounce as4byte no\n", c);
|
||||
if (p->announce_type == ANNOUNCE_SELF)
|
||||
printf("%s\tannounce self\n", c);
|
||||
else if (p->announce_type == ANNOUNCE_NONE)
|
||||
@@ -324,6 +413,10 @@ print_peer(struct peer_config *p, struct
|
||||
printf("%s\tdepend on \"%s\"\n", c, p->if_depend);
|
||||
if (p->flags & PEERFLAG_TRANS_AS)
|
||||
printf("%s\ttransparent-as yes\n", c);
|
||||
+#if defined(IPV6_LINKLOCAL_PEER)
|
||||
+ if (p->lliface[0])
|
||||
+ printf("%s\tinterface %s\n", c, p->lliface);
|
||||
+#endif
|
||||
|
||||
if (p->auth.method == AUTH_MD5SIG)
|
||||
printf("%s\ttcp md5sig\n", c);
|
||||
@@ -354,8 +447,7 @@ print_peer(struct peer_config *p, struct
|
||||
if (p->ttlsec)
|
||||
printf("%s\tttl-security yes\n", c);
|
||||
|
||||
- printf("%s\tannounce IPv4 %s\n", c, print_safi(p->capabilities.mp_v4));
|
||||
- printf("%s\tannounce IPv6 %s\n", c, print_safi(p->capabilities.mp_v6));
|
||||
+ print_announce(p, c);
|
||||
|
||||
if (p->softreconfig_in == 1)
|
||||
printf("%s\tsoftreconfig in yes\n", c);
|
||||
@@ -399,17 +491,14 @@ print_enc_alg(u_int8_t alg)
|
||||
}
|
||||
}
|
||||
|
||||
-const char *
|
||||
-print_safi(u_int8_t safi)
|
||||
+void
|
||||
+print_announce(struct peer_config *p, const char *c)
|
||||
{
|
||||
- switch (safi) {
|
||||
- case SAFI_NONE:
|
||||
- return ("none");
|
||||
- case SAFI_UNICAST:
|
||||
- return ("unicast");
|
||||
- default:
|
||||
- return ("?");
|
||||
- }
|
||||
+ u_int8_t aid;
|
||||
+
|
||||
+ for (aid = 0; aid < AID_MAX; aid++)
|
||||
+ if (p->capabilities.mp[aid])
|
||||
+ printf("%s\tannounce %s\n", c, aid2str(aid));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -455,14 +544,14 @@ print_rule(struct peer *peer_l, struct f
|
||||
} else
|
||||
printf("any ");
|
||||
|
||||
- if (r->match.prefix.addr.af)
|
||||
+ if (r->match.prefix.addr.aid)
|
||||
printf("prefix %s/%u ", log_addr(&r->match.prefix.addr),
|
||||
r->match.prefix.len);
|
||||
|
||||
- if (r->match.prefix.addr.af == 0 && r->match.prefixlen.af) {
|
||||
- if (r->match.prefixlen.af == AF_INET)
|
||||
+ if (r->match.prefix.addr.aid == 0 && r->match.prefixlen.aid) {
|
||||
+ if (r->match.prefixlen.aid == AID_INET)
|
||||
printf("inet ");
|
||||
- if (r->match.prefixlen.af == AF_INET6)
|
||||
+ if (r->match.prefixlen.aid == AID_INET6)
|
||||
printf("inet6 ");
|
||||
}
|
||||
|
||||
@@ -479,6 +568,13 @@ print_rule(struct peer *peer_l, struct f
|
||||
}
|
||||
}
|
||||
|
||||
+ if (r->match.nexthop.flags) {
|
||||
+ if (r->match.nexthop.flags == FILTER_NEXTHOP_NEIGHBOR)
|
||||
+ printf("nexthop neighbor ");
|
||||
+ else
|
||||
+ printf("nexthop %s ", log_addr(&r->match.nexthop.addr));
|
||||
+ }
|
||||
+
|
||||
if (r->match.as.type) {
|
||||
if (r->match.as.type == AS_ALL)
|
||||
printf("AS %s ", log_as(r->match.as.as));
|
||||
@@ -492,11 +588,20 @@ print_rule(struct peer *peer_l, struct f
|
||||
printf("unfluffy-as %s ", log_as(r->match.as.as));
|
||||
}
|
||||
|
||||
+ if (r->match.aslen.type) {
|
||||
+ printf("%s %u ", r->match.aslen.type == ASLEN_MAX ?
|
||||
+ "max-as-len" : "max-as-seq", r->match.aslen.aslen);
|
||||
+ }
|
||||
+
|
||||
if (r->match.community.as != COMMUNITY_UNSET) {
|
||||
printf("community ");
|
||||
print_community(r->match.community.as,
|
||||
r->match.community.type);
|
||||
}
|
||||
+ if (r->match.ext_community.flags & EXT_COMMUNITY_FLAG_VALID) {
|
||||
+ printf("ext-community ");
|
||||
+ print_extcommunity(&r->match.ext_community);
|
||||
+ }
|
||||
|
||||
print_set(&r->set);
|
||||
|
||||
@@ -513,6 +618,8 @@ mrt_type(enum mrt_type t)
|
||||
return "table";
|
||||
case MRT_TABLE_DUMP_MP:
|
||||
return "table-mp";
|
||||
+ case MRT_TABLE_DUMP_V2:
|
||||
+ return "table-v2";
|
||||
case MRT_ALL_IN:
|
||||
return "all in";
|
||||
case MRT_ALL_OUT:
|
||||
@@ -541,12 +648,12 @@ print_mrt(u_int32_t pid, u_int32_t gid,
|
||||
printf("%s%sdump ", prep, prep2);
|
||||
if (m->rib[0])
|
||||
printf("rib %s ", m->rib);
|
||||
+ printf("%s \"%s\"", mrt_type(m->type),
|
||||
+ MRT2MC(m)->name);
|
||||
if (MRT2MC(m)->ReopenTimerInterval == 0)
|
||||
- printf("%s %s\n", mrt_type(m->type),
|
||||
- MRT2MC(m)->name);
|
||||
+ printf("\n");
|
||||
else
|
||||
- printf("%s %s %d\n", mrt_type(m->type),
|
||||
- MRT2MC(m)->name,
|
||||
+ printf(" %ld\n",
|
||||
MRT2MC(m)->ReopenTimerInterval);
|
||||
}
|
||||
}
|
||||
@@ -612,26 +719,34 @@ peer_compare(const void *aa, const void
|
||||
void
|
||||
print_config(struct bgpd_config *conf, struct rib_names *rib_l,
|
||||
struct network_head *net_l, struct peer *peer_l,
|
||||
- struct filter_head *rules_l, struct mrt_head *mrt_l)
|
||||
+ struct filter_head *rules_l, struct mrt_head *mrt_l,
|
||||
+ struct rdomain_head *rdom_l)
|
||||
{
|
||||
struct filter_rule *r;
|
||||
struct network *n;
|
||||
struct rde_rib *rr;
|
||||
+ struct rdomain *rd;
|
||||
|
||||
xmrt_l = mrt_l;
|
||||
- printf("\n");
|
||||
print_mainconf(conf);
|
||||
printf("\n");
|
||||
+ TAILQ_FOREACH(n, net_l, entry)
|
||||
+ print_network(&n->net);
|
||||
+ printf("\n");
|
||||
+ SIMPLEQ_FOREACH(rd, rdom_l, entry)
|
||||
+ print_rdomain(rd);
|
||||
+ printf("\n");
|
||||
SIMPLEQ_FOREACH(rr, rib_l, entry) {
|
||||
if (rr->flags & F_RIB_NOEVALUATE)
|
||||
printf("rde rib %s no evaluate\n", rr->name);
|
||||
- else
|
||||
+ else if (rr->flags & F_RIB_NOFIB)
|
||||
printf("rde rib %s\n", rr->name);
|
||||
+ else
|
||||
+ printf("rde rib %s rtable %u fib-update %s\n", rr->name,
|
||||
+ rr->rtableid, rr->flags & F_RIB_NOFIBSYNC ?
|
||||
+ "no" : "yes");
|
||||
}
|
||||
printf("\n");
|
||||
- TAILQ_FOREACH(n, net_l, entry)
|
||||
- print_network(&n->net);
|
||||
- printf("\n");
|
||||
print_mrt(0, 0, "", "");
|
||||
printf("\n");
|
||||
print_groups(conf, peer_l);
|
2614
net/openbgpd/files/patch-bgpd_rde.c
Normal file
2614
net/openbgpd/files/patch-bgpd_rde.c
Normal file
File diff suppressed because it is too large
Load Diff
361
net/openbgpd/files/patch-bgpd_rde.h
Normal file
361
net/openbgpd/files/patch-bgpd_rde.h
Normal file
@ -0,0 +1,361 @@
|
||||
Index: bgpd/rde.h
|
||||
===================================================================
|
||||
RCS file: /home/cvs/private/hrs/openbgpd/bgpd/rde.h,v
|
||||
retrieving revision 1.1.1.8
|
||||
retrieving revision 1.1.1.13
|
||||
diff -u -p -r1.1.1.8 -r1.1.1.13
|
||||
--- bgpd/rde.h 14 Feb 2010 20:19:57 -0000 1.1.1.8
|
||||
+++ bgpd/rde.h 8 Dec 2012 10:37:09 -0000 1.1.1.13
|
||||
@@ -1,8 +1,8 @@
|
||||
-/* $OpenBSD: rde.h,v 1.120 2009/06/06 01:10:29 claudio Exp $ */
|
||||
+/* $OpenBSD: rde.h,v 1.144 2012/09/12 05:56:22 claudio Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org> and
|
||||
- * Andre Oppermann <oppermann@pipeline.ch>
|
||||
+ * Andre Oppermann <oppermann@networx.ch>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@@ -56,16 +56,16 @@ struct rde_peer {
|
||||
struct bgpd_addr local_v6_addr;
|
||||
struct uptree_prefix up_prefix;
|
||||
struct uptree_attr up_attrs;
|
||||
- struct uplist_attr updates;
|
||||
- struct uplist_prefix withdraws;
|
||||
- struct uplist_attr updates6;
|
||||
- struct uplist_prefix withdraws6;
|
||||
- struct capabilities capa_announced;
|
||||
- struct capabilities capa_received;
|
||||
+ struct uplist_attr updates[AID_MAX];
|
||||
+ struct uplist_prefix withdraws[AID_MAX];
|
||||
+ struct capabilities capa;
|
||||
+ time_t staletime[AID_MAX];
|
||||
u_int64_t prefix_rcvd_update;
|
||||
u_int64_t prefix_rcvd_withdraw;
|
||||
+ u_int64_t prefix_rcvd_eor;
|
||||
u_int64_t prefix_sent_update;
|
||||
u_int64_t prefix_sent_withdraw;
|
||||
+ u_int64_t prefix_sent_eor;
|
||||
u_int32_t prefix_cnt; /* # of prefixes */
|
||||
u_int32_t remote_bgpid; /* host byte order! */
|
||||
u_int32_t up_pcnt;
|
||||
@@ -75,12 +75,16 @@ struct rde_peer {
|
||||
enum peer_state state;
|
||||
u_int16_t ribid;
|
||||
u_int16_t short_as;
|
||||
+ u_int16_t mrt_idx;
|
||||
u_int8_t reconf_in; /* in filter changed */
|
||||
u_int8_t reconf_out; /* out filter changed */
|
||||
+ u_int8_t reconf_rib; /* rib changed */
|
||||
};
|
||||
|
||||
#define AS_SET 1
|
||||
#define AS_SEQUENCE 2
|
||||
+#define AS_CONFED_SEQUENCE 3
|
||||
+#define AS_CONFED_SET 4
|
||||
#define ASPATH_HEADER_SIZE (sizeof(struct aspath) - sizeof(u_char))
|
||||
|
||||
LIST_HEAD(aspath_list, aspath);
|
||||
@@ -117,6 +121,9 @@ enum attrtypes {
|
||||
#define ATTR_PARTIAL 0x20
|
||||
#define ATTR_TRANSITIVE 0x40
|
||||
#define ATTR_OPTIONAL 0x80
|
||||
+#define ATTR_RESERVED 0x0f
|
||||
+/* by default mask the reserved bits and the ext len bit */
|
||||
+#define ATTR_DEFMASK (ATTR_RESERVED | ATTR_EXTLEN)
|
||||
|
||||
/* default attribute flags for well known attributes */
|
||||
#define ATTR_WELL_KNOWN ATTR_TRANSITIVE
|
||||
@@ -163,6 +170,8 @@ LIST_HEAD(prefix_head, prefix);
|
||||
#define F_NEXTHOP_REJECT 0x02000
|
||||
#define F_NEXTHOP_BLACKHOLE 0x04000
|
||||
#define F_NEXTHOP_NOMODIFY 0x08000
|
||||
+#define F_NEXTHOP_MASK 0x0f000
|
||||
+#define F_ATTR_PARSE_ERR 0x10000
|
||||
#define F_ATTR_LINKED 0x20000
|
||||
|
||||
|
||||
@@ -220,14 +229,14 @@ struct nexthop {
|
||||
/* generic entry without address specific part */
|
||||
struct pt_entry {
|
||||
RB_ENTRY(pt_entry) pt_e;
|
||||
- sa_family_t af;
|
||||
+ u_int8_t aid;
|
||||
u_int8_t prefixlen;
|
||||
u_int16_t refcnt;
|
||||
};
|
||||
|
||||
struct pt_entry4 {
|
||||
RB_ENTRY(pt_entry) pt_e;
|
||||
- sa_family_t af;
|
||||
+ u_int8_t aid;
|
||||
u_int8_t prefixlen;
|
||||
u_int16_t refcnt;
|
||||
struct in_addr prefix4;
|
||||
@@ -235,12 +244,25 @@ struct pt_entry4 {
|
||||
|
||||
struct pt_entry6 {
|
||||
RB_ENTRY(pt_entry) pt_e;
|
||||
- sa_family_t af;
|
||||
+ u_int8_t aid;
|
||||
u_int8_t prefixlen;
|
||||
u_int16_t refcnt;
|
||||
struct in6_addr prefix6;
|
||||
};
|
||||
|
||||
+struct pt_entry_vpn4 {
|
||||
+ RB_ENTRY(pt_entry) pt_e;
|
||||
+ u_int8_t aid;
|
||||
+ u_int8_t prefixlen;
|
||||
+ u_int16_t refcnt;
|
||||
+ struct in_addr prefix4;
|
||||
+ u_int64_t rd;
|
||||
+ u_int8_t labelstack[21];
|
||||
+ u_int8_t labellen;
|
||||
+ u_int8_t pad1;
|
||||
+ u_int8_t pad2;
|
||||
+};
|
||||
+
|
||||
struct rib_context {
|
||||
LIST_ENTRY(rib_context) entry;
|
||||
struct rib_entry *ctx_re;
|
||||
@@ -250,7 +272,7 @@ struct rib_context {
|
||||
void (*ctx_wait)(void *);
|
||||
void *ctx_arg;
|
||||
unsigned int ctx_count;
|
||||
- sa_family_t ctx_af;
|
||||
+ u_int8_t ctx_aid;
|
||||
};
|
||||
|
||||
struct rib_entry {
|
||||
@@ -262,23 +284,15 @@ struct rib_entry {
|
||||
u_int16_t flags;
|
||||
};
|
||||
|
||||
-enum rib_state {
|
||||
- RIB_NONE,
|
||||
- RIB_ACTIVE,
|
||||
- RIB_DELETE
|
||||
-};
|
||||
-
|
||||
struct rib {
|
||||
char name[PEER_DESCR_LEN];
|
||||
struct rib_tree rib;
|
||||
- enum rib_state state;
|
||||
+ u_int rtableid;
|
||||
u_int16_t flags;
|
||||
u_int16_t id;
|
||||
+ enum reconf_action state;
|
||||
};
|
||||
|
||||
-#define F_RIB_ENTRYLOCK 0x0001
|
||||
-#define F_RIB_NOEVALUATE 0x0002
|
||||
-#define F_RIB_NOFIB 0x0004
|
||||
#define RIB_FAILED 0xffff
|
||||
|
||||
struct prefix {
|
||||
@@ -292,8 +306,14 @@ struct prefix {
|
||||
extern struct rde_memstats rdemem;
|
||||
|
||||
/* prototypes */
|
||||
+/* mrt.c */
|
||||
+int mrt_dump_v2_hdr(struct mrt *, struct bgpd_config *,
|
||||
+ struct rde_peer_head *);
|
||||
+void mrt_dump_upcall(struct rib_entry *, void *);
|
||||
+void mrt_done(void *);
|
||||
+
|
||||
/* rde.c */
|
||||
-void rde_send_kroute(struct prefix *, struct prefix *);
|
||||
+void rde_send_kroute(struct prefix *, struct prefix *, u_int16_t);
|
||||
void rde_send_nexthop(struct bgpd_addr *, int);
|
||||
void rde_send_pftable(u_int16_t, struct bgpd_addr *,
|
||||
u_int8_t, int);
|
||||
@@ -309,7 +329,7 @@ int rde_as4byte(struct rde_peer *);
|
||||
/* rde_attr.c */
|
||||
int attr_write(void *, u_int16_t, u_int8_t, u_int8_t, void *,
|
||||
u_int16_t);
|
||||
-int attr_writebuf(struct buf *, u_int8_t, u_int8_t, void *,
|
||||
+int attr_writebuf(struct ibuf *, u_int8_t, u_int8_t, void *,
|
||||
u_int16_t);
|
||||
void attr_init(u_int32_t);
|
||||
void attr_shutdown(void);
|
||||
@@ -327,6 +347,7 @@ int aspath_verify(void *, u_int16_t, i
|
||||
#define AS_ERR_LEN -1
|
||||
#define AS_ERR_TYPE -2
|
||||
#define AS_ERR_BAD -3
|
||||
+#define AS_ERR_SOFT -4
|
||||
void aspath_init(u_int32_t);
|
||||
void aspath_shutdown(void);
|
||||
struct aspath *aspath_get(void *, u_int16_t);
|
||||
@@ -341,22 +362,66 @@ u_int32_t aspath_neighbor(struct aspath
|
||||
int aspath_loopfree(struct aspath *, u_int32_t);
|
||||
int aspath_compare(struct aspath *, struct aspath *);
|
||||
u_char *aspath_prepend(struct aspath *, u_int32_t, int, u_int16_t *);
|
||||
-int aspath_match(struct aspath *, enum as_spec, u_int32_t);
|
||||
-int community_match(void *, u_int16_t, int, int);
|
||||
+int aspath_lenmatch(struct aspath *, enum aslen_spec, u_int);
|
||||
+int community_match(struct rde_aspath *, int, int);
|
||||
int community_set(struct rde_aspath *, int, int);
|
||||
void community_delete(struct rde_aspath *, int, int);
|
||||
+int community_ext_match(struct rde_aspath *,
|
||||
+ struct filter_extcommunity *, u_int16_t);
|
||||
+int community_ext_set(struct rde_aspath *,
|
||||
+ struct filter_extcommunity *, u_int16_t);
|
||||
+void community_ext_delete(struct rde_aspath *,
|
||||
+ struct filter_extcommunity *, u_int16_t);
|
||||
+int community_ext_conv(struct filter_extcommunity *, u_int16_t,
|
||||
+ u_int64_t *);
|
||||
+
|
||||
+/* rde_decide.c */
|
||||
+void prefix_evaluate(struct prefix *, struct rib_entry *);
|
||||
+
|
||||
+/* rde_filter.c */
|
||||
+enum filter_actions rde_filter(u_int16_t, struct rde_aspath **,
|
||||
+ struct filter_head *, struct rde_peer *,
|
||||
+ struct rde_aspath *, struct bgpd_addr *, u_int8_t,
|
||||
+ struct rde_peer *, enum directions);
|
||||
+void rde_apply_set(struct rde_aspath *, struct filter_set_head *,
|
||||
+ u_int8_t, struct rde_peer *, struct rde_peer *);
|
||||
+int rde_filter_equal(struct filter_head *, struct filter_head *,
|
||||
+ struct rde_peer *, enum directions);
|
||||
+
|
||||
+/* rde_prefix.c */
|
||||
+#define pt_empty(pt) ((pt)->refcnt == 0)
|
||||
+#define pt_ref(pt) do { \
|
||||
+ ++(pt)->refcnt; \
|
||||
+ if ((pt)->refcnt == 0) \
|
||||
+ fatalx("pt_ref: overflow"); \
|
||||
+} while(0)
|
||||
+#define pt_unref(pt) do { \
|
||||
+ if ((pt)->refcnt == 0) \
|
||||
+ fatalx("pt_unref: underflow"); \
|
||||
+ --(pt)->refcnt; \
|
||||
+} while(0)
|
||||
+
|
||||
+void pt_init(void);
|
||||
+void pt_shutdown(void);
|
||||
+void pt_getaddr(struct pt_entry *, struct bgpd_addr *);
|
||||
+struct pt_entry *pt_fill(struct bgpd_addr *, int);
|
||||
+struct pt_entry *pt_get(struct bgpd_addr *, int);
|
||||
+struct pt_entry *pt_add(struct bgpd_addr *, int);
|
||||
+void pt_remove(struct pt_entry *);
|
||||
+struct pt_entry *pt_lookup(struct bgpd_addr *);
|
||||
+int pt_prefix_cmp(const struct pt_entry *, const struct pt_entry *);
|
||||
|
||||
/* rde_rib.c */
|
||||
extern u_int16_t rib_size;
|
||||
extern struct rib *ribs;
|
||||
|
||||
-u_int16_t rib_new(int, char *, u_int16_t);
|
||||
+u_int16_t rib_new(char *, u_int, u_int16_t);
|
||||
u_int16_t rib_find(char *);
|
||||
void rib_free(struct rib *);
|
||||
struct rib_entry *rib_get(struct rib *, struct bgpd_addr *, int);
|
||||
struct rib_entry *rib_lookup(struct rib *, struct bgpd_addr *);
|
||||
void rib_dump(struct rib *, void (*)(struct rib_entry *, void *),
|
||||
- void *, sa_family_t);
|
||||
+ void *, u_int8_t);
|
||||
void rib_dump_r(struct rib_context *);
|
||||
void rib_dump_runner(void);
|
||||
int rib_dump_pending(void);
|
||||
@@ -368,6 +433,7 @@ int path_update(struct rib *, struct r
|
||||
int path_compare(struct rde_aspath *, struct rde_aspath *);
|
||||
struct rde_aspath *path_lookup(struct rde_aspath *, struct rde_peer *);
|
||||
void path_remove(struct rde_aspath *);
|
||||
+void path_remove_stale(struct rde_aspath *, u_int8_t);
|
||||
void path_destroy(struct rde_aspath *);
|
||||
int path_empty(struct rde_aspath *);
|
||||
struct rde_aspath *path_copy(struct rde_aspath *);
|
||||
@@ -375,8 +441,6 @@ struct rde_aspath *path_get(void);
|
||||
void path_put(struct rde_aspath *);
|
||||
|
||||
#define PREFIX_SIZE(x) (((x) + 7) / 8 + 1)
|
||||
-int prefix_compare(const struct bgpd_addr *,
|
||||
- const struct bgpd_addr *, int);
|
||||
struct prefix *prefix_get(struct rib *, struct rde_peer *,
|
||||
struct bgpd_addr *, int, u_int32_t);
|
||||
int prefix_add(struct rib *, struct rde_aspath *,
|
||||
@@ -385,6 +449,7 @@ void prefix_move(struct rde_aspath *,
|
||||
int prefix_remove(struct rib *, struct rde_peer *,
|
||||
struct bgpd_addr *, int, u_int32_t);
|
||||
int prefix_write(u_char *, int, struct bgpd_addr *, u_int8_t);
|
||||
+int prefix_writebuf(struct ibuf *, struct bgpd_addr *, u_int8_t);
|
||||
struct prefix *prefix_bypeer(struct rib_entry *, struct rde_peer *,
|
||||
u_int32_t);
|
||||
void prefix_updateall(struct rde_aspath *, enum nexthop_state,
|
||||
@@ -395,7 +460,7 @@ void prefix_network_clean(struct rde_p
|
||||
void nexthop_init(u_int32_t);
|
||||
void nexthop_shutdown(void);
|
||||
void nexthop_modify(struct rde_aspath *, struct bgpd_addr *,
|
||||
- enum action_types, sa_family_t);
|
||||
+ enum action_types, u_int8_t);
|
||||
void nexthop_link(struct rde_aspath *);
|
||||
void nexthop_unlink(struct rde_aspath *);
|
||||
int nexthop_delete(struct nexthop *);
|
||||
@@ -403,9 +468,6 @@ void nexthop_update(struct kroute_next
|
||||
struct nexthop *nexthop_get(struct bgpd_addr *);
|
||||
int nexthop_compare(struct nexthop *, struct nexthop *);
|
||||
|
||||
-/* rde_decide.c */
|
||||
-void prefix_evaluate(struct prefix *, struct rib_entry *);
|
||||
-
|
||||
/* rde_update.c */
|
||||
void up_init(struct rde_peer *);
|
||||
void up_down(struct rde_peer *);
|
||||
@@ -415,49 +477,14 @@ int up_generate(struct rde_peer *, str
|
||||
void up_generate_updates(struct filter_head *, struct rde_peer *,
|
||||
struct prefix *, struct prefix *);
|
||||
void up_generate_default(struct filter_head *, struct rde_peer *,
|
||||
- sa_family_t);
|
||||
+ u_int8_t);
|
||||
+int up_generate_marker(struct rde_peer *, u_int8_t);
|
||||
int up_dump_prefix(u_char *, int, struct uplist_prefix *,
|
||||
struct rde_peer *);
|
||||
int up_dump_attrnlri(u_char *, int, struct rde_peer *);
|
||||
-u_char *up_dump_mp_unreach(u_char *, u_int16_t *, struct rde_peer *);
|
||||
-u_char *up_dump_mp_reach(u_char *, u_int16_t *, struct rde_peer *);
|
||||
-
|
||||
-/* rde_prefix.c */
|
||||
-#define pt_empty(pt) ((pt)->refcnt == 0)
|
||||
-#define pt_ref(pt) do { \
|
||||
- ++(pt)->refcnt; \
|
||||
- if ((pt)->refcnt == 0) \
|
||||
- fatalx("pt_ref: overflow"); \
|
||||
-} while(0)
|
||||
-#define pt_unref(pt) do { \
|
||||
- if ((pt)->refcnt == 0) \
|
||||
- fatalx("pt_unref: underflow"); \
|
||||
- --(pt)->refcnt; \
|
||||
-} while(0)
|
||||
-
|
||||
-void pt_init(void);
|
||||
-void pt_shutdown(void);
|
||||
-void pt_getaddr(struct pt_entry *, struct bgpd_addr *);
|
||||
-struct pt_entry *pt_fill(struct bgpd_addr *, int);
|
||||
-struct pt_entry *pt_get(struct bgpd_addr *, int);
|
||||
-struct pt_entry *pt_add(struct bgpd_addr *, int);
|
||||
-void pt_remove(struct pt_entry *);
|
||||
-struct pt_entry *pt_lookup(struct bgpd_addr *);
|
||||
-int pt_prefix_cmp(const struct pt_entry *, const struct pt_entry *);
|
||||
-
|
||||
-
|
||||
-/* rde_filter.c */
|
||||
-enum filter_actions rde_filter(u_int16_t, struct rde_aspath **,
|
||||
- struct filter_head *, struct rde_peer *,
|
||||
- struct rde_aspath *, struct bgpd_addr *, u_int8_t,
|
||||
- struct rde_peer *, enum directions);
|
||||
-void rde_apply_set(struct rde_aspath *, struct filter_set_head *,
|
||||
- sa_family_t, struct rde_peer *, struct rde_peer *);
|
||||
-int rde_filter_community(struct rde_aspath *, int, int);
|
||||
-int rde_filter_equal(struct filter_head *, struct filter_head *,
|
||||
- struct rde_peer *, enum directions);
|
||||
-
|
||||
-/* util.c */
|
||||
-u_int32_t aspath_extract(const void *, int);
|
||||
+u_char *up_dump_mp_unreach(u_char *, u_int16_t *, struct rde_peer *,
|
||||
+ u_int8_t);
|
||||
+int up_dump_mp_reach(u_char *, u_int16_t *, struct rde_peer *,
|
||||
+ u_int8_t);
|
||||
|
||||
#endif /* __RDE_H__ */
|
562
net/openbgpd/files/patch-bgpd_rde_attr.c
Normal file
562
net/openbgpd/files/patch-bgpd_rde_attr.c
Normal file
@ -0,0 +1,562 @@
|
||||
Index: bgpd/rde_attr.c
|
||||
===================================================================
|
||||
RCS file: /home/cvs/private/hrs/openbgpd/bgpd/rde_attr.c,v
|
||||
retrieving revision 1.1.1.6
|
||||
retrieving revision 1.7
|
||||
diff -u -p -r1.1.1.6 -r1.7
|
||||
--- bgpd/rde_attr.c 14 Feb 2010 20:19:57 -0000 1.1.1.6
|
||||
+++ bgpd/rde_attr.c 13 Oct 2012 18:36:00 -0000 1.7
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* $OpenBSD: rde_attr.c,v 1.79 2009/03/19 06:52:59 claudio Exp $ */
|
||||
+/* $OpenBSD: rde_attr.c,v 1.90 2012/04/12 17:27:20 claudio Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
|
||||
@@ -17,14 +17,22 @@
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
+#if defined(__FreeBSD__) /* sys/hash.h */
|
||||
+#include "hash.h"
|
||||
+#else
|
||||
#include <sys/hash.h>
|
||||
+#endif /* defined(__FreeBSD__) */
|
||||
#include <sys/queue.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
+#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
+#if defined(__FreeBSD__) /* limits.h */
|
||||
+#include <limits.h>
|
||||
+#endif /* defined(__FreeBSD__) */
|
||||
|
||||
#include "bgpd.h"
|
||||
#include "rde.h"
|
||||
@@ -36,12 +44,12 @@ attr_write(void *p, u_int16_t p_len, u_i
|
||||
u_char *b = p;
|
||||
u_int16_t tmp, tot_len = 2; /* attribute header (without len) */
|
||||
|
||||
+ flags &= ~ATTR_DEFMASK;
|
||||
if (data_len > 255) {
|
||||
tot_len += 2 + data_len;
|
||||
flags |= ATTR_EXTLEN;
|
||||
} else {
|
||||
tot_len += 1 + data_len;
|
||||
- flags &= ~ATTR_EXTLEN;
|
||||
}
|
||||
|
||||
if (tot_len > p_len)
|
||||
@@ -63,26 +71,26 @@ attr_write(void *p, u_int16_t p_len, u_i
|
||||
}
|
||||
|
||||
int
|
||||
-attr_writebuf(struct buf *buf, u_int8_t flags, u_int8_t type, void *data,
|
||||
+attr_writebuf(struct ibuf *buf, u_int8_t flags, u_int8_t type, void *data,
|
||||
u_int16_t data_len)
|
||||
{
|
||||
u_char hdr[4];
|
||||
|
||||
+ flags &= ~ATTR_DEFMASK;
|
||||
if (data_len > 255) {
|
||||
flags |= ATTR_EXTLEN;
|
||||
hdr[2] = (data_len >> 8) & 0xff;
|
||||
hdr[3] = data_len & 0xff;
|
||||
} else {
|
||||
- flags &= ~ATTR_EXTLEN;
|
||||
hdr[2] = data_len & 0xff;
|
||||
}
|
||||
|
||||
hdr[0] = flags;
|
||||
hdr[1] = type;
|
||||
|
||||
- if (buf_add(buf, hdr, flags & ATTR_EXTLEN ? 4 : 3) == -1)
|
||||
+ if (ibuf_add(buf, hdr, flags & ATTR_EXTLEN ? 4 : 3) == -1)
|
||||
return (-1);
|
||||
- if (buf_add(buf, data, data_len) == -1)
|
||||
+ if (ibuf_add(buf, data, data_len) == -1)
|
||||
return (-1);
|
||||
return (0);
|
||||
}
|
||||
@@ -146,8 +154,11 @@ attr_optadd(struct rde_aspath *asp, u_in
|
||||
for (l = 0; l < asp->others_len; l++) {
|
||||
if (asp->others[l] == NULL)
|
||||
break;
|
||||
- if (type == asp->others[l]->type)
|
||||
+ if (type == asp->others[l]->type) {
|
||||
+ if (a->refcnt == 0)
|
||||
+ attr_put(a);
|
||||
return (-1);
|
||||
+ }
|
||||
}
|
||||
|
||||
/* add attribute to the table but first bump refcnt */
|
||||
@@ -318,6 +329,7 @@ attr_alloc(u_int8_t flags, u_int8_t type
|
||||
fatal("attr_optadd");
|
||||
rdemem.attr_cnt++;
|
||||
|
||||
+ flags &= ~ATTR_DEFMASK; /* normalize mask */
|
||||
a->flags = flags;
|
||||
a->hash = hash32_buf(&flags, sizeof(flags), HASHINIT);
|
||||
a->type = type;
|
||||
@@ -347,6 +359,7 @@ attr_lookup(u_int8_t flags, u_int8_t typ
|
||||
struct attr *a;
|
||||
u_int32_t hash;
|
||||
|
||||
+ flags &= ~ATTR_DEFMASK; /* normalize mask */
|
||||
hash = hash32_buf(&flags, sizeof(flags), HASHINIT);
|
||||
hash = hash32_buf(&type, sizeof(type), hash);
|
||||
hash = hash32_buf(&len, sizeof(len), hash);
|
||||
@@ -405,6 +418,7 @@ aspath_verify(void *data, u_int16_t len,
|
||||
u_int8_t *seg = data;
|
||||
u_int16_t seg_size, as_size = 2;
|
||||
u_int8_t seg_len, seg_type;
|
||||
+ int err = 0;
|
||||
|
||||
if (len & 1)
|
||||
/* odd length aspath are invalid */
|
||||
@@ -419,7 +433,15 @@ aspath_verify(void *data, u_int16_t len,
|
||||
seg_type = seg[0];
|
||||
seg_len = seg[1];
|
||||
|
||||
- if (seg_type != AS_SET && seg_type != AS_SEQUENCE)
|
||||
+ /*
|
||||
+ * BGP confederations should not show up but consider them
|
||||
+ * as a soft error which invalidates the path but keeps the
|
||||
+ * bgp session running.
|
||||
+ */
|
||||
+ if (seg_type == AS_CONFED_SEQUENCE || seg_type == AS_CONFED_SET)
|
||||
+ err = AS_ERR_SOFT;
|
||||
+ if (seg_type != AS_SET && seg_type != AS_SEQUENCE &&
|
||||
+ seg_type != AS_CONFED_SEQUENCE && seg_type != AS_CONFED_SET)
|
||||
return (AS_ERR_TYPE);
|
||||
|
||||
seg_size = 2 + as_size * seg_len;
|
||||
@@ -431,7 +453,7 @@ aspath_verify(void *data, u_int16_t len,
|
||||
/* empty aspath segments are not allowed */
|
||||
return (AS_ERR_BAD);
|
||||
}
|
||||
- return (0); /* aspath is valid but probably not loop free */
|
||||
+ return (err); /* aspath is valid but probably not loop free */
|
||||
}
|
||||
|
||||
void
|
||||
@@ -762,15 +784,9 @@ aspath_countcopy(struct aspath *aspath,
|
||||
u_int32_t
|
||||
aspath_neighbor(struct aspath *aspath)
|
||||
{
|
||||
- /*
|
||||
- * Empty aspath is OK -- internal as route.
|
||||
- * But what is the neighbor? For now let's return 0.
|
||||
- * That should not break anything.
|
||||
- */
|
||||
-
|
||||
+ /* Empty aspath is OK -- internal AS route. */
|
||||
if (aspath->len == 0)
|
||||
- return (0);
|
||||
-
|
||||
+ return (rde_local_as());
|
||||
return (aspath_extract(aspath->data, 0));
|
||||
}
|
||||
|
||||
@@ -910,76 +926,63 @@ aspath_prepend(struct aspath *asp, u_int
|
||||
return (p);
|
||||
}
|
||||
|
||||
-/* we need to be able to search more than one as */
|
||||
int
|
||||
-aspath_match(struct aspath *a, enum as_spec type, u_int32_t as)
|
||||
+aspath_lenmatch(struct aspath *a, enum aslen_spec type, u_int aslen)
|
||||
{
|
||||
u_int8_t *seg;
|
||||
- int final;
|
||||
+ u_int32_t as, lastas = 0;
|
||||
+ u_int count = 0;
|
||||
u_int16_t len, seg_size;
|
||||
u_int8_t i, seg_type, seg_len;
|
||||
|
||||
- if (type == AS_EMPTY) {
|
||||
- if (a->len == 0)
|
||||
+ if (type == ASLEN_MAX) {
|
||||
+ if (aslen < aspath_count(a->data, a->len))
|
||||
return (1);
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
|
||||
- final = 0;
|
||||
+ /* type == ASLEN_SEQ */
|
||||
seg = a->data;
|
||||
for (len = a->len; len > 0; len -= seg_size, seg += seg_size) {
|
||||
seg_type = seg[0];
|
||||
seg_len = seg[1];
|
||||
seg_size = 2 + sizeof(u_int32_t) * seg_len;
|
||||
|
||||
- final = (len == seg_size);
|
||||
-
|
||||
- /* just check the first (leftmost) AS */
|
||||
- if (type == AS_PEER) {
|
||||
- if (as == aspath_extract(seg, 0))
|
||||
- return (1);
|
||||
- else
|
||||
- return (0);
|
||||
- }
|
||||
- /* just check the final (rightmost) AS */
|
||||
- if (type == AS_SOURCE) {
|
||||
- /* not yet in the final segment */
|
||||
- if (!final)
|
||||
- continue;
|
||||
-
|
||||
- if (as == aspath_extract(seg, seg_len - 1))
|
||||
- return (1);
|
||||
- else
|
||||
- return (0);
|
||||
- }
|
||||
-
|
||||
- /* AS_TRANSIT or AS_ALL */
|
||||
for (i = 0; i < seg_len; i++) {
|
||||
- if (as == aspath_extract(seg, i)) {
|
||||
- /*
|
||||
- * the source (rightmost) AS is excluded from
|
||||
- * AS_TRANSIT matches.
|
||||
- */
|
||||
- if (final && i == seg_len - 1 &&
|
||||
- type == AS_TRANSIT)
|
||||
- return (0);
|
||||
- return (1);
|
||||
- }
|
||||
+ /* what should we do with AS_SET? */
|
||||
+ as = aspath_extract(seg, i);
|
||||
+ if (as == lastas) {
|
||||
+ if (aslen < ++count)
|
||||
+ return (1);
|
||||
+ } else
|
||||
+ count = 1;
|
||||
+ lastas = as;
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Functions handling communities and extended communities.
|
||||
+ */
|
||||
+
|
||||
+int community_ext_matchone(struct filter_extcommunity *, u_int16_t, u_int64_t);
|
||||
+
|
||||
int
|
||||
-community_match(void *data, u_int16_t len, int as, int type)
|
||||
+community_match(struct rde_aspath *asp, int as, int type)
|
||||
{
|
||||
- u_int8_t *p = data;
|
||||
- u_int16_t eas, etype;
|
||||
+ struct attr *a;
|
||||
+ u_int8_t *p;
|
||||
+ u_int16_t eas, etype, len;
|
||||
|
||||
- len >>= 2; /* divide by four */
|
||||
+ a = attr_optget(asp, ATTR_COMMUNITIES);
|
||||
+ if (a == NULL)
|
||||
+ /* no communities, no match */
|
||||
+ return (0);
|
||||
|
||||
- for (; len > 0; len--) {
|
||||
+ p = a->data;
|
||||
+ for (len = a->len / 4; len > 0; len--) {
|
||||
eas = *p++;
|
||||
eas <<= 8;
|
||||
eas |= *p++;
|
||||
@@ -1000,7 +1003,6 @@ community_set(struct rde_aspath *asp, in
|
||||
u_int8_t *p = NULL;
|
||||
unsigned int i, ncommunities = 0;
|
||||
u_int8_t f = ATTR_OPTIONAL|ATTR_TRANSITIVE;
|
||||
- u_int8_t t = ATTR_COMMUNITIES;
|
||||
|
||||
attr = attr_optget(asp, ATTR_COMMUNITIES);
|
||||
if (attr != NULL) {
|
||||
@@ -1017,7 +1019,7 @@ community_set(struct rde_aspath *asp, in
|
||||
p += 4;
|
||||
}
|
||||
|
||||
- if (ncommunities++ >= 0x3fff)
|
||||
+ if (ncommunities++ >= USHRT_MAX / 4)
|
||||
/* overflow */
|
||||
return (0);
|
||||
|
||||
@@ -1032,11 +1034,10 @@ community_set(struct rde_aspath *asp, in
|
||||
if (attr != NULL) {
|
||||
memcpy(p + 4, attr->data, attr->len);
|
||||
f = attr->flags;
|
||||
- t = attr->type;
|
||||
attr_free(asp, attr);
|
||||
}
|
||||
|
||||
- attr_optadd(asp, f, t, p, ncommunities << 2);
|
||||
+ attr_optadd(asp, f, ATTR_COMMUNITIES, p, ncommunities << 2);
|
||||
|
||||
free(p);
|
||||
return (1);
|
||||
@@ -1049,7 +1050,7 @@ community_delete(struct rde_aspath *asp,
|
||||
u_int8_t *p, *n;
|
||||
u_int16_t l, len = 0;
|
||||
u_int16_t eas, etype;
|
||||
- u_int8_t f, t;
|
||||
+ u_int8_t f;
|
||||
|
||||
attr = attr_optget(asp, ATTR_COMMUNITIES);
|
||||
if (attr == NULL)
|
||||
@@ -1100,10 +1101,250 @@ community_delete(struct rde_aspath *asp,
|
||||
}
|
||||
|
||||
f = attr->flags;
|
||||
- t = attr->type;
|
||||
|
||||
attr_free(asp, attr);
|
||||
- attr_optadd(asp, f, t, n, len);
|
||||
+ attr_optadd(asp, f, ATTR_COMMUNITIES, n, len);
|
||||
free(n);
|
||||
}
|
||||
|
||||
+int
|
||||
+community_ext_match(struct rde_aspath *asp, struct filter_extcommunity *c,
|
||||
+ u_int16_t neighas)
|
||||
+{
|
||||
+ struct attr *attr;
|
||||
+ u_int8_t *p;
|
||||
+ u_int64_t ec;
|
||||
+ u_int16_t len;
|
||||
+
|
||||
+ attr = attr_optget(asp, ATTR_EXT_COMMUNITIES);
|
||||
+ if (attr == NULL)
|
||||
+ /* no communities, no match */
|
||||
+ return (0);
|
||||
+
|
||||
+ p = attr->data;
|
||||
+ for (len = attr->len / sizeof(ec); len > 0; len--) {
|
||||
+ memcpy(&ec, p, sizeof(ec));
|
||||
+ if (community_ext_matchone(c, neighas, ec))
|
||||
+ return (1);
|
||||
+ p += sizeof(ec);
|
||||
+ }
|
||||
+
|
||||
+ return (0);
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+community_ext_set(struct rde_aspath *asp, struct filter_extcommunity *c,
|
||||
+ u_int16_t neighas)
|
||||
+{
|
||||
+ struct attr *attr;
|
||||
+ u_int8_t *p = NULL;
|
||||
+ u_int64_t community;
|
||||
+ unsigned int i, ncommunities = 0;
|
||||
+ u_int8_t f = ATTR_OPTIONAL|ATTR_TRANSITIVE;
|
||||
+
|
||||
+ if (community_ext_conv(c, neighas, &community))
|
||||
+ return (0);
|
||||
+
|
||||
+ attr = attr_optget(asp, ATTR_EXT_COMMUNITIES);
|
||||
+ if (attr != NULL) {
|
||||
+ p = attr->data;
|
||||
+ ncommunities = attr->len / sizeof(community);
|
||||
+ }
|
||||
+
|
||||
+ /* first check if the community is not already set */
|
||||
+ for (i = 0; i < ncommunities; i++) {
|
||||
+ if (memcmp(&community, p, sizeof(community)) == 0)
|
||||
+ /* already present, nothing todo */
|
||||
+ return (1);
|
||||
+ p += sizeof(community);
|
||||
+ }
|
||||
+
|
||||
+ if (ncommunities++ >= USHRT_MAX / sizeof(community))
|
||||
+ /* overflow */
|
||||
+ return (0);
|
||||
+
|
||||
+ if ((p = malloc(ncommunities * sizeof(community))) == NULL)
|
||||
+ fatal("community_ext_set");
|
||||
+
|
||||
+ memcpy(p, &community, sizeof(community));
|
||||
+ if (attr != NULL) {
|
||||
+ memcpy(p + sizeof(community), attr->data, attr->len);
|
||||
+ f = attr->flags;
|
||||
+ attr_free(asp, attr);
|
||||
+ }
|
||||
+
|
||||
+ attr_optadd(asp, f, ATTR_EXT_COMMUNITIES, p,
|
||||
+ ncommunities * sizeof(community));
|
||||
+
|
||||
+ free(p);
|
||||
+ return (1);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+community_ext_delete(struct rde_aspath *asp, struct filter_extcommunity *c,
|
||||
+ u_int16_t neighas)
|
||||
+{
|
||||
+ struct attr *attr;
|
||||
+ u_int8_t *p, *n;
|
||||
+ u_int64_t community;
|
||||
+ u_int16_t l, len = 0;
|
||||
+ u_int8_t f;
|
||||
+
|
||||
+ if (community_ext_conv(c, neighas, &community))
|
||||
+ return;
|
||||
+
|
||||
+ attr = attr_optget(asp, ATTR_EXT_COMMUNITIES);
|
||||
+ if (attr == NULL)
|
||||
+ /* no attr nothing to do */
|
||||
+ return;
|
||||
+
|
||||
+ p = attr->data;
|
||||
+ for (l = 0; l < attr->len; l += sizeof(community)) {
|
||||
+ if (memcmp(&community, p + l, sizeof(community)) == 0)
|
||||
+ /* match */
|
||||
+ continue;
|
||||
+ len += sizeof(community);
|
||||
+ }
|
||||
+
|
||||
+ if (len == 0) {
|
||||
+ attr_free(asp, attr);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if ((n = malloc(len)) == NULL)
|
||||
+ fatal("community_delete");
|
||||
+
|
||||
+ p = attr->data;
|
||||
+ for (l = 0; l < len && p < attr->data + attr->len;
|
||||
+ p += sizeof(community)) {
|
||||
+ if (memcmp(&community, p, sizeof(community)) == 0)
|
||||
+ /* match */
|
||||
+ continue;
|
||||
+ memcpy(n + l, p, sizeof(community));
|
||||
+ l += sizeof(community);
|
||||
+ }
|
||||
+
|
||||
+ f = attr->flags;
|
||||
+
|
||||
+ attr_free(asp, attr);
|
||||
+ attr_optadd(asp, f, ATTR_EXT_COMMUNITIES, n, len);
|
||||
+ free(n);
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+community_ext_conv(struct filter_extcommunity *c, u_int16_t neighas,
|
||||
+ u_int64_t *community)
|
||||
+{
|
||||
+ u_int64_t com;
|
||||
+ u_int32_t ip;
|
||||
+
|
||||
+ com = (u_int64_t)c->type << 56;
|
||||
+ switch (c->type & EXT_COMMUNITY_VALUE) {
|
||||
+ case EXT_COMMUNITY_TWO_AS:
|
||||
+ com |= (u_int64_t)c->subtype << 48;
|
||||
+ com |= (u_int64_t)c->data.ext_as.as << 32;
|
||||
+ com |= c->data.ext_as.val;
|
||||
+ break;
|
||||
+ case EXT_COMMUNITY_IPV4:
|
||||
+ com |= (u_int64_t)c->subtype << 48;
|
||||
+ ip = ntohl(c->data.ext_ip.addr.s_addr);
|
||||
+ com |= (u_int64_t)ip << 16;
|
||||
+ com |= c->data.ext_ip.val;
|
||||
+ break;
|
||||
+ case EXT_COMMUNITY_FOUR_AS:
|
||||
+ com |= (u_int64_t)c->subtype << 48;
|
||||
+ com |= (u_int64_t)c->data.ext_as4.as4 << 16;
|
||||
+ com |= c->data.ext_as4.val;
|
||||
+ break;
|
||||
+ case EXT_COMMUNITY_OPAQUE:
|
||||
+ com |= (u_int64_t)c->subtype << 48;
|
||||
+ com |= c->data.ext_opaq & EXT_COMMUNITY_OPAQUE_MAX;
|
||||
+ break;
|
||||
+ default:
|
||||
+ com |= c->data.ext_opaq & 0xffffffffffffffULL;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ *community = htobe64(com);
|
||||
+
|
||||
+ return (0);
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+community_ext_matchone(struct filter_extcommunity *c, u_int16_t neighas,
|
||||
+ u_int64_t community)
|
||||
+{
|
||||
+ u_int64_t com, mask;
|
||||
+ u_int32_t ip;
|
||||
+
|
||||
+ community = betoh64(community);
|
||||
+
|
||||
+ com = (u_int64_t)c->type << 56;
|
||||
+ mask = 0xffULL << 56;
|
||||
+ if ((com & mask) != (community & mask))
|
||||
+ return (0);
|
||||
+
|
||||
+ switch (c->type & EXT_COMMUNITY_VALUE) {
|
||||
+ case EXT_COMMUNITY_TWO_AS:
|
||||
+ case EXT_COMMUNITY_IPV4:
|
||||
+ case EXT_COMMUNITY_FOUR_AS:
|
||||
+ case EXT_COMMUNITY_OPAQUE:
|
||||
+ com = (u_int64_t)c->subtype << 48;
|
||||
+ mask = 0xffULL << 48;
|
||||
+ if ((com & mask) != (community & mask))
|
||||
+ return (0);
|
||||
+ break;
|
||||
+ default:
|
||||
+ com = c->data.ext_opaq & 0xffffffffffffffULL;
|
||||
+ mask = 0xffffffffffffffULL;
|
||||
+ if ((com & mask) == (community & mask))
|
||||
+ return (1);
|
||||
+ return (0);
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ switch (c->type & EXT_COMMUNITY_VALUE) {
|
||||
+ case EXT_COMMUNITY_TWO_AS:
|
||||
+ com = (u_int64_t)c->data.ext_as.as << 32;
|
||||
+ mask = 0xffffULL << 32;
|
||||
+ if ((com & mask) != (community & mask))
|
||||
+ return (0);
|
||||
+
|
||||
+ com = c->data.ext_as.val;
|
||||
+ mask = 0xffffffffULL;
|
||||
+ if ((com & mask) == (community & mask))
|
||||
+ return (1);
|
||||
+ break;
|
||||
+ case EXT_COMMUNITY_IPV4:
|
||||
+ ip = ntohl(c->data.ext_ip.addr.s_addr);
|
||||
+ com = (u_int64_t)ip << 16;
|
||||
+ mask = 0xffffffff0000ULL;
|
||||
+ if ((com & mask) != (community & mask))
|
||||
+ return (0);
|
||||
+
|
||||
+ com = c->data.ext_ip.val;
|
||||
+ mask = 0xffff;
|
||||
+ if ((com & mask) == (community & mask))
|
||||
+ return (1);
|
||||
+ break;
|
||||
+ case EXT_COMMUNITY_FOUR_AS:
|
||||
+ com = (u_int64_t)c->data.ext_as4.as4 << 16;
|
||||
+ mask = 0xffffffffULL << 16;
|
||||
+ if ((com & mask) != (community & mask))
|
||||
+ return (0);
|
||||
+
|
||||
+ com = c->data.ext_as4.val;
|
||||
+ mask = 0xffff;
|
||||
+ if ((com & mask) == (community & mask))
|
||||
+ return (1);
|
||||
+ break;
|
||||
+ case EXT_COMMUNITY_OPAQUE:
|
||||
+ com = c->data.ext_opaq & EXT_COMMUNITY_OPAQUE_MAX;
|
||||
+ mask = EXT_COMMUNITY_OPAQUE_MAX;
|
||||
+ if ((com & mask) == (community & mask))
|
||||
+ return (1);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return (0);
|
||||
+}
|
133
net/openbgpd/files/patch-bgpd_rde_decide.c
Normal file
133
net/openbgpd/files/patch-bgpd_rde_decide.c
Normal file
@ -0,0 +1,133 @@
|
||||
Index: bgpd/rde_decide.c
|
||||
===================================================================
|
||||
RCS file: /home/cvs/private/hrs/openbgpd/bgpd/rde_decide.c,v
|
||||
retrieving revision 1.1.1.6
|
||||
retrieving revision 1.4
|
||||
diff -u -p -r1.1.1.6 -r1.4
|
||||
--- bgpd/rde_decide.c 14 Feb 2010 20:19:57 -0000 1.1.1.6
|
||||
+++ bgpd/rde_decide.c 13 Oct 2012 18:36:00 -0000 1.4
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* $OpenBSD: rde_decide.c,v 1.58 2009/06/29 14:10:13 claudio Exp $ */
|
||||
+/* $OpenBSD: rde_decide.c,v 1.61 2012/04/12 17:31:05 claudio Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org>
|
||||
@@ -109,6 +109,9 @@ int
|
||||
prefix_cmp(struct prefix *p1, struct prefix *p2)
|
||||
{
|
||||
struct rde_aspath *asp1, *asp2;
|
||||
+ struct attr *a;
|
||||
+ u_int32_t p1id, p2id;
|
||||
+ int p1cnt, p2cnt;
|
||||
|
||||
if (p1 == NULL)
|
||||
return (-1);
|
||||
@@ -118,6 +121,12 @@ prefix_cmp(struct prefix *p1, struct pre
|
||||
asp1 = p1->aspath;
|
||||
asp2 = p2->aspath;
|
||||
|
||||
+ /* pathes with errors are not eligible */
|
||||
+ if (asp1->flags & F_ATTR_PARSE_ERR)
|
||||
+ return (-1);
|
||||
+ if (asp2->flags & F_ATTR_PARSE_ERR)
|
||||
+ return (1);
|
||||
+
|
||||
/* only loop free pathes are eligible */
|
||||
if (asp1->flags & F_ATTR_LOOP)
|
||||
return (-1);
|
||||
@@ -130,7 +139,7 @@ prefix_cmp(struct prefix *p1, struct pre
|
||||
if (asp1->nexthop != NULL && asp1->nexthop->state != NEXTHOP_REACH)
|
||||
return (-1);
|
||||
|
||||
- /* 2. preference of prefix, bigger is better */
|
||||
+ /* 2. local preference of prefix, bigger is better */
|
||||
if ((asp1->lpref - asp2->lpref) != 0)
|
||||
return (asp1->lpref - asp2->lpref);
|
||||
|
||||
@@ -154,10 +163,10 @@ prefix_cmp(struct prefix *p1, struct pre
|
||||
* It is absolutely important that the ebgp value in peer_config.ebgp
|
||||
* is bigger than all other ones (IBGP, confederations)
|
||||
*/
|
||||
- if ((asp1->peer->conf.ebgp - asp2->peer->conf.ebgp) != 0) {
|
||||
- if (asp1->peer->conf.ebgp == 1) /* p1 is EBGP other is lower */
|
||||
+ if (asp1->peer->conf.ebgp != asp2->peer->conf.ebgp) {
|
||||
+ if (asp1->peer->conf.ebgp) /* p1 is EBGP other is lower */
|
||||
return 1;
|
||||
- else if (asp2->peer->conf.ebgp == 1) /* p2 is EBGP */
|
||||
+ else if (asp2->peer->conf.ebgp) /* p2 is EBGP */
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -181,13 +190,30 @@ prefix_cmp(struct prefix *p1, struct pre
|
||||
if ((p2->lastchange - p1->lastchange) != 0)
|
||||
return (p2->lastchange - p1->lastchange);
|
||||
|
||||
- /* 10. lowest BGP Id wins */
|
||||
- if ((p2->aspath->peer->remote_bgpid -
|
||||
- p1->aspath->peer->remote_bgpid) != 0)
|
||||
- return (p2->aspath->peer->remote_bgpid -
|
||||
- p1->aspath->peer->remote_bgpid);
|
||||
+ /* 10. lowest BGP Id wins, use ORIGINATOR_ID if present */
|
||||
+ if ((a = attr_optget(asp1, ATTR_ORIGINATOR_ID)) != NULL) {
|
||||
+ memcpy(&p1id, a->data, sizeof(p1id));
|
||||
+ p1id = ntohl(p1id);
|
||||
+ } else
|
||||
+ p1id = asp1->peer->remote_bgpid;
|
||||
+ if ((a = attr_optget(asp2, ATTR_ORIGINATOR_ID)) != NULL) {
|
||||
+ memcpy(&p2id, a->data, sizeof(p2id));
|
||||
+ p2id = ntohl(p2id);
|
||||
+ } else
|
||||
+ p2id = asp2->peer->remote_bgpid;
|
||||
+ if ((p2id - p1id) != 0)
|
||||
+ return (p2id - p1id);
|
||||
+
|
||||
+ /* 11. compare CLUSTER_LIST length, shorter is better */
|
||||
+ p1cnt = p2cnt = 0;
|
||||
+ if ((a = attr_optget(asp1, ATTR_CLUSTER_LIST)) != NULL)
|
||||
+ p1cnt = a->len / sizeof(u_int32_t);
|
||||
+ if ((a = attr_optget(asp2, ATTR_CLUSTER_LIST)) != NULL)
|
||||
+ p2cnt = a->len / sizeof(u_int32_t);
|
||||
+ if ((p2cnt - p1cnt) != 0)
|
||||
+ return (p2cnt - p1cnt);
|
||||
|
||||
- /* 11. lowest peer address wins (IPv4 is better than IPv6) */
|
||||
+ /* 12. lowest peer address wins (IPv4 is better than IPv6) */
|
||||
if (memcmp(&p1->aspath->peer->remote_addr,
|
||||
&p2->aspath->peer->remote_addr,
|
||||
sizeof(p1->aspath->peer->remote_addr)) != 0)
|
||||
@@ -195,7 +221,7 @@ prefix_cmp(struct prefix *p1, struct pre
|
||||
&p2->aspath->peer->remote_addr,
|
||||
sizeof(p1->aspath->peer->remote_addr)));
|
||||
|
||||
- /* 12. for announced prefixes prefer dynamic routes */
|
||||
+ /* 13. for announced prefixes prefer dynamic routes */
|
||||
if ((asp1->flags & F_ANN_DYNAMIC) != (asp2->flags & F_ANN_DYNAMIC)) {
|
||||
if (asp1->flags & F_ANN_DYNAMIC)
|
||||
return (1);
|
||||
@@ -204,7 +230,7 @@ prefix_cmp(struct prefix *p1, struct pre
|
||||
}
|
||||
|
||||
fatalx("Uh, oh a politician in the decision process");
|
||||
- /* NOTREACHED */
|
||||
+ return(0); /* NOTREACHED */
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -245,7 +271,7 @@ prefix_evaluate(struct prefix *p, struct
|
||||
}
|
||||
|
||||
xp = LIST_FIRST(&re->prefix_h);
|
||||
- if (xp == NULL || xp->aspath->flags & F_ATTR_LOOP ||
|
||||
+ if (xp == NULL || xp->aspath->flags & (F_ATTR_LOOP|F_ATTR_PARSE_ERR) ||
|
||||
(xp->aspath->nexthop != NULL &&
|
||||
xp->aspath->nexthop->state != NEXTHOP_REACH))
|
||||
/* xp is ineligible */
|
||||
@@ -263,7 +289,7 @@ prefix_evaluate(struct prefix *p, struct
|
||||
*/
|
||||
rde_generate_updates(re->ribid, xp, re->active);
|
||||
if ((re->flags & F_RIB_NOFIB) == 0)
|
||||
- rde_send_kroute(xp, re->active);
|
||||
+ rde_send_kroute(xp, re->active, re->ribid);
|
||||
|
||||
re->active = xp;
|
||||
if (xp != NULL)
|
297
net/openbgpd/files/patch-bgpd_rde_filter.c
Normal file
297
net/openbgpd/files/patch-bgpd_rde_filter.c
Normal file
@ -0,0 +1,297 @@
|
||||
Index: bgpd/rde_filter.c
|
||||
===================================================================
|
||||
RCS file: /home/cvs/private/hrs/openbgpd/bgpd/rde_filter.c,v
|
||||
retrieving revision 1.1.1.7
|
||||
retrieving revision 1.9
|
||||
diff -u -p -r1.1.1.7 -r1.9
|
||||
--- bgpd/rde_filter.c 14 Feb 2010 20:19:57 -0000 1.1.1.7
|
||||
+++ bgpd/rde_filter.c 8 Dec 2012 20:17:59 -0000 1.9
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* $OpenBSD: rde_filter.c,v 1.56 2009/06/06 01:10:29 claudio Exp $ */
|
||||
+/* $OpenBSD: rde_filter.c,v 1.67 2011/09/20 21:19:06 claudio Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
|
||||
@@ -26,7 +26,7 @@
|
||||
#include "rde.h"
|
||||
|
||||
int rde_filter_match(struct filter_rule *, struct rde_aspath *,
|
||||
- struct bgpd_addr *, u_int8_t, struct rde_peer *);
|
||||
+ struct bgpd_addr *, u_int8_t, struct rde_peer *, struct rde_peer *);
|
||||
int filterset_equal(struct filter_set_head *, struct filter_set_head *);
|
||||
|
||||
enum filter_actions
|
||||
@@ -40,6 +40,13 @@ rde_filter(u_int16_t ribid, struct rde_a
|
||||
if (new != NULL)
|
||||
*new = NULL;
|
||||
|
||||
+ if (asp->flags & F_ATTR_PARSE_ERR)
|
||||
+ /*
|
||||
+ * don't try to filter bad updates just deny them
|
||||
+ * so they act as implicit withdraws
|
||||
+ */
|
||||
+ return (ACTION_DENY);
|
||||
+
|
||||
TAILQ_FOREACH(f, rules, entry) {
|
||||
if (dir != f->dir)
|
||||
continue;
|
||||
@@ -51,7 +58,7 @@ rde_filter(u_int16_t ribid, struct rde_a
|
||||
if (f->peer.peerid != 0 &&
|
||||
f->peer.peerid != peer->conf.id)
|
||||
continue;
|
||||
- if (rde_filter_match(f, asp, prefix, prefixlen, peer)) {
|
||||
+ if (rde_filter_match(f, asp, prefix, prefixlen, peer, from)) {
|
||||
if (asp != NULL && new != NULL) {
|
||||
/* asp may get modified so create a copy */
|
||||
if (*new == NULL) {
|
||||
@@ -59,7 +66,7 @@ rde_filter(u_int16_t ribid, struct rde_a
|
||||
/* ... and use the copy from now on */
|
||||
asp = *new;
|
||||
}
|
||||
- rde_apply_set(asp, &f->set, prefix->af,
|
||||
+ rde_apply_set(asp, &f->set, prefix->aid,
|
||||
from, peer);
|
||||
}
|
||||
if (f->action != ACTION_NONE)
|
||||
@@ -73,7 +80,7 @@ rde_filter(u_int16_t ribid, struct rde_a
|
||||
|
||||
void
|
||||
rde_apply_set(struct rde_aspath *asp, struct filter_set_head *sh,
|
||||
- sa_family_t af, struct rde_peer *from, struct rde_peer *peer)
|
||||
+ u_int8_t aid, struct rde_peer *from, struct rde_peer *peer)
|
||||
{
|
||||
struct filter_set *set;
|
||||
u_char *np;
|
||||
@@ -167,7 +174,7 @@ rde_apply_set(struct rde_aspath *asp, st
|
||||
case ACTION_SET_NEXTHOP_NOMODIFY:
|
||||
case ACTION_SET_NEXTHOP_SELF:
|
||||
nexthop_modify(asp, &set->action.nexthop, set->type,
|
||||
- af);
|
||||
+ aid);
|
||||
break;
|
||||
case ACTION_SET_COMMUNITY:
|
||||
switch (set->action.community.as) {
|
||||
@@ -243,19 +250,42 @@ rde_apply_set(struct rde_aspath *asp, st
|
||||
asp->rtlabelid = set->action.id;
|
||||
rtlabel_ref(asp->rtlabelid);
|
||||
break;
|
||||
+ case ACTION_SET_ORIGIN:
|
||||
+ asp->origin = set->action.origin;
|
||||
+ break;
|
||||
+ case ACTION_SET_EXT_COMMUNITY:
|
||||
+ community_ext_set(asp, &set->action.ext_community,
|
||||
+ peer->conf.remote_as);
|
||||
+ break;
|
||||
+ case ACTION_DEL_EXT_COMMUNITY:
|
||||
+ community_ext_delete(asp, &set->action.ext_community,
|
||||
+ peer->conf.remote_as);
|
||||
+ break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
rde_filter_match(struct filter_rule *f, struct rde_aspath *asp,
|
||||
- struct bgpd_addr *prefix, u_int8_t plen, struct rde_peer *peer)
|
||||
+ struct bgpd_addr *prefix, u_int8_t plen, struct rde_peer *peer,
|
||||
+ struct rde_peer *from)
|
||||
{
|
||||
- int as, type;
|
||||
+ u_int32_t pas;
|
||||
+ int cas, type;
|
||||
|
||||
- if (asp != NULL && f->match.as.type != AS_NONE)
|
||||
- if (aspath_match(asp->aspath, f->match.as.type,
|
||||
- f->match.as.as) == 0)
|
||||
+ if (asp != NULL && f->match.as.type != AS_NONE) {
|
||||
+ if (f->match.as.flags & AS_FLAG_NEIGHBORAS)
|
||||
+ pas = peer->conf.remote_as;
|
||||
+ else
|
||||
+ pas = f->match.as.as;
|
||||
+ if (aspath_match(asp->aspath->data, asp->aspath->len,
|
||||
+ f->match.as.type, pas) == 0)
|
||||
+ return (0);
|
||||
+ }
|
||||
+
|
||||
+ if (asp != NULL && f->match.aslen.type != ASLEN_NONE)
|
||||
+ if (aspath_lenmatch(asp->aspath, f->match.aslen.type,
|
||||
+ f->match.aslen.aslen) == 0)
|
||||
return (0);
|
||||
|
||||
if (asp != NULL && f->match.community.as != COMMUNITY_UNSET) {
|
||||
@@ -263,10 +293,10 @@ rde_filter_match(struct filter_rule *f,
|
||||
case COMMUNITY_ERROR:
|
||||
fatalx("rde_apply_set bad community string");
|
||||
case COMMUNITY_NEIGHBOR_AS:
|
||||
- as = peer->conf.remote_as;
|
||||
+ cas = peer->conf.remote_as;
|
||||
break;
|
||||
default:
|
||||
- as = f->match.community.as;
|
||||
+ cas = f->match.community.as;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -281,12 +311,17 @@ rde_filter_match(struct filter_rule *f,
|
||||
break;
|
||||
}
|
||||
|
||||
- if (rde_filter_community(asp, as, type) == 0)
|
||||
+ if (community_match(asp, cas, type) == 0)
|
||||
return (0);
|
||||
}
|
||||
+ if (asp != NULL &&
|
||||
+ (f->match.ext_community.flags & EXT_COMMUNITY_FLAG_VALID))
|
||||
+ if (community_ext_match(asp, &f->match.ext_community,
|
||||
+ peer->conf.remote_as) == 0)
|
||||
+ return (0);
|
||||
|
||||
- if (f->match.prefix.addr.af != 0) {
|
||||
- if (f->match.prefix.addr.af != prefix->af)
|
||||
+ if (f->match.prefix.addr.aid != 0) {
|
||||
+ if (f->match.prefix.addr.aid != prefix->aid)
|
||||
/* don't use IPv4 rules for IPv6 and vice versa */
|
||||
return (0);
|
||||
|
||||
@@ -322,7 +357,7 @@ rde_filter_match(struct filter_rule *f,
|
||||
} else if (f->match.prefixlen.op != OP_NONE) {
|
||||
/* only prefixlen without a prefix */
|
||||
|
||||
- if (f->match.prefixlen.af != prefix->af)
|
||||
+ if (f->match.prefixlen.aid != prefix->aid)
|
||||
/* don't use IPv4 rules for IPv6 and vice versa */
|
||||
return (0);
|
||||
|
||||
@@ -350,25 +385,40 @@ rde_filter_match(struct filter_rule *f,
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
+ if (f->match.nexthop.flags != 0) {
|
||||
+ struct bgpd_addr *nexthop, *cmpaddr;
|
||||
+ if (asp->nexthop == NULL)
|
||||
+ /* no nexthop, skip */
|
||||
+ return (0);
|
||||
+ nexthop = &asp->nexthop->exit_nexthop;
|
||||
+ if (f->match.nexthop.flags == FILTER_NEXTHOP_ADDR)
|
||||
+ cmpaddr = &f->match.nexthop.addr;
|
||||
+ else
|
||||
+ cmpaddr = &from->remote_addr;
|
||||
+ if (cmpaddr->aid != nexthop->aid)
|
||||
+ /* don't use IPv4 rules for IPv6 and vice versa */
|
||||
+ return (0);
|
||||
+
|
||||
+ switch (cmpaddr->aid) {
|
||||
+ case AID_INET:
|
||||
+ if (cmpaddr->v4.s_addr != nexthop->v4.s_addr)
|
||||
+ return (0);
|
||||
+ break;
|
||||
+ case AID_INET6:
|
||||
+ if (memcmp(&cmpaddr->v6, &nexthop->v6,
|
||||
+ sizeof(struct in6_addr)))
|
||||
+ return (0);
|
||||
+ break;
|
||||
+ default:
|
||||
+ fatalx("King Bula lost in address space");
|
||||
+ }
|
||||
+ }
|
||||
|
||||
/* matched somewhen or is anymatch rule */
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
-rde_filter_community(struct rde_aspath *asp, int as, int type)
|
||||
-{
|
||||
- struct attr *a;
|
||||
-
|
||||
- a = attr_optget(asp, ATTR_COMMUNITIES);
|
||||
- if (a == NULL)
|
||||
- /* no communities, no match */
|
||||
- return (0);
|
||||
-
|
||||
- return (community_match(a->data, a->len, as, type));
|
||||
-}
|
||||
-
|
||||
-int
|
||||
rde_filter_equal(struct filter_head *a, struct filter_head *b,
|
||||
struct rde_peer *peer, enum directions dir)
|
||||
{
|
||||
@@ -476,6 +526,12 @@ filterset_cmp(struct filter_set *a, stru
|
||||
return (a->action.community.type - b->action.community.type);
|
||||
}
|
||||
|
||||
+ if (a->type == ACTION_SET_EXT_COMMUNITY ||
|
||||
+ a->type == ACTION_DEL_EXT_COMMUNITY) { /* a->type == b->type */
|
||||
+ return (memcmp(&a->action.ext_community,
|
||||
+ &b->action.ext_community, sizeof(a->action.ext_community)));
|
||||
+ }
|
||||
+
|
||||
if (a->type == ACTION_SET_NEXTHOP && b->type == ACTION_SET_NEXTHOP) {
|
||||
/*
|
||||
* This is the only interesting case, all others are considered
|
||||
@@ -483,13 +539,29 @@ filterset_cmp(struct filter_set *a, stru
|
||||
* reject it at the same time. Allow one IPv4 and one IPv6
|
||||
* per filter set or only one of the other nexthop modifiers.
|
||||
*/
|
||||
- return (a->action.nexthop.af - b->action.nexthop.af);
|
||||
+ return (a->action.nexthop.aid - b->action.nexthop.aid);
|
||||
}
|
||||
|
||||
/* equal */
|
||||
return (0);
|
||||
}
|
||||
|
||||
+void
|
||||
+filterset_move(struct filter_set_head *source, struct filter_set_head *dest)
|
||||
+{
|
||||
+ struct filter_set *s;
|
||||
+
|
||||
+ TAILQ_INIT(dest);
|
||||
+
|
||||
+ if (source == NULL)
|
||||
+ return;
|
||||
+
|
||||
+ while ((s = TAILQ_FIRST(source)) != NULL) {
|
||||
+ TAILQ_REMOVE(source, s, entry);
|
||||
+ TAILQ_INSERT_TAIL(dest, s, entry);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
int
|
||||
filterset_equal(struct filter_set_head *ah, struct filter_set_head *bh)
|
||||
{
|
||||
@@ -574,6 +646,19 @@ filterset_equal(struct filter_set_head *
|
||||
if (strcmp(as, bs) == 0)
|
||||
continue;
|
||||
break;
|
||||
+ case ACTION_SET_ORIGIN:
|
||||
+ if (a->type == b->type &&
|
||||
+ a->action.origin == b->action.origin)
|
||||
+ continue;
|
||||
+ break;
|
||||
+ case ACTION_SET_EXT_COMMUNITY:
|
||||
+ case ACTION_DEL_EXT_COMMUNITY:
|
||||
+ if (a->type == b->type && memcmp(
|
||||
+ &a->action.ext_community,
|
||||
+ &b->action.ext_community,
|
||||
+ sizeof(a->action.ext_community)) == 0)
|
||||
+ continue;
|
||||
+ break;
|
||||
}
|
||||
/* compare failed */
|
||||
return (0);
|
||||
@@ -616,7 +701,14 @@ filterset_name(enum action_types type)
|
||||
case ACTION_RTLABEL:
|
||||
case ACTION_RTLABEL_ID:
|
||||
return ("rtlabel");
|
||||
+ case ACTION_SET_ORIGIN:
|
||||
+ return ("origin");
|
||||
+ case ACTION_SET_EXT_COMMUNITY:
|
||||
+ return ("ext-community");
|
||||
+ case ACTION_DEL_EXT_COMMUNITY:
|
||||
+ return ("ext-community delete");
|
||||
}
|
||||
|
||||
fatalx("filterset_name: got lost");
|
||||
+ return (NULL); /* NOT REACHED */
|
||||
}
|
301
net/openbgpd/files/patch-bgpd_rde_prefix.c
Normal file
301
net/openbgpd/files/patch-bgpd_rde_prefix.c
Normal file
@ -0,0 +1,301 @@
|
||||
Index: bgpd/rde_prefix.c
|
||||
===================================================================
|
||||
RCS file: /home/cvs/private/hrs/openbgpd/bgpd/rde_prefix.c,v
|
||||
retrieving revision 1.1.1.6
|
||||
retrieving revision 1.6
|
||||
diff -u -p -r1.1.1.6 -r1.6
|
||||
--- bgpd/rde_prefix.c 14 Feb 2010 20:19:57 -0000 1.1.1.6
|
||||
+++ bgpd/rde_prefix.c 13 Oct 2012 18:36:00 -0000 1.6
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* $OpenBSD: rde_prefix.c,v 1.29 2009/05/30 18:27:17 claudio Exp $ */
|
||||
+/* $OpenBSD: rde_prefix.c,v 1.31 2010/01/13 06:02:37 claudio Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org>
|
||||
@@ -38,15 +38,16 @@
|
||||
* pt_lookup: lookup a IP in the prefix table. Mainly for "show ip bgp".
|
||||
* pt_empty: returns true if there is no bgp prefix linked to the pt_entry.
|
||||
* pt_init: initialize prefix table.
|
||||
- * pt_alloc?: allocate a AF specific pt_entry. Internal function.
|
||||
+ * pt_alloc: allocate a AF specific pt_entry. Internal function.
|
||||
* pt_free: free a pt_entry. Internal function.
|
||||
*/
|
||||
|
||||
/* internal prototypes */
|
||||
-static struct pt_entry4 *pt_alloc4(void);
|
||||
-static struct pt_entry6 *pt_alloc6(void);
|
||||
+static struct pt_entry *pt_alloc(struct pt_entry *);
|
||||
static void pt_free(struct pt_entry *);
|
||||
|
||||
+size_t pt_sizes[AID_MAX] = AID_PTSIZE;
|
||||
+
|
||||
RB_HEAD(pt_tree, pt_entry);
|
||||
RB_PROTOTYPE(pt_tree, pt_entry, pt_e, pt_prefix_cmp);
|
||||
RB_GENERATE(pt_tree, pt_entry, pt_e, pt_prefix_cmp);
|
||||
@@ -70,17 +71,24 @@ void
|
||||
pt_getaddr(struct pt_entry *pte, struct bgpd_addr *addr)
|
||||
{
|
||||
bzero(addr, sizeof(struct bgpd_addr));
|
||||
- switch (pte->af) {
|
||||
- case AF_INET:
|
||||
- addr->af = pte->af;
|
||||
+ addr->aid = pte->aid;
|
||||
+ switch (addr->aid) {
|
||||
+ case AID_INET:
|
||||
addr->v4 = ((struct pt_entry4 *)pte)->prefix4;
|
||||
break;
|
||||
- case AF_INET6:
|
||||
- addr->af = pte->af;
|
||||
+ case AID_INET6:
|
||||
memcpy(&addr->v6, &((struct pt_entry6 *)pte)->prefix6,
|
||||
sizeof(addr->v6));
|
||||
/* XXX scope_id ??? */
|
||||
break;
|
||||
+ case AID_VPN_IPv4:
|
||||
+ addr->vpn4.addr = ((struct pt_entry_vpn4 *)pte)->prefix4;
|
||||
+ addr->vpn4.rd = ((struct pt_entry_vpn4 *)pte)->rd;
|
||||
+ addr->vpn4.labellen = ((struct pt_entry_vpn4 *)pte)->labellen;
|
||||
+ memcpy(addr->vpn4.labelstack,
|
||||
+ ((struct pt_entry_vpn4 *)pte)->labelstack,
|
||||
+ addr->vpn4.labellen);
|
||||
+ break;
|
||||
default:
|
||||
fatalx("pt_getaddr: unknown af");
|
||||
}
|
||||
@@ -89,33 +97,49 @@ pt_getaddr(struct pt_entry *pte, struct
|
||||
struct pt_entry *
|
||||
pt_fill(struct bgpd_addr *prefix, int prefixlen)
|
||||
{
|
||||
- static struct pt_entry4 pte4;
|
||||
- static struct pt_entry6 pte6;
|
||||
- in_addr_t addr_hbo;
|
||||
+ static struct pt_entry4 pte4;
|
||||
+ static struct pt_entry6 pte6;
|
||||
+ static struct pt_entry_vpn4 pte_vpn4;
|
||||
+ in_addr_t addr_hbo;
|
||||
|
||||
- switch (prefix->af) {
|
||||
- case AF_INET:
|
||||
+ switch (prefix->aid) {
|
||||
+ case AID_INET:
|
||||
bzero(&pte4, sizeof(pte4));
|
||||
+ pte4.aid = prefix->aid;
|
||||
if (prefixlen > 32)
|
||||
- fatalx("pt_get: bad IPv4 prefixlen");
|
||||
- pte4.af = AF_INET;
|
||||
+ fatalx("pt_fill: bad IPv4 prefixlen");
|
||||
addr_hbo = ntohl(prefix->v4.s_addr);
|
||||
pte4.prefix4.s_addr = htonl(addr_hbo &
|
||||
prefixlen2mask(prefixlen));
|
||||
pte4.prefixlen = prefixlen;
|
||||
return ((struct pt_entry *)&pte4);
|
||||
- case AF_INET6:
|
||||
+ case AID_INET6:
|
||||
bzero(&pte6, sizeof(pte6));
|
||||
+ pte6.aid = prefix->aid;
|
||||
if (prefixlen > 128)
|
||||
fatalx("pt_get: bad IPv6 prefixlen");
|
||||
- pte6.af = AF_INET6;
|
||||
pte6.prefixlen = prefixlen;
|
||||
inet6applymask(&pte6.prefix6, &prefix->v6, prefixlen);
|
||||
return ((struct pt_entry *)&pte6);
|
||||
+ case AID_VPN_IPv4:
|
||||
+ bzero(&pte_vpn4, sizeof(pte_vpn4));
|
||||
+ pte_vpn4.aid = prefix->aid;
|
||||
+ if (prefixlen > 32)
|
||||
+ fatalx("pt_fill: bad IPv4 prefixlen");
|
||||
+ addr_hbo = ntohl(prefix->vpn4.addr.s_addr);
|
||||
+ pte_vpn4.prefix4.s_addr = htonl(addr_hbo &
|
||||
+ prefixlen2mask(prefixlen));
|
||||
+ pte_vpn4.prefixlen = prefixlen;
|
||||
+ pte_vpn4.rd = prefix->vpn4.rd;
|
||||
+ pte_vpn4.labellen = prefix->vpn4.labellen;
|
||||
+ memcpy(pte_vpn4.labelstack, prefix->vpn4.labelstack,
|
||||
+ prefix->vpn4.labellen);
|
||||
+ return ((struct pt_entry *)&pte_vpn4);
|
||||
default:
|
||||
- log_warnx("pt_get: unknown af");
|
||||
- return (NULL);
|
||||
+ fatalx("pt_fill: unknown af");
|
||||
}
|
||||
+ /* NOT REACHED */
|
||||
+ return (NULL);
|
||||
}
|
||||
|
||||
struct pt_entry *
|
||||
@@ -131,39 +155,12 @@ struct pt_entry *
|
||||
pt_add(struct bgpd_addr *prefix, int prefixlen)
|
||||
{
|
||||
struct pt_entry *p = NULL;
|
||||
- struct pt_entry4 *p4;
|
||||
- struct pt_entry6 *p6;
|
||||
- in_addr_t addr_hbo;
|
||||
-
|
||||
- switch (prefix->af) {
|
||||
- case AF_INET:
|
||||
- p4 = pt_alloc4();
|
||||
- if (prefixlen > 32)
|
||||
- fatalx("pt_add: bad IPv4 prefixlen");
|
||||
- p4->af = AF_INET;
|
||||
- p4->prefixlen = prefixlen;
|
||||
- addr_hbo = ntohl(prefix->v4.s_addr);
|
||||
- p4->prefix4.s_addr = htonl(addr_hbo &
|
||||
- prefixlen2mask(prefixlen));
|
||||
- p = (struct pt_entry *)p4;
|
||||
- break;
|
||||
- case AF_INET6:
|
||||
- p6 = pt_alloc6();
|
||||
- if (prefixlen > 128)
|
||||
- fatalx("pt_add: bad IPv6 prefixlen");
|
||||
- p6->af = AF_INET6;
|
||||
- p6->prefixlen = prefixlen;
|
||||
- inet6applymask(&p6->prefix6, &prefix->v6, prefixlen);
|
||||
- p = (struct pt_entry *)p6;
|
||||
- break;
|
||||
- default:
|
||||
- fatalx("pt_add: unknown af");
|
||||
- }
|
||||
|
||||
- if (RB_INSERT(pt_tree, &pttable, p) != NULL) {
|
||||
- log_warnx("pt_add: insert failed");
|
||||
- return (NULL);
|
||||
- }
|
||||
+ p = pt_fill(prefix, prefixlen);
|
||||
+ p = pt_alloc(p);
|
||||
+
|
||||
+ if (RB_INSERT(pt_tree, &pttable, p) != NULL)
|
||||
+ fatalx("pt_add: insert failed");
|
||||
|
||||
return (p);
|
||||
}
|
||||
@@ -183,13 +180,14 @@ struct pt_entry *
|
||||
pt_lookup(struct bgpd_addr *addr)
|
||||
{
|
||||
struct pt_entry *p;
|
||||
- int i;
|
||||
+ int i = 0;
|
||||
|
||||
- switch (addr->af) {
|
||||
- case AF_INET:
|
||||
+ switch (addr->aid) {
|
||||
+ case AID_INET:
|
||||
+ case AID_VPN_IPv4:
|
||||
i = 32;
|
||||
break;
|
||||
- case AF_INET6:
|
||||
+ case AID_INET6:
|
||||
i = 128;
|
||||
break;
|
||||
default:
|
||||
@@ -206,17 +204,18 @@ pt_lookup(struct bgpd_addr *addr)
|
||||
int
|
||||
pt_prefix_cmp(const struct pt_entry *a, const struct pt_entry *b)
|
||||
{
|
||||
- const struct pt_entry4 *a4, *b4;
|
||||
- const struct pt_entry6 *a6, *b6;
|
||||
- int i;
|
||||
+ const struct pt_entry4 *a4, *b4;
|
||||
+ const struct pt_entry6 *a6, *b6;
|
||||
+ const struct pt_entry_vpn4 *va4, *vb4;
|
||||
+ int i;
|
||||
|
||||
- if (a->af > b->af)
|
||||
+ if (a->aid > b->aid)
|
||||
return (1);
|
||||
- if (a->af < b->af)
|
||||
+ if (a->aid < b->aid)
|
||||
return (-1);
|
||||
|
||||
- switch (a->af) {
|
||||
- case AF_INET:
|
||||
+ switch (a->aid) {
|
||||
+ case AID_INET:
|
||||
a4 = (const struct pt_entry4 *)a;
|
||||
b4 = (const struct pt_entry4 *)b;
|
||||
if (ntohl(a4->prefix4.s_addr) > ntohl(b4->prefix4.s_addr))
|
||||
@@ -228,7 +227,7 @@ pt_prefix_cmp(const struct pt_entry *a,
|
||||
if (a4->prefixlen < b4->prefixlen)
|
||||
return (-1);
|
||||
return (0);
|
||||
- case AF_INET6:
|
||||
+ case AID_INET6:
|
||||
a6 = (const struct pt_entry6 *)a;
|
||||
b6 = (const struct pt_entry6 *)b;
|
||||
|
||||
@@ -242,49 +241,49 @@ pt_prefix_cmp(const struct pt_entry *a,
|
||||
if (a6->prefixlen > b6->prefixlen)
|
||||
return (1);
|
||||
return (0);
|
||||
+ case AID_VPN_IPv4:
|
||||
+ va4 = (const struct pt_entry_vpn4 *)a;
|
||||
+ vb4 = (const struct pt_entry_vpn4 *)b;
|
||||
+ if (ntohl(va4->prefix4.s_addr) > ntohl(vb4->prefix4.s_addr))
|
||||
+ return (1);
|
||||
+ if (ntohl(va4->prefix4.s_addr) < ntohl(vb4->prefix4.s_addr))
|
||||
+ return (-1);
|
||||
+ if (va4->prefixlen > vb4->prefixlen)
|
||||
+ return (1);
|
||||
+ if (va4->prefixlen < vb4->prefixlen)
|
||||
+ return (-1);
|
||||
+ if (betoh64(va4->rd) > betoh64(vb4->rd))
|
||||
+ return (1);
|
||||
+ if (betoh64(va4->rd) < betoh64(vb4->rd))
|
||||
+ return (-1);
|
||||
+ return (0);
|
||||
default:
|
||||
fatalx("pt_prefix_cmp: unknown af");
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
|
||||
-/* returns a zeroed pt_entry function may not return on fail */
|
||||
-static struct pt_entry4 *
|
||||
-pt_alloc4(void)
|
||||
+/*
|
||||
+ * Returns a pt_entry cloned from the one passed in.
|
||||
+ * Function may not return on failure.
|
||||
+ */
|
||||
+static struct pt_entry *
|
||||
+pt_alloc(struct pt_entry *op)
|
||||
{
|
||||
- struct pt_entry4 *p;
|
||||
+ struct pt_entry *p;
|
||||
|
||||
- p = calloc(1, sizeof(*p));
|
||||
+ p = malloc(pt_sizes[op->aid]);
|
||||
if (p == NULL)
|
||||
fatal("pt_alloc");
|
||||
- rdemem.pt4_cnt++;
|
||||
- return (p);
|
||||
-}
|
||||
+ rdemem.pt_cnt[op->aid]++;
|
||||
+ memcpy(p, op, pt_sizes[op->aid]);
|
||||
|
||||
-static struct pt_entry6 *
|
||||
-pt_alloc6(void)
|
||||
-{
|
||||
- struct pt_entry6 *p;
|
||||
-
|
||||
- p = calloc(1, sizeof(*p));
|
||||
- if (p == NULL)
|
||||
- fatal("pt_alloc");
|
||||
- rdemem.pt6_cnt++;
|
||||
return (p);
|
||||
}
|
||||
|
||||
static void
|
||||
pt_free(struct pt_entry *pte)
|
||||
{
|
||||
- switch (pte->af) {
|
||||
- case AF_INET:
|
||||
- rdemem.pt4_cnt--;
|
||||
- break;
|
||||
- case AF_INET6:
|
||||
- rdemem.pt6_cnt--;
|
||||
- break;
|
||||
- default:
|
||||
- break;
|
||||
- }
|
||||
+ rdemem.pt_cnt[pte->aid]--;
|
||||
free(pte);
|
||||
}
|
513
net/openbgpd/files/patch-bgpd_rde_rib.c
Normal file
513
net/openbgpd/files/patch-bgpd_rde_rib.c
Normal file
@ -0,0 +1,513 @@
|
||||
Index: bgpd/rde_rib.c
|
||||
===================================================================
|
||||
RCS file: /home/cvs/private/hrs/openbgpd/bgpd/rde_rib.c,v
|
||||
retrieving revision 1.1.1.7
|
||||
retrieving revision 1.8
|
||||
diff -u -p -r1.1.1.7 -r1.8
|
||||
--- bgpd/rde_rib.c 14 Feb 2010 20:19:57 -0000 1.1.1.7
|
||||
+++ bgpd/rde_rib.c 13 Oct 2012 18:36:00 -0000 1.8
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* $OpenBSD: rde_rib.c,v 1.116 2009/06/29 14:13:48 claudio Exp $ */
|
||||
+/* $OpenBSD: rde_rib.c,v 1.133 2012/07/01 11:55:13 sthen Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org>
|
||||
@@ -18,7 +18,11 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/queue.h>
|
||||
+#if defined(__FreeBSD__) /* sys/hash.h */
|
||||
+#include "hash.h"
|
||||
+#else
|
||||
#include <sys/hash.h>
|
||||
+#endif /* defined(__FreeBSD__) */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -50,16 +54,15 @@ RB_GENERATE(rib_tree, rib_entry, rib_e,
|
||||
|
||||
/* RIB specific functions */
|
||||
u_int16_t
|
||||
-rib_new(int id, char *name, u_int16_t flags)
|
||||
+rib_new(char *name, u_int rtableid, u_int16_t flags)
|
||||
{
|
||||
struct rib *xribs;
|
||||
size_t newsize;
|
||||
+ u_int16_t id;
|
||||
|
||||
- if (id < 0) {
|
||||
- for (id = 0; id < rib_size; id++) {
|
||||
- if (*ribs[id].name == '\0')
|
||||
- break;
|
||||
- }
|
||||
+ for (id = 0; id < rib_size; id++) {
|
||||
+ if (*ribs[id].name == '\0')
|
||||
+ break;
|
||||
}
|
||||
|
||||
if (id == RIB_FAILED)
|
||||
@@ -78,9 +81,10 @@ rib_new(int id, char *name, u_int16_t fl
|
||||
bzero(&ribs[id], sizeof(struct rib));
|
||||
strlcpy(ribs[id].name, name, sizeof(ribs[id].name));
|
||||
RB_INIT(&ribs[id].rib);
|
||||
- ribs[id].state = RIB_ACTIVE;
|
||||
+ ribs[id].state = RECONF_REINIT;
|
||||
ribs[id].id = id;
|
||||
ribs[id].flags = flags;
|
||||
+ ribs[id].rtableid = rtableid;
|
||||
|
||||
return (id);
|
||||
}
|
||||
@@ -173,15 +177,16 @@ rib_lookup(struct rib *rib, struct bgpd_
|
||||
struct rib_entry *re;
|
||||
int i;
|
||||
|
||||
- switch (addr->af) {
|
||||
- case AF_INET:
|
||||
+ switch (addr->aid) {
|
||||
+ case AID_INET:
|
||||
+ case AID_VPN_IPv4:
|
||||
for (i = 32; i >= 0; i--) {
|
||||
re = rib_get(rib, addr, i);
|
||||
if (re != NULL)
|
||||
return (re);
|
||||
}
|
||||
break;
|
||||
- case AF_INET6:
|
||||
+ case AID_INET6:
|
||||
for (i = 128; i >= 0; i--) {
|
||||
re = rib_get(rib, addr, i);
|
||||
if (re != NULL)
|
||||
@@ -215,6 +220,7 @@ rib_add(struct rib *rib, struct bgpd_add
|
||||
|
||||
if (RB_INSERT(rib_tree, &rib->rib, re) != NULL) {
|
||||
log_warnx("rib_add: insert failed");
|
||||
+ free(re);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
@@ -254,7 +260,7 @@ rib_empty(struct rib_entry *re)
|
||||
|
||||
void
|
||||
rib_dump(struct rib *rib, void (*upcall)(struct rib_entry *, void *),
|
||||
- void *arg, sa_family_t af)
|
||||
+ void *arg, u_int8_t aid)
|
||||
{
|
||||
struct rib_context *ctx;
|
||||
|
||||
@@ -263,7 +269,7 @@ rib_dump(struct rib *rib, void (*upcall)
|
||||
ctx->ctx_rib = rib;
|
||||
ctx->ctx_upcall = upcall;
|
||||
ctx->ctx_arg = arg;
|
||||
- ctx->ctx_af = af;
|
||||
+ ctx->ctx_aid = aid;
|
||||
rib_dump_r(ctx);
|
||||
}
|
||||
|
||||
@@ -280,7 +286,8 @@ rib_dump_r(struct rib_context *ctx)
|
||||
re = rib_restart(ctx);
|
||||
|
||||
for (i = 0; re != NULL; re = RB_NEXT(rib_tree, unused, re)) {
|
||||
- if (ctx->ctx_af != AF_UNSPEC && ctx->ctx_af != re->prefix->af)
|
||||
+ if (ctx->ctx_aid != AID_UNSPEC &&
|
||||
+ ctx->ctx_aid != re->prefix->aid)
|
||||
continue;
|
||||
if (ctx->ctx_count && i++ >= ctx->ctx_count &&
|
||||
(re->flags & F_RIB_ENTRYLOCK) == 0) {
|
||||
@@ -308,7 +315,7 @@ rib_restart(struct rib_context *ctx)
|
||||
re->flags &= ~F_RIB_ENTRYLOCK;
|
||||
|
||||
/* find first non empty element */
|
||||
- while (rib_empty(re))
|
||||
+ while (re && rib_empty(re))
|
||||
re = RB_NEXT(rib_tree, unused, re);
|
||||
|
||||
/* free the previously locked rib element if empty */
|
||||
@@ -502,6 +509,36 @@ path_remove(struct rde_aspath *asp)
|
||||
}
|
||||
}
|
||||
|
||||
+/* remove all stale routes or if staletime is 0 remove all routes for
|
||||
+ a specified AID. */
|
||||
+void
|
||||
+path_remove_stale(struct rde_aspath *asp, u_int8_t aid)
|
||||
+{
|
||||
+ struct prefix *p, *np;
|
||||
+ time_t staletime;
|
||||
+
|
||||
+ staletime = asp->peer->staletime[aid];
|
||||
+ for (p = LIST_FIRST(&asp->prefix_h); p != NULL; p = np) {
|
||||
+ np = LIST_NEXT(p, path_l);
|
||||
+ if (p->prefix->aid != aid)
|
||||
+ continue;
|
||||
+
|
||||
+ if (staletime && p->lastchange > staletime)
|
||||
+ continue;
|
||||
+
|
||||
+ if (asp->pftableid) {
|
||||
+ struct bgpd_addr addr;
|
||||
+
|
||||
+ pt_getaddr(p->prefix, &addr);
|
||||
+ /* Commit is done in peer_flush() */
|
||||
+ rde_send_pftable(p->aspath->pftableid, &addr,
|
||||
+ p->prefix->prefixlen, 1);
|
||||
+ }
|
||||
+ prefix_destroy(p);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+
|
||||
/* this function is only called by prefix_remove and path_remove */
|
||||
void
|
||||
path_destroy(struct rde_aspath *asp)
|
||||
@@ -624,48 +661,6 @@ static void prefix_link(struct prefix
|
||||
struct rde_aspath *);
|
||||
static void prefix_unlink(struct prefix *);
|
||||
|
||||
-int
|
||||
-prefix_compare(const struct bgpd_addr *a, const struct bgpd_addr *b,
|
||||
- int prefixlen)
|
||||
-{
|
||||
- in_addr_t mask, aa, ba;
|
||||
- int i;
|
||||
- u_int8_t m;
|
||||
-
|
||||
- if (a->af != b->af)
|
||||
- return (a->af - b->af);
|
||||
-
|
||||
- switch (a->af) {
|
||||
- case AF_INET:
|
||||
- if (prefixlen > 32)
|
||||
- fatalx("prefix_cmp: bad IPv4 prefixlen");
|
||||
- mask = htonl(prefixlen2mask(prefixlen));
|
||||
- aa = ntohl(a->v4.s_addr & mask);
|
||||
- ba = ntohl(b->v4.s_addr & mask);
|
||||
- if (aa != ba)
|
||||
- return (aa - ba);
|
||||
- return (0);
|
||||
- case AF_INET6:
|
||||
- if (prefixlen > 128)
|
||||
- fatalx("prefix_cmp: bad IPv6 prefixlen");
|
||||
- for (i = 0; i < prefixlen / 8; i++)
|
||||
- if (a->v6.s6_addr[i] != b->v6.s6_addr[i])
|
||||
- return (a->v6.s6_addr[i] - b->v6.s6_addr[i]);
|
||||
- i = prefixlen % 8;
|
||||
- if (i) {
|
||||
- m = 0xff00 >> i;
|
||||
- if ((a->v6.s6_addr[prefixlen / 8] & m) !=
|
||||
- (b->v6.s6_addr[prefixlen / 8] & m))
|
||||
- return ((a->v6.s6_addr[prefixlen / 8] & m) -
|
||||
- (b->v6.s6_addr[prefixlen / 8] & m));
|
||||
- }
|
||||
- return (0);
|
||||
- default:
|
||||
- fatalx("prefix_cmp: unknown af");
|
||||
- }
|
||||
- return (-1);
|
||||
-}
|
||||
-
|
||||
/*
|
||||
* search for specified prefix of a peer. Returns NULL if not found.
|
||||
*/
|
||||
@@ -806,16 +801,58 @@ prefix_write(u_char *buf, int len, struc
|
||||
{
|
||||
int totlen;
|
||||
|
||||
- if (prefix->af != AF_INET && prefix->af != AF_INET6)
|
||||
+ switch (prefix->aid) {
|
||||
+ case AID_INET:
|
||||
+ case AID_INET6:
|
||||
+ totlen = PREFIX_SIZE(plen);
|
||||
+
|
||||
+ if (totlen > len)
|
||||
+ return (-1);
|
||||
+ *buf++ = plen;
|
||||
+ memcpy(buf, &prefix->ba, totlen - 1);
|
||||
+ return (totlen);
|
||||
+ case AID_VPN_IPv4:
|
||||
+ totlen = PREFIX_SIZE(plen) + sizeof(prefix->vpn4.rd) +
|
||||
+ prefix->vpn4.labellen;
|
||||
+ plen += (sizeof(prefix->vpn4.rd) + prefix->vpn4.labellen) * 8;
|
||||
+
|
||||
+ if (totlen > len)
|
||||
+ return (-1);
|
||||
+ *buf++ = plen;
|
||||
+ memcpy(buf, &prefix->vpn4.labelstack, prefix->vpn4.labellen);
|
||||
+ buf += prefix->vpn4.labellen;
|
||||
+ memcpy(buf, &prefix->vpn4.rd, sizeof(prefix->vpn4.rd));
|
||||
+ buf += sizeof(prefix->vpn4.rd);
|
||||
+ memcpy(buf, &prefix->vpn4.addr, PREFIX_SIZE(plen) - 1);
|
||||
+ return (totlen);
|
||||
+ default:
|
||||
return (-1);
|
||||
+ }
|
||||
+}
|
||||
|
||||
- totlen = PREFIX_SIZE(plen);
|
||||
+int
|
||||
+prefix_writebuf(struct ibuf *buf, struct bgpd_addr *prefix, u_int8_t plen)
|
||||
+{
|
||||
+ int totlen;
|
||||
+ void *bptr;
|
||||
|
||||
- if (totlen > len)
|
||||
+ switch (prefix->aid) {
|
||||
+ case AID_INET:
|
||||
+ case AID_INET6:
|
||||
+ totlen = PREFIX_SIZE(plen);
|
||||
+ break;
|
||||
+ case AID_VPN_IPv4:
|
||||
+ totlen = PREFIX_SIZE(plen) + sizeof(prefix->vpn4.rd) +
|
||||
+ prefix->vpn4.labellen;
|
||||
+ default:
|
||||
return (-1);
|
||||
- *buf++ = plen;
|
||||
- memcpy(buf, &prefix->ba, totlen - 1);
|
||||
- return (totlen);
|
||||
+ }
|
||||
+
|
||||
+ if ((bptr = ibuf_reserve(buf, totlen)) == NULL)
|
||||
+ return (-1);
|
||||
+ if (prefix_write(bptr, totlen, prefix, plen) == -1)
|
||||
+ return (-1);
|
||||
+ return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -861,7 +898,7 @@ prefix_updateall(struct rde_aspath *asp,
|
||||
*/
|
||||
if ((p->rib->flags & F_RIB_NOFIB) == 0 &&
|
||||
p == p->rib->active)
|
||||
- rde_send_kroute(p, NULL);
|
||||
+ rde_send_kroute(p, NULL, p->rib->ribid);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -871,7 +908,7 @@ prefix_updateall(struct rde_aspath *asp,
|
||||
* If the prefix is the active one remove it first,
|
||||
* this has to be done because we can not detect when
|
||||
* the active prefix changes its state. In this case
|
||||
- * we know that this is a withdrawl and so the second
|
||||
+ * we know that this is a withdrawal and so the second
|
||||
* prefix_evaluate() will generate no update because
|
||||
* the nexthop is unreachable or ineligible.
|
||||
*/
|
||||
@@ -885,16 +922,12 @@ prefix_updateall(struct rde_aspath *asp,
|
||||
void
|
||||
prefix_destroy(struct prefix *p)
|
||||
{
|
||||
- struct rib_entry *re;
|
||||
struct rde_aspath *asp;
|
||||
|
||||
- re = p->rib;
|
||||
asp = p->aspath;
|
||||
prefix_unlink(p);
|
||||
prefix_free(p);
|
||||
|
||||
- if (rib_empty(re))
|
||||
- rib_remove(re);
|
||||
if (path_empty(asp))
|
||||
path_destroy(asp);
|
||||
}
|
||||
@@ -907,21 +940,16 @@ prefix_network_clean(struct rde_peer *pe
|
||||
{
|
||||
struct rde_aspath *asp, *xasp;
|
||||
struct prefix *p, *xp;
|
||||
- struct pt_entry *pte;
|
||||
|
||||
for (asp = LIST_FIRST(&peer->path_h); asp != NULL; asp = xasp) {
|
||||
xasp = LIST_NEXT(asp, peer_l);
|
||||
- if ((asp->flags & F_ANN_DYNAMIC) == flags)
|
||||
+ if ((asp->flags & F_ANN_DYNAMIC) != flags)
|
||||
continue;
|
||||
for (p = LIST_FIRST(&asp->prefix_h); p != NULL; p = xp) {
|
||||
xp = LIST_NEXT(p, path_l);
|
||||
if (reloadtime > p->lastchange) {
|
||||
- pte = p->prefix;
|
||||
prefix_unlink(p);
|
||||
prefix_free(p);
|
||||
-
|
||||
- if (pt_empty(pte))
|
||||
- pt_remove(pte);
|
||||
}
|
||||
}
|
||||
if (path_empty(asp))
|
||||
@@ -954,11 +982,11 @@ prefix_link(struct prefix *pref, struct
|
||||
static void
|
||||
prefix_unlink(struct prefix *pref)
|
||||
{
|
||||
- if (pref->rib) {
|
||||
- /* make route decision */
|
||||
- LIST_REMOVE(pref, rib_l);
|
||||
- prefix_evaluate(NULL, pref->rib);
|
||||
- }
|
||||
+ struct rib_entry *re = pref->rib;
|
||||
+
|
||||
+ /* make route decision */
|
||||
+ LIST_REMOVE(pref, rib_l);
|
||||
+ prefix_evaluate(NULL, re);
|
||||
|
||||
LIST_REMOVE(pref, path_l);
|
||||
PREFIX_COUNT(pref->aspath, -1);
|
||||
@@ -966,6 +994,8 @@ prefix_unlink(struct prefix *pref)
|
||||
pt_unref(pref->prefix);
|
||||
if (pt_empty(pref->prefix))
|
||||
pt_remove(pref->prefix);
|
||||
+ if (rib_empty(re))
|
||||
+ rib_remove(re);
|
||||
|
||||
/* destroy all references to other objects */
|
||||
pref->aspath = NULL;
|
||||
@@ -973,8 +1003,8 @@ prefix_unlink(struct prefix *pref)
|
||||
pref->rib = NULL;
|
||||
|
||||
/*
|
||||
- * It's the caller's duty to remove empty aspath respectively pt_entry
|
||||
- * structures. Also freeing the unlinked prefix is the caller's duty.
|
||||
+ * It's the caller's duty to remove empty aspath structures.
|
||||
+ * Also freeing the unlinked prefix is the caller's duty.
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -1070,10 +1100,6 @@ nexthop_update(struct kroute_nexthop *ms
|
||||
return;
|
||||
}
|
||||
|
||||
- if (nexthop_delete(nh))
|
||||
- /* nexthop no longer used */
|
||||
- return;
|
||||
-
|
||||
oldstate = nh->state;
|
||||
if (msg->valid)
|
||||
nh->state = NEXTHOP_REACH;
|
||||
@@ -1088,21 +1114,13 @@ nexthop_update(struct kroute_nexthop *ms
|
||||
memcpy(&nh->true_nexthop, &msg->gateway,
|
||||
sizeof(nh->true_nexthop));
|
||||
|
||||
- switch (msg->nexthop.af) {
|
||||
- case AF_INET:
|
||||
- nh->nexthop_netlen = msg->kr.kr4.prefixlen;
|
||||
- nh->nexthop_net.af = AF_INET;
|
||||
- nh->nexthop_net.v4.s_addr = msg->kr.kr4.prefix.s_addr;
|
||||
- break;
|
||||
- case AF_INET6:
|
||||
- nh->nexthop_netlen = msg->kr.kr6.prefixlen;
|
||||
- nh->nexthop_net.af = AF_INET6;
|
||||
- memcpy(&nh->nexthop_net.v6, &msg->kr.kr6.prefix,
|
||||
- sizeof(struct in6_addr));
|
||||
- break;
|
||||
- default:
|
||||
- fatalx("nexthop_update: unknown af");
|
||||
- }
|
||||
+ memcpy(&nh->nexthop_net, &msg->net,
|
||||
+ sizeof(nh->nexthop_net));
|
||||
+ nh->nexthop_netlen = msg->netlen;
|
||||
+
|
||||
+ if (nexthop_delete(nh))
|
||||
+ /* nexthop no longer used */
|
||||
+ return;
|
||||
|
||||
if (rde_noevaluate())
|
||||
/*
|
||||
@@ -1118,35 +1136,38 @@ nexthop_update(struct kroute_nexthop *ms
|
||||
|
||||
void
|
||||
nexthop_modify(struct rde_aspath *asp, struct bgpd_addr *nexthop,
|
||||
- enum action_types type, sa_family_t af)
|
||||
+ enum action_types type, u_int8_t aid)
|
||||
{
|
||||
struct nexthop *nh;
|
||||
|
||||
- if (type == ACTION_SET_NEXTHOP_REJECT) {
|
||||
- asp->flags |= F_NEXTHOP_REJECT;
|
||||
+ if (type == ACTION_SET_NEXTHOP && aid != nexthop->aid)
|
||||
return;
|
||||
- }
|
||||
- if (type == ACTION_SET_NEXTHOP_BLACKHOLE) {
|
||||
+
|
||||
+ asp->flags &= ~F_NEXTHOP_MASK;
|
||||
+ switch (type) {
|
||||
+ case ACTION_SET_NEXTHOP_REJECT:
|
||||
+ asp->flags |= F_NEXTHOP_REJECT;
|
||||
+ break;
|
||||
+ case ACTION_SET_NEXTHOP_BLACKHOLE:
|
||||
asp->flags |= F_NEXTHOP_BLACKHOLE;
|
||||
- return;
|
||||
- }
|
||||
- if (type == ACTION_SET_NEXTHOP_NOMODIFY) {
|
||||
+ break;
|
||||
+ case ACTION_SET_NEXTHOP_NOMODIFY:
|
||||
asp->flags |= F_NEXTHOP_NOMODIFY;
|
||||
- return;
|
||||
- }
|
||||
- if (type == ACTION_SET_NEXTHOP_SELF) {
|
||||
+ break;
|
||||
+ case ACTION_SET_NEXTHOP_SELF:
|
||||
asp->flags |= F_NEXTHOP_SELF;
|
||||
- return;
|
||||
+ break;
|
||||
+ case ACTION_SET_NEXTHOP:
|
||||
+ nh = nexthop_get(nexthop);
|
||||
+ if (asp->flags & F_ATTR_LINKED)
|
||||
+ nexthop_unlink(asp);
|
||||
+ asp->nexthop = nh;
|
||||
+ if (asp->flags & F_ATTR_LINKED)
|
||||
+ nexthop_link(asp);
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
}
|
||||
- if (af != nexthop->af)
|
||||
- return;
|
||||
-
|
||||
- nh = nexthop_get(nexthop);
|
||||
- if (asp->flags & F_ATTR_LINKED)
|
||||
- nexthop_unlink(asp);
|
||||
- asp->nexthop = nh;
|
||||
- if (asp->flags & F_ATTR_LINKED)
|
||||
- nexthop_link(asp);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1233,17 +1254,17 @@ nexthop_compare(struct nexthop *na, stru
|
||||
a = &na->exit_nexthop;
|
||||
b = &nb->exit_nexthop;
|
||||
|
||||
- if (a->af != b->af)
|
||||
- return (a->af - b->af);
|
||||
+ if (a->aid != b->aid)
|
||||
+ return (a->aid - b->aid);
|
||||
|
||||
- switch (a->af) {
|
||||
- case AF_INET:
|
||||
+ switch (a->aid) {
|
||||
+ case AID_INET:
|
||||
if (ntohl(a->v4.s_addr) > ntohl(b->v4.s_addr))
|
||||
return (1);
|
||||
if (ntohl(a->v4.s_addr) < ntohl(b->v4.s_addr))
|
||||
return (-1);
|
||||
return (0);
|
||||
- case AF_INET6:
|
||||
+ case AID_INET6:
|
||||
return (memcmp(&a->v6, &b->v6, sizeof(struct in6_addr)));
|
||||
default:
|
||||
fatalx("nexthop_cmp: unknown af");
|
||||
@@ -1269,14 +1290,14 @@ nexthop_hash(struct bgpd_addr *nexthop)
|
||||
{
|
||||
u_int32_t h = 0;
|
||||
|
||||
- switch (nexthop->af) {
|
||||
- case AF_INET:
|
||||
+ switch (nexthop->aid) {
|
||||
+ case AID_INET:
|
||||
h = (AF_INET ^ ntohl(nexthop->v4.s_addr) ^
|
||||
ntohl(nexthop->v4.s_addr) >> 13) &
|
||||
nexthoptable.nexthop_hashmask;
|
||||
break;
|
||||
- case AF_INET6:
|
||||
- h = hash32_buf(nexthop->v6.s6_addr, sizeof(struct in6_addr),
|
||||
+ case AID_INET6:
|
||||
+ h = hash32_buf(&nexthop->v6, sizeof(struct in6_addr),
|
||||
HASHINIT) & nexthoptable.nexthop_hashmask;
|
||||
break;
|
||||
default:
|
644
net/openbgpd/files/patch-bgpd_rde_update.c
Normal file
644
net/openbgpd/files/patch-bgpd_rde_update.c
Normal file
@ -0,0 +1,644 @@
|
||||
Index: bgpd/rde_update.c
|
||||
===================================================================
|
||||
RCS file: /home/cvs/private/hrs/openbgpd/bgpd/rde_update.c,v
|
||||
retrieving revision 1.1.1.7
|
||||
retrieving revision 1.8
|
||||
diff -u -p -r1.1.1.7 -r1.8
|
||||
--- bgpd/rde_update.c 14 Feb 2010 20:19:57 -0000 1.1.1.7
|
||||
+++ bgpd/rde_update.c 13 Oct 2012 18:36:00 -0000 1.8
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* $OpenBSD: rde_update.c,v 1.68 2009/06/06 01:10:29 claudio Exp $ */
|
||||
+/* $OpenBSD: rde_update.c,v 1.77 2010/01/13 06:02:37 claudio Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
|
||||
@@ -17,19 +17,27 @@
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <sys/queue.h>
|
||||
+#if defined(__FreeBSD__) /* sys/hash.h */
|
||||
+#include "hash.h"
|
||||
+#else
|
||||
#include <sys/hash.h>
|
||||
+#endif /* defined(__FreeBSD__) */
|
||||
|
||||
+#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
+#if defined(__FreeBSD__) /* limits.h */
|
||||
+#include <limits.h>
|
||||
+#endif /* defined(__FreeBSD__) */
|
||||
|
||||
#include "bgpd.h"
|
||||
#include "rde.h"
|
||||
|
||||
in_addr_t up_get_nexthop(struct rde_peer *, struct rde_aspath *);
|
||||
int up_generate_mp_reach(struct rde_peer *, struct update_attr *,
|
||||
- struct rde_aspath *, sa_family_t);
|
||||
+ struct rde_aspath *, u_int8_t);
|
||||
int up_generate_attr(struct rde_peer *, struct update_attr *,
|
||||
- struct rde_aspath *, sa_family_t);
|
||||
+ struct rde_aspath *, u_int8_t);
|
||||
|
||||
/* update stuff. */
|
||||
struct update_prefix {
|
||||
@@ -65,10 +73,12 @@ RB_GENERATE(uptree_attr, update_attr, en
|
||||
void
|
||||
up_init(struct rde_peer *peer)
|
||||
{
|
||||
- TAILQ_INIT(&peer->updates);
|
||||
- TAILQ_INIT(&peer->withdraws);
|
||||
- TAILQ_INIT(&peer->updates6);
|
||||
- TAILQ_INIT(&peer->withdraws6);
|
||||
+ u_int8_t i;
|
||||
+
|
||||
+ for (i = 0; i < AID_MAX; i++) {
|
||||
+ TAILQ_INIT(&peer->updates[i]);
|
||||
+ TAILQ_INIT(&peer->withdraws[i]);
|
||||
+ }
|
||||
RB_INIT(&peer->up_prefix);
|
||||
RB_INIT(&peer->up_attrs);
|
||||
peer->up_pcnt = 0;
|
||||
@@ -103,8 +113,10 @@ up_clear(struct uplist_attr *updates, st
|
||||
void
|
||||
up_down(struct rde_peer *peer)
|
||||
{
|
||||
- up_clear(&peer->updates, &peer->withdraws);
|
||||
- up_clear(&peer->updates6, &peer->withdraws6);
|
||||
+ u_int8_t i;
|
||||
+
|
||||
+ for (i = 0; i < AID_MAX; i++)
|
||||
+ up_clear(&peer->updates[i], &peer->withdraws[i]);
|
||||
|
||||
RB_INIT(&peer->up_prefix);
|
||||
RB_INIT(&peer->up_attrs);
|
||||
@@ -120,19 +132,19 @@ up_prefix_cmp(struct update_prefix *a, s
|
||||
{
|
||||
int i;
|
||||
|
||||
- if (a->prefix.af < b->prefix.af)
|
||||
+ if (a->prefix.aid < b->prefix.aid)
|
||||
return (-1);
|
||||
- if (a->prefix.af > b->prefix.af)
|
||||
+ if (a->prefix.aid > b->prefix.aid)
|
||||
return (1);
|
||||
|
||||
- switch (a->prefix.af) {
|
||||
- case AF_INET:
|
||||
+ switch (a->prefix.aid) {
|
||||
+ case AID_INET:
|
||||
if (ntohl(a->prefix.v4.s_addr) < ntohl(b->prefix.v4.s_addr))
|
||||
return (-1);
|
||||
if (ntohl(a->prefix.v4.s_addr) > ntohl(b->prefix.v4.s_addr))
|
||||
return (1);
|
||||
break;
|
||||
- case AF_INET6:
|
||||
+ case AID_INET6:
|
||||
i = memcmp(&a->prefix.v6, &b->prefix.v6,
|
||||
sizeof(struct in6_addr));
|
||||
if (i > 0)
|
||||
@@ -140,6 +152,25 @@ up_prefix_cmp(struct update_prefix *a, s
|
||||
if (i < 0)
|
||||
return (-1);
|
||||
break;
|
||||
+ case AID_VPN_IPv4:
|
||||
+ if (betoh64(a->prefix.vpn4.rd) < betoh64(b->prefix.vpn4.rd))
|
||||
+ return (-1);
|
||||
+ if (betoh64(a->prefix.vpn4.rd) > betoh64(b->prefix.vpn4.rd))
|
||||
+ return (1);
|
||||
+ if (ntohl(a->prefix.v4.s_addr) < ntohl(b->prefix.v4.s_addr))
|
||||
+ return (-1);
|
||||
+ if (ntohl(a->prefix.v4.s_addr) > ntohl(b->prefix.v4.s_addr))
|
||||
+ return (1);
|
||||
+ if (a->prefixlen < b->prefixlen)
|
||||
+ return (-1);
|
||||
+ if (a->prefixlen > b->prefixlen)
|
||||
+ return (1);
|
||||
+ if (a->prefix.vpn4.labellen < b->prefix.vpn4.labellen)
|
||||
+ return (-1);
|
||||
+ if (a->prefix.vpn4.labellen > b->prefix.vpn4.labellen)
|
||||
+ return (1);
|
||||
+ return (memcmp(a->prefix.vpn4.labelstack,
|
||||
+ b->prefix.vpn4.labelstack, a->prefix.vpn4.labellen));
|
||||
default:
|
||||
fatalx("pt_prefix_cmp: unknown af");
|
||||
}
|
||||
@@ -174,18 +205,8 @@ up_add(struct rde_peer *peer, struct upd
|
||||
struct uplist_attr *upl = NULL;
|
||||
struct uplist_prefix *wdl = NULL;
|
||||
|
||||
- switch (p->prefix.af) {
|
||||
- case AF_INET:
|
||||
- upl = &peer->updates;
|
||||
- wdl = &peer->withdraws;
|
||||
- break;
|
||||
- case AF_INET6:
|
||||
- upl = &peer->updates6;
|
||||
- wdl = &peer->withdraws6;
|
||||
- break;
|
||||
- default:
|
||||
- fatalx("up_add: unknown AF");
|
||||
- }
|
||||
+ upl = &peer->updates[p->prefix.aid];
|
||||
+ wdl = &peer->withdraws[p->prefix.aid];
|
||||
|
||||
/* 1. search for attr */
|
||||
if (a != NULL && (na = RB_FIND(uptree_attr, &peer->up_attrs, a)) ==
|
||||
@@ -270,23 +291,16 @@ up_test_update(struct rde_peer *peer, st
|
||||
/* Do not send routes back to sender */
|
||||
return (0);
|
||||
|
||||
+ if (p->aspath->flags & F_ATTR_PARSE_ERR)
|
||||
+ fatalx("try to send out a botched path");
|
||||
if (p->aspath->flags & F_ATTR_LOOP)
|
||||
fatalx("try to send out a looped path");
|
||||
|
||||
pt_getaddr(p->prefix, &addr);
|
||||
- switch (addr.af) {
|
||||
- case AF_INET:
|
||||
- if (peer->capa_announced.mp_v4 == SAFI_NONE &&
|
||||
- peer->capa_received.mp_v6 != SAFI_NONE)
|
||||
- return (-1);
|
||||
- break;
|
||||
- case AF_INET6:
|
||||
- if (peer->capa_announced.mp_v6 == SAFI_NONE)
|
||||
- return (-1);
|
||||
- break;
|
||||
- }
|
||||
+ if (peer->capa.mp[addr.aid] == 0)
|
||||
+ return (-1);
|
||||
|
||||
- if (p->aspath->peer->conf.ebgp == 0 && peer->conf.ebgp == 0) {
|
||||
+ if (!p->aspath->peer->conf.ebgp && !peer->conf.ebgp) {
|
||||
/*
|
||||
* route reflector redistribution rules:
|
||||
* 1. if announce is set -> announce
|
||||
@@ -325,13 +339,13 @@ up_test_update(struct rde_peer *peer, st
|
||||
}
|
||||
|
||||
/* well known communities */
|
||||
- if (rde_filter_community(p->aspath,
|
||||
+ if (community_match(p->aspath,
|
||||
COMMUNITY_WELLKNOWN, COMMUNITY_NO_ADVERTISE))
|
||||
return (0);
|
||||
- if (peer->conf.ebgp && rde_filter_community(p->aspath,
|
||||
+ if (peer->conf.ebgp && community_match(p->aspath,
|
||||
COMMUNITY_WELLKNOWN, COMMUNITY_NO_EXPORT))
|
||||
return (0);
|
||||
- if (peer->conf.ebgp && rde_filter_community(p->aspath,
|
||||
+ if (peer->conf.ebgp && community_match(p->aspath,
|
||||
COMMUNITY_WELLKNOWN, COMMUNITY_NO_EXPSUBCONFED))
|
||||
return (0);
|
||||
|
||||
@@ -362,7 +376,7 @@ up_generate(struct rde_peer *peer, struc
|
||||
if (ua == NULL)
|
||||
fatal("up_generate");
|
||||
|
||||
- if (up_generate_attr(peer, ua, asp, addr->af) == -1) {
|
||||
+ if (up_generate_attr(peer, ua, asp, addr->aid) == -1) {
|
||||
log_warnx("generation of bgp path attributes failed");
|
||||
free(ua);
|
||||
return (-1);
|
||||
@@ -444,18 +458,12 @@ up_generate_updates(struct filter_head *
|
||||
/* send a default route to the specified peer */
|
||||
void
|
||||
up_generate_default(struct filter_head *rules, struct rde_peer *peer,
|
||||
- sa_family_t af)
|
||||
+ u_int8_t aid)
|
||||
{
|
||||
struct rde_aspath *asp, *fasp;
|
||||
struct bgpd_addr addr;
|
||||
|
||||
- if (peer->capa_received.mp_v4 == SAFI_NONE &&
|
||||
- peer->capa_received.mp_v6 != SAFI_NONE &&
|
||||
- af == AF_INET)
|
||||
- return;
|
||||
-
|
||||
- if (peer->capa_received.mp_v6 == SAFI_NONE &&
|
||||
- af == AF_INET6)
|
||||
+ if (peer->capa.mp[aid] == 0)
|
||||
return;
|
||||
|
||||
asp = path_get();
|
||||
@@ -471,7 +479,7 @@ up_generate_default(struct filter_head *
|
||||
|
||||
/* filter as usual */
|
||||
bzero(&addr, sizeof(addr));
|
||||
- addr.af = af;
|
||||
+ addr.aid = aid;
|
||||
|
||||
if (rde_filter(peer->ribid, &fasp, rules, peer, asp, &addr, 0, NULL,
|
||||
DIR_OUT) == ACTION_DENY) {
|
||||
@@ -491,6 +499,43 @@ up_generate_default(struct filter_head *
|
||||
path_put(asp);
|
||||
}
|
||||
|
||||
+/* generate a EoR marker in the update list. This is a horrible hack. */
|
||||
+int
|
||||
+up_generate_marker(struct rde_peer *peer, u_int8_t aid)
|
||||
+{
|
||||
+ struct update_attr *ua;
|
||||
+ struct update_attr *na = NULL;
|
||||
+ struct uplist_attr *upl = NULL;
|
||||
+
|
||||
+ ua = calloc(1, sizeof(struct update_attr));
|
||||
+ if (ua == NULL)
|
||||
+ fatal("up_generate_marker");
|
||||
+
|
||||
+ upl = &peer->updates[aid];
|
||||
+
|
||||
+ /* 1. search for attr */
|
||||
+ if ((na = RB_FIND(uptree_attr, &peer->up_attrs, ua)) == NULL) {
|
||||
+ /* 1.1 if not found -> add */
|
||||
+ TAILQ_INIT(&ua->prefix_h);
|
||||
+ if (RB_INSERT(uptree_attr, &peer->up_attrs, ua) != NULL) {
|
||||
+ log_warnx("uptree_attr insert failed");
|
||||
+ /* cleanup */
|
||||
+ free(ua);
|
||||
+ return (-1);
|
||||
+ }
|
||||
+ TAILQ_INSERT_TAIL(upl, ua, attr_l);
|
||||
+ peer->up_acnt++;
|
||||
+ } else {
|
||||
+ /* 1.2 if found -> use that, free ua */
|
||||
+ free(ua);
|
||||
+ ua = na;
|
||||
+ /* move to end of update queue */
|
||||
+ TAILQ_REMOVE(upl, ua, attr_l);
|
||||
+ TAILQ_INSERT_TAIL(upl, ua, attr_l);
|
||||
+ }
|
||||
+ return (0);
|
||||
+}
|
||||
+
|
||||
u_char up_attr_buf[4096];
|
||||
|
||||
/* only for IPv4 */
|
||||
@@ -551,28 +596,41 @@ up_get_nexthop(struct rde_peer *peer, st
|
||||
|
||||
int
|
||||
up_generate_mp_reach(struct rde_peer *peer, struct update_attr *upa,
|
||||
- struct rde_aspath *a, sa_family_t af)
|
||||
+ struct rde_aspath *a, u_int8_t aid)
|
||||
{
|
||||
u_int16_t tmp;
|
||||
|
||||
- switch (af) {
|
||||
- case AF_INET6:
|
||||
+ switch (aid) {
|
||||
+ case AID_INET6:
|
||||
upa->mpattr_len = 21; /* AFI + SAFI + NH LEN + NH + Reserved */
|
||||
upa->mpattr = malloc(upa->mpattr_len);
|
||||
if (upa->mpattr == NULL)
|
||||
fatal("up_generate_mp_reach");
|
||||
- tmp = htons(AFI_IPv6);
|
||||
+ if (aid2afi(aid, &tmp, &upa->mpattr[2]))
|
||||
+ fatalx("up_generate_mp_reachi: bad AID");
|
||||
+ tmp = htons(tmp);
|
||||
memcpy(upa->mpattr, &tmp, sizeof(tmp));
|
||||
- upa->mpattr[2] = SAFI_UNICAST;
|
||||
upa->mpattr[3] = sizeof(struct in6_addr);
|
||||
upa->mpattr[20] = 0; /* Reserved must be 0 */
|
||||
|
||||
/* nexthop dance see also up_get_nexthop() */
|
||||
- if (peer->conf.ebgp == 0) {
|
||||
+ if (a->flags & F_NEXTHOP_NOMODIFY) {
|
||||
+ /* no modify flag set */
|
||||
+ if (a->nexthop == NULL)
|
||||
+ memcpy(&upa->mpattr[4], &peer->local_v6_addr.v6,
|
||||
+ sizeof(struct in6_addr));
|
||||
+ else
|
||||
+ memcpy(&upa->mpattr[4],
|
||||
+ &a->nexthop->exit_nexthop.v6,
|
||||
+ sizeof(struct in6_addr));
|
||||
+ } else if (a->flags & F_NEXTHOP_SELF)
|
||||
+ memcpy(&upa->mpattr[4], &peer->local_v6_addr.v6,
|
||||
+ sizeof(struct in6_addr));
|
||||
+ else if (!peer->conf.ebgp) {
|
||||
/* ibgp */
|
||||
if (a->nexthop == NULL ||
|
||||
- (a->nexthop->exit_nexthop.af == AF_INET6 &&
|
||||
- memcmp(&a->nexthop->exit_nexthop.v6,
|
||||
+ (a->nexthop->exit_nexthop.aid == AID_INET6 &&
|
||||
+ !memcmp(&a->nexthop->exit_nexthop.v6,
|
||||
&peer->remote_addr.v6, sizeof(struct in6_addr))))
|
||||
memcpy(&upa->mpattr[4], &peer->local_v6_addr.v6,
|
||||
sizeof(struct in6_addr));
|
||||
@@ -603,6 +661,68 @@ up_generate_mp_reach(struct rde_peer *pe
|
||||
memcpy(&upa->mpattr[4], &peer->local_v6_addr.v6,
|
||||
sizeof(struct in6_addr));
|
||||
return (0);
|
||||
+ case AID_VPN_IPv4:
|
||||
+ upa->mpattr_len = 17; /* AFI + SAFI + NH LEN + NH + Reserved */
|
||||
+ upa->mpattr = calloc(upa->mpattr_len, 1);
|
||||
+ if (upa->mpattr == NULL)
|
||||
+ fatal("up_generate_mp_reach");
|
||||
+ if (aid2afi(aid, &tmp, &upa->mpattr[2]))
|
||||
+ fatalx("up_generate_mp_reachi: bad AID");
|
||||
+ tmp = htons(tmp);
|
||||
+ memcpy(upa->mpattr, &tmp, sizeof(tmp));
|
||||
+ upa->mpattr[3] = sizeof(u_int64_t) + sizeof(struct in_addr);
|
||||
+
|
||||
+ /* nexthop dance see also up_get_nexthop() */
|
||||
+ if (a->flags & F_NEXTHOP_NOMODIFY) {
|
||||
+ /* no modify flag set */
|
||||
+ if (a->nexthop == NULL)
|
||||
+ memcpy(&upa->mpattr[12],
|
||||
+ &peer->local_v4_addr.v4,
|
||||
+ sizeof(struct in_addr));
|
||||
+ else
|
||||
+ /* nexthops are stored as IPv4 addrs */
|
||||
+ memcpy(&upa->mpattr[12],
|
||||
+ &a->nexthop->exit_nexthop.v4,
|
||||
+ sizeof(struct in_addr));
|
||||
+ } else if (a->flags & F_NEXTHOP_SELF)
|
||||
+ memcpy(&upa->mpattr[12], &peer->local_v4_addr.v4,
|
||||
+ sizeof(struct in_addr));
|
||||
+ else if (!peer->conf.ebgp) {
|
||||
+ /* ibgp */
|
||||
+ if (a->nexthop == NULL ||
|
||||
+ (a->nexthop->exit_nexthop.aid == AID_INET &&
|
||||
+ !memcmp(&a->nexthop->exit_nexthop.v4,
|
||||
+ &peer->remote_addr.v4, sizeof(struct in_addr))))
|
||||
+ memcpy(&upa->mpattr[12],
|
||||
+ &peer->local_v4_addr.v4,
|
||||
+ sizeof(struct in_addr));
|
||||
+ else
|
||||
+ memcpy(&upa->mpattr[12],
|
||||
+ &a->nexthop->exit_nexthop.v4,
|
||||
+ sizeof(struct in_addr));
|
||||
+ } else if (peer->conf.distance == 1) {
|
||||
+ /* ebgp directly connected */
|
||||
+ if (a->nexthop != NULL &&
|
||||
+ a->nexthop->flags & NEXTHOP_CONNECTED)
|
||||
+ if (prefix_compare(&peer->remote_addr,
|
||||
+ &a->nexthop->nexthop_net,
|
||||
+ a->nexthop->nexthop_netlen) == 0) {
|
||||
+ /*
|
||||
+ * nexthop and peer are in the same
|
||||
+ * subnet
|
||||
+ */
|
||||
+ memcpy(&upa->mpattr[12],
|
||||
+ &a->nexthop->exit_nexthop.v4,
|
||||
+ sizeof(struct in_addr));
|
||||
+ return (0);
|
||||
+ }
|
||||
+ memcpy(&upa->mpattr[12], &peer->local_v4_addr.v4,
|
||||
+ sizeof(struct in_addr));
|
||||
+ } else
|
||||
+ /* ebgp multihop */
|
||||
+ memcpy(&upa->mpattr[12], &peer->local_v4_addr.v4,
|
||||
+ sizeof(struct in_addr));
|
||||
+ return (0);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -611,7 +731,7 @@ up_generate_mp_reach(struct rde_peer *pe
|
||||
|
||||
int
|
||||
up_generate_attr(struct rde_peer *peer, struct update_attr *upa,
|
||||
- struct rde_aspath *a, sa_family_t af)
|
||||
+ struct rde_aspath *a, u_int8_t aid)
|
||||
{
|
||||
struct attr *oa, *newaggr = NULL;
|
||||
u_char *pdata;
|
||||
@@ -643,8 +763,8 @@ up_generate_attr(struct rde_peer *peer,
|
||||
wlen += r; len -= r;
|
||||
free(pdata);
|
||||
|
||||
- switch (af) {
|
||||
- case AF_INET:
|
||||
+ switch (aid) {
|
||||
+ case AID_INET:
|
||||
nexthop = up_get_nexthop(peer, a);
|
||||
if ((r = attr_write(up_attr_buf + wlen, len, ATTR_WELL_KNOWN,
|
||||
ATTR_NEXTHOP, &nexthop, 4)) == -1)
|
||||
@@ -659,9 +779,11 @@ up_generate_attr(struct rde_peer *peer,
|
||||
/*
|
||||
* The old MED from other peers MUST not be announced to others
|
||||
* unless the MED is originating from us or the peer is an IBGP one.
|
||||
+ * Only exception are routers with "transparent-as yes" set.
|
||||
*/
|
||||
- if (a->flags & F_ATTR_MED && (peer->conf.ebgp == 0 ||
|
||||
- a->flags & F_ATTR_MED_ANNOUNCE)) {
|
||||
+ if (a->flags & F_ATTR_MED && (!peer->conf.ebgp ||
|
||||
+ a->flags & F_ATTR_MED_ANNOUNCE ||
|
||||
+ peer->conf.flags & PEERFLAG_TRANS_AS)) {
|
||||
tmp32 = htonl(a->med);
|
||||
if ((r = attr_write(up_attr_buf + wlen, len, ATTR_OPTIONAL,
|
||||
ATTR_MED, &tmp32, 4)) == -1)
|
||||
@@ -669,7 +791,7 @@ up_generate_attr(struct rde_peer *peer,
|
||||
wlen += r; len -= r;
|
||||
}
|
||||
|
||||
- if (peer->conf.ebgp == 0) {
|
||||
+ if (!peer->conf.ebgp) {
|
||||
/* local preference, only valid for ibgp */
|
||||
tmp32 = htonl(a->lpref);
|
||||
if ((r = attr_write(up_attr_buf + wlen, len, ATTR_WELL_KNOWN,
|
||||
@@ -704,7 +826,7 @@ up_generate_attr(struct rde_peer *peer,
|
||||
u_int16_t tas;
|
||||
|
||||
if ((!(oa->flags & ATTR_TRANSITIVE)) &&
|
||||
- peer->conf.ebgp != 0) {
|
||||
+ peer->conf.ebgp) {
|
||||
r = 0;
|
||||
break;
|
||||
}
|
||||
@@ -730,7 +852,7 @@ up_generate_attr(struct rde_peer *peer,
|
||||
case ATTR_ORIGINATOR_ID:
|
||||
case ATTR_CLUSTER_LIST:
|
||||
if ((!(oa->flags & ATTR_TRANSITIVE)) &&
|
||||
- peer->conf.ebgp != 0) {
|
||||
+ peer->conf.ebgp) {
|
||||
r = 0;
|
||||
break;
|
||||
}
|
||||
@@ -791,7 +913,7 @@ up_generate_attr(struct rde_peer *peer,
|
||||
|
||||
/* write mp attribute to different buffer */
|
||||
if (ismp)
|
||||
- if (up_generate_mp_reach(peer, upa, a, AF_INET6) == -1)
|
||||
+ if (up_generate_mp_reach(peer, upa, a, aid) == -1)
|
||||
return (-1);
|
||||
|
||||
/* the bgp path attributes are now stored in the global buf */
|
||||
@@ -810,6 +932,7 @@ up_dump_prefix(u_char *buf, int len, str
|
||||
{
|
||||
struct update_prefix *upp;
|
||||
int r, wpos = 0;
|
||||
+ u_int8_t i;
|
||||
|
||||
while ((upp = TAILQ_FIRST(prefix_head)) != NULL) {
|
||||
if ((r = prefix_write(buf + wpos, len - wpos,
|
||||
@@ -820,13 +943,14 @@ up_dump_prefix(u_char *buf, int len, str
|
||||
log_warnx("dequeuing update failed.");
|
||||
TAILQ_REMOVE(upp->prefix_h, upp, prefix_l);
|
||||
peer->up_pcnt--;
|
||||
- if (upp->prefix_h == &peer->withdraws ||
|
||||
- upp->prefix_h == &peer->withdraws6) {
|
||||
- peer->up_wcnt--;
|
||||
- peer->prefix_sent_withdraw++;
|
||||
- } else {
|
||||
- peer->up_nlricnt--;
|
||||
- peer->prefix_sent_update++;
|
||||
+ for (i = 0; i < AID_MAX; i++) {
|
||||
+ if (upp->prefix_h == &peer->withdraws[i]) {
|
||||
+ peer->up_wcnt--;
|
||||
+ peer->prefix_sent_withdraw++;
|
||||
+ } else {
|
||||
+ peer->up_nlricnt--;
|
||||
+ peer->prefix_sent_update++;
|
||||
+ }
|
||||
}
|
||||
free(upp);
|
||||
}
|
||||
@@ -844,16 +968,21 @@ up_dump_attrnlri(u_char *buf, int len, s
|
||||
* It is possible that a queued path attribute has no nlri prefix.
|
||||
* Ignore and remove those path attributes.
|
||||
*/
|
||||
- while ((upa = TAILQ_FIRST(&peer->updates)) != NULL)
|
||||
+ while ((upa = TAILQ_FIRST(&peer->updates[AID_INET])) != NULL)
|
||||
if (TAILQ_EMPTY(&upa->prefix_h)) {
|
||||
+ attr_len = upa->attr_len;
|
||||
if (RB_REMOVE(uptree_attr, &peer->up_attrs,
|
||||
upa) == NULL)
|
||||
log_warnx("dequeuing update failed.");
|
||||
- TAILQ_REMOVE(&peer->updates, upa, attr_l);
|
||||
+ TAILQ_REMOVE(&peer->updates[AID_INET], upa, attr_l);
|
||||
free(upa->attr);
|
||||
free(upa->mpattr);
|
||||
free(upa);
|
||||
peer->up_acnt--;
|
||||
+ /* XXX horrible hack,
|
||||
+ * if attr_len is 0, it is a EoR marker */
|
||||
+ if (attr_len == 0)
|
||||
+ return (-1);
|
||||
} else
|
||||
break;
|
||||
|
||||
@@ -884,7 +1013,7 @@ up_dump_attrnlri(u_char *buf, int len, s
|
||||
if (TAILQ_EMPTY(&upa->prefix_h)) {
|
||||
if (RB_REMOVE(uptree_attr, &peer->up_attrs, upa) == NULL)
|
||||
log_warnx("dequeuing update failed.");
|
||||
- TAILQ_REMOVE(&peer->updates, upa, attr_l);
|
||||
+ TAILQ_REMOVE(&peer->updates[AID_INET], upa, attr_l);
|
||||
free(upa->attr);
|
||||
free(upa->mpattr);
|
||||
free(upa);
|
||||
@@ -895,12 +1024,13 @@ up_dump_attrnlri(u_char *buf, int len, s
|
||||
}
|
||||
|
||||
u_char *
|
||||
-up_dump_mp_unreach(u_char *buf, u_int16_t *len, struct rde_peer *peer)
|
||||
+up_dump_mp_unreach(u_char *buf, u_int16_t *len, struct rde_peer *peer,
|
||||
+ u_int8_t aid)
|
||||
{
|
||||
int wpos;
|
||||
u_int16_t datalen, tmp;
|
||||
u_int16_t attrlen = 2; /* attribute header (without len) */
|
||||
- u_int8_t flags = ATTR_OPTIONAL;
|
||||
+ u_int8_t flags = ATTR_OPTIONAL, safi;
|
||||
|
||||
/*
|
||||
* reserve space for withdraw len, attr len, the attribute header
|
||||
@@ -912,7 +1042,7 @@ up_dump_mp_unreach(u_char *buf, u_int16_
|
||||
return (NULL);
|
||||
|
||||
datalen = up_dump_prefix(buf + wpos, *len - wpos,
|
||||
- &peer->withdraws6, peer);
|
||||
+ &peer->withdraws[aid], peer);
|
||||
if (datalen == 0)
|
||||
return (NULL);
|
||||
|
||||
@@ -920,9 +1050,11 @@ up_dump_mp_unreach(u_char *buf, u_int16_
|
||||
|
||||
/* prepend header, need to do it reverse */
|
||||
/* safi & afi */
|
||||
- buf[--wpos] = SAFI_UNICAST;
|
||||
+ if (aid2afi(aid, &tmp, &safi))
|
||||
+ fatalx("up_dump_mp_unreach: bad AID");
|
||||
+ buf[--wpos] = safi;
|
||||
wpos -= sizeof(u_int16_t);
|
||||
- tmp = htons(AFI_IPv6);
|
||||
+ tmp = htons(tmp);
|
||||
memcpy(buf + wpos, &tmp, sizeof(u_int16_t));
|
||||
|
||||
/* attribute length */
|
||||
@@ -959,33 +1091,39 @@ up_dump_mp_unreach(u_char *buf, u_int16_
|
||||
return (buf + wpos);
|
||||
}
|
||||
|
||||
-u_char *
|
||||
-up_dump_mp_reach(u_char *buf, u_int16_t *len, struct rde_peer *peer)
|
||||
+int
|
||||
+up_dump_mp_reach(u_char *buf, u_int16_t *len, struct rde_peer *peer,
|
||||
+ u_int8_t aid)
|
||||
{
|
||||
struct update_attr *upa;
|
||||
int wpos;
|
||||
- u_int16_t datalen, tmp;
|
||||
+ u_int16_t attr_len, datalen, tmp;
|
||||
u_int8_t flags = ATTR_OPTIONAL;
|
||||
|
||||
/*
|
||||
* It is possible that a queued path attribute has no nlri prefix.
|
||||
* Ignore and remove those path attributes.
|
||||
*/
|
||||
- while ((upa = TAILQ_FIRST(&peer->updates6)) != NULL)
|
||||
+ while ((upa = TAILQ_FIRST(&peer->updates[aid])) != NULL)
|
||||
if (TAILQ_EMPTY(&upa->prefix_h)) {
|
||||
+ attr_len = upa->attr_len;
|
||||
if (RB_REMOVE(uptree_attr, &peer->up_attrs,
|
||||
upa) == NULL)
|
||||
log_warnx("dequeuing update failed.");
|
||||
- TAILQ_REMOVE(&peer->updates6, upa, attr_l);
|
||||
+ TAILQ_REMOVE(&peer->updates[aid], upa, attr_l);
|
||||
free(upa->attr);
|
||||
free(upa->mpattr);
|
||||
free(upa);
|
||||
peer->up_acnt--;
|
||||
+ /* XXX horrible hack,
|
||||
+ * if attr_len is 0, it is a EoR marker */
|
||||
+ if (attr_len == 0)
|
||||
+ return (-1);
|
||||
} else
|
||||
break;
|
||||
|
||||
if (upa == NULL)
|
||||
- return (NULL);
|
||||
+ return (-2);
|
||||
|
||||
/*
|
||||
* reserve space for attr len, the attributes, the
|
||||
@@ -993,12 +1131,12 @@ up_dump_mp_reach(u_char *buf, u_int16_t
|
||||
*/
|
||||
wpos = 2 + 2 + upa->attr_len + 4 + upa->mpattr_len;
|
||||
if (*len < wpos)
|
||||
- return (NULL);
|
||||
+ return (-2);
|
||||
|
||||
datalen = up_dump_prefix(buf + wpos, *len - wpos,
|
||||
&upa->prefix_h, peer);
|
||||
if (datalen == 0)
|
||||
- return (NULL);
|
||||
+ return (-2);
|
||||
|
||||
if (upa->mpattr_len == 0 || upa->mpattr == NULL)
|
||||
fatalx("mulitprotocol update without MP attrs");
|
||||
@@ -1038,7 +1176,7 @@ up_dump_mp_reach(u_char *buf, u_int16_t
|
||||
if (TAILQ_EMPTY(&upa->prefix_h)) {
|
||||
if (RB_REMOVE(uptree_attr, &peer->up_attrs, upa) == NULL)
|
||||
log_warnx("dequeuing update failed.");
|
||||
- TAILQ_REMOVE(&peer->updates6, upa, attr_l);
|
||||
+ TAILQ_REMOVE(&peer->updates[aid], upa, attr_l);
|
||||
free(upa->attr);
|
||||
free(upa->mpattr);
|
||||
free(upa);
|
||||
@@ -1046,6 +1184,5 @@ up_dump_mp_reach(u_char *buf, u_int16_t
|
||||
}
|
||||
|
||||
*len = datalen + 4;
|
||||
- return (buf + wpos);
|
||||
+ return (wpos);
|
||||
}
|
||||
-
|
2075
net/openbgpd/files/patch-bgpd_session.c
Normal file
2075
net/openbgpd/files/patch-bgpd_session.c
Normal file
File diff suppressed because it is too large
Load Diff
188
net/openbgpd/files/patch-bgpd_session.h
Normal file
188
net/openbgpd/files/patch-bgpd_session.h
Normal file
@ -0,0 +1,188 @@
|
||||
Index: bgpd/session.h
|
||||
===================================================================
|
||||
RCS file: /home/cvs/private/hrs/openbgpd/bgpd/session.h,v
|
||||
retrieving revision 1.1.1.7
|
||||
retrieving revision 1.1.1.10
|
||||
diff -u -p -r1.1.1.7 -r1.1.1.10
|
||||
--- bgpd/session.h 14 Feb 2010 20:19:57 -0000 1.1.1.7
|
||||
+++ bgpd/session.h 13 Oct 2012 18:22:50 -0000 1.1.1.10
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* $OpenBSD: session.h,v 1.101 2009/06/05 20:26:38 claudio Exp $ */
|
||||
+/* $OpenBSD: session.h,v 1.113 2012/04/12 17:26:09 claudio Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
|
||||
@@ -94,6 +94,13 @@ enum suberr_open {
|
||||
ERR_OPEN_CAPA
|
||||
};
|
||||
|
||||
+enum suberr_fsm {
|
||||
+ ERR_FSM_UNSPECIFIC = 0,
|
||||
+ ERR_FSM_UNEX_OPENSENT,
|
||||
+ ERR_FSM_UNEX_OPENCONFIRM,
|
||||
+ ERR_FSM_UNEX_ESTABLISHED
|
||||
+};
|
||||
+
|
||||
enum opt_params {
|
||||
OPT_PARAM_NONE,
|
||||
OPT_PARAM_AUTH,
|
||||
@@ -109,7 +116,7 @@ enum capa_codes {
|
||||
};
|
||||
|
||||
struct bgp_msg {
|
||||
- struct buf *buf;
|
||||
+ struct ibuf *buf;
|
||||
enum msg_type type;
|
||||
u_int16_t len;
|
||||
};
|
||||
@@ -155,8 +162,10 @@ struct peer_stats {
|
||||
u_int64_t msg_sent_rrefresh;
|
||||
u_int64_t prefix_rcvd_update;
|
||||
u_int64_t prefix_rcvd_withdraw;
|
||||
+ u_int64_t prefix_rcvd_eor;
|
||||
u_int64_t prefix_sent_update;
|
||||
u_int64_t prefix_sent_withdraw;
|
||||
+ u_int64_t prefix_sent_eor;
|
||||
time_t last_updown;
|
||||
time_t last_read;
|
||||
u_int32_t prefix_cnt;
|
||||
@@ -172,6 +181,7 @@ enum Timer {
|
||||
Timer_IdleHold,
|
||||
Timer_IdleHoldReset,
|
||||
Timer_CarpUndemote,
|
||||
+ Timer_RestartTimeout,
|
||||
Timer_Max
|
||||
};
|
||||
|
||||
@@ -189,6 +199,7 @@ struct peer {
|
||||
struct {
|
||||
struct capabilities ann;
|
||||
struct capabilities peer;
|
||||
+ struct capabilities neg;
|
||||
} capa;
|
||||
struct {
|
||||
struct bgpd_addr local_addr;
|
||||
@@ -201,7 +212,7 @@ struct peer {
|
||||
struct sockaddr_storage sa_remote;
|
||||
struct peer_timer_head timers;
|
||||
struct msgbuf wbuf;
|
||||
- struct buf_read *rbuf;
|
||||
+ struct ibuf_read *rbuf;
|
||||
struct peer *next;
|
||||
int fd;
|
||||
int lasterr;
|
||||
@@ -217,47 +228,25 @@ struct peer {
|
||||
u_int8_t passive;
|
||||
};
|
||||
|
||||
-struct peer *peers;
|
||||
+extern struct peer *peers;
|
||||
+extern time_t pauseaccept;
|
||||
|
||||
struct ctl_timer {
|
||||
enum Timer type;
|
||||
time_t val;
|
||||
};
|
||||
|
||||
-/* session.c */
|
||||
-void session_socket_blockmode(int, enum blockmodes);
|
||||
-pid_t session_main(struct bgpd_config *, struct peer *,
|
||||
- struct network_head *, struct filter_head *,
|
||||
- struct mrt_head *, struct rib_names *,
|
||||
- int[2], int[2], int[2], int[2]);
|
||||
-void bgp_fsm(struct peer *, enum session_events);
|
||||
-int session_neighbor_rrefresh(struct peer *p);
|
||||
-struct peer *getpeerbyaddr(struct bgpd_addr *);
|
||||
-struct peer *getpeerbydesc(const char *);
|
||||
-int imsg_compose_parent(int, pid_t, void *, u_int16_t);
|
||||
-int imsg_compose_rde(int, pid_t, void *, u_int16_t);
|
||||
-
|
||||
-/* log.c */
|
||||
-char *log_fmt_peer(const struct peer_config *);
|
||||
-void log_statechange(struct peer *, enum session_state,
|
||||
- enum session_events);
|
||||
-void log_notification(const struct peer *, u_int8_t, u_int8_t,
|
||||
- u_char *, u_int16_t);
|
||||
-void log_conn_attempt(const struct peer *, struct sockaddr *);
|
||||
-
|
||||
-/* parse.y */
|
||||
-int parse_config(char *, struct bgpd_config *, struct mrt_head *,
|
||||
- struct peer **, struct network_head *, struct filter_head *);
|
||||
+/* carp.c */
|
||||
+int carp_demote_init(char *, int);
|
||||
+void carp_demote_shutdown(void);
|
||||
+int carp_demote_get(char *);
|
||||
+int carp_demote_set(char *, int);
|
||||
|
||||
/* config.c */
|
||||
int merge_config(struct bgpd_config *, struct bgpd_config *,
|
||||
struct peer *, struct listen_addrs *);
|
||||
void prepare_listeners(struct bgpd_config *);
|
||||
-
|
||||
-/* rde.c */
|
||||
-pid_t rde_main(struct bgpd_config *, struct peer *, struct network_head *,
|
||||
- struct filter_head *, struct mrt_head *, struct rib_names *,
|
||||
- int[2], int[2], int[2], int[2], int);
|
||||
+int get_mpe_label(struct rdomain *);
|
||||
|
||||
/* control.c */
|
||||
int control_init(int, char *);
|
||||
@@ -266,7 +255,27 @@ void control_shutdown(int);
|
||||
int control_dispatch_msg(struct pollfd *, u_int *);
|
||||
unsigned int control_accept(int, int);
|
||||
|
||||
+/* log.c */
|
||||
+char *log_fmt_peer(const struct peer_config *);
|
||||
+void log_statechange(struct peer *, enum session_state,
|
||||
+ enum session_events);
|
||||
+void log_notification(const struct peer *, u_int8_t, u_int8_t,
|
||||
+ u_char *, u_int16_t, const char *);
|
||||
+void log_conn_attempt(const struct peer *, struct sockaddr *);
|
||||
+
|
||||
+/* mrt.c */
|
||||
+void mrt_dump_bgp_msg(struct mrt *, void *, u_int16_t,
|
||||
+ struct peer *);
|
||||
+void mrt_dump_state(struct mrt *, u_int16_t, u_int16_t,
|
||||
+ struct peer *);
|
||||
+
|
||||
+/* parse.y */
|
||||
+int parse_config(char *, struct bgpd_config *, struct mrt_head *,
|
||||
+ struct peer **, struct network_head *, struct filter_head *,
|
||||
+ struct rdomain_head *);
|
||||
+
|
||||
/* pfkey.c */
|
||||
+int pfkey_read(int, struct sadb_msg *);
|
||||
int pfkey_establish(struct peer *);
|
||||
int pfkey_remove(struct peer *);
|
||||
int pfkey_init(struct bgpd_sysdep *);
|
||||
@@ -274,15 +283,24 @@ int pfkey_init(struct bgpd_sysdep *);
|
||||
/* printconf.c */
|
||||
void print_config(struct bgpd_config *, struct rib_names *,
|
||||
struct network_head *, struct peer *, struct filter_head *,
|
||||
- struct mrt_head *);
|
||||
+ struct mrt_head *, struct rdomain_head *);
|
||||
|
||||
-/* carp.c */
|
||||
-int carp_demote_init(char *, int);
|
||||
-void carp_demote_shutdown(void);
|
||||
-int carp_demote_get(char *);
|
||||
-int carp_demote_set(char *, int);
|
||||
+/* rde.c */
|
||||
+pid_t rde_main(int[2], int[2], int[2], int[2], int);
|
||||
+
|
||||
+/* session.c */
|
||||
+void session_socket_blockmode(int, enum blockmodes);
|
||||
+pid_t session_main(int[2], int[2], int[2], int[2]);
|
||||
+void bgp_fsm(struct peer *, enum session_events);
|
||||
+int session_neighbor_rrefresh(struct peer *p);
|
||||
+struct peer *getpeerbyaddr(struct bgpd_addr *);
|
||||
+struct peer *getpeerbydesc(const char *);
|
||||
+int imsg_compose_parent(int, u_int32_t, pid_t, void *, u_int16_t);
|
||||
+int imsg_compose_rde(int, pid_t, void *, u_int16_t);
|
||||
+void session_stop(struct peer *, u_int8_t);
|
||||
|
||||
/* timer.c */
|
||||
+time_t getmonotime(void);
|
||||
struct peer_timer *timer_get(struct peer *, enum Timer);
|
||||
struct peer_timer *timer_nextisdue(struct peer *);
|
||||
time_t timer_nextduein(struct peer *);
|
32
net/openbgpd/files/patch-bgpd_timer.c
Normal file
32
net/openbgpd/files/patch-bgpd_timer.c
Normal file
@ -0,0 +1,32 @@
|
||||
Index: bgpd/timer.c
|
||||
===================================================================
|
||||
RCS file: /home/cvs/private/hrs/openbgpd/bgpd/timer.c,v
|
||||
retrieving revision 1.1.1.2
|
||||
retrieving revision 1.1.1.4
|
||||
diff -u -p -r1.1.1.2 -r1.1.1.4
|
||||
--- bgpd/timer.c 9 Jul 2009 16:49:54 -0000 1.1.1.2
|
||||
+++ bgpd/timer.c 13 Oct 2012 18:22:50 -0000 1.1.1.4
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* $OpenBSD: timer.c,v 1.13 2009/01/21 20:32:53 henning Exp $ */
|
||||
+/* $OpenBSD: timer.c,v 1.14 2010/10/24 17:20:08 deraadt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003-2007 Henning Brauer <henning@openbsd.org>
|
||||
@@ -23,8 +23,6 @@
|
||||
#include "bgpd.h"
|
||||
#include "session.h"
|
||||
|
||||
-time_t getmonotime(void);
|
||||
-
|
||||
time_t
|
||||
getmonotime(void)
|
||||
{
|
||||
@@ -43,7 +41,7 @@ timer_get(struct peer *p, enum Timer tim
|
||||
|
||||
TAILQ_FOREACH(pt, &p->timers, entry)
|
||||
if (pt->type == timer)
|
||||
- break;
|
||||
+ break;
|
||||
|
||||
return (pt);
|
||||
}
|
440
net/openbgpd/files/patch-bgpd_util.c
Normal file
440
net/openbgpd/files/patch-bgpd_util.c
Normal file
@ -0,0 +1,440 @@
|
||||
Index: bgpd/util.c
|
||||
===================================================================
|
||||
RCS file: /home/cvs/private/hrs/openbgpd/bgpd/util.c,v
|
||||
retrieving revision 1.1.1.6
|
||||
retrieving revision 1.7
|
||||
diff -u -p -r1.1.1.6 -r1.7
|
||||
--- bgpd/util.c 14 Feb 2010 20:19:57 -0000 1.1.1.6
|
||||
+++ bgpd/util.c 13 Oct 2012 18:36:00 -0000 1.7
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* $OpenBSD: util.c,v 1.6 2009/06/12 16:42:53 claudio Exp $ */
|
||||
+/* $OpenBSD: util.c,v 1.11 2010/03/29 09:04:43 claudio Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006 Claudio Jeker <claudio@openbsd.org>
|
||||
@@ -18,6 +18,9 @@
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
+#if defined(__FreeBSD__) /* sys/limits.h */
|
||||
+#include <sys/limits.h>
|
||||
+#endif /* defined(__FreeBSD__) */
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
@@ -28,15 +31,30 @@
|
||||
#include "bgpd.h"
|
||||
#include "rde.h"
|
||||
|
||||
+const char *aspath_delim(u_int8_t, int);
|
||||
+
|
||||
const char *
|
||||
log_addr(const struct bgpd_addr *addr)
|
||||
{
|
||||
static char buf[48];
|
||||
+ char tbuf[16];
|
||||
|
||||
- if (inet_ntop(addr->af, &addr->ba, buf, sizeof(buf)) == NULL)
|
||||
- return ("?");
|
||||
- else
|
||||
+ switch (addr->aid) {
|
||||
+ case AID_INET:
|
||||
+ case AID_INET6:
|
||||
+ if (inet_ntop(aid2af(addr->aid), &addr->ba, buf,
|
||||
+ sizeof(buf)) == NULL)
|
||||
+ return ("?");
|
||||
return (buf);
|
||||
+ case AID_VPN_IPv4:
|
||||
+ if (inet_ntop(AF_INET, &addr->vpn4.addr, tbuf,
|
||||
+ sizeof(tbuf)) == NULL)
|
||||
+ return ("?");
|
||||
+ snprintf(buf, sizeof(buf), "%s %s", log_rd(addr->vpn4.rd),
|
||||
+ tbuf);
|
||||
+ return (buf);
|
||||
+ }
|
||||
+ return ("???");
|
||||
}
|
||||
|
||||
const char *
|
||||
@@ -90,6 +108,96 @@ log_as(u_int32_t as)
|
||||
return (buf);
|
||||
}
|
||||
|
||||
+const char *
|
||||
+log_rd(u_int64_t rd)
|
||||
+{
|
||||
+ static char buf[32];
|
||||
+ struct in_addr addr;
|
||||
+ u_int32_t u32;
|
||||
+ u_int16_t u16;
|
||||
+
|
||||
+ rd = betoh64(rd);
|
||||
+ switch (rd >> 48) {
|
||||
+ case EXT_COMMUNITY_TWO_AS:
|
||||
+ u32 = rd & 0xffffffff;
|
||||
+ u16 = (rd >> 32) & 0xffff;
|
||||
+ snprintf(buf, sizeof(buf), "rd %i:%i", u16, u32);
|
||||
+ break;
|
||||
+ case EXT_COMMUNITY_FOUR_AS:
|
||||
+ u32 = (rd >> 16) & 0xffffffff;
|
||||
+ u16 = rd & 0xffff;
|
||||
+ snprintf(buf, sizeof(buf), "rd %s:%i", log_as(u32), u16);
|
||||
+ break;
|
||||
+ case EXT_COMMUNITY_IPV4:
|
||||
+ u32 = (rd >> 16) & 0xffffffff;
|
||||
+ u16 = rd & 0xffff;
|
||||
+ addr.s_addr = htonl(u32);
|
||||
+ snprintf(buf, sizeof(buf), "rd %s:%i", inet_ntoa(addr), u16);
|
||||
+ break;
|
||||
+ default:
|
||||
+ return ("rd ?");
|
||||
+ }
|
||||
+ return (buf);
|
||||
+}
|
||||
+
|
||||
+/* NOTE: this function does not check if the type/subtype combo is
|
||||
+ * actually valid. */
|
||||
+const char *
|
||||
+log_ext_subtype(u_int8_t subtype)
|
||||
+{
|
||||
+ static char etype[6];
|
||||
+
|
||||
+ switch (subtype) {
|
||||
+ case EXT_COMMUNITY_ROUTE_TGT:
|
||||
+ return ("rt"); /* route target */
|
||||
+ case EXT_CUMMUNITY_ROUTE_ORIG:
|
||||
+ return ("soo"); /* source of origin */
|
||||
+ case EXT_COMMUNITY_OSPF_DOM_ID:
|
||||
+ return ("odi"); /* ospf domain id */
|
||||
+ case EXT_COMMUNITY_OSPF_RTR_TYPE:
|
||||
+ return ("ort"); /* ospf route type */
|
||||
+ case EXT_COMMUNITY_OSPF_RTR_ID:
|
||||
+ return ("ori"); /* ospf router id */
|
||||
+ case EXT_COMMUNITY_BGP_COLLECT:
|
||||
+ return ("bdc"); /* bgp data collection */
|
||||
+ default:
|
||||
+ snprintf(etype, sizeof(etype), "[%u]", subtype);
|
||||
+ return (etype);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+const char *
|
||||
+aspath_delim(u_int8_t seg_type, int closing)
|
||||
+{
|
||||
+ static char db[8];
|
||||
+
|
||||
+ switch (seg_type) {
|
||||
+ case AS_SET:
|
||||
+ if (!closing)
|
||||
+ return ("{ ");
|
||||
+ else
|
||||
+ return (" }");
|
||||
+ case AS_SEQUENCE:
|
||||
+ return ("");
|
||||
+ case AS_CONFED_SEQUENCE:
|
||||
+ if (!closing)
|
||||
+ return ("( ");
|
||||
+ else
|
||||
+ return (" )");
|
||||
+ case AS_CONFED_SET:
|
||||
+ if (!closing)
|
||||
+ return ("[ ");
|
||||
+ else
|
||||
+ return (" ]");
|
||||
+ default:
|
||||
+ if (!closing)
|
||||
+ snprintf(db, sizeof(db), "!%u ", seg_type);
|
||||
+ else
|
||||
+ snprintf(db, sizeof(db), " !%u", seg_type);
|
||||
+ return (db);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
int
|
||||
aspath_snprint(char *buf, size_t size, void *data, u_int16_t len)
|
||||
{
|
||||
@@ -118,16 +226,10 @@ aspath_snprint(char *buf, size_t size, v
|
||||
seg_len = seg[1];
|
||||
seg_size = 2 + sizeof(u_int32_t) * seg_len;
|
||||
|
||||
- if (seg_type == AS_SET) {
|
||||
- if (total_size != 0)
|
||||
- r = snprintf(buf, size, " { ");
|
||||
- else
|
||||
- r = snprintf(buf, size, "{ ");
|
||||
- UPDATE();
|
||||
- } else if (total_size != 0) {
|
||||
- r = snprintf(buf, size, " ");
|
||||
- UPDATE();
|
||||
- }
|
||||
+ r = snprintf(buf, size, "%s%s",
|
||||
+ total_size != 0 ? " " : "",
|
||||
+ aspath_delim(seg_type, 0));
|
||||
+ UPDATE();
|
||||
|
||||
for (i = 0; i < seg_len; i++) {
|
||||
r = snprintf(buf, size, "%s",
|
||||
@@ -138,10 +240,8 @@ aspath_snprint(char *buf, size_t size, v
|
||||
UPDATE();
|
||||
}
|
||||
}
|
||||
- if (seg_type == AS_SET) {
|
||||
- r = snprintf(buf, size, " }");
|
||||
- UPDATE();
|
||||
- }
|
||||
+ r = snprintf(buf, size, "%s", aspath_delim(seg_type, 1));
|
||||
+ UPDATE();
|
||||
}
|
||||
/* ensure that we have a valid C-string especially for empty as path */
|
||||
if (size > 0)
|
||||
@@ -235,6 +335,67 @@ aspath_strlen(void *data, u_int16_t len)
|
||||
return (total_size);
|
||||
}
|
||||
|
||||
+/* we need to be able to search more than one as */
|
||||
+int
|
||||
+aspath_match(void *data, u_int16_t len, enum as_spec type, u_int32_t as)
|
||||
+{
|
||||
+ u_int8_t *seg;
|
||||
+ int final;
|
||||
+ u_int16_t seg_size;
|
||||
+ u_int8_t i, seg_type, seg_len;
|
||||
+
|
||||
+ if (type == AS_EMPTY) {
|
||||
+ if (len == 0)
|
||||
+ return (1);
|
||||
+ else
|
||||
+ return (0);
|
||||
+ }
|
||||
+
|
||||
+ final = 0;
|
||||
+ seg = data;
|
||||
+ for (; len > 0; len -= seg_size, seg += seg_size) {
|
||||
+ seg_type = seg[0];
|
||||
+ seg_len = seg[1];
|
||||
+ seg_size = 2 + sizeof(u_int32_t) * seg_len;
|
||||
+
|
||||
+ final = (len == seg_size);
|
||||
+
|
||||
+ /* just check the first (leftmost) AS */
|
||||
+ if (type == AS_PEER) {
|
||||
+ if (as == aspath_extract(seg, 0))
|
||||
+ return (1);
|
||||
+ else
|
||||
+ return (0);
|
||||
+ }
|
||||
+ /* just check the final (rightmost) AS */
|
||||
+ if (type == AS_SOURCE) {
|
||||
+ /* not yet in the final segment */
|
||||
+ if (!final)
|
||||
+ continue;
|
||||
+
|
||||
+ if (as == aspath_extract(seg, seg_len - 1))
|
||||
+ return (1);
|
||||
+ else
|
||||
+ return (0);
|
||||
+ }
|
||||
+
|
||||
+ /* AS_TRANSIT or AS_ALL */
|
||||
+ for (i = 0; i < seg_len; i++) {
|
||||
+ if (as == aspath_extract(seg, i)) {
|
||||
+ /*
|
||||
+ * the source (rightmost) AS is excluded from
|
||||
+ * AS_TRANSIT matches.
|
||||
+ */
|
||||
+ if (final && i == seg_len - 1 &&
|
||||
+ type == AS_TRANSIT)
|
||||
+ return (0);
|
||||
+ return (1);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ return (0);
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Extract the asnum out of the as segment at the specified position.
|
||||
* Direct access is not possible because of non-aligned reads.
|
||||
@@ -251,6 +412,66 @@ aspath_extract(const void *seg, int pos)
|
||||
return (ntohl(as));
|
||||
}
|
||||
|
||||
+int
|
||||
+prefix_compare(const struct bgpd_addr *a, const struct bgpd_addr *b,
|
||||
+ int prefixlen)
|
||||
+{
|
||||
+ in_addr_t mask, aa, ba;
|
||||
+ int i;
|
||||
+ u_int8_t m;
|
||||
+
|
||||
+ if (a->aid != b->aid)
|
||||
+ return (a->aid - b->aid);
|
||||
+
|
||||
+ switch (a->aid) {
|
||||
+ case AID_INET:
|
||||
+ if (prefixlen > 32)
|
||||
+ fatalx("prefix_cmp: bad IPv4 prefixlen");
|
||||
+ mask = htonl(prefixlen2mask(prefixlen));
|
||||
+ aa = ntohl(a->v4.s_addr & mask);
|
||||
+ ba = ntohl(b->v4.s_addr & mask);
|
||||
+ if (aa != ba)
|
||||
+ return (aa - ba);
|
||||
+ return (0);
|
||||
+ case AID_INET6:
|
||||
+ if (prefixlen > 128)
|
||||
+ fatalx("prefix_cmp: bad IPv6 prefixlen");
|
||||
+ for (i = 0; i < prefixlen / 8; i++)
|
||||
+ if (a->v6.s6_addr[i] != b->v6.s6_addr[i])
|
||||
+ return (a->v6.s6_addr[i] - b->v6.s6_addr[i]);
|
||||
+ i = prefixlen % 8;
|
||||
+ if (i) {
|
||||
+ m = 0xff00 >> i;
|
||||
+ if ((a->v6.s6_addr[prefixlen / 8] & m) !=
|
||||
+ (b->v6.s6_addr[prefixlen / 8] & m))
|
||||
+ return ((a->v6.s6_addr[prefixlen / 8] & m) -
|
||||
+ (b->v6.s6_addr[prefixlen / 8] & m));
|
||||
+ }
|
||||
+ return (0);
|
||||
+ case AID_VPN_IPv4:
|
||||
+ if (prefixlen > 32)
|
||||
+ fatalx("prefix_cmp: bad IPv4 VPN prefixlen");
|
||||
+ if (betoh64(a->vpn4.rd) > betoh64(b->vpn4.rd))
|
||||
+ return (1);
|
||||
+ if (betoh64(a->vpn4.rd) < betoh64(b->vpn4.rd))
|
||||
+ return (-1);
|
||||
+ mask = htonl(prefixlen2mask(prefixlen));
|
||||
+ aa = ntohl(a->vpn4.addr.s_addr & mask);
|
||||
+ ba = ntohl(b->vpn4.addr.s_addr & mask);
|
||||
+ if (aa != ba)
|
||||
+ return (aa - ba);
|
||||
+ if (a->vpn4.labellen > b->vpn4.labellen)
|
||||
+ return (1);
|
||||
+ if (a->vpn4.labellen < b->vpn4.labellen)
|
||||
+ return (-1);
|
||||
+ return (memcmp(a->vpn4.labelstack, b->vpn4.labelstack,
|
||||
+ a->vpn4.labellen));
|
||||
+ default:
|
||||
+ fatalx("prefix_cmp: unknown af");
|
||||
+ }
|
||||
+ return (-1);
|
||||
+}
|
||||
+
|
||||
in_addr_t
|
||||
prefixlen2mask(u_int8_t prefixlen)
|
||||
{
|
||||
@@ -276,3 +497,115 @@ inet6applymask(struct in6_addr *dest, co
|
||||
for (i = 0; i < 16; i++)
|
||||
dest->s6_addr[i] = src->s6_addr[i] & mask.s6_addr[i];
|
||||
}
|
||||
+
|
||||
+/* address family translation functions */
|
||||
+const struct aid aid_vals[AID_MAX] = AID_VALS;
|
||||
+
|
||||
+const char *
|
||||
+aid2str(u_int8_t aid)
|
||||
+{
|
||||
+ if (aid < AID_MAX)
|
||||
+ return (aid_vals[aid].name);
|
||||
+ return ("unknown AID");
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+aid2afi(u_int8_t aid, u_int16_t *afi, u_int8_t *safi)
|
||||
+{
|
||||
+ if (aid < AID_MAX) {
|
||||
+ *afi = aid_vals[aid].afi;
|
||||
+ *safi = aid_vals[aid].safi;
|
||||
+ return (0);
|
||||
+ }
|
||||
+ return (-1);
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+afi2aid(u_int16_t afi, u_int8_t safi, u_int8_t *aid)
|
||||
+{
|
||||
+ u_int8_t i;
|
||||
+
|
||||
+ for (i = 0; i < AID_MAX; i++)
|
||||
+ if (aid_vals[i].afi == afi && aid_vals[i].safi == safi) {
|
||||
+ *aid = i;
|
||||
+ return (0);
|
||||
+ }
|
||||
+
|
||||
+ return (-1);
|
||||
+}
|
||||
+
|
||||
+sa_family_t
|
||||
+aid2af(u_int8_t aid)
|
||||
+{
|
||||
+ if (aid < AID_MAX)
|
||||
+ return (aid_vals[aid].af);
|
||||
+ return (AF_UNSPEC);
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+af2aid(sa_family_t af, u_int8_t safi, u_int8_t *aid)
|
||||
+{
|
||||
+ u_int8_t i;
|
||||
+
|
||||
+ if (safi == 0) /* default to unicast subclass */
|
||||
+ safi = SAFI_UNICAST;
|
||||
+
|
||||
+ for (i = 0; i < AID_MAX; i++)
|
||||
+ if (aid_vals[i].af == af && aid_vals[i].safi == safi) {
|
||||
+ *aid = i;
|
||||
+ return (0);
|
||||
+ }
|
||||
+
|
||||
+ return (-1);
|
||||
+}
|
||||
+
|
||||
+struct sockaddr *
|
||||
+addr2sa(struct bgpd_addr *addr, u_int16_t port)
|
||||
+{
|
||||
+ static struct sockaddr_storage ss;
|
||||
+ struct sockaddr_in *sa_in = (struct sockaddr_in *)&ss;
|
||||
+ struct sockaddr_in6 *sa_in6 = (struct sockaddr_in6 *)&ss;
|
||||
+
|
||||
+ if (addr->aid == AID_UNSPEC)
|
||||
+ return (NULL);
|
||||
+
|
||||
+ bzero(&ss, sizeof(ss));
|
||||
+ switch (addr->aid) {
|
||||
+ case AID_INET:
|
||||
+ sa_in->sin_family = AF_INET;
|
||||
+ sa_in->sin_len = sizeof(struct sockaddr_in);
|
||||
+ sa_in->sin_addr.s_addr = addr->v4.s_addr;
|
||||
+ sa_in->sin_port = htons(port);
|
||||
+ break;
|
||||
+ case AID_INET6:
|
||||
+ sa_in6->sin6_family = AF_INET6;
|
||||
+ sa_in6->sin6_len = sizeof(struct sockaddr_in6);
|
||||
+ memcpy(&sa_in6->sin6_addr, &addr->v6,
|
||||
+ sizeof(sa_in6->sin6_addr));
|
||||
+ sa_in6->sin6_port = htons(port);
|
||||
+ sa_in6->sin6_scope_id = addr->scope_id;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return ((struct sockaddr *)&ss);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+sa2addr(struct sockaddr *sa, struct bgpd_addr *addr)
|
||||
+{
|
||||
+ struct sockaddr_in *sa_in = (struct sockaddr_in *)sa;
|
||||
+ struct sockaddr_in6 *sa_in6 = (struct sockaddr_in6 *)sa;
|
||||
+
|
||||
+ bzero(addr, sizeof(*addr));
|
||||
+ switch (sa->sa_family) {
|
||||
+ case AF_INET:
|
||||
+ addr->aid = AID_INET;
|
||||
+ memcpy(&addr->v4, &sa_in->sin_addr, sizeof(addr->v4));
|
||||
+ break;
|
||||
+ case AF_INET6:
|
||||
+ addr->aid = AID_INET6;
|
||||
+ memcpy(&addr->v6, &sa_in6->sin6_addr, sizeof(addr->v6));
|
||||
+ addr->scope_id = sa_in6->sin6_scope_id; /* I hate v6 */
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
275
net/openbgpd/files/patch-openbsd-compat_fmt_scaled.c
Normal file
275
net/openbgpd/files/patch-openbsd-compat_fmt_scaled.c
Normal file
@ -0,0 +1,275 @@
|
||||
Index: openbsd-compat/fmt_scaled.c
|
||||
===================================================================
|
||||
RCS file: openbsd-compat/fmt_scaled.c
|
||||
diff -N openbsd-compat/fmt_scaled.c
|
||||
--- /dev/null 1 Jan 1970 00:00:00 -0000
|
||||
+++ openbsd-compat/fmt_scaled.c 30 Jun 2009 06:40:07 -0000 1.1
|
||||
@@ -0,0 +1,268 @@
|
||||
+/* $OpenBSD: fmt_scaled.c,v 1.9 2007/03/20 03:42:52 tedu Exp $ */
|
||||
+
|
||||
+/*
|
||||
+ * Copyright (c) 2001, 2002, 2003 Ian F. Darwin. 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.
|
||||
+ * 3. The name of the author may not be used to endorse or promote products
|
||||
+ * derived from this software without specific prior written permission.
|
||||
+ *
|
||||
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
|
||||
+ */
|
||||
+
|
||||
+/*
|
||||
+ * fmt_scaled: Format numbers scaled for human comprehension
|
||||
+ * scan_scaled: Scan numbers in this format.
|
||||
+ *
|
||||
+ * "Human-readable" output uses 4 digits max, and puts a unit suffix at
|
||||
+ * the end. Makes output compact and easy-to-read esp. on huge disks.
|
||||
+ * Formatting code was originally in OpenBSD "df", converted to library routine.
|
||||
+ * Scanning code written for OpenBSD libutil.
|
||||
+ */
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <errno.h>
|
||||
+#include <string.h>
|
||||
+#include <ctype.h>
|
||||
+#include <limits.h>
|
||||
+
|
||||
+#include "util.h"
|
||||
+
|
||||
+typedef enum {
|
||||
+ NONE = 0, KILO = 1, MEGA = 2, GIGA = 3, TERA = 4, PETA = 5, EXA = 6
|
||||
+} unit_type;
|
||||
+
|
||||
+/* These three arrays MUST be in sync! XXX make a struct */
|
||||
+static unit_type units[] = { NONE, KILO, MEGA, GIGA, TERA, PETA, EXA };
|
||||
+static char scale_chars[] = "BKMGTPE";
|
||||
+static long long scale_factors[] = {
|
||||
+ 1LL,
|
||||
+ 1024LL,
|
||||
+ 1024LL*1024,
|
||||
+ 1024LL*1024*1024,
|
||||
+ 1024LL*1024*1024*1024,
|
||||
+ 1024LL*1024*1024*1024*1024,
|
||||
+ 1024LL*1024*1024*1024*1024*1024,
|
||||
+};
|
||||
+#define SCALE_LENGTH (sizeof(units)/sizeof(units[0]))
|
||||
+
|
||||
+#define MAX_DIGITS (SCALE_LENGTH * 3) /* XXX strlen(sprintf("%lld", -1)? */
|
||||
+
|
||||
+/** Convert the given input string "scaled" into numeric in "result".
|
||||
+ * Return 0 on success, -1 and errno set on error.
|
||||
+ */
|
||||
+int
|
||||
+scan_scaled(char *scaled, long long *result)
|
||||
+{
|
||||
+ char *p = scaled;
|
||||
+ int sign = 0;
|
||||
+ unsigned int i, ndigits = 0, fract_digits = 0;
|
||||
+ long long scale_fact = 1, whole = 0, fpart = 0;
|
||||
+
|
||||
+ /* Skip leading whitespace */
|
||||
+ while (isascii(*p) && isspace(*p))
|
||||
+ ++p;
|
||||
+
|
||||
+ /* Then at most one leading + or - */
|
||||
+ while (*p == '-' || *p == '+') {
|
||||
+ if (*p == '-') {
|
||||
+ if (sign) {
|
||||
+ errno = EINVAL;
|
||||
+ return -1;
|
||||
+ }
|
||||
+ sign = -1;
|
||||
+ ++p;
|
||||
+ } else if (*p == '+') {
|
||||
+ if (sign) {
|
||||
+ errno = EINVAL;
|
||||
+ return -1;
|
||||
+ }
|
||||
+ sign = +1;
|
||||
+ ++p;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Main loop: Scan digits, find decimal point, if present.
|
||||
+ * We don't allow exponentials, so no scientific notation
|
||||
+ * (but note that E for Exa might look like e to some!).
|
||||
+ * Advance 'p' to end, to get scale factor.
|
||||
+ */
|
||||
+ for (; isascii(*p) && (isdigit(*p) || *p=='.'); ++p) {
|
||||
+ if (*p == '.') {
|
||||
+ if (fract_digits > 0) { /* oops, more than one '.' */
|
||||
+ errno = EINVAL;
|
||||
+ return -1;
|
||||
+ }
|
||||
+ fract_digits = 1;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ i = (*p) - '0'; /* whew! finally a digit we can use */
|
||||
+ if (fract_digits > 0) {
|
||||
+ if (fract_digits >= MAX_DIGITS-1)
|
||||
+ /* ignore extra fractional digits */
|
||||
+ continue;
|
||||
+ fract_digits++; /* for later scaling */
|
||||
+ fpart *= 10;
|
||||
+ fpart += i;
|
||||
+ } else { /* normal digit */
|
||||
+ if (++ndigits >= MAX_DIGITS) {
|
||||
+ errno = ERANGE;
|
||||
+ return -1;
|
||||
+ }
|
||||
+ whole *= 10;
|
||||
+ whole += i;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (sign) {
|
||||
+ whole *= sign;
|
||||
+ fpart *= sign;
|
||||
+ }
|
||||
+
|
||||
+ /* If no scale factor given, we're done. fraction is discarded. */
|
||||
+ if (!*p) {
|
||||
+ *result = whole;
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ /* Validate scale factor, and scale whole and fraction by it. */
|
||||
+ for (i = 0; i < SCALE_LENGTH; i++) {
|
||||
+
|
||||
+ /** Are we there yet? */
|
||||
+ if (*p == scale_chars[i] ||
|
||||
+ *p == tolower(scale_chars[i])) {
|
||||
+
|
||||
+ /* If it ends with alphanumerics after the scale char, bad. */
|
||||
+ if (isalnum(*(p+1))) {
|
||||
+ errno = EINVAL;
|
||||
+ return -1;
|
||||
+ }
|
||||
+ scale_fact = scale_factors[i];
|
||||
+
|
||||
+ /* scale whole part */
|
||||
+ whole *= scale_fact;
|
||||
+
|
||||
+ /* truncate fpart so it does't overflow.
|
||||
+ * then scale fractional part.
|
||||
+ */
|
||||
+ while (fpart >= LLONG_MAX / scale_fact) {
|
||||
+ fpart /= 10;
|
||||
+ fract_digits--;
|
||||
+ }
|
||||
+ fpart *= scale_fact;
|
||||
+ if (fract_digits > 0) {
|
||||
+ for (i = 0; i < fract_digits -1; i++)
|
||||
+ fpart /= 10;
|
||||
+ }
|
||||
+ whole += fpart;
|
||||
+ *result = whole;
|
||||
+ return 0;
|
||||
+ }
|
||||
+ }
|
||||
+ errno = ERANGE;
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
+/* Format the given "number" into human-readable form in "result".
|
||||
+ * Result must point to an allocated buffer of length FMT_SCALED_STRSIZE.
|
||||
+ * Return 0 on success, -1 and errno set if error.
|
||||
+ */
|
||||
+int
|
||||
+fmt_scaled(long long number, char *result)
|
||||
+{
|
||||
+ long long abval, fract = 0;
|
||||
+ unsigned int i;
|
||||
+ unit_type unit = NONE;
|
||||
+
|
||||
+ abval = (number < 0LL) ? -number : number; /* no long long_abs yet */
|
||||
+
|
||||
+ /* Not every negative long long has a positive representation.
|
||||
+ * Also check for numbers that are just too darned big to format
|
||||
+ */
|
||||
+ if (abval < 0 || abval / 1024 >= scale_factors[SCALE_LENGTH-1]) {
|
||||
+ errno = ERANGE;
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ /* scale whole part; get unscaled fraction */
|
||||
+ for (i = 0; i < SCALE_LENGTH; i++) {
|
||||
+ if (abval/1024 < scale_factors[i]) {
|
||||
+ unit = units[i];
|
||||
+ fract = (i == 0) ? 0 : abval % scale_factors[i];
|
||||
+ number /= scale_factors[i];
|
||||
+ if (i > 0)
|
||||
+ fract /= scale_factors[i - 1];
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ fract = (10 * fract + 512) / 1024;
|
||||
+ /* if the result would be >= 10, round main number */
|
||||
+ if (fract == 10) {
|
||||
+ if (number >= 0)
|
||||
+ number++;
|
||||
+ else
|
||||
+ number--;
|
||||
+ fract = 0;
|
||||
+ }
|
||||
+
|
||||
+ if (number == 0)
|
||||
+ strlcpy(result, "0B", FMT_SCALED_STRSIZE);
|
||||
+ else if (unit == NONE || number >= 100 || number <= -100) {
|
||||
+ if (fract >= 5) {
|
||||
+ if (number >= 0)
|
||||
+ number++;
|
||||
+ else
|
||||
+ number--;
|
||||
+ }
|
||||
+ (void)snprintf(result, FMT_SCALED_STRSIZE, "%lld%c",
|
||||
+ number, scale_chars[unit]);
|
||||
+ } else
|
||||
+ (void)snprintf(result, FMT_SCALED_STRSIZE, "%lld.%1lld%c",
|
||||
+ number, fract, scale_chars[unit]);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#ifdef MAIN
|
||||
+/*
|
||||
+ * This is the original version of the program in the man page.
|
||||
+ * Copy-and-paste whatever you need from it.
|
||||
+ */
|
||||
+int
|
||||
+main(int argc, char **argv)
|
||||
+{
|
||||
+ char *cinput = "1.5K", buf[FMT_SCALED_STRSIZE];
|
||||
+ long long ninput = 10483892, result;
|
||||
+
|
||||
+ if (scan_scaled(cinput, &result) == 0)
|
||||
+ printf("\"%s\" -> %lld\n", cinput, result);
|
||||
+ else
|
||||
+ perror(cinput);
|
||||
+
|
||||
+ if (fmt_scaled(ninput, buf) == 0)
|
||||
+ printf("%lld -> \"%s\"\n", ninput, buf);
|
||||
+ else
|
||||
+ fprintf(stderr, "%lld invalid (%s)\n", ninput, strerror(errno));
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+#endif
|
134
net/openbgpd/files/patch-openbsd-compat_hash.h
Normal file
134
net/openbgpd/files/patch-openbsd-compat_hash.h
Normal file
@ -0,0 +1,134 @@
|
||||
Index: openbsd-compat/hash.h
|
||||
===================================================================
|
||||
RCS file: openbsd-compat/hash.h
|
||||
diff -N openbsd-compat/hash.h
|
||||
--- /dev/null 1 Jan 1970 00:00:00 -0000
|
||||
+++ openbsd-compat/hash.h 30 Jun 2009 05:48:11 -0000 1.1
|
||||
@@ -0,0 +1,127 @@
|
||||
+/* $OpenBSD: hash.h,v 1.4 2004/05/25 18:37:23 jmc Exp $ */
|
||||
+
|
||||
+/*
|
||||
+ * Copyright (c) 2001 Tobias Weingartner
|
||||
+ * 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 ``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 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.
|
||||
+ */
|
||||
+
|
||||
+#ifndef _SYS_HASH_H_
|
||||
+#define _SYS_HASH_H_
|
||||
+#include <sys/types.h>
|
||||
+
|
||||
+/*
|
||||
+ * Note: SMALL_KERNEL might be used to shrink these, right now I
|
||||
+ * do not see the point, as my kernel did not grow appreciably when
|
||||
+ * I switched to these from other inline code. This may have to be
|
||||
+ * revisited when/if these functions become more prevalent in the
|
||||
+ * kernel.
|
||||
+ */
|
||||
+
|
||||
+/* Convenience */
|
||||
+#ifndef HASHINIT
|
||||
+#define HASHINIT 5381
|
||||
+#define HASHSTEP(x,c) (((x << 5) + x) + (c))
|
||||
+#endif
|
||||
+
|
||||
+/*
|
||||
+ * Return a 32-bit hash of the given buffer. The init
|
||||
+ * value should be 0, or the previous hash value to extend
|
||||
+ * the previous hash.
|
||||
+ */
|
||||
+static __inline uint32_t
|
||||
+hash32_buf(const void *buf, size_t len, uint32_t hash)
|
||||
+{
|
||||
+ const unsigned char *p = buf;
|
||||
+
|
||||
+ while (len--)
|
||||
+ hash = HASHSTEP(hash, *p++);
|
||||
+
|
||||
+ return hash;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Return a 32-bit hash of the given string.
|
||||
+ */
|
||||
+static __inline uint32_t
|
||||
+hash32_str(const void *buf, uint32_t hash)
|
||||
+{
|
||||
+ const unsigned char *p = buf;
|
||||
+
|
||||
+ while (*p)
|
||||
+ hash = HASHSTEP(hash, *p++);
|
||||
+
|
||||
+ return hash;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Return a 32-bit hash of the given string, limited by N.
|
||||
+ */
|
||||
+static __inline uint32_t
|
||||
+hash32_strn(const void *buf, size_t len, uint32_t hash)
|
||||
+{
|
||||
+ const unsigned char *p = buf;
|
||||
+
|
||||
+ while (*p && len--)
|
||||
+ hash = HASHSTEP(hash, *p++);
|
||||
+
|
||||
+ return hash;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Return a 32-bit hash of the given string terminated by C,
|
||||
+ * (as well as 0). This is mainly here as a helper for the
|
||||
+ * namei() hashing of path name parts.
|
||||
+ */
|
||||
+static __inline uint32_t
|
||||
+hash32_stre(const void *buf, int end, char **ep, uint32_t hash)
|
||||
+{
|
||||
+ const unsigned char *p = buf;
|
||||
+
|
||||
+ while (*p && (*p != end))
|
||||
+ hash = HASHSTEP(hash, *p++);
|
||||
+
|
||||
+ if (ep)
|
||||
+ *ep = (char *)p;
|
||||
+
|
||||
+ return hash;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Return a 32-bit hash of the given string, limited by N,
|
||||
+ * and terminated by C (as well as 0). This is mainly here
|
||||
+ * as a helper for the namei() hashing of path name parts.
|
||||
+ */
|
||||
+static __inline uint32_t
|
||||
+hash32_strne(const void *buf, size_t len, int end, char **ep, uint32_t hash)
|
||||
+{
|
||||
+ const unsigned char *p = buf;
|
||||
+
|
||||
+ while (*p && (*p != end) && len--)
|
||||
+ hash = HASHSTEP(hash, *p++);
|
||||
+
|
||||
+ if (ep)
|
||||
+ *ep = (char *)p;
|
||||
+
|
||||
+ return hash;
|
||||
+}
|
||||
+#endif /* !_SYS_HASH_H_ */
|
619
net/openbgpd/files/patch-openbsd-compat_if_media.h
Normal file
619
net/openbgpd/files/patch-openbsd-compat_if_media.h
Normal file
@ -0,0 +1,619 @@
|
||||
Index: openbsd-compat/if_media.h
|
||||
===================================================================
|
||||
RCS file: openbsd-compat/if_media.h
|
||||
diff -N openbsd-compat/if_media.h
|
||||
--- /dev/null 1 Jan 1970 00:00:00 -0000
|
||||
+++ openbsd-compat/if_media.h 30 Jun 2009 05:48:11 -0000 1.1
|
||||
@@ -0,0 +1,612 @@
|
||||
+/* $OpenBSD: if_media.h,v 1.17 2004/11/02 02:12:16 reyk Exp $ */
|
||||
+/* $NetBSD: if_media.h,v 1.22 2000/02/17 21:53:16 sommerfeld Exp $ */
|
||||
+
|
||||
+/*-
|
||||
+ * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
|
||||
+ * All rights reserved.
|
||||
+ *
|
||||
+ * This code is derived from software contributed to The NetBSD Foundation
|
||||
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
|
||||
+ * NASA Ames Research Center.
|
||||
+ *
|
||||
+ * 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.
|
||||
+ * 3. All advertising materials mentioning features or use of this software
|
||||
+ * must display the following acknowledgement:
|
||||
+ * This product includes software developed by the NetBSD
|
||||
+ * Foundation, Inc. and its contributors.
|
||||
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
+ * contributors may be used to endorse or promote products derived
|
||||
+ * from this software without specific prior written permission.
|
||||
+ *
|
||||
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
|
||||
+ */
|
||||
+
|
||||
+/*
|
||||
+ * Copyright (c) 1997
|
||||
+ * Jonathan Stone and Jason R. Thorpe. All rights reserved.
|
||||
+ *
|
||||
+ * This software is derived from information provided by Matt Thomas.
|
||||
+ *
|
||||
+ * 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.
|
||||
+ * 3. All advertising materials mentioning features or use of this software
|
||||
+ * must display the following acknowledgement:
|
||||
+ * This product includes software developed by Jonathan Stone
|
||||
+ * and Jason R. Thorpe for the NetBSD Project.
|
||||
+ * 4. The names of the authors may not be used to endorse or promote products
|
||||
+ * derived from this software without specific prior written permission.
|
||||
+ *
|
||||
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 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.
|
||||
+ */
|
||||
+
|
||||
+#ifndef _NET_IF_MEDIA_H_
|
||||
+#define _NET_IF_MEDIA_H_
|
||||
+
|
||||
+/*
|
||||
+ * Prototypes and definitions for BSD/OS-compatible network interface
|
||||
+ * media selection.
|
||||
+ *
|
||||
+ * Where it is safe to do so, this code strays slightly from the BSD/OS
|
||||
+ * design. Software which uses the API (device drivers, basically)
|
||||
+ * shouldn't notice any difference.
|
||||
+ *
|
||||
+ * Many thanks to Matt Thomas for providing the information necessary
|
||||
+ * to implement this interface.
|
||||
+ */
|
||||
+
|
||||
+#ifdef _KERNEL
|
||||
+
|
||||
+#include <sys/queue.h>
|
||||
+
|
||||
+/*
|
||||
+ * Driver callbacks for media status and change requests.
|
||||
+ */
|
||||
+typedef int (*ifm_change_cb_t)(struct ifnet *ifp);
|
||||
+typedef void (*ifm_stat_cb_t)(struct ifnet *ifp, struct ifmediareq *req);
|
||||
+
|
||||
+/*
|
||||
+ * In-kernel representation of a single supported media type.
|
||||
+ */
|
||||
+struct ifmedia_entry {
|
||||
+ TAILQ_ENTRY(ifmedia_entry) ifm_list;
|
||||
+ int ifm_media; /* description of this media attachment */
|
||||
+ int ifm_data; /* for driver-specific use */
|
||||
+ void *ifm_aux; /* for driver-specific use */
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ * One of these goes into a network interface's softc structure.
|
||||
+ * It is used to keep general media state.
|
||||
+ */
|
||||
+struct ifmedia {
|
||||
+ int ifm_mask; /* mask of changes we don't care about */
|
||||
+ int ifm_media; /* current user-set media word */
|
||||
+ struct ifmedia_entry *ifm_cur; /* currently selected media */
|
||||
+ TAILQ_HEAD(, ifmedia_entry) ifm_list; /* list of all supported media */
|
||||
+ ifm_change_cb_t ifm_change; /* media change driver callback */
|
||||
+ ifm_stat_cb_t ifm_status; /* media status driver callback */
|
||||
+};
|
||||
+
|
||||
+/* Initialize an interface's struct if_media field. */
|
||||
+void ifmedia_init(struct ifmedia *ifm, int dontcare_mask,
|
||||
+ ifm_change_cb_t change_callback, ifm_stat_cb_t status_callback);
|
||||
+
|
||||
+/* Add one supported medium to a struct ifmedia. */
|
||||
+void ifmedia_add(struct ifmedia *ifm, int mword, int data, void *aux);
|
||||
+
|
||||
+/* Add an array (of ifmedia_entry) media to a struct ifmedia. */
|
||||
+void ifmedia_list_add(struct ifmedia *mp, struct ifmedia_entry *lp,
|
||||
+ int count);
|
||||
+
|
||||
+/* Set default media type on initialization. */
|
||||
+void ifmedia_set(struct ifmedia *ifm, int mword);
|
||||
+
|
||||
+/* Common ioctl function for getting/setting media, called by driver. */
|
||||
+int ifmedia_ioctl(struct ifnet *ifp, struct ifreq *ifr,
|
||||
+ struct ifmedia *ifm, u_long cmd);
|
||||
+
|
||||
+/* Locate a media entry */
|
||||
+struct ifmedia_entry *ifmedia_match(struct ifmedia *ifm,
|
||||
+ int flags, int mask);
|
||||
+
|
||||
+/* Delete all media for a given media instance */
|
||||
+void ifmedia_delete_instance(struct ifmedia *, int);
|
||||
+
|
||||
+/* Compute baudrate for a given media. */
|
||||
+int ifmedia_baudrate(int);
|
||||
+#endif /*_KERNEL */
|
||||
+
|
||||
+/*
|
||||
+ * if_media Options word:
|
||||
+ * Bits Use
|
||||
+ * ---- -------
|
||||
+ * 0-4 Media subtype MAX SUBTYPE == 31!
|
||||
+ * 5-7 Media type
|
||||
+ * 8-15 Type specific options
|
||||
+ * 16-19 RFU
|
||||
+ * 20-27 Shared (global) options
|
||||
+ * 28-31 Instance
|
||||
+ */
|
||||
+
|
||||
+/*
|
||||
+ * Ethernet
|
||||
+ */
|
||||
+#define IFM_ETHER 0x00000020
|
||||
+#define IFM_10_T 3 /* 10BaseT - RJ45 */
|
||||
+#define IFM_10_2 4 /* 10Base2 - Thinnet */
|
||||
+#define IFM_10_5 5 /* 10Base5 - AUI */
|
||||
+#define IFM_100_TX 6 /* 100BaseTX - RJ45 */
|
||||
+#define IFM_100_FX 7 /* 100BaseFX - Fiber */
|
||||
+#define IFM_100_T4 8 /* 100BaseT4 - 4 pair cat 3 */
|
||||
+#define IFM_100_VG 9 /* 100VG-AnyLAN */
|
||||
+#define IFM_100_T2 10 /* 100BaseT2 */
|
||||
+#define IFM_1000_SX 11 /* 1000BaseSX - multi-mode fiber */
|
||||
+#define IFM_10_STP 12 /* 10BaseT over shielded TP */
|
||||
+#define IFM_10_FL 13 /* 10BaseFL - Fiber */
|
||||
+#define IFM_1000_LX 14 /* 1000baseLX - single-mode fiber */
|
||||
+#define IFM_1000_CX 15 /* 1000baseCX - 150ohm STP */
|
||||
+#define IFM_1000_T 16 /* 1000baseT - 4 pair cat 5 */
|
||||
+#define IFM_1000_TX IFM_1000_T /* for backwards compatibility */
|
||||
+#define IFM_HPNA_1 17 /* HomePNA 1.0 (1Mb/s) */
|
||||
+
|
||||
+#define IFM_ETH_MASTER 0x00000100 /* master mode (1000baseT) */
|
||||
+
|
||||
+/*
|
||||
+ * Token ring
|
||||
+ */
|
||||
+#define IFM_TOKEN 0x00000040
|
||||
+#define IFM_TOK_STP4 3 /* Shielded twisted pair 4m - DB9 */
|
||||
+#define IFM_TOK_STP16 4 /* Shielded twisted pair 16m - DB9 */
|
||||
+#define IFM_TOK_UTP4 5 /* Unshielded twisted pair 4m - RJ45 */
|
||||
+#define IFM_TOK_UTP16 6 /* Unshielded twisted pair 16m - RJ45 */
|
||||
+#define IFM_TOK_ETR 0x00000200 /* Early token release */
|
||||
+#define IFM_TOK_SRCRT 0x00000400 /* Enable source routing features */
|
||||
+#define IFM_TOK_ALLR 0x00000800 /* All routes / Single route bcast */
|
||||
+
|
||||
+/*
|
||||
+ * FDDI
|
||||
+ */
|
||||
+#define IFM_FDDI 0x00000060
|
||||
+#define IFM_FDDI_SMF 3 /* Single-mode fiber */
|
||||
+#define IFM_FDDI_MMF 4 /* Multi-mode fiber */
|
||||
+#define IFM_FDDI_UTP 5 /* CDDI / UTP */
|
||||
+#define IFM_FDDI_DA 0x00000100 /* Dual attach / single attach */
|
||||
+
|
||||
+/*
|
||||
+ * IEEE 802.11 Wireless
|
||||
+ */
|
||||
+#define IFM_IEEE80211 0x00000080
|
||||
+#define IFM_IEEE80211_FH1 3 /* Frequency Hopping 1Mbps */
|
||||
+#define IFM_IEEE80211_FH2 4 /* Frequency Hopping 2Mbps */
|
||||
+#define IFM_IEEE80211_DS2 5 /* Direct Sequence 2Mbps */
|
||||
+#define IFM_IEEE80211_DS5 6 /* Direct Sequence 5Mbps*/
|
||||
+#define IFM_IEEE80211_DS11 7 /* Direct Sequence 11Mbps*/
|
||||
+#define IFM_IEEE80211_DS1 8 /* Direct Sequence 1Mbps*/
|
||||
+#define IFM_IEEE80211_DS22 9 /* Direct Sequence 22Mbps */
|
||||
+#define IFM_IEEE80211_OFDM6 10 /* OFDM 6Mbps */
|
||||
+#define IFM_IEEE80211_OFDM9 11 /* OFDM 9Mbps */
|
||||
+#define IFM_IEEE80211_OFDM12 12 /* OFDM 12Mbps */
|
||||
+#define IFM_IEEE80211_OFDM18 13 /* OFDM 18Mbps */
|
||||
+#define IFM_IEEE80211_OFDM24 14 /* OFDM 24Mbps */
|
||||
+#define IFM_IEEE80211_OFDM36 15 /* OFDM 36Mbps */
|
||||
+#define IFM_IEEE80211_OFDM48 16 /* OFDM 48Mbps */
|
||||
+#define IFM_IEEE80211_OFDM54 17 /* OFDM 54Mbps */
|
||||
+#define IFM_IEEE80211_OFDM72 18 /* OFDM 72Mbps */
|
||||
+
|
||||
+#define IFM_IEEE80211_ADHOC 0x100 /* Operate in Adhoc mode */
|
||||
+#define IFM_IEEE80211_HOSTAP 0x200 /* Operate in Host AP mode */
|
||||
+#define IFM_IEEE80211_IBSS 0x400 /* Operate in IBSS mode */
|
||||
+#define IFM_IEEE80211_IBSSMASTER 0x800 /* Operate as an IBSS master */
|
||||
+#define IFM_IEEE80211_MONITOR 0x1000 /* Operate in Monitor mode */
|
||||
+#define IFM_IEEE80211_TURBO 0x2000 /* Operate in Turbo mode */
|
||||
+
|
||||
+/* operating mode for multi-mode devices */
|
||||
+#define IFM_IEEE80211_11A 0x00010000 /* 5Ghz, OFDM mode */
|
||||
+#define IFM_IEEE80211_11B 0x00020000 /* Direct Sequence mode */
|
||||
+#define IFM_IEEE80211_11G 0x00030000 /* 2Ghz, CCK mode */
|
||||
+#define IFM_IEEE80211_FH 0x00040000 /* 2Ghz, GFSK mode */
|
||||
+
|
||||
+/*
|
||||
+ * Digitally multiplexed "Carrier" Serial Interfaces
|
||||
+ */
|
||||
+#define IFM_TDM 0x000000a0
|
||||
+#define IFM_TDM_T1 3 /* T1 B8ZS+ESF 24 ts */
|
||||
+#define IFM_TDM_T1_AMI 4 /* T1 AMI+SF 24 ts */
|
||||
+#define IFM_TDM_E1 5 /* E1 HDB3+G.703 clearchannel 32 ts */
|
||||
+#define IFM_TDM_E1_G704 6 /* E1 HDB3+G.703+G.704 channelized 31 ts */
|
||||
+#define IFM_TDM_E1_AMI 7 /* E1 AMI+G.703 32 ts */
|
||||
+#define IFM_TDM_E1_AMI_G704 8 /* E1 AMI+G.703+G.704 31 ts */
|
||||
+#define IFM_TDM_T3 9 /* T3 B3ZS+C-bit 672 ts */
|
||||
+#define IFM_TDM_T3_M13 10 /* T3 B3ZS+M13 672 ts */
|
||||
+#define IFM_TDM_E3 11 /* E3 HDB3+G.751 512? ts */
|
||||
+#define IFM_TDM_E3_G751 12 /* E3 G.751 512 ts */
|
||||
+#define IFM_TDM_E3_G832 13 /* E3 G.832 512 ts */
|
||||
+/*
|
||||
+ * 6 major ways that networks talk: Drivers enforce independent selection,
|
||||
+ * meaning, a driver will ensure that only one of these is set at a time.
|
||||
+ */
|
||||
+#define IFM_TDM_HDLC_CRC16 0x0100 /* Use 16-bit CRC for HDLC instead */
|
||||
+#define IFM_TDM_PPP 0x0200 /* SPPP (dumb) */
|
||||
+#define IFM_TDM_FR_ANSI 0x0400 /* Frame Relay + LMI ANSI "Annex D" */
|
||||
+#define IFM_TDM_FR_CISCO 0x0800 /* Frame Relay + LMI Cisco */
|
||||
+#define IFM_TDM_FR_ITU 0x1000 /* Frame Relay + LMI ITU "Q933A" */
|
||||
+
|
||||
+/*
|
||||
+ * Common Access Redundancy Protocol
|
||||
+ */
|
||||
+#define IFM_CARP 0x000000c0
|
||||
+
|
||||
+/*
|
||||
+ * Shared media sub-types
|
||||
+ */
|
||||
+#define IFM_AUTO 0 /* Autoselect best media */
|
||||
+#define IFM_MANUAL 1 /* Jumper/dipswitch selects media */
|
||||
+#define IFM_NONE 2 /* Deselect all media */
|
||||
+
|
||||
+/*
|
||||
+ * Shared options
|
||||
+ */
|
||||
+#define IFM_FDX 0x00100000 /* Force full duplex */
|
||||
+#define IFM_HDX 0x00200000 /* Force half duplex */
|
||||
+#define IFM_FLOW 0x00400000 /* enable hardware flow control */
|
||||
+#define IFM_FLAG0 0x01000000 /* Driver defined flag */
|
||||
+#define IFM_FLAG1 0x02000000 /* Driver defined flag */
|
||||
+#define IFM_FLAG2 0x04000000 /* Driver defined flag */
|
||||
+#define IFM_LOOP 0x08000000 /* Put hardware in loopback */
|
||||
+
|
||||
+/*
|
||||
+ * Masks
|
||||
+ */
|
||||
+#define IFM_NMASK 0x000000e0 /* Network type */
|
||||
+#define IFM_TMASK 0x0000001f /* Media sub-type */
|
||||
+#define IFM_IMASK 0xf0000000 /* Instance */
|
||||
+#define IFM_ISHIFT 28 /* Instance shift */
|
||||
+#define IFM_OMASK 0x0000ff00 /* Type specific options */
|
||||
+#define IFM_MMASK 0x00070000 /* Mode */
|
||||
+#define IFM_MSHIFT 16 /* Mode shift */
|
||||
+#define IFM_GMASK 0x0ff00000 /* Global options */
|
||||
+
|
||||
+#define IFM_NMIN IFM_ETHER /* lowest Network type */
|
||||
+#define IFM_NMAX IFM_NMASK /* highest Network type */
|
||||
+
|
||||
+/*
|
||||
+ * Status bits
|
||||
+ */
|
||||
+#define IFM_AVALID 0x00000001 /* Active bit valid */
|
||||
+#define IFM_ACTIVE 0x00000002 /* Interface attached to working net */
|
||||
+
|
||||
+/* Mask of "status valid" bits, for ifconfig(8). */
|
||||
+#define IFM_STATUS_VALID IFM_AVALID
|
||||
+
|
||||
+/* List of "status valid" bits, for ifconfig(8). */
|
||||
+#define IFM_STATUS_VALID_LIST { \
|
||||
+ IFM_AVALID, \
|
||||
+ 0 \
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Macros to extract various bits of information from the media word.
|
||||
+ */
|
||||
+#define IFM_TYPE(x) ((x) & IFM_NMASK)
|
||||
+#define IFM_SUBTYPE(x) ((x) & IFM_TMASK)
|
||||
+#define IFM_INST(x) (((x) & IFM_IMASK) >> IFM_ISHIFT)
|
||||
+#define IFM_OPTIONS(x) ((x) & (IFM_OMASK|IFM_GMASK))
|
||||
+#define IFM_MODE(x) ((x) & IFM_MMASK)
|
||||
+
|
||||
+#define IFM_INST_MAX IFM_INST(IFM_IMASK)
|
||||
+#define IFM_INST_ANY (-1)
|
||||
+
|
||||
+/*
|
||||
+ * Macro to create a media word.
|
||||
+ */
|
||||
+#define IFM_MAKEWORD(type, subtype, options, instance) \
|
||||
+ ((type) | (subtype) | (options) | ((instance) << IFM_ISHIFT))
|
||||
+#define IFM_MAKEMODE(mode) \
|
||||
+ (((mode) << IFM_MSHIFT) & IFM_MMASK)
|
||||
+/*
|
||||
+ * NetBSD extension not defined in the BSDI API. This is used in various
|
||||
+ * places to get the canonical description for a given type/subtype.
|
||||
+ *
|
||||
+ * In the subtype and mediaopt descriptions, the valid TYPE bits are OR'd
|
||||
+ * in to indicate which TYPE the subtype/option corresponds to. If no
|
||||
+ * TYPE is present, it is a shared media/mediaopt.
|
||||
+ *
|
||||
+ * Note that these are parsed case-insensitive.
|
||||
+ *
|
||||
+ * Order is important. The first matching entry is the canonical name
|
||||
+ * for a media type; subsequent matches are aliases.
|
||||
+ */
|
||||
+struct ifmedia_description {
|
||||
+ int ifmt_word; /* word value; may be masked */
|
||||
+ const char *ifmt_string; /* description */
|
||||
+};
|
||||
+
|
||||
+#define IFM_TYPE_DESCRIPTIONS { \
|
||||
+ { IFM_ETHER, "Ethernet" }, \
|
||||
+ { IFM_ETHER, "ether" }, \
|
||||
+ { IFM_TOKEN, "TokenRing" }, \
|
||||
+ { IFM_TOKEN, "token" }, \
|
||||
+ { IFM_FDDI, "FDDI" }, \
|
||||
+ { IFM_IEEE80211, "IEEE802.11" }, \
|
||||
+ { IFM_TDM, "TDM" }, \
|
||||
+ { IFM_CARP, "CARP" }, \
|
||||
+ { 0, NULL }, \
|
||||
+}
|
||||
+
|
||||
+#define IFM_TYPE_MATCH(dt, t) \
|
||||
+ (IFM_TYPE((dt)) == 0 || IFM_TYPE((dt)) == IFM_TYPE((t)))
|
||||
+
|
||||
+#define IFM_SUBTYPE_DESCRIPTIONS { \
|
||||
+ { IFM_AUTO, "autoselect" }, \
|
||||
+ { IFM_AUTO, "auto" }, \
|
||||
+ { IFM_MANUAL, "manual" }, \
|
||||
+ { IFM_NONE, "none" }, \
|
||||
+ \
|
||||
+ { IFM_ETHER|IFM_10_T, "10baseT" }, \
|
||||
+ { IFM_ETHER|IFM_10_T, "10baseT/UTP" }, \
|
||||
+ { IFM_ETHER|IFM_10_T, "UTP" }, \
|
||||
+ { IFM_ETHER|IFM_10_T, "10UTP" }, \
|
||||
+ { IFM_ETHER|IFM_10_2, "10base2" }, \
|
||||
+ { IFM_ETHER|IFM_10_2, "10base2/BNC" }, \
|
||||
+ { IFM_ETHER|IFM_10_2, "BNC" }, \
|
||||
+ { IFM_ETHER|IFM_10_2, "10BNC" }, \
|
||||
+ { IFM_ETHER|IFM_10_5, "10base5" }, \
|
||||
+ { IFM_ETHER|IFM_10_5, "10base5/AUI" }, \
|
||||
+ { IFM_ETHER|IFM_10_5, "AUI" }, \
|
||||
+ { IFM_ETHER|IFM_10_5, "10AUI" }, \
|
||||
+ { IFM_ETHER|IFM_100_TX, "100baseTX" }, \
|
||||
+ { IFM_ETHER|IFM_100_TX, "100TX" }, \
|
||||
+ { IFM_ETHER|IFM_100_FX, "100baseFX" }, \
|
||||
+ { IFM_ETHER|IFM_100_FX, "100FX" }, \
|
||||
+ { IFM_ETHER|IFM_100_T4, "100baseT4" }, \
|
||||
+ { IFM_ETHER|IFM_100_T4, "100T4" }, \
|
||||
+ { IFM_ETHER|IFM_100_VG, "100baseVG" }, \
|
||||
+ { IFM_ETHER|IFM_100_VG, "100VG" }, \
|
||||
+ { IFM_ETHER|IFM_100_T2, "100baseT2" }, \
|
||||
+ { IFM_ETHER|IFM_100_T2, "100T2" }, \
|
||||
+ { IFM_ETHER|IFM_1000_SX, "1000baseSX" }, \
|
||||
+ { IFM_ETHER|IFM_1000_SX, "1000SX" }, \
|
||||
+ { IFM_ETHER|IFM_10_STP, "10baseSTP" }, \
|
||||
+ { IFM_ETHER|IFM_10_STP, "STP" }, \
|
||||
+ { IFM_ETHER|IFM_10_STP, "10STP" }, \
|
||||
+ { IFM_ETHER|IFM_10_FL, "10baseFL" }, \
|
||||
+ { IFM_ETHER|IFM_10_FL, "FL" }, \
|
||||
+ { IFM_ETHER|IFM_10_FL, "10FL" }, \
|
||||
+ { IFM_ETHER|IFM_1000_LX, "1000baseLX" }, \
|
||||
+ { IFM_ETHER|IFM_1000_LX, "1000LX" }, \
|
||||
+ { IFM_ETHER|IFM_1000_CX, "1000baseCX" }, \
|
||||
+ { IFM_ETHER|IFM_1000_CX, "1000CX" }, \
|
||||
+ { IFM_ETHER|IFM_1000_T, "1000baseT" }, \
|
||||
+ { IFM_ETHER|IFM_1000_T, "1000T" }, \
|
||||
+ { IFM_ETHER|IFM_1000_T, "1000baseTX" }, \
|
||||
+ { IFM_ETHER|IFM_1000_T, "1000TX" }, \
|
||||
+ { IFM_ETHER|IFM_HPNA_1, "HomePNA1" }, \
|
||||
+ { IFM_ETHER|IFM_HPNA_1, "HPNA1" }, \
|
||||
+ \
|
||||
+ { IFM_TOKEN|IFM_TOK_STP4, "DB9/4Mbit" }, \
|
||||
+ { IFM_TOKEN|IFM_TOK_STP4, "4STP" }, \
|
||||
+ { IFM_TOKEN|IFM_TOK_STP16, "DB9/16Mbit" }, \
|
||||
+ { IFM_TOKEN|IFM_TOK_STP16, "16STP" }, \
|
||||
+ { IFM_TOKEN|IFM_TOK_UTP4, "UTP/4Mbit" }, \
|
||||
+ { IFM_TOKEN|IFM_TOK_UTP4, "4UTP" }, \
|
||||
+ { IFM_TOKEN|IFM_TOK_UTP16, "UTP/16Mbit" }, \
|
||||
+ { IFM_TOKEN|IFM_TOK_UTP16, "16UTP" }, \
|
||||
+ \
|
||||
+ { IFM_FDDI|IFM_FDDI_SMF, "Single-mode" }, \
|
||||
+ { IFM_FDDI|IFM_FDDI_SMF, "SMF" }, \
|
||||
+ { IFM_FDDI|IFM_FDDI_MMF, "Multi-mode" }, \
|
||||
+ { IFM_FDDI|IFM_FDDI_MMF, "MMF" }, \
|
||||
+ { IFM_FDDI|IFM_FDDI_UTP, "UTP" }, \
|
||||
+ { IFM_FDDI|IFM_FDDI_UTP, "CDDI" }, \
|
||||
+ \
|
||||
+ { IFM_IEEE80211|IFM_IEEE80211_FH1, "FH1" }, \
|
||||
+ { IFM_IEEE80211|IFM_IEEE80211_FH2, "FH2" }, \
|
||||
+ { IFM_IEEE80211|IFM_IEEE80211_DS2, "DS2" }, \
|
||||
+ { IFM_IEEE80211|IFM_IEEE80211_DS5, "DS5" }, \
|
||||
+ { IFM_IEEE80211|IFM_IEEE80211_DS11, "DS11" }, \
|
||||
+ { IFM_IEEE80211|IFM_IEEE80211_DS1, "DS1" }, \
|
||||
+ { IFM_IEEE80211|IFM_IEEE80211_DS22, "DS22" }, \
|
||||
+ { IFM_IEEE80211|IFM_IEEE80211_OFDM6, "OFDM6" }, \
|
||||
+ { IFM_IEEE80211|IFM_IEEE80211_OFDM9, "OFDM9" }, \
|
||||
+ { IFM_IEEE80211|IFM_IEEE80211_OFDM12, "OFDM12" }, \
|
||||
+ { IFM_IEEE80211|IFM_IEEE80211_OFDM18, "OFDM18" }, \
|
||||
+ { IFM_IEEE80211|IFM_IEEE80211_OFDM24, "OFDM24" }, \
|
||||
+ { IFM_IEEE80211|IFM_IEEE80211_OFDM36, "OFDM36" }, \
|
||||
+ { IFM_IEEE80211|IFM_IEEE80211_OFDM48, "OFDM48" }, \
|
||||
+ { IFM_IEEE80211|IFM_IEEE80211_OFDM54, "OFDM54" }, \
|
||||
+ { IFM_IEEE80211|IFM_IEEE80211_OFDM72, "OFDM72" }, \
|
||||
+ \
|
||||
+ { IFM_TDM|IFM_TDM_T1, "t1" }, \
|
||||
+ { IFM_TDM|IFM_TDM_T1_AMI, "t1-ami" }, \
|
||||
+ { IFM_TDM|IFM_TDM_E1, "e1" }, \
|
||||
+ { IFM_TDM|IFM_TDM_E1_G704, "e1-g.704" }, \
|
||||
+ { IFM_TDM|IFM_TDM_E1_AMI, "e1-ami" }, \
|
||||
+ { IFM_TDM|IFM_TDM_E1_AMI_G704, "e1-ami-g.704" }, \
|
||||
+ { IFM_TDM|IFM_TDM_T3, "t3" }, \
|
||||
+ { IFM_TDM|IFM_TDM_T3_M13, "t3-m13" }, \
|
||||
+ { IFM_TDM|IFM_TDM_E3, "e3" }, \
|
||||
+ { IFM_TDM|IFM_TDM_E3_G751, "e3-g.751" }, \
|
||||
+ { IFM_TDM|IFM_TDM_E3_G832, "e3-g.832" }, \
|
||||
+ \
|
||||
+ { 0, NULL }, \
|
||||
+}
|
||||
+
|
||||
+#define IFM_MODE_DESCRIPTIONS { \
|
||||
+ { IFM_AUTO, "autoselect" }, \
|
||||
+ { IFM_AUTO, "auto" }, \
|
||||
+ { IFM_IEEE80211|IFM_IEEE80211_11A, "11a" }, \
|
||||
+ { IFM_IEEE80211|IFM_IEEE80211_11B, "11b" }, \
|
||||
+ { IFM_IEEE80211|IFM_IEEE80211_11G, "11g" }, \
|
||||
+ { IFM_IEEE80211|IFM_IEEE80211_FH, "fh" }, \
|
||||
+ { 0, NULL }, \
|
||||
+}
|
||||
+
|
||||
+#define IFM_OPTION_DESCRIPTIONS { \
|
||||
+ { IFM_FDX, "full-duplex" }, \
|
||||
+ { IFM_FDX, "fdx" }, \
|
||||
+ { IFM_HDX, "half-duplex" }, \
|
||||
+ { IFM_HDX, "hdx" }, \
|
||||
+ { IFM_FLAG0, "flag0" }, \
|
||||
+ { IFM_FLAG1, "flag1" }, \
|
||||
+ { IFM_FLAG2, "flag2" }, \
|
||||
+ { IFM_LOOP, "loopback" }, \
|
||||
+ { IFM_LOOP, "hw-loopback"}, \
|
||||
+ { IFM_LOOP, "loop" }, \
|
||||
+ \
|
||||
+ { IFM_ETHER|IFM_ETH_MASTER, "master" }, \
|
||||
+ \
|
||||
+ { IFM_TOKEN|IFM_TOK_ETR, "EarlyTokenRelease" }, \
|
||||
+ { IFM_TOKEN|IFM_TOK_ETR, "ETR" }, \
|
||||
+ { IFM_TOKEN|IFM_TOK_SRCRT, "SourceRouting" }, \
|
||||
+ { IFM_TOKEN|IFM_TOK_SRCRT, "SRCRT" }, \
|
||||
+ { IFM_TOKEN|IFM_TOK_ALLR, "AllRoutes" }, \
|
||||
+ { IFM_TOKEN|IFM_TOK_ALLR, "ALLR" }, \
|
||||
+ \
|
||||
+ { IFM_FDDI|IFM_FDDI_DA, "dual-attach" }, \
|
||||
+ { IFM_FDDI|IFM_FDDI_DA, "das" }, \
|
||||
+ \
|
||||
+ { IFM_IEEE80211|IFM_IEEE80211_ADHOC, "adhoc" }, \
|
||||
+ { IFM_IEEE80211|IFM_IEEE80211_HOSTAP, "hostap" }, \
|
||||
+ { IFM_IEEE80211|IFM_IEEE80211_IBSS, "ibss" }, \
|
||||
+ { IFM_IEEE80211|IFM_IEEE80211_IBSSMASTER, "ibss-master" }, \
|
||||
+ { IFM_IEEE80211|IFM_IEEE80211_MONITOR, "monitor" }, \
|
||||
+ { IFM_IEEE80211|IFM_IEEE80211_TURBO, "turbo" }, \
|
||||
+ \
|
||||
+ { IFM_TDM|IFM_TDM_HDLC_CRC16, "hdlc-crc16" }, \
|
||||
+ { IFM_TDM|IFM_TDM_PPP, "ppp" }, \
|
||||
+ { IFM_TDM|IFM_TDM_FR_ANSI, "framerelay-ansi" }, \
|
||||
+ { IFM_TDM|IFM_TDM_FR_CISCO, "framerelay-cisco" }, \
|
||||
+ { IFM_TDM|IFM_TDM_FR_ANSI, "framerelay-itu" }, \
|
||||
+ \
|
||||
+ { 0, NULL }, \
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Baudrate descriptions for the various media types.
|
||||
+ */
|
||||
+struct ifmedia_baudrate {
|
||||
+ int ifmb_word; /* media word */
|
||||
+ int ifmb_baudrate; /* corresponding baudrate */
|
||||
+};
|
||||
+
|
||||
+#define IFM_BAUDRATE_DESCRIPTIONS { \
|
||||
+ { IFM_ETHER|IFM_10_T, IF_Mbps(10) }, \
|
||||
+ { IFM_ETHER|IFM_10_2, IF_Mbps(10) }, \
|
||||
+ { IFM_ETHER|IFM_10_5, IF_Mbps(10) }, \
|
||||
+ { IFM_ETHER|IFM_100_TX, IF_Mbps(100) }, \
|
||||
+ { IFM_ETHER|IFM_100_FX, IF_Mbps(100) }, \
|
||||
+ { IFM_ETHER|IFM_100_T4, IF_Mbps(100) }, \
|
||||
+ { IFM_ETHER|IFM_100_VG, IF_Mbps(100) }, \
|
||||
+ { IFM_ETHER|IFM_100_T2, IF_Mbps(100) }, \
|
||||
+ { IFM_ETHER|IFM_1000_SX, IF_Mbps(1000) }, \
|
||||
+ { IFM_ETHER|IFM_10_STP, IF_Mbps(10) }, \
|
||||
+ { IFM_ETHER|IFM_10_FL, IF_Mbps(10) }, \
|
||||
+ { IFM_ETHER|IFM_1000_LX, IF_Mbps(1000) }, \
|
||||
+ { IFM_ETHER|IFM_1000_CX, IF_Mbps(1000) }, \
|
||||
+ { IFM_ETHER|IFM_1000_T, IF_Mbps(1000) }, \
|
||||
+ { IFM_ETHER|IFM_HPNA_1, IF_Mbps(1) }, \
|
||||
+ \
|
||||
+ { IFM_TOKEN|IFM_TOK_STP4, IF_Mbps(4) }, \
|
||||
+ { IFM_TOKEN|IFM_TOK_STP16, IF_Mbps(16) }, \
|
||||
+ { IFM_TOKEN|IFM_TOK_UTP4, IF_Mbps(4) }, \
|
||||
+ { IFM_TOKEN|IFM_TOK_UTP16, IF_Mbps(16) }, \
|
||||
+ \
|
||||
+ { IFM_FDDI|IFM_FDDI_SMF, IF_Mbps(100) }, \
|
||||
+ { IFM_FDDI|IFM_FDDI_MMF, IF_Mbps(100) }, \
|
||||
+ { IFM_FDDI|IFM_FDDI_UTP, IF_Mbps(100) }, \
|
||||
+ \
|
||||
+ { IFM_IEEE80211|IFM_IEEE80211_FH1, IF_Mbps(1) }, \
|
||||
+ { IFM_IEEE80211|IFM_IEEE80211_FH2, IF_Mbps(2) }, \
|
||||
+ { IFM_IEEE80211|IFM_IEEE80211_DS1, IF_Mbps(1) }, \
|
||||
+ { IFM_IEEE80211|IFM_IEEE80211_DS2, IF_Mbps(2) }, \
|
||||
+ { IFM_IEEE80211|IFM_IEEE80211_DS5, IF_Mbps(5) }, \
|
||||
+ { IFM_IEEE80211|IFM_IEEE80211_DS11, IF_Mbps(11) }, \
|
||||
+ { IFM_IEEE80211|IFM_IEEE80211_DS22, IF_Mbps(22) }, \
|
||||
+ { IFM_IEEE80211|IFM_IEEE80211_OFDM6, IF_Mbps(6) }, \
|
||||
+ { IFM_IEEE80211|IFM_IEEE80211_OFDM9, IF_Mbps(9) }, \
|
||||
+ { IFM_IEEE80211|IFM_IEEE80211_OFDM12, IF_Mbps(12) }, \
|
||||
+ { IFM_IEEE80211|IFM_IEEE80211_OFDM18, IF_Mbps(18) }, \
|
||||
+ { IFM_IEEE80211|IFM_IEEE80211_OFDM24, IF_Mbps(24) }, \
|
||||
+ { IFM_IEEE80211|IFM_IEEE80211_OFDM36, IF_Mbps(36) }, \
|
||||
+ { IFM_IEEE80211|IFM_IEEE80211_OFDM48, IF_Mbps(48) }, \
|
||||
+ { IFM_IEEE80211|IFM_IEEE80211_OFDM54, IF_Mbps(54) }, \
|
||||
+ { IFM_IEEE80211|IFM_IEEE80211_OFDM72, IF_Mbps(72) }, \
|
||||
+ \
|
||||
+ { IFM_TDM|IFM_TDM_T1, IF_Kbps(1536) }, \
|
||||
+ { IFM_TDM|IFM_TDM_T1_AMI, IF_Kbps(1536) }, \
|
||||
+ { IFM_TDM|IFM_TDM_E1, IF_Kbps(2048) }, \
|
||||
+ { IFM_TDM|IFM_TDM_E1_G704, IF_Kbps(2048) }, \
|
||||
+ { IFM_TDM|IFM_TDM_E1_AMI, IF_Kbps(2048) }, \
|
||||
+ { IFM_TDM|IFM_TDM_E1_AMI_G704, IF_Kbps(2048) }, \
|
||||
+ { IFM_TDM|IFM_TDM_T3, IF_Kbps(44736) }, \
|
||||
+ { IFM_TDM|IFM_TDM_T3_M13, IF_Kbps(44736) }, \
|
||||
+ { IFM_TDM|IFM_TDM_E3, IF_Kbps(34368) }, \
|
||||
+ { IFM_TDM|IFM_TDM_E3_G751, IF_Kbps(34368) }, \
|
||||
+ { IFM_TDM|IFM_TDM_E3_G832, IF_Kbps(34368) }, \
|
||||
+ \
|
||||
+ { 0, 0 }, \
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Status bit descriptions for the various media types.
|
||||
+ */
|
||||
+struct ifmedia_status_description {
|
||||
+ int ifms_type;
|
||||
+ int ifms_valid;
|
||||
+ int ifms_bit;
|
||||
+ const char *ifms_string[2];
|
||||
+};
|
||||
+
|
||||
+#define IFM_STATUS_DESC(ifms, bit) \
|
||||
+ (ifms)->ifms_string[((ifms)->ifms_bit & (bit)) ? 1 : 0]
|
||||
+
|
||||
+#define IFM_STATUS_DESCRIPTIONS { \
|
||||
+ { IFM_ETHER, IFM_AVALID, IFM_ACTIVE, \
|
||||
+ { "no carrier", "active" } }, \
|
||||
+ { IFM_FDDI, IFM_AVALID, IFM_ACTIVE, \
|
||||
+ { "no ring", "inserted" } }, \
|
||||
+ { IFM_TOKEN, IFM_AVALID, IFM_ACTIVE, \
|
||||
+ { "no ring", "inserted" } }, \
|
||||
+ { IFM_IEEE80211, IFM_AVALID, IFM_ACTIVE, \
|
||||
+ { "no network", "active" } }, \
|
||||
+ { IFM_TDM, IFM_AVALID, IFM_ACTIVE, \
|
||||
+ { "no carrier", "active" } }, \
|
||||
+ { IFM_CARP, IFM_AVALID, IFM_ACTIVE, \
|
||||
+ { "backup", "master" } }, \
|
||||
+ { 0, 0, 0, \
|
||||
+ { NULL, NULL } } \
|
||||
+}
|
||||
+#endif /* _NET_IF_MEDIA_H_ */
|
312
net/openbgpd/files/patch-openbsd-compat_imsg-buffer.c
Normal file
312
net/openbgpd/files/patch-openbsd-compat_imsg-buffer.c
Normal file
@ -0,0 +1,312 @@
|
||||
Index: openbsd-compat/imsg-buffer.c
|
||||
===================================================================
|
||||
RCS file: openbsd-compat/imsg-buffer.c
|
||||
diff -N openbsd-compat/imsg-buffer.c
|
||||
--- /dev/null 1 Jan 1970 00:00:00 -0000
|
||||
+++ openbsd-compat/imsg-buffer.c 8 Dec 2012 20:17:59 -0000 1.2
|
||||
@@ -0,0 +1,305 @@
|
||||
+/* $OpenBSD: imsg-buffer.c,v 1.1 2010/05/26 16:44:32 nicm Exp $ */
|
||||
+
|
||||
+/*
|
||||
+ * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
|
||||
+ *
|
||||
+ * Permission to use, copy, modify, and distribute this software for any
|
||||
+ * purpose with or without fee is hereby granted, provided that the above
|
||||
+ * copyright notice and this permission notice appear in all copies.
|
||||
+ *
|
||||
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
+ */
|
||||
+
|
||||
+#include <sys/param.h>
|
||||
+#include <sys/queue.h>
|
||||
+#include <sys/socket.h>
|
||||
+#include <sys/uio.h>
|
||||
+
|
||||
+#include <errno.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+#include <unistd.h>
|
||||
+
|
||||
+#include "imsg.h"
|
||||
+
|
||||
+int ibuf_realloc(struct ibuf *, size_t);
|
||||
+void ibuf_enqueue(struct msgbuf *, struct ibuf *);
|
||||
+void ibuf_dequeue(struct msgbuf *, struct ibuf *);
|
||||
+
|
||||
+struct ibuf *
|
||||
+ibuf_open(size_t len)
|
||||
+{
|
||||
+ struct ibuf *buf;
|
||||
+
|
||||
+ if ((buf = calloc(1, sizeof(struct ibuf))) == NULL)
|
||||
+ return (NULL);
|
||||
+ if ((buf->buf = malloc(len)) == NULL) {
|
||||
+ free(buf);
|
||||
+ return (NULL);
|
||||
+ }
|
||||
+ buf->size = buf->max = len;
|
||||
+ buf->fd = -1;
|
||||
+
|
||||
+ return (buf);
|
||||
+}
|
||||
+
|
||||
+struct ibuf *
|
||||
+ibuf_dynamic(size_t len, size_t max)
|
||||
+{
|
||||
+ struct ibuf *buf;
|
||||
+
|
||||
+ if (max < len)
|
||||
+ return (NULL);
|
||||
+
|
||||
+ if ((buf = ibuf_open(len)) == NULL)
|
||||
+ return (NULL);
|
||||
+
|
||||
+ if (max > 0)
|
||||
+ buf->max = max;
|
||||
+
|
||||
+ return (buf);
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+ibuf_realloc(struct ibuf *buf, size_t len)
|
||||
+{
|
||||
+ u_char *b;
|
||||
+
|
||||
+ /* on static buffers max is eq size and so the following fails */
|
||||
+ if (buf->wpos + len > buf->max) {
|
||||
+ errno = ENOMEM;
|
||||
+ return (-1);
|
||||
+ }
|
||||
+
|
||||
+ b = realloc(buf->buf, buf->wpos + len);
|
||||
+ if (b == NULL)
|
||||
+ return (-1);
|
||||
+ buf->buf = b;
|
||||
+ buf->size = buf->wpos + len;
|
||||
+
|
||||
+ return (0);
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+ibuf_add(struct ibuf *buf, const void *data, size_t len)
|
||||
+{
|
||||
+ if (buf->wpos + len > buf->size)
|
||||
+ if (ibuf_realloc(buf, len) == -1)
|
||||
+ return (-1);
|
||||
+
|
||||
+ memcpy(buf->buf + buf->wpos, data, len);
|
||||
+ buf->wpos += len;
|
||||
+ return (0);
|
||||
+}
|
||||
+
|
||||
+void *
|
||||
+ibuf_reserve(struct ibuf *buf, size_t len)
|
||||
+{
|
||||
+ void *b;
|
||||
+
|
||||
+ if (buf->wpos + len > buf->size)
|
||||
+ if (ibuf_realloc(buf, len) == -1)
|
||||
+ return (NULL);
|
||||
+
|
||||
+ b = buf->buf + buf->wpos;
|
||||
+ buf->wpos += len;
|
||||
+ return (b);
|
||||
+}
|
||||
+
|
||||
+void *
|
||||
+ibuf_seek(struct ibuf *buf, size_t pos, size_t len)
|
||||
+{
|
||||
+ /* only allowed to seek in already written parts */
|
||||
+ if (pos + len > buf->wpos)
|
||||
+ return (NULL);
|
||||
+
|
||||
+ return (buf->buf + pos);
|
||||
+}
|
||||
+
|
||||
+size_t
|
||||
+ibuf_size(struct ibuf *buf)
|
||||
+{
|
||||
+ return (buf->wpos);
|
||||
+}
|
||||
+
|
||||
+size_t
|
||||
+ibuf_left(struct ibuf *buf)
|
||||
+{
|
||||
+ return (buf->max - buf->wpos);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+ibuf_close(struct msgbuf *msgbuf, struct ibuf *buf)
|
||||
+{
|
||||
+ ibuf_enqueue(msgbuf, buf);
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+ibuf_write(struct msgbuf *msgbuf)
|
||||
+{
|
||||
+ struct iovec iov[IOV_MAX];
|
||||
+ struct ibuf *buf;
|
||||
+ unsigned int i = 0;
|
||||
+ ssize_t n;
|
||||
+
|
||||
+ bzero(&iov, sizeof(iov));
|
||||
+ TAILQ_FOREACH(buf, &msgbuf->bufs, entry) {
|
||||
+ if (i >= IOV_MAX)
|
||||
+ break;
|
||||
+ iov[i].iov_base = buf->buf + buf->rpos;
|
||||
+ iov[i].iov_len = buf->wpos - buf->rpos;
|
||||
+ i++;
|
||||
+ }
|
||||
+
|
||||
+again:
|
||||
+ if ((n = writev(msgbuf->fd, iov, i)) == -1) {
|
||||
+ if (errno == EAGAIN || errno == EINTR)
|
||||
+ goto again;
|
||||
+ if (errno == ENOBUFS)
|
||||
+ errno = EAGAIN;
|
||||
+ return (-1);
|
||||
+ }
|
||||
+
|
||||
+ if (n == 0) { /* connection closed */
|
||||
+ errno = 0;
|
||||
+ return (0);
|
||||
+ }
|
||||
+
|
||||
+ msgbuf_drain(msgbuf, n);
|
||||
+
|
||||
+ return (1);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+ibuf_free(struct ibuf *buf)
|
||||
+{
|
||||
+ free(buf->buf);
|
||||
+ free(buf);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+msgbuf_init(struct msgbuf *msgbuf)
|
||||
+{
|
||||
+ msgbuf->queued = 0;
|
||||
+ msgbuf->fd = -1;
|
||||
+ TAILQ_INIT(&msgbuf->bufs);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+msgbuf_drain(struct msgbuf *msgbuf, size_t n)
|
||||
+{
|
||||
+ struct ibuf *buf, *next;
|
||||
+
|
||||
+ for (buf = TAILQ_FIRST(&msgbuf->bufs); buf != NULL && n > 0;
|
||||
+ buf = next) {
|
||||
+ next = TAILQ_NEXT(buf, entry);
|
||||
+ if (buf->rpos + n >= buf->wpos) {
|
||||
+ n -= buf->wpos - buf->rpos;
|
||||
+ ibuf_dequeue(msgbuf, buf);
|
||||
+ } else {
|
||||
+ buf->rpos += n;
|
||||
+ n = 0;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+msgbuf_clear(struct msgbuf *msgbuf)
|
||||
+{
|
||||
+ struct ibuf *buf;
|
||||
+
|
||||
+ while ((buf = TAILQ_FIRST(&msgbuf->bufs)) != NULL)
|
||||
+ ibuf_dequeue(msgbuf, buf);
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+msgbuf_write(struct msgbuf *msgbuf)
|
||||
+{
|
||||
+ struct iovec iov[IOV_MAX];
|
||||
+ struct ibuf *buf;
|
||||
+ unsigned int i = 0;
|
||||
+ ssize_t n;
|
||||
+ struct msghdr msg;
|
||||
+ struct cmsghdr *cmsg;
|
||||
+ union {
|
||||
+ struct cmsghdr hdr;
|
||||
+ char buf[CMSG_SPACE(sizeof(int))];
|
||||
+ } cmsgbuf;
|
||||
+
|
||||
+ bzero(&iov, sizeof(iov));
|
||||
+ bzero(&msg, sizeof(msg));
|
||||
+ TAILQ_FOREACH(buf, &msgbuf->bufs, entry) {
|
||||
+ if (i >= IOV_MAX)
|
||||
+ break;
|
||||
+ iov[i].iov_base = buf->buf + buf->rpos;
|
||||
+ iov[i].iov_len = buf->wpos - buf->rpos;
|
||||
+ i++;
|
||||
+ if (buf->fd != -1)
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ msg.msg_iov = iov;
|
||||
+ msg.msg_iovlen = i;
|
||||
+
|
||||
+ if (buf != NULL && buf->fd != -1) {
|
||||
+ msg.msg_control = (caddr_t)&cmsgbuf.buf;
|
||||
+ msg.msg_controllen = sizeof(cmsgbuf.buf);
|
||||
+ cmsg = CMSG_FIRSTHDR(&msg);
|
||||
+ cmsg->cmsg_len = CMSG_LEN(sizeof(int));
|
||||
+ cmsg->cmsg_level = SOL_SOCKET;
|
||||
+ cmsg->cmsg_type = SCM_RIGHTS;
|
||||
+ *(int *)CMSG_DATA(cmsg) = buf->fd;
|
||||
+ }
|
||||
+
|
||||
+again:
|
||||
+ if ((n = sendmsg(msgbuf->fd, &msg, 0)) == -1) {
|
||||
+ if (errno == EAGAIN || errno == EINTR)
|
||||
+ goto again;
|
||||
+ if (errno == ENOBUFS)
|
||||
+ errno = EAGAIN;
|
||||
+ return (-1);
|
||||
+ }
|
||||
+
|
||||
+ if (n == 0) { /* connection closed */
|
||||
+ errno = 0;
|
||||
+ return (0);
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * assumption: fd got sent if sendmsg sent anything
|
||||
+ * this works because fds are passed one at a time
|
||||
+ */
|
||||
+ if (buf != NULL && buf->fd != -1) {
|
||||
+ close(buf->fd);
|
||||
+ buf->fd = -1;
|
||||
+ }
|
||||
+
|
||||
+ msgbuf_drain(msgbuf, n);
|
||||
+
|
||||
+ return (1);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+ibuf_enqueue(struct msgbuf *msgbuf, struct ibuf *buf)
|
||||
+{
|
||||
+ TAILQ_INSERT_TAIL(&msgbuf->bufs, buf, entry);
|
||||
+ msgbuf->queued++;
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+ibuf_dequeue(struct msgbuf *msgbuf, struct ibuf *buf)
|
||||
+{
|
||||
+ TAILQ_REMOVE(&msgbuf->bufs, buf, entry);
|
||||
+
|
||||
+ if (buf->fd != -1)
|
||||
+ close(buf->fd);
|
||||
+
|
||||
+ msgbuf->queued--;
|
||||
+ ibuf_free(buf);
|
||||
+}
|
312
net/openbgpd/files/patch-openbsd-compat_imsg.c
Normal file
312
net/openbgpd/files/patch-openbsd-compat_imsg.c
Normal file
@ -0,0 +1,312 @@
|
||||
Index: openbsd-compat/imsg.c
|
||||
===================================================================
|
||||
RCS file: openbsd-compat/imsg.c
|
||||
diff -N openbsd-compat/imsg.c
|
||||
--- /dev/null 1 Jan 1970 00:00:00 -0000
|
||||
+++ openbsd-compat/imsg.c 8 Dec 2012 20:17:59 -0000 1.2
|
||||
@@ -0,0 +1,305 @@
|
||||
+/* $OpenBSD: imsg.c,v 1.1 2010/05/26 16:44:32 nicm Exp $ */
|
||||
+
|
||||
+/*
|
||||
+ * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
|
||||
+ *
|
||||
+ * Permission to use, copy, modify, and distribute this software for any
|
||||
+ * purpose with or without fee is hereby granted, provided that the above
|
||||
+ * copyright notice and this permission notice appear in all copies.
|
||||
+ *
|
||||
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
+ */
|
||||
+
|
||||
+#include <sys/param.h>
|
||||
+#include <sys/queue.h>
|
||||
+#include <sys/socket.h>
|
||||
+#include <sys/uio.h>
|
||||
+
|
||||
+#include <errno.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+#include <unistd.h>
|
||||
+
|
||||
+#include "imsg.h"
|
||||
+
|
||||
+int imsg_fd_overhead = 0;
|
||||
+
|
||||
+int imsg_get_fd(struct imsgbuf *);
|
||||
+
|
||||
+void
|
||||
+imsg_init(struct imsgbuf *ibuf, int fd)
|
||||
+{
|
||||
+ msgbuf_init(&ibuf->w);
|
||||
+ bzero(&ibuf->r, sizeof(ibuf->r));
|
||||
+ ibuf->fd = fd;
|
||||
+ ibuf->w.fd = fd;
|
||||
+ ibuf->pid = getpid();
|
||||
+ TAILQ_INIT(&ibuf->fds);
|
||||
+}
|
||||
+
|
||||
+ssize_t
|
||||
+imsg_read(struct imsgbuf *ibuf)
|
||||
+{
|
||||
+ struct msghdr msg;
|
||||
+ struct cmsghdr *cmsg;
|
||||
+ union {
|
||||
+ struct cmsghdr hdr;
|
||||
+ char buf[CMSG_SPACE(sizeof(int) * 1)];
|
||||
+ } cmsgbuf;
|
||||
+ struct iovec iov;
|
||||
+ ssize_t n = -1;
|
||||
+ int fd;
|
||||
+ struct imsg_fd *ifd;
|
||||
+
|
||||
+ bzero(&msg, sizeof(msg));
|
||||
+
|
||||
+ iov.iov_base = ibuf->r.buf + ibuf->r.wpos;
|
||||
+ iov.iov_len = sizeof(ibuf->r.buf) - ibuf->r.wpos;
|
||||
+ msg.msg_iov = &iov;
|
||||
+ msg.msg_iovlen = 1;
|
||||
+ msg.msg_control = &cmsgbuf.buf;
|
||||
+ msg.msg_controllen = sizeof(cmsgbuf.buf);
|
||||
+
|
||||
+ if ((ifd = calloc(1, sizeof(struct imsg_fd))) == NULL)
|
||||
+ return (-1);
|
||||
+
|
||||
+again:
|
||||
+#if defined(__FreeBSD__)
|
||||
+ if (imsg_fd_overhead +
|
||||
+#else
|
||||
+ if (getdtablecount() + imsg_fd_overhead +
|
||||
+#endif
|
||||
+ (CMSG_SPACE(sizeof(int))-CMSG_SPACE(0))/sizeof(int)
|
||||
+ >= getdtablesize()) {
|
||||
+ errno = EAGAIN;
|
||||
+ return (-1);
|
||||
+ }
|
||||
+
|
||||
+ if ((n = recvmsg(ibuf->fd, &msg, 0)) == -1) {
|
||||
+ if (errno == EMSGSIZE)
|
||||
+ goto fail;
|
||||
+ if (errno != EINTR && errno != EAGAIN)
|
||||
+ goto fail;
|
||||
+ goto again;
|
||||
+ }
|
||||
+
|
||||
+ ibuf->r.wpos += n;
|
||||
+
|
||||
+ for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
|
||||
+ cmsg = CMSG_NXTHDR(&msg, cmsg)) {
|
||||
+ if (cmsg->cmsg_level == SOL_SOCKET &&
|
||||
+ cmsg->cmsg_type == SCM_RIGHTS) {
|
||||
+ int i;
|
||||
+ int j;
|
||||
+
|
||||
+ /*
|
||||
+ * We only accept one file descriptor. Due to C
|
||||
+ * padding rules, our control buffer might contain
|
||||
+ * more than one fd, and we must close them.
|
||||
+ */
|
||||
+ j = ((char *)cmsg + cmsg->cmsg_len -
|
||||
+ (char *)CMSG_DATA(cmsg)) / sizeof(int);
|
||||
+ for (i = 0; i < j; i++) {
|
||||
+ fd = ((int *)CMSG_DATA(cmsg))[i];
|
||||
+ if (i == 0) {
|
||||
+ ifd->fd = fd;
|
||||
+ TAILQ_INSERT_TAIL(&ibuf->fds, ifd,
|
||||
+ entry);
|
||||
+ ifd = NULL;
|
||||
+ } else
|
||||
+ close(fd);
|
||||
+ }
|
||||
+ }
|
||||
+ /* we do not handle other ctl data level */
|
||||
+ }
|
||||
+
|
||||
+fail:
|
||||
+ if (ifd)
|
||||
+ free(ifd);
|
||||
+ return (n);
|
||||
+}
|
||||
+
|
||||
+ssize_t
|
||||
+imsg_get(struct imsgbuf *ibuf, struct imsg *imsg)
|
||||
+{
|
||||
+ size_t av, left, datalen;
|
||||
+
|
||||
+ av = ibuf->r.wpos;
|
||||
+
|
||||
+ if (IMSG_HEADER_SIZE > av)
|
||||
+ return (0);
|
||||
+
|
||||
+ memcpy(&imsg->hdr, ibuf->r.buf, sizeof(imsg->hdr));
|
||||
+ if (imsg->hdr.len < IMSG_HEADER_SIZE ||
|
||||
+ imsg->hdr.len > MAX_IMSGSIZE) {
|
||||
+ errno = ERANGE;
|
||||
+ return (-1);
|
||||
+ }
|
||||
+ if (imsg->hdr.len > av)
|
||||
+ return (0);
|
||||
+ datalen = imsg->hdr.len - IMSG_HEADER_SIZE;
|
||||
+ ibuf->r.rptr = ibuf->r.buf + IMSG_HEADER_SIZE;
|
||||
+ if ((imsg->data = malloc(datalen)) == NULL)
|
||||
+ return (-1);
|
||||
+
|
||||
+ if (imsg->hdr.flags & IMSGF_HASFD)
|
||||
+ imsg->fd = imsg_get_fd(ibuf);
|
||||
+ else
|
||||
+ imsg->fd = -1;
|
||||
+
|
||||
+ memcpy(imsg->data, ibuf->r.rptr, datalen);
|
||||
+
|
||||
+ if (imsg->hdr.len < av) {
|
||||
+ left = av - imsg->hdr.len;
|
||||
+ memmove(&ibuf->r.buf, ibuf->r.buf + imsg->hdr.len, left);
|
||||
+ ibuf->r.wpos = left;
|
||||
+ } else
|
||||
+ ibuf->r.wpos = 0;
|
||||
+
|
||||
+ return (datalen + IMSG_HEADER_SIZE);
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+imsg_compose(struct imsgbuf *ibuf, u_int32_t type, u_int32_t peerid,
|
||||
+ pid_t pid, int fd, void *data, u_int16_t datalen)
|
||||
+{
|
||||
+ struct ibuf *wbuf;
|
||||
+
|
||||
+ if ((wbuf = imsg_create(ibuf, type, peerid, pid, datalen)) == NULL)
|
||||
+ return (-1);
|
||||
+
|
||||
+ if (imsg_add(wbuf, data, datalen) == -1)
|
||||
+ return (-1);
|
||||
+
|
||||
+ wbuf->fd = fd;
|
||||
+
|
||||
+ imsg_close(ibuf, wbuf);
|
||||
+
|
||||
+ return (1);
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+imsg_composev(struct imsgbuf *ibuf, u_int32_t type, u_int32_t peerid,
|
||||
+ pid_t pid, int fd, const struct iovec *iov, int iovcnt)
|
||||
+{
|
||||
+ struct ibuf *wbuf;
|
||||
+ int i, datalen = 0;
|
||||
+
|
||||
+ for (i = 0; i < iovcnt; i++)
|
||||
+ datalen += iov[i].iov_len;
|
||||
+
|
||||
+ if ((wbuf = imsg_create(ibuf, type, peerid, pid, datalen)) == NULL)
|
||||
+ return (-1);
|
||||
+
|
||||
+ for (i = 0; i < iovcnt; i++)
|
||||
+ if (imsg_add(wbuf, iov[i].iov_base, iov[i].iov_len) == -1)
|
||||
+ return (-1);
|
||||
+
|
||||
+ wbuf->fd = fd;
|
||||
+
|
||||
+ imsg_close(ibuf, wbuf);
|
||||
+
|
||||
+ return (1);
|
||||
+}
|
||||
+
|
||||
+/* ARGSUSED */
|
||||
+struct ibuf *
|
||||
+imsg_create(struct imsgbuf *ibuf, u_int32_t type, u_int32_t peerid,
|
||||
+ pid_t pid, u_int16_t datalen)
|
||||
+{
|
||||
+ struct ibuf *wbuf;
|
||||
+ struct imsg_hdr hdr;
|
||||
+
|
||||
+ datalen += IMSG_HEADER_SIZE;
|
||||
+ if (datalen > MAX_IMSGSIZE) {
|
||||
+ errno = ERANGE;
|
||||
+ return (NULL);
|
||||
+ }
|
||||
+
|
||||
+ hdr.type = type;
|
||||
+ hdr.flags = 0;
|
||||
+ hdr.peerid = peerid;
|
||||
+ if ((hdr.pid = pid) == 0)
|
||||
+ hdr.pid = ibuf->pid;
|
||||
+ if ((wbuf = ibuf_dynamic(datalen, MAX_IMSGSIZE)) == NULL) {
|
||||
+ return (NULL);
|
||||
+ }
|
||||
+ if (imsg_add(wbuf, &hdr, sizeof(hdr)) == -1)
|
||||
+ return (NULL);
|
||||
+
|
||||
+ return (wbuf);
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+imsg_add(struct ibuf *msg, void *data, u_int16_t datalen)
|
||||
+{
|
||||
+ if (datalen)
|
||||
+ if (ibuf_add(msg, data, datalen) == -1) {
|
||||
+ ibuf_free(msg);
|
||||
+ return (-1);
|
||||
+ }
|
||||
+ return (datalen);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+imsg_close(struct imsgbuf *ibuf, struct ibuf *msg)
|
||||
+{
|
||||
+ struct imsg_hdr *hdr;
|
||||
+
|
||||
+ hdr = (struct imsg_hdr *)msg->buf;
|
||||
+
|
||||
+ hdr->flags &= ~IMSGF_HASFD;
|
||||
+ if (msg->fd != -1)
|
||||
+ hdr->flags |= IMSGF_HASFD;
|
||||
+
|
||||
+ hdr->len = (u_int16_t)msg->wpos;
|
||||
+
|
||||
+ ibuf_close(&ibuf->w, msg);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+imsg_free(struct imsg *imsg)
|
||||
+{
|
||||
+ free(imsg->data);
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+imsg_get_fd(struct imsgbuf *ibuf)
|
||||
+{
|
||||
+ int fd;
|
||||
+ struct imsg_fd *ifd;
|
||||
+
|
||||
+ if ((ifd = TAILQ_FIRST(&ibuf->fds)) == NULL)
|
||||
+ return (-1);
|
||||
+
|
||||
+ fd = ifd->fd;
|
||||
+ TAILQ_REMOVE(&ibuf->fds, ifd, entry);
|
||||
+ free(ifd);
|
||||
+
|
||||
+ return (fd);
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+imsg_flush(struct imsgbuf *ibuf)
|
||||
+{
|
||||
+ while (ibuf->w.queued)
|
||||
+ if (msgbuf_write(&ibuf->w) < 0)
|
||||
+ return (-1);
|
||||
+ return (0);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+imsg_clear(struct imsgbuf *ibuf)
|
||||
+{
|
||||
+ int fd;
|
||||
+
|
||||
+ msgbuf_clear(&ibuf->w);
|
||||
+ while ((fd = imsg_get_fd(ibuf)) != -1)
|
||||
+ close(fd);
|
||||
+}
|
119
net/openbgpd/files/patch-openbsd-compat_imsg.h
Normal file
119
net/openbgpd/files/patch-openbsd-compat_imsg.h
Normal file
@ -0,0 +1,119 @@
|
||||
Index: openbsd-compat/imsg.h
|
||||
===================================================================
|
||||
RCS file: openbsd-compat/imsg.h
|
||||
diff -N openbsd-compat/imsg.h
|
||||
--- /dev/null 1 Jan 1970 00:00:00 -0000
|
||||
+++ openbsd-compat/imsg.h 8 Dec 2012 20:17:59 -0000 1.2
|
||||
@@ -0,0 +1,112 @@
|
||||
+/* $OpenBSD: imsg.h,v 1.1 2010/05/26 16:44:32 nicm Exp $ */
|
||||
+
|
||||
+/*
|
||||
+ * Copyright (c) 2006, 2007 Pierre-Yves Ritschard <pyr@openbsd.org>
|
||||
+ * Copyright (c) 2006, 2007, 2008 Reyk Floeter <reyk@openbsd.org>
|
||||
+ * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
|
||||
+ *
|
||||
+ * Permission to use, copy, modify, and distribute this software for any
|
||||
+ * purpose with or without fee is hereby granted, provided that the above
|
||||
+ * copyright notice and this permission notice appear in all copies.
|
||||
+ *
|
||||
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
+ */
|
||||
+
|
||||
+#ifndef _IMSG_H_
|
||||
+#define _IMSG_H_
|
||||
+
|
||||
+#define IBUF_READ_SIZE 65535
|
||||
+#define IMSG_HEADER_SIZE sizeof(struct imsg_hdr)
|
||||
+#define MAX_IMSGSIZE 16384
|
||||
+
|
||||
+struct ibuf {
|
||||
+ TAILQ_ENTRY(ibuf) entry;
|
||||
+ u_char *buf;
|
||||
+ size_t size;
|
||||
+ size_t max;
|
||||
+ size_t wpos;
|
||||
+ size_t rpos;
|
||||
+ int fd;
|
||||
+};
|
||||
+
|
||||
+struct msgbuf {
|
||||
+ TAILQ_HEAD(, ibuf) bufs;
|
||||
+ u_int32_t queued;
|
||||
+ int fd;
|
||||
+};
|
||||
+
|
||||
+struct ibuf_read {
|
||||
+ u_char buf[IBUF_READ_SIZE];
|
||||
+ u_char *rptr;
|
||||
+ size_t wpos;
|
||||
+};
|
||||
+
|
||||
+struct imsg_fd {
|
||||
+ TAILQ_ENTRY(imsg_fd) entry;
|
||||
+ int fd;
|
||||
+};
|
||||
+
|
||||
+struct imsgbuf {
|
||||
+ TAILQ_HEAD(, imsg_fd) fds;
|
||||
+ struct ibuf_read r;
|
||||
+ struct msgbuf w;
|
||||
+ int fd;
|
||||
+ pid_t pid;
|
||||
+};
|
||||
+
|
||||
+#define IMSGF_HASFD 1
|
||||
+
|
||||
+struct imsg_hdr {
|
||||
+ u_int32_t type;
|
||||
+ u_int16_t len;
|
||||
+ u_int16_t flags;
|
||||
+ u_int32_t peerid;
|
||||
+ u_int32_t pid;
|
||||
+};
|
||||
+
|
||||
+struct imsg {
|
||||
+ struct imsg_hdr hdr;
|
||||
+ int fd;
|
||||
+ void *data;
|
||||
+};
|
||||
+
|
||||
+
|
||||
+/* buffer.c */
|
||||
+struct ibuf *ibuf_open(size_t);
|
||||
+struct ibuf *ibuf_dynamic(size_t, size_t);
|
||||
+int ibuf_add(struct ibuf *, const void *, size_t);
|
||||
+void *ibuf_reserve(struct ibuf *, size_t);
|
||||
+void *ibuf_seek(struct ibuf *, size_t, size_t);
|
||||
+size_t ibuf_size(struct ibuf *);
|
||||
+size_t ibuf_left(struct ibuf *);
|
||||
+void ibuf_close(struct msgbuf *, struct ibuf *);
|
||||
+int ibuf_write(struct msgbuf *);
|
||||
+void ibuf_free(struct ibuf *);
|
||||
+void msgbuf_init(struct msgbuf *);
|
||||
+void msgbuf_clear(struct msgbuf *);
|
||||
+int msgbuf_write(struct msgbuf *);
|
||||
+void msgbuf_drain(struct msgbuf *, size_t);
|
||||
+
|
||||
+/* imsg.c */
|
||||
+void imsg_init(struct imsgbuf *, int);
|
||||
+ssize_t imsg_read(struct imsgbuf *);
|
||||
+ssize_t imsg_get(struct imsgbuf *, struct imsg *);
|
||||
+int imsg_compose(struct imsgbuf *, u_int32_t, u_int32_t, pid_t,
|
||||
+ int, void *, u_int16_t);
|
||||
+int imsg_composev(struct imsgbuf *, u_int32_t, u_int32_t, pid_t,
|
||||
+ int, const struct iovec *, int);
|
||||
+struct ibuf *imsg_create(struct imsgbuf *, u_int32_t, u_int32_t, pid_t,
|
||||
+ u_int16_t);
|
||||
+int imsg_add(struct ibuf *, void *, u_int16_t);
|
||||
+void imsg_close(struct imsgbuf *, struct ibuf *);
|
||||
+void imsg_free(struct imsg *);
|
||||
+int imsg_flush(struct imsgbuf *);
|
||||
+void imsg_clear(struct imsgbuf *);
|
||||
+
|
||||
+#endif
|
98
net/openbgpd/files/patch-openbsd-compat_openbsd-compat.h
Normal file
98
net/openbgpd/files/patch-openbsd-compat_openbsd-compat.h
Normal file
@ -0,0 +1,98 @@
|
||||
Index: openbsd-compat/openbsd-compat.h
|
||||
===================================================================
|
||||
RCS file: openbsd-compat/openbsd-compat.h
|
||||
diff -N openbsd-compat/openbsd-compat.h
|
||||
--- /dev/null 1 Jan 1970 00:00:00 -0000
|
||||
+++ openbsd-compat/openbsd-compat.h 13 Oct 2012 18:50:10 -0000 1.8
|
||||
@@ -0,0 +1,91 @@
|
||||
+/*
|
||||
+ * $hrs: openbgpd/openbsd-compat/openbsd-compat.h,v 1.8 2012/10/13 18:50:10 hrs Exp $
|
||||
+ */
|
||||
+
|
||||
+#ifndef _OPENBSD_COMPAT_H
|
||||
+#define _OPENBSD_COMPAT_H
|
||||
+
|
||||
+#define __dead
|
||||
+
|
||||
+/* bgpctl/bgpctl.c */
|
||||
+#include <sys/endian.h>
|
||||
+#include <inttypes.h>
|
||||
+#define betoh64(x) (be64toh(x))
|
||||
+#ifndef IFT_CARP
|
||||
+#define IFT_CARP 0xf8
|
||||
+#endif
|
||||
+
|
||||
+/* bgpd/irrfilter.c */
|
||||
+typedef unsigned long ulong;
|
||||
+
|
||||
+/* bgpd/bgpd.c */
|
||||
+#ifndef RTLABEL_LEN /* defined in net/pfvar.h */
|
||||
+#define RTLABEL_LEN 32
|
||||
+#endif
|
||||
+#define RTA_LABEL 0
|
||||
+
|
||||
+#define SIMPLEQ_FOREACH STAILQ_FOREACH
|
||||
+#define SIMPLEQ_FIRST STAILQ_FIRST
|
||||
+#define SIMPLEQ_REMOVE_HEAD STAILQ_REMOVE_HEAD
|
||||
+#define SIMPLEQ_INSERT_TAIL STAILQ_INSERT_TAIL
|
||||
+#define SIMPLEQ_ENTRY STAILQ_ENTRY
|
||||
+#define SIMPLEQ_HEAD STAILQ_HEAD
|
||||
+#define SIMPLEQ_INIT STAILQ_INIT
|
||||
+#define SIMPLEQ_HEAD_INITIALIZER STAILQ_HEAD_INITIALIZER
|
||||
+
|
||||
+/* Routing priorities used by the different routing protocols */
|
||||
+#define RTP_NONE 0 /* unset priority use sane default */
|
||||
+#define RTP_CONNECTED 4 /* directly connected routes */
|
||||
+#define RTP_STATIC 8 /* static routes base priority */
|
||||
+#define RTP_OSPF 32 /* OSPF routes */
|
||||
+#define RTP_ISIS 36 /* IS-IS routes */
|
||||
+#define RTP_RIP 40 /* RIP routes */
|
||||
+#define RTP_BGP 48 /* BGP routes */
|
||||
+#define RTP_DEFAULT 56 /* routes that have nothing set */
|
||||
+#define RTP_MAX 63 /* maximum priority */
|
||||
+#define RTP_ANY 64 /* any of the above */
|
||||
+#define RTP_MASK 0x7f
|
||||
+#define RTP_DOWN 0x80 /* route/link is down */
|
||||
+
|
||||
+/* missing LINK_STATE_* macros in net/if.h */
|
||||
+#define LINK_STATE_INVALID LINK_STATE_UNKNOWN /* link invalid */
|
||||
+#define LINK_STATE_KALIVE_DOWN 7 /* keepalive reports down */
|
||||
+#define LINK_STATE_HALF_DUPLEX 5 /* link is up and half duplex */
|
||||
+#define LINK_STATE_FULL_DUPLEX 6 /* link is up and full duplex */
|
||||
+
|
||||
+/*
|
||||
+ * Status bit descriptions for the various interface types.
|
||||
+ */
|
||||
+struct if_status_description {
|
||||
+ unsigned char ifs_type;
|
||||
+ unsigned char ifs_state;
|
||||
+ const char *ifs_string;
|
||||
+};
|
||||
+
|
||||
+#define LINK_STATE_DESC_MATCH(_ifs, _t, _s) \
|
||||
+ (((_ifs)->ifs_type == (_t) || (_ifs)->ifs_type == 0) && \
|
||||
+ (_ifs)->ifs_state == (_s))
|
||||
+
|
||||
+#define LINK_STATE_DESCRIPTIONS { \
|
||||
+ { IFT_ETHER, LINK_STATE_DOWN, "no carrier" }, \
|
||||
+ \
|
||||
+ { IFT_IEEE80211, LINK_STATE_DOWN, "no network" }, \
|
||||
+ \
|
||||
+ { IFT_PPP, LINK_STATE_DOWN, "no carrier" }, \
|
||||
+ \
|
||||
+ { IFT_CARP, LINK_STATE_DOWN, "backup" }, \
|
||||
+ { IFT_CARP, LINK_STATE_UP, "master" }, \
|
||||
+ { IFT_CARP, LINK_STATE_HALF_DUPLEX, "master" }, \
|
||||
+ { IFT_CARP, LINK_STATE_FULL_DUPLEX, "master" }, \
|
||||
+ \
|
||||
+ { 0, LINK_STATE_UP, "active" }, \
|
||||
+ { 0, LINK_STATE_HALF_DUPLEX, "active" }, \
|
||||
+ { 0, LINK_STATE_FULL_DUPLEX, "active" }, \
|
||||
+ \
|
||||
+/* { 0, LINK_STATE_UNKNOWN, "unknown" }, */ \
|
||||
+ { 0, LINK_STATE_INVALID, "invalid" }, \
|
||||
+ { 0, LINK_STATE_DOWN, "down" }, \
|
||||
+ { 0, LINK_STATE_KALIVE_DOWN, "keepalive down" }, \
|
||||
+ { 0, 0, NULL } \
|
||||
+}
|
||||
+#endif /* _OPENBSD_COMPAT_H */
|
126
net/openbgpd/files/patch-openbsd-compat_util.h
Normal file
126
net/openbgpd/files/patch-openbsd-compat_util.h
Normal file
@ -0,0 +1,126 @@
|
||||
Index: openbsd-compat/util.h
|
||||
===================================================================
|
||||
RCS file: openbsd-compat/util.h
|
||||
diff -N openbsd-compat/util.h
|
||||
--- /dev/null 1 Jan 1970 00:00:00 -0000
|
||||
+++ openbsd-compat/util.h 30 Jun 2009 06:40:07 -0000 1.1
|
||||
@@ -0,0 +1,119 @@
|
||||
+/* $OpenBSD: util.h,v 1.27 2006/06/14 02:14:25 krw Exp $ */
|
||||
+/* $NetBSD: util.h,v 1.2 1996/05/16 07:00:22 thorpej Exp $ */
|
||||
+
|
||||
+/*-
|
||||
+ * Copyright (c) 1995
|
||||
+ * The Regents of the University of California. All rights reserved.
|
||||
+ * Portions Copyright (c) 1996, Jason Downs. 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.
|
||||
+ * 3. Neither the name of the University nor the names of its contributors
|
||||
+ * may be used to endorse or promote products derived from this software
|
||||
+ * without specific prior written permission.
|
||||
+ *
|
||||
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
|
||||
+ */
|
||||
+
|
||||
+#ifndef _UTIL_H_
|
||||
+#define _UTIL_H_
|
||||
+
|
||||
+#include <sys/cdefs.h>
|
||||
+#include <sys/types.h>
|
||||
+
|
||||
+/*
|
||||
+ * fparseln() specific operation flags.
|
||||
+ */
|
||||
+#define FPARSELN_UNESCESC 0x01
|
||||
+#define FPARSELN_UNESCCONT 0x02
|
||||
+#define FPARSELN_UNESCCOMM 0x04
|
||||
+#define FPARSELN_UNESCREST 0x08
|
||||
+#define FPARSELN_UNESCALL 0x0f
|
||||
+
|
||||
+/*
|
||||
+ * opendev() specific operation flags.
|
||||
+ */
|
||||
+#define OPENDEV_PART 0x01 /* Try to open the raw partition. */
|
||||
+#define OPENDEV_BLCK 0x04 /* Open block, not character device. */
|
||||
+
|
||||
+/*
|
||||
+ * uucplock(3) specific flags.
|
||||
+ */
|
||||
+#define UU_LOCK_INUSE (1)
|
||||
+#define UU_LOCK_OK (0)
|
||||
+#define UU_LOCK_OPEN_ERR (-1)
|
||||
+#define UU_LOCK_READ_ERR (-2)
|
||||
+#define UU_LOCK_CREAT_ERR (-3)
|
||||
+#define UU_LOCK_WRITE_ERR (-4)
|
||||
+#define UU_LOCK_LINK_ERR (-5)
|
||||
+#define UU_LOCK_TRY_ERR (-6)
|
||||
+#define UU_LOCK_OWNER_ERR (-7)
|
||||
+
|
||||
+/*
|
||||
+ * fmt_scaled(3) specific flags.
|
||||
+ */
|
||||
+#define FMT_SCALED_STRSIZE 7 /* minus sign, 4 digits, suffix, null byte */
|
||||
+
|
||||
+/*
|
||||
+ * stub struct definitions.
|
||||
+ */
|
||||
+struct __sFILE;
|
||||
+struct login_cap;
|
||||
+struct passwd;
|
||||
+struct termios;
|
||||
+struct utmp;
|
||||
+struct winsize;
|
||||
+
|
||||
+__BEGIN_DECLS
|
||||
+char *fparseln(struct __sFILE *, size_t *, size_t *, const char[3], int);
|
||||
+void login(struct utmp *);
|
||||
+int login_tty(int);
|
||||
+int logout(const char *);
|
||||
+void logwtmp(const char *, const char *, const char *);
|
||||
+int opendev(char *, int, int, char **);
|
||||
+int pidfile(const char *);
|
||||
+void pw_setdir(const char *);
|
||||
+char *pw_file(const char *);
|
||||
+int pw_lock(int retries);
|
||||
+int pw_mkdb(char *, int);
|
||||
+int pw_abort(void);
|
||||
+void pw_init(void);
|
||||
+void pw_edit(int, const char *);
|
||||
+void pw_prompt(void);
|
||||
+void pw_copy(int, int, const struct passwd *, const struct passwd *);
|
||||
+int pw_scan(char *, struct passwd *, int *);
|
||||
+void pw_error(const char *, int, int);
|
||||
+int openpty(int *, int *, char *, struct termios *, struct winsize *);
|
||||
+int opendisk(const char *path, int flags, char *buf, size_t buflen,
|
||||
+ int iscooked);
|
||||
+pid_t forkpty(int *, char *, struct termios *, struct winsize *);
|
||||
+int getmaxpartitions(void);
|
||||
+int getrawpartition(void);
|
||||
+void login_fbtab(const char *, uid_t, gid_t);
|
||||
+int login_check_expire(struct __sFILE *, struct passwd *, char *, int);
|
||||
+char *readlabelfs(char *, int);
|
||||
+const char *uu_lockerr(int _uu_lockresult);
|
||||
+int uu_lock(const char *_ttyname);
|
||||
+int uu_lock_txfr(const char *_ttyname, pid_t _pid);
|
||||
+int uu_unlock(const char *_ttyname);
|
||||
+int fmt_scaled(long long number, char *result);
|
||||
+int scan_scaled(char *scaled, long long *result);
|
||||
+__END_DECLS
|
||||
+
|
||||
+#endif /* !_UTIL_H_ */
|
@ -1,6 +0,0 @@
|
||||
sbin/bgpctl
|
||||
sbin/bgpd
|
||||
man/man5/bgpd.conf.5.gz
|
||||
man/man8/bgpctl.8.gz
|
||||
man/man8/bgpd.8.gz
|
||||
@sample etc/bgpd.conf.sample
|
Loading…
Reference in New Issue
Block a user