From f83f1768f833cb45bc93429fdc552252a4f55ac3 Mon Sep 17 00:00:00 2001 From: Joonwoo Park Date: Mon, 31 Mar 2008 21:02:47 -0700 Subject: [LLC]: skb allocation size for responses Allocate the skb for llc responses with the received packet size by using the size adjustable llc_frame_alloc. Don't allocate useless extra payload. Cleanup magic numbers. So, this fixes oops. Reported by Jim Westfall: kernel: skb_over_panic: text:c0541fc7 len:1000 put:997 head:c166ac00 data:c166ac2f tail:0xc166b017 end:0xc166ac80 dev:eth0 kernel: ------------[ cut here ]------------ kernel: kernel BUG at net/core/skbuff.c:95! Signed-off-by: Joonwoo Park Acked-by: Arnaldo Carvalho de Melo Signed-off-by: David S. Miller --- net/llc/llc_sap.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) (limited to 'net/llc/llc_sap.c') diff --git a/net/llc/llc_sap.c b/net/llc/llc_sap.c index 2525165e2e8..e2ddde75501 100644 --- a/net/llc/llc_sap.c +++ b/net/llc/llc_sap.c @@ -24,20 +24,41 @@ #include #include +static int llc_mac_header_len(unsigned short devtype) +{ + switch (devtype) { + case ARPHRD_ETHER: + case ARPHRD_LOOPBACK: + return sizeof(struct ethhdr); +#ifdef CONFIG_TR + case ARPHRD_IEEE802_TR: + return sizeof(struct trh_hdr); +#endif + } + return 0; +} + /** * llc_alloc_frame - allocates sk_buff for frame * @dev: network device this skb will be sent over + * @type: pdu type to allocate + * @data_size: data size to allocate * * Allocates an sk_buff for frame and initializes sk_buff fields. * Returns allocated skb or %NULL when out of memory. */ -struct sk_buff *llc_alloc_frame(struct sock *sk, struct net_device *dev) +struct sk_buff *llc_alloc_frame(struct sock *sk, struct net_device *dev, + u8 type, u32 data_size) { - struct sk_buff *skb = alloc_skb(128, GFP_ATOMIC); + int hlen = type == LLC_PDU_TYPE_U ? 3 : 4; + struct sk_buff *skb; + + hlen += llc_mac_header_len(dev->type); + skb = alloc_skb(hlen + data_size, GFP_ATOMIC); if (skb) { skb_reset_mac_header(skb); - skb_reserve(skb, 50); + skb_reserve(skb, hlen); skb_reset_network_header(skb); skb_reset_transport_header(skb); skb->protocol = htons(ETH_P_802_2); -- cgit v1.2.3