@@ -20,10 +20,27 @@ MODULE_DESCRIPTION("Xtables: Bridge physical device match");
2020MODULE_ALIAS ("ipt_physdev" );
2121MODULE_ALIAS ("ip6t_physdev" );
2222
23+ static unsigned long ifname_compare (const char * _a , const char * _b , const char * _mask )
24+ {
25+ const unsigned long * a = (const unsigned long * )_a ;
26+ const unsigned long * b = (const unsigned long * )_b ;
27+ const unsigned long * mask = (const unsigned long * )_mask ;
28+ unsigned long ret ;
29+
30+ ret = (a [0 ] ^ b [0 ]) & mask [0 ];
31+ if (IFNAMSIZ > sizeof (unsigned long ))
32+ ret |= (a [1 ] ^ b [1 ]) & mask [1 ];
33+ if (IFNAMSIZ > 2 * sizeof (unsigned long ))
34+ ret |= (a [2 ] ^ b [2 ]) & mask [2 ];
35+ if (IFNAMSIZ > 3 * sizeof (unsigned long ))
36+ ret |= (a [3 ] ^ b [3 ]) & mask [3 ];
37+ BUILD_BUG_ON (IFNAMSIZ > 4 * sizeof (unsigned long ));
38+ return ret ;
39+ }
40+
2341static bool
2442physdev_mt (const struct sk_buff * skb , const struct xt_match_param * par )
2543{
26- int i ;
2744 static const char nulldevname [IFNAMSIZ ] __attribute__((aligned (sizeof (long ))));
2845 const struct xt_physdev_info * info = par -> matchinfo ;
2946 unsigned long ret ;
@@ -68,11 +85,7 @@ physdev_mt(const struct sk_buff *skb, const struct xt_match_param *par)
6885 if (!(info -> bitmask & XT_PHYSDEV_OP_IN ))
6986 goto match_outdev ;
7087 indev = nf_bridge -> physindev ? nf_bridge -> physindev -> name : nulldevname ;
71- for (i = 0 , ret = 0 ; i < IFNAMSIZ /sizeof (unsigned long ); i ++ ) {
72- ret |= (((const unsigned long * )indev )[i ]
73- ^ ((const unsigned long * )info -> physindev )[i ])
74- & ((const unsigned long * )info -> in_mask )[i ];
75- }
88+ ret = ifname_compare (indev , info -> physindev , info -> in_mask );
7689
7790 if (!ret ^ !(info -> invert & XT_PHYSDEV_OP_IN ))
7891 return false;
@@ -82,11 +95,8 @@ physdev_mt(const struct sk_buff *skb, const struct xt_match_param *par)
8295 return true;
8396 outdev = nf_bridge -> physoutdev ?
8497 nf_bridge -> physoutdev -> name : nulldevname ;
85- for (i = 0 , ret = 0 ; i < IFNAMSIZ /sizeof (unsigned long ); i ++ ) {
86- ret |= (((const unsigned long * )outdev )[i ]
87- ^ ((const unsigned long * )info -> physoutdev )[i ])
88- & ((const unsigned long * )info -> out_mask )[i ];
89- }
98+ ret = ifname_compare (outdev , info -> physoutdev , info -> out_mask );
99+
90100 return (!!ret ^ !(info -> invert & XT_PHYSDEV_OP_OUT ));
91101}
92102
0 commit comments