batman-adv: Reserve extra bytes in skb for better alignment
The ethernet header is 14 bytes long. Therefore, the data after it is not 4 byte aligned and may cause problems on systems without unaligned data access. Reserving NET_IP_ALIGN more byes can fix the misalignment of the ethernet header. Signed-off-by: Sven Eckelmann <sven@narfation.org> Signed-off-by: Marek Lindner <lindner_marek@yahoo.de> Signed-off-by: Antonio Quartulli <ordex@autistici.org>
This commit is contained in:
parent
6f0a0986e3
commit
5b24657443
4 changed files with 22 additions and 19 deletions
|
@ -411,9 +411,11 @@ static void batadv_iv_ogm_aggregate_new(const unsigned char *packet_buff,
|
||||||
|
|
||||||
if ((atomic_read(&bat_priv->aggregated_ogms)) &&
|
if ((atomic_read(&bat_priv->aggregated_ogms)) &&
|
||||||
(packet_len < BATADV_MAX_AGGREGATION_BYTES))
|
(packet_len < BATADV_MAX_AGGREGATION_BYTES))
|
||||||
skb_size = BATADV_MAX_AGGREGATION_BYTES + ETH_HLEN;
|
skb_size = BATADV_MAX_AGGREGATION_BYTES;
|
||||||
else
|
else
|
||||||
skb_size = packet_len + ETH_HLEN;
|
skb_size = packet_len;
|
||||||
|
|
||||||
|
skb_size += ETH_HLEN + NET_IP_ALIGN;
|
||||||
|
|
||||||
forw_packet_aggr->skb = dev_alloc_skb(skb_size);
|
forw_packet_aggr->skb = dev_alloc_skb(skb_size);
|
||||||
if (!forw_packet_aggr->skb) {
|
if (!forw_packet_aggr->skb) {
|
||||||
|
@ -422,7 +424,7 @@ static void batadv_iv_ogm_aggregate_new(const unsigned char *packet_buff,
|
||||||
kfree(forw_packet_aggr);
|
kfree(forw_packet_aggr);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
skb_reserve(forw_packet_aggr->skb, ETH_HLEN);
|
skb_reserve(forw_packet_aggr->skb, ETH_HLEN + NET_IP_ALIGN);
|
||||||
|
|
||||||
INIT_HLIST_NODE(&forw_packet_aggr->list);
|
INIT_HLIST_NODE(&forw_packet_aggr->list);
|
||||||
|
|
||||||
|
|
|
@ -177,13 +177,13 @@ static ssize_t batadv_socket_write(struct file *file, const char __user *buff,
|
||||||
if (len >= sizeof(struct batadv_icmp_packet_rr))
|
if (len >= sizeof(struct batadv_icmp_packet_rr))
|
||||||
packet_len = sizeof(struct batadv_icmp_packet_rr);
|
packet_len = sizeof(struct batadv_icmp_packet_rr);
|
||||||
|
|
||||||
skb = dev_alloc_skb(packet_len + ETH_HLEN);
|
skb = dev_alloc_skb(packet_len + ETH_HLEN + NET_IP_ALIGN);
|
||||||
if (!skb) {
|
if (!skb) {
|
||||||
len = -ENOMEM;
|
len = -ENOMEM;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
skb_reserve(skb, ETH_HLEN);
|
skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN);
|
||||||
icmp_packet = (struct batadv_icmp_packet_rr *)skb_put(skb, packet_len);
|
icmp_packet = (struct batadv_icmp_packet_rr *)skb_put(skb, packet_len);
|
||||||
|
|
||||||
if (copy_from_user(icmp_packet, buff, packet_len)) {
|
if (copy_from_user(icmp_packet, buff, packet_len)) {
|
||||||
|
|
|
@ -1472,11 +1472,11 @@ batadv_tt_response_fill_table(uint16_t tt_len, uint8_t ttvn,
|
||||||
tt_tot = tt_len / sizeof(struct batadv_tt_change);
|
tt_tot = tt_len / sizeof(struct batadv_tt_change);
|
||||||
|
|
||||||
len = tt_query_size + tt_len;
|
len = tt_query_size + tt_len;
|
||||||
skb = dev_alloc_skb(len + ETH_HLEN);
|
skb = dev_alloc_skb(len + ETH_HLEN + NET_IP_ALIGN);
|
||||||
if (!skb)
|
if (!skb)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
skb_reserve(skb, ETH_HLEN);
|
skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN);
|
||||||
tt_response = (struct batadv_tt_query_packet *)skb_put(skb, len);
|
tt_response = (struct batadv_tt_query_packet *)skb_put(skb, len);
|
||||||
tt_response->ttvn = ttvn;
|
tt_response->ttvn = ttvn;
|
||||||
|
|
||||||
|
@ -1538,11 +1538,11 @@ static int batadv_send_tt_request(struct batadv_priv *bat_priv,
|
||||||
if (!tt_req_node)
|
if (!tt_req_node)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
skb = dev_alloc_skb(sizeof(*tt_request) + ETH_HLEN);
|
skb = dev_alloc_skb(sizeof(*tt_request) + ETH_HLEN + NET_IP_ALIGN);
|
||||||
if (!skb)
|
if (!skb)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
skb_reserve(skb, ETH_HLEN);
|
skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN);
|
||||||
|
|
||||||
tt_req_len = sizeof(*tt_request);
|
tt_req_len = sizeof(*tt_request);
|
||||||
tt_request = (struct batadv_tt_query_packet *)skb_put(skb, tt_req_len);
|
tt_request = (struct batadv_tt_query_packet *)skb_put(skb, tt_req_len);
|
||||||
|
@ -1653,11 +1653,11 @@ batadv_send_other_tt_response(struct batadv_priv *bat_priv,
|
||||||
tt_tot = tt_len / sizeof(struct batadv_tt_change);
|
tt_tot = tt_len / sizeof(struct batadv_tt_change);
|
||||||
|
|
||||||
len = sizeof(*tt_response) + tt_len;
|
len = sizeof(*tt_response) + tt_len;
|
||||||
skb = dev_alloc_skb(len + ETH_HLEN);
|
skb = dev_alloc_skb(len + ETH_HLEN + NET_IP_ALIGN);
|
||||||
if (!skb)
|
if (!skb)
|
||||||
goto unlock;
|
goto unlock;
|
||||||
|
|
||||||
skb_reserve(skb, ETH_HLEN);
|
skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN);
|
||||||
packet_pos = skb_put(skb, len);
|
packet_pos = skb_put(skb, len);
|
||||||
tt_response = (struct batadv_tt_query_packet *)packet_pos;
|
tt_response = (struct batadv_tt_query_packet *)packet_pos;
|
||||||
tt_response->ttvn = req_ttvn;
|
tt_response->ttvn = req_ttvn;
|
||||||
|
@ -1780,11 +1780,11 @@ batadv_send_my_tt_response(struct batadv_priv *bat_priv,
|
||||||
tt_tot = tt_len / sizeof(struct batadv_tt_change);
|
tt_tot = tt_len / sizeof(struct batadv_tt_change);
|
||||||
|
|
||||||
len = sizeof(*tt_response) + tt_len;
|
len = sizeof(*tt_response) + tt_len;
|
||||||
skb = dev_alloc_skb(len + ETH_HLEN);
|
skb = dev_alloc_skb(len + ETH_HLEN + NET_IP_ALIGN);
|
||||||
if (!skb)
|
if (!skb)
|
||||||
goto unlock;
|
goto unlock;
|
||||||
|
|
||||||
skb_reserve(skb, ETH_HLEN);
|
skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN);
|
||||||
packet_pos = skb_put(skb, len);
|
packet_pos = skb_put(skb, len);
|
||||||
tt_response = (struct batadv_tt_query_packet *)packet_pos;
|
tt_response = (struct batadv_tt_query_packet *)packet_pos;
|
||||||
tt_response->ttvn = req_ttvn;
|
tt_response->ttvn = req_ttvn;
|
||||||
|
@ -2118,11 +2118,11 @@ static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client,
|
||||||
if (!batadv_tt_check_roam_count(bat_priv, client))
|
if (!batadv_tt_check_roam_count(bat_priv, client))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
skb = dev_alloc_skb(sizeof(*roam_adv_packet) + ETH_HLEN);
|
skb = dev_alloc_skb(sizeof(*roam_adv_packet) + ETH_HLEN + NET_IP_ALIGN);
|
||||||
if (!skb)
|
if (!skb)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
skb_reserve(skb, ETH_HLEN);
|
skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN);
|
||||||
|
|
||||||
roam_adv_packet = (struct batadv_roam_adv_packet *)skb_put(skb, len);
|
roam_adv_packet = (struct batadv_roam_adv_packet *)skb_put(skb, len);
|
||||||
|
|
||||||
|
|
|
@ -396,12 +396,12 @@ batadv_add_packet(struct batadv_priv *bat_priv,
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
len = sizeof(*packet) + vis_info_len;
|
len = sizeof(*packet) + vis_info_len;
|
||||||
info->skb_packet = dev_alloc_skb(len + ETH_HLEN);
|
info->skb_packet = dev_alloc_skb(len + ETH_HLEN + NET_IP_ALIGN);
|
||||||
if (!info->skb_packet) {
|
if (!info->skb_packet) {
|
||||||
kfree(info);
|
kfree(info);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
skb_reserve(info->skb_packet, ETH_HLEN);
|
skb_reserve(info->skb_packet, ETH_HLEN + NET_IP_ALIGN);
|
||||||
packet = (struct batadv_vis_packet *)skb_put(info->skb_packet, len);
|
packet = (struct batadv_vis_packet *)skb_put(info->skb_packet, len);
|
||||||
|
|
||||||
kref_init(&info->refcount);
|
kref_init(&info->refcount);
|
||||||
|
@ -873,12 +873,13 @@ int batadv_vis_init(struct batadv_priv *bat_priv)
|
||||||
if (!bat_priv->vis.my_info)
|
if (!bat_priv->vis.my_info)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
len = sizeof(*packet) + BATADV_MAX_VIS_PACKET_SIZE + ETH_HLEN;
|
len = sizeof(*packet) + BATADV_MAX_VIS_PACKET_SIZE;
|
||||||
|
len += ETH_HLEN + NET_IP_ALIGN;
|
||||||
bat_priv->vis.my_info->skb_packet = dev_alloc_skb(len);
|
bat_priv->vis.my_info->skb_packet = dev_alloc_skb(len);
|
||||||
if (!bat_priv->vis.my_info->skb_packet)
|
if (!bat_priv->vis.my_info->skb_packet)
|
||||||
goto free_info;
|
goto free_info;
|
||||||
|
|
||||||
skb_reserve(bat_priv->vis.my_info->skb_packet, ETH_HLEN);
|
skb_reserve(bat_priv->vis.my_info->skb_packet, ETH_HLEN + NET_IP_ALIGN);
|
||||||
tmp_skb = bat_priv->vis.my_info->skb_packet;
|
tmp_skb = bat_priv->vis.my_info->skb_packet;
|
||||||
packet = (struct batadv_vis_packet *)skb_put(tmp_skb, sizeof(*packet));
|
packet = (struct batadv_vis_packet *)skb_put(tmp_skb, sizeof(*packet));
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue