]> 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>
Mon, 21 Nov 2011 14:25:01 +0000 (18:25 +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.

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

index bd2e2d685f3366ce232b8441d5164b7072ade8e2..b5c4c602b58a905fd5c4272407994bd38bb328e8 100644 (file)
@@ -387,14 +387,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 6a40f33211e654ad8cd75b4a5e188504fe6035c8..d1f6d80b23f4c7a758423d19f517f7bd6057e3cc 100644 (file)
@@ -527,6 +527,30 @@ sockopt_ttl (int family, int sock, int ttl)
   return 0;
 }
 
+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 96b9a0d4a14f50e5e353cb09051dd33062b66150..db145cf271af61bbd6d5ff1574fbc94b19b2a410 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 bd1dbac0717982fa190083645deaed47783aa673..e403159bee38f3a475f1521ee6cc53c66226ee5b 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);