netdev
[Top] [All Lists]

Re: ipt_physdev.c alignment problems on parisc64

To: "David S. Miller" <davem@xxxxxxxxxx>, Harald Welte <laforge@xxxxxxxxxxxxx>
Subject: Re: ipt_physdev.c alignment problems on parisc64
From: Bart De Schuymer <bdschuym@xxxxxxxxxx>
Date: Sat, 13 Sep 2003 21:59:37 +0200
Cc: acme@xxxxxxxxxxxxxxxx, netfilter-devel@xxxxxxxxxxxxxxxxxxx, netdev@xxxxxxxxxxx
In-reply-to: <20030908191400.5ef59ab6.davem@xxxxxxxxxx>
References: <200309022116.41697.bdschuym@xxxxxxxxxx> <20030905153152.GA3623@xxxxxxxxxxxxxxxxxxxxxxxxxx> <20030908191400.5ef59ab6.davem@xxxxxxxxxx>
Sender: netdev-bounce@xxxxxxxxxxx
User-agent: KMail/1.5
On Tuesday 09 September 2003 04:14, David S. Miller wrote:
> On Fri, 5 Sep 2003 17:31:52 +0200
>
> Harald Welte <laforge@xxxxxxxxxxxxx> wrote:
> > The problem is that it is _not_ a simple reimplementation of memcmp(),
> > but a mask-compare.
>
> Ok.  It still should be fixed by not using the "unsigned long *"
> cast-and-op tricks...

The patch below should fix things. It just uses unsigned int instead
of unsigned long, so there should be no problem with the evil Sparc64.
Perhaps the ip_tables.c code from which I copied the original code should
be altered too.
It's a real optimization btw, the .o file is 32 bytes
larger when doing the bit operations on a char with i<IFNAMSIZ.
All hail Rusty :)
The patch doesn't change the .o file on my i386 system. It will probably
be slower for systems where sizeof(unsigned long)>sizeof(unsigned int),
but this is the easiest solution for me.

cheers,
Bart

--- linux-2.6.0-test5/net/ipv4/netfilter/ipt_physdev.c.old      2003-09-11 
21:04:12.000000000 +0200
+++ linux-2.6.0-test5/net/ipv4/netfilter/ipt_physdev.c  2003-09-13 
21:42:23.000000000 +0200
@@ -23,7 +23,7 @@ match(const struct sk_buff *skb,
        int i;
        static const char nulldevname[IFNAMSIZ];
        const struct ipt_physdev_info *info = matchinfo;
-       unsigned long ret;
+       unsigned int ret;
        const char *indev, *outdev;
        struct nf_bridge_info *nf_bridge;
 
@@ -65,10 +65,10 @@ match(const struct sk_buff *skb,
        if (!(info->bitmask & IPT_PHYSDEV_OP_IN))
                goto match_outdev;
        indev = nf_bridge->physindev ? nf_bridge->physindev->name : nulldevname;
-       for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned long); i++) {
-               ret |= (((const unsigned long *)indev)[i]
-                       ^ ((const unsigned long *)info->physindev)[i])
-                       & ((const unsigned long *)info->in_mask)[i];
+       for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned int); i++) {
+               ret |= (((const unsigned int *)indev)[i]
+                       ^ ((const unsigned int *)info->physindev)[i])
+                       & ((const unsigned int *)info->in_mask)[i];
        }
 
        if ((ret == 0) ^ !(info->invert & IPT_PHYSDEV_OP_IN))
@@ -79,10 +79,10 @@ match_outdev:
                return MATCH;
        outdev = nf_bridge->physoutdev ?
                 nf_bridge->physoutdev->name : nulldevname;
-       for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned long); i++) {
-               ret |= (((const unsigned long *)outdev)[i]
-                       ^ ((const unsigned long *)info->physoutdev)[i])
-                       & ((const unsigned long *)info->out_mask)[i];
+       for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned int); i++) {
+               ret |= (((const unsigned int *)outdev)[i]
+                       ^ ((const unsigned int *)info->physoutdev)[i])
+                       & ((const unsigned int *)info->out_mask)[i];
        }
 
        return (ret != 0) ^ !(info->invert & IPT_PHYSDEV_OP_OUT);
--- linux-2.6.0-test5/include/linux/netfilter_ipv4/ipt_physdev.h.old    
2003-09-13 21:32:23.000000000 +0200
+++ linux-2.6.0-test5/include/linux/netfilter_ipv4/ipt_physdev.h        
2003-09-13 21:33:04.000000000 +0200
@@ -15,7 +15,7 @@
 struct ipt_physdev_info {
        u_int8_t invert;
        u_int8_t bitmask;
-       char physindev[IFNAMSIZ];
+       char physindev[IFNAMSIZ] __attribute__ ((aligned (__alignof__(unsigned 
int))));
        char in_mask[IFNAMSIZ];
        char physoutdev[IFNAMSIZ];
        char out_mask[IFNAMSIZ];


<Prev in Thread] Current Thread [Next in Thread>