Commit 2351392f authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://kernel.bkbits.net/davem/net-2.6

into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents 83d6ea2d 7cd101a5
...@@ -4,11 +4,6 @@ ...@@ -4,11 +4,6 @@
#ifdef __KERNEL__ #ifdef __KERNEL__
#include <linux/netfilter_ipv4/lockhelp.h>
/* Protects ftp part of conntracks */
DECLARE_LOCK_EXTERN(ip_ftp_lock);
#define FTP_PORT 21 #define FTP_PORT 21
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
......
...@@ -33,13 +33,8 @@ struct ip_ct_irc_master { ...@@ -33,13 +33,8 @@ struct ip_ct_irc_master {
#ifdef __KERNEL__ #ifdef __KERNEL__
#include <linux/netfilter_ipv4/lockhelp.h>
#define IRC_PORT 6667 #define IRC_PORT 6667
/* Protects irc part of conntracks */
DECLARE_LOCK_EXTERN(ip_irc_lock);
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#endif /* _IP_CONNTRACK_IRC_H */ #endif /* _IP_CONNTRACK_IRC_H */
...@@ -28,7 +28,7 @@ MODULE_DESCRIPTION("ftp connection tracking helper"); ...@@ -28,7 +28,7 @@ MODULE_DESCRIPTION("ftp connection tracking helper");
/* This is slow, but it's simple. --RR */ /* This is slow, but it's simple. --RR */
static char ftp_buffer[65536]; static char ftp_buffer[65536];
DECLARE_LOCK(ip_ftp_lock); static DECLARE_LOCK(ip_ftp_lock);
struct module *ip_conntrack_ftp = THIS_MODULE; struct module *ip_conntrack_ftp = THIS_MODULE;
#define MAX_PORTS 8 #define MAX_PORTS 8
...@@ -460,7 +460,6 @@ static int __init init(void) ...@@ -460,7 +460,6 @@ static int __init init(void)
} }
PROVIDES_CONNTRACK(ftp); PROVIDES_CONNTRACK(ftp);
EXPORT_SYMBOL(ip_ftp_lock);
module_init(init); module_init(init);
module_exit(fini); module_exit(fini);
...@@ -41,6 +41,7 @@ static int max_dcc_channels = 8; ...@@ -41,6 +41,7 @@ static int max_dcc_channels = 8;
static unsigned int dcc_timeout = 300; static unsigned int dcc_timeout = 300;
/* This is slow, but it's simple. --RR */ /* This is slow, but it's simple. --RR */
static char irc_buffer[65536]; static char irc_buffer[65536];
static DECLARE_LOCK(irc_buffer_lock);
MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
MODULE_DESCRIPTION("IRC (DCC) connection tracking helper"); MODULE_DESCRIPTION("IRC (DCC) connection tracking helper");
...@@ -55,7 +56,6 @@ MODULE_PARM_DESC(dcc_timeout, "timeout on for unestablished DCC channels"); ...@@ -55,7 +56,6 @@ MODULE_PARM_DESC(dcc_timeout, "timeout on for unestablished DCC channels");
static char *dccprotos[] = { "SEND ", "CHAT ", "MOVE ", "TSEND ", "SCHAT " }; static char *dccprotos[] = { "SEND ", "CHAT ", "MOVE ", "TSEND ", "SCHAT " };
#define MINMATCHLEN 5 #define MINMATCHLEN 5
DECLARE_LOCK(ip_irc_lock);
struct module *ip_conntrack_irc = THIS_MODULE; struct module *ip_conntrack_irc = THIS_MODULE;
#if 0 #if 0
...@@ -137,7 +137,7 @@ static int help(struct sk_buff *skb, ...@@ -137,7 +137,7 @@ static int help(struct sk_buff *skb,
if (dataoff >= skb->len) if (dataoff >= skb->len)
return NF_ACCEPT; return NF_ACCEPT;
LOCK_BH(&ip_irc_lock); LOCK_BH(&irc_buffer_lock);
ib_ptr = skb_header_pointer(skb, dataoff, ib_ptr = skb_header_pointer(skb, dataoff,
skb->len - dataoff, irc_buffer); skb->len - dataoff, irc_buffer);
BUG_ON(ib_ptr == NULL); BUG_ON(ib_ptr == NULL);
...@@ -232,7 +232,7 @@ static int help(struct sk_buff *skb, ...@@ -232,7 +232,7 @@ static int help(struct sk_buff *skb,
} /* while data < ... */ } /* while data < ... */
out: out:
UNLOCK_BH(&ip_irc_lock); UNLOCK_BH(&irc_buffer_lock);
return NF_ACCEPT; return NF_ACCEPT;
} }
...@@ -306,7 +306,6 @@ static void fini(void) ...@@ -306,7 +306,6 @@ static void fini(void)
} }
PROVIDES_CONNTRACK(irc); PROVIDES_CONNTRACK(irc);
EXPORT_SYMBOL(ip_irc_lock);
module_init(init); module_init(init);
module_exit(fini); module_exit(fini);
...@@ -36,8 +36,6 @@ static int ports_c; ...@@ -36,8 +36,6 @@ static int ports_c;
module_param_array(ports, int, ports_c, 0400); module_param_array(ports, int, ports_c, 0400);
DECLARE_LOCK_EXTERN(ip_ftp_lock);
/* FIXME: Time out? --RR */ /* FIXME: Time out? --RR */
static unsigned int static unsigned int
...@@ -60,8 +58,6 @@ ftp_nat_expected(struct sk_buff **pskb, ...@@ -60,8 +58,6 @@ ftp_nat_expected(struct sk_buff **pskb,
DEBUGP("nat_expected: We have a connection!\n"); DEBUGP("nat_expected: We have a connection!\n");
exp_ftp_info = &ct->master->help.exp_ftp_info; exp_ftp_info = &ct->master->help.exp_ftp_info;
LOCK_BH(&ip_ftp_lock);
if (exp_ftp_info->ftptype == IP_CT_FTP_PORT if (exp_ftp_info->ftptype == IP_CT_FTP_PORT
|| exp_ftp_info->ftptype == IP_CT_FTP_EPRT) { || exp_ftp_info->ftptype == IP_CT_FTP_EPRT) {
/* PORT command: make connection go to the client. */ /* PORT command: make connection go to the client. */
...@@ -76,7 +72,6 @@ ftp_nat_expected(struct sk_buff **pskb, ...@@ -76,7 +72,6 @@ ftp_nat_expected(struct sk_buff **pskb,
DEBUGP("nat_expected: PASV cmd. %u.%u.%u.%u->%u.%u.%u.%u\n", DEBUGP("nat_expected: PASV cmd. %u.%u.%u.%u->%u.%u.%u.%u\n",
NIPQUAD(newsrcip), NIPQUAD(newdstip)); NIPQUAD(newsrcip), NIPQUAD(newdstip));
} }
UNLOCK_BH(&ip_ftp_lock);
if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC) if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC)
newip = newsrcip; newip = newsrcip;
...@@ -112,8 +107,6 @@ mangle_rfc959_packet(struct sk_buff **pskb, ...@@ -112,8 +107,6 @@ mangle_rfc959_packet(struct sk_buff **pskb,
{ {
char buffer[sizeof("nnn,nnn,nnn,nnn,nnn,nnn")]; char buffer[sizeof("nnn,nnn,nnn,nnn,nnn,nnn")];
MUST_BE_LOCKED(&ip_ftp_lock);
sprintf(buffer, "%u,%u,%u,%u,%u,%u", sprintf(buffer, "%u,%u,%u,%u,%u,%u",
NIPQUAD(newip), port>>8, port&0xFF); NIPQUAD(newip), port>>8, port&0xFF);
...@@ -135,8 +128,6 @@ mangle_eprt_packet(struct sk_buff **pskb, ...@@ -135,8 +128,6 @@ mangle_eprt_packet(struct sk_buff **pskb,
{ {
char buffer[sizeof("|1|255.255.255.255|65535|")]; char buffer[sizeof("|1|255.255.255.255|65535|")];
MUST_BE_LOCKED(&ip_ftp_lock);
sprintf(buffer, "|1|%u.%u.%u.%u|%u|", NIPQUAD(newip), port); sprintf(buffer, "|1|%u.%u.%u.%u|%u|", NIPQUAD(newip), port);
DEBUGP("calling ip_nat_mangle_tcp_packet\n"); DEBUGP("calling ip_nat_mangle_tcp_packet\n");
...@@ -157,8 +148,6 @@ mangle_epsv_packet(struct sk_buff **pskb, ...@@ -157,8 +148,6 @@ mangle_epsv_packet(struct sk_buff **pskb,
{ {
char buffer[sizeof("|||65535|")]; char buffer[sizeof("|||65535|")];
MUST_BE_LOCKED(&ip_ftp_lock);
sprintf(buffer, "|||%u|", port); sprintf(buffer, "|||%u|", port);
DEBUGP("calling ip_nat_mangle_tcp_packet\n"); DEBUGP("calling ip_nat_mangle_tcp_packet\n");
...@@ -178,7 +167,7 @@ static int (*mangle[])(struct sk_buff **, u_int32_t, u_int16_t, ...@@ -178,7 +167,7 @@ static int (*mangle[])(struct sk_buff **, u_int32_t, u_int16_t,
[IP_CT_FTP_EPSV] = mangle_epsv_packet [IP_CT_FTP_EPSV] = mangle_epsv_packet
}; };
static int ftp_data_fixup(const struct ip_ct_ftp_expect *ct_ftp_info, static int ftp_data_fixup(const struct ip_ct_ftp_expect *exp_ftp_info,
struct ip_conntrack *ct, struct ip_conntrack *ct,
struct sk_buff **pskb, struct sk_buff **pskb,
enum ip_conntrack_info ctinfo, enum ip_conntrack_info ctinfo,
...@@ -190,15 +179,14 @@ static int ftp_data_fixup(const struct ip_ct_ftp_expect *ct_ftp_info, ...@@ -190,15 +179,14 @@ static int ftp_data_fixup(const struct ip_ct_ftp_expect *ct_ftp_info,
u_int16_t port; u_int16_t port;
struct ip_conntrack_tuple newtuple; struct ip_conntrack_tuple newtuple;
MUST_BE_LOCKED(&ip_ftp_lock);
DEBUGP("FTP_NAT: seq %u + %u in %u\n", DEBUGP("FTP_NAT: seq %u + %u in %u\n",
expect->seq, ct_ftp_info->len, expect->seq, exp_ftp_info->len,
ntohl(tcph->seq)); ntohl(tcph->seq));
/* Change address inside packet to match way we're mapping /* Change address inside packet to match way we're mapping
this connection. */ this connection. */
if (ct_ftp_info->ftptype == IP_CT_FTP_PASV if (exp_ftp_info->ftptype == IP_CT_FTP_PASV
|| ct_ftp_info->ftptype == IP_CT_FTP_EPSV) { || exp_ftp_info->ftptype == IP_CT_FTP_EPSV) {
/* PASV/EPSV response: must be where client thinks server /* PASV/EPSV response: must be where client thinks server
is */ is */
newip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip; newip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip;
...@@ -220,7 +208,7 @@ static int ftp_data_fixup(const struct ip_ct_ftp_expect *ct_ftp_info, ...@@ -220,7 +208,7 @@ static int ftp_data_fixup(const struct ip_ct_ftp_expect *ct_ftp_info,
newtuple.src.u.tcp.port = expect->tuple.src.u.tcp.port; newtuple.src.u.tcp.port = expect->tuple.src.u.tcp.port;
/* Try to get same port: if not, try to change it. */ /* Try to get same port: if not, try to change it. */
for (port = ct_ftp_info->port; port != 0; port++) { for (port = exp_ftp_info->port; port != 0; port++) {
newtuple.dst.u.tcp.port = htons(port); newtuple.dst.u.tcp.port = htons(port);
if (ip_conntrack_change_expect(expect, &newtuple) == 0) if (ip_conntrack_change_expect(expect, &newtuple) == 0)
...@@ -229,9 +217,9 @@ static int ftp_data_fixup(const struct ip_ct_ftp_expect *ct_ftp_info, ...@@ -229,9 +217,9 @@ static int ftp_data_fixup(const struct ip_ct_ftp_expect *ct_ftp_info,
if (port == 0) if (port == 0)
return 0; return 0;
if (!mangle[ct_ftp_info->ftptype](pskb, newip, port, if (!mangle[exp_ftp_info->ftptype](pskb, newip, port,
expect->seq - ntohl(tcph->seq), expect->seq - ntohl(tcph->seq),
ct_ftp_info->len, ct, ctinfo)) exp_ftp_info->len, ct, ctinfo))
return 0; return 0;
return 1; return 1;
...@@ -248,12 +236,12 @@ static unsigned int help(struct ip_conntrack *ct, ...@@ -248,12 +236,12 @@ static unsigned int help(struct ip_conntrack *ct,
struct tcphdr *tcph = (void *)iph + iph->ihl*4; struct tcphdr *tcph = (void *)iph + iph->ihl*4;
unsigned int datalen; unsigned int datalen;
int dir; int dir;
struct ip_ct_ftp_expect *ct_ftp_info; struct ip_ct_ftp_expect *exp_ftp_info;
if (!exp) if (!exp)
DEBUGP("ip_nat_ftp: no exp!!"); DEBUGP("ip_nat_ftp: no exp!!");
ct_ftp_info = &exp->help.exp_ftp_info; exp_ftp_info = &exp->help.exp_ftp_info;
/* Only mangle things once: original direction in POST_ROUTING /* Only mangle things once: original direction in POST_ROUTING
and reply direction on PRE_ROUTING. */ and reply direction on PRE_ROUTING. */
...@@ -269,29 +257,23 @@ static unsigned int help(struct ip_conntrack *ct, ...@@ -269,29 +257,23 @@ static unsigned int help(struct ip_conntrack *ct,
} }
datalen = (*pskb)->len - iph->ihl * 4 - tcph->doff * 4; datalen = (*pskb)->len - iph->ihl * 4 - tcph->doff * 4;
LOCK_BH(&ip_ftp_lock);
/* If it's in the right range... */ /* If it's in the right range... */
if (between(exp->seq + ct_ftp_info->len, if (between(exp->seq + exp_ftp_info->len,
ntohl(tcph->seq), ntohl(tcph->seq),
ntohl(tcph->seq) + datalen)) { ntohl(tcph->seq) + datalen)) {
if (!ftp_data_fixup(ct_ftp_info, ct, pskb, ctinfo, exp)) { if (!ftp_data_fixup(exp_ftp_info, ct, pskb, ctinfo, exp))
UNLOCK_BH(&ip_ftp_lock);
return NF_DROP; return NF_DROP;
}
} else { } else {
/* Half a match? This means a partial retransmisison. /* Half a match? This means a partial retransmisison.
It's a cracker being funky. */ It's a cracker being funky. */
if (net_ratelimit()) { if (net_ratelimit()) {
printk("FTP_NAT: partial packet %u/%u in %u/%u\n", printk("FTP_NAT: partial packet %u/%u in %u/%u\n",
exp->seq, ct_ftp_info->len, exp->seq, exp_ftp_info->len,
ntohl(tcph->seq), ntohl(tcph->seq),
ntohl(tcph->seq) + datalen); ntohl(tcph->seq) + datalen);
} }
UNLOCK_BH(&ip_ftp_lock);
return NF_DROP; return NF_DROP;
} }
UNLOCK_BH(&ip_ftp_lock);
return NF_ACCEPT; return NF_ACCEPT;
} }
......
...@@ -45,9 +45,6 @@ MODULE_LICENSE("GPL"); ...@@ -45,9 +45,6 @@ MODULE_LICENSE("GPL");
module_param_array(ports, int, ports_c, 0400); module_param_array(ports, int, ports_c, 0400);
MODULE_PARM_DESC(ports, "port numbers of IRC servers"); MODULE_PARM_DESC(ports, "port numbers of IRC servers");
/* protects irc part of conntracks */
DECLARE_LOCK_EXTERN(ip_irc_lock);
/* FIXME: Time out? --RR */ /* FIXME: Time out? --RR */
static unsigned int static unsigned int
...@@ -88,7 +85,7 @@ irc_nat_expected(struct sk_buff **pskb, ...@@ -88,7 +85,7 @@ irc_nat_expected(struct sk_buff **pskb,
return ip_nat_setup_info(ct, &mr, hooknum); return ip_nat_setup_info(ct, &mr, hooknum);
} }
static int irc_data_fixup(const struct ip_ct_irc_expect *ct_irc_info, static int irc_data_fixup(const struct ip_ct_irc_expect *exp_irc_info,
struct ip_conntrack *ct, struct ip_conntrack *ct,
struct sk_buff **pskb, struct sk_buff **pskb,
enum ip_conntrack_info ctinfo, enum ip_conntrack_info ctinfo,
...@@ -103,23 +100,16 @@ static int irc_data_fixup(const struct ip_ct_irc_expect *ct_irc_info, ...@@ -103,23 +100,16 @@ static int irc_data_fixup(const struct ip_ct_irc_expect *ct_irc_info,
/* "4294967296 65635 " */ /* "4294967296 65635 " */
char buffer[18]; char buffer[18];
MUST_BE_LOCKED(&ip_irc_lock);
DEBUGP("IRC_NAT: info (seq %u + %u) in %u\n", DEBUGP("IRC_NAT: info (seq %u + %u) in %u\n",
expect->seq, ct_irc_info->len, expect->seq, exp_irc_info->len,
ntohl(tcph->seq)); ntohl(tcph->seq));
newip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip; newip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip;
/* Alter conntrack's expectations. */ /* Alter conntrack's expectations. */
/* We can read expect here without conntrack lock, since it's
only set in ip_conntrack_irc, with ip_irc_lock held
writable */
t = expect->tuple; t = expect->tuple;
t.dst.ip = newip; t.dst.ip = newip;
for (port = ct_irc_info->port; port != 0; port++) { for (port = exp_irc_info->port; port != 0; port++) {
t.dst.u.tcp.port = htons(port); t.dst.u.tcp.port = htons(port);
if (ip_conntrack_change_expect(expect, &t) == 0) { if (ip_conntrack_change_expect(expect, &t) == 0) {
DEBUGP("using port %d", port); DEBUGP("using port %d", port);
...@@ -149,7 +139,7 @@ static int irc_data_fixup(const struct ip_ct_irc_expect *ct_irc_info, ...@@ -149,7 +139,7 @@ static int irc_data_fixup(const struct ip_ct_irc_expect *ct_irc_info,
return ip_nat_mangle_tcp_packet(pskb, ct, ctinfo, return ip_nat_mangle_tcp_packet(pskb, ct, ctinfo,
expect->seq - ntohl(tcph->seq), expect->seq - ntohl(tcph->seq),
ct_irc_info->len, buffer, exp_irc_info->len, buffer,
strlen(buffer)); strlen(buffer));
} }
...@@ -164,12 +154,12 @@ static unsigned int help(struct ip_conntrack *ct, ...@@ -164,12 +154,12 @@ static unsigned int help(struct ip_conntrack *ct,
struct tcphdr *tcph = (void *) iph + iph->ihl * 4; struct tcphdr *tcph = (void *) iph + iph->ihl * 4;
unsigned int datalen; unsigned int datalen;
int dir; int dir;
struct ip_ct_irc_expect *ct_irc_info; struct ip_ct_irc_expect *exp_irc_info;
if (!exp) if (!exp)
DEBUGP("ip_nat_irc: no exp!!"); DEBUGP("ip_nat_irc: no exp!!");
ct_irc_info = &exp->help.exp_irc_info; exp_irc_info = &exp->help.exp_irc_info;
/* Only mangle things once: original direction in POST_ROUTING /* Only mangle things once: original direction in POST_ROUTING
and reply direction on PRE_ROUTING. */ and reply direction on PRE_ROUTING. */
...@@ -186,30 +176,24 @@ static unsigned int help(struct ip_conntrack *ct, ...@@ -186,30 +176,24 @@ static unsigned int help(struct ip_conntrack *ct,
DEBUGP("got beyond not touching\n"); DEBUGP("got beyond not touching\n");
datalen = (*pskb)->len - iph->ihl * 4 - tcph->doff * 4; datalen = (*pskb)->len - iph->ihl * 4 - tcph->doff * 4;
LOCK_BH(&ip_irc_lock);
/* Check whether the whole IP/address pattern is carried in the payload */ /* Check whether the whole IP/address pattern is carried in the payload */
if (between(exp->seq + ct_irc_info->len, if (between(exp->seq + exp_irc_info->len,
ntohl(tcph->seq), ntohl(tcph->seq),
ntohl(tcph->seq) + datalen)) { ntohl(tcph->seq) + datalen)) {
if (!irc_data_fixup(ct_irc_info, ct, pskb, ctinfo, exp)) { if (!irc_data_fixup(exp_irc_info, ct, pskb, ctinfo, exp))
UNLOCK_BH(&ip_irc_lock);
return NF_DROP; return NF_DROP;
}
} else { } else {
/* Half a match? This means a partial retransmisison. /* Half a match? This means a partial retransmisison.
It's a cracker being funky. */ It's a cracker being funky. */
if (net_ratelimit()) { if (net_ratelimit()) {
printk printk
("IRC_NAT: partial packet %u/%u in %u/%u\n", ("IRC_NAT: partial packet %u/%u in %u/%u\n",
exp->seq, ct_irc_info->len, exp->seq, exp_irc_info->len,
ntohl(tcph->seq), ntohl(tcph->seq),
ntohl(tcph->seq) + datalen); ntohl(tcph->seq) + datalen);
} }
UNLOCK_BH(&ip_irc_lock);
return NF_DROP; return NF_DROP;
} }
UNLOCK_BH(&ip_irc_lock);
return NF_ACCEPT; return NF_ACCEPT;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment