Repository : ssh://git@open-mesh.org/batctl
On branch : next
commit 27aa24cad4c90f9399962bb63fbb8c9dce74b417 Author: Simon Wunderlich sw@simonwunderlich.de Date: Mon Dec 2 20:38:31 2013 +0100
batctl: fix header alignment by unrolling batadv_header
The size of the batadv_header of 3 is problematic on some architectures which automatically pad all structures to a 32 bit boundary. To not lose performance by packing this struct, better embed it into the various host structures.
Reported-by: Russell King linux@arm.linux.org.uk Signed-off-by: Simon Wunderlich sw@simonwunderlich.de Signed-off-by: Marek Lindner mareklindner@neomailbox.ch
27aa24cad4c90f9399962bb63fbb8c9dce74b417 packet.h | 74 +++++++++++++++++++++++++++++++++++++++++----------------- ping.c | 11 ++++----- tcpdump.c | 24 +++++++++---------- traceroute.c | 17 +++++++------- 4 files changed, 78 insertions(+), 48 deletions(-)
diff --git a/packet.h b/packet.h index 10597a6..175ce7d 100644 --- a/packet.h +++ b/packet.h @@ -164,23 +164,18 @@ struct batadv_bla_claim_dst { __be16 group; /* group id */ };
-struct batadv_header { - uint8_t packet_type; - uint8_t version; /* batman version field */ - uint8_t ttl; - /* the parent struct has to add a byte after the header to make - * everything 4 bytes aligned again - */ -}; - /** * struct batadv_ogm_packet - ogm (routing protocol) packet - * @header: common batman packet header + * @packet_type: batman-adv packet type, part of the general header + * @version: batman-adv protocol version, part of the genereal header + * @ttl: time to live for this packet, part of the genereal header * @flags: contains routing relevant flags - see enum batadv_iv_flags * @tvlv_len: length of tvlv data following the ogm header */ struct batadv_ogm_packet { - struct batadv_header header; + uint8_t packet_type; + uint8_t version; + uint8_t ttl; uint8_t flags; __be32 seqno; uint8_t orig[ETH_ALEN]; @@ -197,14 +192,18 @@ struct batadv_ogm_packet {
/** * batadv_icmp_header - common ICMP header - * @header: common batman header + * @packet_type: batman-adv packet type, part of the general header + * @version: batman-adv protocol version, part of the genereal header + * @ttl: time to live for this packet, part of the genereal 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 packet_type; + uint8_t version; + uint8_t ttl; uint8_t msg_type; /* see ICMP message types above */ uint8_t dst[ETH_ALEN]; uint8_t orig[ETH_ALEN]; @@ -253,8 +252,18 @@ struct batadv_icmp_packet_rr { */ #pragma pack(2)
+/** + * struct batadv_unicast_packet - unicast packet for network payload + * @packet_type: batman-adv packet type, part of the general header + * @version: batman-adv protocol version, part of the genereal header + * @ttl: time to live for this packet, part of the genereal header + * @ttvn: translation table version number + * @dest: originator destination of the unicast packet + */ struct batadv_unicast_packet { - struct batadv_header header; + uint8_t packet_type; + uint8_t version; + uint8_t ttl; uint8_t ttvn; /* destination translation table version number */ uint8_t dest[ETH_ALEN]; /* "4 bytes boundary + 2 bytes" long to make the payload after the @@ -280,7 +289,9 @@ struct batadv_unicast_4addr_packet {
/** * struct batadv_frag_packet - fragmented packet - * @header: common batman packet header with type, compatversion, and ttl + * @packet_type: batman-adv packet type, part of the general header + * @version: batman-adv protocol version, part of the genereal header + * @ttl: time to live for this packet, part of the genereal header * @dest: final destination used when routing fragments * @orig: originator of the fragment used when merging the packet * @no: fragment number within this sequence @@ -289,7 +300,9 @@ struct batadv_unicast_4addr_packet { * @total_size: size of the merged packet */ struct batadv_frag_packet { - struct batadv_header header; + uint8_t packet_type; + uint8_t version; /* batman version field */ + uint8_t ttl; #if defined(__BIG_ENDIAN_BITFIELD) uint8_t no:4; uint8_t reserved:4; @@ -305,8 +318,19 @@ struct batadv_frag_packet { __be16 total_size; };
+/** + * struct batadv_bcast_packet - broadcast packet for network payload + * @packet_type: batman-adv packet type, part of the general header + * @version: batman-adv protocol version, part of the genereal header + * @ttl: time to live for this packet, part of the genereal header + * @reserved: reserved byte for alignment + * @seqno: sequence identification + * @orig: originator of the broadcast packet + */ struct batadv_bcast_packet { - struct batadv_header header; + uint8_t packet_type; + uint8_t version; /* batman version field */ + uint8_t ttl; uint8_t reserved; __be32 seqno; uint8_t orig[ETH_ALEN]; @@ -317,7 +341,9 @@ struct batadv_bcast_packet {
/** * struct batadv_coded_packet - network coded packet - * @header: common batman packet header and ttl of first included packet + * @packet_type: batman-adv packet type, part of the general header + * @version: batman-adv protocol version, part of the genereal header + * @ttl: time to live for this packet, part of the genereal header * @reserved: Align following fields to 2-byte boundaries * @first_source: original source of first included packet * @first_orig_dest: original destinal of first included packet @@ -332,7 +358,9 @@ struct batadv_bcast_packet { * @coded_len: length of network coded part of the payload */ struct batadv_coded_packet { - struct batadv_header header; + uint8_t packet_type; + uint8_t version; /* batman version field */ + uint8_t ttl; uint8_t first_ttvn; /* uint8_t first_dest[ETH_ALEN]; - saved in mac header destination */ uint8_t first_source[ETH_ALEN]; @@ -351,7 +379,9 @@ struct batadv_coded_packet {
/** * struct batadv_unicast_tvlv - generic unicast packet with tvlv payload - * @header: common batman packet header + * @packet_type: batman-adv packet type, part of the general header + * @version: batman-adv protocol version, part of the genereal header + * @ttl: time to live for this packet, part of the genereal header * @reserved: reserved field (for packet alignment) * @src: address of the source * @dst: address of the destination @@ -359,7 +389,9 @@ struct batadv_coded_packet { * @align: 2 bytes to align the header to a 4 byte boundry */ struct batadv_unicast_tvlv_packet { - struct batadv_header header; + uint8_t packet_type; + uint8_t version; /* batman version field */ + uint8_t ttl; uint8_t reserved; uint8_t dst[ETH_ALEN]; uint8_t src[ETH_ALEN]; diff --git a/ping.c b/ping.c index aad13d9..778e8ae 100644 --- a/ping.c +++ b/ping.c @@ -177,10 +177,10 @@ int ping(char *mesh_iface, int argc, char **argv) packet_len = sizeof(struct batadv_icmp_packet);
memcpy(&icmp_packet_out.icmph.dst, dst_mac, ETH_ALEN); - icmp_packet_out.icmph.header.packet_type = BATADV_ICMP; - icmp_packet_out.icmph.header.version = BATADV_COMPAT_VERSION; + icmp_packet_out.icmph.packet_type = BATADV_ICMP; + icmp_packet_out.icmph.version = BATADV_COMPAT_VERSION; icmp_packet_out.icmph.msg_type = BATADV_ECHO_REQUEST; - icmp_packet_out.icmph.header.ttl = 50; + icmp_packet_out.icmph.ttl = 50; icmp_packet_out.seqno = 0;
if (rr) { @@ -256,7 +256,7 @@ read_packet: printf("%zd bytes from %s icmp_seq=%hu ttl=%d time=%.2f ms", read_len, dst_string, ntohs(icmp_packet_in.seqno), - icmp_packet_in.icmph.header.ttl, + icmp_packet_in.icmph.ttl, time_delta);
if (read_len == sizeof(struct batadv_icmp_packet_rr)) { @@ -306,8 +306,7 @@ read_packet: break; case BATADV_PARAMETER_PROBLEM: fprintf(stderr, "Error - the batman adv kernel module version (%d) differs from ours (%d)\n", - icmp_packet_in.icmph.header.version, - BATADV_COMPAT_VERSION); + icmp_packet_in.icmph.version, BATADV_COMPAT_VERSION); printf("Please make sure to use compatible versions!\n"); goto out; default: diff --git a/tcpdump.c b/tcpdump.c index 8f39ac0..b2376fd 100644 --- a/tcpdump.c +++ b/tcpdump.c @@ -349,7 +349,7 @@ static void dump_batman_iv_ogm(unsigned char *packet_buff, ssize_t buff_len, int printf("OGM IV via neigh %s, seq %u, tq %3d, ttl %2d, v %d, flags [%c%c%c], length %zu\n", get_name_by_macaddr((struct ether_addr *)ether_header->ether_shost, read_opt), ntohl(batman_ogm_packet->seqno), batman_ogm_packet->tq, - batman_ogm_packet->header.ttl, batman_ogm_packet->header.version, + batman_ogm_packet->ttl, batman_ogm_packet->version, (batman_ogm_packet->flags & BATADV_NOT_BEST_NEXT_HOP ? 'N' : '.'), (batman_ogm_packet->flags & BATADV_DIRECTLINK ? 'D' : '.'), (batman_ogm_packet->flags & BATADV_PRIMARIES_FIRST_HOP ? 'F' : '.'), @@ -379,22 +379,22 @@ static void dump_batman_icmp(unsigned char *packet_buff, ssize_t buff_len, int r case BATADV_ECHO_REPLY: printf("%s: ICMP echo reply, id %hhu, seq %hu, ttl %2d, v %d, length %zu\n", name, icmp_packet->icmph.uid, ntohs(icmp_packet->seqno), - icmp_packet->icmph.header.ttl, - icmp_packet->icmph.header.version, + icmp_packet->icmph.ttl, + icmp_packet->icmph.version, (size_t)buff_len - sizeof(struct ether_header)); break; case BATADV_ECHO_REQUEST: printf("%s: ICMP echo request, id %hhu, seq %hu, ttl %2d, v %d, length %zu\n", name, icmp_packet->icmph.uid, ntohs(icmp_packet->seqno), - icmp_packet->icmph.header.ttl, - icmp_packet->icmph.header.version, + icmp_packet->icmph.ttl, + icmp_packet->icmph.version, (size_t)buff_len - sizeof(struct ether_header)); break; case BATADV_TTL_EXCEEDED: printf("%s: ICMP time exceeded in-transit, id %hhu, seq %hu, ttl %2d, v %d, length %zu\n", name, icmp_packet->icmph.uid, ntohs(icmp_packet->seqno), - icmp_packet->icmph.header.ttl, - icmp_packet->icmph.header.version, + icmp_packet->icmph.ttl, + icmp_packet->icmph.version, (size_t)buff_len - sizeof(struct ether_header)); break; default: @@ -425,7 +425,7 @@ static void dump_batman_ucast(unsigned char *packet_buff, ssize_t buff_len, int
printf("%s: UCAST, ttvn %d, ttl %hhu, ", get_name_by_macaddr((struct ether_addr *)unicast_packet->dest, read_opt), - unicast_packet->ttvn, unicast_packet->header.ttl); + unicast_packet->ttvn, unicast_packet->ttl);
parse_eth_hdr(packet_buff + ETH_HLEN + sizeof(struct batadv_unicast_packet), buff_len - ETH_HLEN - sizeof(struct batadv_unicast_packet), @@ -480,7 +480,7 @@ static void dump_batman_4addr(unsigned char *packet_buff, ssize_t buff_len, int printf("%s: 4ADDR, subtybe %hhu, ttvn %d, ttl %hhu, ", get_name_by_macaddr((struct ether_addr *)unicast_4addr_packet->u.dest, read_opt), unicast_4addr_packet->subtype, unicast_4addr_packet->u.ttvn, - unicast_4addr_packet->u.header.ttl); + unicast_4addr_packet->u.ttl);
parse_eth_hdr(packet_buff + ETH_HLEN + sizeof(struct batadv_unicast_4addr_packet), buff_len - ETH_HLEN - sizeof(struct batadv_unicast_4addr_packet), @@ -512,10 +512,10 @@ static void parse_eth_hdr(unsigned char *packet_buff, ssize_t buff_len, int read batman_ogm_packet = (struct batadv_ogm_packet *)(packet_buff + ETH_HLEN);
if ((read_opt & COMPAT_FILTER) && - (batman_ogm_packet->header.version != BATADV_COMPAT_VERSION)) + (batman_ogm_packet->version != BATADV_COMPAT_VERSION)) return;
- switch (batman_ogm_packet->header.packet_type) { + switch (batman_ogm_packet->packet_type) { case BATADV_IV_OGM: if (dump_level & DUMP_TYPE_BATOGM) dump_batman_iv_ogm(packet_buff, buff_len, read_opt, time_printed); @@ -537,7 +537,7 @@ static void parse_eth_hdr(unsigned char *packet_buff, ssize_t buff_len, int read dump_batman_4addr(packet_buff, buff_len, read_opt, time_printed); break; default: - fprintf(stderr, "Warning - packet contains unknown batman packet type: 0x%02x\n", batman_ogm_packet->header.packet_type); + fprintf(stderr, "Warning - packet contains unknown batman packet type: 0x%02x\n", batman_ogm_packet->packet_type); break; }
diff --git a/traceroute.c b/traceroute.c index 18e2428..7b0a826 100644 --- a/traceroute.c +++ b/traceroute.c @@ -134,8 +134,8 @@ int traceroute(char *mesh_iface, int argc, char **argv) }
memcpy(&icmp_packet_out.icmph.dst, dst_mac, ETH_ALEN); - icmp_packet_out.icmph.header.version = BATADV_COMPAT_VERSION; - icmp_packet_out.icmph.header.packet_type = BATADV_ICMP; + icmp_packet_out.icmph.version = BATADV_COMPAT_VERSION; + icmp_packet_out.icmph.packet_type = BATADV_ICMP; icmp_packet_out.icmph.msg_type = BATADV_ECHO_REQUEST; icmp_packet_out.seqno = 0; icmp_packet_out.reserved = 0; @@ -143,9 +143,9 @@ int traceroute(char *mesh_iface, int argc, char **argv) printf("traceroute to %s (%s), %d hops max, %zu byte packets\n", dst_string, mac_string, TTL_MAX, sizeof(icmp_packet_out));
- for (icmp_packet_out.icmph.header.ttl = 1; - !dst_reached && icmp_packet_out.icmph.header.ttl < TTL_MAX; - icmp_packet_out.icmph.header.ttl++) { + for (icmp_packet_out.icmph.ttl = 1; + !dst_reached && icmp_packet_out.icmph.ttl < TTL_MAX; + icmp_packet_out.icmph.ttl++) { return_mac = NULL; bat_host = NULL;
@@ -209,8 +209,7 @@ read_packet: goto out; case BATADV_PARAMETER_PROBLEM: fprintf(stderr, "Error - the batman adv kernel module version (%d) differs from ours (%d)\n", - icmp_packet_in.icmph.header.version, - BATADV_COMPAT_VERSION); + icmp_packet_in.icmph.version, BATADV_COMPAT_VERSION); fprintf(stderr, "Please make sure to use compatible versions!\n"); goto out; default: @@ -221,11 +220,11 @@ read_packet: }
if (!bat_host) - printf("%2hhu: %s", icmp_packet_out.icmph.header.ttl, + printf("%2hhu: %s", icmp_packet_out.icmph.ttl, (return_mac ? return_mac : "*")); else printf("%2hhu: %s (%s)", - icmp_packet_out.icmph.header.ttl, + icmp_packet_out.icmph.ttl, bat_host->name, return_mac);
for (i = 0; i < NUM_PACKETS; i++) {