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);
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;
/* 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;
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[];
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;
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;