Merge pull request #10734 from yuwata/network-use-structured-initializers

network: several cleanups
This commit is contained in:
Lennart Poettering 2018-11-12 11:42:02 +01:00 committed by GitHub
commit 192602cb1e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 438 additions and 568 deletions

View File

@ -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) {

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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)

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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();

View File

@ -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);

View File

@ -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;
}

View File

@ -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;

View File

@ -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);

View File

@ -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);
}

View File

@ -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:

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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) {

View File

@ -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);

View File

@ -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();

View File

@ -4,6 +4,7 @@
#include <macro.h>
#include <linux/ethtool.h>
#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);

View File

@ -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);