batman-adv: create common header for ICMP packets
authorAntonio Quartulli <antonio@open-mesh.com>
Sat, 18 May 2013 12:56:57 +0000 (14:56 +0200)
committerAntonio Quartulli <antonio@meshcoding.com>
Sat, 12 Oct 2013 15:17:09 +0000 (17:17 +0200)
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>
net/batman-adv/icmp_socket.c
net/batman-adv/main.c
net/batman-adv/packet.h
net/batman-adv/routing.c

index 5a99bb4b6b823c8d2b042aec32cb2ff70ee3a8b9..82ac6472fa6f57107b536a5037835406dd470e7d 100644 (file)
@@ -192,25 +192,25 @@ static ssize_t batadv_socket_write(struct file *file, const char __user *buff,
                goto free_skb;
        }
 
-       if (icmp_packet->header.packet_type != BATADV_ICMP) {
+       if (icmp_packet->icmph.header.packet_type != BATADV_ICMP) {
                batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
                           "Error - can't send packet from char device: got bogus packet type (expected: BAT_ICMP)\n");
                len = -EINVAL;
                goto free_skb;
        }
 
-       if (icmp_packet->msg_type != BATADV_ECHO_REQUEST) {
+       if (icmp_packet->icmph.msg_type != BATADV_ECHO_REQUEST) {
                batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
                           "Error - can't send packet from char device: got bogus message type (expected: ECHO_REQUEST)\n");
                len = -EINVAL;
                goto free_skb;
        }
 
-       icmp_packet->uid = socket_client->index;
+       icmp_packet->icmph.uid = socket_client->index;
 
-       if (icmp_packet->header.version != BATADV_COMPAT_VERSION) {
-               icmp_packet->msg_type = BATADV_PARAMETER_PROBLEM;
-               icmp_packet->header.version = BATADV_COMPAT_VERSION;
+       if (icmp_packet->icmph.header.version != BATADV_COMPAT_VERSION) {
+               icmp_packet->icmph.msg_type = BATADV_PARAMETER_PROBLEM;
+               icmp_packet->icmph.header.version = BATADV_COMPAT_VERSION;
                batadv_socket_add_packet(socket_client, icmp_packet,
                                         packet_len);
                goto free_skb;
@@ -219,7 +219,7 @@ static ssize_t batadv_socket_write(struct file *file, const char __user *buff,
        if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE)
                goto dst_unreach;
 
-       orig_node = batadv_orig_hash_find(bat_priv, icmp_packet->dst);
+       orig_node = batadv_orig_hash_find(bat_priv, icmp_packet->icmph.dst);
        if (!orig_node)
                goto dst_unreach;
 
@@ -233,7 +233,7 @@ static ssize_t batadv_socket_write(struct file *file, const char __user *buff,
        if (neigh_node->if_incoming->if_status != BATADV_IF_ACTIVE)
                goto dst_unreach;
 
-       memcpy(icmp_packet->orig,
+       memcpy(icmp_packet->icmph.orig,
               primary_if->net_dev->dev_addr, ETH_ALEN);
 
        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,
        goto out;
 
 dst_unreach:
-       icmp_packet->msg_type = BATADV_DESTINATION_UNREACHABLE;
+       icmp_packet->icmph.msg_type = BATADV_DESTINATION_UNREACHABLE;
        batadv_socket_add_packet(socket_client, icmp_packet, packet_len);
 free_skb:
        kfree_skb(skb);
@@ -318,7 +318,7 @@ static void batadv_socket_add_packet(struct batadv_socket_client *socket_client,
        /* while waiting for the lock the socket_client could have been
         * deleted
         */
-       if (!batadv_socket_client_hash[icmp_packet->uid]) {
+       if (!batadv_socket_client_hash[icmp_packet->icmph.uid]) {
                spin_unlock_bh(&socket_client->lock);
                kfree(socket_packet);
                return;
@@ -347,7 +347,7 @@ void batadv_socket_receive_packet(struct batadv_icmp_packet_rr *icmp_packet,
 {
        struct batadv_socket_client *hash;
 
-       hash = batadv_socket_client_hash[icmp_packet->uid];
+       hash = batadv_socket_client_hash[icmp_packet->icmph.uid];
        if (hash)
                batadv_socket_add_packet(hash, icmp_packet, icmp_len);
 }
index ca6f1340d70c1c2ee1874a1a7d10cadc064ac5b7..519138e32fe6157ab214e5568b1e01cec14a6942 100644 (file)
@@ -401,8 +401,8 @@ static void batadv_recv_handler_init(void)
        BUILD_BUG_ON(offsetof(struct batadv_unicast_packet, dest) != 4);
        BUILD_BUG_ON(offsetof(struct batadv_unicast_tvlv_packet, dst) != 4);
        BUILD_BUG_ON(offsetof(struct batadv_frag_packet, dest) != 4);
-       BUILD_BUG_ON(offsetof(struct batadv_icmp_packet, dst) != 4);
-       BUILD_BUG_ON(offsetof(struct batadv_icmp_packet_rr, dst) != 4);
+       BUILD_BUG_ON(offsetof(struct batadv_icmp_packet, icmph.dst) != 4);
+       BUILD_BUG_ON(offsetof(struct batadv_icmp_packet_rr, icmph.dst) != 4);
 
        /* broadcast packet */
        batadv_rx_handler[BATADV_BCAST] = batadv_recv_bcast_packet;
index aa46c2778ad89004e5a3e4c0bc3851b115ae2c7d..65e723ed030b0b2aab0bde9905b76854c68f9a6d 100644 (file)
@@ -186,29 +186,47 @@ struct batadv_ogm_packet {
 
 #define BATADV_OGM_HLEN sizeof(struct batadv_ogm_packet)
 
-struct batadv_icmp_packet {
+/**
+ * batadv_icmp_header - common ICMP header
+ * @header: common batman header
+ * @msg_type: ICMP packet type
+ * @dst: address of the destination node
+ * @orig: address of the source node
+ * @uid: local ICMP socket identifier
+ */
+struct batadv_icmp_header {
        struct batadv_header header;
        uint8_t  msg_type; /* see ICMP message types above */
        uint8_t  dst[ETH_ALEN];
        uint8_t  orig[ETH_ALEN];
-       __be16   seqno;
        uint8_t  uid;
+};
+
+/**
+ * batadv_icmp_packet - ICMP packet
+ * @icmph: common ICMP header
+ * @reserved: not used - useful for alignment
+ * @seqno: ICMP sequence number
+ */
+struct batadv_icmp_packet {
+       struct batadv_icmp_header icmph;
        uint8_t  reserved;
+       __be16   seqno;
 };
 
 #define BATADV_RR_LEN 16
 
-/* icmp_packet_rr must start with all fields from imcp_packet
- * as this is assumed by code that handles ICMP packets
+/**
+ * batadv_icmp_packet_rr - ICMP RouteRecord packet
+ * @icmph: common ICMP header
+ * @rr_cur: number of entries the rr array
+ * @seqno: ICMP sequence number
+ * @rr: route record array
  */
 struct batadv_icmp_packet_rr {
-       struct batadv_header header;
-       uint8_t  msg_type; /* see ICMP message types above */
-       uint8_t  dst[ETH_ALEN];
-       uint8_t  orig[ETH_ALEN];
-       __be16   seqno;
-       uint8_t  uid;
+       struct batadv_icmp_header icmph;
        uint8_t  rr_cur;
+       __be16   seqno;
        uint8_t  rr[BATADV_RR_LEN][ETH_ALEN];
 };
 
index a080f63b3ef6373937739cf143c4f1955168fe03..3281a504c20aa68d89dd9ceb064a02584f143cd5 100644 (file)
@@ -258,7 +258,7 @@ static int batadv_recv_my_icmp_packet(struct batadv_priv *bat_priv,
        icmp_packet = (struct batadv_icmp_packet_rr *)skb->data;
 
        /* add data to device queue */
-       if (icmp_packet->msg_type != BATADV_ECHO_REQUEST) {
+       if (icmp_packet->icmph.msg_type != BATADV_ECHO_REQUEST) {
                batadv_socket_receive_packet(icmp_packet, icmp_len);
                goto out;
        }
@@ -269,7 +269,7 @@ static int batadv_recv_my_icmp_packet(struct batadv_priv *bat_priv,
 
        /* answer echo request (ping) */
        /* get routing information */
-       orig_node = batadv_orig_hash_find(bat_priv, icmp_packet->orig);
+       orig_node = batadv_orig_hash_find(bat_priv, icmp_packet->icmph.orig);
        if (!orig_node)
                goto out;
 
@@ -279,10 +279,11 @@ static int batadv_recv_my_icmp_packet(struct batadv_priv *bat_priv,
 
        icmp_packet = (struct batadv_icmp_packet_rr *)skb->data;
 
-       memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
-       memcpy(icmp_packet->orig, primary_if->net_dev->dev_addr, ETH_ALEN);
-       icmp_packet->msg_type = BATADV_ECHO_REPLY;
-       icmp_packet->header.ttl = BATADV_TTL;
+       memcpy(icmp_packet->icmph.dst, icmp_packet->icmph.orig, ETH_ALEN);
+       memcpy(icmp_packet->icmph.orig, primary_if->net_dev->dev_addr,
+              ETH_ALEN);
+       icmp_packet->icmph.msg_type = BATADV_ECHO_REPLY;
+       icmp_packet->icmph.header.ttl = BATADV_TTL;
 
        if (batadv_send_skb_to_orig(skb, orig_node, NULL) != NET_XMIT_DROP)
                ret = NET_RX_SUCCESS;
@@ -306,9 +307,9 @@ static int batadv_recv_icmp_ttl_exceeded(struct batadv_priv *bat_priv,
        icmp_packet = (struct batadv_icmp_packet *)skb->data;
 
        /* send TTL exceeded if packet is an echo request (traceroute) */
-       if (icmp_packet->msg_type != BATADV_ECHO_REQUEST) {
+       if (icmp_packet->icmph.msg_type != BATADV_ECHO_REQUEST) {
                pr_debug("Warning - can't forward icmp packet from %pM to %pM: ttl exceeded\n",
-                        icmp_packet->orig, icmp_packet->dst);
+                        icmp_packet->icmph.orig, icmp_packet->icmph.dst);
                goto out;
        }
 
@@ -317,7 +318,7 @@ static int batadv_recv_icmp_ttl_exceeded(struct batadv_priv *bat_priv,
                goto out;
 
        /* get routing information */
-       orig_node = batadv_orig_hash_find(bat_priv, icmp_packet->orig);
+       orig_node = batadv_orig_hash_find(bat_priv, icmp_packet->icmph.orig);
        if (!orig_node)
                goto out;
 
@@ -327,10 +328,11 @@ static int batadv_recv_icmp_ttl_exceeded(struct batadv_priv *bat_priv,
 
        icmp_packet = (struct batadv_icmp_packet *)skb->data;
 
-       memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
-       memcpy(icmp_packet->orig, primary_if->net_dev->dev_addr, ETH_ALEN);
-       icmp_packet->msg_type = BATADV_TTL_EXCEEDED;
-       icmp_packet->header.ttl = BATADV_TTL;
+       memcpy(icmp_packet->icmph.dst, icmp_packet->icmph.orig, ETH_ALEN);
+       memcpy(icmp_packet->icmph.orig, primary_if->net_dev->dev_addr,
+              ETH_ALEN);
+       icmp_packet->icmph.msg_type = BATADV_TTL_EXCEEDED;
+       icmp_packet->icmph.header.ttl = BATADV_TTL;
 
        if (batadv_send_skb_to_orig(skb, orig_node, NULL) != NET_XMIT_DROP)
                ret = NET_RX_SUCCESS;
@@ -379,8 +381,8 @@ int batadv_recv_icmp_packet(struct sk_buff *skb,
        icmp_packet = (struct batadv_icmp_packet_rr *)skb->data;
 
        /* add record route information if not full */
-       if ((icmp_packet->msg_type == BATADV_ECHO_REPLY ||
-            icmp_packet->msg_type == BATADV_ECHO_REQUEST) &&
+       if ((icmp_packet->icmph.msg_type == BATADV_ECHO_REPLY ||
+            icmp_packet->icmph.msg_type == BATADV_ECHO_REQUEST) &&
            (hdr_size == sizeof(struct batadv_icmp_packet_rr)) &&
            (icmp_packet->rr_cur < BATADV_RR_LEN)) {
                memcpy(&(icmp_packet->rr[icmp_packet->rr_cur]),
@@ -389,15 +391,15 @@ int batadv_recv_icmp_packet(struct sk_buff *skb,
        }
 
        /* packet for me */
-       if (batadv_is_my_mac(bat_priv, icmp_packet->dst))
+       if (batadv_is_my_mac(bat_priv, icmp_packet->icmph.dst))
                return batadv_recv_my_icmp_packet(bat_priv, skb, hdr_size);
 
        /* TTL exceeded */
-       if (icmp_packet->header.ttl < 2)
+       if (icmp_packet->icmph.header.ttl < 2)
                return batadv_recv_icmp_ttl_exceeded(bat_priv, skb);
 
        /* get routing information */
-       orig_node = batadv_orig_hash_find(bat_priv, icmp_packet->dst);
+       orig_node = batadv_orig_hash_find(bat_priv, icmp_packet->icmph.dst);
        if (!orig_node)
                goto out;
 
@@ -408,7 +410,7 @@ int batadv_recv_icmp_packet(struct sk_buff *skb,
        icmp_packet = (struct batadv_icmp_packet_rr *)skb->data;
 
        /* decrement ttl */
-       icmp_packet->header.ttl--;
+       icmp_packet->icmph.header.ttl--;
 
        /* route it */
        if (batadv_send_skb_to_orig(skb, orig_node, recv_if) != NET_XMIT_DROP)