Commit 3ed5a695 authored by David S. Miller's avatar David S. Miller

[NET]: Size hh_cache->hh_data more appropriately.

parent 60af0ada
...@@ -766,10 +766,14 @@ static int myri_rebuild_header(struct sk_buff *skb) ...@@ -766,10 +766,14 @@ static int myri_rebuild_header(struct sk_buff *skb)
int myri_header_cache(struct neighbour *neigh, struct hh_cache *hh) int myri_header_cache(struct neighbour *neigh, struct hh_cache *hh)
{ {
unsigned short type = hh->hh_type; unsigned short type = hh->hh_type;
unsigned char *pad = (unsigned char *) hh->hh_data; unsigned char *pad;
struct ethhdr *eth = (struct ethhdr *) (pad + MYRI_PAD_LEN); struct ethhdr *eth;
struct net_device *dev = neigh->dev; struct net_device *dev = neigh->dev;
pad = ((unsigned char *) hh->hh_data) +
HH_DATA_OFF(sizeof(*eth) + MYRI_PAD_LEN);
eth = (struct ethhdr *) (pad + MYRI_PAD_LEN);
if (type == __constant_htons(ETH_P_802_3)) if (type == __constant_htons(ETH_P_802_3))
return -1; return -1;
...@@ -788,7 +792,8 @@ int myri_header_cache(struct neighbour *neigh, struct hh_cache *hh) ...@@ -788,7 +792,8 @@ int myri_header_cache(struct neighbour *neigh, struct hh_cache *hh)
/* Called by Address Resolution module to notify changes in address. */ /* Called by Address Resolution module to notify changes in address. */
void myri_header_cache_update(struct hh_cache *hh, struct net_device *dev, unsigned char * haddr) void myri_header_cache_update(struct hh_cache *hh, struct net_device *dev, unsigned char * haddr)
{ {
memcpy(((u8*)hh->hh_data) + 2, haddr, dev->addr_len); memcpy(((u8*)hh->hh_data) + HH_DATA_OFF(sizeof(struct ethhdr)),
haddr, dev->addr_len);
} }
static int myri_change_mtu(struct net_device *dev, int new_mtu) static int myri_change_mtu(struct net_device *dev, int new_mtu)
......
...@@ -1078,7 +1078,10 @@ int plip_hard_header_cache(struct neighbour *neigh, ...@@ -1078,7 +1078,10 @@ int plip_hard_header_cache(struct neighbour *neigh,
if ((ret = nl->orig_hard_header_cache(neigh, hh)) == 0) if ((ret = nl->orig_hard_header_cache(neigh, hh)) == 0)
{ {
struct ethhdr *eth = (struct ethhdr*)(((u8*)hh->hh_data) + 2); struct ethhdr *eth;
eth = (struct ethhdr*)(((u8*)hh->hh_data) +
HH_DATA_OFF(sizeof(*eth)));
plip_rewrite_address (neigh->dev, eth); plip_rewrite_address (neigh->dev, eth);
} }
......
...@@ -195,8 +195,14 @@ struct hh_cache ...@@ -195,8 +195,14 @@ struct hh_cache
int hh_len; /* length of header */ int hh_len; /* length of header */
int (*hh_output)(struct sk_buff *skb); int (*hh_output)(struct sk_buff *skb);
rwlock_t hh_lock; rwlock_t hh_lock;
/* cached hardware header; allow for machine alignment needs. */ /* cached hardware header; allow for machine alignment needs. */
unsigned long hh_data[16/sizeof(unsigned long)]; #define HH_DATA_MOD 16
#define HH_DATA_OFF(__len) \
(HH_DATA_MOD - ((__len) & (HH_DATA_MOD - 1)))
#define HH_DATA_ALIGN(__len) \
(((__len)+(HH_DATA_MOD-1))&~(HH_DATA_MOD - 1))
unsigned long hh_data[HH_DATA_ALIGN(LL_MAX_HEADER)];
}; };
/* These flag bits are private to the generic network queueing /* These flag bits are private to the generic network queueing
......
...@@ -216,9 +216,12 @@ int eth_header_parse(struct sk_buff *skb, unsigned char *haddr) ...@@ -216,9 +216,12 @@ int eth_header_parse(struct sk_buff *skb, unsigned char *haddr)
int eth_header_cache(struct neighbour *neigh, struct hh_cache *hh) int eth_header_cache(struct neighbour *neigh, struct hh_cache *hh)
{ {
unsigned short type = hh->hh_type; unsigned short type = hh->hh_type;
struct ethhdr *eth = (struct ethhdr*)(((u8*)hh->hh_data) + 2); struct ethhdr *eth;
struct net_device *dev = neigh->dev; struct net_device *dev = neigh->dev;
eth = (struct ethhdr*)
(((u8*)hh->hh_data) + (HH_DATA_OFF(sizeof(*eth))));
if (type == __constant_htons(ETH_P_802_3)) if (type == __constant_htons(ETH_P_802_3))
return -1; return -1;
...@@ -235,5 +238,6 @@ int eth_header_cache(struct neighbour *neigh, struct hh_cache *hh) ...@@ -235,5 +238,6 @@ int eth_header_cache(struct neighbour *neigh, struct hh_cache *hh)
void eth_header_cache_update(struct hh_cache *hh, struct net_device *dev, unsigned char * haddr) void eth_header_cache_update(struct hh_cache *hh, struct net_device *dev, unsigned char * haddr)
{ {
memcpy(((u8*)hh->hh_data) + 2, haddr, dev->addr_len); memcpy(((u8*)hh->hh_data) + HH_DATA_OFF(sizeof(struct ethhdr)),
haddr, dev->addr_len);
} }
...@@ -193,8 +193,11 @@ static inline int ip_finish_output2(struct sk_buff *skb) ...@@ -193,8 +193,11 @@ static inline int ip_finish_output2(struct sk_buff *skb)
#endif /*CONFIG_NETFILTER_DEBUG*/ #endif /*CONFIG_NETFILTER_DEBUG*/
if (hh) { if (hh) {
int hh_alen;
read_lock_bh(&hh->hh_lock); read_lock_bh(&hh->hh_lock);
memcpy(skb->data - 16, hh->hh_data, 16); hh_alen = HH_DATA_ALIGN(hh->hh_len);
memcpy(skb->data - hh_alen, hh->hh_data, hh_alen);
read_unlock_bh(&hh->hh_lock); read_unlock_bh(&hh->hh_lock);
skb_push(skb, hh->hh_len); skb_push(skb, hh->hh_len);
return hh->hh_output(skb); return hh->hh_output(skb);
......
...@@ -90,8 +90,11 @@ static void ip_direct_send(struct sk_buff *skb) ...@@ -90,8 +90,11 @@ static void ip_direct_send(struct sk_buff *skb)
struct hh_cache *hh = dst->hh; struct hh_cache *hh = dst->hh;
if (hh) { if (hh) {
int hh_alen;
read_lock_bh(&hh->hh_lock); read_lock_bh(&hh->hh_lock);
memcpy(skb->data - 16, hh->hh_data, 16); hh_alen = HH_DATA_ALIGN(hh->hh_len);
memcpy(skb->data - hh_alen, hh->hh_data, hh_alen);
read_unlock_bh(&hh->hh_lock); read_unlock_bh(&hh->hh_lock);
skb_push(skb, hh->hh_len); skb_push(skb, hh->hh_len);
hh->hh_output(skb); hh->hh_output(skb);
......
...@@ -76,8 +76,11 @@ static inline int ip6_output_finish(struct sk_buff *skb) ...@@ -76,8 +76,11 @@ static inline int ip6_output_finish(struct sk_buff *skb)
struct hh_cache *hh = dst->hh; struct hh_cache *hh = dst->hh;
if (hh) { if (hh) {
int hh_alen;
read_lock_bh(&hh->hh_lock); read_lock_bh(&hh->hh_lock);
memcpy(skb->data - 16, hh->hh_data, 16); hh_alen = HH_DATA_ALIGN(hh->hh_len);
memcpy(skb->data - hh_alen, hh->hh_data, hh_alen);
read_unlock_bh(&hh->hh_lock); read_unlock_bh(&hh->hh_lock);
skb_push(skb, hh->hh_len); skb_push(skb, hh->hh_len);
return hh->hh_output(skb); return hh->hh_output(skb);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment