Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src Make ifconfig(8) set and display preference numbers for IPv6
details: https://anonhg.NetBSD.org/src/rev/b53de366f352
branches: trunk
changeset: 747344:b53de366f352
user: dyoung <dyoung%NetBSD.org@localhost>
date: Fri Sep 11 22:06:29 2009 +0000
description:
Make ifconfig(8) set and display preference numbers for IPv6
addresses. Make the kernel support SIOC[SG]IFADDRPREF for IPv6
interface addresses.
In in6ifa_ifpforlinklocal(), consult preference numbers before
making an otherwise arbitrary choice of in6_ifaddr. Otherwise,
preference numbers are *not* consulted by the kernel, but that will
be rather easy for somebody with a little bit of free time to fix.
Please note that setting the preference number for a link-local
IPv6 address does not work right, yet, but that ought to be fixed
soon.
In support of the changes above,
1 Add a method to struct domain for "externalizing" a sockaddr, and
provide an implementation for IPv6. Expect more work in this area: it
may be more proper to say that the IPv6 implementation "internalizes"
a sockaddr. Add sockaddr_externalize().
2 Add a subroutine, sofamily(), that returns a struct socket's address
family or AF_UNSPEC.
3 Make a lot of IPv4-specific code generic, and move it from
sys/netinet/ to sys/net/ for re-use by IPv6 parts of the kernel and
ifconfig(8).
diffstat:
sbin/ifconfig/af_inet.c | 58 +++-------------------------------
sbin/ifconfig/af_inet6.c | 11 ++++--
sbin/ifconfig/util.c | 58 ++++++++++++++++++++++++++++++++++-
sbin/ifconfig/util.h | 6 +++
sys/kern/uipc_domain.c | 18 +++++++++-
sys/kern/uipc_socket.c | 17 +++++++++-
sys/net/if.c | 66 ++++++++++++++++++++++++++++++++++++++-
sys/net/if.h | 4 +-
sys/netinet/in.c | 79 ++++-------------------------------------------
sys/netinet6/in6.c | 30 +++++++++++------
sys/netinet6/in6.h | 4 +-
sys/netinet6/in6_proto.c | 5 +-
sys/netinet6/scope6.c | 18 +++++++++-
sys/sys/domain.h | 5 ++-
sys/sys/socket.h | 4 +-
sys/sys/socketvar.h | 3 +-
16 files changed, 231 insertions(+), 155 deletions(-)
diffs (truncated from 780 to 300 lines):
diff -r fd6e01b94fb6 -r b53de366f352 sbin/ifconfig/af_inet.c
--- a/sbin/ifconfig/af_inet.c Fri Sep 11 21:25:07 2009 +0000
+++ b/sbin/ifconfig/af_inet.c Fri Sep 11 22:06:29 2009 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: af_inet.c,v 1.13 2009/08/07 19:35:55 dyoung Exp $ */
+/* $NetBSD: af_inet.c,v 1.14 2009/09/11 22:06:29 dyoung Exp $ */
/*
* Copyright (c) 1983, 1993
@@ -31,7 +31,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: af_inet.c,v 1.13 2009/08/07 19:35:55 dyoung Exp $");
+__RCSID("$NetBSD: af_inet.c,v 1.14 2009/09/11 22:06:29 dyoung Exp $");
#endif /* not lint */
#include <sys/param.h>
@@ -63,7 +63,6 @@
static void in_commit_address(prop_dictionary_t, prop_dictionary_t);
static void in_alias(const char *, prop_dictionary_t, prop_dictionary_t,
struct in_aliasreq *);
-static void in_preference(const char *, const struct sockaddr *);
static struct afswtch af = {
.af_name = "inet", .af_af = AF_INET, .af_status = in_status,
@@ -139,46 +138,12 @@
}
}
-static int16_t
-in_get_preference(const char *ifname, const struct sockaddr *sa)
-{
- struct if_addrprefreq ifap;
- int s;
-
- if ((s = getsock(AF_INET)) == -1) {
- if (errno == EPROTONOSUPPORT)
- return 0;
- err(EXIT_FAILURE, "socket");
- }
- memset(&ifap, 0, sizeof(ifap));
- estrlcpy(ifap.ifap_name, ifname, sizeof(ifap.ifap_name));
- memcpy(&ifap.ifap_addr, sa, MIN(sizeof(ifap.ifap_addr), sa->sa_len));
- if (ioctl(s, SIOCGIFADDRPREF, &ifap) == -1) {
- if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT)
- return 0;
- warn("SIOCGIFADDRPREF");
- }
- return ifap.ifap_preference;
-}
-
-static void
-in_preference(const char *ifname, const struct sockaddr *sa)
-{
- int16_t preference;
-
- if (lflag)
- return;
-
- preference = in_get_preference(ifname, sa);
- printf(" preference %" PRId16, preference);
-}
-
static void
in_status(prop_dictionary_t env, prop_dictionary_t oenv, bool force)
{
struct ifaddrs *ifap, *ifa;
struct in_aliasreq ifra;
- int printprefs = 0;
+ bool printprefs = false;
const char *ifname;
if ((ifname = getifname(env)) == NULL)
@@ -187,19 +152,8 @@
if (getifaddrs(&ifap) != 0)
err(EXIT_FAILURE, "getifaddrs");
- /* Print address preference numbers if any address has a non-zero
- * preference assigned.
- */
- for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
- if (strcmp(ifname, ifa->ifa_name) != 0)
- continue;
- if (ifa->ifa_addr->sa_family != AF_INET)
- continue;
- if (in_get_preference(ifa->ifa_name, ifa->ifa_addr) != 0) {
- printprefs = 1;
- break;
- }
- }
+ printprefs = ifa_any_preferences(ifname, ifap, AF_INET);
+
for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
if (strcmp(ifname, ifa->ifa_name) != 0)
continue;
@@ -213,7 +167,7 @@
memcpy(&ifra.ifra_addr, ifa->ifa_addr, ifa->ifa_addr->sa_len);
in_alias(ifa->ifa_name, env, oenv, &ifra);
if (printprefs)
- in_preference(ifa->ifa_name, ifa->ifa_addr);
+ ifa_print_preference(ifa->ifa_name, ifa->ifa_addr);
printf("\n");
}
freeifaddrs(ifap);
diff -r fd6e01b94fb6 -r b53de366f352 sbin/ifconfig/af_inet6.c
--- a/sbin/ifconfig/af_inet6.c Fri Sep 11 21:25:07 2009 +0000
+++ b/sbin/ifconfig/af_inet6.c Fri Sep 11 22:06:29 2009 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: af_inet6.c,v 1.24 2009/08/07 18:53:37 dyoung Exp $ */
+/* $NetBSD: af_inet6.c,v 1.25 2009/09/11 22:06:29 dyoung Exp $ */
/*
* Copyright (c) 1983, 1993
@@ -31,7 +31,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: af_inet6.c,v 1.24 2009/08/07 18:53:37 dyoung Exp $");
+__RCSID("$NetBSD: af_inet6.c,v 1.25 2009/09/11 22:06:29 dyoung Exp $");
#endif /* not lint */
#include <sys/param.h>
@@ -374,8 +374,6 @@
printf("infty");
}
}
-
- printf("\n");
}
static void
@@ -384,12 +382,14 @@
struct ifaddrs *ifap, *ifa;
struct in6_ifreq ifr;
const char *ifname;
+ bool printprefs = false;
if ((ifname = getifname(env)) == NULL)
err(EXIT_FAILURE, "%s: getifname", __func__);
if (getifaddrs(&ifap) != 0)
err(EXIT_FAILURE, "getifaddrs");
+ printprefs = ifa_any_preferences(ifname, ifap, AF_INET6);
for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
if (strcmp(ifname, ifa->ifa_name) != 0)
continue;
@@ -402,6 +402,9 @@
estrlcpy(ifr.ifr_name, ifa->ifa_name, sizeof(ifr.ifr_name));
memcpy(&ifr.ifr_addr, ifa->ifa_addr, ifa->ifa_addr->sa_len);
in6_alias(ifname, env, oenv, &ifr);
+ if (printprefs)
+ ifa_print_preference(ifa->ifa_name, ifa->ifa_addr);
+ printf("\n");
}
freeifaddrs(ifap);
}
diff -r fd6e01b94fb6 -r b53de366f352 sbin/ifconfig/util.c
--- a/sbin/ifconfig/util.c Fri Sep 11 21:25:07 2009 +0000
+++ b/sbin/ifconfig/util.c Fri Sep 11 22:06:29 2009 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: util.c,v 1.12 2009/08/07 18:53:37 dyoung Exp $ */
+/* $NetBSD: util.c,v 1.13 2009/09/11 22:06:29 dyoung Exp $ */
/*-
* Copyright (c) 2008 David Young. All rights reserved.
@@ -27,7 +27,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: util.c,v 1.12 2009/08/07 18:53:37 dyoung Exp $");
+__RCSID("$NetBSD: util.c,v 1.13 2009/09/11 22:06:29 dyoung Exp $");
#endif /* not lint */
#include <ctype.h>
@@ -290,6 +290,60 @@
freeifaddrs(ifap);
}
+int16_t
+ifa_get_preference(const char *ifname, const struct sockaddr *sa)
+{
+ struct if_addrprefreq ifap;
+ int s;
+
+ if ((s = getsock(sa->sa_family)) == -1) {
+ if (errno == EPROTONOSUPPORT)
+ return 0;
+ err(EXIT_FAILURE, "socket");
+ }
+ memset(&ifap, 0, sizeof(ifap));
+ estrlcpy(ifap.ifap_name, ifname, sizeof(ifap.ifap_name));
+ memcpy(&ifap.ifap_addr, sa, MIN(sizeof(ifap.ifap_addr), sa->sa_len));
+ if (ioctl(s, SIOCGIFADDRPREF, &ifap) == -1) {
+ if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT)
+ return 0;
+ warn("SIOCGIFADDRPREF");
+ }
+ return ifap.ifap_preference;
+}
+
+void
+ifa_print_preference(const char *ifname, const struct sockaddr *sa)
+{
+ int16_t preference;
+
+ if (lflag)
+ return;
+
+ preference = ifa_get_preference(ifname, sa);
+ printf(" preference %" PRId16, preference);
+}
+
+bool
+ifa_any_preferences(const char *ifname, struct ifaddrs *ifap, int family)
+{
+ struct ifaddrs *ifa;
+
+ /* Print address preference numbers if any address has a non-zero
+ * preference assigned.
+ */
+ for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
+ if (strcmp(ifname, ifa->ifa_name) != 0)
+ continue;
+ if (ifa->ifa_addr->sa_family != family)
+ continue;
+ if (ifa_get_preference(ifa->ifa_name, ifa->ifa_addr) != 0)
+ return true;
+ }
+ return false;
+}
+
+
#ifdef INET6
/* KAME idiosyncrasy */
void
diff -r fd6e01b94fb6 -r b53de366f352 sbin/ifconfig/util.h
--- a/sbin/ifconfig/util.h Fri Sep 11 21:25:07 2009 +0000
+++ b/sbin/ifconfig/util.h Fri Sep 11 22:06:29 2009 +0000
@@ -2,6 +2,9 @@
#define _IFCONFIG_UTIL_H
#include <netinet/in.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <ifaddrs.h>
#include "parse.h"
@@ -25,5 +28,8 @@
#ifdef INET6
void in6_fillscopeid(struct sockaddr_in6 *sin6);
#endif /* INET6 */
+bool ifa_any_preferences(const char *, struct ifaddrs *, int);
+void ifa_print_preference(const char *, const struct sockaddr *);
+int16_t ifa_get_preference(const char *, const struct sockaddr *);
#endif /* _IFCONFIG_UTIL_H */
diff -r fd6e01b94fb6 -r b53de366f352 sys/kern/uipc_domain.c
--- a/sys/kern/uipc_domain.c Fri Sep 11 21:25:07 2009 +0000
+++ b/sys/kern/uipc_domain.c Fri Sep 11 22:06:29 2009 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: uipc_domain.c,v 1.83 2009/09/08 18:01:34 dyoung Exp $ */
+/* $NetBSD: uipc_domain.c,v 1.84 2009/09/11 22:06:29 dyoung Exp $ */
/*
* Copyright (c) 1982, 1986, 1993
@@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uipc_domain.c,v 1.83 2009/09/08 18:01:34 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uipc_domain.c,v 1.84 2009/09/11 22:06:29 dyoung Exp $");
#include <sys/param.h>
#include <sys/socket.h>
@@ -268,6 +268,20 @@
return memcpy(dst, src, src->sa_len);
}
+struct sockaddr *
+sockaddr_externalize(struct sockaddr *dst, socklen_t socklen,
+ const struct sockaddr *src)
+{
+ struct domain *dom;
+
+ dom = pffinddomain(src->sa_family);
+
+ if (dom != NULL && dom->dom_sockaddr_externalize != NULL)
+ return (*dom->dom_sockaddr_externalize)(dst, socklen, src);
+
+ return sockaddr_copy(dst, socklen, src);
+}
+
int
sockaddr_cmp(const struct sockaddr *sa1, const struct sockaddr *sa2)
{
diff -r fd6e01b94fb6 -r b53de366f352 sys/kern/uipc_socket.c
--- a/sys/kern/uipc_socket.c Fri Sep 11 21:25:07 2009 +0000
+++ b/sys/kern/uipc_socket.c Fri Sep 11 22:06:29 2009 +0000
Home |
Main Index |
Thread Index |
Old Index