diff options
| author | David S. Miller <davem@davemloft.net> | 2005-09-27 19:03:05 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2005-09-27 19:03:05 -0400 |
| commit | ba645c16026ed733a51f904df34756f61bc155fc (patch) | |
| tree | 504d51adf47bb9fa3cd548e5594f15a60faeba6c | |
| parent | 2fab35d78f32fc107e1af4b1ec23f557fa20d911 (diff) | |
[NET]: Slightly optimize ethernet address comparison.
We know the thing is at least 2-byte aligned, so take
advantage of that instead of invoking memcmp() which
results in truly horrifically inefficient code because
it can't assume anything about alignment.
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | net/ethernet/eth.c | 31 |
1 files changed, 21 insertions, 10 deletions
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c index 87a052a9a84f..8b299cc82060 100644 --- a/net/ethernet/eth.c +++ b/net/ethernet/eth.c | |||
| @@ -146,6 +146,19 @@ int eth_rebuild_header(struct sk_buff *skb) | |||
| 146 | return 0; | 146 | return 0; |
| 147 | } | 147 | } |
| 148 | 148 | ||
| 149 | static inline unsigned int compare_eth_addr(const unsigned char *__a, const unsigned char *__b) | ||
| 150 | { | ||
| 151 | const unsigned short *dest = (unsigned short *) __a; | ||
| 152 | const unsigned short *devaddr = (unsigned short *) __b; | ||
| 153 | unsigned int res; | ||
| 154 | |||
| 155 | BUILD_BUG_ON(ETH_ALEN != 6); | ||
| 156 | res = ((dest[0] ^ devaddr[0]) | | ||
| 157 | (dest[1] ^ devaddr[1]) | | ||
| 158 | (dest[2] ^ devaddr[2])) != 0; | ||
| 159 | |||
| 160 | return res; | ||
| 161 | } | ||
| 149 | 162 | ||
| 150 | /* | 163 | /* |
| 151 | * Determine the packet's protocol ID. The rule here is that we | 164 | * Determine the packet's protocol ID. The rule here is that we |
| @@ -158,16 +171,15 @@ __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev) | |||
| 158 | struct ethhdr *eth; | 171 | struct ethhdr *eth; |
| 159 | unsigned char *rawp; | 172 | unsigned char *rawp; |
| 160 | 173 | ||
| 161 | skb->mac.raw=skb->data; | 174 | skb->mac.raw = skb->data; |
| 162 | skb_pull(skb,ETH_HLEN); | 175 | skb_pull(skb,ETH_HLEN); |
| 163 | eth = eth_hdr(skb); | 176 | eth = eth_hdr(skb); |
| 164 | 177 | ||
| 165 | if(*eth->h_dest&1) | 178 | if (*eth->h_dest&1) { |
| 166 | { | 179 | if (!compare_eth_addr(eth->h_dest, dev->broadcast)) |
| 167 | if(memcmp(eth->h_dest,dev->broadcast, ETH_ALEN)==0) | 180 | skb->pkt_type = PACKET_BROADCAST; |
| 168 | skb->pkt_type=PACKET_BROADCAST; | ||
| 169 | else | 181 | else |
| 170 | skb->pkt_type=PACKET_MULTICAST; | 182 | skb->pkt_type = PACKET_MULTICAST; |
| 171 | } | 183 | } |
| 172 | 184 | ||
| 173 | /* | 185 | /* |
| @@ -178,10 +190,9 @@ __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev) | |||
| 178 | * seems to set IFF_PROMISC. | 190 | * seems to set IFF_PROMISC. |
| 179 | */ | 191 | */ |
| 180 | 192 | ||
| 181 | else if(1 /*dev->flags&IFF_PROMISC*/) | 193 | else if(1 /*dev->flags&IFF_PROMISC*/) { |
| 182 | { | 194 | if (unlikely(!compare_eth_addr(eth->h_dest, dev->dev_addr))) |
| 183 | if(memcmp(eth->h_dest,dev->dev_addr, ETH_ALEN)) | 195 | skb->pkt_type = PACKET_OTHERHOST; |
| 184 | skb->pkt_type=PACKET_OTHERHOST; | ||
| 185 | } | 196 | } |
| 186 | 197 | ||
| 187 | if (ntohs(eth->h_proto) >= 1536) | 198 | if (ntohs(eth->h_proto) >= 1536) |
