diff options
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/bgpd/bgpd.h | 3 | ||||
-rw-r--r-- | usr.sbin/bgpd/parse.y | 31 | ||||
-rw-r--r-- | usr.sbin/bgpd/session.c | 54 |
3 files changed, 64 insertions, 24 deletions
diff --git a/usr.sbin/bgpd/bgpd.h b/usr.sbin/bgpd/bgpd.h index 8beb6f285a5..800c3b9d092 100644 --- a/usr.sbin/bgpd/bgpd.h +++ b/usr.sbin/bgpd/bgpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bgpd.h,v 1.107 2004/04/10 17:27:28 henning Exp $ */ +/* $OpenBSD: bgpd.h,v 1.108 2004/04/24 19:36:19 henning Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -112,6 +112,7 @@ struct bgpd_config { int flags; int log; struct sockaddr_in listen_addr; + struct sockaddr_in6 listen6_addr; }; struct buf_read { diff --git a/usr.sbin/bgpd/parse.y b/usr.sbin/bgpd/parse.y index f023cf21f03..c71cbccfe96 100644 --- a/usr.sbin/bgpd/parse.y +++ b/usr.sbin/bgpd/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.78 2004/03/11 19:01:08 claudio Exp $ */ +/* $OpenBSD: parse.y,v 1.79 2004/04/24 19:36:19 henning Exp $ */ /* * Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -216,11 +216,20 @@ conf_main : AS asnumber { conf->min_holdtime = $3; } | LISTEN ON address { - if ($3.af != AF_INET) { - yyerror("listen-on takes an IPv4 address"); + switch ($3.af) { + case AF_INET: + conf->listen_addr.sin_addr.s_addr = + $3.v4.s_addr; + break; + case AF_INET6: + memcpy(&conf->listen6_addr.sin6_addr, &$3.v6, + sizeof(conf->listen6_addr.sin6_addr)); + break; + default: + yyerror("king bula does not like family %u", + $3.af); YYERROR; } - conf->listen_addr.sin_addr.s_addr = $3.v4.s_addr; } | FIBUPDATE yesno { if ($2 == 0) @@ -349,10 +358,6 @@ optnumber : /* empty */ { $$ = 0; } neighbor : { curpeer = new_peer(); } NEIGHBOR address optnl '{' optnl { - if ($3.af != AF_INET) { - yyerror("king bula sez: IPv4 transport only"); - YYERROR; - } memcpy(&curpeer->conf.remote_addr, &$3, sizeof(curpeer->conf.remote_addr)); if (get_id(curpeer)) { @@ -421,6 +426,11 @@ peeropts : REMOTEAS asnumber { free($2); } | LOCALADDR address { + if ($2.af != curpeer->conf.remote_addr.af) { + yyerror("local-address and neighbor address " + "must be of the same address family"); + YYERROR; + } memcpy(&curpeer->conf.local_addr, &$2, sizeof(curpeer->conf.local_addr)); } @@ -1066,6 +1076,11 @@ parse_config(char *filename, struct bgpd_config *xconf, conf->listen_addr.sin_addr.s_addr = INADDR_ANY; conf->listen_addr.sin_port = htons(BGP_PORT); + bzero(&conf->listen6_addr, sizeof(conf->listen6_addr)); + conf->listen6_addr.sin6_len = sizeof(conf->listen6_addr); + conf->listen6_addr.sin6_family = AF_INET6; + conf->listen6_addr.sin6_port = htons(BGP_PORT); + if ((fin = fopen(filename, "r")) == NULL) { warn("%s", filename); free(conf); diff --git a/usr.sbin/bgpd/session.c b/usr.sbin/bgpd/session.c index 11fcf1c4d48..5f8a8a38f46 100644 --- a/usr.sbin/bgpd/session.c +++ b/usr.sbin/bgpd/session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: session.c,v 1.142 2004/04/16 04:52:26 henning Exp $ */ +/* $OpenBSD: session.c,v 1.143 2004/04/24 19:36:19 henning Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -45,13 +45,14 @@ #include "session.h" #define PFD_LISTEN 0 -#define PFD_PIPE_MAIN 1 -#define PFD_PIPE_ROUTE 2 -#define PFD_SOCK_CTL 3 -#define PFD_PEERS_START 4 +#define PFD_LISTEN6 1 +#define PFD_PIPE_MAIN 2 +#define PFD_PIPE_ROUTE 3 +#define PFD_SOCK_CTL 4 +#define PFD_PEERS_START 5 void session_sighdlr(int); -int setup_listener(void); +int setup_listener(struct sockaddr *); void init_conf(struct bgpd_config *); void init_peer(struct peer *); int timer_due(time_t); @@ -88,6 +89,7 @@ struct peer *npeers; volatile sig_atomic_t session_quit = 0; int pending_reconf = 0; int sock = -1; +int sock6 = -1; int csock = -1; struct imsgbuf ibuf_rde; struct imsgbuf ibuf_main; @@ -106,11 +108,14 @@ session_sighdlr(int sig) } int -setup_listener(void) +setup_listener(struct sockaddr *sa) { int fd, opt; - if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) + if (sa->sa_family != AF_INET && sa->sa_family != AF_INET6) + return (-1); + + if ((fd = socket(sa->sa_family, SOCK_STREAM, IPPROTO_TCP)) == -1) return (fd); opt = 1; @@ -119,8 +124,7 @@ setup_listener(void) if (setsockopt(fd, IPPROTO_TCP, TCP_MD5SIG, &opt, sizeof(opt)) == -1) fatal("setsockopt TCP_MD5SIG"); - if (bind(fd, (struct sockaddr *)&conf->listen_addr, - sizeof(conf->listen_addr))) { + if (bind(fd, sa, sa->sa_len)) { close(fd); return (-1); } @@ -135,7 +139,6 @@ setup_listener(void) return (fd); } - int session_main(struct bgpd_config *config, struct peer *cpeers, struct network_head *net_l, struct filter_head *rules, @@ -181,8 +184,12 @@ session_main(struct bgpd_config *config, struct peer *cpeers, setproctitle("session engine"); bgpd_process = PROC_SE; - if ((sock = setup_listener()) == -1) - fatalx("listener setup failed"); + if ((sock = setup_listener((struct sockaddr *)&conf->listen_addr)) == + -1) + fatalx("IPv4 listener setup failed"); + if ((sock6 = setup_listener((struct sockaddr *)&conf->listen6_addr)) == + -1) + fatalx("IPv6 listener setup failed"); if (pfkey_init() == -1) fatalx("pfkey setup failed"); @@ -230,6 +237,8 @@ session_main(struct bgpd_config *config, struct peer *cpeers, bzero(&pfd, sizeof(pfd)); pfd[PFD_LISTEN].fd = sock; pfd[PFD_LISTEN].events = POLLIN; + pfd[PFD_LISTEN6].fd = sock6; + pfd[PFD_LISTEN6].events = POLLIN; pfd[PFD_PIPE_MAIN].fd = ibuf_main.sock; pfd[PFD_PIPE_MAIN].events = POLLIN; if (ibuf_main.w.queued > 0) @@ -344,6 +353,11 @@ session_main(struct bgpd_config *config, struct peer *cpeers, session_accept(sock); } + if (nfds > 0 && pfd[PFD_LISTEN6].revents & POLLIN) { + nfds--; + session_accept(sock6); + } + if (nfds > 0 && pfd[PFD_PIPE_MAIN].revents & POLLOUT) if (msgbuf_write(&ibuf_main.w) < 0) fatal("pipe write error"); @@ -875,7 +889,7 @@ session_setup_socket(struct peer *p) int pre = IPTOS_PREC_INTERNETCONTROL; int nodelay = 1; - if (p->conf.ebgp) + if (p->conf.ebgp && p->sa_remote.ss_family == AF_INET) /* set TTL to foreign router's distance - 1=direct n=multihop */ if (setsockopt(p->sock, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl)) == -1) { @@ -884,6 +898,15 @@ session_setup_socket(struct peer *p) return (-1); } + if (p->conf.ebgp && p->sa_remote.ss_family == AF_INET6) + /* set hoplimit to foreign router's distance */ + if (setsockopt(p->sock, IPPROTO_IPV6, IPV6_HOPLIMIT, &ttl, + sizeof(ttl)) == -1) { + log_peer_warn(&p->conf, + "session_setup_socket setsockopt hoplimit"); + return (-1); + } + /* set TCP_NODELAY */ if (setsockopt(p->sock, IPPROTO_TCP, TCP_NODELAY, &nodelay, sizeof(nodelay)) == -1) { @@ -893,7 +916,8 @@ session_setup_socket(struct peer *p) } /* set precedence, see rfc1771 appendix 5 */ - if (setsockopt(p->sock, IPPROTO_IP, IP_TOS, &pre, sizeof(pre)) == -1) { + if (p->sa_remote.ss_family == AF_INET && + setsockopt(p->sock, IPPROTO_IP, IP_TOS, &pre, sizeof(pre)) == -1) { log_peer_warn(&p->conf, "session_setup_socket setsockopt TOS"); return (-1); |