aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv
diff options
context:
space:
mode:
authorAntonio Quartulli <antonio@open-mesh.com>2013-05-18 08:56:57 -0400
committerAntonio Quartulli <antonio@meshcoding.com>2013-10-12 11:17:09 -0400
commit0bf84c160a4b3b75bb911b79c3972f64dfb0b039 (patch)
treea9e591fe7314fab7c6554959df2c6340699edc46 /net/batman-adv
parent293e93385e024be71500c9480ef85d6199459d17 (diff)
batman-adv: create common header for ICMP packets
the icmp and the icmp_rr packets share the same initial fields since they use the same code to be processed and forwarded. Extract the common fields and put them into a separate struct so that future ICMP packets can be easily added without bloating the packet definition. However, keep the seqno field outside of the newly created common header because future ICMP types may require a bigger sequence number space. This change breaks compatibility due to fields reordering in the ICMP headers. Signed-off-by: Antonio Quartulli <antonio@open-mesh.com> Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
Diffstat (limited to 'net/batman-adv')
-rw-r--r--net/batman-adv/icmp_socket.c22
-rw-r--r--net/batman-adv/main.c4
-rw-r--r--net/batman-adv/packet.h38
-rw-r--r--net/batman-adv/routing.c40
4 files changed, 62 insertions, 42 deletions
diff --git a/net/batman-adv/icmp_socket.c b/net/batman-adv/icmp_socket.c
index 5a99bb4b6b82..82ac6472fa6f 100644
--- a/net/batman-adv/icmp_socket.c
+++ b/net/batman-adv/icmp_socket.c
@@ -192,25 +192,25 @@ static ssize_t batadv_socket_write(struct file *file, const char __user *buff,
192 goto free_skb; 192 goto free_skb;
193 } 193 }
194 194
195 if (icmp_packet->header.packet_type != BATADV_ICMP) { 195 if (icmp_packet->icmph.header.packet_type != BATADV_ICMP) {
196 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 196 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
197 "Error - can't send packet from char device: got bogus packet type (expected: BAT_ICMP)\n"); 197 "Error - can't send packet from char device: got bogus packet type (expected: BAT_ICMP)\n");
198 len = -EINVAL; 198 len = -EINVAL;
199 goto free_skb; 199 goto free_skb;
200 } 200 }
201 201
202 if (icmp_packet->msg_type != BATADV_ECHO_REQUEST) { 202 if (icmp_packet->icmph.msg_type != BATADV_ECHO_REQUEST) {
203 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 203 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
204 "Error - can't send packet from char device: got bogus message type (expected: ECHO_REQUEST)\n"); 204 "Error - can't send packet from char device: got bogus message type (expected: ECHO_REQUEST)\n");
205 len = -EINVAL; 205 len = -EINVAL;
206 goto free_skb; 206 goto free_skb;
207 } 207 }
208 208
209 icmp_packet->uid = socket_client->index; 209 icmp_packet->icmph.uid = socket_client->index;
210 210
211 if (icmp_packet->header.version != BATADV_COMPAT_VERSION) { 211 if (icmp_packet->icmph.header.version != BATADV_COMPAT_VERSION) {
212 icmp_packet->msg_type = BATADV_PARAMETER_PROBLEM; 212 icmp_packet->icmph.msg_type = BATADV_PARAMETER_PROBLEM;
213 icmp_packet->header.version = BATADV_COMPAT_VERSION; 213 icmp_packet->icmph.header.version = BATADV_COMPAT_VERSION;
214 batadv_socket_add_packet(socket_client, icmp_packet, 214 batadv_socket_add_packet(socket_client, icmp_packet,
215 packet_len); 215 packet_len);
216 goto free_skb; 216 goto free_skb;
@@ -219,7 +219,7 @@ static ssize_t batadv_socket_write(struct file *file, const char __user *buff,
219 if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE) 219 if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE)
220 goto dst_unreach; 220 goto dst_unreach;
221 221
222 orig_node = batadv_orig_hash_find(bat_priv, icmp_packet->dst); 222 orig_node = batadv_orig_hash_find(bat_priv, icmp_packet->icmph.dst);
223 if (!orig_node) 223 if (!orig_node)
224 goto dst_unreach; 224 goto dst_unreach;
225 225
@@ -233,7 +233,7 @@ static ssize_t batadv_socket_write(struct file *file, const char __user *buff,
233 if (neigh_node->if_incoming->if_status != BATADV_IF_ACTIVE) 233 if (neigh_node->if_incoming->if_status != BATADV_IF_ACTIVE)
234 goto dst_unreach; 234 goto dst_unreach;
235 235
236 memcpy(icmp_packet->orig, 236 memcpy(icmp_packet->icmph.orig,
237 primary_if->net_dev->dev_addr, ETH_ALEN); 237 primary_if->net_dev->dev_addr, ETH_ALEN);
238 238
239 if (packet_len == sizeof(struct batadv_icmp_packet_rr)) 239 if (packet_len == sizeof(struct batadv_icmp_packet_rr))
@@ -244,7 +244,7 @@ static ssize_t batadv_socket_write(struct file *file, const char __user *buff,
244 goto out; 244 goto out;
245 245
246dst_unreach: 246dst_unreach:
247 icmp_packet->msg_type = BATADV_DESTINATION_UNREACHABLE; 247 icmp_packet->icmph.msg_type = BATADV_DESTINATION_UNREACHABLE;
248 batadv_socket_add_packet(socket_client, icmp_packet, packet_len); 248 batadv_socket_add_packet(socket_client, icmp_packet, packet_len);
249free_skb: 249free_skb:
250 kfree_skb(skb); 250 kfree_skb(skb);
@@ -318,7 +318,7 @@ static void batadv_socket_add_packet(struct batadv_socket_client *socket_client,
318 /* while waiting for the lock the socket_client could have been 318 /* while waiting for the lock the socket_client could have been
319 * deleted 319 * deleted
320 */ 320 */
321 if (!batadv_socket_client_hash[icmp_packet->uid]) { 321 if (!batadv_socket_client_hash[icmp_packet->icmph.uid]) {
322 spin_unlock_bh(&socket_client->lock); 322 spin_unlock_bh(&socket_client->lock);
323 kfree(socket_packet); 323 kfree(socket_packet);
324 return; 324 return;
@@ -347,7 +347,7 @@ void batadv_socket_receive_packet(struct batadv_icmp_packet_rr *icmp_packet,
347{ 347{
348 struct batadv_socket_client *hash; 348 struct batadv_socket_client *hash;
349 349
350 hash = batadv_socket_client_hash[icmp_packet->uid]; 350 hash = batadv_socket_client_hash[icmp_packet->icmph.uid];
351 if (hash) 351 if (hash)
352 batadv_socket_add_packet(hash, icmp_packet, icmp_len); 352 batadv_socket_add_packet(hash, icmp_packet, icmp_len);
353} 353}
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c
index ca6f1340d70c..519138e32fe6 100644
--- a/net/batman-adv/main.c
+++ b/net/batman-adv/main.c
@@ -401,8 +401,8 @@ static void batadv_recv_handler_init(void)
401 BUILD_BUG_ON(offsetof(struct batadv_unicast_packet, dest) != 4); 401 BUILD_BUG_ON(offsetof(struct batadv_unicast_packet, dest) != 4);
402 BUILD_BUG_ON(offsetof(struct batadv_unicast_tvlv_packet, dst) != 4); 402 BUILD_BUG_ON(offsetof(struct batadv_unicast_tvlv_packet, dst) != 4);
403 BUILD_BUG_ON(offsetof(struct batadv_frag_packet, dest) != 4); 403 BUILD_BUG_ON(offsetof(struct batadv_frag_packet, dest) != 4);
404 BUILD_BUG_ON(offsetof(struct batadv_icmp_packet, dst) != 4); 404 BUILD_BUG_ON(offsetof(struct batadv_icmp_packet, icmph.dst) != 4);
405 BUILD_BUG_ON(offsetof(struct batadv_icmp_packet_rr, dst) != 4); 405 BUILD_BUG_ON(offsetof(struct batadv_icmp_packet_rr, icmph.dst) != 4);
406 406
407 /* broadcast packet */ 407 /* broadcast packet */
408 batadv_rx_handler[BATADV_BCAST] = batadv_recv_bcast_packet; 408 batadv_rx_handler[BATADV_BCAST] = batadv_recv_bcast_packet;
diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h
index aa46c2778ad8..65e723ed030b 100644
--- a/net/batman-adv/packet.h
+++ b/net/batman-adv/packet.h
@@ -186,29 +186,47 @@ struct batadv_ogm_packet {
186 186
187#define BATADV_OGM_HLEN sizeof(struct batadv_ogm_packet) 187#define BATADV_OGM_HLEN sizeof(struct batadv_ogm_packet)
188 188
189struct batadv_icmp_packet { 189/**
190 * batadv_icmp_header - common ICMP header
191 * @header: common batman header
192 * @msg_type: ICMP packet type
193 * @dst: address of the destination node
194 * @orig: address of the source node
195 * @uid: local ICMP socket identifier
196 */
197struct batadv_icmp_header {
190 struct batadv_header header; 198 struct batadv_header header;
191 uint8_t msg_type; /* see ICMP message types above */ 199 uint8_t msg_type; /* see ICMP message types above */
192 uint8_t dst[ETH_ALEN]; 200 uint8_t dst[ETH_ALEN];
193 uint8_t orig[ETH_ALEN]; 201 uint8_t orig[ETH_ALEN];
194 __be16 seqno;
195 uint8_t uid; 202 uint8_t uid;
203};
204
205/**
206 * batadv_icmp_packet - ICMP packet
207 * @icmph: common ICMP header
208 * @reserved: not used - useful for alignment
209 * @seqno: ICMP sequence number
210 */
211struct batadv_icmp_packet {
212 struct batadv_icmp_header icmph;
196 uint8_t reserved; 213 uint8_t reserved;
214 __be16 seqno;
197}; 215};
198 216
199#define BATADV_RR_LEN 16 217#define BATADV_RR_LEN 16
200 218
201/* icmp_packet_rr must start with all fields from imcp_packet 219/**
202 * as this is assumed by code that handles ICMP packets 220 * batadv_icmp_packet_rr - ICMP RouteRecord packet
221 * @icmph: common ICMP header
222 * @rr_cur: number of entries the rr array
223 * @seqno: ICMP sequence number
224 * @rr: route record array
203 */ 225 */
204struct batadv_icmp_packet_rr { 226struct batadv_icmp_packet_rr {
205 struct batadv_header header; 227 struct batadv_icmp_header icmph;
206 uint8_t msg_type; /* see ICMP message types above */
207 uint8_t dst[ETH_ALEN];
208 uint8_t orig[ETH_ALEN];
209 __be16 seqno;
210 uint8_t uid;
211 uint8_t rr_cur; 228 uint8_t rr_cur;
229 __be16 seqno;
212 uint8_t rr[BATADV_RR_LEN][ETH_ALEN]; 230 uint8_t rr[BATADV_RR_LEN][ETH_ALEN];
213}; 231};
214 232
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index a080f63b3ef6..3281a504c20a 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -258,7 +258,7 @@ static int batadv_recv_my_icmp_packet(struct batadv_priv *bat_priv,
258 icmp_packet = (struct batadv_icmp_packet_rr *)skb->data; 258 icmp_packet = (struct batadv_icmp_packet_rr *)skb->data;
259 259
260 /* add data to device queue */ 260 /* add data to device queue */
261 if (icmp_packet->msg_type != BATADV_ECHO_REQUEST) { 261 if (icmp_packet->icmph.msg_type != BATADV_ECHO_REQUEST) {
262 batadv_socket_receive_packet(icmp_packet, icmp_len); 262 batadv_socket_receive_packet(icmp_packet, icmp_len);
263 goto out; 263 goto out;
264 } 264 }
@@ -269,7 +269,7 @@ static int batadv_recv_my_icmp_packet(struct batadv_priv *bat_priv,
269 269
270 /* answer echo request (ping) */ 270 /* answer echo request (ping) */
271 /* get routing information */ 271 /* get routing information */
272 orig_node = batadv_orig_hash_find(bat_priv, icmp_packet->orig); 272 orig_node = batadv_orig_hash_find(bat_priv, icmp_packet->icmph.orig);
273 if (!orig_node) 273 if (!orig_node)
274 goto out; 274 goto out;
275 275
@@ -279,10 +279,11 @@ static int batadv_recv_my_icmp_packet(struct batadv_priv *bat_priv,
279 279
280 icmp_packet = (struct batadv_icmp_packet_rr *)skb->data; 280 icmp_packet = (struct batadv_icmp_packet_rr *)skb->data;
281 281
282 memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN); 282 memcpy(icmp_packet->icmph.dst, icmp_packet->icmph.orig, ETH_ALEN);
283 memcpy(icmp_packet->orig, primary_if->net_dev->dev_addr, ETH_ALEN); 283 memcpy(icmp_packet->icmph.orig, primary_if->net_dev->dev_addr,
284 icmp_packet->msg_type = BATADV_ECHO_REPLY; 284 ETH_ALEN);
285 icmp_packet->header.ttl = BATADV_TTL; 285 icmp_packet->icmph.msg_type = BATADV_ECHO_REPLY;
286 icmp_packet->icmph.header.ttl = BATADV_TTL;
286 287
287 if (batadv_send_skb_to_orig(skb, orig_node, NULL) != NET_XMIT_DROP) 288 if (batadv_send_skb_to_orig(skb, orig_node, NULL) != NET_XMIT_DROP)
288 ret = NET_RX_SUCCESS; 289 ret = NET_RX_SUCCESS;
@@ -306,9 +307,9 @@ static int batadv_recv_icmp_ttl_exceeded(struct batadv_priv *bat_priv,
306 icmp_packet = (struct batadv_icmp_packet *)skb->data; 307 icmp_packet = (struct batadv_icmp_packet *)skb->data;
307 308
308 /* send TTL exceeded if packet is an echo request (traceroute) */ 309 /* send TTL exceeded if packet is an echo request (traceroute) */
309 if (icmp_packet->msg_type != BATADV_ECHO_REQUEST) { 310 if (icmp_packet->icmph.msg_type != BATADV_ECHO_REQUEST) {
310 pr_debug("Warning - can't forward icmp packet from %pM to %pM: ttl exceeded\n", 311 pr_debug("Warning - can't forward icmp packet from %pM to %pM: ttl exceeded\n",
311 icmp_packet->orig, icmp_packet->dst); 312 icmp_packet->icmph.orig, icmp_packet->icmph.dst);
312 goto out; 313 goto out;
313 } 314 }
314 315
@@ -317,7 +318,7 @@ static int batadv_recv_icmp_ttl_exceeded(struct batadv_priv *bat_priv,
317 goto out; 318 goto out;
318 319
319 /* get routing information */ 320 /* get routing information */
320 orig_node = batadv_orig_hash_find(bat_priv, icmp_packet->orig); 321 orig_node = batadv_orig_hash_find(bat_priv, icmp_packet->icmph.orig);
321 if (!orig_node) 322 if (!orig_node)
322 goto out; 323 goto out;
323 324
@@ -327,10 +328,11 @@ static int batadv_recv_icmp_ttl_exceeded(struct batadv_priv *bat_priv,
327 328
328 icmp_packet = (struct batadv_icmp_packet *)skb->data; 329 icmp_packet = (struct batadv_icmp_packet *)skb->data;
329 330
330 memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN); 331 memcpy(icmp_packet->icmph.dst, icmp_packet->icmph.orig, ETH_ALEN);
331 memcpy(icmp_packet->orig, primary_if->net_dev->dev_addr, ETH_ALEN); 332 memcpy(icmp_packet->icmph.orig, primary_if->net_dev->dev_addr,
332 icmp_packet->msg_type = BATADV_TTL_EXCEEDED; 333 ETH_ALEN);
333 icmp_packet->header.ttl = BATADV_TTL; 334 icmp_packet->icmph.msg_type = BATADV_TTL_EXCEEDED;
335 icmp_packet->icmph.header.ttl = BATADV_TTL;
334 336
335 if (batadv_send_skb_to_orig(skb, orig_node, NULL) != NET_XMIT_DROP) 337 if (batadv_send_skb_to_orig(skb, orig_node, NULL) != NET_XMIT_DROP)
336 ret = NET_RX_SUCCESS; 338 ret = NET_RX_SUCCESS;
@@ -379,8 +381,8 @@ int batadv_recv_icmp_packet(struct sk_buff *skb,
379 icmp_packet = (struct batadv_icmp_packet_rr *)skb->data; 381 icmp_packet = (struct batadv_icmp_packet_rr *)skb->data;
380 382
381 /* add record route information if not full */ 383 /* add record route information if not full */
382 if ((icmp_packet->msg_type == BATADV_ECHO_REPLY || 384 if ((icmp_packet->icmph.msg_type == BATADV_ECHO_REPLY ||
383 icmp_packet->msg_type == BATADV_ECHO_REQUEST) && 385 icmp_packet->icmph.msg_type == BATADV_ECHO_REQUEST) &&
384 (hdr_size == sizeof(struct batadv_icmp_packet_rr)) && 386 (hdr_size == sizeof(struct batadv_icmp_packet_rr)) &&
385 (icmp_packet->rr_cur < BATADV_RR_LEN)) { 387 (icmp_packet->rr_cur < BATADV_RR_LEN)) {
386 memcpy(&(icmp_packet->rr[icmp_packet->rr_cur]), 388 memcpy(&(icmp_packet->rr[icmp_packet->rr_cur]),
@@ -389,15 +391,15 @@ int batadv_recv_icmp_packet(struct sk_buff *skb,
389 } 391 }
390 392
391 /* packet for me */ 393 /* packet for me */
392 if (batadv_is_my_mac(bat_priv, icmp_packet->dst)) 394 if (batadv_is_my_mac(bat_priv, icmp_packet->icmph.dst))
393 return batadv_recv_my_icmp_packet(bat_priv, skb, hdr_size); 395 return batadv_recv_my_icmp_packet(bat_priv, skb, hdr_size);
394 396
395 /* TTL exceeded */ 397 /* TTL exceeded */
396 if (icmp_packet->header.ttl < 2) 398 if (icmp_packet->icmph.header.ttl < 2)
397 return batadv_recv_icmp_ttl_exceeded(bat_priv, skb); 399 return batadv_recv_icmp_ttl_exceeded(bat_priv, skb);
398 400
399 /* get routing information */ 401 /* get routing information */
400 orig_node = batadv_orig_hash_find(bat_priv, icmp_packet->dst); 402 orig_node = batadv_orig_hash_find(bat_priv, icmp_packet->icmph.dst);
401 if (!orig_node) 403 if (!orig_node)
402 goto out; 404 goto out;
403 405
@@ -408,7 +410,7 @@ int batadv_recv_icmp_packet(struct sk_buff *skb,
408 icmp_packet = (struct batadv_icmp_packet_rr *)skb->data; 410 icmp_packet = (struct batadv_icmp_packet_rr *)skb->data;
409 411
410 /* decrement ttl */ 412 /* decrement ttl */
411 icmp_packet->header.ttl--; 413 icmp_packet->icmph.header.ttl--;
412 414
413 /* route it */ 415 /* route it */
414 if (batadv_send_skb_to_orig(skb, orig_node, recv_if) != NET_XMIT_DROP) 416 if (batadv_send_skb_to_orig(skb, orig_node, recv_if) != NET_XMIT_DROP)