aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv/aggregation.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/batman-adv/aggregation.c')
-rw-r--r--net/batman-adv/aggregation.c73
1 files changed, 43 insertions, 30 deletions
diff --git a/net/batman-adv/aggregation.c b/net/batman-adv/aggregation.c
index a8c32030527c..69467fe71ff2 100644
--- a/net/batman-adv/aggregation.c
+++ b/net/batman-adv/aggregation.c
@@ -20,28 +20,26 @@
20 */ 20 */
21 21
22#include "main.h" 22#include "main.h"
23#include "translation-table.h"
23#include "aggregation.h" 24#include "aggregation.h"
24#include "send.h" 25#include "send.h"
25#include "routing.h" 26#include "routing.h"
26#include "hard-interface.h" 27#include "hard-interface.h"
27 28
28/* calculate the size of the tt information for a given packet */
29static int tt_len(struct batman_packet *batman_packet)
30{
31 return batman_packet->num_tt * ETH_ALEN;
32}
33
34/* return true if new_packet can be aggregated with forw_packet */ 29/* return true if new_packet can be aggregated with forw_packet */
35static bool can_aggregate_with(struct batman_packet *new_batman_packet, 30static bool can_aggregate_with(const struct batman_packet *new_batman_packet,
31 struct bat_priv *bat_priv,
36 int packet_len, 32 int packet_len,
37 unsigned long send_time, 33 unsigned long send_time,
38 bool directlink, 34 bool directlink,
39 struct hard_iface *if_incoming, 35 const struct hard_iface *if_incoming,
40 struct forw_packet *forw_packet) 36 const struct forw_packet *forw_packet)
41{ 37{
42 struct batman_packet *batman_packet = 38 struct batman_packet *batman_packet =
43 (struct batman_packet *)forw_packet->skb->data; 39 (struct batman_packet *)forw_packet->skb->data;
44 int aggregated_bytes = forw_packet->packet_len + packet_len; 40 int aggregated_bytes = forw_packet->packet_len + packet_len;
41 struct hard_iface *primary_if = NULL;
42 bool res = false;
45 43
46 /** 44 /**
47 * we can aggregate the current packet to this aggregated packet 45 * we can aggregate the current packet to this aggregated packet
@@ -66,6 +64,10 @@ static bool can_aggregate_with(struct batman_packet *new_batman_packet,
66 * packet 64 * packet
67 */ 65 */
68 66
67 primary_if = primary_if_get_selected(bat_priv);
68 if (!primary_if)
69 goto out;
70
69 /* packets without direct link flag and high TTL 71 /* packets without direct link flag and high TTL
70 * are flooded through the net */ 72 * are flooded through the net */
71 if ((!directlink) && 73 if ((!directlink) &&
@@ -75,8 +77,10 @@ static bool can_aggregate_with(struct batman_packet *new_batman_packet,
75 /* own packets originating non-primary 77 /* own packets originating non-primary
76 * interfaces leave only that interface */ 78 * interfaces leave only that interface */
77 ((!forw_packet->own) || 79 ((!forw_packet->own) ||
78 (forw_packet->if_incoming->if_num == 0))) 80 (forw_packet->if_incoming == primary_if))) {
79 return true; 81 res = true;
82 goto out;
83 }
80 84
81 /* if the incoming packet is sent via this one 85 /* if the incoming packet is sent via this one
82 * interface only - we still can aggregate */ 86 * interface only - we still can aggregate */
@@ -89,16 +93,22 @@ static bool can_aggregate_with(struct batman_packet *new_batman_packet,
89 * (= secondary interface packets in general) */ 93 * (= secondary interface packets in general) */
90 (batman_packet->flags & DIRECTLINK || 94 (batman_packet->flags & DIRECTLINK ||
91 (forw_packet->own && 95 (forw_packet->own &&
92 forw_packet->if_incoming->if_num != 0))) 96 forw_packet->if_incoming != primary_if))) {
93 return true; 97 res = true;
98 goto out;
99 }
94 } 100 }
95 101
96 return false; 102out:
103 if (primary_if)
104 hardif_free_ref(primary_if);
105 return res;
97} 106}
98 107
99/* create a new aggregated packet and add this packet to it */ 108/* create a new aggregated packet and add this packet to it */
100static void new_aggregated_packet(unsigned char *packet_buff, int packet_len, 109static void new_aggregated_packet(const unsigned char *packet_buff,
101 unsigned long send_time, bool direct_link, 110 int packet_len, unsigned long send_time,
111 bool direct_link,
102 struct hard_iface *if_incoming, 112 struct hard_iface *if_incoming,
103 int own_packet) 113 int own_packet)
104{ 114{
@@ -118,7 +128,7 @@ static void new_aggregated_packet(unsigned char *packet_buff, int packet_len,
118 } 128 }
119 } 129 }
120 130
121 forw_packet_aggr = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC); 131 forw_packet_aggr = kmalloc(sizeof(*forw_packet_aggr), GFP_ATOMIC);
122 if (!forw_packet_aggr) { 132 if (!forw_packet_aggr) {
123 if (!own_packet) 133 if (!own_packet)
124 atomic_inc(&bat_priv->batman_queue_left); 134 atomic_inc(&bat_priv->batman_queue_left);
@@ -150,7 +160,7 @@ static void new_aggregated_packet(unsigned char *packet_buff, int packet_len,
150 forw_packet_aggr->own = own_packet; 160 forw_packet_aggr->own = own_packet;
151 forw_packet_aggr->if_incoming = if_incoming; 161 forw_packet_aggr->if_incoming = if_incoming;
152 forw_packet_aggr->num_packets = 0; 162 forw_packet_aggr->num_packets = 0;
153 forw_packet_aggr->direct_link_flags = 0; 163 forw_packet_aggr->direct_link_flags = NO_FLAGS;
154 forw_packet_aggr->send_time = send_time; 164 forw_packet_aggr->send_time = send_time;
155 165
156 /* save packet direct link flag status */ 166 /* save packet direct link flag status */
@@ -176,8 +186,7 @@ out:
176 186
177/* aggregate a new packet into the existing aggregation */ 187/* aggregate a new packet into the existing aggregation */
178static void aggregate(struct forw_packet *forw_packet_aggr, 188static void aggregate(struct forw_packet *forw_packet_aggr,
179 unsigned char *packet_buff, 189 const unsigned char *packet_buff, int packet_len,
180 int packet_len,
181 bool direct_link) 190 bool direct_link)
182{ 191{
183 unsigned char *skb_buff; 192 unsigned char *skb_buff;
@@ -195,7 +204,7 @@ static void aggregate(struct forw_packet *forw_packet_aggr,
195 204
196void add_bat_packet_to_list(struct bat_priv *bat_priv, 205void add_bat_packet_to_list(struct bat_priv *bat_priv,
197 unsigned char *packet_buff, int packet_len, 206 unsigned char *packet_buff, int packet_len,
198 struct hard_iface *if_incoming, char own_packet, 207 struct hard_iface *if_incoming, int own_packet,
199 unsigned long send_time) 208 unsigned long send_time)
200{ 209{
201 /** 210 /**
@@ -215,6 +224,7 @@ void add_bat_packet_to_list(struct bat_priv *bat_priv,
215 hlist_for_each_entry(forw_packet_pos, tmp_node, 224 hlist_for_each_entry(forw_packet_pos, tmp_node,
216 &bat_priv->forw_bat_list, list) { 225 &bat_priv->forw_bat_list, list) {
217 if (can_aggregate_with(batman_packet, 226 if (can_aggregate_with(batman_packet,
227 bat_priv,
218 packet_len, 228 packet_len,
219 send_time, 229 send_time,
220 direct_link, 230 direct_link,
@@ -253,8 +263,9 @@ void add_bat_packet_to_list(struct bat_priv *bat_priv,
253} 263}
254 264
255/* unpack the aggregated packets and process them one by one */ 265/* unpack the aggregated packets and process them one by one */
256void receive_aggr_bat_packet(struct ethhdr *ethhdr, unsigned char *packet_buff, 266void receive_aggr_bat_packet(const struct ethhdr *ethhdr,
257 int packet_len, struct hard_iface *if_incoming) 267 unsigned char *packet_buff, int packet_len,
268 struct hard_iface *if_incoming)
258{ 269{
259 struct batman_packet *batman_packet; 270 struct batman_packet *batman_packet;
260 int buff_pos = 0; 271 int buff_pos = 0;
@@ -263,18 +274,20 @@ void receive_aggr_bat_packet(struct ethhdr *ethhdr, unsigned char *packet_buff,
263 batman_packet = (struct batman_packet *)packet_buff; 274 batman_packet = (struct batman_packet *)packet_buff;
264 275
265 do { 276 do {
266 /* network to host order for our 32bit seqno, and the 277 /* network to host order for our 32bit seqno and the
267 orig_interval. */ 278 orig_interval */
268 batman_packet->seqno = ntohl(batman_packet->seqno); 279 batman_packet->seqno = ntohl(batman_packet->seqno);
280 batman_packet->tt_crc = ntohs(batman_packet->tt_crc);
269 281
270 tt_buff = packet_buff + buff_pos + BAT_PACKET_LEN; 282 tt_buff = packet_buff + buff_pos + BAT_PACKET_LEN;
271 receive_bat_packet(ethhdr, batman_packet,
272 tt_buff, tt_len(batman_packet),
273 if_incoming);
274 283
275 buff_pos += BAT_PACKET_LEN + tt_len(batman_packet); 284 receive_bat_packet(ethhdr, batman_packet, tt_buff, if_incoming);
285
286 buff_pos += BAT_PACKET_LEN +
287 tt_len(batman_packet->tt_num_changes);
288
276 batman_packet = (struct batman_packet *) 289 batman_packet = (struct batman_packet *)
277 (packet_buff + buff_pos); 290 (packet_buff + buff_pos);
278 } while (aggregated_packet(buff_pos, packet_len, 291 } while (aggregated_packet(buff_pos, packet_len,
279 batman_packet->num_tt)); 292 batman_packet->tt_num_changes));
280} 293}