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.c266
1 files changed, 0 insertions, 266 deletions
diff --git a/net/batman-adv/aggregation.c b/net/batman-adv/aggregation.c
deleted file mode 100644
index 4716c9386f21..000000000000
--- a/net/batman-adv/aggregation.c
+++ /dev/null
@@ -1,266 +0,0 @@
1/*
2 * Copyright (C) 2007-2011 B.A.T.M.A.N. contributors:
3 *
4 * Marek Lindner, Simon Wunderlich
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of version 2 of the GNU General Public
8 * License as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 * 02110-1301, USA
19 *
20 */
21
22#include "main.h"
23#include "translation-table.h"
24#include "aggregation.h"
25#include "send.h"
26#include "routing.h"
27#include "hard-interface.h"
28
29/* return true if new_packet can be aggregated with forw_packet */
30static bool can_aggregate_with(const struct batman_ogm_packet
31 *new_batman_ogm_packet,
32 struct bat_priv *bat_priv,
33 int packet_len,
34 unsigned long send_time,
35 bool directlink,
36 const struct hard_iface *if_incoming,
37 const struct forw_packet *forw_packet)
38{
39 struct batman_ogm_packet *batman_ogm_packet =
40 (struct batman_ogm_packet *)forw_packet->skb->data;
41 int aggregated_bytes = forw_packet->packet_len + packet_len;
42 struct hard_iface *primary_if = NULL;
43 bool res = false;
44
45 /**
46 * we can aggregate the current packet to this aggregated packet
47 * if:
48 *
49 * - the send time is within our MAX_AGGREGATION_MS time
50 * - the resulting packet wont be bigger than
51 * MAX_AGGREGATION_BYTES
52 */
53
54 if (time_before(send_time, forw_packet->send_time) &&
55 time_after_eq(send_time + msecs_to_jiffies(MAX_AGGREGATION_MS),
56 forw_packet->send_time) &&
57 (aggregated_bytes <= MAX_AGGREGATION_BYTES)) {
58
59 /**
60 * check aggregation compatibility
61 * -> direct link packets are broadcasted on
62 * their interface only
63 * -> aggregate packet if the current packet is
64 * a "global" packet as well as the base
65 * packet
66 */
67
68 primary_if = primary_if_get_selected(bat_priv);
69 if (!primary_if)
70 goto out;
71
72 /* packets without direct link flag and high TTL
73 * are flooded through the net */
74 if ((!directlink) &&
75 (!(batman_ogm_packet->flags & DIRECTLINK)) &&
76 (batman_ogm_packet->ttl != 1) &&
77
78 /* own packets originating non-primary
79 * interfaces leave only that interface */
80 ((!forw_packet->own) ||
81 (forw_packet->if_incoming == primary_if))) {
82 res = true;
83 goto out;
84 }
85
86 /* if the incoming packet is sent via this one
87 * interface only - we still can aggregate */
88 if ((directlink) &&
89 (new_batman_ogm_packet->ttl == 1) &&
90 (forw_packet->if_incoming == if_incoming) &&
91
92 /* packets from direct neighbors or
93 * own secondary interface packets
94 * (= secondary interface packets in general) */
95 (batman_ogm_packet->flags & DIRECTLINK ||
96 (forw_packet->own &&
97 forw_packet->if_incoming != primary_if))) {
98 res = true;
99 goto out;
100 }
101 }
102
103out:
104 if (primary_if)
105 hardif_free_ref(primary_if);
106 return res;
107}
108
109/* create a new aggregated packet and add this packet to it */
110static void new_aggregated_packet(const unsigned char *packet_buff,
111 int packet_len, unsigned long send_time,
112 bool direct_link,
113 struct hard_iface *if_incoming,
114 int own_packet)
115{
116 struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
117 struct forw_packet *forw_packet_aggr;
118 unsigned char *skb_buff;
119
120 if (!atomic_inc_not_zero(&if_incoming->refcount))
121 return;
122
123 /* own packet should always be scheduled */
124 if (!own_packet) {
125 if (!atomic_dec_not_zero(&bat_priv->batman_queue_left)) {
126 bat_dbg(DBG_BATMAN, bat_priv,
127 "batman packet queue full\n");
128 goto out;
129 }
130 }
131
132 forw_packet_aggr = kmalloc(sizeof(*forw_packet_aggr), GFP_ATOMIC);
133 if (!forw_packet_aggr) {
134 if (!own_packet)
135 atomic_inc(&bat_priv->batman_queue_left);
136 goto out;
137 }
138
139 if ((atomic_read(&bat_priv->aggregated_ogms)) &&
140 (packet_len < MAX_AGGREGATION_BYTES))
141 forw_packet_aggr->skb = dev_alloc_skb(MAX_AGGREGATION_BYTES +
142 sizeof(struct ethhdr));
143 else
144 forw_packet_aggr->skb = dev_alloc_skb(packet_len +
145 sizeof(struct ethhdr));
146
147 if (!forw_packet_aggr->skb) {
148 if (!own_packet)
149 atomic_inc(&bat_priv->batman_queue_left);
150 kfree(forw_packet_aggr);
151 goto out;
152 }
153 skb_reserve(forw_packet_aggr->skb, sizeof(struct ethhdr));
154
155 INIT_HLIST_NODE(&forw_packet_aggr->list);
156
157 skb_buff = skb_put(forw_packet_aggr->skb, packet_len);
158 forw_packet_aggr->packet_len = packet_len;
159 memcpy(skb_buff, packet_buff, packet_len);
160
161 forw_packet_aggr->own = own_packet;
162 forw_packet_aggr->if_incoming = if_incoming;
163 forw_packet_aggr->num_packets = 0;
164 forw_packet_aggr->direct_link_flags = NO_FLAGS;
165 forw_packet_aggr->send_time = send_time;
166
167 /* save packet direct link flag status */
168 if (direct_link)
169 forw_packet_aggr->direct_link_flags |= 1;
170
171 /* add new packet to packet list */
172 spin_lock_bh(&bat_priv->forw_bat_list_lock);
173 hlist_add_head(&forw_packet_aggr->list, &bat_priv->forw_bat_list);
174 spin_unlock_bh(&bat_priv->forw_bat_list_lock);
175
176 /* start timer for this packet */
177 INIT_DELAYED_WORK(&forw_packet_aggr->delayed_work,
178 send_outstanding_bat_packet);
179 queue_delayed_work(bat_event_workqueue,
180 &forw_packet_aggr->delayed_work,
181 send_time - jiffies);
182
183 return;
184out:
185 hardif_free_ref(if_incoming);
186}
187
188/* aggregate a new packet into the existing aggregation */
189static void aggregate(struct forw_packet *forw_packet_aggr,
190 const unsigned char *packet_buff, int packet_len,
191 bool direct_link)
192{
193 unsigned char *skb_buff;
194
195 skb_buff = skb_put(forw_packet_aggr->skb, packet_len);
196 memcpy(skb_buff, packet_buff, packet_len);
197 forw_packet_aggr->packet_len += packet_len;
198 forw_packet_aggr->num_packets++;
199
200 /* save packet direct link flag status */
201 if (direct_link)
202 forw_packet_aggr->direct_link_flags |=
203 (1 << forw_packet_aggr->num_packets);
204}
205
206void add_bat_packet_to_list(struct bat_priv *bat_priv,
207 unsigned char *packet_buff, int packet_len,
208 struct hard_iface *if_incoming, int own_packet,
209 unsigned long send_time)
210{
211 /**
212 * _aggr -> pointer to the packet we want to aggregate with
213 * _pos -> pointer to the position in the queue
214 */
215 struct forw_packet *forw_packet_aggr = NULL, *forw_packet_pos = NULL;
216 struct hlist_node *tmp_node;
217 struct batman_ogm_packet *batman_ogm_packet;
218 bool direct_link;
219
220 batman_ogm_packet = (struct batman_ogm_packet *)packet_buff;
221 direct_link = batman_ogm_packet->flags & DIRECTLINK ? 1 : 0;
222
223 /* find position for the packet in the forward queue */
224 spin_lock_bh(&bat_priv->forw_bat_list_lock);
225 /* own packets are not to be aggregated */
226 if ((atomic_read(&bat_priv->aggregated_ogms)) && (!own_packet)) {
227 hlist_for_each_entry(forw_packet_pos, tmp_node,
228 &bat_priv->forw_bat_list, list) {
229 if (can_aggregate_with(batman_ogm_packet,
230 bat_priv,
231 packet_len,
232 send_time,
233 direct_link,
234 if_incoming,
235 forw_packet_pos)) {
236 forw_packet_aggr = forw_packet_pos;
237 break;
238 }
239 }
240 }
241
242 /* nothing to aggregate with - either aggregation disabled or no
243 * suitable aggregation packet found */
244 if (!forw_packet_aggr) {
245 /* the following section can run without the lock */
246 spin_unlock_bh(&bat_priv->forw_bat_list_lock);
247
248 /**
249 * if we could not aggregate this packet with one of the others
250 * we hold it back for a while, so that it might be aggregated
251 * later on
252 */
253 if ((!own_packet) &&
254 (atomic_read(&bat_priv->aggregated_ogms)))
255 send_time += msecs_to_jiffies(MAX_AGGREGATION_MS);
256
257 new_aggregated_packet(packet_buff, packet_len,
258 send_time, direct_link,
259 if_incoming, own_packet);
260 } else {
261 aggregate(forw_packet_aggr,
262 packet_buff, packet_len,
263 direct_link);
264 spin_unlock_bh(&bat_priv->forw_bat_list_lock);
265 }
266}