version 1.319.4.6, 2016/07/09 20:25:22 |
version 1.332, 2016/06/30 06:56:27 |
Line 289 static bool ip_dooptions(struct mbuf *) |
|
Line 289 static bool ip_dooptions(struct mbuf *) |
|
static struct in_ifaddr *ip_rtaddr(struct in_addr); |
static struct in_ifaddr *ip_rtaddr(struct in_addr); |
static void sysctl_net_inet_ip_setup(struct sysctllog **); |
static void sysctl_net_inet_ip_setup(struct sysctllog **); |
|
|
static struct in_ifaddr *ip_match_our_address(struct ifnet *, struct ip *, |
|
int *); |
|
static struct in_ifaddr *ip_match_our_address_broadcast(struct ifnet *, |
|
struct ip *); |
|
|
|
/* XXX: Not yet enabled. */ |
/* XXX: Not yet enabled. */ |
#define SOFTNET_LOCK() KASSERT(mutex_owned(softnet_lock)) |
#define SOFTNET_LOCK() KASSERT(mutex_owned(softnet_lock)) |
#define SOFTNET_UNLOCK() KASSERT(mutex_owned(softnet_lock)) |
#define SOFTNET_UNLOCK() KASSERT(mutex_owned(softnet_lock)) |
|
|
ipstat_percpu = percpu_alloc(sizeof(uint64_t) * IP_NSTATS); |
ipstat_percpu = percpu_alloc(sizeof(uint64_t) * IP_NSTATS); |
} |
} |
|
|
static struct in_ifaddr * |
|
ip_match_our_address(struct ifnet *ifp, struct ip *ip, int *downmatch) |
|
{ |
|
struct in_ifaddr *ia = NULL; |
|
int checkif; |
|
|
|
/* |
|
* Enable a consistency check between the destination address |
|
* and the arrival interface for a unicast packet (the RFC 1122 |
|
* strong ES model) if IP forwarding is disabled and the packet |
|
* is not locally generated. |
|
* |
|
* XXX - Checking also should be disabled if the destination |
|
* address is ipnat'ed to a different interface. |
|
* |
|
* XXX - Checking is incompatible with IP aliases added |
|
* to the loopback interface instead of the interface where |
|
* the packets are received. |
|
* |
|
* XXX - We need to add a per ifaddr flag for this so that |
|
* we get finer grain control. |
|
*/ |
|
checkif = ip_checkinterface && (ipforwarding == 0) && |
|
(ifp->if_flags & IFF_LOOPBACK) == 0; |
|
|
|
IN_ADDRHASH_READER_FOREACH(ia, ip->ip_dst.s_addr) { |
|
if (in_hosteq(ia->ia_addr.sin_addr, ip->ip_dst)) { |
|
if (ia->ia4_flags & IN_IFF_NOTREADY) |
|
continue; |
|
if (checkif && ia->ia_ifp != ifp) |
|
continue; |
|
if ((ia->ia_ifp->if_flags & IFF_UP) != 0) |
|
break; |
|
else |
|
downmatch++; |
|
} |
|
} |
|
|
|
return ia; |
|
} |
|
|
|
static struct in_ifaddr * |
|
ip_match_our_address_broadcast(struct ifnet *ifp, struct ip *ip) |
|
{ |
|
struct in_ifaddr *ia = NULL; |
|
struct ifaddr *ifa; |
|
|
|
IFADDR_READER_FOREACH(ifa, ifp) { |
|
if (ifa->ifa_addr->sa_family != AF_INET) |
|
continue; |
|
ia = ifatoia(ifa); |
|
if (ia->ia4_flags & IN_IFF_NOTREADY) |
|
continue; |
|
if (in_hosteq(ip->ip_dst, ia->ia_broadaddr.sin_addr) || |
|
in_hosteq(ip->ip_dst, ia->ia_netbroadcast) || |
|
/* |
|
* Look for all-0's host part (old broadcast addr), |
|
* either for subnet or net. |
|
*/ |
|
ip->ip_dst.s_addr == ia->ia_subnet || |
|
ip->ip_dst.s_addr == ia->ia_net) |
|
goto matched; |
|
/* |
|
* An interface with IP address zero accepts |
|
* all packets that arrive on that interface. |
|
*/ |
|
if (in_nullhost(ia->ia_addr.sin_addr)) |
|
goto matched; |
|
} |
|
ia = NULL; |
|
|
|
matched: |
|
return ia; |
|
} |
|
|
|
/* |
/* |
* IP software interrupt routine. |
* IP software interrupt routine. |
*/ |
*/ |
Line 448 ip_input(struct mbuf *m) |
|
Line 368 ip_input(struct mbuf *m) |
|
{ |
{ |
struct ip *ip = NULL; |
struct ip *ip = NULL; |
struct in_ifaddr *ia; |
struct in_ifaddr *ia; |
|
struct ifaddr *ifa; |
int hlen = 0, len; |
int hlen = 0, len; |
int downmatch; |
int downmatch; |
|
int checkif; |
int srcrt = 0; |
int srcrt = 0; |
ifnet_t *ifp; |
ifnet_t *ifp; |
struct psref psref; |
struct psref psref; |
Line 469 ip_input(struct mbuf *m) |
|
Line 391 ip_input(struct mbuf *m) |
|
* are receiving, can't do anything with incoming packets yet. |
* are receiving, can't do anything with incoming packets yet. |
* Note: we pre-check without locks held. |
* Note: we pre-check without locks held. |
*/ |
*/ |
if (IN_ADDRLIST_READER_EMPTY()) |
if (!TAILQ_FIRST(&in_ifaddrhead)) { |
goto out; |
goto out; |
|
} |
IP_STATINC(IP_STAT_TOTAL); |
IP_STATINC(IP_STAT_TOTAL); |
|
|
/* |
/* |
Line 658 ip_input(struct mbuf *m) |
|
Line 581 ip_input(struct mbuf *m) |
|
goto out; |
goto out; |
|
|
/* |
/* |
|
* Enable a consistency check between the destination address |
|
* and the arrival interface for a unicast packet (the RFC 1122 |
|
* strong ES model) if IP forwarding is disabled and the packet |
|
* is not locally generated. |
|
* |
|
* XXX - Checking also should be disabled if the destination |
|
* address is ipnat'ed to a different interface. |
|
* |
|
* XXX - Checking is incompatible with IP aliases added |
|
* to the loopback interface instead of the interface where |
|
* the packets are received. |
|
* |
|
* XXX - We need to add a per ifaddr flag for this so that |
|
* we get finer grain control. |
|
*/ |
|
checkif = ip_checkinterface && (ipforwarding == 0) && |
|
(ifp->if_flags & IFF_LOOPBACK) == 0; |
|
|
|
/* |
* Check our list of addresses, to see if the packet is for us. |
* Check our list of addresses, to see if the packet is for us. |
* |
* |
* Traditional 4.4BSD did not consult IFF_UP at all. |
* Traditional 4.4BSD did not consult IFF_UP at all. |
Line 665 ip_input(struct mbuf *m) |
|
Line 607 ip_input(struct mbuf *m) |
|
* or IN_IFF_NOTREADY addresses as not mine. |
* or IN_IFF_NOTREADY addresses as not mine. |
*/ |
*/ |
downmatch = 0; |
downmatch = 0; |
ia = ip_match_our_address(ifp, ip, &downmatch); |
LIST_FOREACH(ia, &IN_IFADDR_HASH(ip->ip_dst.s_addr), ia_hash) { |
|
if (in_hosteq(ia->ia_addr.sin_addr, ip->ip_dst)) { |
|
if (ia->ia4_flags & IN_IFF_NOTREADY) |
|
continue; |
|
if (checkif && ia->ia_ifp != ifp) |
|
continue; |
|
if ((ia->ia_ifp->if_flags & IFF_UP) != 0) |
|
break; |
|
else |
|
downmatch++; |
|
} |
|
} |
if (ia != NULL) |
if (ia != NULL) |
goto ours; |
goto ours; |
|
|
if (ifp->if_flags & IFF_BROADCAST) { |
if (ifp->if_flags & IFF_BROADCAST) { |
ia = ip_match_our_address_broadcast(ifp, ip); |
IFADDR_FOREACH(ifa, ifp) { |
if (ia != NULL) |
if (ifa->ifa_addr->sa_family != AF_INET) |
goto ours; |
continue; |
|
ia = ifatoia(ifa); |
|
if (ia->ia4_flags & IN_IFF_NOTREADY) |
|
continue; |
|
if (in_hosteq(ip->ip_dst, ia->ia_broadaddr.sin_addr) || |
|
in_hosteq(ip->ip_dst, ia->ia_netbroadcast) || |
|
/* |
|
* Look for all-0's host part (old broadcast addr), |
|
* either for subnet or net. |
|
*/ |
|
ip->ip_dst.s_addr == ia->ia_subnet || |
|
ip->ip_dst.s_addr == ia->ia_net) |
|
goto ours; |
|
/* |
|
* An interface with IP address zero accepts |
|
* all packets that arrive on that interface. |
|
*/ |
|
if (in_nullhost(ia->ia_addr.sin_addr)) |
|
goto ours; |
|
} |
} |
} |
|
|
if (IN_MULTICAST(ip->ip_dst.s_addr)) { |
if (IN_MULTICAST(ip->ip_dst.s_addr)) { |
#ifdef MROUTING |
#ifdef MROUTING |
extern struct socket *ip_mrouter; |
extern struct socket *ip_mrouter; |
Line 1472 ip_savecontrol(struct inpcb *inp, struct |
|
Line 1442 ip_savecontrol(struct inpcb *inp, struct |
|
if (inpflags & INP_RECVIF) { |
if (inpflags & INP_RECVIF) { |
struct sockaddr_dl sdl; |
struct sockaddr_dl sdl; |
|
|
sockaddr_dl_init(&sdl, sizeof(sdl), ifp->if_index, 0, NULL, 0, |
sockaddr_dl_init(&sdl, sizeof(sdl), ifp ? |
NULL, 0); |
ifp->if_index : 0, 0, NULL, 0, NULL, 0); |
*mp = sbcreatecontrol(&sdl, sdl.sdl_len, IP_RECVIF, IPPROTO_IP); |
*mp = sbcreatecontrol(&sdl, sdl.sdl_len, IP_RECVIF, IPPROTO_IP); |
if (*mp) |
if (*mp) |
mp = &(*mp)->m_next; |
mp = &(*mp)->m_next; |