From owner-svn-src-head@FreeBSD.ORG Sun Jan 8 17:25:16 2012 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 67C681065676; Sun, 8 Jan 2012 17:25:16 +0000 (UTC) (envelope-from glebius@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 388E08FC0C; Sun, 8 Jan 2012 17:25:16 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q08HPGgA099767; Sun, 8 Jan 2012 17:25:16 GMT (envelope-from glebius@svn.freebsd.org) Received: (from glebius@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q08HPG3m099765; Sun, 8 Jan 2012 17:25:16 GMT (envelope-from glebius@svn.freebsd.org) Message-Id: <201201081725.q08HPG3m099765@svn.freebsd.org> From: Gleb Smirnoff Date: Sun, 8 Jan 2012 17:25:15 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r229816 - head/sys/netinet X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 08 Jan 2012 17:25:16 -0000 Author: glebius Date: Sun Jan 8 17:25:15 2012 New Revision: 229816 URL: http://svn.freebsd.org/changeset/base/229816 Log: Make it possible to use alternative source hardware address in the ARP datagram generated by arprequest(). If caller doesn't supply the address, then it is either picked from CARP or hardware address of the interface is taken. While here, make several minor fixes: - Hold IF_ADDR_RLOCK(ifp) while traversing address list. - Remove not true comment. - Access internet address and mask via in_ifaddr fields, rather than ifaddr. Modified: head/sys/netinet/if_ether.c Modified: head/sys/netinet/if_ether.c ============================================================================== --- head/sys/netinet/if_ether.c Sun Jan 8 17:20:29 2012 (r229815) +++ head/sys/netinet/if_ether.c Sun Jan 8 17:25:15 2012 (r229816) @@ -211,29 +211,41 @@ arprequest(struct ifnet *ifp, struct in_ struct mbuf *m; struct arphdr *ah; struct sockaddr sa; + u_char *carpaddr = NULL; if (sip == NULL) { - /* XXX don't believe this can happen (or explain why) */ /* * The caller did not supply a source address, try to find * a compatible one among those assigned to this interface. */ struct ifaddr *ifa; + IF_ADDR_RLOCK(ifp); TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { - if (!ifa->ifa_addr || - ifa->ifa_addr->sa_family != AF_INET) + if (ifa->ifa_addr->sa_family != AF_INET) continue; - sip = &SIN(ifa->ifa_addr)->sin_addr; + + if (ifa->ifa_carp) { + if ((*carp_iamatch_p)(ifa, &carpaddr) == 0) + continue; + sip = &IA_SIN(ifa)->sin_addr; + } else { + carpaddr = NULL; + sip = &IA_SIN(ifa)->sin_addr; + } + if (0 == ((sip->s_addr ^ tip->s_addr) & - SIN(ifa->ifa_netmask)->sin_addr.s_addr) ) + IA_MASKSIN(ifa)->sin_addr.s_addr)) break; /* found it. */ } + IF_ADDR_RUNLOCK(ifp); if (sip == NULL) { printf("%s: cannot find matching address\n", __func__); return; } } + if (enaddr == NULL) + enaddr = carpaddr ? carpaddr : (u_char *)IF_LLADDR(ifp); if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL) return; @@ -328,9 +340,7 @@ retry: */ if (!(la->la_flags & LLE_STATIC) && time_uptime + la->la_preempt > la->la_expire) { - arprequest(ifp, NULL, - &SIN(dst)->sin_addr, IF_LLADDR(ifp)); - + arprequest(ifp, NULL, &SIN(dst)->sin_addr, NULL); la->la_preempt--; } @@ -406,8 +416,7 @@ retry: LLE_REMREF(la); la->la_asked++; LLE_WUNLOCK(la); - arprequest(ifp, NULL, &SIN(dst)->sin_addr, - IF_LLADDR(ifp)); + arprequest(ifp, NULL, &SIN(dst)->sin_addr, NULL); return (error); } done: