diff options
Diffstat (limited to 'net/batman-adv/aggregation.c')
-rw-r--r-- | net/batman-adv/aggregation.c | 73 |
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 */ | ||
29 | static 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 */ |
35 | static bool can_aggregate_with(struct batman_packet *new_batman_packet, | 30 | static 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; | 102 | out: |
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 */ |
100 | static void new_aggregated_packet(unsigned char *packet_buff, int packet_len, | 109 | static 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 */ |
178 | static void aggregate(struct forw_packet *forw_packet_aggr, | 188 | static 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 | ||
196 | void add_bat_packet_to_list(struct bat_priv *bat_priv, | 205 | void 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 */ |
256 | void receive_aggr_bat_packet(struct ethhdr *ethhdr, unsigned char *packet_buff, | 266 | void 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 | } |