diff options
author | Marek Lindner <lindner_marek@yahoo.de> | 2011-08-03 03:09:30 -0400 |
---|---|---|
committer | Marek Lindner <lindner_marek@yahoo.de> | 2011-09-08 11:44:41 -0400 |
commit | b9dacc521f1cc21f018b27c9f83668258aaec8a2 (patch) | |
tree | 23187d4eb263098f2ab4e9fb48f0442a1bfea48d /net/batman-adv/send.c | |
parent | d0b9fd89c2e44693e4c696bc1454fbe623d2e261 (diff) |
batman-adv: agglomerate all batman iv ogm sending functions in the batman iv file
In the process the batman iv OGM aggregation code could be merged
into the batman iv code base which makes the separate aggregation
files superfluous.
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
Diffstat (limited to 'net/batman-adv/send.c')
-rw-r--r-- | net/batman-adv/send.c | 297 |
1 files changed, 19 insertions, 278 deletions
diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c index 40a5fcd67136..8a684eb738ad 100644 --- a/net/batman-adv/send.c +++ b/net/batman-adv/send.c | |||
@@ -26,33 +26,12 @@ | |||
26 | #include "soft-interface.h" | 26 | #include "soft-interface.h" |
27 | #include "hard-interface.h" | 27 | #include "hard-interface.h" |
28 | #include "vis.h" | 28 | #include "vis.h" |
29 | #include "aggregation.h" | ||
30 | #include "gateway_common.h" | 29 | #include "gateway_common.h" |
31 | #include "originator.h" | 30 | #include "originator.h" |
31 | #include "bat_ogm.h" | ||
32 | 32 | ||
33 | static void send_outstanding_bcast_packet(struct work_struct *work); | 33 | static void send_outstanding_bcast_packet(struct work_struct *work); |
34 | 34 | ||
35 | /* apply hop penalty for a normal link */ | ||
36 | static uint8_t hop_penalty(uint8_t tq, const struct bat_priv *bat_priv) | ||
37 | { | ||
38 | int hop_penalty = atomic_read(&bat_priv->hop_penalty); | ||
39 | return (tq * (TQ_MAX_VALUE - hop_penalty)) / (TQ_MAX_VALUE); | ||
40 | } | ||
41 | |||
42 | /* when do we schedule our own packet to be sent */ | ||
43 | static unsigned long own_send_time(const struct bat_priv *bat_priv) | ||
44 | { | ||
45 | return jiffies + msecs_to_jiffies( | ||
46 | atomic_read(&bat_priv->orig_interval) - | ||
47 | JITTER + (random32() % 2*JITTER)); | ||
48 | } | ||
49 | |||
50 | /* when do we schedule a forwarded packet to be sent */ | ||
51 | static unsigned long forward_send_time(void) | ||
52 | { | ||
53 | return jiffies + msecs_to_jiffies(random32() % (JITTER/2)); | ||
54 | } | ||
55 | |||
56 | /* send out an already prepared packet to the given address via the | 35 | /* send out an already prepared packet to the given address via the |
57 | * specified batman interface */ | 36 | * specified batman interface */ |
58 | int send_skb_packet(struct sk_buff *skb, struct hard_iface *hard_iface, | 37 | int send_skb_packet(struct sk_buff *skb, struct hard_iface *hard_iface, |
@@ -99,133 +78,6 @@ send_skb_err: | |||
99 | return NET_XMIT_DROP; | 78 | return NET_XMIT_DROP; |
100 | } | 79 | } |
101 | 80 | ||
102 | /* Send a packet to a given interface */ | ||
103 | static void send_packet_to_if(struct forw_packet *forw_packet, | ||
104 | struct hard_iface *hard_iface) | ||
105 | { | ||
106 | struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface); | ||
107 | char *fwd_str; | ||
108 | uint8_t packet_num; | ||
109 | int16_t buff_pos; | ||
110 | struct batman_ogm_packet *batman_ogm_packet; | ||
111 | struct sk_buff *skb; | ||
112 | |||
113 | if (hard_iface->if_status != IF_ACTIVE) | ||
114 | return; | ||
115 | |||
116 | packet_num = 0; | ||
117 | buff_pos = 0; | ||
118 | batman_ogm_packet = (struct batman_ogm_packet *)forw_packet->skb->data; | ||
119 | |||
120 | /* adjust all flags and log packets */ | ||
121 | while (aggregated_packet(buff_pos, | ||
122 | forw_packet->packet_len, | ||
123 | batman_ogm_packet->tt_num_changes)) { | ||
124 | |||
125 | /* we might have aggregated direct link packets with an | ||
126 | * ordinary base packet */ | ||
127 | if ((forw_packet->direct_link_flags & (1 << packet_num)) && | ||
128 | (forw_packet->if_incoming == hard_iface)) | ||
129 | batman_ogm_packet->flags |= DIRECTLINK; | ||
130 | else | ||
131 | batman_ogm_packet->flags &= ~DIRECTLINK; | ||
132 | |||
133 | fwd_str = (packet_num > 0 ? "Forwarding" : (forw_packet->own ? | ||
134 | "Sending own" : | ||
135 | "Forwarding")); | ||
136 | bat_dbg(DBG_BATMAN, bat_priv, | ||
137 | "%s %spacket (originator %pM, seqno %d, TQ %d, TTL %d," | ||
138 | " IDF %s, ttvn %d) on interface %s [%pM]\n", | ||
139 | fwd_str, (packet_num > 0 ? "aggregated " : ""), | ||
140 | batman_ogm_packet->orig, | ||
141 | ntohl(batman_ogm_packet->seqno), | ||
142 | batman_ogm_packet->tq, batman_ogm_packet->ttl, | ||
143 | (batman_ogm_packet->flags & DIRECTLINK ? | ||
144 | "on" : "off"), | ||
145 | batman_ogm_packet->ttvn, hard_iface->net_dev->name, | ||
146 | hard_iface->net_dev->dev_addr); | ||
147 | |||
148 | buff_pos += BATMAN_OGM_LEN + | ||
149 | tt_len(batman_ogm_packet->tt_num_changes); | ||
150 | packet_num++; | ||
151 | batman_ogm_packet = (struct batman_ogm_packet *) | ||
152 | (forw_packet->skb->data + buff_pos); | ||
153 | } | ||
154 | |||
155 | /* create clone because function is called more than once */ | ||
156 | skb = skb_clone(forw_packet->skb, GFP_ATOMIC); | ||
157 | if (skb) | ||
158 | send_skb_packet(skb, hard_iface, broadcast_addr); | ||
159 | } | ||
160 | |||
161 | /* send a batman packet */ | ||
162 | static void send_packet(struct forw_packet *forw_packet) | ||
163 | { | ||
164 | struct hard_iface *hard_iface; | ||
165 | struct net_device *soft_iface; | ||
166 | struct bat_priv *bat_priv; | ||
167 | struct hard_iface *primary_if = NULL; | ||
168 | struct batman_ogm_packet *batman_ogm_packet = | ||
169 | (struct batman_ogm_packet *)(forw_packet->skb->data); | ||
170 | unsigned char directlink; | ||
171 | |||
172 | directlink = (batman_ogm_packet->flags & DIRECTLINK ? 1 : 0); | ||
173 | |||
174 | if (!forw_packet->if_incoming) { | ||
175 | pr_err("Error - can't forward packet: incoming iface not " | ||
176 | "specified\n"); | ||
177 | goto out; | ||
178 | } | ||
179 | |||
180 | soft_iface = forw_packet->if_incoming->soft_iface; | ||
181 | bat_priv = netdev_priv(soft_iface); | ||
182 | |||
183 | if (forw_packet->if_incoming->if_status != IF_ACTIVE) | ||
184 | goto out; | ||
185 | |||
186 | primary_if = primary_if_get_selected(bat_priv); | ||
187 | if (!primary_if) | ||
188 | goto out; | ||
189 | |||
190 | /* multihomed peer assumed */ | ||
191 | /* non-primary OGMs are only broadcasted on their interface */ | ||
192 | if ((directlink && (batman_ogm_packet->ttl == 1)) || | ||
193 | (forw_packet->own && (forw_packet->if_incoming != primary_if))) { | ||
194 | |||
195 | /* FIXME: what about aggregated packets ? */ | ||
196 | bat_dbg(DBG_BATMAN, bat_priv, | ||
197 | "%s packet (originator %pM, seqno %d, TTL %d) " | ||
198 | "on interface %s [%pM]\n", | ||
199 | (forw_packet->own ? "Sending own" : "Forwarding"), | ||
200 | batman_ogm_packet->orig, | ||
201 | ntohl(batman_ogm_packet->seqno), | ||
202 | batman_ogm_packet->ttl, | ||
203 | forw_packet->if_incoming->net_dev->name, | ||
204 | forw_packet->if_incoming->net_dev->dev_addr); | ||
205 | |||
206 | /* skb is only used once and than forw_packet is free'd */ | ||
207 | send_skb_packet(forw_packet->skb, forw_packet->if_incoming, | ||
208 | broadcast_addr); | ||
209 | forw_packet->skb = NULL; | ||
210 | |||
211 | goto out; | ||
212 | } | ||
213 | |||
214 | /* broadcast on every interface */ | ||
215 | rcu_read_lock(); | ||
216 | list_for_each_entry_rcu(hard_iface, &hardif_list, list) { | ||
217 | if (hard_iface->soft_iface != soft_iface) | ||
218 | continue; | ||
219 | |||
220 | send_packet_to_if(forw_packet, hard_iface); | ||
221 | } | ||
222 | rcu_read_unlock(); | ||
223 | |||
224 | out: | ||
225 | if (primary_if) | ||
226 | hardif_free_ref(primary_if); | ||
227 | } | ||
228 | |||
229 | static void realloc_packet_buffer(struct hard_iface *hard_iface, | 81 | static void realloc_packet_buffer(struct hard_iface *hard_iface, |
230 | int new_len) | 82 | int new_len) |
231 | { | 83 | { |
@@ -245,11 +97,10 @@ static void realloc_packet_buffer(struct hard_iface *hard_iface, | |||
245 | } | 97 | } |
246 | 98 | ||
247 | /* when calling this function (hard_iface == primary_if) has to be true */ | 99 | /* when calling this function (hard_iface == primary_if) has to be true */ |
248 | static void prepare_packet_buffer(struct bat_priv *bat_priv, | 100 | static int prepare_packet_buffer(struct bat_priv *bat_priv, |
249 | struct hard_iface *hard_iface) | 101 | struct hard_iface *hard_iface) |
250 | { | 102 | { |
251 | int new_len; | 103 | int new_len; |
252 | struct batman_ogm_packet *batman_ogm_packet; | ||
253 | 104 | ||
254 | new_len = BATMAN_OGM_LEN + | 105 | new_len = BATMAN_OGM_LEN + |
255 | tt_len((uint8_t)atomic_read(&bat_priv->tt_local_changes)); | 106 | tt_len((uint8_t)atomic_read(&bat_priv->tt_local_changes)); |
@@ -260,45 +111,34 @@ static void prepare_packet_buffer(struct bat_priv *bat_priv, | |||
260 | new_len = BATMAN_OGM_LEN; | 111 | new_len = BATMAN_OGM_LEN; |
261 | 112 | ||
262 | realloc_packet_buffer(hard_iface, new_len); | 113 | realloc_packet_buffer(hard_iface, new_len); |
263 | batman_ogm_packet = (struct batman_ogm_packet *)hard_iface->packet_buff; | ||
264 | 114 | ||
265 | atomic_set(&bat_priv->tt_crc, tt_local_crc(bat_priv)); | 115 | atomic_set(&bat_priv->tt_crc, tt_local_crc(bat_priv)); |
266 | 116 | ||
267 | /* reset the sending counter */ | 117 | /* reset the sending counter */ |
268 | atomic_set(&bat_priv->tt_ogm_append_cnt, TT_OGM_APPEND_MAX); | 118 | atomic_set(&bat_priv->tt_ogm_append_cnt, TT_OGM_APPEND_MAX); |
269 | 119 | ||
270 | batman_ogm_packet->tt_num_changes = tt_changes_fill_buffer(bat_priv, | 120 | return tt_changes_fill_buffer(bat_priv, |
271 | hard_iface->packet_buff + BATMAN_OGM_LEN, | 121 | hard_iface->packet_buff + BATMAN_OGM_LEN, |
272 | hard_iface->packet_len - BATMAN_OGM_LEN); | 122 | hard_iface->packet_len - BATMAN_OGM_LEN); |
273 | |||
274 | } | 123 | } |
275 | 124 | ||
276 | static void reset_packet_buffer(struct bat_priv *bat_priv, | 125 | static int reset_packet_buffer(struct bat_priv *bat_priv, |
277 | struct hard_iface *hard_iface) | 126 | struct hard_iface *hard_iface) |
278 | { | 127 | { |
279 | struct batman_ogm_packet *batman_ogm_packet; | ||
280 | |||
281 | realloc_packet_buffer(hard_iface, BATMAN_OGM_LEN); | 128 | realloc_packet_buffer(hard_iface, BATMAN_OGM_LEN); |
282 | 129 | return 0; | |
283 | batman_ogm_packet = (struct batman_ogm_packet *)hard_iface->packet_buff; | ||
284 | batman_ogm_packet->tt_num_changes = 0; | ||
285 | } | 130 | } |
286 | 131 | ||
287 | void schedule_own_packet(struct hard_iface *hard_iface) | 132 | void schedule_bat_ogm(struct hard_iface *hard_iface) |
288 | { | 133 | { |
289 | struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface); | 134 | struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface); |
290 | struct hard_iface *primary_if; | 135 | struct hard_iface *primary_if; |
291 | unsigned long send_time; | 136 | int tt_num_changes = -1; |
292 | struct batman_ogm_packet *batman_ogm_packet; | ||
293 | int vis_server; | ||
294 | 137 | ||
295 | if ((hard_iface->if_status == IF_NOT_IN_USE) || | 138 | if ((hard_iface->if_status == IF_NOT_IN_USE) || |
296 | (hard_iface->if_status == IF_TO_BE_REMOVED)) | 139 | (hard_iface->if_status == IF_TO_BE_REMOVED)) |
297 | return; | 140 | return; |
298 | 141 | ||
299 | vis_server = atomic_read(&bat_priv->vis_mode); | ||
300 | primary_if = primary_if_get_selected(bat_priv); | ||
301 | |||
302 | /** | 142 | /** |
303 | * the interface gets activated here to avoid race conditions between | 143 | * the interface gets activated here to avoid race conditions between |
304 | * the moment of activating the interface in | 144 | * the moment of activating the interface in |
@@ -309,125 +149,26 @@ void schedule_own_packet(struct hard_iface *hard_iface) | |||
309 | if (hard_iface->if_status == IF_TO_BE_ACTIVATED) | 149 | if (hard_iface->if_status == IF_TO_BE_ACTIVATED) |
310 | hard_iface->if_status = IF_ACTIVE; | 150 | hard_iface->if_status = IF_ACTIVE; |
311 | 151 | ||
152 | primary_if = primary_if_get_selected(bat_priv); | ||
153 | |||
312 | if (hard_iface == primary_if) { | 154 | if (hard_iface == primary_if) { |
313 | /* if at least one change happened */ | 155 | /* if at least one change happened */ |
314 | if (atomic_read(&bat_priv->tt_local_changes) > 0) { | 156 | if (atomic_read(&bat_priv->tt_local_changes) > 0) { |
315 | tt_commit_changes(bat_priv); | 157 | tt_commit_changes(bat_priv); |
316 | prepare_packet_buffer(bat_priv, hard_iface); | 158 | tt_num_changes = prepare_packet_buffer(bat_priv, |
159 | hard_iface); | ||
317 | } | 160 | } |
318 | 161 | ||
319 | /* if the changes have been sent often enough */ | 162 | /* if the changes have been sent often enough */ |
320 | if (!atomic_dec_not_zero(&bat_priv->tt_ogm_append_cnt)) | 163 | if (!atomic_dec_not_zero(&bat_priv->tt_ogm_append_cnt)) |
321 | reset_packet_buffer(bat_priv, hard_iface); | 164 | tt_num_changes = reset_packet_buffer(bat_priv, |
165 | hard_iface); | ||
322 | } | 166 | } |
323 | 167 | ||
324 | /** | ||
325 | * NOTE: packet_buff might just have been re-allocated in | ||
326 | * prepare_packet_buffer() or in reset_packet_buffer() | ||
327 | */ | ||
328 | batman_ogm_packet = (struct batman_ogm_packet *)hard_iface->packet_buff; | ||
329 | |||
330 | /* change sequence number to network order */ | ||
331 | batman_ogm_packet->seqno = | ||
332 | htonl((uint32_t)atomic_read(&hard_iface->seqno)); | ||
333 | |||
334 | batman_ogm_packet->ttvn = atomic_read(&bat_priv->ttvn); | ||
335 | batman_ogm_packet->tt_crc = htons((uint16_t) | ||
336 | atomic_read(&bat_priv->tt_crc)); | ||
337 | |||
338 | if (vis_server == VIS_TYPE_SERVER_SYNC) | ||
339 | batman_ogm_packet->flags |= VIS_SERVER; | ||
340 | else | ||
341 | batman_ogm_packet->flags &= ~VIS_SERVER; | ||
342 | |||
343 | if ((hard_iface == primary_if) && | ||
344 | (atomic_read(&bat_priv->gw_mode) == GW_MODE_SERVER)) | ||
345 | batman_ogm_packet->gw_flags = | ||
346 | (uint8_t)atomic_read(&bat_priv->gw_bandwidth); | ||
347 | else | ||
348 | batman_ogm_packet->gw_flags = NO_FLAGS; | ||
349 | |||
350 | atomic_inc(&hard_iface->seqno); | ||
351 | |||
352 | slide_own_bcast_window(hard_iface); | ||
353 | send_time = own_send_time(bat_priv); | ||
354 | add_bat_packet_to_list(bat_priv, | ||
355 | hard_iface->packet_buff, | ||
356 | hard_iface->packet_len, | ||
357 | hard_iface, 1, send_time); | ||
358 | |||
359 | if (primary_if) | 168 | if (primary_if) |
360 | hardif_free_ref(primary_if); | 169 | hardif_free_ref(primary_if); |
361 | } | ||
362 | |||
363 | void schedule_forward_packet(struct orig_node *orig_node, | ||
364 | const struct ethhdr *ethhdr, | ||
365 | struct batman_ogm_packet *batman_ogm_packet, | ||
366 | int directlink, | ||
367 | struct hard_iface *if_incoming) | ||
368 | { | ||
369 | struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); | ||
370 | struct neigh_node *router; | ||
371 | uint8_t in_tq, in_ttl, tq_avg = 0; | ||
372 | unsigned long send_time; | ||
373 | uint8_t tt_num_changes; | ||
374 | |||
375 | if (batman_ogm_packet->ttl <= 1) { | ||
376 | bat_dbg(DBG_BATMAN, bat_priv, "ttl exceeded\n"); | ||
377 | return; | ||
378 | } | ||
379 | |||
380 | router = orig_node_get_router(orig_node); | ||
381 | |||
382 | in_tq = batman_ogm_packet->tq; | ||
383 | in_ttl = batman_ogm_packet->ttl; | ||
384 | tt_num_changes = batman_ogm_packet->tt_num_changes; | ||
385 | |||
386 | batman_ogm_packet->ttl--; | ||
387 | memcpy(batman_ogm_packet->prev_sender, ethhdr->h_source, ETH_ALEN); | ||
388 | |||
389 | /* rebroadcast tq of our best ranking neighbor to ensure the rebroadcast | ||
390 | * of our best tq value */ | ||
391 | if (router && router->tq_avg != 0) { | ||
392 | |||
393 | /* rebroadcast ogm of best ranking neighbor as is */ | ||
394 | if (!compare_eth(router->addr, ethhdr->h_source)) { | ||
395 | batman_ogm_packet->tq = router->tq_avg; | ||
396 | |||
397 | if (router->last_ttl) | ||
398 | batman_ogm_packet->ttl = router->last_ttl - 1; | ||
399 | } | ||
400 | |||
401 | tq_avg = router->tq_avg; | ||
402 | } | ||
403 | |||
404 | if (router) | ||
405 | neigh_node_free_ref(router); | ||
406 | |||
407 | /* apply hop penalty */ | ||
408 | batman_ogm_packet->tq = hop_penalty(batman_ogm_packet->tq, bat_priv); | ||
409 | |||
410 | bat_dbg(DBG_BATMAN, bat_priv, | ||
411 | "Forwarding packet: tq_orig: %i, tq_avg: %i, " | ||
412 | "tq_forw: %i, ttl_orig: %i, ttl_forw: %i\n", | ||
413 | in_tq, tq_avg, batman_ogm_packet->tq, in_ttl - 1, | ||
414 | batman_ogm_packet->ttl); | ||
415 | |||
416 | batman_ogm_packet->seqno = htonl(batman_ogm_packet->seqno); | ||
417 | batman_ogm_packet->tt_crc = htons(batman_ogm_packet->tt_crc); | ||
418 | |||
419 | /* switch of primaries first hop flag when forwarding */ | ||
420 | batman_ogm_packet->flags &= ~PRIMARIES_FIRST_HOP; | ||
421 | if (directlink) | ||
422 | batman_ogm_packet->flags |= DIRECTLINK; | ||
423 | else | ||
424 | batman_ogm_packet->flags &= ~DIRECTLINK; | ||
425 | 170 | ||
426 | send_time = forward_send_time(); | 171 | bat_ogm_schedule(hard_iface, tt_num_changes); |
427 | add_bat_packet_to_list(bat_priv, | ||
428 | (unsigned char *)batman_ogm_packet, | ||
429 | BATMAN_OGM_LEN + tt_len(tt_num_changes), | ||
430 | if_incoming, 0, send_time); | ||
431 | } | 172 | } |
432 | 173 | ||
433 | static void forw_packet_free(struct forw_packet *forw_packet) | 174 | static void forw_packet_free(struct forw_packet *forw_packet) |
@@ -561,7 +302,7 @@ out: | |||
561 | atomic_inc(&bat_priv->bcast_queue_left); | 302 | atomic_inc(&bat_priv->bcast_queue_left); |
562 | } | 303 | } |
563 | 304 | ||
564 | void send_outstanding_bat_packet(struct work_struct *work) | 305 | void send_outstanding_bat_ogm_packet(struct work_struct *work) |
565 | { | 306 | { |
566 | struct delayed_work *delayed_work = | 307 | struct delayed_work *delayed_work = |
567 | container_of(work, struct delayed_work, work); | 308 | container_of(work, struct delayed_work, work); |
@@ -577,7 +318,7 @@ void send_outstanding_bat_packet(struct work_struct *work) | |||
577 | if (atomic_read(&bat_priv->mesh_state) == MESH_DEACTIVATING) | 318 | if (atomic_read(&bat_priv->mesh_state) == MESH_DEACTIVATING) |
578 | goto out; | 319 | goto out; |
579 | 320 | ||
580 | send_packet(forw_packet); | 321 | bat_ogm_emit(forw_packet); |
581 | 322 | ||
582 | /** | 323 | /** |
583 | * we have to have at least one packet in the queue | 324 | * we have to have at least one packet in the queue |
@@ -585,7 +326,7 @@ void send_outstanding_bat_packet(struct work_struct *work) | |||
585 | * shutting down | 326 | * shutting down |
586 | */ | 327 | */ |
587 | if (forw_packet->own) | 328 | if (forw_packet->own) |
588 | schedule_own_packet(forw_packet->if_incoming); | 329 | schedule_bat_ogm(forw_packet->if_incoming); |
589 | 330 | ||
590 | out: | 331 | out: |
591 | /* don't count own packet */ | 332 | /* don't count own packet */ |