Page MenuHomeFreeBSD

D32912.id98267.diff
No OneTemporary

D32912.id98267.diff

Index: share/man/man4/inet.4
===================================================================
--- share/man/man4/inet.4
+++ share/man/man4/inet.4
@@ -204,6 +204,21 @@
.Xr sysctl 8
variable affects packets destined for a local host as well as packets
forwarded to some other host.
+.It Va ip.rfc1122_strong_es
+Boolean: in non-forwarding mode
+.Pq ip.forwarding is disabled
+partially implement the Strong End System model per RFC1122.
+If a packet with destination address that is local arrives on a different
+interface than the interface the address belongs to, the packet would be
+silently dropped.
+Enabling this option may break certain setups, e.g. having an alias address(es)
+on loopback that are expected to be reachable by outside traffic.
+Enabling some other network features, e.g.
+.Xr carp 4
+or destination address rewriting
+.Xr pfil 4
+filters may override and bypass this check.
+Disabled by default.
.It Va ip.rfc6864
Boolean: control IP IDs generation behaviour.
True value enables RFC6864 support, which specifies that IP ID field of
Index: sys/netinet/ip_input.c
===================================================================
--- sys/netinet/ip_input.c
+++ sys/netinet/ip_input.c
@@ -118,24 +118,11 @@
&VNET_NAME(ipsendredirects), 0,
"Enable sending IP redirects");
-/*
- * 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.
- */
-VNET_DEFINE_STATIC(int, ip_checkinterface);
-#define V_ip_checkinterface VNET(ip_checkinterface)
-SYSCTL_INT(_net_inet_ip, OID_AUTO, check_interface, CTLFLAG_VNET | CTLFLAG_RW,
- &VNET_NAME(ip_checkinterface), 0,
- "Verify packet arrives on correct interface");
+VNET_DEFINE_STATIC(bool, ip_strong_es) = false;
+#define V_ip_strong_es VNET(ip_strong_es)
+SYSCTL_BOOL(_net_inet_ip, OID_AUTO, rfc1122_strong_es,
+ CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip_strong_es), false,
+ "Packet's IP destination address must match address on arrival interface");
VNET_DEFINE(pfil_head_t, inet_pfil_head); /* Packet filter hooks */
@@ -457,10 +444,11 @@
struct in_ifaddr *ia = NULL;
struct ifaddr *ifa;
struct ifnet *ifp;
- int checkif, hlen = 0;
+ int hlen = 0;
uint16_t sum, ip_len;
int dchg = 0; /* dest changed after fw */
struct in_addr odst; /* original dst address */
+ bool strong_es;
M_ASSERTPKTHDR(m);
NET_EPOCH_ASSERT();
@@ -666,22 +654,14 @@
/*
* 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 and the packet is not subject to
- * 'ipfw fwd'.
- *
- * 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 - This is the case for carp vhost IPs as well so we
- * insert a workaround. If the packet got here, we already
- * checked with carp_iamatch() and carp_forus().
+ * strong ES model) with a list of additional predicates:
+ * - if IP forwarding is disabled
+ * - the packet is not locally generated
+ * - the packet is not subject to 'ipfw fwd'
+ * - Interface is not running CARP. If the packet got here, we already
+ * checked it with carp_iamatch() and carp_forus().
*/
- checkif = V_ip_checkinterface && (V_ipforwarding == 0) &&
+ strong_es = V_ip_strong_es && (V_ipforwarding == 0) &&
ifp != NULL && ((ifp->if_flags & IFF_LOOPBACK) == 0) &&
ifp->if_carp == NULL && (dchg == 0);
@@ -689,18 +669,21 @@
* Check for exact addresses in the hash bucket.
*/
CK_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)
+ continue;
+
/*
- * If the address matches, verify that the packet
- * arrived via the correct interface if checking is
- * enabled.
+ * net.inet.ip.rfc1122_strong_es: the address matches, verify
+ * that the packet arrived via the correct interface.
*/
- if (IA_SIN(ia)->sin_addr.s_addr == ip->ip_dst.s_addr &&
- (!checkif || ia->ia_ifp == ifp)) {
- counter_u64_add(ia->ia_ifa.ifa_ipackets, 1);
- counter_u64_add(ia->ia_ifa.ifa_ibytes,
- m->m_pkthdr.len);
- goto ours;
+ if (__predict_false(strong_es && ia->ia_ifp != ifp)) {
+ IPSTAT_INC(ips_badaddr);
+ goto bad;
}
+
+ counter_u64_add(ia->ia_ifa.ifa_ipackets, 1);
+ counter_u64_add(ia->ia_ifa.ifa_ibytes, m->m_pkthdr.len);
+ goto ours;
}
/*

File Metadata

Mime Type
text/plain
Expires
Tue, Jan 14, 6:12 AM (21 h, 7 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15791705
Default Alt Text
D32912.id98267.diff (5 KB)

Event Timeline