]> git.puffer.fish Git - mirror/frr.git/commitdiff
lib: add sockopt helper for setting IPV6_V6ONLY and use it
authorDavid Lamparter <equinox@diac24.net>
Sun, 4 Oct 2009 14:21:49 +0000 (16:21 +0200)
committerDenis Ovsienko <infrastation@yandex.ru>
Tue, 13 Dec 2011 15:23:38 +0000 (19:23 +0400)
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

bgpd/bgp_network.c
lib/sockunion.c
lib/sockunion.h
lib/vty.c

index 274a989d25b5b71b2de924a2c38d0a930a71cd81..a7dca531327fb63acfc52b52d02e5d5b0d324bef 100644 (file)
@@ -395,14 +395,7 @@ bgp_listener (int sock, struct sockaddr *sa, socklen_t salen)
 #  endif
 #endif
 
-#ifdef IPV6_V6ONLY
-  /* Want only IPV6 on ipv6 socket (not mapped addresses) */
-  if (sa->sa_family == AF_INET6) {
-    int on = 1;
-    setsockopt (sock, IPPROTO_IPV6, IPV6_V6ONLY,
-               (void *) &on, sizeof (on));
-  }
-#endif
+  sockopt_v6only (sa->sa_family, sock);
 
   ret = bind (sock, sa, salen);
   en = errno;
index 27a7ab04fb0b15b670c4c4c04c7cff65f4fc0759..59770529313d523a68951a881ab51437204fd1b4 100644 (file)
@@ -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)
index 0ee2d63b7245116ad89fb0dd0d1379fb87f5f645..4531f620ab92d1b619e22c376eacd62469270335 100644 (file)
@@ -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);
index 6b66a4dadda425de785fec8c8766ce80bc890dd2..d9eb921e26a80fd94774702d68ecbbdb02e07732 100644 (file)
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -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);