Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/sys/netinet/ip_input.c,v rcsdiff: /ftp/cvs/cvsroot/src/sys/netinet/ip_input.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.164 retrieving revision 1.168 diff -u -p -r1.164 -r1.168 --- src/sys/netinet/ip_input.c 2003/02/26 06:31:14 1.164 +++ src/sys/netinet/ip_input.c 2003/06/30 01:21:11 1.168 @@ -1,4 +1,4 @@ -/* $NetBSD: ip_input.c,v 1.164 2003/02/26 06:31:14 matt Exp $ */ +/* $NetBSD: ip_input.c,v 1.168 2003/06/30 01:21:11 itojun Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -102,12 +102,13 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.164 2003/02/26 06:31:14 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.168 2003/06/30 01:21:11 itojun Exp $"); #include "opt_gateway.h" #include "opt_pfil_hooks.h" #include "opt_ipsec.h" #include "opt_mrouting.h" +#include "opt_mbuftrace.h" #include "opt_inet_csum.h" #include @@ -196,6 +197,21 @@ int ip_mtudisc_timeout = IPMTUDISCTIMEOU #ifdef DIAGNOSTIC int ipprintfs = 0; #endif +/* + * XXX - Setting ip_checkinterface mostly implements the receive side of + * the Strong ES model described in RFC 1122, but since the routing table + * and transmit implementation do not implement the Strong ES model, + * setting this to 1 results in an odd hybrid. + * + * XXX - ip_checkinterface currently must be disabled if you use ipnat + * to translate the destination address to another local interface. + * + * XXX - ip_checkinterface must be disabled if you add IP aliases + * to the loopback interface instead of the interface where the + * packets for those addresses are received. + */ +int ip_checkinterface = 0; + struct rttimer_queue *ip_mtudisc_timeout_q = NULL; @@ -205,6 +221,10 @@ u_long in_ifaddrhash; /* size of hash int in_ifaddrentries; /* total number of addrs */ struct in_ifaddrhead in_ifaddr; struct in_ifaddrhashhead *in_ifaddrhashtbl; +u_long in_multihash; /* size of hash table - 1 */ +int in_multientries; /* total number of addrs */ +struct in_multihead in_multi; +struct in_multihashhead *in_multihashtbl; struct ifqueue ipintrq; struct ipstat ipstat; u_int16_t ip_id; @@ -272,6 +292,7 @@ do { \ #define IPQ_UNLOCK() ipq_unlock() +struct pool inmulti_pool; struct pool ipqent_pool; #ifdef INET_CSUM_COUNTERS @@ -324,6 +345,8 @@ ip_init() struct protosw *pr; int i; + pool_init(&inmulti_pool, sizeof(struct in_multi), 0, 0, 0, "inmltpl", + NULL); pool_init(&ipqent_pool, sizeof(struct ipqent), 0, 0, 0, "ipqepl", NULL); @@ -343,6 +366,8 @@ ip_init() TAILQ_INIT(&in_ifaddr); in_ifaddrhashtbl = hashinit(IN_IFADDR_HASH_SIZE, HASH_LIST, M_IFADDR, M_WAITOK, &in_ifaddrhash); + in_multihashtbl = hashinit(IN_IFADDR_HASH_SIZE, HASH_LIST, M_IPMADDR, + M_WAITOK, &in_multihash); ip_mtudisc_timeout_q = rt_timer_queue_create(ip_mtudisc_timeout); #ifdef GATEWAY ipflow_init(); @@ -407,6 +432,7 @@ ip_input(struct mbuf *m) struct ipqent *ipqe; int hlen = 0, mff, len; int downmatch; + int checkif; MCLAIM(m, &ip_rx_mowner); #ifdef DIAGNOSTIC @@ -565,8 +591,8 @@ ip_input(struct mbuf *m) #endif { if (pfil_run_hooks(&inet_pfil_hook, &m, m->m_pkthdr.rcvif, - PFIL_IN) != 0) - return; + PFIL_IN) != 0) + return; if (m == NULL) return; ip = mtod(m, struct ip *); @@ -593,6 +619,26 @@ ip_input(struct mbuf *m) return; /* + * 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) && + (m->m_pkthdr.rcvif != NULL) && + ((m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK) == 0); + + /* * Check our list of addresses, to see if the packet is for us. * * Traditional 4.4BSD did not consult IFF_UP at all. @@ -602,6 +648,8 @@ ip_input(struct mbuf *m) downmatch = 0; 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 (checkif && ia->ia_ifp != m->m_pkthdr.rcvif) + continue; if ((ia->ia_ifp->if_flags & IFF_UP) != 0) break; else @@ -1943,6 +1991,9 @@ ip_sysctl(name, namelen, oldp, oldlenp, return (sysctl_int(oldp, oldlenp, newp, newlen, &ip_maxfragpackets)); + case IPCTL_CHECKINTERFACE: + return (sysctl_int(oldp, oldlenp, newp, newlen, + &ip_checkinterface)); default: return (EOPNOTSUPP); }