summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorHenning Brauer <henning@cvs.openbsd.org>2004-04-24 19:36:20 +0000
committerHenning Brauer <henning@cvs.openbsd.org>2004-04-24 19:36:20 +0000
commitec053ecdd6fe18ab575f9b48eeebce50e5d161cf (patch)
tree9f80a46bd98c3c874170578b237faf6a60e72aa8 /usr.sbin
parent5eb2c8799f752b3a6f32514f18624263e6888ded (diff)
some rather boring windows talk at cansecwest made me hack initial support
for IPv6 transport parts based on a diff from Brent Graveland ok itojun@ claudio@
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/bgpd/bgpd.h3
-rw-r--r--usr.sbin/bgpd/parse.y31
-rw-r--r--usr.sbin/bgpd/session.c54
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);