Skip to content

Commit 4ae89ad

Browse files
JoePerchesummakynes
authored andcommitted
etherdevice.h & bridge: netfilter: Add and use ether_addr_equal_masked
There are code duplications of a masked ethernet address comparison here so make it a separate function instead. Miscellanea: o Neaten alignment of FWINV macro uses to make it clearer for the reader Signed-off-by: Joe Perches <joe@perches.com> Acked-by: David S. Miller <davem@davemloft.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
1 parent 468b021 commit 4ae89ad

File tree

4 files changed

+57
-49
lines changed

4 files changed

+57
-49
lines changed

include/linux/etherdevice.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,29 @@ static inline bool ether_addr_equal_unaligned(const u8 *addr1, const u8 *addr2)
373373
#endif
374374
}
375375

376+
/**
377+
* ether_addr_equal_masked - Compare two Ethernet addresses with a mask
378+
* @addr1: Pointer to a six-byte array containing the 1st Ethernet address
379+
* @addr2: Pointer to a six-byte array containing the 2nd Ethernet address
380+
* @mask: Pointer to a six-byte array containing the Ethernet address bitmask
381+
*
382+
* Compare two Ethernet addresses with a mask, returns true if for every bit
383+
* set in the bitmask the equivalent bits in the ethernet addresses are equal.
384+
* Using a mask with all bits set is a slower ether_addr_equal.
385+
*/
386+
static inline bool ether_addr_equal_masked(const u8 *addr1, const u8 *addr2,
387+
const u8 *mask)
388+
{
389+
int i;
390+
391+
for (i = 0; i < ETH_ALEN; i++) {
392+
if ((addr1[i] ^ addr2[i]) & mask[i])
393+
return false;
394+
}
395+
396+
return true;
397+
}
398+
376399
/**
377400
* is_etherdev_addr - Tell if given Ethernet address belongs to the device.
378401
* @dev: Pointer to a device structure

net/bridge/netfilter/ebt_arp.c

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ ebt_arp_mt(const struct sk_buff *skb, struct xt_action_param *par)
6565
if (info->bitmask & (EBT_ARP_SRC_MAC | EBT_ARP_DST_MAC)) {
6666
const unsigned char *mp;
6767
unsigned char _mac[ETH_ALEN];
68-
uint8_t verdict, i;
6968

7069
if (ah->ar_hln != ETH_ALEN || ah->ar_hrd != htons(ARPHRD_ETHER))
7170
return false;
@@ -74,11 +73,9 @@ ebt_arp_mt(const struct sk_buff *skb, struct xt_action_param *par)
7473
sizeof(_mac), &_mac);
7574
if (mp == NULL)
7675
return false;
77-
verdict = 0;
78-
for (i = 0; i < 6; i++)
79-
verdict |= (mp[i] ^ info->smaddr[i]) &
80-
info->smmsk[i];
81-
if (FWINV(verdict != 0, EBT_ARP_SRC_MAC))
76+
if (FWINV(!ether_addr_equal_masked(mp, info->smaddr,
77+
info->smmsk),
78+
EBT_ARP_SRC_MAC))
8279
return false;
8380
}
8481

@@ -88,11 +85,9 @@ ebt_arp_mt(const struct sk_buff *skb, struct xt_action_param *par)
8885
sizeof(_mac), &_mac);
8986
if (mp == NULL)
9087
return false;
91-
verdict = 0;
92-
for (i = 0; i < 6; i++)
93-
verdict |= (mp[i] ^ info->dmaddr[i]) &
94-
info->dmmsk[i];
95-
if (FWINV(verdict != 0, EBT_ARP_DST_MAC))
88+
if (FWINV(!ether_addr_equal_masked(mp, info->dmaddr,
89+
info->dmmsk),
90+
EBT_ARP_DST_MAC))
9691
return false;
9792
}
9893
}

net/bridge/netfilter/ebt_stp.c

Lines changed: 22 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -46,74 +46,69 @@ static bool ebt_filter_config(const struct ebt_stp_info *info,
4646
const struct ebt_stp_config_info *c;
4747
u16 v16;
4848
u32 v32;
49-
int verdict, i;
5049

5150
c = &info->config;
5251
if ((info->bitmask & EBT_STP_FLAGS) &&
5352
FWINV(c->flags != stpc->flags, EBT_STP_FLAGS))
5453
return false;
5554
if (info->bitmask & EBT_STP_ROOTPRIO) {
5655
v16 = NR16(stpc->root);
57-
if (FWINV(v16 < c->root_priol ||
58-
v16 > c->root_priou, EBT_STP_ROOTPRIO))
56+
if (FWINV(v16 < c->root_priol || v16 > c->root_priou,
57+
EBT_STP_ROOTPRIO))
5958
return false;
6059
}
6160
if (info->bitmask & EBT_STP_ROOTADDR) {
62-
verdict = 0;
63-
for (i = 0; i < 6; i++)
64-
verdict |= (stpc->root[2+i] ^ c->root_addr[i]) &
65-
c->root_addrmsk[i];
66-
if (FWINV(verdict != 0, EBT_STP_ROOTADDR))
61+
if (FWINV(!ether_addr_equal_masked(&stpc->root[2], c->root_addr,
62+
c->root_addrmsk),
63+
EBT_STP_ROOTADDR))
6764
return false;
6865
}
6966
if (info->bitmask & EBT_STP_ROOTCOST) {
7067
v32 = NR32(stpc->root_cost);
71-
if (FWINV(v32 < c->root_costl ||
72-
v32 > c->root_costu, EBT_STP_ROOTCOST))
68+
if (FWINV(v32 < c->root_costl || v32 > c->root_costu,
69+
EBT_STP_ROOTCOST))
7370
return false;
7471
}
7572
if (info->bitmask & EBT_STP_SENDERPRIO) {
7673
v16 = NR16(stpc->sender);
77-
if (FWINV(v16 < c->sender_priol ||
78-
v16 > c->sender_priou, EBT_STP_SENDERPRIO))
74+
if (FWINV(v16 < c->sender_priol || v16 > c->sender_priou,
75+
EBT_STP_SENDERPRIO))
7976
return false;
8077
}
8178
if (info->bitmask & EBT_STP_SENDERADDR) {
82-
verdict = 0;
83-
for (i = 0; i < 6; i++)
84-
verdict |= (stpc->sender[2+i] ^ c->sender_addr[i]) &
85-
c->sender_addrmsk[i];
86-
if (FWINV(verdict != 0, EBT_STP_SENDERADDR))
79+
if (FWINV(!ether_addr_equal_masked(&stpc->sender[2],
80+
c->sender_addr,
81+
c->sender_addrmsk),
82+
EBT_STP_SENDERADDR))
8783
return false;
8884
}
8985
if (info->bitmask & EBT_STP_PORT) {
9086
v16 = NR16(stpc->port);
91-
if (FWINV(v16 < c->portl ||
92-
v16 > c->portu, EBT_STP_PORT))
87+
if (FWINV(v16 < c->portl || v16 > c->portu, EBT_STP_PORT))
9388
return false;
9489
}
9590
if (info->bitmask & EBT_STP_MSGAGE) {
9691
v16 = NR16(stpc->msg_age);
97-
if (FWINV(v16 < c->msg_agel ||
98-
v16 > c->msg_ageu, EBT_STP_MSGAGE))
92+
if (FWINV(v16 < c->msg_agel || v16 > c->msg_ageu,
93+
EBT_STP_MSGAGE))
9994
return false;
10095
}
10196
if (info->bitmask & EBT_STP_MAXAGE) {
10297
v16 = NR16(stpc->max_age);
103-
if (FWINV(v16 < c->max_agel ||
104-
v16 > c->max_ageu, EBT_STP_MAXAGE))
98+
if (FWINV(v16 < c->max_agel || v16 > c->max_ageu,
99+
EBT_STP_MAXAGE))
105100
return false;
106101
}
107102
if (info->bitmask & EBT_STP_HELLOTIME) {
108103
v16 = NR16(stpc->hello_time);
109-
if (FWINV(v16 < c->hello_timel ||
110-
v16 > c->hello_timeu, EBT_STP_HELLOTIME))
104+
if (FWINV(v16 < c->hello_timel || v16 > c->hello_timeu,
105+
EBT_STP_HELLOTIME))
111106
return false;
112107
}
113108
if (info->bitmask & EBT_STP_FWDD) {
114109
v16 = NR16(stpc->forward_delay);
115-
if (FWINV(v16 < c->forward_delayl ||
116-
v16 > c->forward_delayu, EBT_STP_FWDD))
110+
if (FWINV(v16 < c->forward_delayl || v16 > c->forward_delayu,
111+
EBT_STP_FWDD))
117112
return false;
118113
}
119114
return true;

net/bridge/netfilter/ebtables.c

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,6 @@ ebt_basic_match(const struct ebt_entry *e, const struct sk_buff *skb,
130130
const struct ethhdr *h = eth_hdr(skb);
131131
const struct net_bridge_port *p;
132132
__be16 ethproto;
133-
int verdict, i;
134133

135134
if (skb_vlan_tag_present(skb))
136135
ethproto = htons(ETH_P_8021Q);
@@ -157,19 +156,15 @@ ebt_basic_match(const struct ebt_entry *e, const struct sk_buff *skb,
157156
return 1;
158157

159158
if (e->bitmask & EBT_SOURCEMAC) {
160-
verdict = 0;
161-
for (i = 0; i < 6; i++)
162-
verdict |= (h->h_source[i] ^ e->sourcemac[i]) &
163-
e->sourcemsk[i];
164-
if (FWINV2(verdict != 0, EBT_ISOURCE))
159+
if (FWINV2(!ether_addr_equal_masked(h->h_source,
160+
e->sourcemac, e->sourcemsk),
161+
EBT_ISOURCE))
165162
return 1;
166163
}
167164
if (e->bitmask & EBT_DESTMAC) {
168-
verdict = 0;
169-
for (i = 0; i < 6; i++)
170-
verdict |= (h->h_dest[i] ^ e->destmac[i]) &
171-
e->destmsk[i];
172-
if (FWINV2(verdict != 0, EBT_IDEST))
165+
if (FWINV2(!ether_addr_equal_masked(h->h_dest,
166+
e->destmac, e->destmsk),
167+
EBT_IDEST))
173168
return 1;
174169
}
175170
return 0;

0 commit comments

Comments
 (0)