diff options
Diffstat (limited to 'usr.sbin/bgpd/session.c')
-rw-r--r-- | usr.sbin/bgpd/session.c | 54 |
1 files changed, 39 insertions, 15 deletions
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); |