patch-2.2.0-pre5 linux/net/ipv4/ip_masq.c
Next file: linux/net/ipv4/ip_masq_mfw.c
Previous file: linux/net/ipv4/ip_fw.c
Back to the patch index
Back to the overall index
- Lines: 238
- Date:
Mon Jan 4 15:31:35 1999
- Orig file:
v2.2.0-pre4/linux/net/ipv4/ip_masq.c
- Orig date:
Fri Jan 1 12:58:21 1999
diff -u --recursive --new-file v2.2.0-pre4/linux/net/ipv4/ip_masq.c linux/net/ipv4/ip_masq.c
@@ -4,7 +4,7 @@
*
* Copyright (c) 1994 Pauline Middelink
*
- * $Id: ip_masq.c,v 1.28 1998/11/21 00:33:30 davem Exp $
+ * $Id: ip_masq.c,v 1.32 1999/01/04 20:37:05 davem Exp $
*
*
* See ip_fw.c for original log
@@ -44,6 +44,8 @@
* Juan Jose Ciarlante : fixed stupid SMP locking bug
* Juan Jose Ciarlante : fixed "tap"ing in demasq path by copy-on-w
* Juan Jose Ciarlante : make masq_proto_doff() robust against fake sized/corrupted packets
+ * Kai Bankett : do not toss other IP protos in proto_doff()
+ * Dan Kegel : pointed correct NAT behavior for UDP streams
*
*/
@@ -391,6 +393,20 @@
struct ip_fw_masq *ip_masq_expire = &ip_masq_dummy;
#endif
+/*
+ * These flags enable non-strict d{addr,port} checks
+ * Given that both (in/out) lookup tables are hashed
+ * by m{addr,port} and s{addr,port} this is quite easy
+ */
+
+#define MASQ_DADDR_PASS (IP_MASQ_F_NO_DADDR|IP_MASQ_F_DLOOSE)
+#define MASQ_DPORT_PASS (IP_MASQ_F_NO_DPORT|IP_MASQ_F_DLOOSE)
+
+/*
+ * By default enable dest loose semantics
+ */
+#define CONFIG_IP_MASQ_LOOSE_DEFAULT 1
+
/*
* Set masq expiration (deletion) and adds timer,
@@ -522,12 +538,12 @@
hash = ip_masq_hash_key(protocol, d_addr, d_port);
-
for(ms = ip_masq_m_tab[hash]; ms ; ms = ms->m_link) {
- if (protocol==ms->protocol &&
- ((s_addr==ms->daddr || ms->flags & IP_MASQ_F_NO_DADDR)) &&
- (s_port==ms->dport || ms->flags & IP_MASQ_F_NO_DPORT) &&
- (d_addr==ms->maddr && d_port==ms->mport)) {
+ if (protocol==ms->protocol &&
+ (d_addr==ms->maddr && d_port==ms->mport) &&
+ (s_addr==ms->daddr || ms->flags & MASQ_DADDR_PASS) &&
+ (s_port==ms->dport || ms->flags & MASQ_DPORT_PASS)
+ ) {
IP_MASQ_DEBUG(2, "look/in %d %08X:%04hX->%08X:%04hX OK\n",
protocol,
s_addr,
@@ -578,7 +594,9 @@
for(ms = ip_masq_s_tab[hash]; ms ; ms = ms->s_link) {
if (protocol == ms->protocol &&
s_addr == ms->saddr && s_port == ms->sport &&
- d_addr == ms->daddr && d_port == ms->dport ) {
+ (d_addr==ms->daddr || ms->flags & MASQ_DADDR_PASS) &&
+ (d_port==ms->dport || ms->flags & MASQ_DPORT_PASS)
+ ) {
IP_MASQ_DEBUG(2, "lk/out1 %d %08X:%04hX->%08X:%04hX OK\n",
protocol,
s_addr,
@@ -600,7 +618,9 @@
if (ms->flags & IP_MASQ_F_NO_SPORT &&
protocol == ms->protocol &&
s_addr == ms->saddr &&
- d_addr == ms->daddr && d_port == ms->dport ) {
+ (d_addr==ms->daddr || ms->flags & MASQ_DADDR_PASS) &&
+ (d_port==ms->dport || ms->flags & MASQ_DPORT_PASS)
+ ) {
IP_MASQ_DEBUG(2, "lk/out2 %d %08X:%04hX->%08X:%04hX OK\n",
protocol,
s_addr,
@@ -623,7 +643,7 @@
return ms;
}
-#ifdef CONFIG_IP_MASQUERADE_NREUSE
+#ifdef CONFIG_IP_MASQ_NREUSE
/*
* Returns ip_masq for given proto,m_addr,m_port.
* called by allocation routine to find an unused m_port.
@@ -841,7 +861,15 @@
atomic_set(&ms->refcnt,0);
if (proto == IPPROTO_UDP && !mport)
+#ifdef CONFIG_IP_MASQ_LOOSE_DEFAULT
+ /*
+ * Flag this tunnel as "dest loose"
+ *
+ */
+ ms->flags |= IP_MASQ_F_DLOOSE;
+#else
ms->flags |= IP_MASQ_F_NO_DADDR;
+#endif
/* get masq address from rif */
@@ -916,7 +944,7 @@
else
write_lock(&__ip_masq_lock);
-#ifdef CONFIG_IP_MASQUERADE_NREUSE
+#ifdef CONFIG_IP_MASQ_NREUSE
mst = __ip_masq_getbym(proto, maddr, mport);
#else
mst = __ip_masq_in_get(proto, daddr, dport, maddr, mport);
@@ -966,6 +994,9 @@
/*
* Get transport protocol data offset, check against size
+ * return:
+ * 0 if other IP proto
+ * -1 if error
*/
static __inline__ int proto_doff(unsigned proto, char *th, unsigned size)
{
@@ -993,6 +1024,9 @@
}
break;
+ default:
+ /* Other proto: nothing to say, by now :) */
+ ret = 0;
}
if (ret < 0)
IP_MASQ_DEBUG(0, "mess proto_doff for proto=%d, size =%d\n",
@@ -1024,11 +1058,16 @@
h.raw = (char*) iph + iph->ihl * 4;
size = ntohs(iph->tot_len) - (iph->ihl * 4);
+
doff = proto_doff(iph->protocol, h.raw, size);
- if (doff < 0) {
- IP_MASQ_DEBUG(0, "O-pkt invalid packet data size\n");
+ if (doff <= 0) {
+ /*
+ * Output path: do not pass other IP protos nor
+ * invalid packets.
+ */
return -1;
}
+
switch (iph->protocol) {
case IPPROTO_ICMP:
return(ip_fw_masq_icmp(skb_p, maddr));
@@ -1131,6 +1170,13 @@
IP_MASQ_DEBUG(1, "ip_fw_masquerade(): filled sport=%d\n",
ntohs(ms->sport));
}
+ if (ms->flags & IP_MASQ_F_DLOOSE) {
+ /*
+ * update dest loose values
+ */
+ ms->dport = h.portp[1];
+ ms->daddr = iph->daddr;
+ }
} else {
/*
* Nope, not found, create a new entry for it
@@ -1431,8 +1477,8 @@
if (ip_compute_csum((unsigned char *) icmph, len))
{
/* Failed checksum! */
- IP_MASQ_WARNING( "forward ICMP: failed checksum from %d.%d.%d.%d!\n",
- NIPQUAD(iph->saddr));
+ IP_MASQ_DEBUG(0, "forward ICMP: failed checksum from %d.%d.%d.%d!\n",
+ NIPQUAD(iph->saddr));
return(-1);
}
@@ -1776,9 +1822,17 @@
size = ntohs(iph->tot_len) - (iph->ihl * 4);
doff = proto_doff(iph->protocol, h.raw, size);
- if (doff < 0) {
- IP_MASQ_DEBUG(0, "I-pkt invalid packet data size\n");
- return -1;
+
+ switch (doff) {
+ case 0:
+ /*
+ * Input path: other IP protos Ok, will
+ * reach local sockets path.
+ */
+ return 0;
+ case -1:
+ IP_MASQ_DEBUG(0, "I-pkt invalid packet data size\n");
+ return -1;
}
maddr = iph->daddr;
@@ -1870,10 +1924,18 @@
*/
ms->flags &= ~IP_MASQ_F_NO_REPLY;
- /*
- * Set dport if not defined yet.
+ /*
+ * Set daddr,dport if not defined yet
+ * and tunnel is not setup as "dest loose"
*/
+ if (ms->flags & IP_MASQ_F_DLOOSE) {
+ /*
+ * update dest loose values
+ */
+ ms->dport = h.portp[0];
+ ms->daddr = iph->saddr;
+ } else {
if ( ms->flags & IP_MASQ_F_NO_DPORT ) { /* && ms->protocol == IPPROTO_TCP ) { */
ms->flags &= ~IP_MASQ_F_NO_DPORT;
ms->dport = h.portp[0];
@@ -1890,6 +1952,7 @@
ntohl(ms->daddr));
}
+ }
if ((skb=masq_skb_cow(skb_p, &iph, &h.raw)) == NULL) {
ip_masq_put(ms);
return -1;
@@ -2309,8 +2372,8 @@
#ifdef CONFIG_IP_MASQUERADE_IPPORTFW
ip_portfw_init();
#endif
-#ifdef CONFIG_IP_MASQUERADE_IPMARKFW
- ip_markfw_init();
+#ifdef CONFIG_IP_MASQUERADE_MFW
+ ip_mfw_init();
#endif
ip_masq_app_init();
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov