The following commit has been merged in the merge/master branch: commit 3b9bcebb9aa41474afaee34286d8a09a751a66fa Merge: b345bfb392e96d2cda71dbae0a83bc62c121ed03 fe4331557dd8bd702b592b9b899242af3284ca77 Author: Antonio Quartulli ordex@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));