Module Name: src Committed By: ozaki-r Date: Wed Jul 6 08:42:34 UTC 2016
Modified Files: src/sys/net: if_stf.c src/sys/netinet: in.c in_gif.c in_pcb.c in_var.h ip_carp.c ip_icmp.c ip_input.c src/sys/netipsec: key.c Log Message: 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. To generate a diff of this commit: cvs rdiff -u -r1.93 -r1.94 src/sys/net/if_stf.c cvs rdiff -u -r1.170 -r1.171 src/sys/netinet/in.c cvs rdiff -u -r1.80 -r1.81 src/sys/netinet/in_gif.c cvs rdiff -u -r1.164 -r1.165 src/sys/netinet/in_pcb.c cvs rdiff -u -r1.75 -r1.76 src/sys/netinet/in_var.h cvs rdiff -u -r1.72 -r1.73 src/sys/netinet/ip_carp.c cvs rdiff -u -r1.147 -r1.148 src/sys/netinet/ip_icmp.c cvs rdiff -u -r1.334 -r1.335 src/sys/netinet/ip_input.c cvs rdiff -u -r1.98 -r1.99 src/sys/netipsec/key.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/net/if_stf.c diff -u src/sys/net/if_stf.c:1.93 src/sys/net/if_stf.c:1.94 --- src/sys/net/if_stf.c:1.93 Mon Jul 4 04:35:09 2016 +++ src/sys/net/if_stf.c Wed Jul 6 08:42:34 2016 @@ -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, con /* * 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) Index: src/sys/netinet/in.c diff -u src/sys/netinet/in.c:1.170 src/sys/netinet/in.c:1.171 --- src/sys/netinet/in.c:1.170 Wed Jul 6 05:27:52 2016 +++ src/sys/netinet/in.c Wed Jul 6 08:42:34 2016 @@ -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 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 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, i 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, st 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; } Index: src/sys/netinet/in_gif.c diff -u src/sys/netinet/in_gif.c:1.80 src/sys/netinet/in_gif.c:1.81 --- src/sys/netinet/in_gif.c:1.80 Wed Jul 6 01:10:07 2016 +++ src/sys/netinet/in_gif.c Wed Jul 6 08:42:34 2016 @@ -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, struc 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) Index: src/sys/netinet/in_pcb.c diff -u src/sys/netinet/in_pcb.c:1.164 src/sys/netinet/in_pcb.c:1.165 --- src/sys/netinet/in_pcb.c:1.164 Tue Jun 21 03:28:27 2016 +++ src/sys/netinet/in_pcb.c Wed Jul 6 08:42:34 2016 @@ -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 * 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_i 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_i */ 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; Index: src/sys/netinet/in_var.h diff -u src/sys/netinet/in_var.h:1.75 src/sys/netinet/in_var.h:1.76 --- src/sys/netinet/in_var.h:1.75 Wed Jul 6 05:27:52 2016 +++ src/sys/netinet/in_var.h Wed Jul 6 08:42:34 2016 @@ -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_ifaddrhe 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[]; /* Index: src/sys/netinet/ip_carp.c diff -u src/sys/netinet/ip_carp.c:1.72 src/sys/netinet/ip_carp.c:1.73 --- src/sys/netinet/ip_carp.c:1.72 Mon Jul 4 06:48:14 2016 +++ src/sys/netinet/ip_carp.c Wed Jul 6 08:42:34 2016 @@ -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, str /* 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 && Index: src/sys/netinet/ip_icmp.c diff -u src/sys/netinet/ip_icmp.c:1.147 src/sys/netinet/ip_icmp.c:1.148 --- src/sys/netinet/ip_icmp.c:1.147 Fri Jun 10 13:31:44 2016 +++ src/sys/netinet/ip_icmp.c Wed Jul 6 08:42:34 2016 @@ -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; Index: src/sys/netinet/ip_input.c diff -u src/sys/netinet/ip_input.c:1.334 src/sys/netinet/ip_input.c:1.335 --- src/sys/netinet/ip_input.c:1.334 Wed Jul 6 05:27:52 2016 +++ src/sys/netinet/ip_input.c Wed Jul 6 08:42:34 2016 @@ -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); /* Index: src/sys/netipsec/key.c diff -u src/sys/netipsec/key.c:1.98 src/sys/netipsec/key.c:1.99 --- src/sys/netipsec/key.c:1.98 Mon Jul 4 06:48:14 2016 +++ src/sys/netipsec/key.c Wed Jul 6 08:42:34 2016 @@ -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)