Commit 689827f0 authored by Alexey Kuznetsov's avatar Alexey Kuznetsov Committed by David S. Miller

[NET]: hard_header reservation.

1. Fix bad reservation in xfrm_state_check_space()
2. Macroize formula for reservation, use the macro over all the places
   in IP.
parent 7f2c2754
......@@ -90,6 +90,11 @@ struct vlan_group;
#define MAX_HEADER (LL_MAX_HEADER + 48)
#endif
/* Reserve 16byte aligned hard_header_len, but at least 16.
* Alternative is: dev->hard_header_len ? (dev->hard_header_len + 15)&~15 : 0
*/
#define LL_RESERVED_SPACE(dev) (((dev)->hard_header_len&~15) + 16)
/*
* Network device statistics. Akin to the 2.0 ether stats but
* with byte counters.
......
......@@ -510,11 +510,11 @@ void arp_send(int type, int ptype, u32 dest_ip,
*/
skb = alloc_skb(sizeof(struct arphdr)+ 2*(dev->addr_len+4)
+ dev->hard_header_len + 15, GFP_ATOMIC);
+ LL_RESERVED_SPACE(dev), GFP_ATOMIC);
if (skb == NULL)
return;
skb_reserve(skb, (dev->hard_header_len+15)&~15);
skb_reserve(skb, LL_RESERVED_SPACE(dev));
skb->nh.raw = skb->data;
arp = (struct arphdr *) skb_put(skb,sizeof(struct arphdr) + 2*(dev->addr_len+4));
skb->dev = dev;
......
......@@ -211,7 +211,7 @@ static int igmp_send_report(struct net_device *dev, u32 group, int type)
return -1;
}
skb=alloc_skb(IGMP_SIZE+dev->hard_header_len+15, GFP_ATOMIC);
skb=alloc_skb(IGMP_SIZE+LL_RESERVED_SPACE(dev), GFP_ATOMIC);
if (skb == NULL) {
ip_rt_put(rt);
return -1;
......@@ -219,7 +219,7 @@ static int igmp_send_report(struct net_device *dev, u32 group, int type)
skb->dst = &rt->u.dst;
skb_reserve(skb, (dev->hard_header_len+15)&~15);
skb_reserve(skb, LL_RESERVED_SPACE(dev));
skb->nh.iph = iph = (struct iphdr *)skb_put(skb, sizeof(struct iphdr)+4);
......
......@@ -92,7 +92,7 @@ int ip_forward(struct sk_buff *skb)
goto sr_failed;
/* We are about to mangle packet. Copy it! */
if (skb_cow(skb, rt->u.dst.dev->hard_header_len+rt->u.dst.header_len))
if (skb_cow(skb, LL_RESERVED_SPACE(rt->u.dst.dev)+rt->u.dst.header_len))
goto drop;
iph = skb->nh.iph;
......
......@@ -824,7 +824,7 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
skb->h.raw = skb->nh.raw;
max_headroom = ((tdev->hard_header_len+15)&~15)+ gre_hlen;
max_headroom = LL_RESERVED_SPACE(tdev) + gre_hlen;
if (skb_headroom(skb) < max_headroom || skb_cloned(skb) || skb_shared(skb)) {
struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom);
......
......@@ -162,13 +162,13 @@ static inline int ip_finish_output2(struct sk_buff *skb)
struct dst_entry *dst = skb->dst;
struct hh_cache *hh = dst->hh;
struct net_device *dev = dst->dev;
int hh_len = LL_RESERVED_SPACE(dev);
/* Be paranoid, rather than too clever. */
if (unlikely(skb_headroom(skb) < dev->hard_header_len
&& dev->hard_header)) {
if (unlikely(skb_headroom(skb) < hh_len && dev->hard_header)) {
struct sk_buff *skb2;
skb2 = skb_realloc_headroom(skb, (dev->hard_header_len&~15) + 16);
skb2 = skb_realloc_headroom(skb, LL_RESERVED_SPACE(dev));
if (skb2 == NULL) {
kfree_skb(skb);
return -ENOMEM;
......@@ -572,7 +572,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
* Allocate buffer.
*/
if ((skb2 = alloc_skb(len+hlen+rt->u.dst.dev->hard_header_len+16,GFP_ATOMIC)) == NULL) {
if ((skb2 = alloc_skb(len+hlen+LL_RESERVED_SPACE(rt->u.dst.dev), GFP_ATOMIC)) == NULL) {
NETDEBUG(printk(KERN_INFO "IP: frag: no memory for new fragment!\n"));
err = -ENOMEM;
goto fail;
......@@ -583,7 +583,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
*/
ip_copy_metadata(skb2, skb);
skb_reserve(skb2, (rt->u.dst.dev->hard_header_len&~15)+16);
skb_reserve(skb2, LL_RESERVED_SPACE(rt->u.dst.dev));
skb_put(skb2, len + hlen);
skb2->nh.raw = skb2->data;
skb2->h.raw = skb2->data + hlen;
......@@ -771,7 +771,7 @@ int ip_append_data(struct sock *sk,
exthdrlen = 0;
mtu = inet->cork.fragsize;
}
hh_len = (rt->u.dst.dev->hard_header_len&~15) + 16;
hh_len = LL_RESERVED_SPACE(rt->u.dst.dev);
fragheaderlen = sizeof(struct iphdr) + (opt ? opt->optlen : 0);
maxfraglen = ((mtu-fragheaderlen) & ~7) + fragheaderlen;
......@@ -967,7 +967,7 @@ ssize_t ip_append_page(struct sock *sk, struct page *page,
if (!(rt->u.dst.dev->features&NETIF_F_SG))
return -EOPNOTSUPP;
hh_len = (rt->u.dst.dev->hard_header_len&~15)+16;
hh_len = LL_RESERVED_SPACE(rt->u.dst.dev);
mtu = inet->cork.fragsize;
fragheaderlen = sizeof(struct iphdr) + (opt ? opt->optlen : 0);
......
......@@ -656,7 +656,7 @@ static void __init ic_bootp_send_if(struct ic_device *d, unsigned long jiffies_d
struct net_device *dev = d->dev;
struct sk_buff *skb;
struct bootp_pkt *b;
int hh_len = (dev->hard_header_len + 15) & ~15;
int hh_len = LL_RESERVED_SPACE(dev);
struct iphdr *h;
/* Allocate packet */
......
......@@ -616,7 +616,7 @@ static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
/*
* Okay, now see if we can stuff it in the buffer as-is.
*/
max_headroom = (((tdev->hard_header_len+15)&~15)+sizeof(struct iphdr));
max_headroom = (LL_RESERVED_SPACE(tdev)+sizeof(struct iphdr));
if (skb_headroom(skb) < max_headroom || skb_cloned(skb) || skb_shared(skb)) {
struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom);
......
......@@ -1178,7 +1178,7 @@ static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c,
return;
}
encap += dev->hard_header_len;
encap += LL_RESERVED_SPACE(dev);
if (skb_headroom(skb) < encap || skb_cloned(skb) || !last)
skb2 = skb_realloc_headroom(skb, (encap + 15)&~15);
......
......@@ -280,7 +280,7 @@ static int raw_send_hdrinc(struct sock *sk, void *from, int length,
if (flags&MSG_PROBE)
goto out;
hh_len = (rt->u.dst.dev->hard_header_len&~15) + 16;
hh_len = LL_RESERVED_SPACE(rt->u.dst.dev);
skb = sock_alloc_send_skb(sk, length+hh_len+15,
flags&MSG_DONTWAIT, &err);
......
......@@ -501,7 +501,7 @@ int xfrm_state_check_expire(struct xfrm_state *x)
int xfrm_state_check_space(struct xfrm_state *x, struct sk_buff *skb)
{
int nhead = x->props.header_len + skb->dst->dev->hard_header_len
int nhead = x->props.header_len + LL_RESERVED_SPACE(skb->dst->dev)
- skb_headroom(skb);
if (nhead > 0)
......
......@@ -552,7 +552,7 @@ static int ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
/*
* Okay, now see if we can stuff it in the buffer as-is.
*/
max_headroom = (((tdev->hard_header_len+15)&~15)+sizeof(struct iphdr));
max_headroom = LL_RESERVED_SPACE(tdev)+sizeof(struct iphdr);
if (skb_headroom(skb) < max_headroom || skb_cloned(skb) || skb_shared(skb)) {
struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom);
......
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