Commit 36fb0cbc authored by Linus Torvalds's avatar Linus Torvalds

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

into ppc970.osdl.org:/home/torvalds/v2.5/linux
parents 9b91e15b 5c4cee5b
...@@ -1802,7 +1802,7 @@ static int hrz_send (struct atm_vcc * atm_vcc, struct sk_buff * skb) { ...@@ -1802,7 +1802,7 @@ static int hrz_send (struct atm_vcc * atm_vcc, struct sk_buff * skb) {
/********** reset a card **********/ /********** reset a card **********/
static void __init hrz_reset (const hrz_dev * dev) { static void hrz_reset (const hrz_dev * dev) {
u32 control_0_reg = rd_regl (dev, CONTROL_0_REG); u32 control_0_reg = rd_regl (dev, CONTROL_0_REG);
// why not set RESET_HORIZON to one and wait for the card to // why not set RESET_HORIZON to one and wait for the card to
......
...@@ -320,7 +320,7 @@ static int pci_slot_ar[MAX_S514_CARDS]; ...@@ -320,7 +320,7 @@ static int pci_slot_ar[MAX_S514_CARDS];
* Context: process * Context: process
*/ */
int sdladrv_init(void) static int __init sdladrv_init(void)
{ {
int i=0; int i=0;
...@@ -340,18 +340,16 @@ int sdladrv_init(void) ...@@ -340,18 +340,16 @@ int sdladrv_init(void)
return 0; return 0;
} }
#ifdef MODULE
/*============================================================================ /*============================================================================
* Module 'remove' entry point. * Module 'remove' entry point.
* o release all remaining system resources * o release all remaining system resources
*/ */
static void sdladrv_cleanup(void) static void __exit sdladrv_cleanup(void)
{ {
} }
module_init(sdladrv_init); module_init(sdladrv_init);
module_exit(sdladrv_cleanup); module_exit(sdladrv_cleanup);
#endif
/******* Kernel APIs ********************************************************/ /******* Kernel APIs ********************************************************/
......
...@@ -50,6 +50,7 @@ ...@@ -50,6 +50,7 @@
#include <linux/stddef.h> /* offsetof(), etc. */ #include <linux/stddef.h> /* offsetof(), etc. */
#include <linux/errno.h> /* return codes */ #include <linux/errno.h> /* return codes */
#include <linux/string.h> /* inline memset(), etc. */ #include <linux/string.h> /* inline memset(), etc. */
#include <linux/init.h>
#include <linux/slab.h> /* kmalloc(), kfree() */ #include <linux/slab.h> /* kmalloc(), kfree() */
#include <linux/kernel.h> /* printk(), and other useful stuff */ #include <linux/kernel.h> /* printk(), and other useful stuff */
#include <linux/module.h> /* support for loadable modules */ #include <linux/module.h> /* support for loadable modules */
...@@ -232,7 +233,7 @@ static int wanpipe_bh_critical; ...@@ -232,7 +233,7 @@ static int wanpipe_bh_critical;
* Context: process * Context: process
*/ */
int wanpipe_init(void) static int __init wanpipe_init(void)
{ {
int cnt, err = 0; int cnt, err = 0;
...@@ -297,13 +298,12 @@ int wanpipe_init(void) ...@@ -297,13 +298,12 @@ int wanpipe_init(void)
return err; return err;
} }
#ifdef MODULE
/*============================================================================ /*============================================================================
* Module 'remove' entry point. * Module 'remove' entry point.
* o unregister all adapters from the WAN router * o unregister all adapters from the WAN router
* o release all remaining system resources * o release all remaining system resources
*/ */
static void wanpipe_cleanup(void) static void __exit wanpipe_cleanup(void)
{ {
int i; int i;
...@@ -322,7 +322,6 @@ static void wanpipe_cleanup(void) ...@@ -322,7 +322,6 @@ static void wanpipe_cleanup(void)
module_init(wanpipe_init); module_init(wanpipe_init);
module_exit(wanpipe_cleanup); module_exit(wanpipe_cleanup);
#endif
/******* WAN Device Driver Entry Points *************************************/ /******* WAN Device Driver Entry Points *************************************/
......
...@@ -2,20 +2,11 @@ ...@@ -2,20 +2,11 @@
#define _IP_CONNTRACK_AMANDA_H #define _IP_CONNTRACK_AMANDA_H
/* AMANDA tracking. */ /* AMANDA tracking. */
#ifdef __KERNEL__
#include <linux/netfilter_ipv4/lockhelp.h>
/* Protects amanda part of conntracks */
DECLARE_LOCK_EXTERN(ip_amanda_lock);
#endif
struct ip_ct_amanda_expect struct ip_ct_amanda_expect
{ {
u_int16_t port; /* port number of this expectation */ u_int16_t port; /* port number of this expectation */
u_int16_t offset; /* offset of the port specification in ctrl packet */ u_int16_t offset; /* offset of port in ctrl packet */
u_int16_t len; /* the length of the port number specification */ u_int16_t len; /* length of the port number string */
}; };
#endif /* _IP_CONNTRACK_AMANDA_H */ #endif /* _IP_CONNTRACK_AMANDA_H */
...@@ -885,7 +885,7 @@ static void *arp_get_idx(struct arp_state *state, loff_t l) ...@@ -885,7 +885,7 @@ static void *arp_get_idx(struct arp_state *state, loff_t l)
if (v) if (v)
goto done; goto done;
} }
state->n = clip_tbl_hook->hash_buckets[state->bucket + 1]; state->n = clip_tbl.hash_buckets[state->bucket + 1];
} }
done: done:
return v; return v;
...@@ -896,18 +896,12 @@ static void *arp_seq_start(struct seq_file *seq, loff_t *pos) ...@@ -896,18 +896,12 @@ static void *arp_seq_start(struct seq_file *seq, loff_t *pos)
struct arp_state *state = seq->private; struct arp_state *state = seq->private;
void *ret = (void *)1; void *ret = (void *)1;
if (!clip_tbl_hook) { read_lock_bh(&clip_tbl.lock);
state->bucket = -1;
goto out;
}
read_lock_bh(&clip_tbl_hook->lock);
state->bucket = 0; state->bucket = 0;
state->n = clip_tbl_hook->hash_buckets[0]; state->n = clip_tbl.hash_buckets[0];
state->vcc = (void *)1; state->vcc = (void *)1;
if (*pos) if (*pos)
ret = arp_get_idx(state, *pos); ret = arp_get_idx(state, *pos);
out:
return ret; return ret;
} }
...@@ -916,7 +910,7 @@ static void arp_seq_stop(struct seq_file *seq, void *v) ...@@ -916,7 +910,7 @@ static void arp_seq_stop(struct seq_file *seq, void *v)
struct arp_state *state = seq->private; struct arp_state *state = seq->private;
if (state->bucket != -1) if (state->bucket != -1)
read_unlock_bh(&clip_tbl_hook->lock); read_unlock_bh(&clip_tbl.lock);
} }
static void *arp_seq_next(struct seq_file *seq, void *v, loff_t *pos) static void *arp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
......
...@@ -617,10 +617,15 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char *optval, int opt ...@@ -617,10 +617,15 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char *optval, int opt
} }
case IP_MSFILTER: case IP_MSFILTER:
{ {
extern int sysctl_optmem_max;
struct ip_msfilter *msf; struct ip_msfilter *msf;
if (optlen < IP_MSFILTER_SIZE(0)) if (optlen < IP_MSFILTER_SIZE(0))
goto e_inval; goto e_inval;
if (optlen > sysctl_optmem_max) {
err = -ENOBUFS;
break;
}
msf = (struct ip_msfilter *)kmalloc(optlen, GFP_KERNEL); msf = (struct ip_msfilter *)kmalloc(optlen, GFP_KERNEL);
if (msf == 0) { if (msf == 0) {
err = -ENOBUFS; err = -ENOBUFS;
...@@ -631,7 +636,9 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char *optval, int opt ...@@ -631,7 +636,9 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char *optval, int opt
kfree(msf); kfree(msf);
break; break;
} }
if (IP_MSFILTER_SIZE(msf->imsf_numsrc) > optlen) { if (IP_MSFILTER_SIZE(msf->imsf_numsrc) <
IP_MSFILTER_SIZE(0) ||
IP_MSFILTER_SIZE(msf->imsf_numsrc) > optlen) {
kfree(msf); kfree(msf);
err = -EINVAL; err = -EINVAL;
break; break;
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
* *
*/ */
#include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/netfilter.h> #include <linux/netfilter.h>
#include <linux/ip.h> #include <linux/ip.h>
...@@ -36,50 +37,37 @@ MODULE_LICENSE("GPL"); ...@@ -36,50 +37,37 @@ MODULE_LICENSE("GPL");
MODULE_PARM(master_timeout, "i"); MODULE_PARM(master_timeout, "i");
MODULE_PARM_DESC(master_timeout, "timeout for the master connection"); MODULE_PARM_DESC(master_timeout, "timeout for the master connection");
DECLARE_LOCK(ip_amanda_lock); static char *conns[] = { "DATA ", "MESG ", "INDEX " };
char *conns[] = { "DATA ", "MESG ", "INDEX " };
#if 0
#define DEBUGP printk
#else
#define DEBUGP(format, args...)
#endif
/* This is slow, but it's simple. --RR */ /* This is slow, but it's simple. --RR */
static char amanda_buffer[65536]; static char amanda_buffer[65536];
static DECLARE_LOCK(amanda_buffer_lock);
static int help(struct sk_buff *skb, static int help(struct sk_buff *skb,
struct ip_conntrack *ct, enum ip_conntrack_info ctinfo) struct ip_conntrack *ct, enum ip_conntrack_info ctinfo)
{ {
char *data, *data_limit; struct ip_conntrack_expect exp;
int dir = CTINFO2DIR(ctinfo); struct ip_ct_amanda_expect *exp_amanda_info;
char *data, *data_limit, *tmp;
unsigned int dataoff, i; unsigned int dataoff, i;
struct ip_ct_amanda *info =
(struct ip_ct_amanda *)&ct->help.ct_ftp_info;
/* Can't track connections formed before we registered */ /* Only look at packets from the Amanda server */
if (!info) if (CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL)
return NF_ACCEPT; return NF_ACCEPT;
/* increase the UDP timeout of the master connection as replies from /* increase the UDP timeout of the master connection as replies from
* Amanda clients to the server can be quite delayed */ * Amanda clients to the server can be quite delayed */
ip_ct_refresh(ct, master_timeout * HZ); ip_ct_refresh(ct, master_timeout * HZ);
/* If packet is coming from Amanda server */
if (dir == IP_CT_DIR_ORIGINAL)
return NF_ACCEPT;
/* No data? */ /* No data? */
dataoff = skb->nh.iph->ihl*4 + sizeof(struct udphdr); dataoff = skb->nh.iph->ihl*4 + sizeof(struct udphdr);
if (dataoff >= skb->len) { if (dataoff >= skb->len) {
if (net_ratelimit()) if (net_ratelimit())
printk("ip_conntrack_amanda_help: skblen = %u\n", printk("amanda_help: skblen = %u\n", skb->len);
(unsigned)skb->len);
return NF_ACCEPT; return NF_ACCEPT;
} }
LOCK_BH(&ip_amanda_lock); LOCK_BH(&amanda_buffer_lock);
skb_copy_bits(skb, dataoff, amanda_buffer, skb->len - dataoff); skb_copy_bits(skb, dataoff, amanda_buffer, skb->len - dataoff);
data = amanda_buffer; data = amanda_buffer;
data_limit = amanda_buffer + skb->len - dataoff; data_limit = amanda_buffer + skb->len - dataoff;
...@@ -89,84 +77,39 @@ static int help(struct sk_buff *skb, ...@@ -89,84 +77,39 @@ static int help(struct sk_buff *skb,
data = strstr(data, "CONNECT "); data = strstr(data, "CONNECT ");
if (!data) if (!data)
goto out; goto out;
DEBUGP("ip_conntrack_amanda_help: CONNECT found in connection "
"%u.%u.%u.%u:%u %u.%u.%u.%u:%u\n",
NIPQUAD(iph->saddr), htons(udph->source),
NIPQUAD(iph->daddr), htons(udph->dest));
data += strlen("CONNECT "); data += strlen("CONNECT ");
memset(&exp, 0, sizeof(exp));
exp.tuple.src.ip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip;
exp.tuple.dst.ip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip;
exp.tuple.dst.protonum = IPPROTO_TCP;
exp.mask.src.ip = 0xFFFFFFFF;
exp.mask.dst.ip = 0xFFFFFFFF;
exp.mask.dst.protonum = 0xFFFF;
exp.mask.dst.u.tcp.port = 0xFFFF;
/* Only search first line. */ /* Only search first line. */
if (strchr(data, '\n')) if ((tmp = strchr(data, '\n')))
*strchr(data, '\n') = '\0'; *tmp = '\0';
exp_amanda_info = &exp.help.exp_amanda_info;
for (i = 0; i < ARRAY_SIZE(conns); i++) { for (i = 0; i < ARRAY_SIZE(conns); i++) {
char *match = strstr(data, conns[i]); char *match = strstr(data, conns[i]);
if (match) { if (!match)
char *portchr; continue;
struct ip_conntrack_expect expect; tmp = data = match + strlen(conns[i]);
struct ip_ct_amanda_expect *exp_amanda_info = exp_amanda_info->offset = data - amanda_buffer;
&expect.help.exp_amanda_info; exp_amanda_info->port = simple_strtoul(data, &data, 10);
exp_amanda_info->len = data - tmp;
memset(&expect, 0, sizeof(expect)); if (exp_amanda_info->port == 0 || exp_amanda_info->len > 5)
break;
data += strlen(conns[i]);
/* this is not really tcp, but let's steal an exp.tuple.dst.u.tcp.port = htons(exp_amanda_info->port);
* idea from a tcp stream helper :-) */ ip_conntrack_expect_related(ct, &exp);
// XXX expect.seq = data - amanda_buffer;
exp_amanda_info->offset = data - amanda_buffer;
// XXX DEBUGP("expect.seq = %p - %p = %d\n", data, amanda_buffer, expect.seq);
DEBUGP("exp_amanda_info->offset = %p - %p = %d\n", data, amanda_buffer, exp_amanda_info->offset);
portchr = data;
exp_amanda_info->port = simple_strtoul(data, &data,10);
exp_amanda_info->len = data - portchr;
/* eat whitespace */
while (*data == ' ')
data++;
DEBUGP("ip_conntrack_amanda_help: "
"CONNECT %s request with port "
"%u found\n", conns[i],
exp_amanda_info->port);
expect.tuple = ((struct ip_conntrack_tuple)
{ { ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip,
{ 0 } },
{ ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip,
{ htons(exp_amanda_info->port) },
IPPROTO_TCP }});
expect.mask = ((struct ip_conntrack_tuple)
{ { 0, { 0 } },
{ 0xFFFFFFFF, { 0xFFFF }, 0xFFFF }});
expect.expectfn = NULL;
DEBUGP ("ip_conntrack_amanda_help: "
"expect_related: %u.%u.%u.%u:%u - "
"%u.%u.%u.%u:%u\n",
NIPQUAD(expect.tuple.src.ip),
ntohs(expect.tuple.src.u.tcp.port),
NIPQUAD(expect.tuple.dst.ip),
ntohs(expect.tuple.dst.u.tcp.port));
if (ip_conntrack_expect_related(ct, &expect)
== -EEXIST) {
;
/* this must be a packet being resent */
/* XXX - how do I get the
* ip_conntrack_expect that
* already exists so that I can
* update the .seq so that the
* nat module rewrites the port
* numbers?
* Perhaps I should use the
* exp_amanda_info instead of
* .seq.
*/
}
}
} }
out:
UNLOCK_BH(&ip_amanda_lock); out:
UNLOCK_BH(&amanda_buffer_lock);
return NF_ACCEPT; return NF_ACCEPT;
} }
...@@ -186,29 +129,16 @@ static struct ip_conntrack_helper amanda_helper = { ...@@ -186,29 +129,16 @@ static struct ip_conntrack_helper amanda_helper = {
}, },
}; };
static void fini(void) static void __exit fini(void)
{ {
DEBUGP("ip_ct_amanda: unregistering helper for port 10080\n");
ip_conntrack_helper_unregister(&amanda_helper); ip_conntrack_helper_unregister(&amanda_helper);
} }
static int __init init(void) static int __init init(void)
{ {
int ret; return ip_conntrack_helper_register(&amanda_helper);
DEBUGP("ip_ct_amanda: registering helper for port 10080\n");
ret = ip_conntrack_helper_register(&amanda_helper);
if (ret) {
printk("ip_ct_amanda: ERROR registering helper\n");
fini();
return -EBUSY;
}
return 0;
} }
PROVIDES_CONNTRACK(amanda); PROVIDES_CONNTRACK(amanda);
EXPORT_SYMBOL(ip_amanda_lock);
module_init(init); module_init(init);
module_exit(fini); module_exit(fini);
...@@ -11,69 +11,45 @@ ...@@ -11,69 +11,45 @@
* insmod ip_nat_amanda.o * insmod ip_nat_amanda.o
*/ */
#include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/netfilter_ipv4.h> #include <linux/netfilter.h>
#include <linux/skbuff.h>
#include <linux/ip.h> #include <linux/ip.h>
#include <linux/udp.h> #include <linux/udp.h>
#include <linux/kernel.h>
#include <net/tcp.h> #include <net/tcp.h>
#include <net/udp.h> #include <net/udp.h>
#include <linux/netfilter_ipv4.h>
#include <linux/netfilter_ipv4/ip_nat.h> #include <linux/netfilter_ipv4/ip_nat.h>
#include <linux/netfilter_ipv4/ip_nat_helper.h> #include <linux/netfilter_ipv4/ip_nat_helper.h>
#include <linux/netfilter_ipv4/ip_nat_rule.h>
#include <linux/netfilter_ipv4/ip_conntrack_helper.h> #include <linux/netfilter_ipv4/ip_conntrack_helper.h>
#include <linux/netfilter_ipv4/ip_conntrack_amanda.h> #include <linux/netfilter_ipv4/ip_conntrack_amanda.h>
#if 0
#define DEBUGP printk
#define DUMP_OFFSET(x) printk("offset_before=%d, offset_after=%d, correction_pos=%u\n", x->offset_before, x->offset_after, x->correction_pos);
#else
#define DEBUGP(format, args...)
#define DUMP_OFFSET(x)
#endif
MODULE_AUTHOR("Brian J. Murrell <netfilter@interlinx.bc.ca>"); MODULE_AUTHOR("Brian J. Murrell <netfilter@interlinx.bc.ca>");
MODULE_DESCRIPTION("Amanda NAT helper"); MODULE_DESCRIPTION("Amanda NAT helper");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
/* protects amanda part of conntracks */
DECLARE_LOCK_EXTERN(ip_amanda_lock);
static unsigned int static unsigned int
amanda_nat_expected(struct sk_buff **pskb, amanda_nat_expected(struct sk_buff **pskb,
unsigned int hooknum, unsigned int hooknum,
struct ip_conntrack *ct, struct ip_conntrack *ct,
struct ip_nat_info *info) struct ip_nat_info *info)
{ {
struct ip_nat_multi_range mr;
u_int32_t newdstip, newsrcip, newip;
u_int16_t port;
struct ip_ct_amanda_expect *exp_info;
struct ip_conntrack *master = master_ct(ct); struct ip_conntrack *master = master_ct(ct);
struct ip_ct_amanda_expect *exp_amanda_info;
struct ip_nat_multi_range mr;
u_int32_t newip;
IP_NF_ASSERT(info); IP_NF_ASSERT(info);
IP_NF_ASSERT(master); IP_NF_ASSERT(master);
IP_NF_ASSERT(!(info->initialized & (1 << HOOK2MANIP(hooknum)))); IP_NF_ASSERT(!(info->initialized & (1 << HOOK2MANIP(hooknum))));
DEBUGP("nat_expected: We have a connection!\n");
exp_info = &ct->master->help.exp_amanda_info;
newdstip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip;
newsrcip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip;
DEBUGP("nat_expected: %u.%u.%u.%u->%u.%u.%u.%u\n",
NIPQUAD(newsrcip), NIPQUAD(newdstip));
port = exp_info->port;
if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC) if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC)
newip = newsrcip; newip = master->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip;
else else
newip = newdstip; newip = master->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip;
DEBUGP("nat_expected: IP to %u.%u.%u.%u\n", NIPQUAD(newip));
mr.rangesize = 1; mr.rangesize = 1;
/* We don't want to manip the per-protocol, just the IPs. */ /* We don't want to manip the per-protocol, just the IPs. */
...@@ -81,121 +57,79 @@ amanda_nat_expected(struct sk_buff **pskb, ...@@ -81,121 +57,79 @@ amanda_nat_expected(struct sk_buff **pskb,
mr.range[0].min_ip = mr.range[0].max_ip = newip; mr.range[0].min_ip = mr.range[0].max_ip = newip;
if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_DST) { if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_DST) {
exp_amanda_info = &ct->master->help.exp_amanda_info;
mr.range[0].flags |= IP_NAT_RANGE_PROTO_SPECIFIED; mr.range[0].flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
mr.range[0].min = mr.range[0].max mr.range[0].min = mr.range[0].max
= ((union ip_conntrack_manip_proto) = ((union ip_conntrack_manip_proto)
{ .udp = { htons(port) } }); { .udp = { htons(exp_amanda_info->port) } });
} }
return ip_nat_setup_info(ct, &mr, hooknum); return ip_nat_setup_info(ct, &mr, hooknum);
} }
static int amanda_data_fixup(struct ip_conntrack *ct, static int amanda_data_fixup(struct ip_conntrack *ct,
struct sk_buff **pskb, struct sk_buff **pskb,
enum ip_conntrack_info ctinfo, enum ip_conntrack_info ctinfo,
struct ip_conntrack_expect *expect) struct ip_conntrack_expect *exp)
{ {
u_int32_t newip; struct ip_ct_amanda_expect *exp_amanda_info;
/* DATA 99999 MESG 99999 INDEX 99999 */
char buffer[6];
struct ip_conntrack_expect *exp = expect;
struct ip_ct_amanda_expect *ct_amanda_info = &exp->help.exp_amanda_info;
struct ip_conntrack_tuple t = exp->tuple; struct ip_conntrack_tuple t = exp->tuple;
char buffer[sizeof("65535")];
u_int16_t port; u_int16_t port;
MUST_BE_LOCKED(&ip_amanda_lock);
newip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip;
DEBUGP ("ip_nat_amanda_help: newip = %u.%u.%u.%u\n", NIPQUAD(newip));
/* Alter conntrack's expectations. */ /* Alter conntrack's expectations. */
exp_amanda_info = &exp->help.exp_amanda_info;
/* We can read expect here without conntrack lock, since it's t.dst.ip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip;
only set in ip_conntrack_amanda, with ip_amanda_lock held for (port = exp_amanda_info->port; port != 0; port++) {
writable */
t.dst.ip = newip;
for (port = ct_amanda_info->port; port != 0; port++) {
t.dst.u.tcp.port = htons(port); t.dst.u.tcp.port = htons(port);
if (ip_conntrack_change_expect(exp, &t) == 0) if (ip_conntrack_change_expect(exp, &t) == 0)
break; break;
} }
if (port == 0) if (port == 0)
return 0; return 0;
sprintf(buffer, "%u", port); sprintf(buffer, "%u", port);
return ip_nat_mangle_udp_packet(pskb, ct, ctinfo,
return ip_nat_mangle_udp_packet(pskb, ct, ctinfo, /* XXX exp->seq */ ct_amanda_info->offset, exp_amanda_info->offset,
ct_amanda_info->len, buffer, strlen(buffer)); exp_amanda_info->len,
buffer, strlen(buffer));
} }
static unsigned int help(struct ip_conntrack *ct, static unsigned int help(struct ip_conntrack *ct,
struct ip_conntrack_expect *exp, struct ip_conntrack_expect *exp,
struct ip_nat_info *info, struct ip_nat_info *info,
enum ip_conntrack_info ctinfo, enum ip_conntrack_info ctinfo,
unsigned int hooknum, unsigned int hooknum,
struct sk_buff **pskb) struct sk_buff **pskb)
{ {
int dir; int dir = CTINFO2DIR(ctinfo);
int ret = NF_ACCEPT;
if (!exp)
DEBUGP("ip_nat_amanda: no exp!!");
/* 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. */
dir = CTINFO2DIR(ctinfo);
if (!((hooknum == NF_IP_POST_ROUTING && dir == IP_CT_DIR_ORIGINAL) if (!((hooknum == NF_IP_POST_ROUTING && dir == IP_CT_DIR_ORIGINAL)
|| (hooknum == NF_IP_PRE_ROUTING && dir == IP_CT_DIR_REPLY))) { || (hooknum == NF_IP_PRE_ROUTING && dir == IP_CT_DIR_REPLY)))
DEBUGP("ip_nat_amanda_help: Not touching dir %s at hook %s\n",
dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY",
hooknum == NF_IP_POST_ROUTING ? "POSTROUTING"
: hooknum == NF_IP_PRE_ROUTING ? "PREROUTING"
: hooknum == NF_IP_LOCAL_OUT ? "OUTPUT"
: hooknum == NF_IP_LOCAL_IN ? "INPUT" : "???");
return NF_ACCEPT; return NF_ACCEPT;
}
DEBUGP("ip_nat_amanda_help: got beyond not touching: dir %s at hook %s for expect: ", /* if this exectation has a "offset" the packet needs to be mangled */
dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY",
hooknum == NF_IP_POST_ROUTING ? "POSTROUTING"
: hooknum == NF_IP_PRE_ROUTING ? "PREROUTING"
: hooknum == NF_IP_LOCAL_OUT ? "OUTPUT"
: hooknum == NF_IP_LOCAL_IN ? "INPUT" : "???");
DUMP_TUPLE(&exp->tuple);
LOCK_BH(&ip_amanda_lock);
// XXX if (exp->seq != 0)
if (exp->help.exp_amanda_info.offset != 0) if (exp->help.exp_amanda_info.offset != 0)
/* if this packet has a "seq" it needs to have it's content mangled */ if (!amanda_data_fixup(ct, pskb, ctinfo, exp))
if (!amanda_data_fixup(ct, pskb, ctinfo, exp)) { ret = NF_DROP;
UNLOCK_BH(&ip_amanda_lock);
DEBUGP("ip_nat_amanda: NF_DROP\n");
return NF_DROP;
}
exp->help.exp_amanda_info.offset = 0; exp->help.exp_amanda_info.offset = 0;
UNLOCK_BH(&ip_amanda_lock);
DEBUGP("ip_nat_amanda: NF_ACCEPT\n"); return ret;
return NF_ACCEPT;
} }
static struct ip_nat_helper ip_nat_amanda_helper; static struct ip_nat_helper ip_nat_amanda_helper;
/* This function is intentionally _NOT_ defined as __exit, because static void __exit fini(void)
* it is needed by init() */
static void fini(void)
{ {
DEBUGP("ip_nat_amanda: unregistering nat helper\n");
ip_nat_helper_unregister(&ip_nat_amanda_helper); ip_nat_helper_unregister(&ip_nat_amanda_helper);
} }
static int __init init(void) static int __init init(void)
{ {
int ret = 0; struct ip_nat_helper *hlpr = &ip_nat_amanda_helper;
struct ip_nat_helper *hlpr;
hlpr = &ip_nat_amanda_helper;
memset(hlpr, 0, sizeof(struct ip_nat_helper));
hlpr->tuple.dst.protonum = IPPROTO_UDP; hlpr->tuple.dst.protonum = IPPROTO_UDP;
hlpr->tuple.src.u.udp.port = htons(10080); hlpr->tuple.src.u.udp.port = htons(10080);
...@@ -205,20 +139,9 @@ static int __init init(void) ...@@ -205,20 +139,9 @@ static int __init init(void)
hlpr->flags = 0; hlpr->flags = 0;
hlpr->me = THIS_MODULE; hlpr->me = THIS_MODULE;
hlpr->expect = amanda_nat_expected; hlpr->expect = amanda_nat_expected;
hlpr->name = "amanda"; hlpr->name = "amanda";
DEBUGP return ip_nat_helper_register(hlpr);
("ip_nat_amanda: Trying to register nat helper\n");
ret = ip_nat_helper_register(hlpr);
if (ret) {
printk
("ip_nat_amanda: error registering nat helper\n");
fini();
return 1;
}
return ret;
} }
NEEDS_CONNTRACK(amanda); NEEDS_CONNTRACK(amanda);
......
...@@ -436,10 +436,15 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname, char *optval, ...@@ -436,10 +436,15 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname, char *optval,
} }
case MCAST_MSFILTER: case MCAST_MSFILTER:
{ {
extern int sysctl_optmem_max;
struct group_filter *gsf; struct group_filter *gsf;
if (optlen < GROUP_FILTER_SIZE(0)) if (optlen < GROUP_FILTER_SIZE(0))
goto e_inval; goto e_inval;
if (optlen > sysctl_optmem_max) {
retv = -ENOBUFS;
break;
}
gsf = (struct group_filter *)kmalloc(optlen,GFP_KERNEL); gsf = (struct group_filter *)kmalloc(optlen,GFP_KERNEL);
if (gsf == 0) { if (gsf == 0) {
retv = -ENOBUFS; retv = -ENOBUFS;
...@@ -450,7 +455,8 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname, char *optval, ...@@ -450,7 +455,8 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname, char *optval,
kfree(gsf); kfree(gsf);
break; break;
} }
if (GROUP_FILTER_SIZE(gsf->gf_numsrc) > optlen) { if (GROUP_FILTER_SIZE(gsf->gf_numsrc) < GROUP_FILTER_SIZE(0) ||
GROUP_FILTER_SIZE(gsf->gf_numsrc) > optlen) {
kfree(gsf); kfree(gsf);
retv = -EINVAL; retv = -EINVAL;
break; break;
......
...@@ -381,6 +381,7 @@ static int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk, ...@@ -381,6 +381,7 @@ static int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk,
if (flags & MSG_ERRQUEUE) if (flags & MSG_ERRQUEUE)
return ipv6_recv_error(sk, msg, len); return ipv6_recv_error(sk, msg, len);
try_again:
skb = skb_recv_datagram(sk, flags, noblock, &err); skb = skb_recv_datagram(sk, flags, noblock, &err);
if (!skb) if (!skb)
goto out; goto out;
...@@ -458,12 +459,13 @@ static int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk, ...@@ -458,12 +459,13 @@ static int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk,
kfree_skb(skb); kfree_skb(skb);
} }
/* Error for blocking case is chosen to masquerade skb_free_datagram(sk, skb);
as some normal condition.
*/ if (flags & MSG_DONTWAIT) {
err = (flags&MSG_DONTWAIT) ? -EAGAIN : -EHOSTUNREACH; UDP6_INC_STATS_USER(UdpInErrors);
UDP6_INC_STATS_USER(UdpInErrors); return -EAGAIN;
goto out_free; }
goto try_again;
} }
static void udpv6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, static void udpv6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
......
...@@ -1927,10 +1927,6 @@ int sock_unregister(int family) ...@@ -1927,10 +1927,6 @@ int sock_unregister(int family)
extern void sk_init(void); extern void sk_init(void);
#ifdef CONFIG_WAN_ROUTER
extern void wanrouter_init(void);
#endif
void __init sock_init(void) void __init sock_init(void)
{ {
int i; int i;
...@@ -1955,14 +1951,6 @@ void __init sock_init(void) ...@@ -1955,14 +1951,6 @@ void __init sock_init(void)
skb_init(); skb_init();
#endif #endif
/*
* Wan router layer.
*/
#ifdef CONFIG_WAN_ROUTER
wanrouter_init();
#endif
/* /*
* Initialize the protocols module. * Initialize the protocols module.
*/ */
......
...@@ -46,6 +46,7 @@ ...@@ -46,6 +46,7 @@
#include <linux/stddef.h> /* offsetof(), etc. */ #include <linux/stddef.h> /* offsetof(), etc. */
#include <linux/errno.h> /* return codes */ #include <linux/errno.h> /* return codes */
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h> /* support for loadable modules */ #include <linux/module.h> /* support for loadable modules */
#include <linux/slab.h> /* kmalloc(), kfree() */ #include <linux/slab.h> /* kmalloc(), kfree() */
#include <linux/mm.h> /* verify_area(), etc. */ #include <linux/mm.h> /* verify_area(), etc. */
...@@ -164,13 +165,9 @@ static unsigned char wanrouter_oui_ether[] = { 0x00, 0x00, 0x00 }; ...@@ -164,13 +165,9 @@ static unsigned char wanrouter_oui_ether[] = { 0x00, 0x00, 0x00 };
static unsigned char wanrouter_oui_802_2[] = { 0x00, 0x80, 0xC2 }; static unsigned char wanrouter_oui_802_2[] = { 0x00, 0x80, 0xC2 };
#endif #endif
#ifndef MODULE static int __init wanrouter_init(void)
int wanrouter_init(void)
{ {
int err; int err;
extern int wanpipe_init(void);
extern int sdladrv_init(void);
printk(KERN_INFO "%s v%u.%u %s\n", printk(KERN_INFO "%s v%u.%u %s\n",
wanrouter_fullname, ROUTER_VERSION, ROUTER_RELEASE, wanrouter_fullname, ROUTER_VERSION, ROUTER_RELEASE,
...@@ -181,15 +178,6 @@ int wanrouter_init(void) ...@@ -181,15 +178,6 @@ int wanrouter_init(void)
printk(KERN_INFO "%s: can't create entry in proc filesystem!\n", printk(KERN_INFO "%s: can't create entry in proc filesystem!\n",
wanrouter_modname); wanrouter_modname);
/*
* Initialise compiled in boards
*/
#ifdef CONFIG_VENDOR_SANGOMA
sdladrv_init();
wanpipe_init();
#endif
return err; return err;
} }
...@@ -198,50 +186,13 @@ static void __exit wanrouter_cleanup (void) ...@@ -198,50 +186,13 @@ static void __exit wanrouter_cleanup (void)
wanrouter_proc_cleanup(); wanrouter_proc_cleanup();
} }
#else
/*
* Kernel Loadable Module Entry Points
*/
/* /*
* Module 'insert' entry point. * This is just plain dumb. We should move the bugger to drivers/net/wan,
* o print announcement * slap it first in directory and make it module_init(). The only reason
* o initialize static data * for subsys_initcall() here is that net goes after drivers (why, BTW?)
* o create /proc/net/router directory and static entries
*
* Return: 0 Ok
* < 0 error.
* Context: process
*/ */
subsys_initcall(wanrouter_init)
int init_module (void) module_exit(wanrouter_cleanup)
{
int err;
printk(KERN_INFO "%s v%u.%u %s\n",
wanrouter_fullname, ROUTER_VERSION, ROUTER_RELEASE,
wanrouter_copyright);
err = wanrouter_proc_init();
if (err)
printk(KERN_INFO "%s: can't create entry in proc filesystem!\n",
wanrouter_modname);
return err;
}
/*
* Module 'remove' entry point.
* o delete /proc/net/router directory and static entries.
*/
void cleanup_module (void)
{
wanrouter_proc_cleanup();
}
#endif
/* /*
* Kernel APIs * Kernel APIs
......
...@@ -1052,9 +1052,8 @@ static int xfrm_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *xt, ...@@ -1052,9 +1052,8 @@ static int xfrm_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *xt,
struct sk_buff *skb; struct sk_buff *skb;
size_t len; size_t len;
len = RTA_LENGTH(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr); len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr);
len = RTA_ALIGN(len); len += NLMSG_SPACE(sizeof(struct xfrm_user_acquire));
len += NLMSG_ALIGN(NLMSG_LENGTH(sizeof(struct xfrm_user_acquire)));
skb = alloc_skb(len, GFP_ATOMIC); skb = alloc_skb(len, GFP_ATOMIC);
if (skb == NULL) if (skb == NULL)
return -ENOMEM; return -ENOMEM;
...@@ -1151,9 +1150,8 @@ static int xfrm_send_policy_notify(struct xfrm_policy *xp, int dir, int hard) ...@@ -1151,9 +1150,8 @@ static int xfrm_send_policy_notify(struct xfrm_policy *xp, int dir, int hard)
struct sk_buff *skb; struct sk_buff *skb;
size_t len; size_t len;
len = sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr; len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr);
len = RTA_ALIGN(RTA_LENGTH(len)); len += NLMSG_SPACE(sizeof(struct xfrm_user_polexpire));
len += NLMSG_ALIGN(NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_info)));
skb = alloc_skb(len, GFP_ATOMIC); skb = alloc_skb(len, GFP_ATOMIC);
if (skb == NULL) if (skb == NULL)
return -ENOMEM; return -ENOMEM;
......
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