aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorSimon Wunderlich <sw@simonwunderlich.de>2013-10-22 16:50:09 -0400
committerAntonio Quartulli <antonio@meshcoding.com>2013-10-23 11:03:47 -0400
commitda6b8c20a5b8c7edce95c95fa2356300691094f5 (patch)
tree1154c27c3f4e9d62c099044f891441125f965e1f /net
parent15c33da6e8c960e61691ec302fd72f247e97055b (diff)
batman-adv: generalize batman-adv icmp packet handling
Instead of handling icmp packets only up to length of icmp_packet_rr, the code should handle any icmp length size. Therefore the length truncating is moved to when the packet is actually sent to userspace (this does not support lengths longer than icmp_packet_rr yet). Longer packets are forwarded without truncating. This patch also cleans up some parts where the icmp header struct could be used instead of other icmp_packet(_rr) structs to make the code more readable. Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de> Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch> Signed-off-by: Antonio Quartulli <antonio@meshcoding.com>
Diffstat (limited to 'net')
-rw-r--r--net/batman-adv/icmp_socket.c128
-rw-r--r--net/batman-adv/icmp_socket.h2
-rw-r--r--net/batman-adv/packet.h2
-rw-r--r--net/batman-adv/routing.c120
-rw-r--r--net/batman-adv/types.h2
5 files changed, 157 insertions, 97 deletions
diff --git a/net/batman-adv/icmp_socket.c b/net/batman-adv/icmp_socket.c
index 82ac6472fa6f..29ae4efe3543 100644
--- a/net/batman-adv/icmp_socket.c
+++ b/net/batman-adv/icmp_socket.c
@@ -29,7 +29,7 @@
29static struct batadv_socket_client *batadv_socket_client_hash[256]; 29static struct batadv_socket_client *batadv_socket_client_hash[256];
30 30
31static void batadv_socket_add_packet(struct batadv_socket_client *socket_client, 31static void batadv_socket_add_packet(struct batadv_socket_client *socket_client,
32 struct batadv_icmp_packet_rr *icmp_packet, 32 struct batadv_icmp_header *icmph,
33 size_t icmp_len); 33 size_t icmp_len);
34 34
35void batadv_socket_init(void) 35void batadv_socket_init(void)
@@ -155,13 +155,13 @@ static ssize_t batadv_socket_write(struct file *file, const char __user *buff,
155 struct batadv_priv *bat_priv = socket_client->bat_priv; 155 struct batadv_priv *bat_priv = socket_client->bat_priv;
156 struct batadv_hard_iface *primary_if = NULL; 156 struct batadv_hard_iface *primary_if = NULL;
157 struct sk_buff *skb; 157 struct sk_buff *skb;
158 struct batadv_icmp_packet_rr *icmp_packet; 158 struct batadv_icmp_packet_rr *icmp_packet_rr;
159 159 struct batadv_icmp_header *icmp_header;
160 struct batadv_orig_node *orig_node = NULL; 160 struct batadv_orig_node *orig_node = NULL;
161 struct batadv_neigh_node *neigh_node = NULL; 161 struct batadv_neigh_node *neigh_node = NULL;
162 size_t packet_len = sizeof(struct batadv_icmp_packet); 162 size_t packet_len = sizeof(struct batadv_icmp_packet);
163 163
164 if (len < sizeof(struct batadv_icmp_packet)) { 164 if (len < sizeof(struct batadv_icmp_header)) {
165 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 165 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
166 "Error - can't send packet from char device: invalid packet size\n"); 166 "Error - can't send packet from char device: invalid packet size\n");
167 return -EINVAL; 167 return -EINVAL;
@@ -174,8 +174,10 @@ static ssize_t batadv_socket_write(struct file *file, const char __user *buff,
174 goto out; 174 goto out;
175 } 175 }
176 176
177 if (len >= sizeof(struct batadv_icmp_packet_rr)) 177 if (len >= BATADV_ICMP_MAX_PACKET_SIZE)
178 packet_len = sizeof(struct batadv_icmp_packet_rr); 178 packet_len = BATADV_ICMP_MAX_PACKET_SIZE;
179 else
180 packet_len = len;
179 181
180 skb = netdev_alloc_skb_ip_align(NULL, packet_len + ETH_HLEN); 182 skb = netdev_alloc_skb_ip_align(NULL, packet_len + ETH_HLEN);
181 if (!skb) { 183 if (!skb) {
@@ -185,67 +187,78 @@ static ssize_t batadv_socket_write(struct file *file, const char __user *buff,
185 187
186 skb->priority = TC_PRIO_CONTROL; 188 skb->priority = TC_PRIO_CONTROL;
187 skb_reserve(skb, ETH_HLEN); 189 skb_reserve(skb, ETH_HLEN);
188 icmp_packet = (struct batadv_icmp_packet_rr *)skb_put(skb, packet_len); 190 icmp_header = (struct batadv_icmp_header *)skb_put(skb, packet_len);
189 191
190 if (copy_from_user(icmp_packet, buff, packet_len)) { 192 if (copy_from_user(icmp_header, buff, packet_len)) {
191 len = -EFAULT; 193 len = -EFAULT;
192 goto free_skb; 194 goto free_skb;
193 } 195 }
194 196
195 if (icmp_packet->icmph.header.packet_type != BATADV_ICMP) { 197 if (icmp_header->header.packet_type != BATADV_ICMP) {
196 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 198 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
197 "Error - can't send packet from char device: got bogus packet type (expected: BAT_ICMP)\n"); 199 "Error - can't send packet from char device: got bogus packet type (expected: BAT_ICMP)\n");
198 len = -EINVAL; 200 len = -EINVAL;
199 goto free_skb; 201 goto free_skb;
200 } 202 }
201 203
202 if (icmp_packet->icmph.msg_type != BATADV_ECHO_REQUEST) { 204 switch (icmp_header->msg_type) {
205 case BATADV_ECHO_REQUEST:
206 if (len < sizeof(struct batadv_icmp_packet)) {
207 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
208 "Error - can't send packet from char device: invalid packet size\n");
209 len = -EINVAL;
210 goto free_skb;
211 }
212
213 if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE)
214 goto dst_unreach;
215
216 orig_node = batadv_orig_hash_find(bat_priv, icmp_header->dst);
217 if (!orig_node)
218 goto dst_unreach;
219
220 neigh_node = batadv_orig_node_get_router(orig_node);
221 if (!neigh_node)
222 goto dst_unreach;
223
224 if (!neigh_node->if_incoming)
225 goto dst_unreach;
226
227 if (neigh_node->if_incoming->if_status != BATADV_IF_ACTIVE)
228 goto dst_unreach;
229
230 icmp_packet_rr = (struct batadv_icmp_packet_rr *)icmp_header;
231 if (packet_len == sizeof(*icmp_packet_rr))
232 memcpy(icmp_packet_rr->rr,
233 neigh_node->if_incoming->net_dev->dev_addr,
234 ETH_ALEN);
235
236 break;
237 default:
203 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 238 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
204 "Error - can't send packet from char device: got bogus message type (expected: ECHO_REQUEST)\n"); 239 "Error - can't send packet from char device: got unknown message type\n");
205 len = -EINVAL; 240 len = -EINVAL;
206 goto free_skb; 241 goto free_skb;
207 } 242 }
208 243
209 icmp_packet->icmph.uid = socket_client->index; 244 icmp_header->uid = socket_client->index;
210 245
211 if (icmp_packet->icmph.header.version != BATADV_COMPAT_VERSION) { 246 if (icmp_header->header.version != BATADV_COMPAT_VERSION) {
212 icmp_packet->icmph.msg_type = BATADV_PARAMETER_PROBLEM; 247 icmp_header->msg_type = BATADV_PARAMETER_PROBLEM;
213 icmp_packet->icmph.header.version = BATADV_COMPAT_VERSION; 248 icmp_header->header.version = BATADV_COMPAT_VERSION;
214 batadv_socket_add_packet(socket_client, icmp_packet, 249 batadv_socket_add_packet(socket_client, icmp_header,
215 packet_len); 250 packet_len);
216 goto free_skb; 251 goto free_skb;
217 } 252 }
218 253
219 if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE) 254 memcpy(icmp_header->orig, primary_if->net_dev->dev_addr, ETH_ALEN);
220 goto dst_unreach;
221
222 orig_node = batadv_orig_hash_find(bat_priv, icmp_packet->icmph.dst);
223 if (!orig_node)
224 goto dst_unreach;
225
226 neigh_node = batadv_orig_node_get_router(orig_node);
227 if (!neigh_node)
228 goto dst_unreach;
229
230 if (!neigh_node->if_incoming)
231 goto dst_unreach;
232
233 if (neigh_node->if_incoming->if_status != BATADV_IF_ACTIVE)
234 goto dst_unreach;
235
236 memcpy(icmp_packet->icmph.orig,
237 primary_if->net_dev->dev_addr, ETH_ALEN);
238
239 if (packet_len == sizeof(struct batadv_icmp_packet_rr))
240 memcpy(icmp_packet->rr,
241 neigh_node->if_incoming->net_dev->dev_addr, ETH_ALEN);
242 255
243 batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); 256 batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
244 goto out; 257 goto out;
245 258
246dst_unreach: 259dst_unreach:
247 icmp_packet->icmph.msg_type = BATADV_DESTINATION_UNREACHABLE; 260 icmp_header->msg_type = BATADV_DESTINATION_UNREACHABLE;
248 batadv_socket_add_packet(socket_client, icmp_packet, packet_len); 261 batadv_socket_add_packet(socket_client, icmp_header, packet_len);
249free_skb: 262free_skb:
250 kfree_skb(skb); 263 kfree_skb(skb);
251out: 264out:
@@ -298,27 +311,40 @@ err:
298 return -ENOMEM; 311 return -ENOMEM;
299} 312}
300 313
314/**
315 * batadv_socket_receive_packet - schedule an icmp packet to be sent to userspace
316 * on an icmp socket.
317 * @socket_client: the socket this packet belongs to
318 * @icmph: pointer to the header of the icmp packet
319 * @icmp_len: total length of the icmp packet
320 */
301static void batadv_socket_add_packet(struct batadv_socket_client *socket_client, 321static void batadv_socket_add_packet(struct batadv_socket_client *socket_client,
302 struct batadv_icmp_packet_rr *icmp_packet, 322 struct batadv_icmp_header *icmph,
303 size_t icmp_len) 323 size_t icmp_len)
304{ 324{
305 struct batadv_socket_packet *socket_packet; 325 struct batadv_socket_packet *socket_packet;
326 size_t len;
306 327
307 socket_packet = kmalloc(sizeof(*socket_packet), GFP_ATOMIC); 328 socket_packet = kmalloc(sizeof(*socket_packet), GFP_ATOMIC);
308 329
309 if (!socket_packet) 330 if (!socket_packet)
310 return; 331 return;
311 332
333 len = icmp_len;
334 /* check the maximum length before filling the buffer */
335 if (len > sizeof(socket_packet->icmp_packet))
336 len = sizeof(socket_packet->icmp_packet);
337
312 INIT_LIST_HEAD(&socket_packet->list); 338 INIT_LIST_HEAD(&socket_packet->list);
313 memcpy(&socket_packet->icmp_packet, icmp_packet, icmp_len); 339 memcpy(&socket_packet->icmp_packet, icmph, len);
314 socket_packet->icmp_len = icmp_len; 340 socket_packet->icmp_len = len;
315 341
316 spin_lock_bh(&socket_client->lock); 342 spin_lock_bh(&socket_client->lock);
317 343
318 /* while waiting for the lock the socket_client could have been 344 /* while waiting for the lock the socket_client could have been
319 * deleted 345 * deleted
320 */ 346 */
321 if (!batadv_socket_client_hash[icmp_packet->icmph.uid]) { 347 if (!batadv_socket_client_hash[icmph->uid]) {
322 spin_unlock_bh(&socket_client->lock); 348 spin_unlock_bh(&socket_client->lock);
323 kfree(socket_packet); 349 kfree(socket_packet);
324 return; 350 return;
@@ -342,12 +368,18 @@ static void batadv_socket_add_packet(struct batadv_socket_client *socket_client,
342 wake_up(&socket_client->queue_wait); 368 wake_up(&socket_client->queue_wait);
343} 369}
344 370
345void batadv_socket_receive_packet(struct batadv_icmp_packet_rr *icmp_packet, 371/**
372 * batadv_socket_receive_packet - schedule an icmp packet to be received
373 * locally and sent to userspace.
374 * @icmph: pointer to the header of the icmp packet
375 * @icmp_len: total length of the icmp packet
376 */
377void batadv_socket_receive_packet(struct batadv_icmp_header *icmph,
346 size_t icmp_len) 378 size_t icmp_len)
347{ 379{
348 struct batadv_socket_client *hash; 380 struct batadv_socket_client *hash;
349 381
350 hash = batadv_socket_client_hash[icmp_packet->icmph.uid]; 382 hash = batadv_socket_client_hash[icmph->uid];
351 if (hash) 383 if (hash)
352 batadv_socket_add_packet(hash, icmp_packet, icmp_len); 384 batadv_socket_add_packet(hash, icmph, icmp_len);
353} 385}
diff --git a/net/batman-adv/icmp_socket.h b/net/batman-adv/icmp_socket.h
index 1fcca37b6223..6665080dff79 100644
--- a/net/batman-adv/icmp_socket.h
+++ b/net/batman-adv/icmp_socket.h
@@ -24,7 +24,7 @@
24 24
25void batadv_socket_init(void); 25void batadv_socket_init(void);
26int batadv_socket_setup(struct batadv_priv *bat_priv); 26int batadv_socket_setup(struct batadv_priv *bat_priv);
27void batadv_socket_receive_packet(struct batadv_icmp_packet_rr *icmp_packet, 27void batadv_socket_receive_packet(struct batadv_icmp_header *icmph,
28 size_t icmp_len); 28 size_t icmp_len);
29 29
30#endif /* _NET_BATMAN_ADV_ICMP_SOCKET_H_ */ 30#endif /* _NET_BATMAN_ADV_ICMP_SOCKET_H_ */
diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h
index 843b96ac355a..207459b62966 100644
--- a/net/batman-adv/packet.h
+++ b/net/batman-adv/packet.h
@@ -239,6 +239,8 @@ struct batadv_icmp_packet_rr {
239 uint8_t rr[BATADV_RR_LEN][ETH_ALEN]; 239 uint8_t rr[BATADV_RR_LEN][ETH_ALEN];
240}; 240};
241 241
242#define BATADV_ICMP_MAX_PACKET_SIZE sizeof(struct batadv_icmp_packet_rr)
243
242/* All packet headers in front of an ethernet header have to be completely 244/* All packet headers in front of an ethernet header have to be completely
243 * divisible by 2 but not by 4 to make the payload after the ethernet 245 * divisible by 2 but not by 4 to make the payload after the ethernet
244 * header again 4 bytes boundary aligned. 246 * header again 4 bytes boundary aligned.
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index 71fba146ddf1..d4114d775ad6 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -260,47 +260,65 @@ bool batadv_check_management_packet(struct sk_buff *skb,
260 return true; 260 return true;
261} 261}
262 262
263/**
264 * batadv_recv_my_icmp_packet - receive an icmp packet locally
265 * @bat_priv: the bat priv with all the soft interface information
266 * @skb: icmp packet to process
267 *
268 * Returns NET_RX_SUCCESS if the packet has been consumed or NET_RX_DROP
269 * otherwise.
270 */
263static int batadv_recv_my_icmp_packet(struct batadv_priv *bat_priv, 271static int batadv_recv_my_icmp_packet(struct batadv_priv *bat_priv,
264 struct sk_buff *skb, size_t icmp_len) 272 struct sk_buff *skb)
265{ 273{
266 struct batadv_hard_iface *primary_if = NULL; 274 struct batadv_hard_iface *primary_if = NULL;
267 struct batadv_orig_node *orig_node = NULL; 275 struct batadv_orig_node *orig_node = NULL;
268 struct batadv_icmp_packet_rr *icmp_packet; 276 struct batadv_icmp_header *icmph;
269 int ret = NET_RX_DROP; 277 int res, ret = NET_RX_DROP;
270 278
271 icmp_packet = (struct batadv_icmp_packet_rr *)skb->data; 279 icmph = (struct batadv_icmp_header *)skb->data;
272 280
273 /* add data to device queue */ 281 switch (icmph->msg_type) {
274 if (icmp_packet->icmph.msg_type != BATADV_ECHO_REQUEST) { 282 case BATADV_ECHO_REPLY:
275 batadv_socket_receive_packet(icmp_packet, icmp_len); 283 case BATADV_DESTINATION_UNREACHABLE:
276 goto out; 284 case BATADV_TTL_EXCEEDED:
277 } 285 /* receive the packet */
286 if (skb_linearize(skb) < 0)
287 break;
278 288
279 primary_if = batadv_primary_if_get_selected(bat_priv); 289 batadv_socket_receive_packet(icmph, skb->len);
280 if (!primary_if) 290 break;
281 goto out; 291 case BATADV_ECHO_REQUEST:
292 /* answer echo request (ping) */
293 primary_if = batadv_primary_if_get_selected(bat_priv);
294 if (!primary_if)
295 goto out;
282 296
283 /* answer echo request (ping) */ 297 /* get routing information */
284 /* get routing information */ 298 orig_node = batadv_orig_hash_find(bat_priv, icmph->orig);
285 orig_node = batadv_orig_hash_find(bat_priv, icmp_packet->icmph.orig); 299 if (!orig_node)
286 if (!orig_node) 300 goto out;
287 goto out;
288 301
289 /* create a copy of the skb, if needed, to modify it. */ 302 /* create a copy of the skb, if needed, to modify it. */
290 if (skb_cow(skb, ETH_HLEN) < 0) 303 if (skb_cow(skb, ETH_HLEN) < 0)
291 goto out; 304 goto out;
292 305
293 icmp_packet = (struct batadv_icmp_packet_rr *)skb->data; 306 icmph = (struct batadv_icmp_header *)skb->data;
294 307
295 memcpy(icmp_packet->icmph.dst, icmp_packet->icmph.orig, ETH_ALEN); 308 memcpy(icmph->dst, icmph->orig, ETH_ALEN);
296 memcpy(icmp_packet->icmph.orig, primary_if->net_dev->dev_addr, 309 memcpy(icmph->orig, primary_if->net_dev->dev_addr, ETH_ALEN);
297 ETH_ALEN); 310 icmph->msg_type = BATADV_ECHO_REPLY;
298 icmp_packet->icmph.msg_type = BATADV_ECHO_REPLY; 311 icmph->header.ttl = BATADV_TTL;
299 icmp_packet->icmph.header.ttl = BATADV_TTL;
300 312
301 if (batadv_send_skb_to_orig(skb, orig_node, NULL) != NET_XMIT_DROP) 313 res = batadv_send_skb_to_orig(skb, orig_node, NULL);
302 ret = NET_RX_SUCCESS; 314 if (res != NET_XMIT_DROP)
315 ret = NET_RX_SUCCESS;
303 316
317 break;
318 default:
319 /* drop unknown type */
320 goto out;
321 }
304out: 322out:
305 if (primary_if) 323 if (primary_if)
306 batadv_hardif_free_ref(primary_if); 324 batadv_hardif_free_ref(primary_if);
@@ -363,16 +381,13 @@ int batadv_recv_icmp_packet(struct sk_buff *skb,
363 struct batadv_hard_iface *recv_if) 381 struct batadv_hard_iface *recv_if)
364{ 382{
365 struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface); 383 struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface);
366 struct batadv_icmp_packet_rr *icmp_packet; 384 struct batadv_icmp_header *icmph;
385 struct batadv_icmp_packet_rr *icmp_packet_rr;
367 struct ethhdr *ethhdr; 386 struct ethhdr *ethhdr;
368 struct batadv_orig_node *orig_node = NULL; 387 struct batadv_orig_node *orig_node = NULL;
369 int hdr_size = sizeof(struct batadv_icmp_packet); 388 int hdr_size = sizeof(struct batadv_icmp_header);
370 int ret = NET_RX_DROP; 389 int ret = NET_RX_DROP;
371 390
372 /* we truncate all incoming icmp packets if they don't match our size */
373 if (skb->len >= sizeof(struct batadv_icmp_packet_rr))
374 hdr_size = sizeof(struct batadv_icmp_packet_rr);
375
376 /* drop packet if it has not necessary minimum size */ 391 /* drop packet if it has not necessary minimum size */
377 if (unlikely(!pskb_may_pull(skb, hdr_size))) 392 if (unlikely(!pskb_may_pull(skb, hdr_size)))
378 goto out; 393 goto out;
@@ -391,28 +406,39 @@ int batadv_recv_icmp_packet(struct sk_buff *skb,
391 if (!batadv_is_my_mac(bat_priv, ethhdr->h_dest)) 406 if (!batadv_is_my_mac(bat_priv, ethhdr->h_dest))
392 goto out; 407 goto out;
393 408
394 icmp_packet = (struct batadv_icmp_packet_rr *)skb->data; 409 icmph = (struct batadv_icmp_header *)skb->data;
395 410
396 /* add record route information if not full */ 411 /* add record route information if not full */
397 if ((icmp_packet->icmph.msg_type == BATADV_ECHO_REPLY || 412 if ((icmph->msg_type == BATADV_ECHO_REPLY ||
398 icmp_packet->icmph.msg_type == BATADV_ECHO_REQUEST) && 413 icmph->msg_type == BATADV_ECHO_REQUEST) &&
399 (hdr_size == sizeof(struct batadv_icmp_packet_rr)) && 414 (skb->len >= sizeof(struct batadv_icmp_packet_rr))) {
400 (icmp_packet->rr_cur < BATADV_RR_LEN)) { 415 if (skb_linearize(skb) < 0)
401 memcpy(&(icmp_packet->rr[icmp_packet->rr_cur]), 416 goto out;
417
418 /* create a copy of the skb, if needed, to modify it. */
419 if (skb_cow(skb, ETH_HLEN) < 0)
420 goto out;
421
422 icmph = (struct batadv_icmp_header *)skb->data;
423 icmp_packet_rr = (struct batadv_icmp_packet_rr *)icmph;
424 if (icmp_packet_rr->rr_cur >= BATADV_RR_LEN)
425 goto out;
426
427 memcpy(&(icmp_packet_rr->rr[icmp_packet_rr->rr_cur]),
402 ethhdr->h_dest, ETH_ALEN); 428 ethhdr->h_dest, ETH_ALEN);
403 icmp_packet->rr_cur++; 429 icmp_packet_rr->rr_cur++;
404 } 430 }
405 431
406 /* packet for me */ 432 /* packet for me */
407 if (batadv_is_my_mac(bat_priv, icmp_packet->icmph.dst)) 433 if (batadv_is_my_mac(bat_priv, icmph->dst))
408 return batadv_recv_my_icmp_packet(bat_priv, skb, hdr_size); 434 return batadv_recv_my_icmp_packet(bat_priv, skb);
409 435
410 /* TTL exceeded */ 436 /* TTL exceeded */
411 if (icmp_packet->icmph.header.ttl < 2) 437 if (icmph->header.ttl < 2)
412 return batadv_recv_icmp_ttl_exceeded(bat_priv, skb); 438 return batadv_recv_icmp_ttl_exceeded(bat_priv, skb);
413 439
414 /* get routing information */ 440 /* get routing information */
415 orig_node = batadv_orig_hash_find(bat_priv, icmp_packet->icmph.dst); 441 orig_node = batadv_orig_hash_find(bat_priv, icmph->dst);
416 if (!orig_node) 442 if (!orig_node)
417 goto out; 443 goto out;
418 444
@@ -420,10 +446,10 @@ int batadv_recv_icmp_packet(struct sk_buff *skb,
420 if (skb_cow(skb, ETH_HLEN) < 0) 446 if (skb_cow(skb, ETH_HLEN) < 0)
421 goto out; 447 goto out;
422 448
423 icmp_packet = (struct batadv_icmp_packet_rr *)skb->data; 449 icmph = (struct batadv_icmp_header *)skb->data;
424 450
425 /* decrement ttl */ 451 /* decrement ttl */
426 icmp_packet->icmph.header.ttl--; 452 icmph->header.ttl--;
427 453
428 /* route it */ 454 /* route it */
429 if (batadv_send_skb_to_orig(skb, orig_node, recv_if) != NET_XMIT_DROP) 455 if (batadv_send_skb_to_orig(skb, orig_node, recv_if) != NET_XMIT_DROP)
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index 3c2116274de2..91dd369b0ff2 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -749,7 +749,7 @@ struct batadv_socket_client {
749struct batadv_socket_packet { 749struct batadv_socket_packet {
750 struct list_head list; 750 struct list_head list;
751 size_t icmp_len; 751 size_t icmp_len;
752 struct batadv_icmp_packet_rr icmp_packet; 752 uint8_t icmp_packet[BATADV_ICMP_MAX_PACKET_SIZE];
753}; 753};
754 754
755/** 755/**