aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv/send.c
diff options
context:
space:
mode:
authorMarek Lindner <lindner_marek@yahoo.de>2011-08-03 03:09:30 -0400
committerMarek Lindner <lindner_marek@yahoo.de>2011-09-08 11:44:41 -0400
commitb9dacc521f1cc21f018b27c9f83668258aaec8a2 (patch)
tree23187d4eb263098f2ab4e9fb48f0442a1bfea48d /net/batman-adv/send.c
parentd0b9fd89c2e44693e4c696bc1454fbe623d2e261 (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.c297
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
33static void send_outstanding_bcast_packet(struct work_struct *work); 33static void send_outstanding_bcast_packet(struct work_struct *work);
34 34
35/* apply hop penalty for a normal link */
36static 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 */
43static 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 */
51static 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 */
58int send_skb_packet(struct sk_buff *skb, struct hard_iface *hard_iface, 37int 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 */
103static 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 */
162static 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
224out:
225 if (primary_if)
226 hardif_free_ref(primary_if);
227}
228
229static void realloc_packet_buffer(struct hard_iface *hard_iface, 81static 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 */
248static void prepare_packet_buffer(struct bat_priv *bat_priv, 100static 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
276static void reset_packet_buffer(struct bat_priv *bat_priv, 125static 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
287void schedule_own_packet(struct hard_iface *hard_iface) 132void 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
363void 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
433static void forw_packet_free(struct forw_packet *forw_packet) 174static 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
564void send_outstanding_bat_packet(struct work_struct *work) 305void 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
590out: 331out:
591 /* don't count own packet */ 332 /* don't count own packet */