The following commit has been merged in the merge/master branch:
commit 3b9bcebb9aa41474afaee34286d8a09a751a66fa
Merge: b345bfb392e96d2cda71dbae0a83bc62c121ed03 fe4331557dd8bd702b592b9b899242af3284ca77
Author: Antonio Quartulli <ordex(a)autistici.org>
Date: Wed Nov 7 17:28:53 2012 +0100
Merge remote-tracking branch 'pkg/next' into merge/master
diff --combined net/batman-adv/bat_iv_ogm.c
index 75403a4,9f3925a..9f3925a
--- a/net/batman-adv/bat_iv_ogm.c
+++ b/net/batman-adv/bat_iv_ogm.c
@@@ -411,9 -411,11 +411,11 @@@ static void batadv_iv_ogm_aggregate_new
if ((atomic_read(&bat_priv->aggregated_ogms)) &&
(packet_len < BATADV_MAX_AGGREGATION_BYTES))
- skb_size = BATADV_MAX_AGGREGATION_BYTES + ETH_HLEN;
+ skb_size = BATADV_MAX_AGGREGATION_BYTES;
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);
if (!forw_packet_aggr->skb) {
@@@ -422,7 -424,7 +424,7 @@@
kfree(forw_packet_aggr);
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);
diff --combined net/batman-adv/icmp_socket.c
index 5874c0e,87ca809..87ca809
--- a/net/batman-adv/icmp_socket.c
+++ b/net/batman-adv/icmp_socket.c
@@@ -177,13 -177,13 +177,13 @@@ static ssize_t batadv_socket_write(stru
if (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) {
len = -ENOMEM;
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);
if (copy_from_user(icmp_packet, buff, packet_len)) {
diff --combined net/batman-adv/packet.h
index aa3e63a,1c5454d..1c5454d
--- a/net/batman-adv/packet.h
+++ b/net/batman-adv/packet.h
@@@ -121,13 -121,16 +121,16 @@@ struct batadv_bla_claim_dst
uint8_t magic[3]; /* FF:43:05 */
uint8_t type; /* bla_claimframe */
__be16 group; /* group id */
- } __packed;
+ };
struct batadv_header {
uint8_t packet_type;
uint8_t version; /* batman version field */
uint8_t ttl;
- } __packed;
+ /* the parent struct has to add a byte after the header to make
+ * everything 4 bytes aligned again
+ */
+ };
struct batadv_ogm_packet {
struct batadv_header header;
@@@ -152,7 -155,7 +155,7 @@@ struct batadv_icmp_packet
__be16 seqno;
uint8_t uid;
uint8_t reserved;
- } __packed;
+ };
#define BATADV_RR_LEN 16
@@@ -168,13 -171,28 +171,28 @@@ struct batadv_icmp_packet_rr
uint8_t uid;
uint8_t rr_cur;
uint8_t rr[BATADV_RR_LEN][ETH_ALEN];
- } __packed;
+ };
+
+ /* All packet headers in front of an ethernet header have to be completely
+ * divisible by 2 but not by 4 to make the payload after the ethernet
+ * header again 4 bytes boundary aligned.
+ *
+ * A packing of 2 is necessary to avoid extra padding at the end of the struct
+ * caused by a structure member which is larger than two bytes. Otherwise
+ * the structure would not fulfill the previously mentioned rule to avoid the
+ * misalignment of the payload after the ethernet header. It may also lead to
+ * leakage of information when the padding it not initialized before sending.
+ */
+ #pragma pack(2)
struct batadv_unicast_packet {
struct batadv_header header;
uint8_t ttvn; /* destination translation table version number */
uint8_t dest[ETH_ALEN];
- } __packed;
+ /* "4 bytes boundary + 2 bytes" long to make the payload after the
+ * following ethernet header again 4 bytes boundary aligned
+ */
+ };
/**
* struct batadv_unicast_4addr_packet - extended unicast packet
@@@ -186,7 -204,11 +204,11 @@@ struct batadv_unicast_4addr_packet
struct batadv_unicast_packet u;
uint8_t src[ETH_ALEN];
uint8_t subtype;
- } __packed;
+ uint8_t reserved;
+ /* "4 bytes boundary + 2 bytes" long to make the payload after the
+ * following ethernet header again 4 bytes boundary aligned
+ */
+ };
struct batadv_unicast_frag_packet {
struct batadv_header header;
@@@ -203,7 -225,12 +225,12 @@@ struct batadv_bcast_packet
uint8_t reserved;
__be32 seqno;
uint8_t orig[ETH_ALEN];
- } __packed;
+ /* "4 bytes boundary + 2 bytes" long to make the payload after the
+ * following ethernet header again 4 bytes boundary aligned
+ */
+ };
+
+ #pragma pack()
struct batadv_vis_packet {
struct batadv_header header;
@@@ -214,7 -241,7 +241,7 @@@
uint8_t vis_orig[ETH_ALEN]; /* originator reporting its neighbors */
uint8_t target_orig[ETH_ALEN]; /* who should receive this packet */
uint8_t sender_orig[ETH_ALEN]; /* who sent or forwarded this packet */
- } __packed;
+ };
struct batadv_tt_query_packet {
struct batadv_header header;
diff --combined net/batman-adv/routing.c
index d5a01d1,63ff456..63ff456
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@@ -890,22 -890,37 +890,37 @@@ batadv_reroute_unicast_packet(struct ba
struct batadv_unicast_packet *unicast_packet,
uint8_t *dst_addr)
{
- struct batadv_orig_node *orig_node;
+ struct batadv_orig_node *orig_node = NULL;
+ struct batadv_hard_iface *primary_if = NULL;
bool ret = false;
+ uint8_t *orig_addr, orig_ttvn;
- orig_node = batadv_transtable_search(bat_priv, NULL, dst_addr);
- if (!orig_node)
- goto out;
+ if (batadv_is_my_client(bat_priv, dst_addr)) {
+ primary_if = batadv_primary_if_get_selected(bat_priv);
+ if (!primary_if)
+ goto out;
+ orig_addr = primary_if->net_dev->dev_addr;
+ orig_ttvn = (uint8_t)atomic_read(&bat_priv->tt.vn);
+ } else {
+ orig_node = batadv_transtable_search(bat_priv, NULL, dst_addr);
+ if (!orig_node)
+ goto out;
- if (batadv_compare_eth(orig_node->orig, unicast_packet->dest))
- goto out;
+ if (batadv_compare_eth(orig_node->orig, unicast_packet->dest))
+ goto out;
+
+ orig_addr = orig_node->orig;
+ orig_ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn);
+ }
/* update the packet header */
- memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN);
- unicast_packet->ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn);
+ memcpy(unicast_packet->dest, orig_addr, ETH_ALEN);
+ unicast_packet->ttvn = orig_ttvn;
ret = true;
out:
+ if (primary_if)
+ batadv_hardif_free_ref(primary_if);
if (orig_node)
batadv_orig_node_free_ref(orig_node);
@@@ -914,7 -929,7 +929,7 @@@
static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv,
struct sk_buff *skb) {
- uint8_t curr_ttvn;
+ uint8_t curr_ttvn, old_ttvn;
struct batadv_orig_node *orig_node;
struct ethhdr *ethhdr;
struct batadv_hard_iface *primary_if;
@@@ -979,6 -994,7 +994,7 @@@
if (!is_old_ttvn)
return 1;
+ old_ttvn = unicast_packet->ttvn;
/* the packet was forged based on outdated network information. Its
* destination can possibly be updated and forwarded towards the new
* target host
@@@ -988,7 -1004,7 +1004,7 @@@
net_ratelimited_function(batadv_dbg, BATADV_DBG_TT, bat_priv,
"Rerouting unicast packet to %pM (dst=%pM): TTVN mismatch old_ttvn=%u new_ttvn=%u\n",
unicast_packet->dest, ethhdr->h_dest,
- unicast_packet->ttvn, curr_ttvn);
+ old_ttvn, curr_ttvn);
return 1;
}
diff --combined net/batman-adv/translation-table.c
index 6fecb94,f3628a2..f3628a2
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@@ -292,7 -292,6 +292,6 @@@ void batadv_tt_local_add(struct net_dev
*/
tt_local->common.flags &= ~BATADV_TT_CLIENT_ROAM;
roamed_back = true;
- goto check_roaming;
}
goto check_roaming;
}
@@@ -860,14 -859,6 +859,6 @@@ int batadv_tt_global_add(struct batadv_
*/
common->flags &= ~BATADV_TT_CLIENT_TEMP;
- /* if this is a normal add, possibly unset the ROAM flag. This
- * flag could have been set before because the client was
- * roaming, but now that the node got the ADD event, the flag
- * can be unset
- */
- if (!(flags & BATADV_TT_CLIENT_ROAM))
- common->flags &= ~BATADV_TT_CLIENT_ROAM;
-
/* If there is the BATADV_TT_CLIENT_ROAM flag set, there is only
* one originator left in the list and we previously received a
* delete + roaming change for this originator.
@@@ -1594,11 -1585,11 +1585,11 @@@ batadv_tt_response_fill_table(uint16_t
tt_tot = tt_len / sizeof(struct batadv_tt_change);
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)
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->ttvn = ttvn;
@@@ -1659,11 -1650,11 +1650,11 @@@ static int batadv_send_tt_request(struc
if (!tt_req_node)
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)
goto out;
- skb_reserve(skb, ETH_HLEN);
+ skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN);
tt_req_len = sizeof(*tt_request);
tt_request = (struct batadv_tt_query_packet *)skb_put(skb, tt_req_len);
@@@ -1761,11 -1752,11 +1752,11 @@@ batadv_send_other_tt_response(struct ba
tt_tot = tt_len / sizeof(struct batadv_tt_change);
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)
goto unlock;
- skb_reserve(skb, ETH_HLEN);
+ skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN);
packet_pos = skb_put(skb, len);
tt_response = (struct batadv_tt_query_packet *)packet_pos;
tt_response->ttvn = req_ttvn;
@@@ -1880,11 -1871,11 +1871,11 @@@ batadv_send_my_tt_response(struct batad
tt_tot = tt_len / sizeof(struct batadv_tt_change);
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)
goto unlock;
- skb_reserve(skb, ETH_HLEN);
+ skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN);
packet_pos = skb_put(skb, len);
tt_response = (struct batadv_tt_query_packet *)packet_pos;
tt_response->ttvn = req_ttvn;
@@@ -2211,11 -2202,11 +2202,11 @@@ static void batadv_send_roam_adv(struc
if (!batadv_tt_check_roam_count(bat_priv, client))
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)
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);
diff --combined net/batman-adv/unicast.c
index 9416136,10aff49..10aff49
--- a/net/batman-adv/unicast.c
+++ b/net/batman-adv/unicast.c
@@@ -374,6 -374,7 +374,7 @@@ bool batadv_unicast_4addr_prepare_skb(s
memcpy(unicast_4addr_packet->src, primary_if->net_dev->dev_addr,
ETH_ALEN);
unicast_4addr_packet->subtype = packet_subtype;
+ unicast_4addr_packet->reserved = 0;
ret = true;
out:
diff --combined net/batman-adv/vis.c
index 79589a3,0f65a9d..0f65a9d
--- a/net/batman-adv/vis.c
+++ b/net/batman-adv/vis.c
@@@ -396,12 -396,12 +396,12 @@@ batadv_add_packet(struct batadv_priv *b
return NULL;
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) {
kfree(info);
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);
kref_init(&info->refcount);
@@@ -856,12 -856,13 +856,13 @@@ int batadv_vis_init(struct batadv_priv
if (!bat_priv->vis.my_info)
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);
if (!bat_priv->vis.my_info->skb_packet)
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;
packet = (struct batadv_vis_packet *)skb_put(tmp_skb, sizeof(*packet));
--
linux integration