diff -urN linux-2.4.23-fixes/include/linux/netfilter_ipv4/ip_conntrack_amanda.h linux-2.4.23-pom-031219-1-subm/include/linux/netfilter_ipv4/ip_conntrack_amanda.h --- linux-2.4.23-fixes/include/linux/netfilter_ipv4/ip_conntrack_amanda.h Sat Nov 1 22:08:18 2003 +++ linux-2.4.23-pom-031219-1-subm/include/linux/netfilter_ipv4/ip_conntrack_amanda.h Sun Jan 4 19:01:09 2004 @@ -2,28 +2,11 @@ #define _IP_CONNTRACK_AMANDA_H /* AMANDA tracking. */ -#ifdef __KERNEL__ - -#include - -/* Protects amanda part of conntracks */ -DECLARE_LOCK_EXTERN(ip_amanda_lock); - -#endif - -struct conn { - char* match; - int matchlen; -}; - -#define NUM_MSGS 3 - - struct ip_ct_amanda_expect { u_int16_t port; /* port number of this expectation */ - u_int16_t offset; /* offset of the port specification in ctrl packet */ - u_int16_t len; /* the length of the port number specification */ + u_int16_t offset; /* offset of port in ctrl packet */ + u_int16_t len; /* length of the port number string */ }; #endif /* _IP_CONNTRACK_AMANDA_H */ diff -urN linux-2.4.23-fixes/include/linux/netfilter_ipv4/listhelp.h linux-2.4.23-pom-031219-1-subm/include/linux/netfilter_ipv4/listhelp.h --- linux-2.4.23-fixes/include/linux/netfilter_ipv4/listhelp.h Sun Dec 7 09:56:17 2003 +++ linux-2.4.23-pom-031219-1-subm/include/linux/netfilter_ipv4/listhelp.h Sun Jan 4 19:01:13 2004 @@ -11,48 +11,42 @@ required to allow inlining of cmpfn. */ #define LIST_FIND(head, cmpfn, type, args...) \ ({ \ - const struct list_head *__i = (head); \ + const struct list_head *__i, *__j = NULL; \ \ ASSERT_READ_LOCK(head); \ - do { \ - __i = __i->next; \ - if (__i == (head)) { \ - __i = NULL; \ + list_for_each(__i, (head)) \ + if (cmpfn((const type)__i , ## args)) { \ + __j = __i; \ break; \ } \ - } while (!cmpfn((const type)__i , ## args)); \ - (type)__i; \ + (type)__j; \ }) -#define LIST_FIND_W(head, cmpfn, type, args...) \ -({ \ - const struct list_head *__i = (head); \ - \ - ASSERT_WRITE_LOCK(head); \ - do { \ - __i = __i->next; \ - if (__i == (head)) { \ - __i = NULL; \ - break; \ - } \ - } while (!cmpfn((type)__i , ## args)); \ - (type)__i; \ +#define LIST_FIND_W(head, cmpfn, type, args...) \ +({ \ + const struct list_head *__i, *__j = NULL; \ + \ + ASSERT_WRITE_LOCK(head); \ + list_for_each(__i, (head)) \ + if (cmpfn((const type)__i , ## args)) { \ + __j = __i; \ + break; \ + } \ + (type)__j; \ }) /* Just like LIST_FIND but we search backwards */ #define LIST_FIND_B(head, cmpfn, type, args...) \ ({ \ - const struct list_head *__i = (head); \ + const struct list_head *__i, *__j = NULL; \ \ ASSERT_READ_LOCK(head); \ - do { \ - __i = __i->prev; \ - if (__i == (head)) { \ - __i = NULL; \ + list_for_each_prev(__i, (head)) \ + if (cmpfn((const type)__i , ## args)) { \ + __j = __i; \ break; \ } \ - } while (!cmpfn((const type)__i , ## args)); \ - (type)__i; \ + (type)__j; \ }) static inline int @@ -100,9 +94,9 @@ do { \ struct list_head *__i; \ ASSERT_WRITE_LOCK(head); \ - for (__i = (head)->next; \ - !cmpfn((new), (typeof (new))__i) && __i != (head); \ - __i = __i->next); \ + list_for_each(__i, (head)) \ + if ((new), (typeof (new))__i) \ + break; \ list_add((struct list_head *)(new), __i->prev); \ } while(0) diff -urN linux-2.4.23-fixes/include/linux/sysctl.h linux-2.4.23-pom-031219-1-subm/include/linux/sysctl.h --- linux-2.4.23-fixes/include/linux/sysctl.h Sat Dec 6 08:14:51 2003 +++ linux-2.4.23-pom-031219-1-subm/include/linux/sysctl.h Sun Jan 4 19:01:16 2004 @@ -376,6 +376,7 @@ NET_IPV4_NF_CONNTRACK_UDP_TIMEOUT_STREAM=11, NET_IPV4_NF_CONNTRACK_ICMP_TIMEOUT=12, NET_IPV4_NF_CONNTRACK_GENERIC_TIMEOUT=13, + NET_IPV4_NF_CONNTRACK_BUCKETS=14, }; /* /proc/sys/net/ipv6 */ diff -urN linux-2.4.23-fixes/net/ipv4/netfilter/ip_conntrack_amanda.c linux-2.4.23-pom-031219-1-subm/net/ipv4/netfilter/ip_conntrack_amanda.c --- linux-2.4.23-fixes/net/ipv4/netfilter/ip_conntrack_amanda.c Sat May 10 11:36:02 2003 +++ linux-2.4.23-pom-031219-1-subm/net/ipv4/netfilter/ip_conntrack_amanda.c Sun Jan 4 19:01:09 2004 @@ -18,13 +18,13 @@ * */ +#include #include #include #include #include #include -#include #include #include @@ -36,176 +36,96 @@ MODULE_PARM(master_timeout, "i"); MODULE_PARM_DESC(master_timeout, "timeout for the master connection"); -DECLARE_LOCK(ip_amanda_lock); -struct module *ip_conntrack_amanda = THIS_MODULE; - -#define MAXMATCHLEN 6 -struct conn conns[NUM_MSGS] = { - {"DATA ", 5}, - {"MESG ", 5}, - {"INDEX ", 6}, +static struct { char *match; int len; } conns[] = { + { "DATA ", 5}, + { "MESG ", 5}, + { "INDEX ", 6}, }; -#if 0 -#define DEBUGP printk -#else -#define DEBUGP(format, args...) -#endif +#define NUM_MSGS 3 -/* FIXME: This should be in userspace. Later. */ static int help(const struct iphdr *iph, size_t len, - struct ip_conntrack *ct, enum ip_conntrack_info ctinfo) + struct ip_conntrack *ct, enum ip_conntrack_info ctinfo) { + struct ip_conntrack_expect exp; + struct ip_ct_amanda_expect *exp_amanda_info; struct udphdr *udph = (void *)iph + iph->ihl * 4; u_int32_t udplen = len - iph->ihl * 4; u_int32_t datalen = udplen - sizeof(struct udphdr); char *data = (char *)udph + sizeof(struct udphdr); - char *datap = data; - char *data_limit = (char *) data + datalen; - int dir = CTINFO2DIR(ctinfo); - struct ip_ct_amanda *info = - (struct ip_ct_amanda *)&ct->help.ct_ftp_info; - - /* Can't track connections formed before we registered */ - if (!info) - return NF_ACCEPT; - - /* increase the UDP timeout of the master connection as replies from - * Amanda clients to the server can be quite delayed */ - ip_ct_refresh(ct, master_timeout * HZ); + char *data_limit = data + datalen; + char *start = data, *tmp; + int i; - /* If packet is coming from Amanda server */ - if (dir == IP_CT_DIR_ORIGINAL) + /* Only look at packets from the Amanda server */ + if (CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL) return NF_ACCEPT; - /* Not whole UDP header? */ if (udplen < sizeof(struct udphdr)) { - printk("ip_conntrack_amanda_help: udplen = %u\n", - (unsigned)udplen); + if (net_ratelimit()) + printk("amanda_help: udplen = %u\n", udplen); return NF_ACCEPT; } - /* Checksum invalid? Ignore. */ - if (csum_tcpudp_magic(iph->saddr, iph->daddr, udplen, IPPROTO_UDP, - csum_partial((char *)udph, udplen, 0))) { - DEBUGP("ip_ct_talk_help: bad csum: %p %u %u.%u.%u.%u " - "%u.%u.%u.%u\n", - udph, udplen, NIPQUAD(iph->saddr), - NIPQUAD(iph->daddr)); + if (udph->check && + csum_tcpudp_magic(iph->saddr, iph->daddr, udplen, IPPROTO_UDP, + csum_partial((char *)udph, udplen, 0))) return NF_ACCEPT; - } + + /* increase the UDP timeout of the master connection as replies from + * Amanda clients to the server can be quite delayed */ + ip_ct_refresh(ct, master_timeout * HZ); - /* Search for the CONNECT string */ - while (data < data_limit) { + /* Search for "CONNECT " string */ + do { + if (data + 8 >= data_limit) + return NF_ACCEPT; if (!memcmp(data, "CONNECT ", 8)) { + data += 8; break; } data++; - } - if (memcmp(data, "CONNECT ", 8)) - return NF_ACCEPT; + } while(1); - 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 += 8; - while (*data != 0x0a && data < data_limit) { - - int i; - - for (i = 0; i < NUM_MSGS; i++) { - if (!memcmp(data, conns[i].match, - conns[i].matchlen)) { - - char *portchr; - struct ip_conntrack_expect expect; - struct ip_ct_amanda_expect - *exp_amanda_info = - &expect.help.exp_amanda_info; - - memset(&expect, 0, sizeof(expect)); - - data += conns[i].matchlen; - /* this is not really tcp, but let's steal an - * idea from a tcp stream helper :-) - */ - // XXX expect.seq = data - datap; - exp_amanda_info->offset = data - datap; -// XXX DEBUGP("expect.seq = %p - %p = %d\n", data, datap, expect.seq); -DEBUGP("exp_amanda_info->offset = %p - %p = %d\n", data, datap, 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].match, - exp_amanda_info->port); - - LOCK_BH(&ip_amanda_lock); - - 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. - */ - } - UNLOCK_BH(&ip_amanda_lock); - } /* if memcmp(conns) */ - } /* for .. NUM_MSGS */ - data++; - } /* while (*data != 0x0a && data < data_limit) */ + 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; + + exp_amanda_info = &exp.help.exp_amanda_info; + for (i = 0; data + conns[i].len < data_limit && *data != '\n'; data++) { + if (memcmp(data, conns[i].match, conns[i].len)) + continue; + tmp = data += conns[i].len; + exp_amanda_info->offset = data - start; + exp_amanda_info->port = simple_strtoul(data, &data, 10); + exp_amanda_info->len = data - tmp; + if (exp_amanda_info->port == 0 || exp_amanda_info->len > 5) + break; + + exp.tuple.dst.u.tcp.port = htons(exp_amanda_info->port); + ip_conntrack_expect_related(ct, &exp); + if (++i == NUM_MSGS) + break; + } return NF_ACCEPT; } 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); } static int __init init(void) { - int ret; - - memset(&amanda_helper, 0, sizeof(struct ip_conntrack_helper)); amanda_helper.tuple.src.u.udp.port = htons(10080); amanda_helper.tuple.dst.protonum = IPPROTO_UDP; amanda_helper.mask.src.u.udp.port = 0xFFFF; @@ -213,23 +133,12 @@ amanda_helper.max_expected = NUM_MSGS; amanda_helper.timeout = 180; amanda_helper.flags = IP_CT_HELPER_F_REUSE_EXPECT; - amanda_helper.me = ip_conntrack_amanda; + amanda_helper.me = THIS_MODULE; amanda_helper.help = help; amanda_helper.name = "amanda"; - 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; + return ip_conntrack_helper_register(&amanda_helper); } - -EXPORT_SYMBOL(ip_amanda_lock); module_init(init); module_exit(fini); diff -urN linux-2.4.23-fixes/net/ipv4/netfilter/ip_conntrack_core.c linux-2.4.23-pom-031219-1-subm/net/ipv4/netfilter/ip_conntrack_core.c --- linux-2.4.23-fixes/net/ipv4/netfilter/ip_conntrack_core.c Sat Dec 6 08:14:52 2003 +++ linux-2.4.23-pom-031219-1-subm/net/ipv4/netfilter/ip_conntrack_core.c Sun Jan 4 19:01:14 2004 @@ -975,7 +975,6 @@ } } else if (related_to->helper->max_expected && related_to->expecting >= related_to->helper->max_expected) { - struct list_head *cur_item; /* old == NULL */ if (!(related_to->helper->flags & IP_CT_HELPER_F_REUSE_EXPECT)) { @@ -1000,21 +999,14 @@ NIPQUAD(related_to->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip)); /* choose the the oldest expectation to evict */ - list_for_each(cur_item, &related_to->sibling_list) { - struct ip_conntrack_expect *cur; - - cur = list_entry(cur_item, - struct ip_conntrack_expect, - expected_list); - if (cur->sibling == NULL) { - old = cur; + list_for_each_entry(old, &related_to->sibling_list, + expected_list) + if (old->sibling == NULL) break; - } - } - /* (!old) cannot happen, since related_to->expecting is the - * number of unconfirmed expects */ - IP_NF_ASSERT(old); + /* We cannot fail since related_to->expecting is the number + * of unconfirmed expectations */ + IP_NF_ASSERT(old && old->sibling == NULL); /* newnat14 does not reuse the real allocated memory * structures but rather unexpects the old and @@ -1046,7 +1038,7 @@ atomic_set(&new->use, 1); /* add to expected list for this connection */ - list_add(&new->expected_list, &related_to->sibling_list); + list_add_tail(&new->expected_list, &related_to->sibling_list); /* add to global list of expectations */ list_prepend(&ip_conntrack_expect_list, &new->list); /* add and start timer if required */ @@ -1266,14 +1258,13 @@ /* Bring out ya dead! */ static struct ip_conntrack_tuple_hash * get_next_corpse(int (*kill)(const struct ip_conntrack *i, void *data), - void *data) + void *data, unsigned int *bucket) { struct ip_conntrack_tuple_hash *h = NULL; - unsigned int i; READ_LOCK(&ip_conntrack_lock); - for (i = 0; !h && i < ip_conntrack_htable_size; i++) { - h = LIST_FIND(&ip_conntrack_hash[i], do_kill, + for (; !h && *bucket < ip_conntrack_htable_size; (*bucket)++) { + h = LIST_FIND(&ip_conntrack_hash[*bucket], do_kill, struct ip_conntrack_tuple_hash *, kill, data); } if (h) @@ -1288,9 +1279,9 @@ void *data) { struct ip_conntrack_tuple_hash *h; + unsigned int bucket = 0; - /* This is order n^2, by the way. */ - while ((h = get_next_corpse(kill, data)) != NULL) { + while ((h = get_next_corpse(kill, data, &bucket)) != NULL) { /* Time to push up daises... */ if (del_timer(&h->ctrack->timeout)) death_by_timeout((unsigned long)h->ctrack); diff -urN linux-2.4.23-fixes/net/ipv4/netfilter/ip_conntrack_standalone.c linux-2.4.23-pom-031219-1-subm/net/ipv4/netfilter/ip_conntrack_standalone.c --- linux-2.4.23-fixes/net/ipv4/netfilter/ip_conntrack_standalone.c Sat Dec 6 08:14:52 2003 +++ linux-2.4.23-pom-031219-1-subm/net/ipv4/netfilter/ip_conntrack_standalone.c Sun Jan 4 19:01:16 2004 @@ -249,6 +249,7 @@ /* From ip_conntrack_core.c */ extern int ip_conntrack_max; +extern unsigned int ip_conntrack_htable_size; /* From ip_conntrack_proto_tcp.c */ extern unsigned long ip_ct_tcp_timeout_syn_sent; @@ -275,6 +276,9 @@ static ctl_table ip_ct_sysctl_table[] = { {NET_IPV4_NF_CONNTRACK_MAX, "ip_conntrack_max", &ip_conntrack_max, sizeof(int), 0644, NULL, + &proc_dointvec}, + {NET_IPV4_NF_CONNTRACK_BUCKETS, "ip_conntrack_buckets", + &ip_conntrack_htable_size, sizeof(unsigned int), 0444, NULL, &proc_dointvec}, {NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT, "ip_conntrack_tcp_timeout_syn_sent", &ip_ct_tcp_timeout_syn_sent, sizeof(unsigned int), 0644, NULL, diff -urN linux-2.4.23-fixes/net/ipv4/netfilter/ip_conntrack_tftp.c linux-2.4.23-pom-031219-1-subm/net/ipv4/netfilter/ip_conntrack_tftp.c --- linux-2.4.23-fixes/net/ipv4/netfilter/ip_conntrack_tftp.c Mon Apr 21 22:41:13 2003 +++ linux-2.4.23-pom-031219-1-subm/net/ipv4/netfilter/ip_conntrack_tftp.c Sun Jan 4 19:01:06 2004 @@ -94,8 +94,6 @@ for (i = 0 ; (i < MAX_PORTS) && ports[i] ; i++) { /* Create helper structure */ - memset(&tftp[i], 0, sizeof(struct ip_conntrack_helper)); - tftp[i].tuple.dst.protonum = IPPROTO_UDP; tftp[i].tuple.src.u.udp.port = htons(ports[i]); tftp[i].mask.dst.protonum = 0xFFFF; diff -urN linux-2.4.23-fixes/net/ipv4/netfilter/ip_nat_amanda.c linux-2.4.23-pom-031219-1-subm/net/ipv4/netfilter/ip_nat_amanda.c --- linux-2.4.23-fixes/net/ipv4/netfilter/ip_nat_amanda.c Sat Dec 6 08:14:52 2003 +++ linux-2.4.23-pom-031219-1-subm/net/ipv4/netfilter/ip_nat_amanda.c Sun Jan 4 19:01:09 2004 @@ -11,69 +11,45 @@ * insmod ip_nat_amanda.o */ +#include #include -#include +#include +#include #include #include -#include #include #include +#include #include #include -#include #include #include -#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 "); -MODULE_DESCRIPTION("Amanda network address translation module"); +MODULE_DESCRIPTION("Amanda NAT helper"); MODULE_LICENSE("GPL"); -/* protects amanda part of conntracks */ -DECLARE_LOCK_EXTERN(ip_amanda_lock); - static unsigned int amanda_nat_expected(struct sk_buff **pskb, - unsigned int hooknum, - struct ip_conntrack *ct, - struct ip_nat_info *info) + unsigned int hooknum, + struct ip_conntrack *ct, + 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_ct_amanda_expect *exp_amanda_info; + struct ip_nat_multi_range mr; + u_int32_t newip; IP_NF_ASSERT(info); IP_NF_ASSERT(master); - 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) - newip = newsrcip; + newip = master->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip; else - newip = newdstip; - - DEBUGP("nat_expected: IP to %u.%u.%u.%u\n", NIPQUAD(newip)); + newip = master->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip; mr.rangesize = 1; /* We don't want to manip the per-protocol, just the IPs. */ @@ -81,121 +57,79 @@ mr.range[0].min_ip = mr.range[0].max_ip = newip; 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].min = mr.range[0].max = ((union ip_conntrack_manip_proto) - { .udp = { htons(port) } }); + { .udp = { htons(exp_amanda_info->port) } }); } return ip_nat_setup_info(ct, &mr, hooknum); } static int amanda_data_fixup(struct ip_conntrack *ct, - struct sk_buff **pskb, - enum ip_conntrack_info ctinfo, - struct ip_conntrack_expect *expect) + struct sk_buff **pskb, + enum ip_conntrack_info ctinfo, + struct ip_conntrack_expect *exp) { - u_int32_t newip; - /* 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_ct_amanda_expect *exp_amanda_info; struct ip_conntrack_tuple t = exp->tuple; + char buffer[sizeof("65535")]; 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. */ - - /* We can read expect here without conntrack lock, since it's - only set in ip_conntrack_amanda, with ip_amanda_lock held - writable */ - - t.dst.ip = newip; - for (port = ct_amanda_info->port; port != 0; port++) { + exp_amanda_info = &exp->help.exp_amanda_info; + t.dst.ip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip; + for (port = exp_amanda_info->port; port != 0; port++) { t.dst.u.tcp.port = htons(port); if (ip_conntrack_change_expect(exp, &t) == 0) break; } - if (port == 0) return 0; sprintf(buffer, "%u", port); - - return ip_nat_mangle_udp_packet(pskb, ct, ctinfo, /* XXX exp->seq */ ct_amanda_info->offset, - ct_amanda_info->len, buffer, strlen(buffer)); + return ip_nat_mangle_udp_packet(pskb, ct, ctinfo, + exp_amanda_info->offset, + exp_amanda_info->len, + buffer, strlen(buffer)); } static unsigned int help(struct ip_conntrack *ct, - struct ip_conntrack_expect *exp, - struct ip_nat_info *info, - enum ip_conntrack_info ctinfo, - unsigned int hooknum, - struct sk_buff **pskb) + struct ip_conntrack_expect *exp, + struct ip_nat_info *info, + enum ip_conntrack_info ctinfo, + unsigned int hooknum, + 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 and reply direction on PRE_ROUTING. */ - dir = CTINFO2DIR(ctinfo); if (!((hooknum == NF_IP_POST_ROUTING && dir == IP_CT_DIR_ORIGINAL) - || (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" : "???"); + || (hooknum == NF_IP_PRE_ROUTING && dir == IP_CT_DIR_REPLY))) return NF_ACCEPT; - } - DEBUGP("ip_nat_amanda_help: got beyond not touching: dir %s at hook %s for expect: ", - 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 this exectation has a "offset" the packet needs to be mangled */ 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)) { - UNLOCK_BH(&ip_amanda_lock); - DEBUGP("ip_nat_amanda: NF_DROP\n"); - return NF_DROP; - } + if (!amanda_data_fixup(ct, pskb, ctinfo, exp)) + ret = NF_DROP; exp->help.exp_amanda_info.offset = 0; - UNLOCK_BH(&ip_amanda_lock); - DEBUGP("ip_nat_amanda: NF_ACCEPT\n"); - return NF_ACCEPT; + return ret; } static struct ip_nat_helper ip_nat_amanda_helper; -/* This function is intentionally _NOT_ defined as __exit, because - * it is needed by init() */ -static void fini(void) +static void __exit fini(void) { - DEBUGP("ip_nat_amanda: unregistering nat helper\n"); ip_nat_helper_unregister(&ip_nat_amanda_helper); } static int __init init(void) { - int ret = 0; - struct ip_nat_helper *hlpr; - - hlpr = &ip_nat_amanda_helper; - memset(hlpr, 0, sizeof(struct ip_nat_helper)); + struct ip_nat_helper *hlpr = &ip_nat_amanda_helper; hlpr->tuple.dst.protonum = IPPROTO_UDP; hlpr->tuple.src.u.udp.port = htons(10080); @@ -205,22 +139,10 @@ hlpr->flags = 0; hlpr->me = THIS_MODULE; hlpr->expect = amanda_nat_expected; - hlpr->name = "amanda"; - DEBUGP - ("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; + return ip_nat_helper_register(hlpr); } - module_init(init); module_exit(fini); diff -urN linux-2.4.23-fixes/net/ipv4/netfilter/ip_nat_core.c linux-2.4.23-pom-031219-1-subm/net/ipv4/netfilter/ip_nat_core.c --- linux-2.4.23-fixes/net/ipv4/netfilter/ip_nat_core.c Sat Dec 6 08:14:52 2003 +++ linux-2.4.23-pom-031219-1-subm/net/ipv4/netfilter/ip_nat_core.c Sun Jan 4 19:01:10 2004 @@ -815,7 +815,7 @@ /* Have to grab read lock before sibling_list traversal */ READ_LOCK(&ip_conntrack_lock); - list_for_each(cur_item, &ct->sibling_list) { + list_for_each_prev(cur_item, &ct->sibling_list) { exp = list_entry(cur_item, struct ip_conntrack_expect, expected_list); diff -urN linux-2.4.23-fixes/net/ipv4/netfilter/ip_nat_tftp.c linux-2.4.23-pom-031219-1-subm/net/ipv4/netfilter/ip_nat_tftp.c --- linux-2.4.23-fixes/net/ipv4/netfilter/ip_nat_tftp.c Sat Dec 6 08:14:52 2003 +++ linux-2.4.23-pom-031219-1-subm/net/ipv4/netfilter/ip_nat_tftp.c Sun Jan 4 19:01:06 2004 @@ -160,8 +160,6 @@ ports[0] = TFTP_PORT; for (i = 0 ; (i < MAX_PORTS) && ports[i] ; i++) { - memset(&tftp[i], 0, sizeof(struct ip_nat_helper)); - tftp[i].tuple.dst.protonum = IPPROTO_UDP; tftp[i].tuple.src.u.udp.port = htons(ports[i]); tftp[i].mask.dst.protonum = 0xFFFF; diff -urN linux-2.4.23-fixes/net/ipv4/netfilter/ip_queue.c linux-2.4.23-pom-031219-1-subm/net/ipv4/netfilter/ip_queue.c --- linux-2.4.23-fixes/net/ipv4/netfilter/ip_queue.c Sat May 10 11:36:02 2003 +++ linux-2.4.23-pom-031219-1-subm/net/ipv4/netfilter/ip_queue.c Sun Jan 4 19:01:17 2004 @@ -585,12 +585,11 @@ 0 }; -static int sysctl_maxlen = IPQ_QMAX_DEFAULT; static struct ctl_table_header *ipq_sysctl_header; static ctl_table ipq_table[] = { - { NET_IPQ_QMAX, NET_IPQ_QMAX_NAME, &sysctl_maxlen, - sizeof(sysctl_maxlen), 0644, NULL, proc_dointvec }, + { NET_IPQ_QMAX, NET_IPQ_QMAX_NAME, &queue_maxlen, + sizeof(queue_maxlen), 0644, NULL, proc_dointvec }, { 0 } }; diff -urN linux-2.4.23-fixes/net/ipv4/netfilter/ipt_MASQUERADE.c linux-2.4.23-pom-031219-1-subm/net/ipv4/netfilter/ipt_MASQUERADE.c --- linux-2.4.23-fixes/net/ipv4/netfilter/ipt_MASQUERADE.c Sat Dec 6 08:14:52 2003 +++ linux-2.4.23-pom-031219-1-subm/net/ipv4/netfilter/ipt_MASQUERADE.c Sun Jan 4 19:01:08 2004 @@ -124,63 +124,37 @@ } static inline int -device_cmp(const struct ip_conntrack *i, void *ifindex) +device_cmp(const struct ip_conntrack *i, void *_ina) { - int ret; + int ret = 0; + struct in_ifaddr *ina = _ina; READ_LOCK(&masq_lock); - ret = (i->nat.masq_index == (int)(long)ifindex); + /* If it's masquerading out this interface with a different address, + * or we don't know the new address of this interface. */ + if (i->nat.masq_index == ina->ifa_dev->dev->ifindex + && i->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip != ina->ifa_address) + ret = 1; READ_UNLOCK(&masq_lock); return ret; } -static int masq_device_event(struct notifier_block *this, - unsigned long event, - void *ptr) -{ - struct net_device *dev = ptr; - - if (event == NETDEV_DOWN) { - /* Device was downed. Search entire table for - conntracks which were associated with that device, - and forget them. */ - IP_NF_ASSERT(dev->ifindex != 0); - - ip_ct_selective_cleanup(device_cmp, (void *)(long)dev->ifindex); - } - - return NOTIFY_DONE; -} - static int masq_inet_event(struct notifier_block *this, unsigned long event, void *ptr) { - struct net_device *dev = ((struct in_ifaddr *)ptr)->ifa_dev->dev; - - if (event == NETDEV_DOWN) { - /* IP address was deleted. Search entire table for - conntracks which were associated with that device, - and forget them. */ - IP_NF_ASSERT(dev->ifindex != 0); - - ip_ct_selective_cleanup(device_cmp, (void *)(long)dev->ifindex); - } + /* For some configurations, interfaces often come back with + * the same address. If not, clean up old conntrack + * entries. */ + if (event == NETDEV_UP) + ip_ct_selective_cleanup(device_cmp, ptr); return NOTIFY_DONE; } -static struct notifier_block masq_dev_notifier = { - masq_device_event, - NULL, - 0 -}; - static struct notifier_block masq_inet_notifier = { - masq_inet_event, - NULL, - 0 + .notifier_call = masq_inet_event }; static struct ipt_target masquerade @@ -193,12 +167,9 @@ ret = ipt_register_target(&masquerade); - if (ret == 0) { - /* Register for device down reports */ - register_netdevice_notifier(&masq_dev_notifier); + if (ret == 0) /* Register IP address change reports */ register_inetaddr_notifier(&masq_inet_notifier); - } return ret; } @@ -206,7 +177,6 @@ static void __exit fini(void) { ipt_unregister_target(&masquerade); - unregister_netdevice_notifier(&masq_dev_notifier); unregister_inetaddr_notifier(&masq_inet_notifier); } diff -urN linux-2.4.23-fixes/net/ipv4/netfilter/ipt_recent.c linux-2.4.23-pom-031219-1-subm/net/ipv4/netfilter/ipt_recent.c --- linux-2.4.23-fixes/net/ipv4/netfilter/ipt_recent.c Sat Sep 13 07:57:34 2003 +++ linux-2.4.23-pom-031219-1-subm/net/ipv4/netfilter/ipt_recent.c Sun Jan 4 19:01:11 2004 @@ -91,8 +91,10 @@ */ static spinlock_t recent_lock = SPIN_LOCK_UNLOCKED; +#ifdef CONFIG_PROC_FS /* Our /proc/net/ipt_recent entry */ static struct proc_dir_entry *proc_net_ipt_recent = NULL; +#endif /* Function declaration for later. */ static int @@ -963,8 +965,10 @@ int count; printk(version); +#ifdef CONFIG_PROC_FS proc_net_ipt_recent = proc_mkdir("ipt_recent",proc_net); if(!proc_net_ipt_recent) return -ENOMEM; +#endif if(ip_list_hash_size && ip_list_hash_size <= ip_list_tot) { printk(KERN_WARNING RECENT_NAME ": ip_list_hash_size too small, resetting to default.\n"); diff -urN linux-2.4.23-fixes/net/ipv6/netfilter/ip6_queue.c linux-2.4.23-pom-031219-1-subm/net/ipv6/netfilter/ip6_queue.c --- linux-2.4.23-fixes/net/ipv6/netfilter/ip6_queue.c Sat May 10 11:36:02 2003 +++ linux-2.4.23-pom-031219-1-subm/net/ipv6/netfilter/ip6_queue.c Sun Jan 4 19:01:17 2004 @@ -589,12 +589,11 @@ 0 }; -static int sysctl_maxlen = IPQ_QMAX_DEFAULT; static struct ctl_table_header *ipq_sysctl_header; static ctl_table ipq_table[] = { - { NET_IPQ_QMAX, NET_IPQ_QMAX_NAME, &sysctl_maxlen, - sizeof(sysctl_maxlen), 0644, NULL, proc_dointvec }, + { NET_IPQ_QMAX, NET_IPQ_QMAX_NAME, &queue_maxlen, + sizeof(queue_maxlen), 0644, NULL, proc_dointvec }, { 0 } };