summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/bgpd/bgpd.c5
-rw-r--r--usr.sbin/bgpd/bgpd.conf.510
-rw-r--r--usr.sbin/bgpd/bgpd.h5
-rw-r--r--usr.sbin/bgpd/kroute.c55
-rw-r--r--usr.sbin/bgpd/parse.y12
-rw-r--r--usr.sbin/bgpd/printconf.c4
6 files changed, 67 insertions, 24 deletions
diff --git a/usr.sbin/bgpd/bgpd.c b/usr.sbin/bgpd/bgpd.c
index 65fa69dfa29..af2d9f1c813 100644
--- a/usr.sbin/bgpd/bgpd.c
+++ b/usr.sbin/bgpd/bgpd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bgpd.c,v 1.139 2006/06/19 20:48:36 jmc Exp $ */
+/* $OpenBSD: bgpd.c,v 1.140 2006/11/28 16:39:34 henning Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -240,7 +240,8 @@ 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))) == -1)
+ if ((rfd = kr_init(!(conf.flags & BGPD_FLAG_NO_FIB_UPDATE),
+ conf.rtableid)) == -1)
quit = 1;
if (pftable_clear_all() != 0)
quit = 1;
diff --git a/usr.sbin/bgpd/bgpd.conf.5 b/usr.sbin/bgpd/bgpd.conf.5
index b07f74eb980..b0bc750ca62 100644
--- a/usr.sbin/bgpd/bgpd.conf.5
+++ b/usr.sbin/bgpd/bgpd.conf.5
@@ -1,4 +1,4 @@
-.\" $OpenBSD: bgpd.conf.5,v 1.76 2006/09/12 13:39:37 jmc Exp $
+.\" $OpenBSD: bgpd.conf.5,v 1.77 2006/11/28 16:39:34 henning Exp $
.\"
.\" Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
.\" Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -304,6 +304,14 @@ router-id 10.0.0.1
If not given, the BGP ID is determined as the biggest IP address assigned
to the local machine.
.Pp
+.It Ic rtable Ar number
+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.
+.Pp
.It Xo
.Ic transparent-as
.Pq Ic yes Ns \&| Ns Ic no
diff --git a/usr.sbin/bgpd/bgpd.h b/usr.sbin/bgpd/bgpd.h
index fff515b8a79..2ae63f4c90f 100644
--- a/usr.sbin/bgpd/bgpd.h
+++ b/usr.sbin/bgpd/bgpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: bgpd.h,v 1.208 2006/08/27 16:11:04 henning Exp $ */
+/* $OpenBSD: bgpd.h,v 1.209 2006/11/28 16:39:34 henning Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -153,6 +153,7 @@ struct bgpd_config {
int opts;
int flags;
int log;
+ u_int rtableid;
u_int32_t bgpid;
u_int32_t clusterid;
u_int16_t as;
@@ -733,7 +734,7 @@ void imsg_free(struct imsg *);
int imsg_get_fd(struct imsgbuf *);
/* kroute.c */
-int kr_init(int);
+int kr_init(int, u_int);
int kr_change(struct kroute_label *);
int kr_delete(struct kroute_label *);
int kr6_change(struct kroute6_label *);
diff --git a/usr.sbin/bgpd/kroute.c b/usr.sbin/bgpd/kroute.c
index a417f0f7e6b..f92e5ffcc59 100644
--- a/usr.sbin/bgpd/kroute.c
+++ b/usr.sbin/bgpd/kroute.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kroute.c,v 1.149 2006/11/28 16:36:58 henning Exp $ */
+/* $OpenBSD: kroute.c,v 1.150 2006/11/28 16:39:34 henning Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -39,6 +39,7 @@
struct {
u_int32_t rtseq;
pid_t pid;
+ u_int rtableid;
int fib_sync;
int fd;
} kr_state;
@@ -131,10 +132,10 @@ void if_announce(void *);
int send_rtmsg(int, int, struct kroute *);
int send_rt6msg(int, int, struct kroute6 *);
int dispatch_rtmsg(void);
-int fetchtable(void);
+int fetchtable(u_int, int);
int fetchifs(int);
int dispatch_rtmsg_addr(struct rt_msghdr *,
- struct sockaddr *[RTAX_MAX]);
+ struct sockaddr *[RTAX_MAX], int);
RB_HEAD(kroute_tree, kroute_node) krt;
RB_PROTOTYPE(kroute_tree, kroute_node, entry, kroute_compare)
@@ -157,12 +158,13 @@ RB_GENERATE(kif_tree, kif_node, entry, kif_compare)
*/
int
-kr_init(int fs)
+kr_init(int fs, u_int rtableid)
{
int opt = 0, rcvbuf, default_rcvbuf;
socklen_t optlen;
kr_state.fib_sync = fs;
+ kr_state.rtableid = rtableid;
if ((kr_state.fd = socket(AF_ROUTE, SOCK_RAW, 0)) == -1) {
log_warn("kr_init: socket");
@@ -198,8 +200,11 @@ kr_init(int fs)
if (fetchifs(0) == -1)
return (-1);
- if (fetchtable() == -1)
+ if (fetchtable(kr_state.rtableid, 0) == -1)
return (-1);
+ if (kr_state.rtableid != 0)
+ if (fetchtable(0, 1) == -1)
+ return (-1);
if (protect_lo() == -1)
return (-1);
@@ -1742,6 +1747,7 @@ send_rtmsg(int fd, int action, struct kroute *kroute)
r.hdr.rtm_msglen = sizeof(r);
r.hdr.rtm_version = RTM_VERSION;
r.hdr.rtm_type = action;
+ r.hdr.rtm_tableid = kr_state.rtableid;
r.hdr.rtm_flags = RTF_PROTO1;
if (kroute->flags & F_BLACKHOLE)
r.hdr.rtm_flags |= RTF_BLACKHOLE;
@@ -1818,6 +1824,7 @@ send_rt6msg(int fd, int action, struct kroute6 *kroute)
r.hdr.rtm_msglen = sizeof(r);
r.hdr.rtm_version = RTM_VERSION;
r.hdr.rtm_type = action;
+ r.hdr.rtm_tableid = kr_state.rtableid;
r.hdr.rtm_flags = RTF_PROTO1;
if (kroute->flags & F_BLACKHOLE)
r.hdr.rtm_flags |= RTF_BLACKHOLE;
@@ -1877,7 +1884,7 @@ retry:
}
int
-fetchtable(void)
+fetchtable(u_int rtableid, int connected_only)
{
size_t len;
int mib[7];
@@ -1895,9 +1902,11 @@ fetchtable(void)
mib[3] = 0;
mib[4] = NET_RT_DUMP;
mib[5] = 0;
- mib[6] = 0; /* rtableid */
+ mib[6] = rtableid;
if (sysctl(mib, 7, NULL, &len, NULL, 0) == -1) {
+ if (rtableid != 0 && errno == EINVAL) /* table nonexistant */
+ return (0);
log_warn("sysctl");
return (-1);
}
@@ -2020,19 +2029,24 @@ fetchtable(void)
}
if (sa->sa_family == AF_INET) {
+log_debug("fetchtable id %u, %s/%u, %s", rtableid, inet_ntoa(kr->r.prefix), kr->r.prefixlen,
+kr->r.flags & F_CONNECTED ? "connected" : "");
if (rtm->rtm_flags & RTF_PROTO1) {
send_rtmsg(kr_state.fd, RTM_DELETE, &kr->r);
free(kr);
- } else
+ } else if (connected_only && !(kr->r.flags & F_CONNECTED))
+ free(kr);
+ else
kroute_insert(kr);
} else if (sa->sa_family == AF_INET6) {
if (rtm->rtm_flags & RTF_PROTO1) {
send_rt6msg(kr_state.fd, RTM_DELETE, &kr6->r);
free(kr6);
- } else
+ } else if (connected_only && !(kr6->r.flags & F_CONNECTED))
+ free(kr6);
+ else
kroute6_insert(kr6);
}
-
}
free(buf);
return (0);
@@ -2119,6 +2133,7 @@ dispatch_rtmsg(void)
struct rt_msghdr *rtm;
struct if_msghdr ifm;
struct sockaddr *sa, *rti_info[RTAX_MAX];
+ int connected_only;
if ((n = read(kr_state.fd, &buf, sizeof(buf))) == -1) {
log_warn("dispatch_rtmsg: read error");
@@ -2134,9 +2149,6 @@ dispatch_rtmsg(void)
for (next = buf; next < lim; next += rtm->rtm_msglen) {
rtm = (struct rt_msghdr *)next;
- if (rtm->rtm_tableid != 0)
- continue;
-
switch (rtm->rtm_type) {
case RTM_ADD:
case RTM_CHANGE:
@@ -2153,7 +2165,15 @@ dispatch_rtmsg(void)
if (rtm->rtm_flags & RTF_LLINFO) /* arp cache */
continue;
- if (dispatch_rtmsg_addr(rtm, rti_info) == -1)
+ connected_only = 0;
+ if (rtm->rtm_tableid != kr_state.rtableid) {
+ if (rtm->rtm_tableid == 0)
+ connected_only = 1;
+ else
+ continue;
+ }
+
+ if (dispatch_rtmsg_addr(rtm, rti_info, connected_only) == -1)
return (-1);
break;
case RTM_IFINFO:
@@ -2173,7 +2193,8 @@ dispatch_rtmsg(void)
}
int
-dispatch_rtmsg_addr(struct rt_msghdr *rtm, struct sockaddr *rti_info[RTAX_MAX])
+dispatch_rtmsg_addr(struct rt_msghdr *rtm, struct sockaddr *rti_info[RTAX_MAX],
+ int connected_only)
{
struct sockaddr *sa;
struct sockaddr_in *sa_in;
@@ -2265,6 +2286,9 @@ dispatch_rtmsg_addr(struct rt_msghdr *rtm, struct sockaddr *rti_info[RTAX_MAX])
break;
}
+ if (connected_only && !(flags & F_CONNECTED))
+ return (0);
+
if (sa == NULL && !(flags & F_CONNECTED)) {
log_warnx("dispatch_rtmsg no nexthop for %s/%u",
log_addr(&prefix), prefixlen);
@@ -2380,4 +2404,3 @@ dispatch_rtmsg_addr(struct rt_msghdr *rtm, struct sockaddr *rti_info[RTAX_MAX])
return (0);
}
-
diff --git a/usr.sbin/bgpd/parse.y b/usr.sbin/bgpd/parse.y
index d397357dbbc..240b8d91459 100644
--- a/usr.sbin/bgpd/parse.y
+++ b/usr.sbin/bgpd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.196 2006/10/25 18:48:29 henning Exp $ */
+/* $OpenBSD: parse.y,v 1.197 2006/11/28 16:39:34 henning Exp $ */
/*
* Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -150,7 +150,7 @@ typedef struct {
%}
-%token AS ROUTERID HOLDTIME YMIN LISTEN ON FIBUPDATE
+%token AS ROUTERID HOLDTIME YMIN LISTEN ON FIBUPDATE RTABLE
%token RDE EVALUATE IGNORE COMPARE
%token GROUP NEIGHBOR NETWORK
%token REMOTEAS DESCR LOCALADDR MULTIHOP PASSIVE MAXPREFIX RESTART
@@ -470,6 +470,13 @@ conf_main : AS asnumber {
}
free($4);
}
+ | RTABLE number {
+ if ($2 > RT_TABLEID_MAX || $2 < 0) {
+ yyerror("invalid rtable id");
+ YYERROR;
+ }
+ conf->rtableid = $2;
+ }
;
mrtdump : DUMP STRING inout STRING optnumber {
@@ -1664,6 +1671,7 @@ lookup(char *s)
{ "route-collector", ROUTECOLL},
{ "route-reflector", REFLECTOR},
{ "router-id", ROUTERID},
+ { "rtable", RTABLE},
{ "rtlabel", RTLABEL},
{ "self", SELF},
{ "set", SET},
diff --git a/usr.sbin/bgpd/printconf.c b/usr.sbin/bgpd/printconf.c
index d945967e23b..75c167299a3 100644
--- a/usr.sbin/bgpd/printconf.c
+++ b/usr.sbin/bgpd/printconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: printconf.c,v 1.57 2006/08/04 12:01:48 henning Exp $ */
+/* $OpenBSD: printconf.c,v 1.58 2006/11/28 16:39:34 henning Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -241,6 +241,8 @@ print_mainconf(struct bgpd_config *conf)
print_set(&conf->staticset6);
printf("\n");
}
+ if (conf->rtableid)
+ printf("rtable %u\n", conf->rtableid);
}
void