@@ -89,6 +89,25 @@ ip6t_ext_hdr(u8 nexthdr)
8989 (nexthdr == IPPROTO_DSTOPTS ) );
9090}
9191
92+ static unsigned long ifname_compare (const char * _a , const char * _b ,
93+ const unsigned char * _mask )
94+ {
95+ const unsigned long * a = (const unsigned long * )_a ;
96+ const unsigned long * b = (const unsigned long * )_b ;
97+ const unsigned long * mask = (const unsigned long * )_mask ;
98+ unsigned long ret ;
99+
100+ ret = (a [0 ] ^ b [0 ]) & mask [0 ];
101+ if (IFNAMSIZ > sizeof (unsigned long ))
102+ ret |= (a [1 ] ^ b [1 ]) & mask [1 ];
103+ if (IFNAMSIZ > 2 * sizeof (unsigned long ))
104+ ret |= (a [2 ] ^ b [2 ]) & mask [2 ];
105+ if (IFNAMSIZ > 3 * sizeof (unsigned long ))
106+ ret |= (a [3 ] ^ b [3 ]) & mask [3 ];
107+ BUILD_BUG_ON (IFNAMSIZ > 4 * sizeof (unsigned long ));
108+ return ret ;
109+ }
110+
92111/* Returns whether matches rule or not. */
93112/* Performance critical - called for every packet */
94113static inline bool
@@ -99,7 +118,6 @@ ip6_packet_match(const struct sk_buff *skb,
99118 unsigned int * protoff ,
100119 int * fragoff , bool * hotdrop )
101120{
102- size_t i ;
103121 unsigned long ret ;
104122 const struct ipv6hdr * ipv6 = ipv6_hdr (skb );
105123
@@ -120,12 +138,7 @@ ip6_packet_match(const struct sk_buff *skb,
120138 return false;
121139 }
122140
123- /* Look for ifname matches; this should unroll nicely. */
124- for (i = 0 , ret = 0 ; i < IFNAMSIZ /sizeof (unsigned long ); i ++ ) {
125- ret |= (((const unsigned long * )indev )[i ]
126- ^ ((const unsigned long * )ip6info -> iniface )[i ])
127- & ((const unsigned long * )ip6info -> iniface_mask )[i ];
128- }
141+ ret = ifname_compare (indev , ip6info -> iniface , ip6info -> iniface_mask );
129142
130143 if (FWINV (ret != 0 , IP6T_INV_VIA_IN )) {
131144 dprintf ("VIA in mismatch (%s vs %s).%s\n" ,
@@ -134,11 +147,7 @@ ip6_packet_match(const struct sk_buff *skb,
134147 return false;
135148 }
136149
137- for (i = 0 , ret = 0 ; i < IFNAMSIZ /sizeof (unsigned long ); i ++ ) {
138- ret |= (((const unsigned long * )outdev )[i ]
139- ^ ((const unsigned long * )ip6info -> outiface )[i ])
140- & ((const unsigned long * )ip6info -> outiface_mask )[i ];
141- }
150+ ret = ifname_compare (outdev , ip6info -> outiface , ip6info -> outiface_mask );
142151
143152 if (FWINV (ret != 0 , IP6T_INV_VIA_OUT )) {
144153 dprintf ("VIA out mismatch (%s vs %s).%s\n" ,
0 commit comments