Merge pull request #7675 from shawnl/unaligned

Issue #7654 (unaligned loads on sparc64)
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2018-01-20 10:00:14 +11:00 committed by GitHub
commit c3de717e51
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 30 additions and 40 deletions

View file

@ -26,89 +26,77 @@
/* BE */
static inline uint16_t unaligned_read_be16(const void *_u) {
const uint8_t *u = _u;
const struct __attribute__((packed, may_alias)) { uint16_t x; } *u = _u;
return (((uint16_t) u[0]) << 8) |
((uint16_t) u[1]);
return be16toh(u->x);
}
static inline uint32_t unaligned_read_be32(const void *_u) {
const uint8_t *u = _u;
const struct __attribute__((packed, may_alias)) { uint32_t x; } *u = _u;
return (((uint32_t) unaligned_read_be16(u)) << 16) |
((uint32_t) unaligned_read_be16(u + 2));
return be32toh(u->x);
}
static inline uint64_t unaligned_read_be64(const void *_u) {
const uint8_t *u = _u;
const struct __attribute__((packed, may_alias)) { uint64_t x; } *u = _u;
return (((uint64_t) unaligned_read_be32(u)) << 32) |
((uint64_t) unaligned_read_be32(u + 4));
return be64toh(u->x);
}
static inline void unaligned_write_be16(void *_u, uint16_t a) {
uint8_t *u = _u;
struct __attribute__((packed, may_alias)) { uint16_t x; } *u = _u;
u[0] = (uint8_t) (a >> 8);
u[1] = (uint8_t) a;
u->x = be16toh(a);
}
static inline void unaligned_write_be32(void *_u, uint32_t a) {
uint8_t *u = _u;
struct __attribute__((packed, may_alias)) { uint32_t x; } *u = _u;
unaligned_write_be16(u, (uint16_t) (a >> 16));
unaligned_write_be16(u + 2, (uint16_t) a);
u->x = be32toh(a);
}
static inline void unaligned_write_be64(void *_u, uint64_t a) {
uint8_t *u = _u;
struct __attribute__((packed, may_alias)) { uint64_t x; } *u = _u;
unaligned_write_be32(u, (uint32_t) (a >> 32));
unaligned_write_be32(u + 4, (uint32_t) a);
u->x = be64toh(a);
}
/* LE */
static inline uint16_t unaligned_read_le16(const void *_u) {
const uint8_t *u = _u;
const struct __attribute__((packed, may_alias)) { uint16_t x; } *u = _u;
return (((uint16_t) u[1]) << 8) |
((uint16_t) u[0]);
return le16toh(u->x);
}
static inline uint32_t unaligned_read_le32(const void *_u) {
const uint8_t *u = _u;
const struct __attribute__((packed, may_alias)) { uint32_t x; } *u = _u;
return (((uint32_t) unaligned_read_le16(u + 2)) << 16) |
((uint32_t) unaligned_read_le16(u));
return le32toh(u->x);
}
static inline uint64_t unaligned_read_le64(const void *_u) {
const uint8_t *u = _u;
const struct __attribute__((packed, may_alias)) { uint64_t x; } *u = _u;
return (((uint64_t) unaligned_read_le32(u + 4)) << 32) |
((uint64_t) unaligned_read_le32(u));
return le64toh(u->x);
}
static inline void unaligned_write_le16(void *_u, uint16_t a) {
uint8_t *u = _u;
struct __attribute__((packed, may_alias)) { uint16_t x; } *u = _u;
u[0] = (uint8_t) a;
u[1] = (uint8_t) (a >> 8);
u->x = le16toh(a);
}
static inline void unaligned_write_le32(void *_u, uint32_t a) {
uint8_t *u = _u;
struct __attribute__((packed, may_alias)) { uint32_t x; } *u = _u;
unaligned_write_le16(u, (uint16_t) a);
unaligned_write_le16(u + 2, (uint16_t) (a >> 16));
u->x = le32toh(a);
}
static inline void unaligned_write_le64(void *_u, uint64_t a) {
uint8_t *u = _u;
struct __attribute__((packed, may_alias)) { uint64_t x; } *u = _u;
unaligned_write_le32(u, (uint32_t) a);
unaligned_write_le32(u + 4, (uint32_t) (a >> 32));
u->x = le64toh(a);
}
#if __BYTE_ORDER == __BIG_ENDIAN

View file

@ -24,6 +24,7 @@
#include "arp-util.h"
#include "fd-util.h"
#include "unaligned.h"
#include "util.h"
int arp_network_bind_raw_socket(int ifindex, be32_t address, const struct ether_addr *eth_mac) {
@ -48,12 +49,12 @@ int arp_network_bind_raw_socket(int ifindex, be32_t address, const struct ether_
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ARPOP_REPLY, 1, 0), /* protocol == reply ? */
BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */
/* Sender Hardware Address must be different from our own */
BPF_STMT(BPF_LD + BPF_IMM, htobe32(*((uint32_t *) eth_mac))), /* A <- 4 bytes of client's MAC */
BPF_STMT(BPF_LD + BPF_IMM, unaligned_read_ne32(&eth_mac->ether_addr_octet[0])),/* A <- 4 bytes of client's MAC */
BPF_STMT(BPF_MISC + BPF_TAX, 0), /* X <- A */
BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(struct ether_arp, arp_sha)), /* A <- 4 bytes of SHA */
BPF_STMT(BPF_ALU + BPF_XOR + BPF_X, 0), /* A xor X */
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, 0, 6), /* A == 0 ? */
BPF_STMT(BPF_LD + BPF_IMM, htobe16(*((uint16_t *) (((char *) eth_mac) + 4)))), /* A <- remainder of client's MAC */
BPF_STMT(BPF_LD + BPF_IMM, unaligned_read_ne16(&eth_mac->ether_addr_octet[4])),/* A <- remainder of client's MAC */
BPF_STMT(BPF_MISC + BPF_TAX, 0), /* X <- A */
BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(struct ether_arp, arp_sha) + 4), /* A <- remainder of SHA */
BPF_STMT(BPF_ALU + BPF_XOR + BPF_X, 0), /* A xor X */

View file

@ -32,6 +32,7 @@
#include "dhcp-internal.h"
#include "fd-util.h"
#include "socket-util.h"
#include "unaligned.h"
static int _bind_raw_socket(int ifindex, union sockaddr_union *link,
uint32_t xid, const uint8_t *mac_addr,
@ -70,13 +71,13 @@ static int _bind_raw_socket(int ifindex, union sockaddr_union *link,
BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(DHCPPacket, dhcp.xid)), /* A <- client identifier */
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, xid, 1, 0), /* client identifier == xid ? */
BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */
BPF_STMT(BPF_LD + BPF_IMM, htobe32(*((unsigned int *) eth_mac))), /* A <- 4 bytes of client's MAC */
BPF_STMT(BPF_LD + BPF_IMM, unaligned_read_be32(&eth_mac->ether_addr_octet[0])), /* A <- 4 bytes of client's MAC */
BPF_STMT(BPF_MISC + BPF_TAX, 0), /* X <- A */
BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(DHCPPacket, dhcp.chaddr)), /* A <- 4 bytes of MAC from dhcp.chaddr */
BPF_STMT(BPF_ALU + BPF_XOR + BPF_X, 0), /* A xor X */
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, 1, 0), /* A == 0 ? */
BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */
BPF_STMT(BPF_LD + BPF_IMM, htobe16(*((unsigned short *) (((char *) eth_mac) + 4)))), /* A <- remainder of client's MAC */
BPF_STMT(BPF_LD + BPF_IMM, unaligned_read_be16(&eth_mac->ether_addr_octet[4])), /* A <- remainder of client's MAC */
BPF_STMT(BPF_MISC + BPF_TAX, 0), /* X <- A */
BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(DHCPPacket, dhcp.chaddr) + 4), /* A <- remainder of MAC from dhcp.chaddr */
BPF_STMT(BPF_ALU + BPF_XOR + BPF_X, 0), /* A xor X */