diff options
author | David Lamparter <equinox@diac24.net> | 2009-10-04 16:21:49 +0200 |
---|---|---|
committer | Denis Ovsienko <infrastation@yandex.ru> | 2011-12-13 19:23:38 +0400 |
commit | ca0512692156d5bbb902523d2f123fc89dbec1ab (patch) | |
tree | 6dd0206cb175c3e790023f9e5d5d755b57181b0d /lib | |
parent | e0ca5fde7be5b5ce90dae78c2477e8245aecb8e9 (diff) |
lib: add sockopt helper for setting IPV6_V6ONLY and use it
getaddrinfo returns a list of socket parameters for listening. it
will contain both IPv4 and IPv6 listening sockets. unless we use
IPV6_V6ONLY on the IPv6 ones, only the socket listed first will
work. if the IPv4 one came first, the IPv6 one would get an
"Address in use" error.
this functionality was already present for bgpd and its listening
sockets. as it is needed for vtys as well, make it a common helper.
Conflicts:
lib/sockunion.c
Diffstat (limited to 'lib')
-rw-r--r-- | lib/sockunion.c | 24 | ||||
-rw-r--r-- | lib/sockunion.h | 1 | ||||
-rw-r--r-- | lib/vty.c | 1 |
3 files changed, 26 insertions, 0 deletions
diff --git a/lib/sockunion.c b/lib/sockunion.c index 27a7ab04..59770529 100644 --- a/lib/sockunion.c +++ b/lib/sockunion.c @@ -566,6 +566,30 @@ sockopt_minttl (int family, int sock, int minttl) return -1; } +int +sockopt_v6only (int family, int sock) +{ + int ret, on = 1; + +#ifdef HAVE_IPV6 +#ifdef IPV6_V6ONLY + if (family == AF_INET6) + { + ret = setsockopt (sock, IPPROTO_IPV6, IPV6_V6ONLY, + (void *) &on, sizeof (int)); + if (ret < 0) + { + zlog (NULL, LOG_WARNING, "can't set sockopt IPV6_V6ONLY " + "to socket %d", sock); + return -1; + } + return 0; + } +#endif /* IPV6_V6ONLY */ +#endif /* HAVE_IPV6 */ + return 0; +} + /* If same family and same prefix return 1. */ int sockunion_same (union sockunion *su1, union sockunion *su2) diff --git a/lib/sockunion.h b/lib/sockunion.h index 0ee2d63b..4531f620 100644 --- a/lib/sockunion.h +++ b/lib/sockunion.h @@ -99,6 +99,7 @@ extern int sockunion_accept (int sock, union sockunion *); extern int sockunion_stream_socket (union sockunion *); extern int sockopt_reuseaddr (int); extern int sockopt_reuseport (int); +extern int sockopt_v6only (int family, int sock); extern int sockunion_bind (int sock, union sockunion *, unsigned short, union sockunion *); extern int sockopt_ttl (int family, int sock, int ttl); @@ -1816,6 +1816,7 @@ vty_serv_sock_addrinfo (const char *hostname, unsigned short port) if (sock < 0) continue; + sockopt_v6only (ainfo->ai_family, sock); sockopt_reuseaddr (sock); sockopt_reuseport (sock); |