diff --git a/src/libsystemd/sd-bus/bus-error.c b/src/libsystemd/sd-bus/bus-error.c index 5415aa76a3..5ef643134e 100644 --- a/src/libsystemd/sd-bus/bus-error.c +++ b/src/libsystemd/sd-bus/bus-error.c @@ -205,7 +205,7 @@ _public_ void sd_bus_error_free(sd_bus_error *e) { free((void*) e->message); } - *e = (sd_bus_error) {}; + *e = SD_BUS_ERROR_NULL; } _public_ int sd_bus_error_set(sd_bus_error *e, const char *name, const char *message) { diff --git a/src/network/netdev/bond.h b/src/network/netdev/bond.h index ce6e8cadef..99ef25d0d3 100644 --- a/src/network/netdev/bond.h +++ b/src/network/netdev/bond.h @@ -147,15 +147,15 @@ BondArpAllTargets bond_arp_all_targets_from_string(const char *d) _pure_; const char *bond_primary_reselect_to_string(BondPrimaryReselect d) _const_; BondPrimaryReselect bond_primary_reselect_from_string(const char *d) _pure_; -int config_parse_bond_mode(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); -int config_parse_bond_xmit_hash_policy(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); -int config_parse_bond_lacp_rate(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); -int config_parse_bond_ad_select(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); -int config_parse_bond_fail_over_mac(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); -int config_parse_bond_arp_validate(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); -int config_parse_bond_arp_all_targets(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); -int config_parse_bond_primary_reselect(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); -int config_parse_arp_ip_target_address(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); -int config_parse_ad_actor_sys_prio(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); -int config_parse_ad_user_port_key(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); -int config_parse_ad_actor_system(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); +CONFIG_PARSER_PROTOTYPE(config_parse_bond_mode); +CONFIG_PARSER_PROTOTYPE(config_parse_bond_xmit_hash_policy); +CONFIG_PARSER_PROTOTYPE(config_parse_bond_lacp_rate); +CONFIG_PARSER_PROTOTYPE(config_parse_bond_ad_select); +CONFIG_PARSER_PROTOTYPE(config_parse_bond_fail_over_mac); +CONFIG_PARSER_PROTOTYPE(config_parse_bond_arp_validate); +CONFIG_PARSER_PROTOTYPE(config_parse_bond_arp_all_targets); +CONFIG_PARSER_PROTOTYPE(config_parse_bond_primary_reselect); +CONFIG_PARSER_PROTOTYPE(config_parse_arp_ip_target_address); +CONFIG_PARSER_PROTOTYPE(config_parse_ad_actor_sys_prio); +CONFIG_PARSER_PROTOTYPE(config_parse_ad_user_port_key); +CONFIG_PARSER_PROTOTYPE(config_parse_ad_actor_system); diff --git a/src/network/netdev/fou-tunnel.h b/src/network/netdev/fou-tunnel.h index 28111fd157..9e4c1e9629 100644 --- a/src/network/netdev/fou-tunnel.h +++ b/src/network/netdev/fou-tunnel.h @@ -33,8 +33,4 @@ extern const NetDevVTable foutnl_vtable; const char *fou_encap_type_to_string(FooOverUDPEncapType d) _const_; FooOverUDPEncapType fou_encap_type_from_string(const char *d) _pure_; -int config_parse_fou_encap_type(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); +CONFIG_PARSER_PROTOTYPE(config_parse_fou_encap_type); diff --git a/src/network/netdev/geneve.h b/src/network/netdev/geneve.h index 2b38a92e4b..c201981e02 100644 --- a/src/network/netdev/geneve.h +++ b/src/network/netdev/geneve.h @@ -33,35 +33,6 @@ struct Geneve { DEFINE_NETDEV_CAST(GENEVE, Geneve); extern const NetDevVTable geneve_vtable; -int config_parse_geneve_vni(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); - -int config_parse_geneve_address(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); - -int config_parse_geneve_flow_label(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); +CONFIG_PARSER_PROTOTYPE(config_parse_geneve_vni); +CONFIG_PARSER_PROTOTYPE(config_parse_geneve_address); +CONFIG_PARSER_PROTOTYPE(config_parse_geneve_flow_label); diff --git a/src/network/netdev/ipvlan.h b/src/network/netdev/ipvlan.h index f181132720..b60587f2b6 100644 --- a/src/network/netdev/ipvlan.h +++ b/src/network/netdev/ipvlan.h @@ -38,5 +38,5 @@ IPVlanMode ipvlan_mode_from_string(const char *d) _pure_; const char *ipvlan_flags_to_string(IPVlanFlags d) _const_; IPVlanFlags ipvlan_flags_from_string(const char *d) _pure_; -int config_parse_ipvlan_mode(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); -int config_parse_ipvlan_flags(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); +CONFIG_PARSER_PROTOTYPE(config_parse_ipvlan_mode); +CONFIG_PARSER_PROTOTYPE(config_parse_ipvlan_flags); diff --git a/src/network/netdev/macvlan.h b/src/network/netdev/macvlan.h index 6b1587d86f..b473f1e19f 100644 --- a/src/network/netdev/macvlan.h +++ b/src/network/netdev/macvlan.h @@ -28,4 +28,4 @@ extern const NetDevVTable macvtap_vtable; const char *macvlan_mode_to_string(MacVlanMode d) _const_; MacVlanMode macvlan_mode_from_string(const char *d) _pure_; -int config_parse_macvlan_mode(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); +CONFIG_PARSER_PROTOTYPE(config_parse_macvlan_mode); diff --git a/src/network/netdev/netdev.c b/src/network/netdev/netdev.c index f9a2246d08..53149636ea 100644 --- a/src/network/netdev/netdev.c +++ b/src/network/netdev/netdev.c @@ -356,12 +356,14 @@ static int netdev_enslave(NetDev *netdev, Link *link, sd_netlink_message_handler /* the netdev is not yet read, save this request for when it is */ netdev_join_callback *cb; - cb = new0(netdev_join_callback, 1); + cb = new(netdev_join_callback, 1); if (!cb) return log_oom(); - cb->callback = callback; - cb->link = link_ref(link); + *cb = (netdev_join_callback) { + .callback = callback, + .link = link_ref(link), + }; LIST_PREPEND(callbacks, netdev->callbacks, cb); @@ -651,13 +653,15 @@ int netdev_load_one(Manager *manager, const char *filename) { return 0; } - netdev_raw = new0(NetDev, 1); + netdev_raw = new(NetDev, 1); if (!netdev_raw) return log_oom(); - netdev_raw->n_ref = 1; - netdev_raw->kind = _NETDEV_KIND_INVALID; - netdev_raw->state = _NETDEV_STATE_INVALID; /* an invalid state means done() of the implementation won't be called on destruction */ + *netdev_raw = (NetDev) { + .n_ref = 1, + .kind = _NETDEV_KIND_INVALID, + .state = _NETDEV_STATE_INVALID, /* an invalid state means done() of the implementation won't be called on destruction */ + }; dropin_dirname = strjoina(basename(filename), ".d"); r = config_parse_many(filename, network_dirs, dropin_dirname, @@ -725,6 +729,10 @@ int netdev_load_one(Manager *manager, const char *filename) { return log_error_errno(r, "Failed to generate predictable MAC address for %s: %m", netdev->ifname); } + r = hashmap_ensure_allocated(&netdev->manager->netdevs, &string_hash_ops); + if (r < 0) + return r; + r = hashmap_put(netdev->manager->netdevs, netdev->ifname, netdev); if (r < 0) return r; @@ -790,14 +798,12 @@ int netdev_load_one(Manager *manager, const char *filename) { int netdev_load(Manager *manager) { _cleanup_strv_free_ char **files = NULL; - NetDev *netdev; char **f; int r; assert(manager); - while ((netdev = hashmap_first(manager->netdevs))) - netdev_unref(netdev); + hashmap_clear_with_destructor(manager->netdevs, netdev_unref); r = conf_files_list_strv(&files, ".netdev", NULL, 0, network_dirs); if (r < 0) diff --git a/src/network/netdev/netdev.h b/src/network/netdev/netdev.h index a1557bec41..6597897d2f 100644 --- a/src/network/netdev/netdev.h +++ b/src/network/netdev/netdev.h @@ -3,6 +3,7 @@ #include "sd-netlink.h" +#include "conf-parser.h" #include "list.h" #include "time-util.h" @@ -162,7 +163,7 @@ int netdev_join(NetDev *netdev, Link *link, sd_netlink_message_handler_t cb); const char *netdev_kind_to_string(NetDevKind d) _const_; NetDevKind netdev_kind_from_string(const char *d) _pure_; -int config_parse_netdev_kind(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); +CONFIG_PARSER_PROTOTYPE(config_parse_netdev_kind); /* gperf */ const struct ConfigPerfItem* network_netdev_gperf_lookup(const char *key, GPERF_LEN_TYPE length); diff --git a/src/network/netdev/tunnel.h b/src/network/netdev/tunnel.h index 24721e87cd..be73c513cc 100644 --- a/src/network/netdev/tunnel.h +++ b/src/network/netdev/tunnel.h @@ -78,39 +78,9 @@ extern const NetDevVTable ip6tnl_vtable; const char *ip6tnl_mode_to_string(Ip6TnlMode d) _const_; Ip6TnlMode ip6tnl_mode_from_string(const char *d) _pure_; -int config_parse_ip6tnl_mode(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); - -int config_parse_tunnel_address(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); - -int config_parse_ipv6_flowlabel(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); - -int config_parse_encap_limit(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); - -int config_parse_tunnel_key(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); - +CONFIG_PARSER_PROTOTYPE(config_parse_ip6tnl_mode); +CONFIG_PARSER_PROTOTYPE(config_parse_tunnel_address); +CONFIG_PARSER_PROTOTYPE(config_parse_ipv6_flowlabel); +CONFIG_PARSER_PROTOTYPE(config_parse_encap_limit); +CONFIG_PARSER_PROTOTYPE(config_parse_tunnel_key); CONFIG_PARSER_PROTOTYPE(config_parse_6rd_prefix); diff --git a/src/network/netdev/vxlan.h b/src/network/netdev/vxlan.h index bb5c4b9c51..3b273e97bd 100644 --- a/src/network/netdev/vxlan.h +++ b/src/network/netdev/vxlan.h @@ -47,34 +47,6 @@ struct VxLan { DEFINE_NETDEV_CAST(VXLAN, VxLan); extern const NetDevVTable vxlan_vtable; -int config_parse_vxlan_address(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); -int config_parse_port_range(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); - -int config_parse_flow_label(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); +CONFIG_PARSER_PROTOTYPE(config_parse_vxlan_address); +CONFIG_PARSER_PROTOTYPE(config_parse_port_range); +CONFIG_PARSER_PROTOTYPE(config_parse_flow_label); diff --git a/src/network/netdev/wireguard.h b/src/network/netdev/wireguard.h index 70690ee2b8..143e93cdc5 100644 --- a/src/network/netdev/wireguard.h +++ b/src/network/netdev/wireguard.h @@ -63,11 +63,11 @@ struct Wireguard { DEFINE_NETDEV_CAST(WIREGUARD, Wireguard); extern const NetDevVTable wireguard_vtable; -int config_parse_wireguard_allowed_ips(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); -int config_parse_wireguard_endpoint(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); -int config_parse_wireguard_listen_port(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); +CONFIG_PARSER_PROTOTYPE(config_parse_wireguard_allowed_ips); +CONFIG_PARSER_PROTOTYPE(config_parse_wireguard_endpoint); +CONFIG_PARSER_PROTOTYPE(config_parse_wireguard_listen_port); -int config_parse_wireguard_public_key(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); -int config_parse_wireguard_private_key(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); -int config_parse_wireguard_preshared_key(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); -int config_parse_wireguard_keepalive(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); +CONFIG_PARSER_PROTOTYPE(config_parse_wireguard_public_key); +CONFIG_PARSER_PROTOTYPE(config_parse_wireguard_private_key); +CONFIG_PARSER_PROTOTYPE(config_parse_wireguard_preshared_key); +CONFIG_PARSER_PROTOTYPE(config_parse_wireguard_keepalive); diff --git a/src/network/networkd-address-label.c b/src/network/networkd-address-label.c index 98e40d3f6a..691bbf4761 100644 --- a/src/network/networkd-address-label.c +++ b/src/network/networkd-address-label.c @@ -11,18 +11,6 @@ #include "parse-util.h" #include "socket-util.h" -int address_label_new(AddressLabel **ret) { - _cleanup_(address_label_freep) AddressLabel *addrlabel = NULL; - - addrlabel = new0(AddressLabel, 1); - if (!addrlabel) - return -ENOMEM; - - *ret = TAKE_PTR(addrlabel); - - return 0; -} - void address_label_free(AddressLabel *label) { if (!label) return; @@ -50,31 +38,42 @@ static int address_label_new_static(Network *network, const char *filename, unsi assert(ret); assert(!!filename == (section_line > 0)); - r = network_config_section_new(filename, section_line, &n); - if (r < 0) - return r; + if (filename) { + r = network_config_section_new(filename, section_line, &n); + if (r < 0) + return r; - label = hashmap_get(network->address_labels_by_section, n); - if (label) { - *ret = TAKE_PTR(label); + label = hashmap_get(network->address_labels_by_section, n); + if (label) { + *ret = TAKE_PTR(label); - return 0; + return 0; + } } - r = address_label_new(&label); - if (r < 0) - return r; + label = new(AddressLabel, 1); + if (!label) + return -ENOMEM; - label->section = TAKE_PTR(n); + *label = (AddressLabel) { + .network = network, + }; - r = hashmap_put(network->address_labels_by_section, label->section, label); - if (r < 0) - return r; - - label->network = network; LIST_APPEND(labels, network->address_labels, label); network->n_address_labels++; + if (filename) { + label->section = TAKE_PTR(n); + + r = hashmap_ensure_allocated(&network->address_labels_by_section, &network_config_hash_ops); + if (r < 0) + return r; + + r = hashmap_put(network->address_labels_by_section, label->section, label); + if (r < 0) + return r; + } + *ret = TAKE_PTR(label); return 0; diff --git a/src/network/networkd-address-label.h b/src/network/networkd-address-label.h index 2e55feabd0..da506b2de4 100644 --- a/src/network/networkd-address-label.h +++ b/src/network/networkd-address-label.h @@ -28,7 +28,6 @@ struct AddressLabel { LIST_FIELDS(AddressLabel, labels); }; -int address_label_new(AddressLabel **ret); void address_label_free(AddressLabel *label); DEFINE_TRIVIAL_CLEANUP_FUNC(AddressLabel*, address_label_free); diff --git a/src/network/networkd-address-pool.c b/src/network/networkd-address-pool.c index 2e35f77093..1650515064 100644 --- a/src/network/networkd-address-pool.c +++ b/src/network/networkd-address-pool.c @@ -19,14 +19,16 @@ int address_pool_new( assert(ret); assert(u); - p = new0(AddressPool, 1); + p = new(AddressPool, 1); if (!p) return -ENOMEM; - p->manager = m; - p->family = family; - p->prefixlen = prefixlen; - p->in_addr = *u; + *p = (AddressPool) { + .manager = m, + .family = family, + .prefixlen = prefixlen, + .in_addr = *u, + }; LIST_PREPEND(address_pools, m->address_pools, p); diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c index 1f722aca52..09f041602c 100644 --- a/src/network/networkd-address.c +++ b/src/network/networkd-address.c @@ -22,14 +22,16 @@ int address_new(Address **ret) { _cleanup_(address_freep) Address *address = NULL; - address = new0(Address, 1); + address = new(Address, 1); if (!address) return -ENOMEM; - address->family = AF_UNSPEC; - address->scope = RT_SCOPE_UNIVERSE; - address->cinfo.ifa_prefered = CACHE_INFO_INFINITY_LIFE_TIME; - address->cinfo.ifa_valid = CACHE_INFO_INFINITY_LIFE_TIME; + *address = (Address) { + .family = AF_UNSPEC, + .scope = RT_SCOPE_UNIVERSE, + .cinfo.ifa_prefered = CACHE_INFO_INFINITY_LIFE_TIME, + .cinfo.ifa_valid = CACHE_INFO_INFINITY_LIFE_TIME, + }; *ret = TAKE_PTR(address); @@ -65,18 +67,22 @@ int address_new_static(Network *network, const char *filename, unsigned section_ if (r < 0) return r; + address->network = network; + LIST_APPEND(addresses, network->static_addresses, address); + network->n_static_addresses++; + if (filename) { address->section = TAKE_PTR(n); + r = hashmap_ensure_allocated(&network->addresses_by_section, &network_config_hash_ops); + if (r < 0) + return r; + r = hashmap_put(network->addresses_by_section, address->section, address); if (r < 0) return r; } - address->network = network; - LIST_APPEND(addresses, network->static_addresses, address); - network->n_static_addresses++; - *ret = TAKE_PTR(address); return 0; diff --git a/src/network/networkd-fdb.c b/src/network/networkd-fdb.c index aa0c4c800f..c7742a93fb 100644 --- a/src/network/networkd-fdb.c +++ b/src/network/networkd-fdb.c @@ -20,18 +20,26 @@ /* create a new FDB entry or get an existing one. */ int fdb_entry_new_static( Network *network, - unsigned section, + const char *filename, + unsigned section_line, FdbEntry **ret) { + _cleanup_(network_config_section_freep) NetworkConfigSection *n = NULL; _cleanup_(fdb_entry_freep) FdbEntry *fdb_entry = NULL; - struct ether_addr *mac_addr = NULL; + _cleanup_free_ struct ether_addr *mac_addr = NULL; + int r; assert(network); assert(ret); + assert(!!filename == (section_line > 0)); /* search entry in hashmap first. */ - if (section) { - fdb_entry = hashmap_get(network->fdb_entries_by_section, UINT_TO_PTR(section)); + if (filename) { + r = network_config_section_new(filename, section_line, &n); + if (r < 0) + return r; + + fdb_entry = hashmap_get(network->fdb_entries_by_section, n); if (fdb_entry) { *ret = TAKE_PTR(fdb_entry); @@ -48,24 +56,29 @@ int fdb_entry_new_static( return -ENOMEM; /* allocate space for and FDB entry. */ - fdb_entry = new0(FdbEntry, 1); - if (!fdb_entry) { - /* free previously allocated space for mac_addr. */ - free(mac_addr); + fdb_entry = new(FdbEntry, 1); + if (!fdb_entry) return -ENOMEM; - } /* init FDB structure. */ - fdb_entry->network = network; - fdb_entry->mac_addr = mac_addr; + *fdb_entry = (FdbEntry) { + .network = network, + .mac_addr = TAKE_PTR(mac_addr), + }; LIST_PREPEND(static_fdb_entries, network->static_fdb_entries, fdb_entry); network->n_static_fdb_entries++; - if (section) { - fdb_entry->section = section; - hashmap_put(network->fdb_entries_by_section, - UINT_TO_PTR(fdb_entry->section), fdb_entry); + if (filename) { + fdb_entry->section = TAKE_PTR(n); + + r = hashmap_ensure_allocated(&network->fdb_entries_by_section, &network_config_hash_ops); + if (r < 0) + return r; + + r = hashmap_put(network->fdb_entries_by_section, fdb_entry->section, fdb_entry); + if (r < 0) + return r; } /* return allocated FDB structure. */ @@ -151,16 +164,15 @@ void fdb_entry_free(FdbEntry *fdb_entry) { if (fdb_entry->network) { LIST_REMOVE(static_fdb_entries, fdb_entry->network->static_fdb_entries, fdb_entry); - assert(fdb_entry->network->n_static_fdb_entries > 0); fdb_entry->network->n_static_fdb_entries--; if (fdb_entry->section) - hashmap_remove(fdb_entry->network->fdb_entries_by_section, UINT_TO_PTR(fdb_entry->section)); + hashmap_remove(fdb_entry->network->fdb_entries_by_section, fdb_entry->section); } + network_config_section_free(fdb_entry->section); free(fdb_entry->mac_addr); - free(fdb_entry); } @@ -187,7 +199,7 @@ int config_parse_fdb_hwaddr( assert(rvalue); assert(data); - r = fdb_entry_new_static(network, section_line, &fdb_entry); + r = fdb_entry_new_static(network, filename, section_line, &fdb_entry); if (r < 0) return log_oom(); @@ -233,7 +245,7 @@ int config_parse_fdb_vlan_id( assert(rvalue); assert(data); - r = fdb_entry_new_static(network, section_line, &fdb_entry); + r = fdb_entry_new_static(network, filename, section_line, &fdb_entry); if (r < 0) return log_oom(); diff --git a/src/network/networkd-fdb.h b/src/network/networkd-fdb.h index ac0d131a99..55fc3a2170 100644 --- a/src/network/networkd-fdb.h +++ b/src/network/networkd-fdb.h @@ -12,10 +12,11 @@ typedef struct Network Network; typedef struct FdbEntry FdbEntry; typedef struct Link Link; +typedef struct NetworkConfigSection NetworkConfigSection; struct FdbEntry { Network *network; - unsigned section; + NetworkConfigSection *section; struct ether_addr *mac_addr; uint16_t vlan_id; @@ -23,7 +24,7 @@ struct FdbEntry { LIST_FIELDS(FdbEntry, static_fdb_entries); }; -int fdb_entry_new_static(Network *network, unsigned section, FdbEntry **ret); +int fdb_entry_new_static(Network *network, const char *filename, unsigned section_line, FdbEntry **ret); void fdb_entry_free(FdbEntry *fdb_entry); int fdb_entry_configure(Link *link, FdbEntry *fdb_entry); diff --git a/src/network/networkd-ipv6-proxy-ndp.c b/src/network/networkd-ipv6-proxy-ndp.c index 6286b37deb..8d58406c34 100644 --- a/src/network/networkd-ipv6-proxy-ndp.c +++ b/src/network/networkd-ipv6-proxy-ndp.c @@ -57,17 +57,18 @@ int ipv6_proxy_ndp_address_new_static(Network *network, IPv6ProxyNDPAddress **re assert(ret); /* allocate space for IPv6ProxyNDPAddress entry */ - ipv6_proxy_ndp_address = new0(IPv6ProxyNDPAddress, 1); + ipv6_proxy_ndp_address = new(IPv6ProxyNDPAddress, 1); if (!ipv6_proxy_ndp_address) return -ENOMEM; - ipv6_proxy_ndp_address->network = network; + *ipv6_proxy_ndp_address = (IPv6ProxyNDPAddress) { + .network = network, + }; LIST_PREPEND(ipv6_proxy_ndp_addresses, network->ipv6_proxy_ndp_addresses, ipv6_proxy_ndp_address); network->n_ipv6_proxy_ndp_addresses++; - *ret = ipv6_proxy_ndp_address; - ipv6_proxy_ndp_address = NULL; + *ret = TAKE_PTR(ipv6_proxy_ndp_address); return 0; } diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 1b233507e7..1ccaf0e15b 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -449,16 +449,19 @@ static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) { if (r < 0) return r; - link = new0(Link, 1); + link = new(Link, 1); if (!link) return -ENOMEM; - link->n_ref = 1; - link->manager = manager; - link->state = LINK_STATE_PENDING; - link->rtnl_extended_attrs = true; - link->ifindex = ifindex; - link->iftype = iftype; + *link = (Link) { + .n_ref = 1, + .manager = manager, + .state = LINK_STATE_PENDING, + .rtnl_extended_attrs = true, + .ifindex = ifindex, + .iftype = iftype, + }; + link->ifname = strdup(ifname); if (!link->ifname) return -ENOMEM; diff --git a/src/network/networkd-lldp-tx.h b/src/network/networkd-lldp-tx.h index 860065cc6d..6842804a7e 100644 --- a/src/network/networkd-lldp-tx.h +++ b/src/network/networkd-lldp-tx.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ #pragma once +#include "conf-parser.h" #include "networkd-link.h" typedef enum LLDPEmit { @@ -14,4 +15,4 @@ typedef enum LLDPEmit { int link_lldp_emit_start(Link *link); void link_lldp_emit_stop(Link *link); -int config_parse_lldp_emit(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); +CONFIG_PARSER_PROTOTYPE(config_parse_lldp_emit); diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c index 2b5fc3a50b..fe481f1c02 100644 --- a/src/network/networkd-manager.c +++ b/src/network/networkd-manager.c @@ -1198,25 +1198,21 @@ static int manager_dirty_handler(sd_event_source *s, void *userdata) { Manager *m = userdata; Link *link; Iterator i; - int r; assert(m); if (m->dirty) manager_save(m); - SET_FOREACH(link, m->dirty_links, i) { - r = link_save(link); - if (r >= 0) + SET_FOREACH(link, m->dirty_links, i) + if (link_save(link) >= 0) link_clean(link); - } return 1; } Link *manager_dhcp6_prefix_get(Manager *m, struct in6_addr *addr) { assert_return(m, NULL); - assert_return(m->dhcp6_prefixes, NULL); assert_return(addr, NULL); return hashmap_get(m->dhcp6_prefixes, addr); @@ -1235,13 +1231,31 @@ static int dhcp6_route_add_handler(sd_netlink *nl, sd_netlink_message *m, void * return 0; } +static void dhcp6_prefixes_hash_func(const void *p, struct siphash *state) { + const struct in6_addr *addr = p; + + assert(p); + + siphash24_compress(addr, sizeof(*addr), state); +} + +static int dhcp6_prefixes_compare_func(const void *_a, const void *_b) { + const struct in6_addr *a = _a, *b = _b; + + return memcmp(a, b, sizeof(*a)); +} + +static const struct hash_ops dhcp6_prefixes_hash_ops = { + .hash = dhcp6_prefixes_hash_func, + .compare = dhcp6_prefixes_compare_func, +}; + int manager_dhcp6_prefix_add(Manager *m, struct in6_addr *addr, Link *link) { - int r; - Route *route; _cleanup_free_ char *buf = NULL; + Route *route; + int r; assert_return(m, -EINVAL); - assert_return(m->dhcp6_prefixes, -ENODATA); assert_return(addr, -EINVAL); r = route_add(link, AF_INET6, (union in_addr_union *) addr, 64, @@ -1256,6 +1270,10 @@ int manager_dhcp6_prefix_add(Manager *m, struct in6_addr *addr, Link *link) { (void) in_addr_to_string(AF_INET6, (union in_addr_union *) addr, &buf); log_link_debug(link, "Adding prefix route %s/64", strnull(buf)); + r = hashmap_ensure_allocated(&m->dhcp6_prefixes, &dhcp6_prefixes_hash_ops); + if (r < 0) + return r; + return hashmap_put(m->dhcp6_prefixes, addr, link); } @@ -1273,13 +1291,12 @@ static int dhcp6_route_remove_handler(sd_netlink *nl, sd_netlink_message *m, voi } static int manager_dhcp6_prefix_remove(Manager *m, struct in6_addr *addr) { + _cleanup_free_ char *buf = NULL; + Route *route; Link *l; int r; - Route *route; - _cleanup_free_ char *buf = NULL; assert_return(m, -EINVAL); - assert_return(m->dhcp6_prefixes, -ENODATA); assert_return(addr, -EINVAL); l = hashmap_remove(m->dhcp6_prefixes, addr); @@ -1303,9 +1320,9 @@ static int manager_dhcp6_prefix_remove(Manager *m, struct in6_addr *addr) { } int manager_dhcp6_prefix_remove_all(Manager *m, Link *link) { + struct in6_addr *addr; Iterator i; Link *l; - struct in6_addr *addr; assert_return(m, -EINVAL); assert_return(link, -EINVAL); @@ -1320,25 +1337,6 @@ int manager_dhcp6_prefix_remove_all(Manager *m, Link *link) { return 0; } -static void dhcp6_prefixes_hash_func(const void *p, struct siphash *state) { - const struct in6_addr *addr = p; - - assert(p); - - siphash24_compress(addr, sizeof(*addr), state); -} - -static int dhcp6_prefixes_compare_func(const void *_a, const void *_b) { - const struct in6_addr *a = _a, *b = _b; - - return memcmp(a, b, sizeof(*a)); -} - -static const struct hash_ops dhcp6_prefixes_hash_ops = { - .hash = dhcp6_prefixes_hash_func, - .compare = dhcp6_prefixes_compare_func, -}; - int manager_new(Manager **ret) { _cleanup_(manager_freep) Manager *m = NULL; int r; @@ -1375,10 +1373,6 @@ int manager_new(Manager **ret) { if (r < 0) return r; - m->netdevs = hashmap_new(&string_hash_ops); - if (!m->netdevs) - return -ENOMEM; - LIST_HEAD_INIT(m->networks); r = sd_resolve_default(&m->resolve); @@ -1393,10 +1387,6 @@ int manager_new(Manager **ret) { if (r < 0) return r; - m->dhcp6_prefixes = hashmap_new(&dhcp6_prefixes_hash_ops); - if (!m->dhcp6_prefixes) - return -ENOMEM; - m->duid.type = DUID_TYPE_EN; (void) routing_policy_load_rules(m->state_file, &m->rules_saved); @@ -1427,13 +1417,9 @@ void manager_free(Manager *m) { manager_dhcp6_prefix_remove_all(m, link); hashmap_free(m->dhcp6_prefixes); - while ((link = hashmap_first(m->links))) { + while ((link = hashmap_steal_first(m->links))) { if (link->dhcp6_client) - (void) dhcp6_lease_pd_prefix_lost(link->dhcp6_client, - link); - - hashmap_remove(m->links, INT_TO_PTR(link->ifindex)); - + (void) dhcp6_lease_pd_prefix_lost(link->dhcp6_client, link); link_unref(link); } diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c index 855eb8c054..8596db11c7 100644 --- a/src/network/networkd-ndisc.c +++ b/src/network/networkd-ndisc.c @@ -37,7 +37,7 @@ static int ndisc_route_handler(sd_netlink *rtnl, sd_netlink_message *m, void *us return 1; } -static void ndisc_router_process_default(Link *link, sd_ndisc_router *rt) { +static int ndisc_router_process_default(Link *link, sd_ndisc_router *rt) { _cleanup_(route_freep) Route *route = NULL; struct in6_addr gateway; uint16_t lifetime; @@ -52,70 +52,55 @@ static void ndisc_router_process_default(Link *link, sd_ndisc_router *rt) { assert(rt); r = sd_ndisc_router_get_lifetime(rt, &lifetime); - if (r < 0) { - log_link_warning_errno(link, r, "Failed to get gateway address from RA: %m"); - return; - } + if (r < 0) + return log_link_warning_errno(link, r, "Failed to get gateway address from RA: %m"); + if (lifetime == 0) /* not a default router */ - return; + return 0; r = sd_ndisc_router_get_address(rt, &gateway); - if (r < 0) { - log_link_warning_errno(link, r, "Failed to get gateway address from RA: %m"); - return; - } + if (r < 0) + return log_link_warning_errno(link, r, "Failed to get gateway address from RA: %m"); - SET_FOREACH(address, link->addresses, i) { - if (!memcmp(&gateway, &address->in_addr.in6, - sizeof(address->in_addr.in6))) { + SET_FOREACH(address, link->addresses, i) + if (!memcmp(&gateway, &address->in_addr.in6, sizeof(address->in_addr.in6))) { char buffer[INET6_ADDRSTRLEN]; log_link_debug(link, "No NDisc route added, gateway %s matches local address", inet_ntop(AF_INET6, &address->in_addr.in6, buffer, sizeof(buffer))); - return; + return 0; } - } - SET_FOREACH(address, link->addresses_foreign, i) { - if (!memcmp(&gateway, &address->in_addr.in6, - sizeof(address->in_addr.in6))) { + SET_FOREACH(address, link->addresses_foreign, i) + if (!memcmp(&gateway, &address->in_addr.in6, sizeof(address->in_addr.in6))) { char buffer[INET6_ADDRSTRLEN]; log_link_debug(link, "No NDisc route added, gateway %s matches local address", inet_ntop(AF_INET6, &address->in_addr.in6, buffer, sizeof(buffer))); - return; + return 0; } - } r = sd_ndisc_router_get_preference(rt, &preference); - if (r < 0) { - log_link_warning_errno(link, r, "Failed to get default router preference from RA: %m"); - return; - } + if (r < 0) + return log_link_warning_errno(link, r, "Failed to get default router preference from RA: %m"); r = sd_ndisc_router_get_timestamp(rt, clock_boottime_or_monotonic(), &time_now); - if (r < 0) { - log_link_warning_errno(link, r, "Failed to get RA timestamp: %m"); - return; - } + if (r < 0) + return log_link_warning_errno(link, r, "Failed to get RA timestamp: %m"); r = sd_ndisc_router_get_mtu(rt, &mtu); if (r == -ENODATA) mtu = 0; - else if (r < 0) { - log_link_warning_errno(link, r, "Failed to get default router MTU from RA: %m"); - return; - } + else if (r < 0) + return log_link_warning_errno(link, r, "Failed to get default router MTU from RA: %m"); r = route_new(&route); - if (r < 0) { - log_link_error_errno(link, r, "Could not allocate route: %m"); - return; - } + if (r < 0) + return log_link_error_errno(link, r, "Could not allocate route: %m"); route->family = AF_INET6; route->table = link->network->ipv6_accept_ra_route_table; @@ -130,13 +115,15 @@ static void ndisc_router_process_default(Link *link, sd_ndisc_router *rt) { if (r < 0) { log_link_warning_errno(link, r, "Could not set default route: %m"); link_enter_failed(link); - return; + return r; } link->ndisc_messages++; + + return 0; } -static void ndisc_router_process_autonomous_prefix(Link *link, sd_ndisc_router *rt) { +static int ndisc_router_process_autonomous_prefix(Link *link, sd_ndisc_router *rt) { _cleanup_(address_freep) Address *address = NULL; Address *existing_address; uint32_t lifetime_valid, lifetime_preferred, lifetime_remaining; @@ -148,45 +135,33 @@ static void ndisc_router_process_autonomous_prefix(Link *link, sd_ndisc_router * assert(rt); r = sd_ndisc_router_get_timestamp(rt, clock_boottime_or_monotonic(), &time_now); - if (r < 0) { - log_link_warning_errno(link, r, "Failed to get RA timestamp: %m"); - return; - } + if (r < 0) + return log_link_warning_errno(link, r, "Failed to get RA timestamp: %m"); r = sd_ndisc_router_prefix_get_prefixlen(rt, &prefixlen); - if (r < 0) { - log_link_error_errno(link, r, "Failed to get prefix length: %m"); - return; - } + if (r < 0) + return log_link_error_errno(link, r, "Failed to get prefix length: %m"); r = sd_ndisc_router_prefix_get_valid_lifetime(rt, &lifetime_valid); - if (r < 0) { - log_link_error_errno(link, r, "Failed to get prefix valid lifetime: %m"); - return; - } + if (r < 0) + return log_link_error_errno(link, r, "Failed to get prefix valid lifetime: %m"); r = sd_ndisc_router_prefix_get_preferred_lifetime(rt, &lifetime_preferred); - if (r < 0) { - log_link_error_errno(link, r, "Failed to get prefix preferred lifetime: %m"); - return; - } + if (r < 0) + return log_link_error_errno(link, r, "Failed to get prefix preferred lifetime: %m"); /* The preferred lifetime is never greater than the valid lifetime */ if (lifetime_preferred > lifetime_valid) - return; + return 0; r = address_new(&address); - if (r < 0) { - log_link_error_errno(link, r, "Could not allocate address: %m"); - return; - } + if (r < 0) + return log_link_error_errno(link, r, "Could not allocate address: %m"); address->family = AF_INET6; r = sd_ndisc_router_prefix_get_address(rt, &address->in_addr.in6); - if (r < 0) { - log_link_error_errno(link, r, "Failed to get prefix address: %m"); - return; - } + if (r < 0) + return log_link_error_errno(link, r, "Failed to get prefix address: %m"); if (in_addr_is_null(AF_INET6, (const union in_addr_union *) &link->network->ipv6_token) == 0) memcpy(((char *)&address->in_addr.in6) + 8, ((char *)&link->network->ipv6_token) + 8, 8); @@ -219,22 +194,24 @@ static void ndisc_router_process_autonomous_prefix(Link *link, sd_ndisc_router * } else if (lifetime_valid > 0) address->cinfo.ifa_valid = lifetime_valid; else - return; /* see RFC4862 section 5.5.3.d */ + return 0; /* see RFC4862 section 5.5.3.d */ if (address->cinfo.ifa_valid == 0) - return; + return 0; r = address_configure(address, link, ndisc_route_handler, true); if (r < 0) { log_link_warning_errno(link, r, "Could not set SLAAC address: %m"); link_enter_failed(link); - return; + return r; } link->ndisc_messages++; + + return 0; } -static void ndisc_router_process_onlink_prefix(Link *link, sd_ndisc_router *rt) { +static int ndisc_router_process_onlink_prefix(Link *link, sd_ndisc_router *rt) { _cleanup_(route_freep) Route *route = NULL; usec_t time_now; uint32_t lifetime; @@ -245,28 +222,20 @@ static void ndisc_router_process_onlink_prefix(Link *link, sd_ndisc_router *rt) assert(rt); r = sd_ndisc_router_get_timestamp(rt, clock_boottime_or_monotonic(), &time_now); - if (r < 0) { - log_link_warning_errno(link, r, "Failed to get RA timestamp: %m"); - return; - } + if (r < 0) + return log_link_warning_errno(link, r, "Failed to get RA timestamp: %m"); r = sd_ndisc_router_prefix_get_prefixlen(rt, &prefixlen); - if (r < 0) { - log_link_error_errno(link, r, "Failed to get prefix length: %m"); - return; - } + if (r < 0) + return log_link_error_errno(link, r, "Failed to get prefix length: %m"); r = sd_ndisc_router_prefix_get_valid_lifetime(rt, &lifetime); - if (r < 0) { - log_link_error_errno(link, r, "Failed to get prefix lifetime: %m"); - return; - } + if (r < 0) + return log_link_error_errno(link, r, "Failed to get prefix lifetime: %m"); r = route_new(&route); - if (r < 0) { - log_link_error_errno(link, r, "Could not allocate route: %m"); - return; - } + if (r < 0) + return log_link_error_errno(link, r, "Could not allocate route: %m"); route->family = AF_INET6; route->table = link->network->ipv6_accept_ra_route_table; @@ -277,22 +246,22 @@ static void ndisc_router_process_onlink_prefix(Link *link, sd_ndisc_router *rt) route->lifetime = time_now + lifetime * USEC_PER_SEC; r = sd_ndisc_router_prefix_get_address(rt, &route->dst.in6); - if (r < 0) { - log_link_error_errno(link, r, "Failed to get prefix address: %m"); - return; - } + if (r < 0) + return log_link_error_errno(link, r, "Failed to get prefix address: %m"); r = route_configure(route, link, ndisc_route_handler); if (r < 0) { log_link_warning_errno(link, r, "Could not set prefix route: %m"); link_enter_failed(link); - return; + return r; } link->ndisc_messages++; + + return 0; } -static void ndisc_router_process_route(Link *link, sd_ndisc_router *rt) { +static int ndisc_router_process_route(Link *link, sd_ndisc_router *rt) { _cleanup_(route_freep) Route *route = NULL; struct in6_addr gateway; uint32_t lifetime; @@ -303,42 +272,31 @@ static void ndisc_router_process_route(Link *link, sd_ndisc_router *rt) { assert(link); r = sd_ndisc_router_route_get_lifetime(rt, &lifetime); - if (r < 0) { - log_link_warning_errno(link, r, "Failed to get gateway address from RA: %m"); - return; - } + if (r < 0) + return log_link_warning_errno(link, r, "Failed to get gateway address from RA: %m"); + if (lifetime == 0) - return; + return 0; r = sd_ndisc_router_get_address(rt, &gateway); - if (r < 0) { - log_link_warning_errno(link, r, "Failed to get gateway address from RA: %m"); - return; - } + if (r < 0) + return log_link_warning_errno(link, r, "Failed to get gateway address from RA: %m"); r = sd_ndisc_router_route_get_prefixlen(rt, &prefixlen); - if (r < 0) { - log_link_warning_errno(link, r, "Failed to get route prefix length: %m"); - return; - } + if (r < 0) + return log_link_warning_errno(link, r, "Failed to get route prefix length: %m"); r = sd_ndisc_router_route_get_preference(rt, &preference); - if (r < 0) { - log_link_warning_errno(link, r, "Failed to get default router preference from RA: %m"); - return; - } + if (r < 0) + return log_link_warning_errno(link, r, "Failed to get default router preference from RA: %m"); r = sd_ndisc_router_get_timestamp(rt, clock_boottime_or_monotonic(), &time_now); - if (r < 0) { - log_link_warning_errno(link, r, "Failed to get RA timestamp: %m"); - return; - } + if (r < 0) + return log_link_warning_errno(link, r, "Failed to get RA timestamp: %m"); r = route_new(&route); - if (r < 0) { - log_link_error_errno(link, r, "Could not allocate route: %m"); - return; - } + if (r < 0) + return log_link_error_errno(link, r, "Could not allocate route: %m"); route->family = AF_INET6; route->table = link->network->ipv6_accept_ra_route_table; @@ -349,19 +307,19 @@ static void ndisc_router_process_route(Link *link, sd_ndisc_router *rt) { route->lifetime = time_now + lifetime * USEC_PER_SEC; r = sd_ndisc_router_route_get_address(rt, &route->dst.in6); - if (r < 0) { - log_link_error_errno(link, r, "Failed to get route address: %m"); - return; - } + if (r < 0) + return log_link_error_errno(link, r, "Failed to get route address: %m"); r = route_configure(route, link, ndisc_route_handler); if (r < 0) { log_link_warning_errno(link, r, "Could not set additional route: %m"); link_enter_failed(link); - return; + return r; } link->ndisc_messages++; + + return 0; } static void ndisc_rdnss_hash_func(const void *p, struct siphash *state) { @@ -381,7 +339,7 @@ static const struct hash_ops ndisc_rdnss_hash_ops = { .compare = ndisc_rdnss_compare_func }; -static void ndisc_router_process_rdnss(Link *link, sd_ndisc_router *rt) { +static int ndisc_router_process_rdnss(Link *link, sd_ndisc_router *rt) { uint32_t lifetime; const struct in6_addr *a; usec_t time_now; @@ -391,27 +349,22 @@ static void ndisc_router_process_rdnss(Link *link, sd_ndisc_router *rt) { assert(rt); r = sd_ndisc_router_get_timestamp(rt, clock_boottime_or_monotonic(), &time_now); - if (r < 0) { - log_link_warning_errno(link, r, "Failed to get RA timestamp: %m"); - return; - } + if (r < 0) + return log_link_warning_errno(link, r, "Failed to get RA timestamp: %m"); r = sd_ndisc_router_rdnss_get_lifetime(rt, &lifetime); - if (r < 0) { - log_link_warning_errno(link, r, "Failed to get RDNSS lifetime: %m"); - return; - } + if (r < 0) + return log_link_warning_errno(link, r, "Failed to get RDNSS lifetime: %m"); n = sd_ndisc_router_rdnss_get_addresses(rt, &a); - if (n < 0) { - log_link_warning_errno(link, n, "Failed to get RDNSS addresses: %m"); - return; - } + if (n < 0) + return log_link_warning_errno(link, n, "Failed to get RDNSS addresses: %m"); for (i = 0; i < n; i++) { + _cleanup_free_ NDiscRDNSS *x = NULL; NDiscRDNSS d = { - .address = a[i] - }, *x; + .address = a[i], + }, *y; if (lifetime == 0) { (void) set_remove(link->ndisc_rdnss, &d); @@ -419,9 +372,9 @@ static void ndisc_router_process_rdnss(Link *link, sd_ndisc_router *rt) { continue; } - x = set_get(link->ndisc_rdnss, &d); - if (x) { - x->valid_until = time_now + lifetime * USEC_PER_SEC; + y = set_get(link->ndisc_rdnss, &d); + if (y) { + y->valid_until = time_now + lifetime * USEC_PER_SEC; continue; } @@ -433,30 +386,29 @@ static void ndisc_router_process_rdnss(Link *link, sd_ndisc_router *rt) { } r = set_ensure_allocated(&link->ndisc_rdnss, &ndisc_rdnss_hash_ops); - if (r < 0) { - log_oom(); - return; - } + if (r < 0) + return log_oom(); - x = new0(NDiscRDNSS, 1); - if (!x) { - log_oom(); - return; - } + x = new(NDiscRDNSS, 1); + if (!x) + return log_oom(); - x->address = a[i]; - x->valid_until = time_now + lifetime * USEC_PER_SEC; + *x = (NDiscRDNSS) { + .address = a[i], + .valid_until = time_now + lifetime * USEC_PER_SEC, + }; r = set_put(link->ndisc_rdnss, x); - if (r < 0) { - free(x); - log_oom(); - return; - } + if (r < 0) + return log_oom(); + + TAKE_PTR(x); assert(r > 0); link_dirty(link); } + + return 0; } static void ndisc_dnssl_hash_func(const void *p, struct siphash *state) { @@ -590,25 +542,25 @@ static void ndisc_router_process_options(Link *link, sd_ndisc_router *rt) { } if (flags & ND_OPT_PI_FLAG_ONLINK) - ndisc_router_process_onlink_prefix(link, rt); + (void) ndisc_router_process_onlink_prefix(link, rt); if (flags & ND_OPT_PI_FLAG_AUTO) - ndisc_router_process_autonomous_prefix(link, rt); + (void) ndisc_router_process_autonomous_prefix(link, rt); break; } case SD_NDISC_OPTION_ROUTE_INFORMATION: - ndisc_router_process_route(link, rt); + (void) ndisc_router_process_route(link, rt); break; case SD_NDISC_OPTION_RDNSS: if (link->network->ipv6_accept_ra_use_dns) - ndisc_router_process_rdnss(link, rt); + (void) ndisc_router_process_rdnss(link, rt); break; case SD_NDISC_OPTION_DNSSL: if (link->network->ipv6_accept_ra_use_dns) - ndisc_router_process_dnssl(link, rt); + (void) ndisc_router_process_dnssl(link, rt); break; } @@ -616,9 +568,9 @@ static void ndisc_router_process_options(Link *link, sd_ndisc_router *rt) { } } -static void ndisc_router_handler(Link *link, sd_ndisc_router *rt) { +static int ndisc_router_handler(Link *link, sd_ndisc_router *rt) { uint64_t flags; - int r; + int r = 0; assert(link); assert(link->network); @@ -626,22 +578,24 @@ static void ndisc_router_handler(Link *link, sd_ndisc_router *rt) { assert(rt); r = sd_ndisc_router_get_flags(rt, &flags); - if (r < 0) { - log_link_warning_errno(link, r, "Failed to get RA flags: %m"); - return; - } + if (r < 0) + return log_link_warning_errno(link, r, "Failed to get RA flags: %m"); if (flags & (ND_RA_FLAG_MANAGED | ND_RA_FLAG_OTHER)) { /* (re)start DHCPv6 client in stateful or stateless mode according to RA flags */ r = dhcp6_request_address(link, !(flags & ND_RA_FLAG_MANAGED)); if (r < 0 && r != -EBUSY) log_link_warning_errno(link, r, "Could not acquire DHCPv6 lease on NDisc request: %m"); - else + else { log_link_debug(link, "Acquiring DHCPv6 lease on NDisc request"); + r = 0; + } } ndisc_router_process_default(link, rt); ndisc_router_process_options(link, rt); + + return r; } static void ndisc_handler(sd_ndisc *nd, sd_ndisc_event event, sd_ndisc_router *rt, void *userdata) { @@ -655,7 +609,7 @@ static void ndisc_handler(sd_ndisc *nd, sd_ndisc_event event, sd_ndisc_router *r switch (event) { case SD_NDISC_EVENT_ROUTER: - ndisc_router_handler(link, rt); + (void) ndisc_router_handler(link, rt); break; case SD_NDISC_EVENT_TIMEOUT: diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index b2663ebf13..989c92322b 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -127,47 +127,71 @@ int network_load_one(Manager *manager, const char *filename) { return 0; } - network = new0(Network, 1); + network = new(Network, 1); if (!network) return log_oom(); - network->manager = manager; + *network = (Network) { + .manager = manager, - LIST_HEAD_INIT(network->static_addresses); - LIST_HEAD_INIT(network->static_routes); - LIST_HEAD_INIT(network->static_fdb_entries); - LIST_HEAD_INIT(network->ipv6_proxy_ndp_addresses); - LIST_HEAD_INIT(network->address_labels); - LIST_HEAD_INIT(network->static_prefixes); - LIST_HEAD_INIT(network->rules); + .required_for_online = true, + .dhcp = ADDRESS_FAMILY_NO, + .dhcp_use_ntp = true, + .dhcp_use_dns = true, + .dhcp_use_hostname = true, + .dhcp_use_routes = true, + /* NOTE: this var might be overwriten by network_apply_anonymize_if_set */ + .dhcp_send_hostname = true, + /* To enable/disable RFC7844 Anonymity Profiles */ + .dhcp_anonymize = false, + .dhcp_route_metric = DHCP_ROUTE_METRIC, + /* NOTE: this var might be overwrite by network_apply_anonymize_if_set */ + .dhcp_client_identifier = DHCP_CLIENT_ID_DUID, + .dhcp_route_table = RT_TABLE_MAIN, + .dhcp_route_table_set = false, + /* NOTE: from man: UseMTU=... Defaults to false*/ + .dhcp_use_mtu = false, + /* NOTE: from man: UseTimezone=... Defaults to "no".*/ + .dhcp_use_timezone = false, + .rapid_commit = true, - network->stacked_netdevs = hashmap_new(&string_hash_ops); - if (!network->stacked_netdevs) - return log_oom(); + .dhcp_server_emit_dns = true, + .dhcp_server_emit_ntp = true, + .dhcp_server_emit_router = true, + .dhcp_server_emit_timezone = true, - network->addresses_by_section = hashmap_new(&network_config_hash_ops); - if (!network->addresses_by_section) - return log_oom(); + .router_emit_dns = true, + .router_emit_domains = true, - network->routes_by_section = hashmap_new(&network_config_hash_ops); - if (!network->routes_by_section) - return log_oom(); + .use_bpdu = -1, + .hairpin = -1, + .fast_leave = -1, + .allow_port_to_be_root = -1, + .unicast_flood = -1, + .priority = LINK_BRIDGE_PORT_PRIORITY_INVALID, - network->fdb_entries_by_section = hashmap_new(NULL); - if (!network->fdb_entries_by_section) - return log_oom(); + .lldp_mode = LLDP_MODE_ROUTERS_ONLY, - network->address_labels_by_section = hashmap_new(&network_config_hash_ops); - if (!network->address_labels_by_section) - log_oom(); + .llmnr = RESOLVE_SUPPORT_YES, + .mdns = RESOLVE_SUPPORT_NO, + .dnssec_mode = _DNSSEC_MODE_INVALID, + .dns_over_tls_mode = _DNS_OVER_TLS_MODE_INVALID, - network->prefixes_by_section = hashmap_new(&network_config_hash_ops); - if (!network->prefixes_by_section) - return log_oom(); + .link_local = ADDRESS_FAMILY_IPV6, - network->rules_by_section = hashmap_new(&network_config_hash_ops); - if (!network->rules_by_section) - return log_oom(); + .ipv6_privacy_extensions = IPV6_PRIVACY_EXTENSIONS_NO, + .ipv6_accept_ra = -1, + .ipv6_dad_transmits = -1, + .ipv6_hop_limit = -1, + .ipv6_proxy_ndp = -1, + .duid.type = _DUID_TYPE_INVALID, + .proxy_arp = -1, + .arp = -1, + .multicast = -1, + .allmulticast = -1, + .ipv6_accept_ra_use_dns = true, + .ipv6_accept_ra_route_table = RT_TABLE_MAIN, + }; network->filename = strdup(filename); if (!network->filename) @@ -183,65 +207,6 @@ int network_load_one(Manager *manager, const char *filename) { *d = '\0'; - network->required_for_online = true; - network->dhcp = ADDRESS_FAMILY_NO; - network->dhcp_use_ntp = true; - network->dhcp_use_dns = true; - network->dhcp_use_hostname = true; - network->dhcp_use_routes = true; - /* NOTE: this var might be overwriten by network_apply_anonymize_if_set */ - network->dhcp_send_hostname = true; - /* To enable/disable RFC7844 Anonymity Profiles */ - network->dhcp_anonymize = false; - network->dhcp_route_metric = DHCP_ROUTE_METRIC; - /* NOTE: this var might be overwrite by network_apply_anonymize_if_set */ - network->dhcp_client_identifier = DHCP_CLIENT_ID_DUID; - network->dhcp_route_table = RT_TABLE_MAIN; - network->dhcp_route_table_set = false; - /* NOTE: from man: UseMTU=... Defaults to false*/ - network->dhcp_use_mtu = false; - /* NOTE: from man: UseTimezone=... Defaults to "no".*/ - network->dhcp_use_timezone = false; - network->rapid_commit = true; - - network->dhcp_server_emit_dns = true; - network->dhcp_server_emit_ntp = true; - network->dhcp_server_emit_router = true; - network->dhcp_server_emit_timezone = true; - - network->router_emit_dns = true; - network->router_emit_domains = true; - - network->use_bpdu = -1; - network->hairpin = -1; - network->fast_leave = -1; - network->allow_port_to_be_root = -1; - network->unicast_flood = -1; - network->priority = LINK_BRIDGE_PORT_PRIORITY_INVALID; - - network->lldp_mode = LLDP_MODE_ROUTERS_ONLY; - - network->llmnr = RESOLVE_SUPPORT_YES; - network->mdns = RESOLVE_SUPPORT_NO; - network->dnssec_mode = _DNSSEC_MODE_INVALID; - network->dns_over_tls_mode = _DNS_OVER_TLS_MODE_INVALID; - - network->link_local = ADDRESS_FAMILY_IPV6; - - network->ipv6_privacy_extensions = IPV6_PRIVACY_EXTENSIONS_NO; - network->ipv6_accept_ra = -1; - network->ipv6_dad_transmits = -1; - network->ipv6_hop_limit = -1; - network->ipv6_proxy_ndp = -1; - network->duid.type = _DUID_TYPE_INVALID; - network->proxy_arp = -1; - network->arp = -1; - network->multicast = -1; - network->allmulticast = -1; - network->ipv6_accept_ra_use_dns = true; - network->ipv6_accept_ra_route_table = RT_TABLE_MAIN; - network->ipv6_mtu = 0; - dropin_dirname = strjoina(network->name, ".network.d"); r = config_parse_many(filename, network_dirs, dropin_dirname, @@ -622,6 +587,10 @@ int config_parse_netdev(const char *unit, case NETDEV_KIND_IPVLAN: case NETDEV_KIND_VXLAN: case NETDEV_KIND_VCAN: + r = hashmap_ensure_allocated(&network->stacked_netdevs, &string_hash_ops); + if (r < 0) + return log_oom(); + r = hashmap_put(network->stacked_netdevs, netdev->ifname, netdev); if (r < 0) { log_syntax(unit, LOG_ERR, filename, line, r, "Cannot add NetDev '%s' to network: %m", rvalue); @@ -760,6 +729,10 @@ int config_parse_tunnel(const char *unit, return 0; } + r = hashmap_ensure_allocated(&network->stacked_netdevs, &string_hash_ops); + if (r < 0) + return log_oom(); + r = hashmap_put(network->stacked_netdevs, netdev->ifname, netdev); if (r < 0) { log_syntax(unit, LOG_ERR, filename, line, r, "Cannot add VLAN '%s' to network, ignoring: %m", rvalue); diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index 919a2c4b3c..5c1fccbc41 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -89,8 +89,8 @@ typedef struct NetworkConfigSection { int network_config_section_new(const char *filename, unsigned line, NetworkConfigSection **s); void network_config_section_free(NetworkConfigSection *network); - DEFINE_TRIVIAL_CLEANUP_FUNC(NetworkConfigSection*, network_config_section_free); +extern const struct hash_ops network_config_hash_ops; typedef struct Manager Manager; diff --git a/src/network/networkd-radv.c b/src/network/networkd-radv.c index 600fb27d75..346d64953b 100644 --- a/src/network/networkd-radv.c +++ b/src/network/networkd-radv.c @@ -153,19 +153,22 @@ int prefix_new_static(Network *network, const char *filename, if (r < 0) return r; - if (filename) { - prefix->section = TAKE_PTR(n); - - r = hashmap_put(network->prefixes_by_section, prefix->section, - prefix); - if (r < 0) - return r; - } - prefix->network = network; LIST_APPEND(prefixes, network->static_prefixes, prefix); network->n_static_prefixes++; + if (filename) { + prefix->section = TAKE_PTR(n); + + r = hashmap_ensure_allocated(&network->prefixes_by_section, &network_config_hash_ops); + if (r < 0) + return r; + + r = hashmap_put(network->prefixes_by_section, prefix->section, prefix); + if (r < 0) + return r; + } + *ret = TAKE_PTR(prefix); return 0; diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c index 21b5de3f26..2f70844d47 100644 --- a/src/network/networkd-route.c +++ b/src/network/networkd-route.c @@ -46,17 +46,19 @@ static unsigned routes_max(void) { int route_new(Route **ret) { _cleanup_(route_freep) Route *route = NULL; - route = new0(Route, 1); + route = new(Route, 1); if (!route) return -ENOMEM; - route->family = AF_UNSPEC; - route->scope = RT_SCOPE_UNIVERSE; - route->protocol = RTPROT_UNSPEC; - route->type = RTN_UNICAST; - route->table = RT_TABLE_MAIN; - route->lifetime = USEC_INFINITY; - route->quickack = -1; + *route = (Route) { + .family = AF_UNSPEC, + .scope = RT_SCOPE_UNIVERSE, + .protocol = RTPROT_UNSPEC, + .type = RTN_UNICAST, + .table = RT_TABLE_MAIN, + .lifetime = USEC_INFINITY, + .quickack = -1, + }; *ret = TAKE_PTR(route); @@ -93,19 +95,22 @@ int route_new_static(Network *network, const char *filename, unsigned section_li return r; route->protocol = RTPROT_STATIC; + route->network = network; + LIST_PREPEND(routes, network->static_routes, route); + network->n_static_routes++; if (filename) { route->section = TAKE_PTR(n); + r = hashmap_ensure_allocated(&network->routes_by_section, &network_config_hash_ops); + if (r < 0) + return r; + r = hashmap_put(network->routes_by_section, route->section, route); if (r < 0) return r; } - route->network = network; - LIST_PREPEND(routes, network->static_routes, route); - network->n_static_routes++; - *ret = TAKE_PTR(route); return 0; diff --git a/src/network/networkd-routing-policy-rule.c b/src/network/networkd-routing-policy-rule.c index 739f9e6a5a..683c166289 100644 --- a/src/network/networkd-routing-policy-rule.c +++ b/src/network/networkd-routing-policy-rule.c @@ -40,11 +40,8 @@ void routing_policy_rule_free(RoutingPolicyRule *rule) { assert(rule->network->n_rules > 0); rule->network->n_rules--; - if (rule->section) { + if (rule->section) hashmap_remove(rule->network->rules_by_section, rule->section); - network_config_section_free(rule->section); - } - } if (rule->manager) { @@ -52,6 +49,7 @@ void routing_policy_rule_free(RoutingPolicyRule *rule) { set_remove(rule->manager->rules_foreign, rule); } + network_config_section_free(rule->section); free(rule->iif); free(rule->oif); free(rule); @@ -390,31 +388,39 @@ static int routing_policy_rule_new_static(Network *network, const char *filename assert(ret); assert(!!filename == (section_line > 0)); - r = network_config_section_new(filename, section_line, &n); - if (r < 0) - return r; + if (filename) { + r = network_config_section_new(filename, section_line, &n); + if (r < 0) + return r; - rule = hashmap_get(network->rules_by_section, n); - if (rule) { - *ret = TAKE_PTR(rule); + rule = hashmap_get(network->rules_by_section, n); + if (rule) { + *ret = TAKE_PTR(rule); - return 0; + return 0; + } } r = routing_policy_rule_new(&rule); if (r < 0) return r; - rule->section = TAKE_PTR(n); rule->network = network; - - r = hashmap_put(network->rules_by_section, rule->section, rule); - if (r < 0) - return r; - LIST_APPEND(rules, network->rules, rule); network->n_rules++; + if (filename) { + rule->section = TAKE_PTR(n); + + r = hashmap_ensure_allocated(&network->rules_by_section, &network_config_hash_ops); + if (r < 0) + return r; + + r = hashmap_put(network->rules_by_section, rule->section, rule); + if (r < 0) + return r; + } + *ret = TAKE_PTR(rule); return 0; diff --git a/src/network/test-networkd-conf.c b/src/network/test-networkd-conf.c index abef6e761a..86d4e7e733 100644 --- a/src/network/test-networkd-conf.c +++ b/src/network/test-networkd-conf.c @@ -172,7 +172,6 @@ static void test_config_parse_address_one(const char *rvalue, int family, unsign _cleanup_(network_freep) Network *network = NULL; assert_se(network = new0(Network, 1)); - assert_se(network->addresses_by_section = hashmap_new(NULL)); assert_se(config_parse_address("network", "filename", 1, "section", 1, "Address", 0, rvalue, network, network) == 0); assert_se(network->n_static_addresses == n_addresses); if (n_addresses > 0) { diff --git a/src/network/wait-online/manager.c b/src/network/wait-online/manager.c index 0dfe7482fc..e1ccc9ff67 100644 --- a/src/network/wait-online/manager.c +++ b/src/network/wait-online/manager.c @@ -292,14 +292,10 @@ int manager_new(Manager **ret, char **interfaces, char **ignore, usec_t timeout) } void manager_free(Manager *m) { - Link *l; - if (!m) return; - while ((l = hashmap_first(m->links))) - link_free(l); - hashmap_free(m->links); + hashmap_free_with_destructor(m->links, link_free); hashmap_free(m->links_by_name); sd_event_source_unref(m->network_monitor_event_source); diff --git a/src/test/test-udev.c b/src/test/test-udev.c index 9f3aba70ab..102da4adc6 100644 --- a/src/test/test-udev.c +++ b/src/test/test-udev.c @@ -69,8 +69,14 @@ int main(int argc, char *argv[]) { if (fake_filesystems() < 0) return EXIT_FAILURE; - if (argc == 2) + if (argc == 2) { + if (!streq(argv[1], "check")) { + log_error("Unknown argument: %s", argv[1]); + return EXIT_FAILURE; + } + return EXIT_SUCCESS; + } log_debug("version %s", PACKAGE_VERSION); mac_selinux_init(); diff --git a/src/udev/net/ethtool-util.h b/src/udev/net/ethtool-util.h index abb0cd0264..73c4d447d1 100644 --- a/src/udev/net/ethtool-util.h +++ b/src/udev/net/ethtool-util.h @@ -4,6 +4,7 @@ #include #include +#include "conf-parser.h" #include "missing.h" struct link_config; @@ -119,8 +120,8 @@ NetDevPort port_from_string(const char *port) _pure_; const char *advertise_to_string(NetDevAdvertise advertise) _const_; NetDevAdvertise advertise_from_string(const char *advertise) _pure_; -int config_parse_duplex(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); -int config_parse_wol(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); -int config_parse_port(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); -int config_parse_channel(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); -int config_parse_advertise(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); +CONFIG_PARSER_PROTOTYPE(config_parse_duplex); +CONFIG_PARSER_PROTOTYPE(config_parse_wol); +CONFIG_PARSER_PROTOTYPE(config_parse_port); +CONFIG_PARSER_PROTOTYPE(config_parse_channel); +CONFIG_PARSER_PROTOTYPE(config_parse_advertise); diff --git a/src/udev/net/link-config.h b/src/udev/net/link-config.h index ca6c8ddabe..88e3651b7b 100644 --- a/src/udev/net/link-config.h +++ b/src/udev/net/link-config.h @@ -4,6 +4,7 @@ #include "sd-device.h" #include "condition.h" +#include "conf-parser.h" #include "ethtool-util.h" #include "list.h" #include "set.h" @@ -82,5 +83,5 @@ MACPolicy mac_policy_from_string(const char *p) _pure_; /* gperf lookup function */ const struct ConfigPerfItem* link_config_gperf_lookup(const char *key, GPERF_LEN_TYPE length); -int config_parse_mac_policy(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); -int config_parse_name_policy(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); +CONFIG_PARSER_PROTOTYPE(config_parse_mac_policy); +CONFIG_PARSER_PROTOTYPE(config_parse_name_policy);