summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorozaki-r <ozaki-r@NetBSD.org>2016-07-06 08:42:34 +0000
committerozaki-r <ozaki-r@NetBSD.org>2016-07-06 08:42:34 +0000
commit6bfa4b77fbeda0e4cf486fc71a04f90ef5e8d874 (patch)
tree0401f5e920d58f872a1f34e56d0d87994e398ef8 /sys
parent28c5e5242f5d58e51961ea05f738ec5b84febfac (diff)
Switch the IPv4 address list to pslist(9)
Note that we leave the old list just in case; it seems there are some kvm(3) users accessing the list. We can remove it later if we confirmed nobody does actually.
Diffstat (limited to 'sys')
-rw-r--r--sys/net/if_stf.c7
-rw-r--r--sys/netinet/in.c30
-rw-r--r--sys/netinet/in_gif.c6
-rw-r--r--sys/netinet/in_pcb.c13
-rw-r--r--sys/netinet/in_var.h53
-rw-r--r--sys/netinet/ip_carp.c8
-rw-r--r--sys/netinet/ip_icmp.c6
-rw-r--r--sys/netinet/ip_input.c7
-rw-r--r--sys/netipsec/key.c10
9 files changed, 98 insertions, 42 deletions
diff --git a/sys/net/if_stf.c b/sys/net/if_stf.c
index 87d89557217..c38815b8409 100644
--- a/sys/net/if_stf.c
+++ b/sys/net/if_stf.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_stf.c,v 1.93 2016/07/04 04:35:09 knakahara Exp $ */
+/* $NetBSD: if_stf.c,v 1.94 2016/07/06 08:42:34 ozaki-r Exp $ */
/* $KAME: if_stf.c,v 1.62 2001/06/07 22:32:16 itojun Exp $ */
/*
@@ -75,7 +75,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_stf.c,v 1.93 2016/07/04 04:35:09 knakahara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_stf.c,v 1.94 2016/07/06 08:42:34 ozaki-r Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@@ -488,8 +488,7 @@ stf_checkaddr4(struct stf_softc *sc, const struct in_addr *in,
/*
* reject packets with broadcast
*/
- TAILQ_FOREACH(ia4, &in_ifaddrhead, ia_list)
- {
+ IN_ADDRLIST_READER_FOREACH(ia4) {
if ((ia4->ia_ifa.ifa_ifp->if_flags & IFF_BROADCAST) == 0)
continue;
if (in->s_addr == ia4->ia_broadaddr.sin_addr.s_addr)
diff --git a/sys/netinet/in.c b/sys/netinet/in.c
index 842305d707a..dd538bac893 100644
--- a/sys/netinet/in.c
+++ b/sys/netinet/in.c
@@ -1,4 +1,4 @@
-/* $NetBSD: in.c,v 1.170 2016/07/06 05:27:52 ozaki-r Exp $ */
+/* $NetBSD: in.c,v 1.171 2016/07/06 08:42:34 ozaki-r Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -91,7 +91,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in.c,v 1.170 2016/07/06 05:27:52 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in.c,v 1.171 2016/07/06 08:42:34 ozaki-r Exp $");
#include "arp.h"
@@ -185,13 +185,14 @@ static krwlock_t in_multilock;
#define IN_MULTI_HASH(x, ifp) \
(in_multihashtbl[(u_long)((x) ^ (ifp->if_index)) % IN_MULTI_HASH_SIZE])
-/* XXX DEPRECATED. Keep it to avoid breaking kvm(3) users. */
+/* XXX DEPRECATED. Keep them to avoid breaking kvm(3) users. */
struct in_ifaddrhashhead * in_ifaddrhashtbl;
u_long in_ifaddrhash;
struct in_ifaddrhead in_ifaddrhead;
struct pslist_head * in_ifaddrhashtbl_pslist;
u_long in_ifaddrhash_pslist;
+struct pslist_head in_ifaddrhead_pslist;
void
in_init(void)
@@ -199,6 +200,7 @@ in_init(void)
pool_init(&inmulti_pool, sizeof(struct in_multi), 0, 0, 0, "inmltpl",
NULL, IPL_SOFTNET);
TAILQ_INIT(&in_ifaddrhead);
+ PSLIST_INIT(&in_ifaddrhead_pslist);
in_ifaddrhashtbl = hashinit(IN_IFADDR_HASH_SIZE, HASH_LIST, true,
&in_ifaddrhash);
@@ -223,13 +225,15 @@ in_localaddr(struct in_addr in)
struct in_ifaddr *ia;
if (subnetsarelocal) {
- TAILQ_FOREACH(ia, &in_ifaddrhead, ia_list)
+ IN_ADDRLIST_READER_FOREACH(ia) {
if ((in.s_addr & ia->ia_netmask) == ia->ia_net)
return (1);
+ }
} else {
- TAILQ_FOREACH(ia, &in_ifaddrhead, ia_list)
+ IN_ADDRLIST_READER_FOREACH(ia) {
if ((in.s_addr & ia->ia_subnetmask) == ia->ia_subnet)
return (1);
+ }
}
return (0);
}
@@ -304,7 +308,7 @@ in_setmaxmtu(void)
struct ifnet *ifp;
unsigned long maxmtu = 0;
- TAILQ_FOREACH(ia, &in_ifaddrhead, ia_list) {
+ IN_ADDRLIST_READER_FOREACH(ia) {
if ((ifp = ia->ia_ifp) == 0)
continue;
if ((ifp->if_flags & (IFF_UP|IFF_LOOPBACK)) != IFF_UP)
@@ -466,6 +470,7 @@ in_control(struct socket *so, u_long cmd, void *data, struct ifnet *ifp)
ia->ia_idsalt = cprng_fast32() % 65535;
LIST_INIT(&ia->ia_multiaddrs);
IN_ADDRHASH_ENTRY_INIT(ia);
+ IN_ADDRLIST_ENTRY_INIT(ia);
newifaddr = 1;
}
@@ -640,6 +645,8 @@ in_control(struct socket *so, u_long cmd, void *data, struct ifnet *ifp)
TAILQ_INSERT_TAIL(&in_ifaddrhead, ia, ia_list);
ifaref(&ia->ia_ifa);
ifa_insert(ifp, &ia->ia_ifa);
+ TAILQ_INSERT_TAIL(&in_ifaddrhead, ia, ia_list);
+ IN_ADDRLIST_WRITER_INSERT_TAIL(ia);
LIST_INSERT_HEAD(&IN_IFADDR_HASH(ia->ia_addr.sin_addr.s_addr),
ia, ia_hash);
IN_ADDRHASH_WRITER_INSERT_HEAD(ia);
@@ -690,7 +697,7 @@ in_ifremlocal(struct ifaddr *ifa)
ia = (struct in_ifaddr *)ifa;
/* Delete the entry if exactly one ifaddr matches the
* address, ifa->ifa_addr. */
- TAILQ_FOREACH(p, &in_ifaddrhead, ia_list) {
+ IN_ADDRLIST_READER_FOREACH(p) {
if (!in_hosteq(p->ia_addr.sin_addr, ia->ia_addr.sin_addr))
continue;
if (p->ia_ifp != ia->ia_ifp)
@@ -722,6 +729,9 @@ in_purgeaddr(struct ifaddr *ifa)
IN_ADDRHASH_ENTRY_DESTROY(ia);
ifa_remove(ifp, &ia->ia_ifa);
TAILQ_REMOVE(&in_ifaddrhead, ia, ia_list);
+ IN_ADDRLIST_WRITER_REMOVE(ia);
+ IN_ADDRLIST_ENTRY_DESTROY(ia);
+
if (ia->ia_allhosts != NULL)
in_delmulti(ia->ia_allhosts);
ifafree(&ia->ia_ifa);
@@ -1066,7 +1076,7 @@ in_addprefix(struct in_ifaddr *target, int flags)
prefix.s_addr &= mask.s_addr;
}
- TAILQ_FOREACH(ia, &in_ifaddrhead, ia_list) {
+ IN_ADDRLIST_READER_FOREACH(ia) {
if (rtinitflags(ia))
p = ia->ia_dstaddr.sin_addr;
else {
@@ -1126,7 +1136,7 @@ in_scrubprefix(struct in_ifaddr *target)
prefix.s_addr &= mask.s_addr;
}
- TAILQ_FOREACH(ia, &in_ifaddrhead, ia_list) {
+ IN_ADDRLIST_READER_FOREACH(ia) {
if (rtinitflags(ia))
p = ia->ia_dstaddr.sin_addr;
else {
@@ -1524,7 +1534,7 @@ in_selectsrc(struct sockaddr_in *sin, struct route *ro,
sin->sin_port = fport;
if (ia == NULL) {
/* Find 1st non-loopback AF_INET address */
- TAILQ_FOREACH(ia, &in_ifaddrhead, ia_list) {
+ IN_ADDRLIST_READER_FOREACH(ia) {
if (!(ia->ia_ifp->if_flags & IFF_LOOPBACK))
break;
}
diff --git a/sys/netinet/in_gif.c b/sys/netinet/in_gif.c
index f73ebbbc4e3..248dd1b0711 100644
--- a/sys/netinet/in_gif.c
+++ b/sys/netinet/in_gif.c
@@ -1,4 +1,4 @@
-/* $NetBSD: in_gif.c,v 1.80 2016/07/06 01:10:07 knakahara Exp $ */
+/* $NetBSD: in_gif.c,v 1.81 2016/07/06 08:42:34 ozaki-r Exp $ */
/* $KAME: in_gif.c,v 1.66 2001/07/29 04:46:09 itojun Exp $ */
/*
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in_gif.c,v 1.80 2016/07/06 01:10:07 knakahara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in_gif.c,v 1.81 2016/07/06 08:42:34 ozaki-r Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@@ -306,7 +306,7 @@ gif_validate4(const struct ip *ip, struct gif_softc *sc, struct ifnet *ifp)
return 0;
}
/* reject packets with broadcast on source */
- TAILQ_FOREACH(ia4, &in_ifaddrhead, ia_list) {
+ IN_ADDRLIST_READER_FOREACH(ia4) {
if ((ia4->ia_ifa.ifa_ifp->if_flags & IFF_BROADCAST) == 0)
continue;
if (ip->ip_src.s_addr == ia4->ia_broadaddr.sin_addr.s_addr)
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c
index 93b49e098b5..fab1a953d10 100644
--- a/sys/netinet/in_pcb.c
+++ b/sys/netinet/in_pcb.c
@@ -1,4 +1,4 @@
-/* $NetBSD: in_pcb.c,v 1.164 2016/06/21 03:28:27 ozaki-r Exp $ */
+/* $NetBSD: in_pcb.c,v 1.165 2016/07/06 08:42:34 ozaki-r Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -93,7 +93,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in_pcb.c,v 1.164 2016/06/21 03:28:27 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in_pcb.c,v 1.165 2016/07/06 08:42:34 ozaki-r Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@@ -411,7 +411,7 @@ in_pcbbind(void *v, struct sockaddr_in *sin, struct lwp *l)
if (inp->inp_af != AF_INET)
return (EINVAL);
- if (TAILQ_FIRST(&in_ifaddrhead) == 0)
+ if (IN_ADDRLIST_READER_EMPTY())
return (EADDRNOTAVAIL);
if (inp->inp_lport || !in_nullhost(inp->inp_laddr))
return (EINVAL);
@@ -470,7 +470,7 @@ in_pcbconnect(void *v, struct sockaddr_in *sin, struct lwp *l)
inp->inp_socket->so_type == SOCK_STREAM)
return EADDRNOTAVAIL;
- if (TAILQ_FIRST(&in_ifaddrhead) != 0) {
+ if (!IN_ADDRLIST_READER_EMPTY()) {
/*
* If the destination address is INADDR_ANY,
* use any local address (likely loopback).
@@ -480,10 +480,11 @@ in_pcbconnect(void *v, struct sockaddr_in *sin, struct lwp *l)
*/
if (in_nullhost(sin->sin_addr)) {
+ /* XXX racy */
sin->sin_addr =
- TAILQ_FIRST(&in_ifaddrhead)->ia_addr.sin_addr;
+ IN_ADDRLIST_READER_FIRST()->ia_addr.sin_addr;
} else if (sin->sin_addr.s_addr == INADDR_BROADCAST) {
- TAILQ_FOREACH(ia, &in_ifaddrhead, ia_list) {
+ IN_ADDRLIST_READER_FOREACH(ia) {
if (ia->ia_ifp->if_flags & IFF_BROADCAST) {
sin->sin_addr =
ia->ia_broadaddr.sin_addr;
diff --git a/sys/netinet/in_var.h b/sys/netinet/in_var.h
index eb5da1f902c..52bc07006f4 100644
--- a/sys/netinet/in_var.h
+++ b/sys/netinet/in_var.h
@@ -1,4 +1,4 @@
-/* $NetBSD: in_var.h,v 1.75 2016/07/06 05:27:52 ozaki-r Exp $ */
+/* $NetBSD: in_var.h,v 1.76 2016/07/06 08:42:34 ozaki-r Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -107,6 +107,7 @@ struct in_ifaddr {
#ifdef _KERNEL
struct pslist_entry ia_hash_pslist_entry;
+ struct pslist_entry ia_pslist_entry;
#endif
};
@@ -148,6 +149,7 @@ extern struct in_ifaddrhead in_ifaddrhead; /* List head (in ip_input) */
extern struct pslist_head *in_ifaddrhashtbl_pslist;
extern u_long in_ifaddrhash_pslist;
+extern struct pslist_head in_ifaddrhead_pslist;
#define IN_IFADDR_HASH_PSLIST(x) \
in_ifaddrhashtbl_pslist[(u_long)(x) % IN_IFADDR_HASH_SIZE]
@@ -166,6 +168,55 @@ extern u_long in_ifaddrhash_pslist;
#define IN_ADDRHASH_ENTRY_DESTROY(__ia) \
PSLIST_ENTRY_DESTROY((__ia), ia_hash_pslist_entry);
+#define IN_ADDRLIST_ENTRY_INIT(__ia) \
+ PSLIST_ENTRY_INIT((__ia), ia_pslist_entry)
+#define IN_ADDRLIST_ENTRY_DESTROY(__ia) \
+ PSLIST_ENTRY_DESTROY((__ia), ia_pslist_entry);
+#define IN_ADDRLIST_READER_EMPTY() \
+ (PSLIST_READER_FIRST(&in_ifaddrhead_pslist, struct in_ifaddr, \
+ ia_pslist_entry) == NULL)
+#define IN_ADDRLIST_READER_FIRST() \
+ PSLIST_READER_FIRST(&in_ifaddrhead_pslist, struct in_ifaddr, \
+ ia_pslist_entry)
+#define IN_ADDRLIST_READER_NEXT(__ia) \
+ PSLIST_READER_NEXT((__ia), struct in_ifaddr, ia_pslist_entry)
+#define IN_ADDRLIST_READER_FOREACH(__ia) \
+ PSLIST_READER_FOREACH((__ia), &in_ifaddrhead_pslist, \
+ struct in_ifaddr, ia_pslist_entry)
+#define IN_ADDRLIST_WRITER_INSERT_HEAD(__ia) \
+ PSLIST_WRITER_INSERT_HEAD(&in_ifaddrhead_pslist, (__ia), \
+ ia_pslist_entry)
+#define IN_ADDRLIST_WRITER_REMOVE(__ia) \
+ PSLIST_WRITER_REMOVE((__ia), ia_pslist_entry)
+#define IN_ADDRLIST_WRITER_FOREACH(__ia) \
+ PSLIST_WRITER_FOREACH((__ia), &in_ifaddrhead_pslist, \
+ struct in_ifaddr, ia_pslist_entry)
+#define IN_ADDRLIST_WRITER_FIRST() \
+ PSLIST_WRITER_FIRST(&in_ifaddrhead_pslist, struct in_ifaddr, \
+ ia_pslist_entry)
+#define IN_ADDRLIST_WRITER_NEXT(__ia) \
+ PSLIST_WRITER_NEXT((__ia), struct in_ifaddr, ia_pslist_entry)
+#define IN_ADDRLIST_WRITER_INSERT_AFTER(__ia, __new) \
+ PSLIST_WRITER_INSERT_AFTER((__ia), (__new), ia_pslist_entry)
+#define IN_ADDRLIST_WRITER_EMPTY() \
+ (PSLIST_WRITER_FIRST(&in_ifaddrhead_pslist, struct in_ifaddr, \
+ ia_pslist_entry) == NULL)
+#define IN_ADDRLIST_WRITER_INSERT_TAIL(__new) \
+ do { \
+ if (IN_ADDRLIST_WRITER_EMPTY()) { \
+ IN_ADDRLIST_WRITER_INSERT_HEAD((__new)); \
+ } else { \
+ struct in_ifaddr *__ia; \
+ IN_ADDRLIST_WRITER_FOREACH(__ia) { \
+ if (IN_ADDRLIST_WRITER_NEXT(__ia) == NULL) { \
+ IN_ADDRLIST_WRITER_INSERT_AFTER(__ia,\
+ (__new)); \
+ break; \
+ } \
+ } \
+ } \
+ } while (0)
+
extern const int inetctlerrmap[];
/*
diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c
index 9a6e1b7548a..807de8b1991 100644
--- a/sys/netinet/ip_carp.c
+++ b/sys/netinet/ip_carp.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ip_carp.c,v 1.72 2016/07/04 06:48:14 ozaki-r Exp $ */
+/* $NetBSD: ip_carp.c,v 1.73 2016/07/06 08:42:34 ozaki-r Exp $ */
/* $OpenBSD: ip_carp.c,v 1.113 2005/11/04 08:11:54 mcbride Exp $ */
/*
@@ -33,7 +33,7 @@
#endif
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip_carp.c,v 1.72 2016/07/04 06:48:14 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_carp.c,v 1.73 2016/07/06 08:42:34 ozaki-r Exp $");
/*
* TODO:
@@ -1735,9 +1735,7 @@ carp_set_addr(struct carp_softc *sc, struct sockaddr_in *sin)
/* we have to do this by hand to ensure we don't match on ourselves */
ia_if = NULL;
- for (ia = TAILQ_FIRST(&in_ifaddrhead); ia;
- ia = TAILQ_NEXT(ia, ia_list)) {
-
+ IN_ADDRLIST_READER_FOREACH(ia) {
/* and, yeah, we need a multicast-capable iface too */
if (ia->ia_ifp != &sc->sc_if &&
ia->ia_ifp->if_type != IFT_CARP &&
diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c
index 1f5ac5c11f3..f568ef93fd5 100644
--- a/sys/netinet/ip_icmp.c
+++ b/sys/netinet/ip_icmp.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ip_icmp.c,v 1.147 2016/06/10 13:31:44 ozaki-r Exp $ */
+/* $NetBSD: ip_icmp.c,v 1.148 2016/07/06 08:42:34 ozaki-r Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -94,7 +94,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip_icmp.c,v 1.147 2016/06/10 13:31:44 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_icmp.c,v 1.148 2016/07/06 08:42:34 ozaki-r Exp $");
#ifdef _KERNEL_OPT
#include "opt_ipsec.h"
@@ -793,7 +793,7 @@ icmp_reflect(struct mbuf *m)
* interface.
*/
if (sin == NULL)
- TAILQ_FOREACH(ia, &in_ifaddrhead, ia_list) {
+ IN_ADDRLIST_READER_FOREACH(ia) {
if (ia->ia_ifp->if_flags & IFF_LOOPBACK)
continue;
sin = &ia->ia_addr;
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index 87d776d7102..210e45d9e96 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ip_input.c,v 1.334 2016/07/06 05:27:52 ozaki-r Exp $ */
+/* $NetBSD: ip_input.c,v 1.335 2016/07/06 08:42:34 ozaki-r Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -91,7 +91,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.334 2016/07/06 05:27:52 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.335 2016/07/06 08:42:34 ozaki-r Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@@ -469,9 +469,8 @@ ip_input(struct mbuf *m)
* are receiving, can't do anything with incoming packets yet.
* Note: we pre-check without locks held.
*/
- if (!TAILQ_FIRST(&in_ifaddrhead)) {
+ if (IN_ADDRLIST_READER_EMPTY())
goto out;
- }
IP_STATINC(IP_STAT_TOTAL);
/*
diff --git a/sys/netipsec/key.c b/sys/netipsec/key.c
index 9d430c85e53..ec57c379aa0 100644
--- a/sys/netipsec/key.c
+++ b/sys/netipsec/key.c
@@ -1,4 +1,4 @@
-/* $NetBSD: key.c,v 1.98 2016/07/04 06:48:14 ozaki-r Exp $ */
+/* $NetBSD: key.c,v 1.99 2016/07/06 08:42:34 ozaki-r Exp $ */
/* $FreeBSD: src/sys/netipsec/key.c,v 1.3.2.3 2004/02/14 22:23:23 bms Exp $ */
/* $KAME: key.c,v 1.191 2001/06/27 10:46:49 sakane Exp $ */
@@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: key.c,v 1.98 2016/07/04 06:48:14 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: key.c,v 1.99 2016/07/06 08:42:34 ozaki-r Exp $");
/*
* This code is referd to RFC 2367
@@ -4116,7 +4116,7 @@ key_ismyaddr(const struct sockaddr *sa)
{
#ifdef INET
const struct sockaddr_in *sin;
- const struct in_ifaddr *ia;
+ struct in_ifaddr *ia;
#endif
/* sanity check */
@@ -4127,9 +4127,7 @@ key_ismyaddr(const struct sockaddr *sa)
#ifdef INET
case AF_INET:
sin = (const struct sockaddr_in *)sa;
- for (ia = in_ifaddrhead.tqh_first; ia;
- ia = ia->ia_link.tqe_next)
- {
+ IN_ADDRLIST_READER_FOREACH(ia) {
if (sin->sin_family == ia->ia_addr.sin_family &&
sin->sin_len == ia->ia_addr.sin_len &&
sin->sin_addr.s_addr == ia->ia_addr.sin_addr.s_addr)