summaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/igmp.c2
-rw-r--r--net/ipv4/netfilter/Config.in11
-rw-r--r--net/ipv4/netfilter/Makefile2
-rw-r--r--net/ipv4/netfilter/ip_conntrack_core.c9
-rw-r--r--net/ipv4/netfilter/ip_nat_core.c21
-rw-r--r--net/ipv4/netfilter/ipt_MASQUERADE.c14
-rw-r--r--net/ipv4/netfilter/ipt_REJECT.c24
-rw-r--r--net/ipv4/netfilter/iptable_mangle.c6
-rw-r--r--net/ipv4/tcp.c2
-rw-r--r--net/ipv4/tcp_input.c2
10 files changed, 57 insertions, 36 deletions
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 1d8002bdd..81fae9233 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -504,8 +504,8 @@ void ip_mc_inc_group(struct in_device *in_dev, u32 addr)
im->timer.function=&igmp_timer_expire;
im->unsolicit_count = IGMP_Unsolicited_Report_Count;
im->reporter = 0;
- im->loaded = 0;
#endif
+ im->loaded = 0;
write_lock_bh(&in_dev->lock);
im->next=in_dev->mc_list;
in_dev->mc_list=im;
diff --git a/net/ipv4/netfilter/Config.in b/net/ipv4/netfilter/Config.in
index 406d2ea3d..5887658fb 100644
--- a/net/ipv4/netfilter/Config.in
+++ b/net/ipv4/netfilter/Config.in
@@ -37,11 +37,20 @@ if [ "$CONFIG_IP_NF_IPTABLES" != "n" ]; then
fi
if [ "$CONFIG_IP_NF_CONNTRACK" != "n" ]; then
- dep_tristate ' Full NAT' CONFIG_IP_NF_NAT $CONFIG_IP_NF_IPTABLES
+ dep_tristate ' Full NAT' CONFIG_IP_NF_NAT $CONFIG_IP_NF_IPTABLES $CONFIG_IP_NF_CONNTRACK
if [ "$CONFIG_IP_NF_NAT" != "n" ]; then
define_bool CONFIG_IP_NF_NAT_NEEDED y
dep_tristate ' MASQUERADE target support' CONFIG_IP_NF_TARGET_MASQUERADE $CONFIG_IP_NF_NAT
dep_tristate ' REDIRECT target support' CONFIG_IP_NF_TARGET_REDIRECT $CONFIG_IP_NF_NAT
+ # If they want FTP, set to $CONFIG_IP_NF_NAT (m or y),
+ # or $CONFIG_IP_NF_FTP (m or y), whichever is weaker. Argh.
+ if [ "$CONFIG_IP_NF_FTP" = "m" ]; then
+ define_tristate CONFIG_IP_NF_NAT_FTP m
+ else
+ if [ "$CONFIG_IP_NF_FTP" = "y" ]; then
+ define_tristate CONFIG_IP_NF_NAT_FTP $CONFIG_IP_NF_NAT
+ fi
+ fi
fi
fi
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile
index 995860767..c40caa75e 100644
--- a/net/ipv4/netfilter/Makefile
+++ b/net/ipv4/netfilter/Makefile
@@ -35,7 +35,7 @@ obj-$(CONFIG_IP_NF_CONNTRACK) += ip_conntrack.o
obj-$(CONFIG_IP_NF_FTP) += ip_conntrack_ftp.o
# NAT helpers
-obj-$(CONFIG_IP_NF_FTP) += ip_nat_ftp.o
+obj-$(CONFIG_IP_NF_NAT_FTP) += ip_nat_ftp.o
# generic IP tables
obj-$(CONFIG_IP_NF_IPTABLES) += ip_tables.o
diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c
index 2e4dd82ee..bc7e64c8b 100644
--- a/net/ipv4/netfilter/ip_conntrack_core.c
+++ b/net/ipv4/netfilter/ip_conntrack_core.c
@@ -882,10 +882,15 @@ ip_ct_gather_frags(struct sk_buff *skb)
#ifdef CONFIG_NETFILTER_DEBUG
unsigned int olddebug = skb->nf_debug;
#endif
- if (sk) sock_hold(sk);
+ if (sk) {
+ sock_hold(sk);
+ skb_orphan(skb);
+ }
+
local_bh_disable();
skb = ip_defrag(skb);
- local_bh_enable();
+ local_bh_enable();
+
if (!skb) {
if (sk) sock_put(sk);
return skb;
diff --git a/net/ipv4/netfilter/ip_nat_core.c b/net/ipv4/netfilter/ip_nat_core.c
index 9ba62dc84..cc19e1f0b 100644
--- a/net/ipv4/netfilter/ip_nat_core.c
+++ b/net/ipv4/netfilter/ip_nat_core.c
@@ -438,8 +438,27 @@ get_unique_tuple(struct ip_conntrack_tuple *tuple,
conntrack));
ret = 1;
goto clear_fulls;
+ } else if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_DST) {
+ /* Try implicit source NAT; protocol
+ may be able to play with ports to
+ make it unique. */
+ struct ip_nat_range r
+ = { IP_NAT_RANGE_MAP_IPS,
+ tuple->src.ip, tuple->src.ip,
+ { 0 }, { 0 } };
+ DEBUGP("Trying implicit mapping\n");
+ if (proto->unique_tuple(tuple, &r,
+ IP_NAT_MANIP_SRC,
+ conntrack)) {
+ /* Must be unique. */
+ IP_NF_ASSERT(!ip_nat_used_tuple
+ (tuple, conntrack));
+ ret = 1;
+ goto clear_fulls;
+ }
}
- DEBUGP("Protocol can't get unique tuple.\n");
+ DEBUGP("Protocol can't get unique tuple %u.\n",
+ hooknum);
}
/* Eliminate that from range, and try again. */
diff --git a/net/ipv4/netfilter/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_MASQUERADE.c
index 99164a7a0..f2a19702d 100644
--- a/net/ipv4/netfilter/ipt_MASQUERADE.c
+++ b/net/ipv4/netfilter/ipt_MASQUERADE.c
@@ -1,5 +1,6 @@
/* Masquerade. Simple mapping which alters range to a local IP address
(depending on route). */
+#include <linux/config.h>
#include <linux/types.h>
#include <linux/ip.h>
#include <linux/timer.h>
@@ -68,6 +69,7 @@ masquerade_target(struct sk_buff **pskb,
struct ip_nat_multi_range newrange;
u_int32_t newsrc;
struct rtable *rt;
+ struct rt_key key;
IP_NF_ASSERT(hooknum == NF_IP_POST_ROUTING);
@@ -82,10 +84,14 @@ masquerade_target(struct sk_buff **pskb,
mr = targinfo;
- if (ip_route_output(&rt, (*pskb)->nh.iph->daddr,
- 0,
- RT_TOS((*pskb)->nh.iph->tos)|RTO_CONN,
- out->ifindex) != 0) {
+ key.dst = (*pskb)->nh.iph->daddr;
+ key.src = 0; /* Unknown: that's what we're trying to establish */
+ key.tos = RT_TOS((*pskb)->nh.iph->tos)|RTO_CONN;
+ key.oif = out->ifindex;
+#ifdef CONFIG_IP_ROUTE_FWMARK
+ key.fwmark = (*pskb)->nfmark;
+#endif
+ if (ip_route_output_key(&rt, &key) != 0) {
/* Shouldn't happen */
printk("MASQUERADE: No route: Rusty's brain broke!\n");
return NF_DROP;
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c
index 9c1088e76..cc5ffbc4a 100644
--- a/net/ipv4/netfilter/ipt_REJECT.c
+++ b/net/ipv4/netfilter/ipt_REJECT.c
@@ -167,27 +167,9 @@ static unsigned int reject(struct sk_buff **pskb,
case IPT_ICMP_HOST_PROHIBITED:
icmp_send(*pskb, ICMP_DEST_UNREACH, ICMP_HOST_ANO, 0);
break;
- case IPT_ICMP_ECHOREPLY: {
- struct icmphdr *icmph = (struct icmphdr *)
- ((u_int32_t *)(*pskb)->nh.iph + (*pskb)->nh.iph->ihl);
- unsigned int datalen = (*pskb)->len - (*pskb)->nh.iph->ihl * 4;
-
- /* Not non-head frags, or truncated */
- if (((ntohs((*pskb)->nh.iph->frag_off) & IP_OFFSET) == 0)
- && datalen >= 4) {
- /* Usually I don't like cut & pasting code,
- but dammit, my party is starting in 45
- mins! --RR */
- struct icmp_bxm icmp_param;
-
- icmp_param.icmph=*icmph;
- icmp_param.icmph.type=ICMP_ECHOREPLY;
- icmp_param.data_ptr=(icmph+1);
- icmp_param.data_len=datalen;
- icmp_reply(&icmp_param, *pskb);
- }
- }
- break;
+ case IPT_ICMP_ECHOREPLY:
+ printk("REJECT: ECHOREPLY no longer supported.\n");
+ break;
case IPT_TCP_RESET:
send_reset(*pskb, hooknum == NF_IP_LOCAL_IN);
break;
diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c
index c52ada64e..60d4698fb 100644
--- a/net/ipv4/netfilter/iptable_mangle.c
+++ b/net/ipv4/netfilter/iptable_mangle.c
@@ -53,7 +53,7 @@ static struct
sizeof(struct ipt_entry),
sizeof(struct ipt_standard),
0, { 0, 0 }, { } },
- { { { { sizeof(struct ipt_standard_target), "" } }, { } },
+ { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } },
-NF_ACCEPT - 1 } },
/* LOCAL_OUT */
{ { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
@@ -61,7 +61,7 @@ static struct
sizeof(struct ipt_entry),
sizeof(struct ipt_standard),
0, { 0, 0 }, { } },
- { { { { sizeof(struct ipt_standard_target), "" } }, { } },
+ { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } },
-NF_ACCEPT - 1 } }
},
/* ERROR */
@@ -70,7 +70,7 @@ static struct
sizeof(struct ipt_entry),
sizeof(struct ipt_error),
0, { 0, 0 }, { } },
- { { { { sizeof(struct ipt_error_target), IPT_ERROR_TARGET } },
+ { { { { IPT_ALIGN(sizeof(struct ipt_error_target)), IPT_ERROR_TARGET } },
{ } },
"ERROR"
}
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index b370fcdf9..6660e0f72 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -954,7 +954,7 @@ int tcp_sendmsg(struct sock *sk, struct msghdr *msg, int size)
*/
skb = sk->write_queue.prev;
if (tp->send_head &&
- (mss_now - skb->len) > 0) {
+ (mss_now > skb->len)) {
copy = skb->len;
if (skb_tailroom(skb) > 0) {
int last_byte_was_odd = (copy % 4);
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 4e3eab087..a3f83272b 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -1705,7 +1705,7 @@ static __inline__ void tcp_ack_packets_out(struct sock *sk, struct tcp_opt *tp)
if ((__s32)when < (__s32)tp->rttvar)
when = tp->rttvar;
- tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, when);
+ tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, min(when, TCP_RTO_MAX));
}
}