diff --git a/drivers/staging/batman-adv/send.c b/drivers/staging/batman-adv/send.c index e874caee999c62a8a6746d17377da38225aa4b4b..b39c67b3562079e7dc3ea85e438767d47e73cf24 100644 --- a/drivers/staging/batman-adv/send.c +++ b/drivers/staging/batman-adv/send.c @@ -73,7 +73,7 @@ int send_skb_packet(struct sk_buff *skb, } /* push to the ethernet header. */ - if (my_skb_push(skb, sizeof(struct ethhdr)) < 0) + if (my_skb_head_push(skb, sizeof(struct ethhdr)) < 0) goto send_skb_err; skb_reset_mac_header(skb); diff --git a/drivers/staging/batman-adv/soft-interface.c b/drivers/staging/batman-adv/soft-interface.c index d60b1a8ac7ffffee36348b3352df56c40160ce13..e8be209ce26f5bbb6eb4c36706340adbbe08be8e 100644 --- a/drivers/staging/batman-adv/soft-interface.c +++ b/drivers/staging/batman-adv/soft-interface.c @@ -31,8 +31,6 @@ static uint32_t bcast_seqno = 1; /* give own bcast messages seq numbers to avoid * broadcast storms */ -static int32_t skb_packets; -static int32_t skb_bad_packets; unsigned char main_if_addr[ETH_ALEN]; static int bat_get_settings(struct net_device *dev, struct ethtool_cmd *cmd); @@ -59,18 +57,22 @@ void set_main_if_addr(uint8_t *addr) memcpy(main_if_addr, addr, ETH_ALEN); } -int my_skb_push(struct sk_buff *skb, unsigned int len) +int my_skb_head_push(struct sk_buff *skb, unsigned int len) { - int result = 0; + int result; - skb_packets++; - if (skb_headroom(skb) < len) { - skb_bad_packets++; - result = pskb_expand_head(skb, len, 0, GFP_ATOMIC); + /** + * TODO: We must check if we can release all references to non-payload + * data using skb_header_release in our skbs to allow skb_cow_header to + * work optimally. This means that those skbs are not allowed to read + * or write any data which is before the current position of skb->data + * after that call and thus allow other skbs with the same data buffer + * to write freely in that area. + */ + result = skb_cow_head(skb, len); - if (result < 0) - return result; - } + if (result < 0) + return result; skb_push(skb, len); return 0; @@ -140,7 +142,7 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev) /* ethernet packet should be broadcasted */ if (is_bcast(ethhdr->h_dest) || is_mcast(ethhdr->h_dest)) { - if (my_skb_push(skb, sizeof(struct bcast_packet)) < 0) + if (my_skb_head_push(skb, sizeof(struct bcast_packet)) < 0) goto dropped; bcast_packet = (struct bcast_packet *)skb->data; diff --git a/drivers/staging/batman-adv/soft-interface.h b/drivers/staging/batman-adv/soft-interface.h index 6364854390092a6e1c851f2cc0888da31f4ef2d6..9dbf5fc44e4752f5784cf54f57d3e1d99a8a68f4 100644 --- a/drivers/staging/batman-adv/soft-interface.h +++ b/drivers/staging/batman-adv/soft-interface.h @@ -26,7 +26,7 @@ void set_main_if_addr(uint8_t *addr); void interface_setup(struct net_device *dev); int interface_tx(struct sk_buff *skb, struct net_device *dev); void interface_rx(struct sk_buff *skb, int hdr_size); -int my_skb_push(struct sk_buff *skb, unsigned int len); +int my_skb_head_push(struct sk_buff *skb, unsigned int len); extern unsigned char main_if_addr[]; diff --git a/drivers/staging/batman-adv/unicast.c b/drivers/staging/batman-adv/unicast.c index 153914e29516b6d2cc1a4e2186969a4333a8ec3c..61ebd3840ce55a2530e317e8535d0993602ee486 100644 --- a/drivers/staging/batman-adv/unicast.c +++ b/drivers/staging/batman-adv/unicast.c @@ -163,8 +163,8 @@ static int unicast_send_frag_skb(struct sk_buff *skb, struct bat_priv *bat_priv, frag_skb = dev_alloc_skb(data_len - (data_len / 2) + hdr_len); skb_split(skb, frag_skb, data_len / 2); - if (my_skb_push(frag_skb, hdr_len) < 0 || - my_skb_push(skb, hdr_len) < 0) + if (my_skb_head_push(frag_skb, hdr_len) < 0 || + my_skb_head_push(skb, hdr_len) < 0) goto drop_frag; ucast_frag1 = (struct unicast_frag_packet *)skb->data; @@ -240,7 +240,7 @@ int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv) return unicast_send_frag_skb(skb, bat_priv, batman_if, dstaddr, orig_node); - if (my_skb_push(skb, sizeof(struct unicast_packet)) < 0) + if (my_skb_head_push(skb, sizeof(struct unicast_packet)) < 0) goto dropped; unicast_packet = (struct unicast_packet *)skb->data;