diff options
-rw-r--r-- | usr.sbin/bgpd/bgpd.c | 5 | ||||
-rw-r--r-- | usr.sbin/bgpd/bgpd.conf.5 | 10 | ||||
-rw-r--r-- | usr.sbin/bgpd/bgpd.h | 5 | ||||
-rw-r--r-- | usr.sbin/bgpd/kroute.c | 55 | ||||
-rw-r--r-- | usr.sbin/bgpd/parse.y | 12 | ||||
-rw-r--r-- | usr.sbin/bgpd/printconf.c | 4 |
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 |