[netfilter-cvslog] r3566 - in trunk: nfsim nfsim/core
nfsim/core/ipv4 nfsim/kernelenv nfsim/kernelenv/include
nfsim/tools nfsim-testsuite nfsim-testsuite/01iptables
nfsim-testsuite/02conntrack
rusty at netfilter.org
rusty at netfilter.org
Tue Jan 4 10:11:30 CET 2005
Author: rusty at netfilter.org
Date: 2005-01-04 10:11:29 +0100 (Tue, 04 Jan 2005)
New Revision: 3566
Modified:
trunk/nfsim-testsuite/01iptables/01reject.sim
trunk/nfsim-testsuite/02conntrack/07fragments.sim
trunk/nfsim-testsuite/README
trunk/nfsim-testsuite/test.sh
trunk/nfsim/core/core.c
trunk/nfsim/core/core.h
trunk/nfsim/core/ipv4/ipv4.c
trunk/nfsim/core/ipv4/ipv4.h
trunk/nfsim/core/tui.c
trunk/nfsim/kernelenv/include/kernelenv.h
trunk/nfsim/kernelenv/kernelenv.c
trunk/nfsim/netfilter.c.sed
trunk/nfsim/tools/gen_err.c
trunk/nfsim/tools/gen_ip.c
trunk/nfsim/tools/time.c
Log:
Major nfsim rework for nonlinear skbs, and to make valgrind clean:
override skb_ip_make_writable to record which parts are writable
and make worst-cast split packet, and always realloc.
fix fragment size, and skb len
Real ip_select_ident so field is initialized
Fix truncated packet descriptions
Remove broken "command not found" expect handling (current_cmd is NULL)
Implement nfsim_check_packet, call in various places.
Remove skb->malloc_data.
Move skb_shinfo to hidden field, not end of data, so valgrind can see overruns.
nfsim_nonlinear_skb() and nfsim_skb() allocators.
panic() turned to barf() (don't rely on kernel routines)
Fix timer use-after-free bug.
Initialize all fields in packet, esp. padding and mac addresses.
Valgrind is now only run with --valgrind, not just because it's installed.
"time +infinity" fixed everywhere, and "time garbage" caught.
Found many kernel bugs with this!
Modified: trunk/nfsim/core/core.c
===================================================================
--- trunk/nfsim/core/core.c 2005-01-03 09:55:14 UTC (rev 3565)
+++ trunk/nfsim/core/core.c 2005-01-04 09:11:29 UTC (rev 3566)
@@ -138,6 +138,8 @@
unsigned int ret;
char *hookname = talloc_asprintf(NULL, "%s:%i", __func__, hooknum);
+ nfsim_check_packet(*skb);
+
if (should_i_fail(hookname)) {
talloc_free(hookname);
return NF_DROP;
Modified: trunk/nfsim/core/core.h
===================================================================
--- trunk/nfsim/core/core.h 2005-01-03 09:55:14 UTC (rev 3565)
+++ trunk/nfsim/core/core.h 2005-01-04 09:11:29 UTC (rev 3566)
@@ -51,6 +51,14 @@
int nf_rcv(struct sk_buff *skb);
int nf_rcv_local(struct sk_buff *skb);
+/* Create an skb: first amount that is linear, then the rest. */
+struct sk_buff *nfsim_nonlinear_skb(const void *data1, unsigned int size1,
+ const void *data2, unsigned int size2);
+
+/* Check packet is OK. */
+void nfsim_check_packet(const struct sk_buff *skb);
+/* Internal routine to say we updated packet. */
+void nfsim_update_skb(struct sk_buff *skb, void *p, unsigned int size);
/*
* simulator queueing
*/
@@ -238,8 +246,6 @@
return len;
}
-int skb_ip_make_writable(struct sk_buff **pskb, unsigned int writable_len);
-
unsigned int skb_checksum(const struct sk_buff *skb, int offset,
int len, unsigned int csum);
Modified: trunk/nfsim/core/ipv4/ipv4.c
===================================================================
--- trunk/nfsim/core/ipv4/ipv4.c 2005-01-03 09:55:14 UTC (rev 3565)
+++ trunk/nfsim/core/ipv4/ipv4.c 2005-01-04 09:11:29 UTC (rev 3566)
@@ -349,11 +349,14 @@
kfree_skb(skb);
return 1;
}
+ nfsim_update_skb(skb, &skb->nh.iph->ttl, sizeof(skb->nh.iph->ttl));
check = skb->nh.iph->check;
check += htons(0x0100);
skb->nh.iph->check = check + (check>=0xFFFF);
+ /* Tell nfsim it's me changing data here. */
+ nfsim_update_skb(skb, &skb->nh.iph->check, sizeof(skb->nh.iph->check));
/* FIXME: strict source routing... */
@@ -497,9 +500,8 @@
max = len + off;
memset(filled + off, 1, len);
- memcpy(data + off, (void *)f->frags[i]->nh.iph
- + f->frags[i]->nh.iph->ihl * 4,
- len);
+ skb_copy_bits(f->frags[i], f->frags[i]->nh.iph->ihl * 4,
+ data + off, len);
if (!(ntohs(f->frags[i]->nh.iph->frag_off) & IP_MF))
ended = true;
}
@@ -517,11 +519,11 @@
skb->nh.iph = (void *)skb->data;
memcpy(skb->nh.iph, f->frags[0]->nh.iph, f->frags[0]->nh.iph->ihl*4);
- memcpy((void *)skb->nh.iph + f->frags[0]->nh.iph->ihl*4, data, len);
+ memcpy(skb_put(skb, max), data, max);
/* Except we're not a fragment, and we're longer. */
skb->nh.iph->frag_off = 0;
- skb->nh.iph->tot_len = max + skb->nh.iph->ihl*4;
+ skb->nh.iph->tot_len = htons(max + skb->nh.iph->ihl*4);
list_del(&f->list);
talloc_free(f);
@@ -731,6 +733,11 @@
return addr;
}
+void ip_select_ident(struct iphdr *iph, struct dst_entry *dst, struct sock *sk)
+{
+ iph->id = 0;
+}
+
static char *print_data(char *ptr, const char *data, int len)
{
int i;
@@ -807,6 +814,7 @@
goto out;
iplen = htons(iph->tot_len) - sizeof(struct iphdr);
+ len -= sizeof(struct iphdr);
switch (iph->protocol) {
case IPPROTO_ICMP:
@@ -814,7 +822,7 @@
ptr += sprintf(ptr, "%u %u ",
iplen - sizeof(struct icmphdr), iph->protocol);
- if (len - sizeof(struct iphdr) < sizeof(struct icmphdr)) {
+ if (len < sizeof(struct icmphdr)) {
ptr += sprintf(ptr, "-TRUNCATED-");
goto out;
}
@@ -850,8 +858,7 @@
ptr += sprintf(ptr, "%u %u ",
iplen - sizeof(struct udphdr), iph->protocol);
- if (len - sizeof(struct iphdr) <
- sizeof(struct udphdr)) {
+ if (len < sizeof(struct udphdr)) {
ptr += sprintf(ptr, "-TRUNCATED-");
goto out;
}
@@ -882,13 +889,16 @@
case IPPROTO_TCP:
tcph = (struct tcphdr *)(iph + 1);
- ptr += sprintf(ptr, "%u %u ",
- iplen - tcph->doff*4, iph->protocol);
+ if (len < sizeof(struct tcphdr)) {
+ /* Assume no tcp options... */
+ ptr += sprintf(ptr, "%u %u ",
+ iplen - sizeof(*tcph), iph->protocol);
- if (len - sizeof(struct iphdr) < sizeof(struct tcphdr)) {
ptr += sprintf(ptr, "-TRUNCATED-");
goto out;
}
+ ptr += sprintf(ptr, "%u %u ",
+ iplen - tcph->doff*4, iph->protocol);
ptr += sprintf(ptr, "%u %u ",
ntohs(tcph->source), ntohs(tcph->dest));
@@ -957,6 +967,10 @@
default:
ptr += sprintf(ptr, "%u %u", iplen, iph->protocol);
+ if (len < iplen) {
+ ptr += sprintf(ptr, "-TRUNCATED-");
+ goto out;
+ }
}
out:
@@ -970,8 +984,11 @@
char *ipv4_describe_packet(struct sk_buff *skb)
{
static char ipv4_pbuf[1024];
+ char packet[skb->len];
- describe(ipv4_pbuf, skb->len, skb->nh.iph,
+ if (skb_copy_bits(skb, 0, packet, skb->len) != 0)
+ barf("skb_copy_bits failed");
+ describe(ipv4_pbuf, skb->len, (struct iphdr *)packet,
field_value(skb, "dump_flags"));
return ipv4_pbuf;
}
Modified: trunk/nfsim/core/ipv4/ipv4.h
===================================================================
--- trunk/nfsim/core/ipv4/ipv4.h 2005-01-03 09:55:14 UTC (rev 3565)
+++ trunk/nfsim/core/ipv4/ipv4.h 2005-01-04 09:11:29 UTC (rev 3566)
@@ -448,7 +448,7 @@
};
-#define ip_select_ident(iph,dst,sk)
+void ip_select_ident(struct iphdr *iph, struct dst_entry *dst, struct sock *sk);
/* fib */
enum
Modified: trunk/nfsim/core/tui.c
===================================================================
--- trunk/nfsim/core/tui.c 2005-01-03 09:55:14 UTC (rev 3565)
+++ trunk/nfsim/core/tui.c 2005-01-04 09:11:29 UTC (rev 3566)
@@ -212,10 +212,10 @@
return ret;
}
- /* Someone might expect this command not to be found? */
- if (!nfsim_log(LOG_UI, "%s: command not found", argv[0])
- && abort)
+ if (abort)
script_fail("%s not found", argv[0]);
+
+ nfsim_log(LOG_UI, "%s: command not found", argv[0]);
return false;
}
Modified: trunk/nfsim/kernelenv/include/kernelenv.h
===================================================================
--- trunk/nfsim/kernelenv/include/kernelenv.h 2005-01-03 09:55:14 UTC (rev 3565)
+++ trunk/nfsim/kernelenv/include/kernelenv.h 2005-01-04 09:11:29 UTC (rev 3566)
@@ -479,8 +479,7 @@
#endif
- unsigned char *malloc_data,
- *head,
+ unsigned char *head,
*data,
*tail,
*end;
@@ -517,12 +516,9 @@
extern void nf_ct_attach(struct sk_buff *, struct sk_buff *);
-#define alloc_skb(size, gfp) __alloc_skb((size), (gfp), __location__)
-struct sk_buff *__alloc_skb(unsigned int size, int gfp_mask, const char *loc);
+struct sk_buff *alloc_skb(unsigned int size, int priority);
void kfree_skb(struct sk_buff *skb);
-#define dev_alloc_skb(s) alloc_skb(s,0)
-
unsigned int skb_headroom(const struct sk_buff *skb);
unsigned int skb_tailroom(const struct sk_buff *skb);
@@ -551,9 +547,9 @@
void skb_orphan(struct sk_buff *skb);
-int skb_is_nonlinear(struct sk_buff *skb);
+int skb_is_nonlinear(const struct sk_buff *skb);
-#define skb_linearize(skb, len) 0
+extern int skb_linearize(struct sk_buff *skb, int gfp);
#define skb_copy(skb, gfp) \
skb_copy_expand(skb, skb_headroom(skb), skb_tailroom(skb), gfp)
@@ -565,7 +561,7 @@
extern int skb_checksum_help(struct sk_buff *skb, int inward);
#endif
-#define skb_shinfo(SKB) ((struct skb_shared_info *)((SKB)->end))
+extern struct skb_shared_info *skb_shinfo(struct sk_buff *skb);
void *skb_header_pointer(const struct sk_buff *skb, int offset,
int len, void *buffer);
@@ -618,6 +614,12 @@
void skb_set_owner_w(struct sk_buff *skb, struct sock *sk);
struct sk_buff *skb_realloc_headroom(struct sk_buff *skb, unsigned int headroom);
+
+int skb_ip_make_writable(struct sk_buff **pskb, unsigned int writable_len);
+
+/* netfilter.c's version: unused. */
+int __unused_skb_ip_make_writable(struct sk_buff **, unsigned int);
+
/* net.h */
#define net_ratelimit() 1
Modified: trunk/nfsim/kernelenv/kernelenv.c
===================================================================
--- trunk/nfsim/kernelenv/kernelenv.c 2005-01-03 09:55:14 UTC (rev 3565)
+++ trunk/nfsim/kernelenv/kernelenv.c 2005-01-04 09:11:29 UTC (rev 3566)
@@ -32,35 +32,127 @@
unsigned long jiffies = INITIAL_JIFFIES;
/* skbuff */
-struct sk_buff *alloc_skb_internal(unsigned int size, int gfp_mask, const char *loc)
+static int nfsim_seq;
+
+/* We hide the shared info in hidden field (kernel puts it after
+ * data). This way valgrind can spot overruns. */
+struct skb_shared_info *skb_shinfo(struct sk_buff *skb)
{
+ return field_value(skb, "skb_shinfo");
+}
+
+struct skb_extra_info {
+ void *data;
+ unsigned int len, writable_len;
+};
+
+/* Create an skb: first amount that is linear, then the rest. */
+struct sk_buff *nfsim_nonlinear_skb(const void *data1, unsigned int size1,
+ const void *data2, unsigned int size2)
+{
struct sk_buff *skb;
- static int seq;
+ struct skb_shared_info *sinfo;
+ struct skb_extra_info *extra;
- /* skb, followed by data, followed by skb_shinfo */
- skb = talloc_zero_named_const(__skb_ctx, sizeof(struct sk_buff) +
- sizeof(struct skb_shared_info) + size,
- loc);
+ /* Skb header. */
+ skb = talloc_zero(__skb_ctx, struct sk_buff);
+ /* Save copy of data, all non-writable. */
+ extra = talloc(skb, struct skb_extra_info);
+ extra->len = size1 + size2;
+ extra->writable_len = 0;
+ extra->data = talloc_size(extra, extra->len);
+ memcpy(extra->data, data1, size1);
+ memcpy(extra->data+size1, data2, size2);
+ field_attach(skb, "extra_data", extra);
+
+ /* Place linear data in skb. */
+ skb->data = talloc_memdup(skb, extra->data, size1);
+
+ sinfo = talloc(skb, struct skb_shared_info);
+ field_attach(skb, "skb_shinfo", sinfo);
+
atomic_set(&skb->users, 1);
- skb->head = skb->data = skb->tail = (char *)skb + sizeof(struct sk_buff);
+ skb->head = skb->data;
+ skb->end = skb->tail = skb->data + size1;
+ skb->len = size1 + size2;
+
+ skb->seq = ++nfsim_seq;
+
+ /* set shinfo fields */
+ skb_shinfo(skb)->tso_size = 0;
+
+ return skb;
+}
+
+/* Normal, linear skb. */
+static struct sk_buff *nfsim_skb(unsigned int size)
+{
+ struct sk_buff *skb;
+ struct skb_shared_info *sinfo;
+
+ /* Skb header. */
+ skb = talloc_zero(__skb_ctx, struct sk_buff);
+
+ /* Place linear data in skb. */
+ skb->data = talloc_size(skb, size);
+ sinfo = talloc(skb, struct skb_shared_info);
+ field_attach(skb, "skb_shinfo", sinfo);
+
+ atomic_set(&skb->users, 1);
+ skb->head = skb->tail = skb->data;
+ skb->len = 0;
skb->end = skb->data + size;
- skb->seq = ++seq;
+ skb->seq = ++nfsim_seq;
/* set shinfo fields */
skb_shinfo(skb)->tso_size = 0;
+ return skb;
+}
- return skb;
+void nfsim_check_packet(const struct sk_buff *skb)
+{
+ struct skb_extra_info *extra = field_value(skb, "extra_data");
+ unsigned int linear_len = skb->end - skb->head;
+
+ if (!extra)
+ return;
+
+ /* Packet should not have been changed where not writable. */
+ if (memcmp(skb->head + extra->writable_len,
+ extra->data + extra->writable_len,
+ linear_len - extra->writable_len) != 0)
+ barf("skb modified without being made writable!");
}
-struct sk_buff *__alloc_skb(unsigned int size, int gfp_mask, const char *loc)
+/* Internal routine to say we updated skb. */
+void nfsim_update_skb(struct sk_buff *skb, void *p, unsigned int size)
{
- if (should_i_fail(loc))
+ struct skb_extra_info *extra = field_value(skb, "extra_data");
+ unsigned int off = p - (void *)skb->head;
+
+ if (!extra)
+ return;
+
+ if (off + size > extra->len)
+ barf("Bad nfsim_update_skb %i");
+
+ /* If it wasn't already writable, copy update to master. */
+ if (off + size > extra->writable_len)
+ memcpy(extra->data + off, p, size);
+
+ nfsim_check_packet(skb);
+}
+
+/* Defined to return a linear skb. */
+struct sk_buff *alloc_skb(unsigned int size, int priority)
+{
+ if (should_i_fail(__func__))
return NULL;
- return alloc_skb_internal(size, gfp_mask, loc);
+ return nfsim_skb(size);
}
void kfree_skb(struct sk_buff *skb)
@@ -74,16 +166,13 @@
talloc_free(skb);
}
-
unsigned char *skb_put(struct sk_buff *skb, unsigned int len)
{
unsigned char *tmp = skb->tail;
skb->tail += len;
skb->len += len;
- if (skb->tail > skb->end) {
- panic("skb_put will overrun buffer");
- /* panic ? */
- }
+ if (skb->tail > skb->end)
+ barf("skb_put will overrun buffer");
return tmp;
}
@@ -91,10 +180,8 @@
{
skb->data -= len;
skb->len += len;
- if (skb->data < skb->head) {
- panic("skb_push will underrun buffer");
- /* panic */
- }
+ if (skb->data < skb->head)
+ barf("skb_push will underrun buffer");
return skb->data;
}
@@ -103,42 +190,35 @@
skb->data += len;
skb->len -= len;
- if (skb->data < skb->head) {
- panic("skb_pull will underrun buffer");
- /* panic */
- }
+ if (skb->data < skb->head)
+ barf("skb_pull will underrun buffer");
+
return skb->data;
}
+/* Defined to return a writable, linear skb. */
struct sk_buff *skb_copy_expand(const struct sk_buff *skb,
int newheadroom, int newtailroom, int gfp_mask)
{
- struct sk_buff *n = alloc_skb(newheadroom + skb->len + newtailroom, 0);
+ struct sk_buff *n;
- if (!n)
- return 0;
-
+ nfsim_check_packet(skb);
+
+ if (should_i_fail(__func__))
+ return NULL;
+
+ n = nfsim_skb(newheadroom + skb->len + newtailroom);
skb_reserve(n, newheadroom);
-
skb_put(n, skb->len);
- if (skb_copy_bits(skb, 0, n->data, skb->len)) {
- panic("skb_copy_bits failed");
- /* panic */
- }
+ if (skb_copy_bits(skb, 0, n->data, skb->len))
+ barf("skb_copy_bits failed");
copy_skb_header(n, skb);
return n;
}
-/*
-unsigned int skb_headlen(const struct sk_buff *skb)
-{
- return skb->len - skb->data_len;
-}
-*/
-
unsigned int skb_headroom(const struct sk_buff *skb)
{
return skb->data - skb->head;
@@ -146,13 +226,15 @@
unsigned int skb_tailroom(const struct sk_buff *skb)
{
- return skb->end - skb->tail;
+ return skb_is_nonlinear(skb) ? 0 : skb->end - skb->tail;
}
void skb_reserve(struct sk_buff *skb, unsigned int len)
{
skb->data += len;
skb->tail += len;
+ if (skb->data > skb->end || skb->tail > skb->end)
+ barf("skb_reserve: too much");
}
/* careful with this one.. */
@@ -191,14 +273,35 @@
#undef __copy
+static inline int nfsim_linear_length(const struct sk_buff *skb)
+{
+ return skb->end - skb->data;
+}
-int skb_copy_bits(const struct sk_buff *skb, int offset,
- void *to, int len)
+int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len)
{
+ struct skb_extra_info *extra = field_value(skb, "extra_data");
+
+ nfsim_check_packet(skb);
+
if (offset > (int)skb->len - len)
return -EFAULT;
- memcpy(to, skb->data + offset, len);
+ /* Can we copy some from linear part of packet? */
+ if (offset < nfsim_linear_length(skb)) {
+ int len_from_data = min(len, nfsim_linear_length(skb)-offset);
+
+ memcpy(to, skb->data + offset, len_from_data);
+ offset += len_from_data;
+ len -= len_from_data;
+ to += len_from_data;
+ }
+
+ /* Copy from nonlinear part. */
+ if (extra)
+ memcpy(to, extra->data + skb_headroom(skb) + offset, len);
+ else
+ assert(len == 0);
return 0;
}
@@ -282,11 +385,12 @@
unsigned int skb_checksum(const struct sk_buff *skb, int offset,
int len, unsigned int csum)
{
- assert(offset + len <= skb->len);
+ char data[len];
- csum = csum_partial(skb->data + offset, len, csum);
+ if (skb_copy_bits(skb, offset, data, len) != 0)
+ barf("skb_checksum invalid length");
- return csum;
+ return csum_partial(data, len, csum);
}
void __skb_trim(struct sk_buff *skb, unsigned int len)
@@ -309,20 +413,89 @@
skb->sk = NULL;
}
-/* FIXME: nonlinear skb support would be good. */
-int skb_is_nonlinear(struct sk_buff *skb)
+int skb_is_nonlinear(const struct sk_buff *skb)
{
+ nfsim_check_packet(skb);
+
+ return skb->data + skb->len > skb->end;
+}
+
+int skb_ip_make_writable(struct sk_buff **pskb, unsigned int writable_len)
+{
+ struct sk_buff *new;
+ struct skb_extra_info *extra;
+ char data[(*pskb)->len];
+
+ nfsim_check_packet(*pskb);
+
+ if (writable_len > (*pskb)->len)
+ return 0;
+
+ if (should_i_fail(__func__))
+ return 0;
+
+ /* Use skb_copy_bits, which handles packet whatever shape. */
+ skb_copy_bits(*pskb, 0, data, (*pskb)->len);
+
+ /* Always reallocate, to catch cached pointers. */
+ new = nfsim_nonlinear_skb(data, writable_len,
+ data + writable_len,
+ (*pskb)->len - writable_len);
+ copy_skb_header(new, *pskb);
+ extra = field_value(new, "extra_data");
+ extra->writable_len = writable_len;
+
+ if ((*pskb)->sk)
+ skb_set_owner_w(new, (*pskb)->sk);
+
+ kfree_skb(*pskb);
+ *pskb = new;
+ return 1;
+}
+
+int skb_linearize(struct sk_buff *skb, int len)
+{
+ unsigned char *new_head;
+ unsigned int headroom = skb_headroom(skb);
+
+ nfsim_check_packet(skb);
+
+ if (should_i_fail(__func__))
+ return -ENOMEM;
+
+ new_head = talloc_size(skb, skb->len + headroom);
+ memcpy(new_head, skb->head, headroom);
+ skb_copy_bits(skb, 0, new_head + headroom, skb->len);
+
+ skb->data = new_head + headroom;
+ skb->tail = skb->end = new_head + headroom + skb->len;
+ talloc_free(skb->head);
+ skb->head = new_head;
+
+ /* Don't need this on writable, linear packets. */
+ field_detach(skb, "extra_data");
return 0;
}
+/* Either copy into buffer or give pointer to in-place. */
void *skb_header_pointer(const struct sk_buff *skb, int offset,
int len, void *buffer)
{
- /* We're always linear. */
+ nfsim_check_packet(skb);
+
if (offset + len > skb->len)
return NULL;
- return skb->data + offset;
+ /* We should test copying even if not required. */
+ if (!should_i_fail_once(__func__)) {
+ if (offset + len <= nfsim_linear_length(skb))
+ return skb->data + offset;
+ }
+
+ if (skb_copy_bits(skb, offset, buffer, len) < 0)
+ barf("skb_header_pointer: logic error");
+
+ return buffer;
}
void sock_hold(struct sock *sk)
@@ -422,33 +595,6 @@
return (struct ethhdr *)skb->mac.raw;
}
-/*
-{
- unsigned int csum;
- int offset = (*pskb)->h.raw - (*pskb)->data;
-
- if (inward) {
- (*pskb)->ip_summed = CHECKSUM_NONE;
- return 0;
- }
-
- if (offset > (int)skb->len)
- BUG();
- csum = skb_checksum((*pskb), offset, (*pskb)->len-offset, 0);
-
- offset = (*pskb)->tail - (*pskb)->h.raw;
- if (offset <= 0)
- BUG();
- if ((*pskb)->csum + 2 > offset)
- BUG();
-
- *(u16*)((*pskb)->h.raw + (*pskb)->csum) = csum_fold(csum);
- (*pskb)->ip_summed = CHECKSUM_NONE;
-
- return 0;
-}
-*/
-
/* spinlock: use talloc for unreleased lock detection */
void __generic_write_lock(spinlock_t *lock, const char *location)
{
@@ -622,8 +768,8 @@
struct timer_list *t, *next;
list_for_each_entry_safe(t, next, &__running_timers, entry) {
list_del(&t->entry);
+ talloc_free(t->use);
t->function(t->data);
- talloc_free(t->use);
}
return true;
}
@@ -664,9 +810,9 @@
t->ownerfunction, t->function);
i = i->next;
list_del(&t->entry);
- t->function(t->data);
talloc_free(t->use);
t->use = NULL;
+ t->function(t->data);
}
}
Modified: trunk/nfsim/netfilter.c.sed
===================================================================
--- trunk/nfsim/netfilter.c.sed 2005-01-03 09:55:14 UTC (rev 3565)
+++ trunk/nfsim/netfilter.c.sed 2005-01-04 09:11:29 UTC (rev 3566)
@@ -4,5 +4,6 @@
s/^int nf_register_hook(/int __nf_register_hook(/
s/^void nf_unregister_sockopt(/void __nf_unregister_sockopt(/
s/^void nf_unregister_hook(/void __nf_unregister_hook(/
+s/^int skb_ip_make_writable(/int __unused_skb_ip_make_writable(/
Modified: trunk/nfsim/tools/gen_err.c
===================================================================
--- trunk/nfsim/tools/gen_err.c 2005-01-03 09:55:14 UTC (rev 3565)
+++ trunk/nfsim/tools/gen_err.c 2005-01-04 09:11:29 UTC (rev 3566)
@@ -45,6 +45,9 @@
return false;
}
+ packet->pad = 0;
+ memset(&packet->ehdr, 0, sizeof(packet->ehdr));
+ packet->ehdr.h_proto = htons(ETH_P_IP);
packet->iph = ((struct iphdr)
{
#if __BYTE_ORDER == __LITTLE_ENDIAN
Modified: trunk/nfsim/tools/gen_ip.c
===================================================================
--- trunk/nfsim/tools/gen_ip.c 2005-01-03 09:55:14 UTC (rev 3565)
+++ trunk/nfsim/tools/gen_ip.c 2005-01-04 09:11:29 UTC (rev 3566)
@@ -552,21 +552,20 @@
struct sk_buff *skb;
int len;
- len = 16 + ntohs(packet->iph.tot_len);
+ /* Ethernet header and IPv4 headers are linear for netfilter hooks. */
+ len = offsetof(struct packet, iph) + packet->iph.ihl*4;
+ skb = nfsim_nonlinear_skb(packet, len, (void *)packet + len,
+ offsetof(struct packet, iph)
+ + ntohs(packet->iph.tot_len) - len);
+ nfsim_check_packet(skb);
- skb = alloc_skb_internal(len + 4096, 0, "send_packet");
-
- skb_reserve(skb, 2048);
- skb_put(skb, len);
+ skb->mac.ethernet = (void *)skb->data + offsetof(struct packet, ehdr);
+ skb->nh.iph = (void *)skb->data + offsetof(struct packet, iph);
+ skb->protocol = skb->mac.ethernet->h_proto;
- memcpy(skb->data, packet, len);
+ /* You'll need to linearize to get this one. */
+ skb->h.raw = NULL;
- skb->mac.ethernet = (void *)(skb->data + offsetof(struct packet, ehdr));
- skb->nh.iph = (void *)(skb->data + offsetof(struct packet, iph));
- skb->h.raw = skb->data + offsetof(struct packet, u);
-
- skb->protocol = skb->mac.ethernet->h_proto;
-
if (dump_flags)
field_attach(skb, "dump_flags", dump_flags);
@@ -732,6 +731,9 @@
}
argc--;
argv++;
+ } else {
+ memset(packet->ehdr.h_dest, 0, sizeof(packet->ehdr.h_dest));
+ memset(packet->ehdr.h_source, 0,sizeof(packet->ehdr.h_source));
}
if (argc > 5 && strncmp(argv[1], "TOS=", 4) == 0) {
@@ -835,6 +837,7 @@
if (ce)
packet->iph.frag_off |= htons(IP_CE);
+ packet->pad = 0;
packet->iph.check = ~csum_partial(&packet->iph, sizeof(packet->iph),0);
packet->ehdr.h_proto = htons(ETH_P_IP);
return true;
Modified: trunk/nfsim/tools/time.c
===================================================================
--- trunk/nfsim/tools/time.c 2005-01-03 09:55:14 UTC (rev 3565)
+++ trunk/nfsim/tools/time.c 2005-01-04 09:11:29 UTC (rev 3566)
@@ -42,15 +42,20 @@
}
if (argc == 2) {
- if (*argv[1] == '+') {
+ if (streq(argv[1], "+infinity")) {
+ increment_time(find_last_timer() - jiffies);
+ } else if (*argv[1] == '+') {
increment_time(atoi(argv[1]+1) * HZ);
} else if (*argv[1] == '-') {
nfsim_log(LOG_ALWAYS, "Backwards time travel not "
"implemented");
return false;
- } else if (streq(argv[1], "infinity")) {
- increment_time(find_last_timer() - jiffies);
} else {
+ if (atoi(argv[1]) == 0) {
+ nfsim_log(LOG_ALWAYS,
+ "Bad time argument %s", argv[1]);
+ return false;
+ }
if (atoi(argv[1]) * HZ < jiffies) {
nfsim_log(LOG_ALWAYS,
"Flares alert: Backwards time travel not "
@@ -83,7 +88,7 @@
</cmdsynopsis>
<cmdsynopsis>
<command>time</command>
- <arg choice="req">+intinife</arg>
+ <arg choice="req">+infinity</arg>
</cmdsynopsis>
<para><command>time</command> with no arguments will show the current
kernel time (in seconds).</para>
Modified: trunk/nfsim-testsuite/01iptables/01reject.sim
===================================================================
--- trunk/nfsim-testsuite/01iptables/01reject.sim 2005-01-03 09:55:14 UTC (rev 3565)
+++ trunk/nfsim-testsuite/01iptables/01reject.sim 2005-01-04 09:11:29 UTC (rev 3566)
@@ -7,9 +7,9 @@
gen_ip IF=eth0 192.168.0.2 192.168.0.1 10 17 1 2
# nothing in return for an ICMP error.
-expect gen_err hook:NF_IP_LOCAL_IN * NF_DROP {IPv4 192.168.0.2 192.168.0.1 30 1 3 0 CONTAINS 192.168.0.1 192.168.0.2 10 17 1 2}
+expect gen_err hook:NF_IP_LOCAL_IN * NF_DROP {IPv4 192.168.0.2 192.168.0.1 38 1 3 0 CONTAINS 192.168.0.1 192.168.0.2 10 17 1 2}
expect ! gen_err send:eth0*
-gen_err IF=eth0 LEN=30 192.168.0.2 3 0 192.168.0.1 192.168.0.2 10 17 1 2
+gen_err IF=eth0 LEN=38 192.168.0.2 3 0 192.168.0.1 192.168.0.2 10 17 1 2
iptables -D INPUT -j REJECT
Modified: trunk/nfsim-testsuite/02conntrack/07fragments.sim
===================================================================
--- trunk/nfsim-testsuite/02conntrack/07fragments.sim 2005-01-03 09:55:14 UTC (rev 3565)
+++ trunk/nfsim-testsuite/02conntrack/07fragments.sim 2005-01-04 09:11:29 UTC (rev 3566)
@@ -7,13 +7,13 @@
expect ! proc *
proc /proc/net/ip_conntrack
-expect gen_ip hook:NF_IP_PRE_ROUTING ip_conntrack NF_ACCEPT {IPv4 192.168.0.2 192.168.1.2 21484 3}
+expect gen_ip hook:NF_IP_PRE_ROUTING ip_conntrack NF_ACCEPT {IPv4 192.168.0.2 192.168.1.2 64 3}
gen_ip IF=eth0 FRAG=32,32 192.168.0.2 192.168.1.2 64 3
expect proc unknown 3 600 src=192.168.0.2 dst=192.168.1.2 *[UNREPLIED] src=192.168.1.2 dst=192.168.0.2 *use=1
proc cat /proc/net/ip_conntrack
-time infinity
+time +infinity
# Reverse order should be the same.
expect gen_ip hook:NF_IP_PRE_ROUTING * NF_STOLEN
@@ -23,7 +23,7 @@
expect ! proc *
proc cat /proc/net/ip_conntrack
-expect gen_ip hook:NF_IP_PRE_ROUTING ip_conntrack NF_ACCEPT {IPv4 192.168.0.2 192.168.1.2 21484 3}
+expect gen_ip hook:NF_IP_PRE_ROUTING ip_conntrack NF_ACCEPT {IPv4 192.168.0.2 192.168.1.2 64 3}
gen_ip IF=eth0 FRAG=0,32 MF 192.168.0.2 192.168.1.2 64 3
expect proc unknown 3 600 src=192.168.0.2 dst=192.168.1.2 *[UNREPLIED] src=192.168.1.2 dst=192.168.0.2 *use=1
Modified: trunk/nfsim-testsuite/README
===================================================================
--- trunk/nfsim-testsuite/README 2005-01-03 09:55:14 UTC (rev 3565)
+++ trunk/nfsim-testsuite/README 2005-01-04 09:11:29 UTC (rev 3566)
@@ -24,6 +24,9 @@
coverage. nfsim will fork, and the child will test
the failure case.
+ --valgrind
+ Use valgrind to check for memory errors.
+
-v
Verbose mode: print out test names, and errors from
tests we are expecting to fail.
Modified: trunk/nfsim-testsuite/test.sh
===================================================================
--- trunk/nfsim-testsuite/test.sh 2005-01-03 09:55:14 UTC (rev 3565)
+++ trunk/nfsim-testsuite/test.sh 2005-01-04 09:11:29 UTC (rev 3566)
@@ -18,8 +18,9 @@
-k) KEEP_GOING=1; shift;;
--nfsim=*) NFSIM=`echo "$1" | cut -d= -f2-`; shift;;
--time) TIME=time; VERBOSE=1; shift;;
+ --valgrind) VALGRIND=1; shift;;
--help)
- echo "Usage $0 [-k|-vv|-v|--failtest|--time|--nfsim=<nfsim>]" >&2; exit 0;;
+ echo "Usage $0 [-k|-vv|-v|--failtest|--time|--valgrind|--nfsim=<nfsim>]" >&2; exit 0;;
--*) NFSIM_ARGS="$NFSIM_ARGS $1"; shift;;
*) break;;
esac
@@ -93,10 +94,8 @@
}
export -f valgrind_nfsim
-# Make them run the valgrind wrappers, if available.
-if type valgrind 2>/dev/null; then
- NFSIM="valgrind_nfsim $NFSIM"
-fi
+# --valgrind?
+[ -z "$VALGRIND" ] || NFSIM="valgrind_nfsim $NFSIM"
export NFSIM NFSIM_ARGS
# Use iptables from SVN dir if we're in it.
More information about the netfilter-cvslog
mailing list