diff --git a/src/basic/ether-addr-util.c b/src/basic/ether-addr-util.c index 9be4baf123..b97997e1bf 100644 --- a/src/basic/ether-addr-util.c +++ b/src/basic/ether-addr-util.c @@ -39,7 +39,7 @@ int hw_addr_compare(const struct hw_addr_data *a, const struct hw_addr_data *b) return memcmp(a->bytes, b->bytes, a->length); } -static void hw_addr_hash_func(const struct hw_addr_data *p, struct siphash *state) { +void hw_addr_hash_func(const struct hw_addr_data *p, struct siphash *state) { assert(p); assert(state); diff --git a/src/basic/ether-addr-util.h b/src/basic/ether-addr-util.h index ae6605fb11..b2a3f0d58c 100644 --- a/src/basic/ether-addr-util.h +++ b/src/basic/ether-addr-util.h @@ -41,6 +41,7 @@ char* hw_addr_to_string(const struct hw_addr_data *addr, char buffer[HW_ADDR_TO_ #define HW_ADDR_NULL ((const struct hw_addr_data){}) +void hw_addr_hash_func(const struct hw_addr_data *p, struct siphash *state); 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; diff --git a/src/libsystemd/sd-netlink/netlink-types-rtnl.c b/src/libsystemd/sd-netlink/netlink-types-rtnl.c index 85a6c79396..624422eea2 100644 --- a/src/libsystemd/sd-netlink/netlink-types-rtnl.c +++ b/src/libsystemd/sd-netlink/netlink-types-rtnl.c @@ -968,7 +968,7 @@ DEFINE_TYPE_SYSTEM(rtnl_route); static const NLType rtnl_neigh_types[] = { [NDA_DST] = { .type = NETLINK_TYPE_IN_ADDR }, - [NDA_LLADDR] = { /* struct ether_addr, struct in_addr, or struct in6_addr */ }, + [NDA_LLADDR] = { .type = NETLINK_TYPE_ETHER_ADDR }, [NDA_CACHEINFO] = { .type = NETLINK_TYPE_CACHE_INFO, .size = sizeof(struct nda_cacheinfo) }, [NDA_PROBES] = { .type = NETLINK_TYPE_U32 }, [NDA_VLAN] = { .type = NETLINK_TYPE_U16 }, diff --git a/src/network/networkd-neighbor.c b/src/network/networkd-neighbor.c index 2c0a7b0c7f..1766095e53 100644 --- a/src/network/networkd-neighbor.c +++ b/src/network/networkd-neighbor.c @@ -91,7 +91,6 @@ void neighbor_hash_func(const Neighbor *neighbor, struct siphash *state) { assert(neighbor); siphash24_compress(&neighbor->family, sizeof(neighbor->family), state); - siphash24_compress(&neighbor->lladdr_size, sizeof(neighbor->lladdr_size), state); switch (neighbor->family) { case AF_INET: @@ -104,7 +103,7 @@ void neighbor_hash_func(const Neighbor *neighbor, struct siphash *state) { break; } - siphash24_compress(&neighbor->lladdr, neighbor->lladdr_size, state); + hw_addr_hash_func(&neighbor->ll_addr, state); } int neighbor_compare_func(const Neighbor *a, const Neighbor *b) { @@ -114,10 +113,6 @@ int neighbor_compare_func(const Neighbor *a, const Neighbor *b) { if (r != 0) return r; - r = CMP(a->lladdr_size, b->lladdr_size); - if (r != 0) - return r; - switch (a->family) { case AF_INET: case AF_INET6: @@ -126,7 +121,7 @@ int neighbor_compare_func(const Neighbor *a, const Neighbor *b) { return r; } - return memcmp(&a->lladdr, &b->lladdr, a->lladdr_size); + return hw_addr_compare(&a->ll_addr, &b->ll_addr); } DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(neighbor_hash_ops, Neighbor, neighbor_hash_func, neighbor_compare_func, neighbor_free); @@ -163,7 +158,7 @@ static int neighbor_add(Link *link, Neighbor *neighbor) { } static void log_neighbor_debug(const Neighbor *neighbor, const char *str, const Link *link) { - _cleanup_free_ char *state = NULL, *lladdr = NULL, *dst = NULL; + _cleanup_free_ char *state = NULL, *dst = NULL; assert(neighbor); assert(str); @@ -172,19 +167,12 @@ static void log_neighbor_debug(const Neighbor *neighbor, const char *str, const return; (void) network_config_state_to_string_alloc(neighbor->state, &state); - if (neighbor->lladdr_size == sizeof(struct ether_addr)) - (void) ether_addr_to_string_alloc(&neighbor->lladdr.mac, &lladdr); - else if (neighbor->lladdr_size == sizeof(struct in_addr)) - (void) in_addr_to_string(AF_INET, &neighbor->lladdr.ip, &lladdr); - else if (neighbor->lladdr_size == sizeof(struct in6_addr)) - (void) in_addr_to_string(AF_INET6, &neighbor->lladdr.ip, &lladdr); - (void) in_addr_to_string(neighbor->family, &neighbor->in_addr, &dst); log_link_debug(link, "%s %s neighbor (%s): lladdr: %s, dst: %s", str, strna(network_config_source_to_string(neighbor->source)), strna(state), - strna(lladdr), strna(dst)); + HW_ADDR_TO_STR(&neighbor->ll_addr), strna(dst)); } static int neighbor_configure( @@ -213,7 +201,7 @@ static int neighbor_configure( if (r < 0) return log_link_error_errno(link, r, "Could not set state: %m"); - r = sd_netlink_message_append_data(req, NDA_LLADDR, &neighbor->lladdr, neighbor->lladdr_size); + r = netlink_message_append_hw_addr(req, NDA_LLADDR, &neighbor->ll_addr); if (r < 0) return log_link_error_errno(link, r, "Could not append NDA_LLADDR attribute: %m"); @@ -466,7 +454,6 @@ int request_process_neighbor(Request *req) { int manager_rtnl_process_neighbor(sd_netlink *rtnl, sd_netlink_message *message, Manager *m) { _cleanup_(neighbor_freep) Neighbor *tmp = NULL; - _cleanup_free_ void *lladdr = NULL; Neighbor *neighbor = NULL; uint16_t type, state; int ifindex, r; @@ -536,15 +523,11 @@ int manager_rtnl_process_neighbor(sd_netlink *rtnl, sd_netlink_message *message, return 0; } - r = sd_netlink_message_read_data(message, NDA_LLADDR, &tmp->lladdr_size, &lladdr); + r = netlink_message_read_hw_addr(message, NDA_LLADDR, &tmp->ll_addr); if (r < 0) { - log_link_warning_errno(link, r, "rtnl: received neighbor message without valid lladdr, ignoring: %m"); - return 0; - } else if (!IN_SET(tmp->lladdr_size, sizeof(struct ether_addr), sizeof(struct in_addr), sizeof(struct in6_addr))) { - log_link_warning(link, "rtnl: received neighbor message with invalid lladdr size (%zu), ignoring: %m", tmp->lladdr_size); + log_link_warning_errno(link, r, "rtnl: received neighbor message without valid link layer address, ignoring: %m"); return 0; } - memcpy(&tmp->lladdr, lladdr, tmp->lladdr_size); (void) neighbor_get(link, tmp, &neighbor); @@ -596,7 +579,7 @@ static int neighbor_section_verify(Neighbor *neighbor) { "Ignoring [Neighbor] section from line %u.", neighbor->section->filename, neighbor->section->line); - if (neighbor->lladdr_size == 0) + if (neighbor->ll_addr.length == 0) return log_warning_errno(SYNTHETIC_ERRNO(EINVAL), "%s: Neighbor section without LinkLayerAddress= configured. " "Ignoring [Neighbor] section from line %u.", @@ -628,20 +611,27 @@ int config_parse_neighbor_address( void *data, void *userdata) { - Network *network = userdata; _cleanup_(neighbor_free_or_set_invalidp) Neighbor *n = NULL; + Network *network = userdata; int r; assert(filename); assert(section); assert(lvalue); assert(rvalue); - assert(data); + assert(userdata); r = neighbor_new_static(network, filename, section_line, &n); if (r < 0) return log_oom(); + if (isempty(rvalue)) { + n->family = AF_UNSPEC; + n->in_addr = IN_ADDR_NULL; + TAKE_PTR(n); + return 0; + } + r = in_addr_from_string_auto(rvalue, &n->family, &n->in_addr); if (r < 0) { log_syntax(unit, LOG_WARNING, filename, line, r, @@ -650,7 +640,6 @@ int config_parse_neighbor_address( } TAKE_PTR(n); - return 0; } @@ -666,74 +655,34 @@ int config_parse_neighbor_lladdr( void *data, void *userdata) { - Network *network = userdata; _cleanup_(neighbor_free_or_set_invalidp) Neighbor *n = NULL; - int family, r; - - assert(filename); - assert(section); - assert(lvalue); - assert(rvalue); - assert(data); - - r = neighbor_new_static(network, filename, section_line, &n); - if (r < 0) - return log_oom(); - - r = parse_ether_addr(rvalue, &n->lladdr.mac); - if (r >= 0) - n->lladdr_size = sizeof(n->lladdr.mac); - else { - r = in_addr_from_string_auto(rvalue, &family, &n->lladdr.ip); - if (r < 0) { - log_syntax(unit, LOG_WARNING, filename, line, r, - "Neighbor LinkLayerAddress= is invalid, ignoring assignment: %s", - rvalue); - return 0; - } - n->lladdr_size = family == AF_INET ? sizeof(n->lladdr.ip.in) : sizeof(n->lladdr.ip.in6); - } - - TAKE_PTR(n); - - return 0; -} - -int config_parse_neighbor_hwaddr( - const char *unit, - const char *filename, - unsigned line, - const char *section, - unsigned section_line, - const char *lvalue, - int ltype, - const char *rvalue, - void *data, - void *userdata) { - Network *network = userdata; - _cleanup_(neighbor_free_or_set_invalidp) Neighbor *n = NULL; int r; assert(filename); assert(section); assert(lvalue); assert(rvalue); - assert(data); + assert(userdata); r = neighbor_new_static(network, filename, section_line, &n); if (r < 0) return log_oom(); - r = parse_ether_addr(rvalue, &n->lladdr.mac); - if (r < 0) { - log_syntax(unit, LOG_WARNING, filename, line, r, - "Neighbor MACAddress= is invalid, ignoring assignment: %s", rvalue); + if (isempty(rvalue)) { + n->ll_addr = HW_ADDR_NULL; + TAKE_PTR(n); return 0; } - n->lladdr_size = sizeof(n->lladdr.mac); - TAKE_PTR(n); + r = parse_hw_addr(rvalue, &n->ll_addr); + if (r < 0) { + log_syntax(unit, LOG_WARNING, filename, line, r, + "Neighbor %s= is invalid, ignoring assignment: %s", + lvalue, rvalue); + return 0; + } + TAKE_PTR(n); return 0; } diff --git a/src/network/networkd-neighbor.h b/src/network/networkd-neighbor.h index d4f2ff55f2..e9e1854110 100644 --- a/src/network/networkd-neighbor.h +++ b/src/network/networkd-neighbor.h @@ -15,11 +15,6 @@ typedef struct Manager Manager; typedef struct Network Network; typedef struct Request Request; -union lladdr_union { - struct ether_addr mac; - union in_addr_union ip; -}; - typedef struct Neighbor { Network *network; Link *link; @@ -29,8 +24,7 @@ typedef struct Neighbor { int family; union in_addr_union in_addr; - union lladdr_union lladdr; - size_t lladdr_size; + struct hw_addr_data ll_addr; } Neighbor; Neighbor *neighbor_free(Neighbor *neighbor); @@ -52,5 +46,4 @@ int manager_rtnl_process_neighbor(sd_netlink *rtnl, sd_netlink_message *message, DEFINE_NETWORK_CONFIG_STATE_FUNCTIONS(Neighbor, neighbor); CONFIG_PARSER_PROTOTYPE(config_parse_neighbor_address); -CONFIG_PARSER_PROTOTYPE(config_parse_neighbor_hwaddr); CONFIG_PARSER_PROTOTYPE(config_parse_neighbor_lladdr); diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index 7787a033fa..515a5b5bd9 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -156,7 +156,7 @@ IPv6AddressLabel.Prefix, config_parse_address_label_prefix, IPv6AddressLabel.Label, config_parse_address_label, 0, 0 Neighbor.Address, config_parse_neighbor_address, 0, 0 Neighbor.LinkLayerAddress, config_parse_neighbor_lladdr, 0, 0 -Neighbor.MACAddress, config_parse_neighbor_hwaddr, 0, 0 /* deprecated */ +Neighbor.MACAddress, config_parse_neighbor_lladdr, 0, 0 /* deprecated */ RoutingPolicyRule.TypeOfService, config_parse_routing_policy_rule_tos, 0, 0 RoutingPolicyRule.Priority, config_parse_routing_policy_rule_priority, 0, 0 RoutingPolicyRule.Table, config_parse_routing_policy_rule_table, 0, 0