X Tutup
Skip to content

Commit 807aa0b

Browse files
authored
Merge pull request systemd#19980 from yuwata/sd-ipv4acd-filter-all-hwaddr
network: IPv4LL and ACD fixes
2 parents dc9880d + 4492443 commit 807aa0b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+876
-679
lines changed

src/basic/ether-addr-util.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,16 @@ int hw_addr_compare(const struct hw_addr_data *a, const struct hw_addr_data *b)
3737
return memcmp(a->bytes, b->bytes, a->length);
3838
}
3939

40+
static void hw_addr_hash_func(const struct hw_addr_data *p, struct siphash *state) {
41+
assert(p);
42+
assert(state);
43+
44+
siphash24_compress(&p->length, sizeof(p->length), state);
45+
siphash24_compress(p->bytes, p->length, state);
46+
}
47+
48+
DEFINE_HASH_OPS(hw_addr_hash_ops, struct hw_addr_data, hw_addr_hash_func, hw_addr_compare);
49+
4050
char* ether_addr_to_string(const struct ether_addr *addr, char buffer[ETHER_ADDR_TO_STRING_MAX]) {
4151
assert(addr);
4252
assert(buffer);

src/basic/ether-addr-util.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ static inline bool hw_addr_is_null(const struct hw_addr_data *addr) {
3636
return hw_addr_equal(addr, &HW_ADDR_NULL);
3737
}
3838

39+
extern const struct hash_ops hw_addr_hash_ops;
40+
3941
#define ETHER_ADDR_FORMAT_STR "%02X%02X%02X%02X%02X%02X"
4042
#define ETHER_ADDR_FORMAT_VAL(x) (x).ether_addr_octet[0], (x).ether_addr_octet[1], (x).ether_addr_octet[2], (x).ether_addr_octet[3], (x).ether_addr_octet[4], (x).ether_addr_octet[5]
4143

src/libsystemd-network/arp-util.c

Lines changed: 51 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@
88
#include <netinet/if_ether.h>
99

1010
#include "arp-util.h"
11+
#include "ether-addr-util.h"
1112
#include "fd-util.h"
13+
#include "in-addr-util.h"
1214
#include "unaligned.h"
1315
#include "util.h"
1416

15-
int arp_network_bind_raw_socket(int ifindex, be32_t address, const struct ether_addr *eth_mac) {
17+
int arp_update_filter(int fd, const struct in_addr *a, const struct ether_addr *eth_mac) {
1618
struct sock_filter filter[] = {
1719
BPF_STMT(BPF_LD + BPF_W + BPF_LEN, 0), /* A <- packet length */
1820
BPF_JUMP(BPF_JMP + BPF_JGE + BPF_K, sizeof(struct ether_arp), 1, 0), /* packet >= arp packet ? */
@@ -46,13 +48,13 @@ int arp_network_bind_raw_socket(int ifindex, be32_t address, const struct ether_
4648
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, 0, 1), /* A == 0 ? */
4749
BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */
4850
/* Sender Protocol Address or Target Protocol Address must be equal to the one we care about */
49-
BPF_STMT(BPF_LD + BPF_IMM, htobe32(address)), /* A <- clients IP */
51+
BPF_STMT(BPF_LD + BPF_IMM, htobe32(a->s_addr)), /* A <- clients IP */
5052
BPF_STMT(BPF_MISC + BPF_TAX, 0), /* X <- A */
5153
BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(struct ether_arp, arp_spa)), /* A <- SPA */
5254
BPF_STMT(BPF_ALU + BPF_XOR + BPF_X, 0), /* X xor A */
5355
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, 0, 1), /* A == 0 ? */
5456
BPF_STMT(BPF_RET + BPF_K, 65535), /* return all */
55-
BPF_STMT(BPF_LD + BPF_IMM, htobe32(address)), /* A <- clients IP */
57+
BPF_STMT(BPF_LD + BPF_IMM, htobe32(a->s_addr)), /* A <- clients IP */
5658
BPF_STMT(BPF_MISC + BPF_TAX, 0), /* X <- A */
5759
BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(struct ether_arp, arp_tpa)), /* A <- TPA */
5860
BPF_STMT(BPF_ALU + BPF_XOR + BPF_X, 0), /* X xor A */
@@ -61,15 +63,25 @@ int arp_network_bind_raw_socket(int ifindex, be32_t address, const struct ether_
6163
BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */
6264
};
6365
struct sock_fprog fprog = {
64-
.len = ELEMENTSOF(filter),
65-
.filter = (struct sock_filter*) filter
66+
.len = ELEMENTSOF(filter),
67+
.filter = (struct sock_filter*) filter,
6668
};
69+
70+
assert(fd >= 0);
71+
72+
if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &fprog, sizeof(fprog)) < 0)
73+
return -errno;
74+
75+
return 0;
76+
}
77+
78+
int arp_network_bind_raw_socket(int ifindex, const struct in_addr *a, const struct ether_addr *eth_mac) {
6779
union sockaddr_union link = {
68-
.ll.sll_family = AF_PACKET,
80+
.ll.sll_family = AF_PACKET,
6981
.ll.sll_protocol = htobe16(ETH_P_ARP),
70-
.ll.sll_ifindex = ifindex,
71-
.ll.sll_halen = ETH_ALEN,
72-
.ll.sll_addr = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
82+
.ll.sll_ifindex = ifindex,
83+
.ll.sll_halen = ETH_ALEN,
84+
.ll.sll_addr = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
7385
};
7486
_cleanup_close_ int s = -1;
7587
int r;
@@ -80,59 +92,57 @@ int arp_network_bind_raw_socket(int ifindex, be32_t address, const struct ether_
8092
if (s < 0)
8193
return -errno;
8294

83-
r = setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER, &fprog, sizeof(fprog));
95+
r = arp_update_filter(s, a, eth_mac);
8496
if (r < 0)
85-
return -errno;
97+
return r;
8698

87-
r = bind(s, &link.sa, sizeof(link.ll));
88-
if (r < 0)
99+
if (bind(s, &link.sa, sizeof(link.ll)) < 0)
89100
return -errno;
90101

91102
return TAKE_FD(s);
92103
}
93104

94-
static int arp_send_packet(int fd, int ifindex,
95-
be32_t pa, const struct ether_addr *ha,
96-
bool announce) {
105+
int arp_send_packet(
106+
int fd,
107+
int ifindex,
108+
const struct in_addr *pa,
109+
const struct ether_addr *ha,
110+
bool announce) {
111+
97112
union sockaddr_union link = {
98-
.ll.sll_family = AF_PACKET,
113+
.ll.sll_family = AF_PACKET,
99114
.ll.sll_protocol = htobe16(ETH_P_ARP),
100-
.ll.sll_ifindex = ifindex,
101-
.ll.sll_halen = ETH_ALEN,
102-
.ll.sll_addr = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
115+
.ll.sll_ifindex = ifindex,
116+
.ll.sll_halen = ETH_ALEN,
117+
.ll.sll_addr = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
103118
};
104119
struct ether_arp arp = {
105-
.ea_hdr.ar_hrd = htobe16(ARPHRD_ETHER), /* HTYPE */
106-
.ea_hdr.ar_pro = htobe16(ETHERTYPE_IP), /* PTYPE */
107-
.ea_hdr.ar_hln = ETH_ALEN, /* HLEN */
108-
.ea_hdr.ar_pln = sizeof(be32_t), /* PLEN */
109-
.ea_hdr.ar_op = htobe16(ARPOP_REQUEST), /* REQUEST */
120+
.ea_hdr.ar_hrd = htobe16(ARPHRD_ETHER), /* HTYPE */
121+
.ea_hdr.ar_pro = htobe16(ETHERTYPE_IP), /* PTYPE */
122+
.ea_hdr.ar_hln = ETH_ALEN, /* HLEN */
123+
.ea_hdr.ar_pln = sizeof(struct in_addr), /* PLEN */
124+
.ea_hdr.ar_op = htobe16(ARPOP_REQUEST), /* REQUEST */
110125
};
111-
int r;
126+
ssize_t n;
112127

113128
assert(fd >= 0);
114-
assert(pa != 0);
129+
assert(ifindex > 0);
130+
assert(pa);
131+
assert(in4_addr_is_set(pa));
115132
assert(ha);
133+
assert(!ether_addr_is_null(ha));
116134

117135
memcpy(&arp.arp_sha, ha, ETH_ALEN);
118-
memcpy(&arp.arp_tpa, &pa, sizeof(pa));
136+
memcpy(&arp.arp_tpa, pa, sizeof(struct in_addr));
119137

120138
if (announce)
121-
memcpy(&arp.arp_spa, &pa, sizeof(pa));
139+
memcpy(&arp.arp_spa, pa, sizeof(struct in_addr));
122140

123-
r = sendto(fd, &arp, sizeof(struct ether_arp), 0, &link.sa, sizeof(link.ll));
124-
if (r < 0)
141+
n = sendto(fd, &arp, sizeof(struct ether_arp), 0, &link.sa, sizeof(link.ll));
142+
if (n < 0)
125143
return -errno;
144+
if (n != sizeof(struct ether_arp))
145+
return -EIO;
126146

127147
return 0;
128148
}
129-
130-
int arp_send_probe(int fd, int ifindex,
131-
be32_t pa, const struct ether_addr *ha) {
132-
return arp_send_packet(fd, ifindex, pa, ha, false);
133-
}
134-
135-
int arp_send_announcement(int fd, int ifindex,
136-
be32_t pa, const struct ether_addr *ha) {
137-
return arp_send_packet(fd, ifindex, pa, ha, true);
138-
}

src/libsystemd-network/arp-util.h

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,31 @@
66
***/
77

88
#include <net/ethernet.h>
9+
#include <netinet/in.h>
910

1011
#include "socket-util.h"
1112
#include "sparse-endian.h"
1213

13-
int arp_network_bind_raw_socket(int index, be32_t address, const struct ether_addr *eth_mac);
14+
int arp_update_filter(int fd, const struct in_addr *a, const struct ether_addr *eth_mac);
15+
int arp_network_bind_raw_socket(int ifindex, const struct in_addr *a, const struct ether_addr *eth_mac);
1416

15-
int arp_send_probe(int fd, int ifindex,
16-
be32_t pa, const struct ether_addr *ha);
17-
int arp_send_announcement(int fd, int ifindex,
18-
be32_t pa, const struct ether_addr *ha);
17+
int arp_send_packet(
18+
int fd,
19+
int ifindex,
20+
const struct in_addr *pa,
21+
const struct ether_addr *ha,
22+
bool announce);
23+
static inline int arp_send_probe(
24+
int fd,
25+
int ifindex,
26+
const struct in_addr *pa,
27+
const struct ether_addr *ha) {
28+
return arp_send_packet(fd, ifindex, pa, ha, false);
29+
}
30+
static inline int arp_send_announcement(
31+
int fd,
32+
int ifindex,
33+
const struct in_addr *pa,
34+
const struct ether_addr *ha) {
35+
return arp_send_packet(fd, ifindex, pa, ha, true);
36+
}

0 commit comments

Comments
 (0)
X Tutup