mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-10 01:17:44 +03:00
Merge pull request #7675 from shawnl/unaligned
Issue #7654 (unaligned loads on sparc64)
This commit is contained in:
commit
c3de717e51
@ -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
|
||||
|
@ -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(ð_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(ð_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 */
|
||||
|
@ -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(ð_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(ð_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 */
|
||||
|
Loading…
Reference in New Issue
Block a user