Merge pull request #19867 from yuwata/ether-addr-util

ether-addr-util: introduce hw_addr_equal() and friends
This commit is contained in:
Lennart Poettering
2021-06-10 09:29:36 +02:00
committed by GitHub
18 changed files with 85 additions and 73 deletions
+15 -2
View File
@@ -10,13 +10,13 @@
#include "macro.h"
#include "string-util.h"
char* hw_addr_to_string(const hw_addr_data *addr, char buffer[HW_ADDR_TO_STRING_MAX]) {
char* hw_addr_to_string(const struct hw_addr_data *addr, char buffer[HW_ADDR_TO_STRING_MAX]) {
assert(addr);
assert(buffer);
assert(addr->length <= HW_ADDR_MAX_SIZE);
for (size_t i = 0; i < addr->length; i++) {
sprintf(&buffer[3*i], "%02"PRIx8, addr->addr.bytes[i]);
sprintf(&buffer[3*i], "%02"PRIx8, addr->bytes[i]);
if (i < addr->length - 1)
buffer[3*i + 2] = ':';
}
@@ -24,6 +24,19 @@ char* hw_addr_to_string(const hw_addr_data *addr, char buffer[HW_ADDR_TO_STRING_
return buffer;
}
int hw_addr_compare(const struct hw_addr_data *a, const struct hw_addr_data *b) {
int r;
assert(a);
assert(b);
r = CMP(a->length, b->length);
if (r != 0)
return r;
return memcmp(a->bytes, b->bytes, a->length);
}
char* ether_addr_to_string(const struct ether_addr *addr, char buffer[ETHER_ADDR_TO_STRING_MAX]) {
assert(addr);
assert(buffer);
+19 -11
View File
@@ -11,24 +11,30 @@
* defines a macro of the same name with a much lower size. */
#define HW_ADDR_MAX_SIZE 32
union hw_addr_union {
struct ether_addr ether;
uint8_t infiniband[INFINIBAND_ALEN];
uint8_t bytes[HW_ADDR_MAX_SIZE];
struct hw_addr_data {
size_t length;
union {
struct ether_addr ether;
uint8_t infiniband[INFINIBAND_ALEN];
uint8_t bytes[HW_ADDR_MAX_SIZE];
};
};
typedef struct hw_addr_data {
union hw_addr_union addr;
size_t length;
} hw_addr_data;
#define HW_ADDR_TO_STRING_MAX (3*HW_ADDR_MAX_SIZE)
char* hw_addr_to_string(const hw_addr_data *addr, char buffer[HW_ADDR_TO_STRING_MAX]);
char* hw_addr_to_string(const struct hw_addr_data *addr, char buffer[HW_ADDR_TO_STRING_MAX]);
/* Use only as function argument, never stand-alone! */
#define HW_ADDR_TO_STR(hw_addr) hw_addr_to_string((hw_addr), (char[HW_ADDR_TO_STRING_MAX]){})
#define HW_ADDR_NULL ((const hw_addr_data){})
#define HW_ADDR_NULL ((const struct hw_addr_data){})
int hw_addr_compare(const struct hw_addr_data *a, const struct hw_addr_data *b);
static inline bool hw_addr_equal(const struct hw_addr_data *a, const struct hw_addr_data *b) {
return hw_addr_compare(a, b) == 0;
}
static inline bool hw_addr_is_null(const struct hw_addr_data *addr) {
return hw_addr_equal(addr, &HW_ADDR_NULL);
}
#define ETHER_ADDR_FORMAT_STR "%02X%02X%02X%02X%02X%02X"
#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]
@@ -36,6 +42,8 @@ char* hw_addr_to_string(const hw_addr_data *addr, char buffer[HW_ADDR_TO_STRING_
#define ETHER_ADDR_TO_STRING_MAX (3*6)
char* ether_addr_to_string(const struct ether_addr *addr, char buffer[ETHER_ADDR_TO_STRING_MAX]);
int ether_addr_to_string_alloc(const struct ether_addr *addr, char **ret);
/* Use only as function argument, never stand-alone! */
#define ETHER_ADDR_TO_STR(addr) ether_addr_to_string((addr), (char[ETHER_ADDR_TO_STRING_MAX]){})
int ether_addr_compare(const struct ether_addr *a, const struct ether_addr *b);
static inline bool ether_addr_equal(const struct ether_addr *a, const struct ether_addr *b) {
+5 -5
View File
@@ -494,7 +494,7 @@ int sd_netlink_message_append_ether_addr(sd_netlink_message *m, unsigned short t
return 0;
}
int netlink_message_append_hw_addr(sd_netlink_message *m, unsigned short type, const hw_addr_data *data) {
int netlink_message_append_hw_addr(sd_netlink_message *m, unsigned short type, const struct hw_addr_data *data) {
int r;
assert_return(m, -EINVAL);
@@ -506,7 +506,7 @@ int netlink_message_append_hw_addr(sd_netlink_message *m, unsigned short type, c
if (r < 0)
return r;
r = add_rtattr(m, type, data->addr.bytes, data->length);
r = add_rtattr(m, type, data->bytes, data->length);
if (r < 0)
return r;
@@ -886,7 +886,7 @@ int sd_netlink_message_read_ether_addr(sd_netlink_message *m, unsigned short typ
return 0;
}
int netlink_message_read_hw_addr(sd_netlink_message *m, unsigned short type, hw_addr_data *data) {
int netlink_message_read_hw_addr(sd_netlink_message *m, unsigned short type, struct hw_addr_data *data) {
int r;
void *attr_data;
@@ -899,11 +899,11 @@ int netlink_message_read_hw_addr(sd_netlink_message *m, unsigned short type, hw_
r = netlink_message_read_internal(m, type, &attr_data, NULL);
if (r < 0)
return r;
else if ((size_t) r > sizeof(union hw_addr_union))
else if (r > HW_ADDR_MAX_SIZE)
return -EIO;
if (data) {
memcpy(data->addr.bytes, attr_data, r);
memcpy(data->bytes, attr_data, r);
data->length = r;
}
+2 -2
View File
@@ -117,11 +117,11 @@ int rtnl_log_create_error(int r);
userdata, description); \
})
int netlink_message_append_hw_addr(sd_netlink_message *m, unsigned short type, const hw_addr_data *data);
int netlink_message_append_hw_addr(sd_netlink_message *m, unsigned short type, const struct hw_addr_data *data);
int netlink_message_append_in_addr_union(sd_netlink_message *m, unsigned short type, int family, const union in_addr_union *data);
int netlink_message_append_sockaddr_union(sd_netlink_message *m, unsigned short type, const union sockaddr_union *data);
int netlink_message_read_hw_addr(sd_netlink_message *m, unsigned short type, hw_addr_data *data);
int netlink_message_read_hw_addr(sd_netlink_message *m, unsigned short type, struct hw_addr_data *data);
int netlink_message_read_in_addr_union(sd_netlink_message *m, unsigned short type, int family, union in_addr_union *data);
void rtattr_append_attribute_internal(struct rtattr *rta, unsigned short type, const void *data, size_t data_length);
+2 -5
View File
@@ -1040,7 +1040,6 @@ static int route_dump(Route *route, FILE *f) {
}
void network_dump(Network *network, FILE *f) {
char mac[ETHER_ADDR_TO_STRING_MAX];
Address *address;
Route *route;
const char *dhcp;
@@ -1057,7 +1056,7 @@ void network_dump(Network *network, FILE *f) {
fputs("\n[Link]\n", f);
if (!ether_addr_is_null(&network->mac))
fprintf(f, "MACAddress=%s\n", ether_addr_to_string(&network->mac, mac));
fprintf(f, "MACAddress=%s\n", ETHER_ADDR_TO_STR(&network->mac));
if (network->mtu > 0)
fprintf(f, "MTUBytes=%" PRIu32 "\n", network->mtu);
@@ -1111,15 +1110,13 @@ void netdev_dump(NetDev *netdev, FILE *f) {
}
void link_dump(Link *link, FILE *f) {
char mac[ETHER_ADDR_TO_STRING_MAX];
assert(link);
assert(f);
fputs("[Match]\n", f);
if (!ether_addr_is_null(&link->mac))
fprintf(f, "MACAddress=%s\n", ether_addr_to_string(&link->mac, mac));
fprintf(f, "MACAddress=%s\n", ETHER_ADDR_TO_STR(&link->mac));
fprintf(f,
"\n[Link]\n"
+7 -9
View File
@@ -272,7 +272,7 @@ typedef struct LinkInfo {
sd_device *sd_device;
int ifindex;
unsigned short iftype;
hw_addr_data hw_address;
struct hw_addr_data hw_address;
struct ether_addr permanent_mac_address;
uint32_t master;
uint32_t mtu;
@@ -554,13 +554,13 @@ static int decode_link(sd_netlink_message *m, LinkInfo *info, char **patterns, b
info->has_mac_address =
netlink_message_read_hw_addr(m, IFLA_ADDRESS, &info->hw_address) >= 0 &&
memcmp(&info->hw_address, &HW_ADDR_NULL, sizeof(hw_addr_data)) != 0;
!hw_addr_is_null(&info->hw_address);
info->has_permanent_mac_address =
ethtool_get_permanent_macaddr(NULL, info->name, &info->permanent_mac_address) >= 0 &&
memcmp(&info->permanent_mac_address, &ETHER_ADDR_NULL, sizeof(struct ether_addr)) != 0 &&
!ether_addr_is_null(&info->permanent_mac_address) &&
(info->hw_address.length != sizeof(struct ether_addr) ||
memcmp(&info->permanent_mac_address, info->hw_address.addr.bytes, sizeof(struct ether_addr)) != 0);
memcmp(&info->permanent_mac_address, info->hw_address.bytes, sizeof(struct ether_addr)) != 0);
(void) sd_netlink_message_read_u32(m, IFLA_MTU, &info->mtu);
(void) sd_netlink_message_read_u32(m, IFLA_MIN_MTU, &info->min_mtu);
@@ -1684,7 +1684,7 @@ static int link_status_one(
_cleanup_free_ char *description = NULL;
if (info->hw_address.length == ETH_ALEN)
(void) ieee_oui(hwdb, &info->hw_address.addr.ether, &description);
(void) ieee_oui(hwdb, &info->hw_address.ether, &description);
r = table_add_many(table,
TABLE_EMPTY,
@@ -1702,7 +1702,6 @@ static int link_status_one(
if (info->has_permanent_mac_address) {
_cleanup_free_ char *description = NULL;
char ea[ETHER_ADDR_TO_STRING_MAX];
(void) ieee_oui(hwdb, &info->permanent_mac_address, &description);
@@ -1712,7 +1711,7 @@ static int link_status_one(
if (r < 0)
return table_log_add_error(r);
r = table_add_cell_stringf(table, NULL, "%s%s%s%s",
ether_addr_to_string(&info->permanent_mac_address, ea),
ETHER_ADDR_TO_STR(&info->permanent_mac_address),
description ? " (" : "",
strempty(description),
description ? ")" : "");
@@ -2107,7 +2106,6 @@ static int link_status_one(
if (info->has_wlan_link_info) {
_cleanup_free_ char *esc = NULL;
char buf[ETHER_ADDR_TO_STRING_MAX];
r = table_add_many(table,
TABLE_EMPTY,
@@ -2120,7 +2118,7 @@ static int link_status_one(
r = table_add_cell_stringf(table, NULL, "%s (%s)",
strnull(esc),
ether_addr_to_string(&info->bssid, buf));
ETHER_ADDR_TO_STR(&info->bssid));
if (r < 0)
return table_log_add_error(r);
}
+9 -9
View File
@@ -59,22 +59,22 @@ int generate_ipv6_eui_64_address(const Link *link, struct in6_addr *ret) {
if (link->iftype == ARPHRD_INFINIBAND) {
/* see RFC4391 section 8 */
memcpy(&ret->s6_addr[8], &link->hw_addr.addr.infiniband[12], 8);
memcpy(&ret->s6_addr[8], &link->hw_addr.infiniband[12], 8);
ret->s6_addr[8] ^= 1 << 1;
return 0;
}
/* see RFC4291 section 2.5.1 */
ret->s6_addr[8] = link->hw_addr.addr.ether.ether_addr_octet[0];
ret->s6_addr[8] = link->hw_addr.ether.ether_addr_octet[0];
ret->s6_addr[8] ^= 1 << 1;
ret->s6_addr[9] = link->hw_addr.addr.ether.ether_addr_octet[1];
ret->s6_addr[10] = link->hw_addr.addr.ether.ether_addr_octet[2];
ret->s6_addr[9] = link->hw_addr.ether.ether_addr_octet[1];
ret->s6_addr[10] = link->hw_addr.ether.ether_addr_octet[2];
ret->s6_addr[11] = 0xff;
ret->s6_addr[12] = 0xfe;
ret->s6_addr[13] = link->hw_addr.addr.ether.ether_addr_octet[3];
ret->s6_addr[14] = link->hw_addr.addr.ether.ether_addr_octet[4];
ret->s6_addr[15] = link->hw_addr.addr.ether.ether_addr_octet[5];
ret->s6_addr[13] = link->hw_addr.ether.ether_addr_octet[3];
ret->s6_addr[14] = link->hw_addr.ether.ether_addr_octet[4];
ret->s6_addr[15] = link->hw_addr.ether.ether_addr_octet[5];
return 0;
}
@@ -1531,7 +1531,7 @@ static int ipv4_dad_configure(Address *address) {
if (r < 0)
return r;
r = sd_ipv4acd_set_mac(address->acd, &address->link->hw_addr.addr.ether);
r = sd_ipv4acd_set_mac(address->acd, &address->link->hw_addr.ether);
if (r < 0)
return r;
@@ -1561,7 +1561,7 @@ static int ipv4_dad_update_mac_one(Address *address) {
if (r < 0)
return r;
r = sd_ipv4acd_set_mac(address->acd, &address->link->hw_addr.addr.ether);
r = sd_ipv4acd_set_mac(address->acd, &address->link->hw_addr.ether);
if (r < 0)
return r;
+7 -7
View File
@@ -852,7 +852,7 @@ static int dhcp4_configure_dad(Link *link) {
if (r < 0)
return r;
r = sd_ipv4acd_set_mac(link->dhcp_acd, &link->hw_addr.addr.ether);
r = sd_ipv4acd_set_mac(link->dhcp_acd, &link->hw_addr.ether);
if (r < 0)
return r;
@@ -874,7 +874,7 @@ static int dhcp4_dad_update_mac(Link *link) {
if (r < 0)
return r;
r = sd_ipv4acd_set_mac(link->dhcp_acd, &link->hw_addr.addr.ether);
r = sd_ipv4acd_set_mac(link->dhcp_acd, &link->hw_addr.ether);
if (r < 0)
return r;
@@ -1437,7 +1437,7 @@ static int dhcp4_set_client_identifier(Link *link) {
break;
}
case DHCP_CLIENT_ID_MAC: {
const uint8_t *hw_addr = link->hw_addr.addr.bytes;
const uint8_t *hw_addr = link->hw_addr.bytes;
size_t hw_addr_len = link->hw_addr.length;
if (link->iftype == ARPHRD_INFINIBAND && hw_addr_len == INFINIBAND_ALEN) {
@@ -1546,8 +1546,8 @@ int dhcp4_configure(Link *link) {
return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to attach event to DHCP4 client: %m");
r = sd_dhcp_client_set_mac(link->dhcp_client,
link->hw_addr.addr.bytes,
link->bcast_addr.length > 0 ? link->bcast_addr.addr.bytes : NULL,
link->hw_addr.bytes,
link->bcast_addr.length > 0 ? link->bcast_addr.bytes : NULL,
link->hw_addr.length, link->iftype);
if (r < 0)
return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set MAC address: %m");
@@ -1702,8 +1702,8 @@ int dhcp4_update_mac(Link *link) {
if (!link->dhcp_client)
return 0;
r = sd_dhcp_client_set_mac(link->dhcp_client, link->hw_addr.addr.bytes,
link->bcast_addr.length > 0 ? link->bcast_addr.addr.bytes : NULL,
r = sd_dhcp_client_set_mac(link->dhcp_client, link->hw_addr.bytes,
link->bcast_addr.length > 0 ? link->bcast_addr.bytes : NULL,
link->hw_addr.length, link->iftype);
if (r < 0)
return r;
+1 -1
View File
@@ -1569,7 +1569,7 @@ static int dhcp6_set_identifier(Link *link, sd_dhcp6_client *client) {
assert(link->network);
assert(client);
r = sd_dhcp6_client_set_mac(client, link->hw_addr.addr.bytes, link->hw_addr.length, link->iftype);
r = sd_dhcp6_client_set_mac(client, link->hw_addr.bytes, link->hw_addr.length, link->iftype);
if (r < 0)
return r;
+2 -2
View File
@@ -166,7 +166,7 @@ int ipv4ll_configure(Link *link) {
return r;
}
r = sd_ipv4ll_set_mac(link->ipv4ll, &link->hw_addr.addr.ether);
r = sd_ipv4ll_set_mac(link->ipv4ll, &link->hw_addr.ether);
if (r < 0)
return r;
@@ -196,7 +196,7 @@ int ipv4ll_update_mac(Link *link) {
if (r < 0)
return r;
r = sd_ipv4ll_set_mac(link->ipv4ll, &link->hw_addr.addr.ether);
r = sd_ipv4ll_set_mac(link->ipv4ll, &link->hw_addr.ether);
if (r < 0)
return r;
+5 -6
View File
@@ -1157,7 +1157,7 @@ static int link_get_network(Link *link, Network **ret) {
r = net_match_config(
&network->match,
link->sd_device,
&link->hw_addr.addr.ether,
&link->hw_addr.ether,
&link->permanent_mac,
link->driver,
link->iftype,
@@ -1968,7 +1968,7 @@ static int link_update_master(Link *link, sd_netlink_message *message) {
}
static int link_update_hardware_address(Link *link, sd_netlink_message *message) {
hw_addr_data hw_addr;
struct hw_addr_data hw_addr;
int r;
assert(link);
@@ -1984,8 +1984,7 @@ static int link_update_hardware_address(Link *link, sd_netlink_message *message)
if (r < 0)
return log_link_warning_errno(link, r, "rtnl: failed to read hardware address: %m");
if (link->hw_addr.length == hw_addr.length &&
memcmp(link->hw_addr.addr.bytes, hw_addr.addr.bytes, hw_addr.length) == 0)
if (hw_addr_equal(&link->hw_addr, &hw_addr))
return 0;
link->hw_addr = hw_addr;
@@ -2009,13 +2008,13 @@ static int link_update_hardware_address(Link *link, sd_netlink_message *message)
return log_link_debug_errno(link, r, "Could not update MAC address for Router Advertisement: %m");
if (link->ndisc) {
r = sd_ndisc_set_mac(link->ndisc, &link->hw_addr.addr.ether);
r = sd_ndisc_set_mac(link->ndisc, &link->hw_addr.ether);
if (r < 0)
return log_link_debug_errno(link, r, "Could not update MAC for NDisc: %m");
}
if (link->lldp) {
r = sd_lldp_set_filter_address(link->lldp, &link->hw_addr.addr.ether);
r = sd_lldp_set_filter_address(link->lldp, &link->hw_addr.ether);
if (r < 0)
return log_link_debug_errno(link, r, "Could not update MAC address for LLDP: %m");
}
+2 -2
View File
@@ -53,8 +53,8 @@ typedef struct Link {
char *kind;
unsigned short iftype;
char *state_file;
hw_addr_data hw_addr;
hw_addr_data bcast_addr;
struct hw_addr_data hw_addr;
struct hw_addr_data bcast_addr;
struct ether_addr permanent_mac;
struct in6_addr ipv6ll_address;
uint32_t mtu;
+1 -1
View File
@@ -95,7 +95,7 @@ int link_lldp_rx_configure(Link *link) {
if (r < 0)
return r;
r = sd_lldp_set_filter_address(link->lldp, &link->hw_addr.addr.ether);
r = sd_lldp_set_filter_address(link->lldp, &link->hw_addr.ether);
if (r < 0)
return r;
+1 -1
View File
@@ -314,7 +314,7 @@ static int link_send_lldp(Link *link) {
SD_LLDP_SYSTEM_CAPABILITIES_STATION;
r = lldp_make_packet(link->network->lldp_emit,
&link->hw_addr.addr.ether,
&link->hw_addr.ether,
sd_id128_to_string(machine_id, machine_id_string),
link->ifname,
(uint16_t) ttl,
+3 -3
View File
@@ -657,9 +657,9 @@ static int make_stableprivate_address(Link *link, const struct in6_addr *prefix,
siphash24_compress_string(link->ifname, &state);
/* Only last 8 bytes of IB MAC are stable */
if (link->iftype == ARPHRD_INFINIBAND)
siphash24_compress(&link->hw_addr.addr.infiniband[12], 8, &state);
siphash24_compress(&link->hw_addr.infiniband[12], 8, &state);
else
siphash24_compress(link->hw_addr.addr.bytes, link->hw_addr.length, &state);
siphash24_compress(link->hw_addr.bytes, link->hw_addr.length, &state);
siphash24_compress(&dad_counter, sizeof(uint8_t), &state);
rid = htole64(siphash24_finalize(&state));
@@ -1370,7 +1370,7 @@ int ndisc_configure(Link *link) {
if (r < 0)
return r;
r = sd_ndisc_set_mac(link->ndisc, &link->hw_addr.addr.ether);
r = sd_ndisc_set_mac(link->ndisc, &link->hw_addr.ether);
if (r < 0)
return r;
+1 -2
View File
@@ -16,7 +16,6 @@ static int property_get_ether_addrs(
void *userdata,
sd_bus_error *error) {
char buf[ETHER_ADDR_TO_STRING_MAX];
const struct ether_addr *p;
Set *s;
int r;
@@ -32,7 +31,7 @@ static int property_get_ether_addrs(
return r;
SET_FOREACH(p, s) {
r = sd_bus_message_append(reply, "s", ether_addr_to_string(p, buf));
r = sd_bus_message_append(reply, "s", ETHER_ADDR_TO_STR(p));
if (r < 0)
return r;
}
+2 -2
View File
@@ -694,7 +694,7 @@ int radv_configure(Link *link) {
if (r < 0)
return r;
r = sd_radv_set_mac(link->radv, &link->hw_addr.addr.ether);
r = sd_radv_set_mac(link->radv, &link->hw_addr.ether);
if (r < 0)
return r;
@@ -766,7 +766,7 @@ int radv_update_mac(Link *link) {
if (r < 0)
return r;
r = sd_radv_set_mac(link->radv, &link->hw_addr.addr.ether);
r = sd_radv_set_mac(link->radv, &link->hw_addr.ether);
if (r < 0)
return r;
+1 -3
View File
@@ -55,11 +55,9 @@ int wifi_get_info(Link *link) {
}
if (r > 0 || s > 0) {
char buf[ETHER_ADDR_TO_STRING_MAX];
if (link->wlan_iftype == NL80211_IFTYPE_STATION && link->ssid)
log_link_info(link, "Connected WiFi access point: %s (%s)",
link->ssid, ether_addr_to_string(&link->bssid, buf));
link->ssid, ETHER_ADDR_TO_STR(&link->bssid));
return 1; /* Some information is updated. */
}