mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
Use network epoch to protect local IPv4 addresses hash.
The modification to the hash are already naturally locked by in_control_sx. Convert the hash lists to CK lists. Remove the in_ifaddr_rmlock. Assert the network epoch where necessary. Most cases when the hash lookup is done the epoch is already entered. Cover a few cases, that need entering the epoch, which mostly is initial configuration of tunnel interfaces and multicast addresses. Reviewed by: melifaro Differential revision: https://reviews.freebsd.org/D32584
This commit is contained in:
parent
c242672339
commit
c8ee75f231
14 changed files with 69 additions and 102 deletions
|
|
@ -1014,6 +1014,7 @@ static int
|
||||||
ipsec_set_tunnel(struct ipsec_softc *sc, struct sockaddr *src,
|
ipsec_set_tunnel(struct ipsec_softc *sc, struct sockaddr *src,
|
||||||
struct sockaddr *dst, uint32_t reqid)
|
struct sockaddr *dst, uint32_t reqid)
|
||||||
{
|
{
|
||||||
|
struct epoch_tracker et;
|
||||||
struct secpolicy *sp[IPSEC_SPCOUNT];
|
struct secpolicy *sp[IPSEC_SPCOUNT];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
|
@ -1037,7 +1038,9 @@ ipsec_set_tunnel(struct ipsec_softc *sc, struct sockaddr *src,
|
||||||
sc->ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
|
sc->ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
|
||||||
return (ENOMEM);
|
return (ENOMEM);
|
||||||
}
|
}
|
||||||
|
NET_EPOCH_ENTER(et);
|
||||||
ipsec_set_running(sc);
|
ipsec_set_running(sc);
|
||||||
|
NET_EPOCH_EXIT(et);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -403,6 +403,7 @@ me_srcaddr(void *arg __unused, const struct sockaddr *sa,
|
||||||
static int
|
static int
|
||||||
me_set_tunnel(struct me_softc *sc, in_addr_t src, in_addr_t dst)
|
me_set_tunnel(struct me_softc *sc, in_addr_t src, in_addr_t dst)
|
||||||
{
|
{
|
||||||
|
struct epoch_tracker et;
|
||||||
struct me_softc *tmp;
|
struct me_softc *tmp;
|
||||||
|
|
||||||
sx_assert(&me_ioctl_sx, SA_XLOCKED);
|
sx_assert(&me_ioctl_sx, SA_XLOCKED);
|
||||||
|
|
@ -429,7 +430,9 @@ me_set_tunnel(struct me_softc *sc, in_addr_t src, in_addr_t dst)
|
||||||
CK_LIST_INSERT_HEAD(&ME_HASH(src, dst), sc, chain);
|
CK_LIST_INSERT_HEAD(&ME_HASH(src, dst), sc, chain);
|
||||||
CK_LIST_INSERT_HEAD(&ME_SRCHASH(src), sc, srchash);
|
CK_LIST_INSERT_HEAD(&ME_SRCHASH(src), sc, srchash);
|
||||||
|
|
||||||
|
NET_EPOCH_ENTER(et);
|
||||||
me_set_running(sc);
|
me_set_running(sc);
|
||||||
|
NET_EPOCH_EXIT(et);
|
||||||
if_link_state_change(ME2IFP(sc), LINK_STATE_UP);
|
if_link_state_change(ME2IFP(sc), LINK_STATE_UP);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,6 @@
|
||||||
#include <sys/module.h>
|
#include <sys/module.h>
|
||||||
#include <sys/proc.h>
|
#include <sys/proc.h>
|
||||||
#include <sys/queue.h>
|
#include <sys/queue.h>
|
||||||
#include <sys/rmlock.h>
|
|
||||||
#include <sys/sysctl.h>
|
#include <sys/sysctl.h>
|
||||||
#include <machine/cpu.h>
|
#include <machine/cpu.h>
|
||||||
|
|
||||||
|
|
@ -369,7 +368,6 @@ stf_encapcheck(const struct mbuf *m, int off, int proto, void *arg)
|
||||||
static int
|
static int
|
||||||
stf_getsrcifa6(struct ifnet *ifp, struct in6_addr *addr, struct in6_addr *mask)
|
stf_getsrcifa6(struct ifnet *ifp, struct in6_addr *addr, struct in6_addr *mask)
|
||||||
{
|
{
|
||||||
struct rm_priotracker in_ifa_tracker;
|
|
||||||
struct ifaddr *ia;
|
struct ifaddr *ia;
|
||||||
struct in_ifaddr *ia4;
|
struct in_ifaddr *ia4;
|
||||||
struct in6_ifaddr *ia6;
|
struct in6_ifaddr *ia6;
|
||||||
|
|
@ -386,11 +384,9 @@ stf_getsrcifa6(struct ifnet *ifp, struct in6_addr *addr, struct in6_addr *mask)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
bcopy(GET_V4(&sin6->sin6_addr), &in, sizeof(in));
|
bcopy(GET_V4(&sin6->sin6_addr), &in, sizeof(in));
|
||||||
IN_IFADDR_RLOCK(&in_ifa_tracker);
|
CK_LIST_FOREACH(ia4, INADDR_HASH(in.s_addr), ia_hash)
|
||||||
LIST_FOREACH(ia4, INADDR_HASH(in.s_addr), ia_hash)
|
|
||||||
if (ia4->ia_addr.sin_addr.s_addr == in.s_addr)
|
if (ia4->ia_addr.sin_addr.s_addr == in.s_addr)
|
||||||
break;
|
break;
|
||||||
IN_IFADDR_RUNLOCK(&in_ifa_tracker);
|
|
||||||
if (ia4 == NULL)
|
if (ia4 == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,6 @@ __FBSDID("$FreeBSD$");
|
||||||
#include <sys/mbuf.h>
|
#include <sys/mbuf.h>
|
||||||
#include <sys/malloc.h>
|
#include <sys/malloc.h>
|
||||||
#include <sys/proc.h>
|
#include <sys/proc.h>
|
||||||
#include <sys/rmlock.h>
|
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/syslog.h>
|
#include <sys/syslog.h>
|
||||||
|
|
||||||
|
|
@ -779,7 +778,6 @@ SYSCTL_INT(_net_link_ether_inet, OID_AUTO, allow_multicast, CTLFLAG_RW,
|
||||||
static void
|
static void
|
||||||
in_arpinput(struct mbuf *m)
|
in_arpinput(struct mbuf *m)
|
||||||
{
|
{
|
||||||
struct rm_priotracker in_ifa_tracker;
|
|
||||||
struct arphdr *ah;
|
struct arphdr *ah;
|
||||||
struct ifnet *ifp = m->m_pkthdr.rcvif;
|
struct ifnet *ifp = m->m_pkthdr.rcvif;
|
||||||
struct llentry *la = NULL, *la_tmp;
|
struct llentry *la = NULL, *la_tmp;
|
||||||
|
|
@ -846,24 +844,21 @@ in_arpinput(struct mbuf *m)
|
||||||
* of the receive interface. (This will change slightly
|
* of the receive interface. (This will change slightly
|
||||||
* when we have clusters of interfaces).
|
* when we have clusters of interfaces).
|
||||||
*/
|
*/
|
||||||
IN_IFADDR_RLOCK(&in_ifa_tracker);
|
CK_LIST_FOREACH(ia, INADDR_HASH(itaddr.s_addr), ia_hash) {
|
||||||
LIST_FOREACH(ia, INADDR_HASH(itaddr.s_addr), ia_hash) {
|
|
||||||
if (((bridged && ia->ia_ifp->if_bridge == ifp->if_bridge) ||
|
if (((bridged && ia->ia_ifp->if_bridge == ifp->if_bridge) ||
|
||||||
ia->ia_ifp == ifp) &&
|
ia->ia_ifp == ifp) &&
|
||||||
itaddr.s_addr == ia->ia_addr.sin_addr.s_addr &&
|
itaddr.s_addr == ia->ia_addr.sin_addr.s_addr &&
|
||||||
(ia->ia_ifa.ifa_carp == NULL ||
|
(ia->ia_ifa.ifa_carp == NULL ||
|
||||||
(*carp_iamatch_p)(&ia->ia_ifa, &enaddr))) {
|
(*carp_iamatch_p)(&ia->ia_ifa, &enaddr))) {
|
||||||
ifa_ref(&ia->ia_ifa);
|
ifa_ref(&ia->ia_ifa);
|
||||||
IN_IFADDR_RUNLOCK(&in_ifa_tracker);
|
|
||||||
goto match;
|
goto match;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LIST_FOREACH(ia, INADDR_HASH(isaddr.s_addr), ia_hash)
|
CK_LIST_FOREACH(ia, INADDR_HASH(isaddr.s_addr), ia_hash)
|
||||||
if (((bridged && ia->ia_ifp->if_bridge == ifp->if_bridge) ||
|
if (((bridged && ia->ia_ifp->if_bridge == ifp->if_bridge) ||
|
||||||
ia->ia_ifp == ifp) &&
|
ia->ia_ifp == ifp) &&
|
||||||
isaddr.s_addr == ia->ia_addr.sin_addr.s_addr) {
|
isaddr.s_addr == ia->ia_addr.sin_addr.s_addr) {
|
||||||
ifa_ref(&ia->ia_ifa);
|
ifa_ref(&ia->ia_ifa);
|
||||||
IN_IFADDR_RUNLOCK(&in_ifa_tracker);
|
|
||||||
goto match;
|
goto match;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -878,17 +873,15 @@ in_arpinput(struct mbuf *m)
|
||||||
* meant to be destined to the bridge member.
|
* meant to be destined to the bridge member.
|
||||||
*/
|
*/
|
||||||
if (is_bridge) {
|
if (is_bridge) {
|
||||||
LIST_FOREACH(ia, INADDR_HASH(itaddr.s_addr), ia_hash) {
|
CK_LIST_FOREACH(ia, INADDR_HASH(itaddr.s_addr), ia_hash) {
|
||||||
if (BDG_MEMBER_MATCHES_ARP(itaddr.s_addr, ifp, ia)) {
|
if (BDG_MEMBER_MATCHES_ARP(itaddr.s_addr, ifp, ia)) {
|
||||||
ifa_ref(&ia->ia_ifa);
|
ifa_ref(&ia->ia_ifa);
|
||||||
ifp = ia->ia_ifp;
|
ifp = ia->ia_ifp;
|
||||||
IN_IFADDR_RUNLOCK(&in_ifa_tracker);
|
|
||||||
goto match;
|
goto match;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#undef BDG_MEMBER_MATCHES_ARP
|
#undef BDG_MEMBER_MATCHES_ARP
|
||||||
IN_IFADDR_RUNLOCK(&in_ifa_tracker);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* No match, use the first inet address on the receive interface
|
* No match, use the first inet address on the receive interface
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,6 @@ __FBSDID("$FreeBSD$");
|
||||||
#include <sys/kernel.h>
|
#include <sys/kernel.h>
|
||||||
#include <sys/lock.h>
|
#include <sys/lock.h>
|
||||||
#include <sys/proc.h>
|
#include <sys/proc.h>
|
||||||
#include <sys/rmlock.h>
|
|
||||||
#include <sys/sysctl.h>
|
#include <sys/sysctl.h>
|
||||||
#include <sys/syslog.h>
|
#include <sys/syslog.h>
|
||||||
#include <sys/sx.h>
|
#include <sys/sx.h>
|
||||||
|
|
@ -124,21 +123,18 @@ in_localaddr(struct in_addr in)
|
||||||
* Return 1 if an internet address is for the local host and configured
|
* Return 1 if an internet address is for the local host and configured
|
||||||
* on one of its interfaces.
|
* on one of its interfaces.
|
||||||
*/
|
*/
|
||||||
int
|
bool
|
||||||
in_localip(struct in_addr in)
|
in_localip(struct in_addr in)
|
||||||
{
|
{
|
||||||
struct rm_priotracker in_ifa_tracker;
|
|
||||||
struct in_ifaddr *ia;
|
struct in_ifaddr *ia;
|
||||||
|
|
||||||
IN_IFADDR_RLOCK(&in_ifa_tracker);
|
NET_EPOCH_ASSERT();
|
||||||
LIST_FOREACH(ia, INADDR_HASH(in.s_addr), ia_hash) {
|
|
||||||
if (IA_SIN(ia)->sin_addr.s_addr == in.s_addr) {
|
CK_LIST_FOREACH(ia, INADDR_HASH(in.s_addr), ia_hash)
|
||||||
IN_IFADDR_RUNLOCK(&in_ifa_tracker);
|
if (IA_SIN(ia)->sin_addr.s_addr == in.s_addr)
|
||||||
return (1);
|
return (true);
|
||||||
}
|
|
||||||
}
|
return (false);
|
||||||
IN_IFADDR_RUNLOCK(&in_ifa_tracker);
|
|
||||||
return (0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -170,24 +166,24 @@ in_ifhasaddr(struct ifnet *ifp, struct in_addr in)
|
||||||
static struct in_ifaddr *
|
static struct in_ifaddr *
|
||||||
in_localip_more(struct in_ifaddr *original_ia)
|
in_localip_more(struct in_ifaddr *original_ia)
|
||||||
{
|
{
|
||||||
struct rm_priotracker in_ifa_tracker;
|
struct epoch_tracker et;
|
||||||
in_addr_t original_addr = IA_SIN(original_ia)->sin_addr.s_addr;
|
in_addr_t original_addr = IA_SIN(original_ia)->sin_addr.s_addr;
|
||||||
uint32_t original_fib = original_ia->ia_ifa.ifa_ifp->if_fib;
|
uint32_t original_fib = original_ia->ia_ifa.ifa_ifp->if_fib;
|
||||||
struct in_ifaddr *ia;
|
struct in_ifaddr *ia;
|
||||||
|
|
||||||
IN_IFADDR_RLOCK(&in_ifa_tracker);
|
NET_EPOCH_ENTER(et);
|
||||||
LIST_FOREACH(ia, INADDR_HASH(original_addr), ia_hash) {
|
CK_LIST_FOREACH(ia, INADDR_HASH(original_addr), ia_hash) {
|
||||||
in_addr_t addr = IA_SIN(ia)->sin_addr.s_addr;
|
in_addr_t addr = IA_SIN(ia)->sin_addr.s_addr;
|
||||||
uint32_t fib = ia->ia_ifa.ifa_ifp->if_fib;
|
uint32_t fib = ia->ia_ifa.ifa_ifp->if_fib;
|
||||||
if (!V_rt_add_addr_allfibs && (original_fib != fib))
|
if (!V_rt_add_addr_allfibs && (original_fib != fib))
|
||||||
continue;
|
continue;
|
||||||
if ((original_ia != ia) && (original_addr == addr)) {
|
if ((original_ia != ia) && (original_addr == addr)) {
|
||||||
ifa_ref(&ia->ia_ifa);
|
ifa_ref(&ia->ia_ifa);
|
||||||
IN_IFADDR_RUNLOCK(&in_ifa_tracker);
|
NET_EPOCH_EXIT(et);
|
||||||
return (ia);
|
return (ia);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IN_IFADDR_RUNLOCK(&in_ifa_tracker);
|
NET_EPOCH_EXIT(et);
|
||||||
|
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
@ -500,10 +496,10 @@ in_aifaddr_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, struct thread *td)
|
||||||
IF_ADDR_WUNLOCK(ifp);
|
IF_ADDR_WUNLOCK(ifp);
|
||||||
|
|
||||||
ifa_ref(ifa); /* in_ifaddrhead */
|
ifa_ref(ifa); /* in_ifaddrhead */
|
||||||
IN_IFADDR_WLOCK();
|
sx_assert(&in_control_sx, SA_XLOCKED);
|
||||||
CK_STAILQ_INSERT_TAIL(&V_in_ifaddrhead, ia, ia_link);
|
CK_STAILQ_INSERT_TAIL(&V_in_ifaddrhead, ia, ia_link);
|
||||||
LIST_INSERT_HEAD(INADDR_HASH(ia->ia_addr.sin_addr.s_addr), ia, ia_hash);
|
CK_LIST_INSERT_HEAD(INADDR_HASH(ia->ia_addr.sin_addr.s_addr), ia,
|
||||||
IN_IFADDR_WUNLOCK();
|
ia_hash);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Give the interface a chance to initialize
|
* Give the interface a chance to initialize
|
||||||
|
|
@ -575,10 +571,9 @@ fail1:
|
||||||
IF_ADDR_WUNLOCK(ifp);
|
IF_ADDR_WUNLOCK(ifp);
|
||||||
ifa_free(&ia->ia_ifa); /* if_addrhead */
|
ifa_free(&ia->ia_ifa); /* if_addrhead */
|
||||||
|
|
||||||
IN_IFADDR_WLOCK();
|
sx_assert(&in_control_sx, SA_XLOCKED);
|
||||||
CK_STAILQ_REMOVE(&V_in_ifaddrhead, ia, in_ifaddr, ia_link);
|
CK_STAILQ_REMOVE(&V_in_ifaddrhead, ia, in_ifaddr, ia_link);
|
||||||
LIST_REMOVE(ia, ia_hash);
|
CK_LIST_REMOVE(ia, ia_hash);
|
||||||
IN_IFADDR_WUNLOCK();
|
|
||||||
ifa_free(&ia->ia_ifa); /* in_ifaddrhead */
|
ifa_free(&ia->ia_ifa); /* in_ifaddrhead */
|
||||||
|
|
||||||
return (error);
|
return (error);
|
||||||
|
|
@ -639,10 +634,9 @@ in_difaddr_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, struct thread *td)
|
||||||
IF_ADDR_WUNLOCK(ifp);
|
IF_ADDR_WUNLOCK(ifp);
|
||||||
ifa_free(&ia->ia_ifa); /* if_addrhead */
|
ifa_free(&ia->ia_ifa); /* if_addrhead */
|
||||||
|
|
||||||
IN_IFADDR_WLOCK();
|
sx_assert(&in_control_sx, SA_XLOCKED);
|
||||||
CK_STAILQ_REMOVE(&V_in_ifaddrhead, ia, in_ifaddr, ia_link);
|
CK_STAILQ_REMOVE(&V_in_ifaddrhead, ia, in_ifaddr, ia_link);
|
||||||
LIST_REMOVE(ia, ia_hash);
|
CK_LIST_REMOVE(ia, ia_hash);
|
||||||
IN_IFADDR_WUNLOCK();
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* in_scrubprefix() kills the interface route.
|
* in_scrubprefix() kills the interface route.
|
||||||
|
|
|
||||||
|
|
@ -649,7 +649,7 @@ int in_broadcast(struct in_addr, struct ifnet *);
|
||||||
int in_ifaddr_broadcast(struct in_addr, struct in_ifaddr *);
|
int in_ifaddr_broadcast(struct in_addr, struct in_ifaddr *);
|
||||||
int in_canforward(struct in_addr);
|
int in_canforward(struct in_addr);
|
||||||
int in_localaddr(struct in_addr);
|
int in_localaddr(struct in_addr);
|
||||||
int in_localip(struct in_addr);
|
bool in_localip(struct in_addr);
|
||||||
int in_ifhasaddr(struct ifnet *, struct in_addr);
|
int in_ifhasaddr(struct ifnet *, struct in_addr);
|
||||||
struct in_ifaddr *in_findlocal(uint32_t, bool);
|
struct in_ifaddr *in_findlocal(uint32_t, bool);
|
||||||
int inet_aton(const char *, struct in_addr *); /* in libkern */
|
int inet_aton(const char *, struct in_addr *); /* in libkern */
|
||||||
|
|
|
||||||
|
|
@ -90,9 +90,9 @@ in_show_in_ifaddr(struct in_ifaddr *ia)
|
||||||
IA_DB_RPINTF_PTR("%p", ia_ifa);
|
IA_DB_RPINTF_PTR("%p", ia_ifa);
|
||||||
IA_DB_RPINTF("0x%08lx", ia_subnet);
|
IA_DB_RPINTF("0x%08lx", ia_subnet);
|
||||||
IA_DB_RPINTF("0x%08lx", ia_subnetmask);
|
IA_DB_RPINTF("0x%08lx", ia_subnetmask);
|
||||||
IA_DB_RPINTF("%p", ia_hash.le_next);
|
IA_DB_RPINTF("%p", ia_hash.cle_next);
|
||||||
IA_DB_RPINTF("%p", ia_hash.le_prev);
|
IA_DB_RPINTF("%p", ia_hash.cle_prev);
|
||||||
IA_DB_RPINTF_DPTR("%p", ia_hash.le_prev);
|
IA_DB_RPINTF_DPTR("%p", ia_hash.cle_prev);
|
||||||
IA_DB_RPINTF("%p", ia_link.cstqe_next);
|
IA_DB_RPINTF("%p", ia_link.cstqe_next);
|
||||||
IA_DB_RPINTF_PTR("%p", ia_addr);
|
IA_DB_RPINTF_PTR("%p", ia_addr);
|
||||||
IA_DB_RPINTF_PTR("%p", ia_dstaddr);
|
IA_DB_RPINTF_PTR("%p", ia_dstaddr);
|
||||||
|
|
|
||||||
|
|
@ -196,6 +196,7 @@ int
|
||||||
in_gif_ioctl(struct gif_softc *sc, u_long cmd, caddr_t data)
|
in_gif_ioctl(struct gif_softc *sc, u_long cmd, caddr_t data)
|
||||||
{
|
{
|
||||||
struct ifreq *ifr = (struct ifreq *)data;
|
struct ifreq *ifr = (struct ifreq *)data;
|
||||||
|
struct epoch_tracker et;
|
||||||
struct sockaddr_in *dst, *src;
|
struct sockaddr_in *dst, *src;
|
||||||
struct ip *ip;
|
struct ip *ip;
|
||||||
int error;
|
int error;
|
||||||
|
|
@ -245,7 +246,9 @@ in_gif_ioctl(struct gif_softc *sc, u_long cmd, caddr_t data)
|
||||||
sc->gif_family = AF_INET;
|
sc->gif_family = AF_INET;
|
||||||
sc->gif_iphdr = ip;
|
sc->gif_iphdr = ip;
|
||||||
in_gif_attach(sc);
|
in_gif_attach(sc);
|
||||||
|
NET_EPOCH_ENTER(et);
|
||||||
in_gif_set_running(sc);
|
in_gif_set_running(sc);
|
||||||
|
NET_EPOCH_EXIT(et);
|
||||||
break;
|
break;
|
||||||
case SIOCGIFPSRCADDR:
|
case SIOCGIFPSRCADDR:
|
||||||
case SIOCGIFPDSTADDR:
|
case SIOCGIFPDSTADDR:
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,6 @@ __FBSDID("$FreeBSD$");
|
||||||
#include <sys/malloc.h>
|
#include <sys/malloc.h>
|
||||||
#include <sys/mbuf.h>
|
#include <sys/mbuf.h>
|
||||||
#include <sys/protosw.h>
|
#include <sys/protosw.h>
|
||||||
#include <sys/rmlock.h>
|
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/socketvar.h>
|
#include <sys/socketvar.h>
|
||||||
#include <sys/protosw.h>
|
#include <sys/protosw.h>
|
||||||
|
|
@ -1378,7 +1377,6 @@ static int
|
||||||
inp_block_unblock_source(struct inpcb *inp, struct sockopt *sopt)
|
inp_block_unblock_source(struct inpcb *inp, struct sockopt *sopt)
|
||||||
{
|
{
|
||||||
struct group_source_req gsr;
|
struct group_source_req gsr;
|
||||||
struct rm_priotracker in_ifa_tracker;
|
|
||||||
sockunion_t *gsa, *ssa;
|
sockunion_t *gsa, *ssa;
|
||||||
struct ifnet *ifp;
|
struct ifnet *ifp;
|
||||||
struct in_mfilter *imf;
|
struct in_mfilter *imf;
|
||||||
|
|
@ -1416,9 +1414,12 @@ inp_block_unblock_source(struct inpcb *inp, struct sockopt *sopt)
|
||||||
ssa->sin.sin_addr = mreqs.imr_sourceaddr;
|
ssa->sin.sin_addr = mreqs.imr_sourceaddr;
|
||||||
|
|
||||||
if (!in_nullhost(mreqs.imr_interface)) {
|
if (!in_nullhost(mreqs.imr_interface)) {
|
||||||
IN_IFADDR_RLOCK(&in_ifa_tracker);
|
struct epoch_tracker et;
|
||||||
|
|
||||||
|
NET_EPOCH_ENTER(et);
|
||||||
INADDR_TO_IFP(mreqs.imr_interface, ifp);
|
INADDR_TO_IFP(mreqs.imr_interface, ifp);
|
||||||
IN_IFADDR_RUNLOCK(&in_ifa_tracker);
|
/* XXXGL: ifref? */
|
||||||
|
NET_EPOCH_EXIT(et);
|
||||||
}
|
}
|
||||||
if (sopt->sopt_name == IP_BLOCK_SOURCE)
|
if (sopt->sopt_name == IP_BLOCK_SOURCE)
|
||||||
doblock = 1;
|
doblock = 1;
|
||||||
|
|
@ -1871,7 +1872,6 @@ static struct ifnet *
|
||||||
inp_lookup_mcast_ifp(const struct inpcb *inp,
|
inp_lookup_mcast_ifp(const struct inpcb *inp,
|
||||||
const struct sockaddr_in *gsin, const struct in_addr ina)
|
const struct sockaddr_in *gsin, const struct in_addr ina)
|
||||||
{
|
{
|
||||||
struct rm_priotracker in_ifa_tracker;
|
|
||||||
struct ifnet *ifp;
|
struct ifnet *ifp;
|
||||||
struct nhop_object *nh;
|
struct nhop_object *nh;
|
||||||
|
|
||||||
|
|
@ -1883,11 +1883,9 @@ inp_lookup_mcast_ifp(const struct inpcb *inp,
|
||||||
|
|
||||||
ifp = NULL;
|
ifp = NULL;
|
||||||
if (!in_nullhost(ina)) {
|
if (!in_nullhost(ina)) {
|
||||||
IN_IFADDR_RLOCK(&in_ifa_tracker);
|
|
||||||
INADDR_TO_IFP(ina, ifp);
|
INADDR_TO_IFP(ina, ifp);
|
||||||
if (ifp != NULL)
|
if (ifp != NULL)
|
||||||
if_ref(ifp);
|
if_ref(ifp);
|
||||||
IN_IFADDR_RUNLOCK(&in_ifa_tracker);
|
|
||||||
} else {
|
} else {
|
||||||
nh = fib4_lookup(inp->inp_inc.inc_fibnum, gsin->sin_addr, 0, NHR_NONE, 0);
|
nh = fib4_lookup(inp->inp_inc.inc_fibnum, gsin->sin_addr, 0, NHR_NONE, 0);
|
||||||
if (nh != NULL) {
|
if (nh != NULL) {
|
||||||
|
|
@ -2247,7 +2245,6 @@ inp_leave_group(struct inpcb *inp, struct sockopt *sopt)
|
||||||
{
|
{
|
||||||
struct group_source_req gsr;
|
struct group_source_req gsr;
|
||||||
struct ip_mreq_source mreqs;
|
struct ip_mreq_source mreqs;
|
||||||
struct rm_priotracker in_ifa_tracker;
|
|
||||||
sockunion_t *gsa, *ssa;
|
sockunion_t *gsa, *ssa;
|
||||||
struct ifnet *ifp;
|
struct ifnet *ifp;
|
||||||
struct in_mfilter *imf;
|
struct in_mfilter *imf;
|
||||||
|
|
@ -2307,9 +2304,12 @@ inp_leave_group(struct inpcb *inp, struct sockopt *sopt)
|
||||||
* using an IPv4 address as a key is racy.
|
* using an IPv4 address as a key is racy.
|
||||||
*/
|
*/
|
||||||
if (!in_nullhost(mreqs.imr_interface)) {
|
if (!in_nullhost(mreqs.imr_interface)) {
|
||||||
IN_IFADDR_RLOCK(&in_ifa_tracker);
|
struct epoch_tracker et;
|
||||||
|
|
||||||
|
NET_EPOCH_ENTER(et);
|
||||||
INADDR_TO_IFP(mreqs.imr_interface, ifp);
|
INADDR_TO_IFP(mreqs.imr_interface, ifp);
|
||||||
IN_IFADDR_RUNLOCK(&in_ifa_tracker);
|
/* XXXGL ifref? */
|
||||||
|
NET_EPOCH_EXIT(et);
|
||||||
}
|
}
|
||||||
CTR3(KTR_IGMPV3, "%s: imr_interface = 0x%08x, ifp = %p",
|
CTR3(KTR_IGMPV3, "%s: imr_interface = 0x%08x, ifp = %p",
|
||||||
__func__, ntohl(mreqs.imr_interface.s_addr), ifp);
|
__func__, ntohl(mreqs.imr_interface.s_addr), ifp);
|
||||||
|
|
@ -2465,7 +2465,6 @@ out_inp_locked:
|
||||||
static int
|
static int
|
||||||
inp_set_multicast_if(struct inpcb *inp, struct sockopt *sopt)
|
inp_set_multicast_if(struct inpcb *inp, struct sockopt *sopt)
|
||||||
{
|
{
|
||||||
struct rm_priotracker in_ifa_tracker;
|
|
||||||
struct in_addr addr;
|
struct in_addr addr;
|
||||||
struct ip_mreqn mreqn;
|
struct ip_mreqn mreqn;
|
||||||
struct ifnet *ifp;
|
struct ifnet *ifp;
|
||||||
|
|
@ -2504,9 +2503,12 @@ inp_set_multicast_if(struct inpcb *inp, struct sockopt *sopt)
|
||||||
if (in_nullhost(addr)) {
|
if (in_nullhost(addr)) {
|
||||||
ifp = NULL;
|
ifp = NULL;
|
||||||
} else {
|
} else {
|
||||||
IN_IFADDR_RLOCK(&in_ifa_tracker);
|
struct epoch_tracker et;
|
||||||
|
|
||||||
|
NET_EPOCH_ENTER(et);
|
||||||
INADDR_TO_IFP(addr, ifp);
|
INADDR_TO_IFP(addr, ifp);
|
||||||
IN_IFADDR_RUNLOCK(&in_ifa_tracker);
|
/* XXXGL ifref? */
|
||||||
|
NET_EPOCH_EXIT(et);
|
||||||
if (ifp == NULL)
|
if (ifp == NULL)
|
||||||
return (EADDRNOTAVAIL);
|
return (EADDRNOTAVAIL);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ struct in_ifaddr {
|
||||||
/* ia_subnet{,mask} in host order */
|
/* ia_subnet{,mask} in host order */
|
||||||
u_long ia_subnet; /* subnet address */
|
u_long ia_subnet; /* subnet address */
|
||||||
u_long ia_subnetmask; /* mask of subnet */
|
u_long ia_subnetmask; /* mask of subnet */
|
||||||
LIST_ENTRY(in_ifaddr) ia_hash; /* entry in bucket of inet addresses */
|
CK_LIST_ENTRY(in_ifaddr) ia_hash; /* hash of internet addresses */
|
||||||
CK_STAILQ_ENTRY(in_ifaddr) ia_link; /* list of internet addresses */
|
CK_STAILQ_ENTRY(in_ifaddr) ia_link; /* list of internet addresses */
|
||||||
struct sockaddr_in ia_addr; /* reserve space for interface name */
|
struct sockaddr_in ia_addr; /* reserve space for interface name */
|
||||||
struct sockaddr_in ia_dstaddr; /* reserve space for broadcast addr */
|
struct sockaddr_in ia_dstaddr; /* reserve space for broadcast addr */
|
||||||
|
|
@ -108,7 +108,7 @@ extern u_char inetctlerrmap[];
|
||||||
* Hash table for IP addresses.
|
* Hash table for IP addresses.
|
||||||
*/
|
*/
|
||||||
CK_STAILQ_HEAD(in_ifaddrhead, in_ifaddr);
|
CK_STAILQ_HEAD(in_ifaddrhead, in_ifaddr);
|
||||||
LIST_HEAD(in_ifaddrhashhead, in_ifaddr);
|
CK_LIST_HEAD(in_ifaddrhashhead, in_ifaddr);
|
||||||
|
|
||||||
VNET_DECLARE(struct in_ifaddrhashhead *, in_ifaddrhashtbl);
|
VNET_DECLARE(struct in_ifaddrhashhead *, in_ifaddrhashtbl);
|
||||||
VNET_DECLARE(struct in_ifaddrhead, in_ifaddrhead);
|
VNET_DECLARE(struct in_ifaddrhead, in_ifaddrhead);
|
||||||
|
|
@ -124,16 +124,6 @@ VNET_DECLARE(u_long, in_ifaddrhmask); /* mask for hash table */
|
||||||
#define INADDR_HASH(x) \
|
#define INADDR_HASH(x) \
|
||||||
(&V_in_ifaddrhashtbl[INADDR_HASHVAL(x) & V_in_ifaddrhmask])
|
(&V_in_ifaddrhashtbl[INADDR_HASHVAL(x) & V_in_ifaddrhmask])
|
||||||
|
|
||||||
extern struct rmlock in_ifaddr_lock;
|
|
||||||
|
|
||||||
#define IN_IFADDR_LOCK_ASSERT() rm_assert(&in_ifaddr_lock, RA_LOCKED)
|
|
||||||
#define IN_IFADDR_RLOCK(t) rm_rlock(&in_ifaddr_lock, (t))
|
|
||||||
#define IN_IFADDR_RLOCK_ASSERT() rm_assert(&in_ifaddr_lock, RA_RLOCKED)
|
|
||||||
#define IN_IFADDR_RUNLOCK(t) rm_runlock(&in_ifaddr_lock, (t))
|
|
||||||
#define IN_IFADDR_WLOCK() rm_wlock(&in_ifaddr_lock)
|
|
||||||
#define IN_IFADDR_WLOCK_ASSERT() rm_assert(&in_ifaddr_lock, RA_WLOCKED)
|
|
||||||
#define IN_IFADDR_WUNLOCK() rm_wunlock(&in_ifaddr_lock)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Macro for finding the internet address structure (in_ifaddr)
|
* Macro for finding the internet address structure (in_ifaddr)
|
||||||
* corresponding to one of our IP addresses (in_addr).
|
* corresponding to one of our IP addresses (in_addr).
|
||||||
|
|
@ -141,11 +131,11 @@ extern struct rmlock in_ifaddr_lock;
|
||||||
#define INADDR_TO_IFADDR(addr, ia) \
|
#define INADDR_TO_IFADDR(addr, ia) \
|
||||||
/* struct in_addr addr; */ \
|
/* struct in_addr addr; */ \
|
||||||
/* struct in_ifaddr *ia; */ \
|
/* struct in_ifaddr *ia; */ \
|
||||||
do { \
|
do { \
|
||||||
\
|
NET_EPOCH_ASSERT(); \
|
||||||
LIST_FOREACH(ia, INADDR_HASH((addr).s_addr), ia_hash) \
|
CK_LIST_FOREACH(ia, INADDR_HASH((addr).s_addr), ia_hash) \
|
||||||
if (IA_SIN(ia)->sin_addr.s_addr == (addr).s_addr) \
|
if (IA_SIN(ia)->sin_addr.s_addr == (addr).s_addr) \
|
||||||
break; \
|
break; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -363,6 +363,7 @@ fail:
|
||||||
static int
|
static int
|
||||||
in_gre_attach(struct gre_softc *sc)
|
in_gre_attach(struct gre_softc *sc)
|
||||||
{
|
{
|
||||||
|
struct epoch_tracker et;
|
||||||
struct grehdr *gh;
|
struct grehdr *gh;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
|
@ -397,7 +398,9 @@ in_gre_attach(struct gre_softc *sc)
|
||||||
sc, srchash);
|
sc, srchash);
|
||||||
|
|
||||||
/* Set IFF_DRV_RUNNING if interface is ready */
|
/* Set IFF_DRV_RUNNING if interface is ready */
|
||||||
|
NET_EPOCH_ENTER(et);
|
||||||
in_gre_set_running(sc);
|
in_gre_set_running(sc);
|
||||||
|
NET_EPOCH_EXIT(et);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,6 @@ __FBSDID("$FreeBSD$");
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/kernel.h>
|
#include <sys/kernel.h>
|
||||||
#include <sys/lock.h>
|
#include <sys/lock.h>
|
||||||
#include <sys/rmlock.h>
|
|
||||||
#include <sys/sysctl.h>
|
#include <sys/sysctl.h>
|
||||||
#include <sys/syslog.h>
|
#include <sys/syslog.h>
|
||||||
|
|
||||||
|
|
@ -756,7 +755,6 @@ freeit:
|
||||||
static void
|
static void
|
||||||
icmp_reflect(struct mbuf *m)
|
icmp_reflect(struct mbuf *m)
|
||||||
{
|
{
|
||||||
struct rm_priotracker in_ifa_tracker;
|
|
||||||
struct ip *ip = mtod(m, struct ip *);
|
struct ip *ip = mtod(m, struct ip *);
|
||||||
struct ifaddr *ifa;
|
struct ifaddr *ifa;
|
||||||
struct ifnet *ifp;
|
struct ifnet *ifp;
|
||||||
|
|
@ -785,15 +783,12 @@ icmp_reflect(struct mbuf *m)
|
||||||
* If the incoming packet was addressed directly to one of our
|
* If the incoming packet was addressed directly to one of our
|
||||||
* own addresses, use dst as the src for the reply.
|
* own addresses, use dst as the src for the reply.
|
||||||
*/
|
*/
|
||||||
IN_IFADDR_RLOCK(&in_ifa_tracker);
|
CK_LIST_FOREACH(ia, INADDR_HASH(t.s_addr), ia_hash) {
|
||||||
LIST_FOREACH(ia, INADDR_HASH(t.s_addr), ia_hash) {
|
|
||||||
if (t.s_addr == IA_SIN(ia)->sin_addr.s_addr) {
|
if (t.s_addr == IA_SIN(ia)->sin_addr.s_addr) {
|
||||||
t = IA_SIN(ia)->sin_addr;
|
t = IA_SIN(ia)->sin_addr;
|
||||||
IN_IFADDR_RUNLOCK(&in_ifa_tracker);
|
|
||||||
goto match;
|
goto match;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IN_IFADDR_RUNLOCK(&in_ifa_tracker);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the incoming packet was addressed to one of our broadcast
|
* If the incoming packet was addressed to one of our broadcast
|
||||||
|
|
|
||||||
|
|
@ -102,9 +102,6 @@ extern void ipreass_slowtimo(void);
|
||||||
extern void ipreass_destroy(void);
|
extern void ipreass_destroy(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct rmlock in_ifaddr_lock;
|
|
||||||
RM_SYSINIT(in_ifaddr_lock, &in_ifaddr_lock, "in_ifaddr_lock");
|
|
||||||
|
|
||||||
VNET_DEFINE(int, rsvp_on);
|
VNET_DEFINE(int, rsvp_on);
|
||||||
|
|
||||||
VNET_DEFINE(int, ipforwarding);
|
VNET_DEFINE(int, ipforwarding);
|
||||||
|
|
@ -180,6 +177,9 @@ VNET_DEFINE(struct in_ifaddrhead, in_ifaddrhead); /* first inet address */
|
||||||
VNET_DEFINE(struct in_ifaddrhashhead *, in_ifaddrhashtbl); /* inet addr hash table */
|
VNET_DEFINE(struct in_ifaddrhashhead *, in_ifaddrhashtbl); /* inet addr hash table */
|
||||||
VNET_DEFINE(u_long, in_ifaddrhmask); /* mask for hash table */
|
VNET_DEFINE(u_long, in_ifaddrhmask); /* mask for hash table */
|
||||||
|
|
||||||
|
/* Make sure it is safe to use hashinit(9) on CK_LIST. */
|
||||||
|
CTASSERT(sizeof(struct in_ifaddrhashhead) == sizeof(LIST_HEAD(, in_addr)));
|
||||||
|
|
||||||
#ifdef IPCTL_DEFMTU
|
#ifdef IPCTL_DEFMTU
|
||||||
SYSCTL_INT(_net_inet_ip, IPCTL_DEFMTU, mtu, CTLFLAG_RW,
|
SYSCTL_INT(_net_inet_ip, IPCTL_DEFMTU, mtu, CTLFLAG_RW,
|
||||||
&ip_mtu, 0, "Default MTU");
|
&ip_mtu, 0, "Default MTU");
|
||||||
|
|
@ -453,7 +453,6 @@ void
|
||||||
ip_input(struct mbuf *m)
|
ip_input(struct mbuf *m)
|
||||||
{
|
{
|
||||||
MROUTER_RLOCK_TRACKER;
|
MROUTER_RLOCK_TRACKER;
|
||||||
struct rm_priotracker in_ifa_tracker;
|
|
||||||
struct ip *ip = NULL;
|
struct ip *ip = NULL;
|
||||||
struct in_ifaddr *ia = NULL;
|
struct in_ifaddr *ia = NULL;
|
||||||
struct ifaddr *ifa;
|
struct ifaddr *ifa;
|
||||||
|
|
@ -689,8 +688,7 @@ passin:
|
||||||
/*
|
/*
|
||||||
* Check for exact addresses in the hash bucket.
|
* Check for exact addresses in the hash bucket.
|
||||||
*/
|
*/
|
||||||
IN_IFADDR_RLOCK(&in_ifa_tracker);
|
CK_LIST_FOREACH(ia, INADDR_HASH(ip->ip_dst.s_addr), ia_hash) {
|
||||||
LIST_FOREACH(ia, INADDR_HASH(ip->ip_dst.s_addr), ia_hash) {
|
|
||||||
/*
|
/*
|
||||||
* If the address matches, verify that the packet
|
* If the address matches, verify that the packet
|
||||||
* arrived via the correct interface if checking is
|
* arrived via the correct interface if checking is
|
||||||
|
|
@ -701,11 +699,9 @@ passin:
|
||||||
counter_u64_add(ia->ia_ifa.ifa_ipackets, 1);
|
counter_u64_add(ia->ia_ifa.ifa_ipackets, 1);
|
||||||
counter_u64_add(ia->ia_ifa.ifa_ibytes,
|
counter_u64_add(ia->ia_ifa.ifa_ibytes,
|
||||||
m->m_pkthdr.len);
|
m->m_pkthdr.len);
|
||||||
IN_IFADDR_RUNLOCK(&in_ifa_tracker);
|
|
||||||
goto ours;
|
goto ours;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IN_IFADDR_RUNLOCK(&in_ifa_tracker);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check for broadcast addresses.
|
* Check for broadcast addresses.
|
||||||
|
|
|
||||||
|
|
@ -1593,20 +1593,9 @@ pf_isforlocal(struct mbuf *m, int af)
|
||||||
switch (af) {
|
switch (af) {
|
||||||
#ifdef INET
|
#ifdef INET
|
||||||
case AF_INET: {
|
case AF_INET: {
|
||||||
struct rm_priotracker in_ifa_tracker;
|
struct ip *ip = mtod(m, struct ip *);
|
||||||
struct ip *ip;
|
|
||||||
struct in_ifaddr *ia = NULL;
|
|
||||||
|
|
||||||
ip = mtod(m, struct ip *);
|
return (in_localip(ip->ip_dst));
|
||||||
IN_IFADDR_RLOCK(&in_ifa_tracker);
|
|
||||||
LIST_FOREACH(ia, INADDR_HASH(ip->ip_dst.s_addr), ia_hash) {
|
|
||||||
if (IA_SIN(ia)->sin_addr.s_addr == ip->ip_dst.s_addr) {
|
|
||||||
IN_IFADDR_RUNLOCK(&in_ifa_tracker);
|
|
||||||
return (true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
IN_IFADDR_RUNLOCK(&in_ifa_tracker);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef INET6
|
#ifdef INET6
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue