diff options
52 files changed, 0 insertions, 13324 deletions
diff --git a/src/network/.gitignore b/src/network/.gitignore deleted file mode 100644 index 8858596489..0000000000 --- a/src/network/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/networkd-network-gperf.c -/networkd-netdev-gperf.c diff --git a/src/network/Makefile b/src/network/Makefile deleted file mode 120000 index d0b0e8e008..0000000000 --- a/src/network/Makefile +++ /dev/null @@ -1 +0,0 @@ -../Makefile
\ No newline at end of file diff --git a/src/network/networkctl.c b/src/network/networkctl.c deleted file mode 100644 index 9716499a73..0000000000 --- a/src/network/networkctl.c +++ /dev/null @@ -1,1114 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2014 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#include <stdbool.h> -#include <getopt.h> -#include <net/if.h> - -#include "sd-network.h" -#include "sd-rtnl.h" -#include "sd-hwdb.h" -#include "sd-device.h" - -#include "strv.h" -#include "build.h" -#include "util.h" -#include "pager.h" -#include "lldp.h" -#include "rtnl-util.h" -#include "device-util.h" -#include "hwdb-util.h" -#include "arphrd-list.h" -#include "local-addresses.h" -#include "socket-util.h" -#include "ether-addr-util.h" -#include "verbs.h" - -static bool arg_no_pager = false; -static bool arg_legend = true; -static bool arg_all = false; - -static void pager_open_if_enabled(void) { - - if (arg_no_pager) - return; - - pager_open(false); -} - -static int link_get_type_string(int iftype, sd_device *d, char **ret) { - const char *t; - char *p; - - assert(ret); - - if (iftype == ARPHRD_ETHER && d) { - const char *devtype, *id = NULL; - /* WLANs have iftype ARPHRD_ETHER, but we want - * to show a more useful type string for - * them */ - - (void)sd_device_get_devtype(d, &devtype); - - if (streq_ptr(devtype, "wlan")) - id = "wlan"; - else if (streq_ptr(devtype, "wwan")) - id = "wwan"; - - if (id) { - p = strdup(id); - if (!p) - return -ENOMEM; - - *ret = p; - return 1; - } - } - - t = arphrd_to_name(iftype); - if (!t) { - *ret = NULL; - return 0; - } - - p = strdup(t); - if (!p) - return -ENOMEM; - - ascii_strlower(p); - *ret = p; - - return 0; -} - -typedef struct LinkInfo { - const char *name; - int ifindex; - unsigned iftype; -} LinkInfo; - -static int link_info_compare(const void *a, const void *b) { - const LinkInfo *x = a, *y = b; - - return x->ifindex - y->ifindex; -} - -static int decode_and_sort_links(sd_rtnl_message *m, LinkInfo **ret) { - _cleanup_free_ LinkInfo *links = NULL; - size_t size = 0, c = 0; - sd_rtnl_message *i; - int r; - - for (i = m; i; i = sd_rtnl_message_next(i)) { - const char *name; - unsigned iftype; - uint16_t type; - int ifindex; - - r = sd_rtnl_message_get_type(i, &type); - if (r < 0) - return r; - - if (type != RTM_NEWLINK) - continue; - - r = sd_rtnl_message_link_get_ifindex(i, &ifindex); - if (r < 0) - return r; - - r = sd_rtnl_message_read_string(i, IFLA_IFNAME, &name); - if (r < 0) - return r; - - r = sd_rtnl_message_link_get_type(i, &iftype); - if (r < 0) - return r; - - if (!GREEDY_REALLOC(links, size, c+1)) - return -ENOMEM; - - links[c].name = name; - links[c].ifindex = ifindex; - links[c].iftype = iftype; - c++; - } - - qsort_safe(links, c, sizeof(LinkInfo), link_info_compare); - - *ret = links; - links = NULL; - - return (int) c; -} - -static void operational_state_to_color(const char *state, const char **on, const char **off) { - assert(on); - assert(off); - - if (streq_ptr(state, "routable")) { - *on = ansi_highlight_green(); - *off = ansi_highlight_off(); - } else if (streq_ptr(state, "degraded")) { - *on = ansi_highlight_yellow(); - *off = ansi_highlight_off(); - } else - *on = *off = ""; -} - -static void setup_state_to_color(const char *state, const char **on, const char **off) { - assert(on); - assert(off); - - if (streq_ptr(state, "configured")) { - *on = ansi_highlight_green(); - *off = ansi_highlight_off(); - } else if (streq_ptr(state, "configuring")) { - *on = ansi_highlight_yellow(); - *off = ansi_highlight_off(); - } else if (streq_ptr(state, "failed") || streq_ptr(state, "linger")) { - *on = ansi_highlight_red(); - *off = ansi_highlight_off(); - } else - *on = *off = ""; -} - -static int list_links(int argc, char *argv[], void *userdata) { - _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL; - _cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL; - _cleanup_free_ LinkInfo *links = NULL; - int r, c, i; - - pager_open_if_enabled(); - - r = sd_rtnl_open(&rtnl, 0); - if (r < 0) - return log_error_errno(r, "Failed to connect to netlink: %m"); - - r = sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, 0); - if (r < 0) - return rtnl_log_create_error(r); - - r = sd_rtnl_message_request_dump(req, true); - if (r < 0) - return rtnl_log_create_error(r); - - r = sd_rtnl_call(rtnl, req, 0, &reply); - if (r < 0) - return log_error_errno(r, "Failed to enumerate links: %m"); - - if (arg_legend) - printf("%3s %-16s %-18s %-11s %-10s\n", "IDX", "LINK", "TYPE", "OPERATIONAL", "SETUP"); - - c = decode_and_sort_links(reply, &links); - if (c < 0) - return rtnl_log_parse_error(c); - - for (i = 0; i < c; i++) { - _cleanup_free_ char *setup_state = NULL, *operational_state = NULL; - _cleanup_device_unref_ sd_device *d = NULL; - const char *on_color_operational, *off_color_operational, - *on_color_setup, *off_color_setup; - char devid[2 + DECIMAL_STR_MAX(int)]; - _cleanup_free_ char *t = NULL; - - sd_network_link_get_operational_state(links[i].ifindex, &operational_state); - operational_state_to_color(operational_state, &on_color_operational, &off_color_operational); - - sd_network_link_get_setup_state(links[i].ifindex, &setup_state); - setup_state_to_color(setup_state, &on_color_setup, &off_color_setup); - - sprintf(devid, "n%i", links[i].ifindex); - (void)sd_device_new_from_device_id(&d, devid); - - link_get_type_string(links[i].iftype, d, &t); - - printf("%3i %-16s %-18s %s%-11s%s %s%-10s%s\n", - links[i].ifindex, links[i].name, strna(t), - on_color_operational, strna(operational_state), off_color_operational, - on_color_setup, strna(setup_state), off_color_setup); - } - - if (arg_legend) - printf("\n%i links listed.\n", c); - - return 0; -} - -/* IEEE Organizationally Unique Identifier vendor string */ -static int ieee_oui(sd_hwdb *hwdb, struct ether_addr *mac, char **ret) { - const char *description; - char modalias[strlen("OUI:XXYYXXYYXXYY") + 1], *desc; - int r; - - assert(ret); - - if (!hwdb) - return -EINVAL; - - if (!mac) - return -EINVAL; - - /* skip commonly misused 00:00:00 (Xerox) prefix */ - if (memcmp(mac, "\0\0\0", 3) == 0) - return -EINVAL; - - snprintf(modalias, sizeof(modalias), "OUI:" ETHER_ADDR_FORMAT_STR, ETHER_ADDR_FORMAT_VAL(*mac)); - - r = sd_hwdb_get(hwdb, modalias, "ID_OUI_FROM_DATABASE", &description); - if (r < 0) - return r; - - desc = strdup(description); - if (!desc) - return -ENOMEM; - - *ret = desc; - - return 0; -} - -static int get_gateway_description( - sd_rtnl *rtnl, - sd_hwdb *hwdb, - int ifindex, - int family, - union in_addr_union *gateway, - char **gateway_description) { - _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL; - sd_rtnl_message *m; - int r; - - assert(rtnl); - assert(ifindex >= 0); - assert(family == AF_INET || family == AF_INET6); - assert(gateway); - assert(gateway_description); - - r = sd_rtnl_message_new_neigh(rtnl, &req, RTM_GETNEIGH, ifindex, family); - if (r < 0) - return r; - - r = sd_rtnl_message_request_dump(req, true); - if (r < 0) - return r; - - r = sd_rtnl_call(rtnl, req, 0, &reply); - if (r < 0) - return r; - - for (m = reply; m; m = sd_rtnl_message_next(m)) { - union in_addr_union gw = {}; - struct ether_addr mac = {}; - uint16_t type; - int ifi, fam; - - r = sd_rtnl_message_get_errno(m); - if (r < 0) { - log_error_errno(r, "got error: %m"); - continue; - } - - r = sd_rtnl_message_get_type(m, &type); - if (r < 0) { - log_error_errno(r, "could not get type: %m"); - continue; - } - - if (type != RTM_NEWNEIGH) { - log_error("type is not RTM_NEWNEIGH"); - continue; - } - - r = sd_rtnl_message_neigh_get_family(m, &fam); - if (r < 0) { - log_error_errno(r, "could not get family: %m"); - continue; - } - - if (fam != family) { - log_error("family is not correct"); - continue; - } - - r = sd_rtnl_message_neigh_get_ifindex(m, &ifi); - if (r < 0) { - log_error_errno(r, "could not get ifindex: %m"); - continue; - } - - if (ifindex > 0 && ifi != ifindex) - continue; - - switch (fam) { - case AF_INET: - r = sd_rtnl_message_read_in_addr(m, NDA_DST, &gw.in); - if (r < 0) - continue; - - break; - case AF_INET6: - r = sd_rtnl_message_read_in6_addr(m, NDA_DST, &gw.in6); - if (r < 0) - continue; - - break; - default: - continue; - } - - if (!in_addr_equal(fam, &gw, gateway)) - continue; - - r = sd_rtnl_message_read_ether_addr(m, NDA_LLADDR, &mac); - if (r < 0) - continue; - - r = ieee_oui(hwdb, &mac, gateway_description); - if (r < 0) - continue; - - return 0; - } - - return -ENODATA; -} - -static int dump_gateways( - sd_rtnl *rtnl, - sd_hwdb *hwdb, - const char *prefix, - int ifindex) { - _cleanup_free_ struct local_address *local = NULL; - int r, n, i; - - n = local_gateways(rtnl, ifindex, AF_UNSPEC, &local); - if (n < 0) - return n; - - for (i = 0; i < n; i++) { - _cleanup_free_ char *gateway = NULL, *description = NULL; - - r = in_addr_to_string(local[i].family, &local[i].address, &gateway); - if (r < 0) - return r; - - r = get_gateway_description(rtnl, hwdb, local[i].ifindex, local[i].family, &local[i].address, &description); - if (r < 0) - log_debug_errno(r, "Could not get description of gateway: %m"); - - printf("%*s%s", - (int) strlen(prefix), - i == 0 ? prefix : "", - gateway); - - if (description) - printf(" (%s)", description); - - /* Show interface name for the entry if we show - * entries for all interfaces */ - if (ifindex <= 0) { - char name[IF_NAMESIZE+1]; - - if (if_indextoname(local[i].ifindex, name)) { - fputs(" on ", stdout); - fputs(name, stdout); - } else - printf(" on %%%i", local[i].ifindex); - } - - fputc('\n', stdout); - } - - return 0; -} - -static int dump_addresses( - sd_rtnl *rtnl, - const char *prefix, - int ifindex) { - - _cleanup_free_ struct local_address *local = NULL; - int r, n, i; - - n = local_addresses(rtnl, ifindex, AF_UNSPEC, &local); - if (n < 0) - return n; - - for (i = 0; i < n; i++) { - _cleanup_free_ char *pretty = NULL; - - r = in_addr_to_string(local[i].family, &local[i].address, &pretty); - if (r < 0) - return r; - - printf("%*s%s", - (int) strlen(prefix), - i == 0 ? prefix : "", - pretty); - - if (ifindex <= 0) { - char name[IF_NAMESIZE+1]; - - if (if_indextoname(local[i].ifindex, name)) { - fputs(" on ", stdout); - fputs(name, stdout); - } else - printf(" on %%%i", local[i].ifindex); - } - - fputc('\n', stdout); - } - - return 0; -} - -static void dump_list(const char *prefix, char **l) { - char **i; - - STRV_FOREACH(i, l) { - printf("%*s%s\n", - (int) strlen(prefix), - i == l ? prefix : "", - *i); - } -} - -static int link_status_one( - sd_rtnl *rtnl, - sd_hwdb *hwdb, - const char *name) { - _cleanup_strv_free_ char **dns = NULL, **ntp = NULL, **domains = NULL; - _cleanup_free_ char *setup_state = NULL, *operational_state = NULL; - _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL; - _cleanup_device_unref_ sd_device *d = NULL; - char devid[2 + DECIMAL_STR_MAX(int)]; - _cleanup_free_ char *t = NULL, *network = NULL; - const char *driver = NULL, *path = NULL, *vendor = NULL, *model = NULL, *link = NULL; - const char *on_color_operational, *off_color_operational, - *on_color_setup, *off_color_setup; - _cleanup_strv_free_ char **carrier_bound_to = NULL; - _cleanup_strv_free_ char **carrier_bound_by = NULL; - struct ether_addr e; - unsigned iftype; - int r, ifindex; - bool have_mac; - uint32_t mtu; - - assert(rtnl); - assert(name); - - if (safe_atoi(name, &ifindex) >= 0 && ifindex > 0) - r = sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, ifindex); - else { - r = sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, 0); - if (r < 0) - return rtnl_log_create_error(r); - - r = sd_rtnl_message_append_string(req, IFLA_IFNAME, name); - } - - if (r < 0) - return rtnl_log_create_error(r); - - r = sd_rtnl_call(rtnl, req, 0, &reply); - if (r < 0) - return log_error_errno(r, "Failed to query link: %m"); - - r = sd_rtnl_message_link_get_ifindex(reply, &ifindex); - if (r < 0) - return rtnl_log_parse_error(r); - - r = sd_rtnl_message_read_string(reply, IFLA_IFNAME, &name); - if (r < 0) - return rtnl_log_parse_error(r); - - r = sd_rtnl_message_link_get_type(reply, &iftype); - if (r < 0) - return rtnl_log_parse_error(r); - - have_mac = sd_rtnl_message_read_ether_addr(reply, IFLA_ADDRESS, &e) >= 0; - - if (have_mac) { - const uint8_t *p; - bool all_zeroes = true; - - for (p = (uint8_t*) &e; p < (uint8_t*) &e + sizeof(e); p++) - if (*p != 0) { - all_zeroes = false; - break; - } - - if (all_zeroes) - have_mac = false; - } - - sd_rtnl_message_read_u32(reply, IFLA_MTU, &mtu); - - sd_network_link_get_operational_state(ifindex, &operational_state); - operational_state_to_color(operational_state, &on_color_operational, &off_color_operational); - - sd_network_link_get_setup_state(ifindex, &setup_state); - setup_state_to_color(setup_state, &on_color_setup, &off_color_setup); - - sd_network_link_get_dns(ifindex, &dns); - sd_network_link_get_ntp(ifindex, &ntp); - sd_network_link_get_domains(ifindex, &domains); - r = sd_network_link_get_wildcard_domain(ifindex); - if (r > 0) { - char *wildcard; - - wildcard = strdup("*"); - if (!wildcard) - return log_oom(); - - if (strv_consume(&domains, wildcard) < 0) - return log_oom(); - } - - sprintf(devid, "n%i", ifindex); - - (void)sd_device_new_from_device_id(&d, devid); - - if (d) { - (void)sd_device_get_property_value(d, "ID_NET_LINK_FILE", &link); - (void)sd_device_get_property_value(d, "ID_NET_DRIVER", &driver); - (void)sd_device_get_property_value(d, "ID_PATH", &path); - - r = sd_device_get_property_value(d, "ID_VENDOR_FROM_DATABASE", &vendor); - if (r < 0) - (void)sd_device_get_property_value(d, "ID_VENDOR", &vendor); - - r = sd_device_get_property_value(d, "ID_MODEL_FROM_DATABASE", &model); - if (r < 0) - (void)sd_device_get_property_value(d, "ID_MODEL", &model); - } - - link_get_type_string(iftype, d, &t); - - sd_network_link_get_network_file(ifindex, &network); - - sd_network_link_get_carrier_bound_to(ifindex, &carrier_bound_to); - sd_network_link_get_carrier_bound_by(ifindex, &carrier_bound_by); - - printf("%s%s%s %i: %s\n", on_color_operational, draw_special_char(DRAW_BLACK_CIRCLE), off_color_operational, ifindex, name); - - printf(" Link File: %s\n" - " Network File: %s\n" - " Type: %s\n" - " State: %s%s%s (%s%s%s)\n", - strna(link), - strna(network), - strna(t), - on_color_operational, strna(operational_state), off_color_operational, - on_color_setup, strna(setup_state), off_color_setup); - - if (path) - printf(" Path: %s\n", path); - if (driver) - printf(" Driver: %s\n", driver); - if (vendor) - printf(" Vendor: %s\n", vendor); - if (model) - printf(" Model: %s\n", model); - - if (have_mac) { - _cleanup_free_ char *description = NULL; - char ea[ETHER_ADDR_TO_STRING_MAX]; - - ieee_oui(hwdb, &e, &description); - - if (description) - printf(" HW Address: %s (%s)\n", ether_addr_to_string(&e, ea), description); - else - printf(" HW Address: %s\n", ether_addr_to_string(&e, ea)); - } - - if (mtu > 0) - printf(" MTU: %u\n", mtu); - - dump_addresses(rtnl, " Address: ", ifindex); - dump_gateways(rtnl, hwdb, " Gateway: ", ifindex); - - if (!strv_isempty(dns)) - dump_list(" DNS: ", dns); - if (!strv_isempty(domains)) - dump_list(" Domain: ", domains); - if (!strv_isempty(ntp)) - dump_list(" NTP: ", ntp); - - if (!strv_isempty(carrier_bound_to)) - dump_list("Carrier Bound To: ", carrier_bound_to); - - if (!strv_isempty(carrier_bound_by)) - dump_list("Carrier Bound By: ", carrier_bound_by); - - return 0; -} - -static int link_status(int argc, char *argv[], void *userdata) { - _cleanup_hwdb_unref_ sd_hwdb *hwdb = NULL; - _cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL; - char **name; - int r; - - r = sd_rtnl_open(&rtnl, 0); - if (r < 0) - return log_error_errno(r, "Failed to connect to netlink: %m"); - - r = sd_hwdb_new(&hwdb); - if (r < 0) - log_debug_errno(r, "Failed to open hardware database: %m"); - - if (argc <= 1 && !arg_all) { - _cleanup_free_ char *operational_state = NULL; - _cleanup_strv_free_ char **dns = NULL, **ntp = NULL, **domains = NULL; - const char *on_color_operational, *off_color_operational; - - sd_network_get_operational_state(&operational_state); - operational_state_to_color(operational_state, &on_color_operational, &off_color_operational); - - printf("%s%s%s State: %s%s%s\n", - on_color_operational, draw_special_char(DRAW_BLACK_CIRCLE), off_color_operational, - on_color_operational, strna(operational_state), off_color_operational); - - dump_addresses(rtnl, " Address: ", 0); - dump_gateways(rtnl, hwdb, " Gateway: ", 0); - - sd_network_get_dns(&dns); - if (!strv_isempty(dns)) - dump_list(" DNS: ", dns); - - sd_network_get_domains(&domains); - if (!strv_isempty(domains)) - dump_list(" Domain: ", domains); - - sd_network_get_ntp(&ntp); - if (!strv_isempty(ntp)) - dump_list(" NTP: ", ntp); - - return 0; - } - - pager_open_if_enabled(); - - if (arg_all) { - _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL; - _cleanup_free_ LinkInfo *links = NULL; - int c, i; - - r = sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, 0); - if (r < 0) - return rtnl_log_create_error(r); - - r = sd_rtnl_message_request_dump(req, true); - if (r < 0) - return rtnl_log_create_error(r); - - r = sd_rtnl_call(rtnl, req, 0, &reply); - if (r < 0) - return log_error_errno(r, "Failed to enumerate links: %m"); - - c = decode_and_sort_links(reply, &links); - if (c < 0) - return rtnl_log_parse_error(c); - - for (i = 0; i < c; i++) { - if (i > 0) - fputc('\n', stdout); - - link_status_one(rtnl, hwdb, links[i].name); - } - } else { - STRV_FOREACH(name, argv + 1) { - if (name != argv + 1) - fputc('\n', stdout); - - link_status_one(rtnl, hwdb, *name); - } - } - - return 0; -} - -const char *lldp_system_capability_to_string(LLDPSystemCapabilities d) _const_; -LLDPSystemCapabilities lldp_system_capability_from_string(const char *d) _pure_; - -static const char* const lldp_system_capability_table[_LLDP_SYSTEM_CAPABILITIES_MAX + 1] = { - [LLDP_SYSTEM_CAPABILITIES_OTHER] = "O", - [LLDP_SYSTEM_CAPABILITIES_REPEATER] = "P", - [LLDP_SYSTEM_CAPABILITIES_BRIDGE] = "B", - [LLDP_SYSTEM_CAPABILITIES_WLAN_AP] = "W", - [LLDP_SYSTEM_CAPABILITIES_ROUTER] = "R", - [LLDP_SYSTEM_CAPABILITIES_PHONE] = "T", - [LLDP_SYSTEM_CAPABILITIES_DOCSIS] = "D", - [LLDP_SYSTEM_CAPABILITIES_STATION] = "A", - [LLDP_SYSTEM_CAPABILITIES_CVLAN] = "C", - [LLDP_SYSTEM_CAPABILITIES_SVLAN] = "S", - [LLDP_SYSTEM_CAPABILITIES_TPMR] = "M", - [_LLDP_SYSTEM_CAPABILITIES_MAX] = "N/A", -}; - -DEFINE_STRING_TABLE_LOOKUP(lldp_system_capability, LLDPSystemCapabilities); - -static char *lldp_system_caps(uint16_t cap) { - _cleanup_free_ char *s = NULL, *t = NULL; - char *capability; - - t = strdup("[ "); - if (!t) - return NULL; - - if (cap & LLDP_SYSTEM_CAPABILITIES_OTHER) { - s = strjoin(t, lldp_system_capability_to_string(LLDP_SYSTEM_CAPABILITIES_OTHER), " ", NULL); - if (!s) - return NULL; - - free(t); - t = s; - } - - if (cap & LLDP_SYSTEM_CAPABILITIES_REPEATER) { - s = strjoin(t, lldp_system_capability_to_string(LLDP_SYSTEM_CAPABILITIES_REPEATER), " ", NULL); - if (!s) - return NULL; - - free(t); - t = s; - } - - if (cap & LLDP_SYSTEM_CAPABILITIES_BRIDGE) { - s = strjoin(t, lldp_system_capability_to_string(LLDP_SYSTEM_CAPABILITIES_BRIDGE), " ", NULL); - if (!s) - return NULL; - - free(t); - t = s; - } - - if (cap & LLDP_SYSTEM_CAPABILITIES_WLAN_AP) { - s = strjoin(t, lldp_system_capability_to_string(LLDP_SYSTEM_CAPABILITIES_WLAN_AP), " ", NULL); - if (!s) - return NULL; - - free(t); - t = s; - } - - if (cap & LLDP_SYSTEM_CAPABILITIES_ROUTER) { - s = strjoin(t, lldp_system_capability_to_string(LLDP_SYSTEM_CAPABILITIES_ROUTER), " ", NULL); - if (!s) - return NULL; - - free(t); - t = s; - } - - if (cap & LLDP_SYSTEM_CAPABILITIES_PHONE) { - s = strjoin(t, lldp_system_capability_to_string(LLDP_SYSTEM_CAPABILITIES_PHONE), " ", NULL); - if (!s) - return NULL; - - free(t); - t = s; - } - - if (cap & LLDP_SYSTEM_CAPABILITIES_DOCSIS) { - s = strjoin(t, lldp_system_capability_to_string(LLDP_SYSTEM_CAPABILITIES_DOCSIS), " ", NULL); - if (!s) - return NULL; - - free(t); - t = s; - } - - if (cap & LLDP_SYSTEM_CAPABILITIES_STATION) { - s = strjoin(t, lldp_system_capability_to_string(LLDP_SYSTEM_CAPABILITIES_STATION), " ", NULL); - if (!s) - return NULL; - - free(t); - t = s; - } - - if (cap & LLDP_SYSTEM_CAPABILITIES_CVLAN) { - s = strjoin(t, lldp_system_capability_to_string(LLDP_SYSTEM_CAPABILITIES_CVLAN), " ", NULL); - if (!s) - return NULL; - - free(t); - t = s; - } - - if (cap & LLDP_SYSTEM_CAPABILITIES_SVLAN) { - s = strjoin(t, lldp_system_capability_to_string(LLDP_SYSTEM_CAPABILITIES_SVLAN), " ", NULL); - if (!s) - return NULL; - - free(t); - t = s; - } - - if (cap & LLDP_SYSTEM_CAPABILITIES_TPMR) { - s = strappend(t, lldp_system_capability_to_string(LLDP_SYSTEM_CAPABILITIES_TPMR)); - if (!s) - return NULL; - - free(t); - } - - if (!s) { - s = strappend(t, lldp_system_capability_to_string(_LLDP_SYSTEM_CAPABILITIES_MAX)); - if (!s) - return NULL; - - free(t); - } - - t = strappend(s, "]"); - if (!t) - return NULL; - - free(s); - capability = t; - - s = NULL; - t = NULL; - - return capability; -} - -static int link_lldp_status(int argc, char *argv[], void *userdata) { - _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL; - _cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL; - _cleanup_free_ LinkInfo *links = NULL; - const char *state, *word; - - double ttl = -1; - uint32_t capability; - int i, r, c, j; - size_t ll; - char **s; - - pager_open_if_enabled(); - - r = sd_rtnl_open(&rtnl, 0); - if (r < 0) - return log_error_errno(r, "Failed to connect to netlink: %m"); - - r = sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, 0); - if (r < 0) - return rtnl_log_create_error(r); - - r = sd_rtnl_message_request_dump(req, true); - if (r < 0) - return rtnl_log_create_error(r); - - r = sd_rtnl_call(rtnl, req, 0, &reply); - if (r < 0) - return log_error_errno(r, "Failed to enumerate links: %m"); - - c = decode_and_sort_links(reply, &links); - if (c < 0) - return rtnl_log_parse_error(c); - - if (arg_legend) - printf("%s %16s %24s %16s %16s\n", "Local Intf", "Device ID", "Port ID", "TTL", "Capability"); - - for (i = j = 0; i < c; i++) { - _cleanup_free_ char *chassis = NULL, *port = NULL, *cap = NULL, *lldp = NULL; - _cleanup_strv_free_ char **l = NULL; - - r = sd_network_link_get_lldp(links[i].ifindex, &lldp); - if (r < 0) - continue; - - l = strv_split_newlines(lldp); - if (!l) - return -ENOMEM; - - STRV_FOREACH(s, l) { - FOREACH_WORD_QUOTED(word, ll, *s, state) { - _cleanup_free_ char *t = NULL, *a = NULL, *b = NULL; - - t = strndup(word, ll); - if (!t) - return -ENOMEM; - - r = split_pair(t, "=", &a, &b); - if (r < 0) - continue; - - if (streq(a, "_Chassis")) { - r = free_and_strdup(&chassis, b); - if (r < 0) - return r; - - } else if (streq(a, "_Port")) { - r = free_and_strdup(&port, b); - if (r < 0) - return r; - - } else if (streq(a, "_TTL")) { - long long unsigned x = 0; - usec_t time; - - r = safe_atollu(b, &x); - if (r < 0 || (usec_t) x != x) - return log_warning_errno(r < 0 ? r : ERANGE, - "Failed to parse TTL \"%s\": %m", b); - - time = now(CLOCK_BOOTTIME); - if (x < time) - continue; - - ttl = (double) (x - time) / USEC_PER_SEC; - - } else if (streq(a, "_CAP")) { - sscanf(b, "%x", &capability); - - cap = lldp_system_caps(capability); - } - - } - - if (ttl >= 0) { - printf("%10s %24s %16s %16f %16s\n", - links[i].name, - strna(chassis), strna(port), - ttl, cap); - j++; - } - } - } - - if (arg_legend) { - printf("\nCapability Codes:\n" - "(O) - Other, (P) - Repeater, (B) - Bridge , (W) - WLAN Access Point, (R) = Router,\n" - "(T) - Telephone, (D) - Data Over Cable Service Interface Specifications, (A) - Station,\n" - "(C) - Customer VLAN, (S) - Service VLAN, (M) - Two-port MAC Relay (TPMR)\n\n"); - - printf("Total entries displayed: %d\n", j); - } - - return 0; -} - -static void help(void) { - printf("%s [OPTIONS...]\n\n" - "Query and control the networking subsystem.\n\n" - " -h --help Show this help\n" - " --version Show package version\n" - " --no-pager Do not pipe output into a pager\n" - " --no-legend Do not show the headers and footers\n" - " -a --all Show status for all links\n\n" - "Commands:\n" - " list List links\n" - " status [LINK...] Show link status\n" - " lldp Show lldp information\n" - , program_invocation_short_name); -} - -static int parse_argv(int argc, char *argv[]) { - - enum { - ARG_VERSION = 0x100, - ARG_NO_PAGER, - ARG_NO_LEGEND, - }; - - static const struct option options[] = { - { "help", no_argument, NULL, 'h' }, - { "version", no_argument, NULL, ARG_VERSION }, - { "no-pager", no_argument, NULL, ARG_NO_PAGER }, - { "no-legend", no_argument, NULL, ARG_NO_LEGEND }, - { "all", no_argument, NULL, 'a' }, - {} - }; - - int c; - - assert(argc >= 0); - assert(argv); - - while ((c = getopt_long(argc, argv, "ha", options, NULL)) >= 0) { - - switch (c) { - - case 'h': - help(); - return 0; - - case ARG_VERSION: - puts(PACKAGE_STRING); - puts(SYSTEMD_FEATURES); - return 0; - - case ARG_NO_PAGER: - arg_no_pager = true; - break; - - case ARG_NO_LEGEND: - arg_legend = false; - break; - - case 'a': - arg_all = true; - break; - - case '?': - return -EINVAL; - - default: - assert_not_reached("Unhandled option"); - } - } - - return 1; -} - -static int networkctl_main(int argc, char *argv[]) { - const Verb verbs[] = { - { "list", VERB_ANY, 1, VERB_DEFAULT, list_links }, - { "status", 1, VERB_ANY, 0, link_status }, - { "lldp", VERB_ANY, 1, VERB_DEFAULT, link_lldp_status }, - {} - }; - - return dispatch_verb(argc, argv, verbs, NULL); -} - -int main(int argc, char* argv[]) { - int r; - - log_parse_environment(); - log_open(); - - r = parse_argv(argc, argv); - if (r <= 0) - goto finish; - - r = networkctl_main(argc, argv); - -finish: - pager_close(); - - return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; -} diff --git a/src/network/networkd-address-pool.c b/src/network/networkd-address-pool.c deleted file mode 100644 index 584a956a7e..0000000000 --- a/src/network/networkd-address-pool.c +++ /dev/null @@ -1,166 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2014 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - - -#include "networkd.h" -#include "networkd-link.h" - -int address_pool_new( - Manager *m, - AddressPool **ret, - int family, - const union in_addr_union *u, - unsigned prefixlen) { - - AddressPool *p; - - assert(m); - assert(ret); - assert(u); - - p = new0(AddressPool, 1); - if (!p) - return -ENOMEM; - - p->manager = m; - p->family = family; - p->prefixlen = prefixlen; - p->in_addr = *u; - - LIST_PREPEND(address_pools, m->address_pools, p); - - *ret = p; - return 0; -} - -int address_pool_new_from_string( - Manager *m, - AddressPool **ret, - int family, - const char *p, - unsigned prefixlen) { - - union in_addr_union u; - int r; - - assert(m); - assert(ret); - assert(p); - - r = in_addr_from_string(family, p, &u); - if (r < 0) - return r; - - return address_pool_new(m, ret, family, &u, prefixlen); -} - -void address_pool_free(AddressPool *p) { - - if (!p) - return; - - if (p->manager) - LIST_REMOVE(address_pools, p->manager->address_pools, p); - - free(p); -} - -static bool address_pool_prefix_is_taken( - AddressPool *p, - const union in_addr_union *u, - unsigned prefixlen) { - - Iterator i; - Link *l; - Network *n; - - assert(p); - assert(u); - - HASHMAP_FOREACH(l, p->manager->links, i) { - Address *a; - - /* Don't clash with assigned addresses */ - LIST_FOREACH(addresses, a, l->addresses) { - if (a->family != p->family) - continue; - - if (in_addr_prefix_intersect(p->family, u, prefixlen, &a->in_addr, a->prefixlen)) - return true; - } - - /* Don't clash with addresses already pulled from the pool, but not assigned yet */ - LIST_FOREACH(addresses, a, l->pool_addresses) { - if (a->family != p->family) - continue; - - if (in_addr_prefix_intersect(p->family, u, prefixlen, &a->in_addr, a->prefixlen)) - return true; - } - } - - /* And don't clash with configured but un-assigned addresses either */ - LIST_FOREACH(networks, n, p->manager->networks) { - Address *a; - - LIST_FOREACH(addresses, a, n->static_addresses) { - if (a->family != p->family) - continue; - - if (in_addr_prefix_intersect(p->family, u, prefixlen, &a->in_addr, a->prefixlen)) - return true; - } - } - - return false; -} - -int address_pool_acquire(AddressPool *p, unsigned prefixlen, union in_addr_union *found) { - union in_addr_union u; - - assert(p); - assert(prefixlen > 0); - assert(found); - - if (p->prefixlen > prefixlen) - return 0; - - u = p->in_addr; - for (;;) { - if (!address_pool_prefix_is_taken(p, &u, prefixlen)) { - _cleanup_free_ char *s = NULL; - - in_addr_to_string(p->family, &u, &s); - log_debug("Found range %s/%u", strna(s), prefixlen); - - *found = u; - return 1; - } - - if (!in_addr_prefix_next(p->family, &u, prefixlen)) - return 0; - - if (!in_addr_prefix_intersect(p->family, &p->in_addr, p->prefixlen, &u, prefixlen)) - return 0; - } - - return 0; -} diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c deleted file mode 100644 index 85acc49945..0000000000 --- a/src/network/networkd-address.c +++ /dev/null @@ -1,635 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2013 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#include <net/if.h> - -#include "utf8.h" -#include "util.h" -#include "conf-parser.h" -#include "fw-util.h" -#include "networkd.h" -#include "networkd-link.h" - -static void address_init(Address *address) { - assert(address); - - 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; -} - -int address_new_static(Network *network, unsigned section, Address **ret) { - _cleanup_address_free_ Address *address = NULL; - - if (section) { - address = hashmap_get(network->addresses_by_section, UINT_TO_PTR(section)); - if (address) { - *ret = address; - address = NULL; - - return 0; - } - } - - address = new0(Address, 1); - if (!address) - return -ENOMEM; - - address_init(address); - - address->network = network; - - LIST_APPEND(addresses, network->static_addresses, address); - - if (section) { - address->section = section; - hashmap_put(network->addresses_by_section, - UINT_TO_PTR(address->section), address); - } - - *ret = address; - address = NULL; - - return 0; -} - -int address_new_dynamic(Address **ret) { - _cleanup_address_free_ Address *address = NULL; - - address = new0(Address, 1); - if (!address) - return -ENOMEM; - - address_init(address); - - *ret = address; - address = NULL; - - return 0; -} - -void address_free(Address *address) { - if (!address) - return; - - if (address->network) { - LIST_REMOVE(addresses, address->network->static_addresses, address); - - if (address->section) - hashmap_remove(address->network->addresses_by_section, - UINT_TO_PTR(address->section)); - } - - free(address); -} - -int address_establish(Address *address, Link *link) { - bool masq; - int r; - - assert(address); - assert(link); - - masq = link->network && - link->network->ip_masquerade && - address->family == AF_INET && - address->scope < RT_SCOPE_LINK; - - /* Add firewall entry if this is requested */ - if (address->ip_masquerade_done != masq) { - union in_addr_union masked = address->in_addr; - in_addr_mask(address->family, &masked, address->prefixlen); - - r = fw_add_masquerade(masq, AF_INET, 0, &masked, address->prefixlen, NULL, NULL, 0); - if (r < 0) - log_link_warning_errno(link, r, "Could not enable IP masquerading: %m"); - - address->ip_masquerade_done = masq; - } - - return 0; -} - -int address_release(Address *address, Link *link) { - int r; - - assert(address); - assert(link); - - /* Remove masquerading firewall entry if it was added */ - if (address->ip_masquerade_done) { - union in_addr_union masked = address->in_addr; - in_addr_mask(address->family, &masked, address->prefixlen); - - r = fw_add_masquerade(false, AF_INET, 0, &masked, address->prefixlen, NULL, NULL, 0); - if (r < 0) - log_link_warning_errno(link, r, "Failed to disable IP masquerading: %m"); - - address->ip_masquerade_done = false; - } - - return 0; -} - -int address_drop(Address *address, Link *link, - sd_rtnl_message_handler_t callback) { - _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL; - int r; - - assert(address); - assert(address->family == AF_INET || address->family == AF_INET6); - assert(link); - assert(link->ifindex > 0); - assert(link->manager); - assert(link->manager->rtnl); - - address_release(address, link); - - r = sd_rtnl_message_new_addr(link->manager->rtnl, &req, RTM_DELADDR, - link->ifindex, address->family); - if (r < 0) - return log_error_errno(r, "Could not allocate RTM_DELADDR message: %m"); - - r = sd_rtnl_message_addr_set_prefixlen(req, address->prefixlen); - if (r < 0) - return log_error_errno(r, "Could not set prefixlen: %m"); - - if (address->family == AF_INET) - r = sd_rtnl_message_append_in_addr(req, IFA_LOCAL, &address->in_addr.in); - else if (address->family == AF_INET6) - r = sd_rtnl_message_append_in6_addr(req, IFA_LOCAL, &address->in_addr.in6); - if (r < 0) - return log_error_errno(r, "Could not append IFA_LOCAL attribute: %m"); - - r = sd_rtnl_call_async(link->manager->rtnl, req, callback, link, 0, NULL); - if (r < 0) - return log_error_errno(r, "Could not send rtnetlink message: %m"); - - link_ref(link); - - return 0; -} - -int address_update(Address *address, Link *link, - sd_rtnl_message_handler_t callback) { - _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL; - int r; - - assert(address); - assert(address->family == AF_INET || address->family == AF_INET6); - assert(link->ifindex > 0); - assert(link->manager); - assert(link->manager->rtnl); - - r = sd_rtnl_message_new_addr_update(link->manager->rtnl, &req, - link->ifindex, address->family); - if (r < 0) - return log_error_errno(r, "Could not allocate RTM_NEWADDR message: %m"); - - r = sd_rtnl_message_addr_set_prefixlen(req, address->prefixlen); - if (r < 0) - return log_error_errno(r, "Could not set prefixlen: %m"); - - address->flags |= IFA_F_PERMANENT; - - r = sd_rtnl_message_addr_set_flags(req, address->flags & 0xff); - if (r < 0) - return log_error_errno(r, "Could not set flags: %m"); - - if (address->flags & ~0xff) { - r = sd_rtnl_message_append_u32(req, IFA_FLAGS, address->flags); - if (r < 0) - return log_error_errno(r, "Could not set extended flags: %m"); - } - - r = sd_rtnl_message_addr_set_scope(req, address->scope); - if (r < 0) - return log_error_errno(r, "Could not set scope: %m"); - - if (address->family == AF_INET) - r = sd_rtnl_message_append_in_addr(req, IFA_LOCAL, &address->in_addr.in); - else if (address->family == AF_INET6) - r = sd_rtnl_message_append_in6_addr(req, IFA_LOCAL, &address->in_addr.in6); - if (r < 0) - return log_error_errno(r, "Could not append IFA_LOCAL attribute: %m"); - - if (address->family == AF_INET) { - r = sd_rtnl_message_append_in_addr(req, IFA_BROADCAST, &address->broadcast); - if (r < 0) - return log_error_errno(r, "Could not append IFA_BROADCAST attribute: %m"); - } - - if (address->label) { - r = sd_rtnl_message_append_string(req, IFA_LABEL, address->label); - if (r < 0) - return log_error_errno(r, "Could not append IFA_LABEL attribute: %m"); - } - - r = sd_rtnl_message_append_cache_info(req, IFA_CACHEINFO, &address->cinfo); - if (r < 0) - return log_error_errno(r, "Could not append IFA_CACHEINFO attribute: %m"); - - r = sd_rtnl_call_async(link->manager->rtnl, req, callback, link, 0, NULL); - if (r < 0) - return log_error_errno(r, "Could not send rtnetlink message: %m"); - - link_ref(link); - - return 0; -} - -static int address_acquire(Link *link, Address *original, Address **ret) { - union in_addr_union in_addr = {}; - struct in_addr broadcast = {}; - _cleanup_address_free_ Address *na = NULL; - int r; - - assert(link); - assert(original); - assert(ret); - - /* Something useful was configured? just use it */ - if (in_addr_is_null(original->family, &original->in_addr) <= 0) - return 0; - - /* The address is configured to be 0.0.0.0 or [::] by the user? - * Then let's acquire something more useful from the pool. */ - r = manager_address_pool_acquire(link->manager, original->family, original->prefixlen, &in_addr); - if (r < 0) { - log_link_error(link, "Failed to acquire address from pool: %s", strerror(-r)); - return r; - } - if (r == 0) { - log_link_error(link, "Couldn't find free address for interface, all taken."); - return -EBUSY; - } - - if (original->family == AF_INET) { - /* Pick first address in range for ourselves ... */ - in_addr.in.s_addr = in_addr.in.s_addr | htobe32(1); - - /* .. and use last as broadcast address */ - broadcast.s_addr = in_addr.in.s_addr | htobe32(0xFFFFFFFFUL >> original->prefixlen); - } else if (original->family == AF_INET6) - in_addr.in6.s6_addr[15] |= 1; - - r = address_new_dynamic(&na); - if (r < 0) - return r; - - na->family = original->family; - na->prefixlen = original->prefixlen; - na->scope = original->scope; - na->cinfo = original->cinfo; - - if (original->label) { - na->label = strdup(original->label); - if (!na->label) - return -ENOMEM; - } - - na->broadcast = broadcast; - na->in_addr = in_addr; - - LIST_PREPEND(addresses, link->pool_addresses, na); - - *ret = na; - na = NULL; - - return 0; -} - -int address_configure(Address *address, Link *link, - sd_rtnl_message_handler_t callback) { - _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL; - int r; - - assert(address); - assert(address->family == AF_INET || address->family == AF_INET6); - assert(link); - assert(link->ifindex > 0); - assert(link->manager); - assert(link->manager->rtnl); - - r = address_acquire(link, address, &address); - if (r < 0) - return r; - - r = sd_rtnl_message_new_addr(link->manager->rtnl, &req, RTM_NEWADDR, - link->ifindex, address->family); - if (r < 0) - return log_error_errno(r, "Could not allocate RTM_NEWADDR message: %m"); - - r = sd_rtnl_message_addr_set_prefixlen(req, address->prefixlen); - if (r < 0) - return log_error_errno(r, "Could not set prefixlen: %m"); - - address->flags |= IFA_F_PERMANENT; - - r = sd_rtnl_message_addr_set_flags(req, (address->flags & 0xff)); - if (r < 0) - return log_error_errno(r, "Could not set flags: %m"); - - if (address->flags & ~0xff) { - r = sd_rtnl_message_append_u32(req, IFA_FLAGS, address->flags); - if (r < 0) - return log_error_errno(r, "Could not set extended flags: %m"); - } - - r = sd_rtnl_message_addr_set_scope(req, address->scope); - if (r < 0) - return log_error_errno(r, "Could not set scope: %m"); - - if (address->family == AF_INET) - r = sd_rtnl_message_append_in_addr(req, IFA_LOCAL, &address->in_addr.in); - else if (address->family == AF_INET6) - r = sd_rtnl_message_append_in6_addr(req, IFA_LOCAL, &address->in_addr.in6); - if (r < 0) - return log_error_errno(r, "Could not append IFA_LOCAL attribute: %m"); - - if (!in_addr_is_null(address->family, &address->in_addr_peer)) { - if (address->family == AF_INET) - r = sd_rtnl_message_append_in_addr(req, IFA_ADDRESS, &address->in_addr_peer.in); - else if (address->family == AF_INET6) - r = sd_rtnl_message_append_in6_addr(req, IFA_ADDRESS, &address->in_addr_peer.in6); - if (r < 0) - return log_error_errno(r, "Could not append IFA_ADDRESS attribute: %m"); - } else { - if (address->family == AF_INET) { - r = sd_rtnl_message_append_in_addr(req, IFA_BROADCAST, &address->broadcast); - if (r < 0) - return log_error_errno(r, "Could not append IFA_BROADCAST attribute: %m"); - } - } - - if (address->label) { - r = sd_rtnl_message_append_string(req, IFA_LABEL, address->label); - if (r < 0) - return log_error_errno(r, "Could not append IFA_LABEL attribute: %m"); - } - - r = sd_rtnl_message_append_cache_info(req, IFA_CACHEINFO, - &address->cinfo); - if (r < 0) - return log_error_errno(r, "Could not append IFA_CACHEINFO attribute: %m"); - - r = sd_rtnl_call_async(link->manager->rtnl, req, callback, link, 0, NULL); - if (r < 0) - return log_error_errno(r, "Could not send rtnetlink message: %m"); - - link_ref(link); - - address_establish(address, link); - - return 0; -} - -int config_parse_broadcast( - const char *unit, - const char *filename, - unsigned line, - const char *section, - unsigned section_line, - const char *lvalue, - int ltype, - const char *rvalue, - void *data, - void *userdata) { - - Network *network = userdata; - _cleanup_address_free_ Address *n = NULL; - int r; - - assert(filename); - assert(section); - assert(lvalue); - assert(rvalue); - assert(data); - - r = address_new_static(network, section_line, &n); - if (r < 0) - return r; - - if (n->family == AF_INET6) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Broadcast is not valid for IPv6 addresses, ignoring assignment: %s", rvalue); - return 0; - } - - r = in_addr_from_string(AF_INET, rvalue, (union in_addr_union*) &n->broadcast); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Broadcast is invalid, ignoring assignment: %s", rvalue); - return 0; - } - - n->family = AF_INET; - n = NULL; - - return 0; -} - -int config_parse_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) { - - Network *network = userdata; - _cleanup_address_free_ Address *n = NULL; - const char *address, *e; - union in_addr_union buffer; - int r, f; - - assert(filename); - assert(section); - assert(lvalue); - assert(rvalue); - assert(data); - - if (streq(section, "Network")) { - /* we are not in an Address section, so treat - * this as the special '0' section */ - section_line = 0; - } - - r = address_new_static(network, section_line, &n); - if (r < 0) - return r; - - /* Address=address/prefixlen */ - - /* prefixlen */ - e = strchr(rvalue, '/'); - if (e) { - unsigned i; - r = safe_atou(e + 1, &i); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Prefix length is invalid, ignoring assignment: %s", e + 1); - return 0; - } - - n->prefixlen = (unsigned char) i; - - address = strndupa(rvalue, e - rvalue); - } else - address = rvalue; - - r = in_addr_from_string_auto(address, &f, &buffer); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Address is invalid, ignoring assignment: %s", address); - return 0; - } - - if (!e && f == AF_INET) { - r = in_addr_default_prefixlen(&buffer.in, &n->prefixlen); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Prefix length not specified, and a default one can not be deduced for '%s', ignoring assignment", address); - return 0; - } - } - - if (n->family != AF_UNSPEC && f != n->family) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Address is incompatible, ignoring assignment: %s", address); - return 0; - } - - n->family = f; - - if (streq(lvalue, "Address")) - n->in_addr = buffer; - else - n->in_addr_peer = buffer; - - if (n->family == AF_INET && n->broadcast.s_addr == 0) - n->broadcast.s_addr = n->in_addr.in.s_addr | htonl(0xfffffffflu >> n->prefixlen); - - n = NULL; - - return 0; -} - -int config_parse_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) { - Network *network = userdata; - _cleanup_address_free_ Address *n = NULL; - char *label; - int r; - - assert(filename); - assert(section); - assert(lvalue); - assert(rvalue); - assert(data); - - r = address_new_static(network, section_line, &n); - if (r < 0) - return r; - - label = strdup(rvalue); - if (!label) - return log_oom(); - - if (!ascii_is_valid(label) || strlen(label) >= IFNAMSIZ) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Interface label is not ASCII clean or is too" - " long, ignoring assignment: %s", rvalue); - free(label); - return 0; - } - - free(n->label); - if (*label) - n->label = label; - else { - free(label); - n->label = NULL; - } - - n = NULL; - - return 0; -} - -bool address_equal(Address *a1, Address *a2) { - /* same object */ - if (a1 == a2) - return true; - - /* one, but not both, is NULL */ - if (!a1 || !a2) - return false; - - if (a1->family != a2->family) - return false; - - switch (a1->family) { - /* use the same notion of equality as the kernel does */ - case AF_UNSPEC: - return true; - - case AF_INET: - if (a1->prefixlen != a2->prefixlen) - return false; - else if (a1->prefixlen == 0) - /* make sure we don't try to shift by 32. - * See ISO/IEC 9899:TC3 § 6.5.7.3. */ - return true; - else { - uint32_t b1, b2; - - b1 = be32toh(a1->in_addr.in.s_addr); - b2 = be32toh(a2->in_addr.in.s_addr); - - return (b1 >> (32 - a1->prefixlen)) == (b2 >> (32 - a1->prefixlen)); - } - - case AF_INET6: { - uint64_t *b1, *b2; - - b1 = (uint64_t*)&a1->in_addr.in6; - b2 = (uint64_t*)&a2->in_addr.in6; - - return (((b1[0] ^ b2[0]) | (b1[1] ^ b2[1])) == 0UL); - } - - default: - assert_not_reached("Invalid address family"); - } -} diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c deleted file mode 100644 index 38321905e6..0000000000 --- a/src/network/networkd-dhcp4.c +++ /dev/null @@ -1,681 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2013-2014 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#include <netinet/ether.h> -#include <linux/if.h> - -#include "networkd-link.h" -#include "network-internal.h" -#include "dhcp-lease-internal.h" - -static int dhcp4_route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, - void *userdata) { - _cleanup_link_unref_ Link *link = userdata; - int r; - - assert(link); - assert(link->dhcp4_messages); - - link->dhcp4_messages --; - - r = sd_rtnl_message_get_errno(m); - if (r < 0 && r != -EEXIST) { - log_link_error(link, "could not set DHCPv4 route: %s", - strerror(-r)); - link_enter_failed(link); - } - - if (!link->dhcp4_messages) { - link->dhcp4_configured = true; - link_client_handler(link); - } - - return 1; -} - -static int link_set_dhcp_routes(Link *link) { - struct in_addr gateway; - struct sd_dhcp_route *static_routes; - int r, n, i; - - assert(link); - assert(link->dhcp_lease); - - r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway); - if (r < 0 && r != -ENOENT) { - log_link_warning(link, - "DHCP error: could not get gateway: %s", - strerror(-r)); - return r; - } - if (r >= 0) { - struct in_addr address; - _cleanup_route_free_ Route *route = NULL; - _cleanup_route_free_ Route *route_gw = NULL; - - r = sd_dhcp_lease_get_address(link->dhcp_lease, &address); - if (r < 0) { - log_link_warning(link, - "DHCP error: could not get address: %s", - strerror(-r)); - return r; - } - - r = route_new_dynamic(&route, RTPROT_DHCP); - if (r < 0) { - log_link_error(link, - "Could not allocate route: %s", - strerror(-r)); - return r; - } - - r = route_new_dynamic(&route_gw, RTPROT_DHCP); - if (r < 0) { - log_link_error(link, - "Could not allocate route: %s", - strerror(-r)); - return r; - } - - /* The dhcp netmask may mask out the gateway. Add an explicit - * route for the gw host so that we can route no matter the - * netmask or existing kernel route tables. */ - route_gw->family = AF_INET; - route_gw->dst_addr.in = gateway; - route_gw->dst_prefixlen = 32; - route_gw->prefsrc_addr.in = address; - route_gw->scope = RT_SCOPE_LINK; - route_gw->metrics = link->network->dhcp_route_metric; - - r = route_configure(route_gw, link, &dhcp4_route_handler); - if (r < 0) { - log_link_warning(link, - "could not set host route: %s", - strerror(-r)); - return r; - } - - link->dhcp4_messages ++; - - route->family = AF_INET; - route->in_addr.in = gateway; - route->prefsrc_addr.in = address; - route->metrics = link->network->dhcp_route_metric; - - r = route_configure(route, link, &dhcp4_route_handler); - if (r < 0) { - log_link_warning(link, - "could not set routes: %s", - strerror(-r)); - link_enter_failed(link); - return r; - } - - link->dhcp4_messages ++; - } - - n = sd_dhcp_lease_get_routes(link->dhcp_lease, &static_routes); - if (n == -ENOENT) - return 0; - if (n < 0) { - log_link_warning(link, - "DHCP error: could not get routes: %s", - strerror(-n)); - - return n; - } - - for (i = 0; i < n; i++) { - _cleanup_route_free_ Route *route = NULL; - - r = route_new_dynamic(&route, RTPROT_DHCP); - if (r < 0) { - log_link_error(link, "Could not allocate route: %s", - strerror(-r)); - return r; - } - - route->family = AF_INET; - route->in_addr.in = static_routes[i].gw_addr; - route->dst_addr.in = static_routes[i].dst_addr; - route->dst_prefixlen = static_routes[i].dst_prefixlen; - route->metrics = link->network->dhcp_route_metric; - - r = route_configure(route, link, &dhcp4_route_handler); - if (r < 0) { - log_link_warning(link, - "could not set host route: %s", - strerror(-r)); - return r; - } - - link->dhcp4_messages ++; - } - - return 0; -} - -static int dhcp_lease_lost(Link *link) { - _cleanup_address_free_ Address *address = NULL; - struct in_addr addr; - struct in_addr netmask; - struct in_addr gateway; - unsigned prefixlen = 0; - int r; - - assert(link); - assert(link->dhcp_lease); - - log_link_warning(link, "DHCP lease lost"); - - if (link->network->dhcp_routes) { - struct sd_dhcp_route *routes; - int n, i; - - n = sd_dhcp_lease_get_routes(link->dhcp_lease, &routes); - if (n >= 0) { - for (i = 0; i < n; i++) { - _cleanup_route_free_ Route *route = NULL; - - r = route_new_dynamic(&route, RTPROT_UNSPEC); - if (r >= 0) { - route->family = AF_INET; - route->in_addr.in = routes[i].gw_addr; - route->dst_addr.in = routes[i].dst_addr; - route->dst_prefixlen = routes[i].dst_prefixlen; - - route_drop(route, link, - &link_route_drop_handler); - } - } - } - } - - r = address_new_dynamic(&address); - if (r >= 0) { - r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway); - if (r >= 0) { - _cleanup_route_free_ Route *route_gw = NULL; - _cleanup_route_free_ Route *route = NULL; - - r = route_new_dynamic(&route_gw, RTPROT_UNSPEC); - if (r >= 0) { - route_gw->family = AF_INET; - route_gw->dst_addr.in = gateway; - route_gw->dst_prefixlen = 32; - route_gw->scope = RT_SCOPE_LINK; - - route_drop(route_gw, link, - &link_route_drop_handler); - } - - r = route_new_dynamic(&route, RTPROT_UNSPEC); - if (r >= 0) { - route->family = AF_INET; - route->in_addr.in = gateway; - - route_drop(route, link, - &link_route_drop_handler); - } - } - - r = sd_dhcp_lease_get_address(link->dhcp_lease, &addr); - if (r >= 0) { - r = sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask); - if (r >= 0) - prefixlen = in_addr_netmask_to_prefixlen(&netmask); - - address->family = AF_INET; - address->in_addr.in = addr; - address->prefixlen = prefixlen; - - address_drop(address, link, &link_address_drop_handler); - } - } - - if (link->network->dhcp_mtu) { - uint16_t mtu; - - r = sd_dhcp_lease_get_mtu(link->dhcp_lease, &mtu); - if (r >= 0 && link->original_mtu != mtu) { - r = link_set_mtu(link, link->original_mtu); - if (r < 0) { - log_link_warning(link, - "DHCP error: could not reset MTU"); - link_enter_failed(link); - return r; - } - } - } - - if (link->network->dhcp_hostname) { - const char *hostname = NULL; - - r = sd_dhcp_lease_get_hostname(link->dhcp_lease, &hostname); - if (r >= 0 && hostname) { - r = link_set_hostname(link, ""); - if (r < 0) - log_link_error(link, - "Failed to reset transient hostname"); - } - } - - link->dhcp_lease = sd_dhcp_lease_unref(link->dhcp_lease); - link->dhcp4_configured = false; - - return 0; -} - -static int dhcp4_address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, - void *userdata) { - _cleanup_link_unref_ Link *link = userdata; - int r; - - assert(link); - - r = sd_rtnl_message_get_errno(m); - if (r < 0 && r != -EEXIST) { - log_link_error(link, "could not set DHCPv4 address: %s", - strerror(-r)); - link_enter_failed(link); - } else if (r >= 0) - link_rtnl_process_address(rtnl, m, link->manager); - - link_set_dhcp_routes(link); - - return 1; -} - -static int dhcp4_update_address(Link *link, - struct in_addr *address, - struct in_addr *netmask, - uint32_t lifetime) { - _cleanup_address_free_ Address *addr = NULL; - unsigned prefixlen; - int r; - - assert(address); - assert(netmask); - assert(lifetime); - - prefixlen = in_addr_netmask_to_prefixlen(netmask); - - r = address_new_dynamic(&addr); - if (r < 0) - return r; - - addr->family = AF_INET; - addr->in_addr.in.s_addr = address->s_addr; - addr->cinfo.ifa_prefered = lifetime; - addr->cinfo.ifa_valid = lifetime; - addr->prefixlen = prefixlen; - addr->broadcast.s_addr = address->s_addr | ~netmask->s_addr; - - /* use update rather than configure so that we will update the - * lifetime of an existing address if it has already been configured */ - r = address_update(addr, link, &dhcp4_address_handler); - if (r < 0) - return r; - - return 0; -} - -static int dhcp_lease_renew(sd_dhcp_client *client, Link *link) { - sd_dhcp_lease *lease; - struct in_addr address; - struct in_addr netmask; - uint32_t lifetime = CACHE_INFO_INFINITY_LIFE_TIME; - int r; - - assert(link); - assert(client); - assert(link->network); - - r = sd_dhcp_client_get_lease(client, &lease); - if (r < 0) { - log_link_warning(link, "DHCP error: no lease %s", - strerror(-r)); - return r; - } - - sd_dhcp_lease_unref(link->dhcp_lease); - link->dhcp4_configured = false; - link->dhcp_lease = lease; - - r = sd_dhcp_lease_get_address(lease, &address); - if (r < 0) { - log_link_warning(link, "DHCP error: no address: %s", - strerror(-r)); - return r; - } - - r = sd_dhcp_lease_get_netmask(lease, &netmask); - if (r < 0) { - log_link_warning(link, "DHCP error: no netmask: %s", - strerror(-r)); - return r; - } - - if (!link->network->dhcp_critical) { - r = sd_dhcp_lease_get_lifetime(link->dhcp_lease, - &lifetime); - if (r < 0) { - log_link_warning(link, - "DHCP error: no lifetime: %s", - strerror(-r)); - return r; - } - } - - r = dhcp4_update_address(link, &address, &netmask, lifetime); - if (r < 0) { - log_link_warning(link, "could not update IP address: %s", - strerror(-r)); - link_enter_failed(link); - return r; - } - - return 0; -} - -static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) { - sd_dhcp_lease *lease; - struct in_addr address; - struct in_addr netmask; - struct in_addr gateway; - unsigned prefixlen; - uint32_t lifetime = CACHE_INFO_INFINITY_LIFE_TIME; - int r; - - assert(client); - assert(link); - - r = sd_dhcp_client_get_lease(client, &lease); - if (r < 0) { - log_link_warning(link, "DHCP error: no lease: %s", - strerror(-r)); - return r; - } - - r = sd_dhcp_lease_get_address(lease, &address); - if (r < 0) { - log_link_warning(link, "DHCP error: no address: %s", - strerror(-r)); - return r; - } - - r = sd_dhcp_lease_get_netmask(lease, &netmask); - if (r < 0) { - log_link_warning(link, "DHCP error: no netmask: %s", - strerror(-r)); - return r; - } - - prefixlen = in_addr_netmask_to_prefixlen(&netmask); - - r = sd_dhcp_lease_get_router(lease, &gateway); - if (r < 0 && r != -ENOENT) { - log_link_warning(link, "DHCP error: could not get gateway: %s", - strerror(-r)); - return r; - } - - if (r >= 0) - log_link_struct(link, LOG_INFO, - "MESSAGE=%-*s: DHCPv4 address %u.%u.%u.%u/%u via %u.%u.%u.%u", - IFNAMSIZ, - link->ifname, - ADDRESS_FMT_VAL(address), - prefixlen, - ADDRESS_FMT_VAL(gateway), - "ADDRESS=%u.%u.%u.%u", - ADDRESS_FMT_VAL(address), - "PREFIXLEN=%u", - prefixlen, - "GATEWAY=%u.%u.%u.%u", - ADDRESS_FMT_VAL(gateway), - NULL); - else - log_link_struct(link, LOG_INFO, - "MESSAGE=%-*s: DHCPv4 address %u.%u.%u.%u/%u", - IFNAMSIZ, - link->ifname, - ADDRESS_FMT_VAL(address), - prefixlen, - "ADDRESS=%u.%u.%u.%u", - ADDRESS_FMT_VAL(address), - "PREFIXLEN=%u", - prefixlen, - NULL); - - link->dhcp_lease = lease; - - if (link->network->dhcp_mtu) { - uint16_t mtu; - - r = sd_dhcp_lease_get_mtu(lease, &mtu); - if (r >= 0) { - r = link_set_mtu(link, mtu); - if (r < 0) - log_link_error(link, "Failed to set MTU " - "to %" PRIu16, mtu); - } - } - - if (link->network->dhcp_hostname) { - const char *hostname; - - r = sd_dhcp_lease_get_hostname(lease, &hostname); - if (r >= 0) { - r = link_set_hostname(link, hostname); - if (r < 0) - log_link_error(link, - "Failed to set transient hostname to '%s'", - hostname); - } - } - - if (!link->network->dhcp_critical) { - r = sd_dhcp_lease_get_lifetime(link->dhcp_lease, - &lifetime); - if (r < 0) { - log_link_warning(link, - "DHCP error: no lifetime: %s", - strerror(-r)); - return r; - } - } - - r = dhcp4_update_address(link, &address, &netmask, lifetime); - if (r < 0) { - log_link_warning(link, "could not update IP address: %s", - strerror(-r)); - link_enter_failed(link); - return r; - } - - return 0; -} -static void dhcp4_handler(sd_dhcp_client *client, int event, void *userdata) { - Link *link = userdata; - int r = 0; - - assert(link); - assert(link->network); - assert(link->manager); - - if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) - return; - - switch (event) { - case DHCP_EVENT_EXPIRED: - case DHCP_EVENT_STOP: - case DHCP_EVENT_IP_CHANGE: - if (link->network->dhcp_critical) { - log_link_error(link, - "DHCPv4 connection considered system critical, ignoring request to reconfigure it."); - return; - } - - if (link->dhcp_lease) { - r = dhcp_lease_lost(link); - if (r < 0) { - link_enter_failed(link); - return; - } - } - - if (event == DHCP_EVENT_IP_CHANGE) { - r = dhcp_lease_acquired(client, link); - if (r < 0) { - link_enter_failed(link); - return; - } - } - - break; - case DHCP_EVENT_RENEW: - r = dhcp_lease_renew(client, link); - if (r < 0) { - link_enter_failed(link); - return; - } - break; - case DHCP_EVENT_IP_ACQUIRE: - r = dhcp_lease_acquired(client, link); - if (r < 0) { - link_enter_failed(link); - return; - } - break; - default: - if (event < 0) - log_link_warning(link, - "DHCP error: client failed: %s", - strerror(-event)); - else - log_link_warning(link, - "DHCP unknown event: %d", - event); - break; - } - - return; -} - -int dhcp4_configure(Link *link) { - int r; - - assert(link); - assert(link->network); - assert(IN_SET(link->network->dhcp, ADDRESS_FAMILY_YES, ADDRESS_FAMILY_IPV4)); - - r = sd_dhcp_client_new(&link->dhcp_client); - if (r < 0) - return r; - - r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0); - if (r < 0) - return r; - - r = sd_dhcp_client_set_mac(link->dhcp_client, - (const uint8_t *) &link->mac, - sizeof (link->mac), ARPHRD_ETHER); - if (r < 0) - return r; - - r = sd_dhcp_client_set_index(link->dhcp_client, link->ifindex); - if (r < 0) - return r; - - r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp4_handler, link); - if (r < 0) - return r; - - r = sd_dhcp_client_set_request_broadcast(link->dhcp_client, - link->network->dhcp_broadcast); - if (r < 0) - return r; - - if (link->mtu) { - r = sd_dhcp_client_set_mtu(link->dhcp_client, link->mtu); - if (r < 0) - return r; - } - - if (link->network->dhcp_mtu) { - r = sd_dhcp_client_set_request_option(link->dhcp_client, - DHCP_OPTION_INTERFACE_MTU); - if (r < 0) - return r; - } - - if (link->network->dhcp_routes) { - r = sd_dhcp_client_set_request_option(link->dhcp_client, - DHCP_OPTION_STATIC_ROUTE); - if (r < 0) - return r; - r = sd_dhcp_client_set_request_option(link->dhcp_client, - DHCP_OPTION_CLASSLESS_STATIC_ROUTE); - if (r < 0) - return r; - } - - if (link->network->dhcp_sendhost) { - _cleanup_free_ char *hostname = NULL; - - hostname = gethostname_malloc(); - if (!hostname) - return -ENOMEM; - - if (!is_localhost(hostname)) { - r = sd_dhcp_client_set_hostname(link->dhcp_client, - hostname); - if (r < 0) - return r; - } - } - - if (link->network->dhcp_vendor_class_identifier) { - r = sd_dhcp_client_set_vendor_class_identifier(link->dhcp_client, - link->network->dhcp_vendor_class_identifier); - if (r < 0) - return r; - } - - switch (link->network->dhcp_client_identifier) { - case DHCP_CLIENT_ID_DUID: - /* Library defaults to this. */ - break; - case DHCP_CLIENT_ID_MAC: - r = sd_dhcp_client_set_client_id(link->dhcp_client, - ARPHRD_ETHER, - (const uint8_t *) &link->mac, - sizeof (link->mac)); - if (r < 0) - return r; - break; - default: - assert_not_reached("Unknown client identifier type."); - } - - return 0; -} diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c deleted file mode 100644 index e863f4b347..0000000000 --- a/src/network/networkd-dhcp6.c +++ /dev/null @@ -1,325 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright (C) 2014 Intel Corporation. All rights reserved. - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#include <netinet/ether.h> -#include <linux/if.h> - -#include "networkd-link.h" -#include "network-internal.h" - -#include "sd-icmp6-nd.h" -#include "sd-dhcp6-client.h" - -static int dhcp6_lease_information_acquired(sd_dhcp6_client *client, - Link *link) { - return 0; -} - -static int dhcp6_address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, - void *userdata) { - _cleanup_link_unref_ Link *link = userdata; - int r; - - assert(link); - - r = sd_rtnl_message_get_errno(m); - if (r < 0 && r != -EEXIST) { - log_link_error(link, "Could not set DHCPv6 address: %s", - strerror(-r)); - - link_enter_failed(link); - - } else if (r >= 0) - link_rtnl_process_address(rtnl, m, link->manager); - - return 1; -} - -static int dhcp6_address_update(Link *link, struct in6_addr *ip6_addr, - uint8_t prefixlen, uint32_t lifetime_preferred, - uint32_t lifetime_valid) { - int r; - _cleanup_address_free_ Address *addr = NULL; - - r = address_new_dynamic(&addr); - if (r < 0) - return r; - - addr->family = AF_INET6; - memcpy(&addr->in_addr.in6, ip6_addr, sizeof(*ip6_addr)); - - addr->flags = IFA_F_NOPREFIXROUTE; - addr->prefixlen = 64; - - addr->cinfo.ifa_prefered = lifetime_preferred; - addr->cinfo.ifa_valid = lifetime_valid; - - log_link_struct(link, LOG_INFO, "MESSAGE=%-*s: DHCPv6 address "SD_ICMP6_ADDRESS_FORMAT_STR"/%d timeout preferred %d valid %d", - IFNAMSIZ, - link->ifname, SD_ICMP6_ADDRESS_FORMAT_VAL(addr->in_addr.in6), - addr->prefixlen, lifetime_preferred, lifetime_valid, - NULL); - - r = address_update(addr, link, dhcp6_address_handler); - if (r < 0) - log_link_warning(link, "Could not assign DHCPv6 address: %s", - strerror(-r)); - - return r; -} - -static int dhcp6_lease_address_acquired(sd_dhcp6_client *client, Link *link) { - int r; - sd_dhcp6_lease *lease; - struct in6_addr ip6_addr; - uint32_t lifetime_preferred, lifetime_valid; - uint8_t prefixlen; - - r = sd_dhcp6_client_get_lease(client, &lease); - if (r < 0) - return r; - - sd_dhcp6_lease_reset_address_iter(lease); - - while (sd_dhcp6_lease_get_address(lease, &ip6_addr, - &lifetime_preferred, - &lifetime_valid) >= 0) { - - r = sd_icmp6_ra_get_prefixlen(link->icmp6_router_discovery, - &ip6_addr, &prefixlen); - if (r < 0 && r != -EADDRNOTAVAIL) { - log_link_warning(link, "Could not get prefix information: %s", - strerror(-r)); - return r; - } - - if (r == -EADDRNOTAVAIL) - prefixlen = 128; - - r = dhcp6_address_update(link, &ip6_addr, prefixlen, - lifetime_preferred, lifetime_valid); - if (r < 0) - return r; - } - - return 0; -} - -static void dhcp6_handler(sd_dhcp6_client *client, int event, void *userdata) { - int r; - Link *link = userdata; - - assert(link); - assert(link->network); - assert(link->manager); - - if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) - return; - - switch(event) { - case DHCP6_EVENT_STOP: - case DHCP6_EVENT_RESEND_EXPIRE: - case DHCP6_EVENT_RETRANS_MAX: - log_link_debug(link, "DHCPv6 event %d", event); - break; - - case DHCP6_EVENT_IP_ACQUIRE: - r = dhcp6_lease_address_acquired(client, link); - if (r < 0) { - link_enter_failed(link); - return; - } - - /* fall through */ - case DHCP6_EVENT_INFORMATION_REQUEST: - r = dhcp6_lease_information_acquired(client, link); - if (r < 0) { - link_enter_failed(link); - return; - } - - break; - - default: - if (event < 0) - log_link_warning(link, "DHCPv6 error: %s", - strerror(-event)); - else - log_link_warning(link, "DHCPv6 unknown event: %d", - event); - return; - } -} - -static int dhcp6_configure(Link *link, int event) { - int r; - bool information_request; - - assert_return(link, -EINVAL); - - if (link->dhcp6_client) { - if (event != ICMP6_EVENT_ROUTER_ADVERTISMENT_MANAGED) - return 0; - - r = sd_dhcp6_client_get_information_request(link->dhcp6_client, - &information_request); - if (r < 0) { - log_link_warning(link, "Could not get DHCPv6 Information request setting: %s", - strerror(-r)); - link->dhcp6_client = - sd_dhcp6_client_unref(link->dhcp6_client); - return r; - } - - if (!information_request) - return r; - - r = sd_dhcp6_client_set_information_request(link->dhcp6_client, - false); - if (r < 0) { - log_link_warning(link, "Could not unset DHCPv6 Information request: %s", - strerror(-r)); - link->dhcp6_client = - sd_dhcp6_client_unref(link->dhcp6_client); - return r; - } - - r = sd_dhcp6_client_start(link->dhcp6_client); - if (r < 0) { - log_link_warning(link, "Could not restart DHCPv6 after enabling Information request: %s", - strerror(-r)); - link->dhcp6_client = - sd_dhcp6_client_unref(link->dhcp6_client); - return r; - } - - return r; - } - - r = sd_dhcp6_client_new(&link->dhcp6_client); - if (r < 0) - return r; - - r = sd_dhcp6_client_attach_event(link->dhcp6_client, NULL, 0); - if (r < 0) { - link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client); - return r; - } - - r = sd_dhcp6_client_set_mac(link->dhcp6_client, - (const uint8_t *) &link->mac, - sizeof (link->mac), ARPHRD_ETHER); - if (r < 0) { - link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client); - return r; - } - - r = sd_dhcp6_client_set_index(link->dhcp6_client, link->ifindex); - if (r < 0) { - link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client); - return r; - } - - r = sd_dhcp6_client_set_callback(link->dhcp6_client, dhcp6_handler, - link); - if (r < 0) { - link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client); - return r; - } - - if (event == ICMP6_EVENT_ROUTER_ADVERTISMENT_OTHER) { - r = sd_dhcp6_client_set_information_request(link->dhcp6_client, - true); - if (r < 0) { - link->dhcp6_client = - sd_dhcp6_client_unref(link->dhcp6_client); - return r; - } - } - - r = sd_dhcp6_client_start(link->dhcp6_client); - if (r < 0) - link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client); - - return r; -} - -static void icmp6_router_handler(sd_icmp6_nd *nd, int event, void *userdata) { - Link *link = userdata; - - assert(link); - assert(link->network); - assert(link->manager); - - if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) - return; - - switch(event) { - case ICMP6_EVENT_ROUTER_ADVERTISMENT_NONE: - case ICMP6_EVENT_ROUTER_ADVERTISMENT_PREFIX_EXPIRED: - return; - - case ICMP6_EVENT_ROUTER_ADVERTISMENT_TIMEOUT: - case ICMP6_EVENT_ROUTER_ADVERTISMENT_OTHER: - case ICMP6_EVENT_ROUTER_ADVERTISMENT_MANAGED: - dhcp6_configure(link, event); - - break; - - default: - if (event < 0) - log_link_warning(link, "ICMPv6 error: %s", - strerror(-event)); - else - log_link_warning(link, "ICMPv6 unknown event: %d", - event); - - break; - } - -} - -int icmp6_configure(Link *link) { - int r; - - assert_return(link, -EINVAL); - - r = sd_icmp6_nd_new(&link->icmp6_router_discovery); - if (r < 0) - return r; - - r = sd_icmp6_nd_attach_event(link->icmp6_router_discovery, NULL, 0); - if (r < 0) - return r; - - r = sd_icmp6_nd_set_mac(link->icmp6_router_discovery, &link->mac); - if (r < 0) - return r; - - r = sd_icmp6_nd_set_index(link->icmp6_router_discovery, link->ifindex); - if (r < 0) - return r; - - r = sd_icmp6_nd_set_callback(link->icmp6_router_discovery, - icmp6_router_handler, link); - - return r; -} diff --git a/src/network/networkd-fdb.c b/src/network/networkd-fdb.c deleted file mode 100644 index b6b8327b23..0000000000 --- a/src/network/networkd-fdb.c +++ /dev/null @@ -1,248 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright (C) 2014 Intel Corporation. All rights reserved. - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#include <net/if.h> -#include <net/ethernet.h> - -#include "networkd.h" -#include "networkd-link.h" -#include "conf-parser.h" -#include "util.h" - -/* create a new FDB entry or get an existing one. */ -int fdb_entry_new_static(Network *const network, - const unsigned section, - FdbEntry **ret) { - _cleanup_fdbentry_free_ FdbEntry *fdb_entry = NULL; - struct ether_addr *mac_addr = NULL; - - assert(network); - - /* search entry in hashmap first. */ - if(section) { - fdb_entry = hashmap_get(network->fdb_entries_by_section, UINT_TO_PTR(section)); - if (fdb_entry) { - *ret = fdb_entry; - fdb_entry = NULL; - - return 0; - } - } - - /* allocate space for MAC address. */ - mac_addr = new0(struct ether_addr, 1); - if (!mac_addr) - 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); - return -ENOMEM; - } - - /* init FDB structure. */ - fdb_entry->network = network; - fdb_entry->mac_addr = mac_addr; - - LIST_PREPEND(static_fdb_entries, network->static_fdb_entries, fdb_entry); - - if (section) { - fdb_entry->section = section; - hashmap_put(network->fdb_entries_by_section, - UINT_TO_PTR(fdb_entry->section), fdb_entry); - } - - /* return allocated FDB structure. */ - *ret = fdb_entry; - fdb_entry = NULL; - - return 0; -} - -static int set_fdb_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) { - Link *link = userdata; - int r; - - assert(link); - - r = sd_rtnl_message_get_errno(m); - if (r < 0 && r != -EEXIST) - log_link_error(link, "Could not add FDB entry: %s", strerror(-r)); - - return 1; -} - -/* send a request to the kernel to add a FDB entry in its static MAC table. */ -int fdb_entry_configure(Link *const link, FdbEntry *const fdb_entry) { - _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL; - sd_rtnl *rtnl; - int r; - - assert(link); - assert(link->manager); - assert(fdb_entry); - - rtnl = link->manager->rtnl; - - /* create new RTM message */ - r = sd_rtnl_message_new_neigh(rtnl, &req, RTM_NEWNEIGH, link->ifindex, PF_BRIDGE); - if (r < 0) - return rtnl_log_create_error(r); - - /* only NTF_SELF flag supported. */ - r = sd_rtnl_message_neigh_set_flags(req, NTF_SELF); - if (r < 0) - return rtnl_log_create_error(r); - - /* only NUD_PERMANENT state supported. */ - r = sd_rtnl_message_neigh_set_state(req, NUD_NOARP | NUD_PERMANENT); - if (r < 0) - return rtnl_log_create_error(r); - - r = sd_rtnl_message_append_ether_addr(req, NDA_LLADDR, fdb_entry->mac_addr); - if (r < 0) - return rtnl_log_create_error(r); - - /* VLAN Id is optional. We'll add VLAN Id only if it's specified. */ - if (0 != fdb_entry->vlan_id) { - r = sd_rtnl_message_append_u16(req, NDA_VLAN, fdb_entry->vlan_id); - if (r < 0) - return rtnl_log_create_error(r); - } - - /* send message to the kernel to update its internal static MAC table. */ - r = sd_rtnl_call_async(rtnl, req, set_fdb_handler, link, 0, NULL); - if (r < 0) { - log_link_error(link, "Could not send rtnetlink message: %s", strerror(-r)); - return r; - } - - return 0; -} - -/* remove and FDB entry. */ -void fdb_entry_free(FdbEntry *fdb_entry) { - if(!fdb_entry) - return; - - if(fdb_entry->network) { - LIST_REMOVE(static_fdb_entries, fdb_entry->network->static_fdb_entries, - fdb_entry); - - if(fdb_entry->section) - hashmap_remove(fdb_entry->network->fdb_entries_by_section, - UINT_TO_PTR(fdb_entry->section)); - } - - free(fdb_entry->mac_addr); - - free(fdb_entry); -} - -/* parse the HW address from config files. */ -int config_parse_fdb_hwaddr(const char *unit, - const char *filename, - unsigned line, - const char *section, - unsigned section_line, - const char *lvalue, - int ltype, - const char *rvalue, - void *data, - void *userdata) { - Network *network = userdata; - _cleanup_fdbentry_free_ FdbEntry *fdb_entry = NULL; - int r; - - assert(filename); - assert(section); - assert(lvalue); - assert(rvalue); - assert(data); - - r = fdb_entry_new_static(network, section_line, &fdb_entry); - if (r < 0) { - log_error("Failed to allocate a new FDB entry: %s", strerror(-r)); - return r; - } - - /* read in the MAC address for the FDB table. */ - r = sscanf(rvalue, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", - &fdb_entry->mac_addr->ether_addr_octet[0], - &fdb_entry->mac_addr->ether_addr_octet[1], - &fdb_entry->mac_addr->ether_addr_octet[2], - &fdb_entry->mac_addr->ether_addr_octet[3], - &fdb_entry->mac_addr->ether_addr_octet[4], - &fdb_entry->mac_addr->ether_addr_octet[5]); - - if (ETHER_ADDR_LEN != r) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Not a valid MAC address, ignoring assignment: %s", rvalue); - return 0; - } - - fdb_entry = NULL; - - return 0; -} - -/* parse the VLAN Id from config files. */ -int config_parse_fdb_vlan_id(const char *unit, - const char *filename, - unsigned line, - const char *section, - unsigned section_line, - const char *lvalue, - int ltype, - const char *rvalue, - void *data, - void *userdata) { - Network *network = userdata; - _cleanup_fdbentry_free_ FdbEntry *fdb_entry = NULL; - int r; - - assert(filename); - assert(section); - assert(lvalue); - assert(rvalue); - assert(data); - - r = fdb_entry_new_static(network, section_line, &fdb_entry); - if (r < 0) { - log_error("Failed to allocate a new FDB entry: %s", strerror(-r)); - return r; - } - - r = config_parse_unsigned(unit, filename, line, section, - section_line, lvalue, ltype, - rvalue, &fdb_entry->vlan_id, userdata); - if (r < 0) { - log_error("Failed to parse the unsigned integer: %s", strerror(-r)); - return r; - } - - fdb_entry = NULL; - - return 0; -} diff --git a/src/network/networkd-ipv4ll.c b/src/network/networkd-ipv4ll.c deleted file mode 100644 index 8050801e19..0000000000 --- a/src/network/networkd-ipv4ll.c +++ /dev/null @@ -1,244 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2013-2014 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#include <netinet/ether.h> -#include <linux/if.h> - -#include "networkd-link.h" -#include "network-internal.h" - -static int ipv4ll_address_lost(Link *link) { - _cleanup_address_free_ Address *address = NULL; - _cleanup_route_free_ Route *route = NULL; - struct in_addr addr; - int r; - - assert(link); - - link->ipv4ll_route = false; - link->ipv4ll_address = false; - - r = sd_ipv4ll_get_address(link->ipv4ll, &addr); - if (r < 0) - return 0; - - log_link_debug(link, "IPv4 link-local release %u.%u.%u.%u", ADDRESS_FMT_VAL(addr)); - - r = address_new_dynamic(&address); - if (r < 0) { - log_link_error(link, "Could not allocate address: %s", strerror(-r)); - return r; - } - - address->family = AF_INET; - address->in_addr.in = addr; - address->prefixlen = 16; - address->scope = RT_SCOPE_LINK; - - address_drop(address, link, &link_address_drop_handler); - - r = route_new_dynamic(&route, RTPROT_UNSPEC); - if (r < 0) { - log_link_error(link, "Could not allocate route: %s", - strerror(-r)); - return r; - } - - route->family = AF_INET; - route->scope = RT_SCOPE_LINK; - route->metrics = IPV4LL_ROUTE_METRIC; - - route_drop(route, link, &link_route_drop_handler); - - link_client_handler(link); - - return 0; -} - -static int ipv4ll_route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) { - _cleanup_link_unref_ Link *link = userdata; - int r; - - assert(link); - assert(!link->ipv4ll_route); - - r = sd_rtnl_message_get_errno(m); - if (r < 0 && r != -EEXIST) { - log_link_error(link, "could not set ipv4ll route: %s", strerror(-r)); - link_enter_failed(link); - } - - link->ipv4ll_route = true; - - if (link->ipv4ll_address == true) - link_client_handler(link); - - return 1; -} - -static int ipv4ll_address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) { - _cleanup_link_unref_ Link *link = userdata; - int r; - - assert(link); - assert(!link->ipv4ll_address); - - r = sd_rtnl_message_get_errno(m); - if (r < 0 && r != -EEXIST) { - log_link_error(link, "could not set ipv4ll address: %s", strerror(-r)); - link_enter_failed(link); - } else if (r >= 0) - link_rtnl_process_address(rtnl, m, link->manager); - - link->ipv4ll_address = true; - - if (link->ipv4ll_route == true) - link_client_handler(link); - - return 1; -} - -static int ipv4ll_address_claimed(sd_ipv4ll *ll, Link *link) { - _cleanup_address_free_ Address *ll_addr = NULL; - _cleanup_route_free_ Route *route = NULL; - struct in_addr address; - int r; - - assert(ll); - assert(link); - - r = sd_ipv4ll_get_address(ll, &address); - if (r == -ENOENT) - return 0; - else if (r < 0) - return r; - - log_link_debug(link, "IPv4 link-local claim %u.%u.%u.%u", - ADDRESS_FMT_VAL(address)); - - r = address_new_dynamic(&ll_addr); - if (r < 0) - return r; - - ll_addr->family = AF_INET; - ll_addr->in_addr.in = address; - ll_addr->prefixlen = 16; - ll_addr->broadcast.s_addr = ll_addr->in_addr.in.s_addr | htonl(0xfffffffflu >> ll_addr->prefixlen); - ll_addr->scope = RT_SCOPE_LINK; - - r = address_configure(ll_addr, link, ipv4ll_address_handler); - if (r < 0) - return r; - - link->ipv4ll_address = false; - - r = route_new_dynamic(&route, RTPROT_STATIC); - if (r < 0) - return r; - - route->family = AF_INET; - route->scope = RT_SCOPE_LINK; - route->metrics = IPV4LL_ROUTE_METRIC; - - r = route_configure(route, link, ipv4ll_route_handler); - if (r < 0) - return r; - - link->ipv4ll_route = false; - - return 0; -} - -static void ipv4ll_handler(sd_ipv4ll *ll, int event, void *userdata){ - Link *link = userdata; - int r; - - assert(link); - assert(link->network); - assert(link->manager); - - if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) - return; - - switch(event) { - case IPV4LL_EVENT_STOP: - case IPV4LL_EVENT_CONFLICT: - r = ipv4ll_address_lost(link); - if (r < 0) { - link_enter_failed(link); - return; - } - break; - case IPV4LL_EVENT_BIND: - r = ipv4ll_address_claimed(ll, link); - if (r < 0) { - link_enter_failed(link); - return; - } - break; - default: - if (event < 0) - log_link_warning(link, "IPv4 link-local error: %s", strerror(-event)); - else - log_link_warning(link, "IPv4 link-local unknown event: %d", event); - break; - } -} - -int ipv4ll_configure(Link *link) { - uint8_t seed[8]; - int r; - - assert(link); - assert(link->network); - assert(IN_SET(link->network->link_local, ADDRESS_FAMILY_IPV4, ADDRESS_FAMILY_YES)); - - r = sd_ipv4ll_new(&link->ipv4ll); - if (r < 0) - return r; - - if (link->udev_device) { - r = net_get_unique_predictable_data(link->udev_device, seed); - if (r >= 0) { - r = sd_ipv4ll_set_address_seed(link->ipv4ll, seed); - if (r < 0) - return r; - } - } - - r = sd_ipv4ll_attach_event(link->ipv4ll, NULL, 0); - if (r < 0) - return r; - - r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac); - if (r < 0) - return r; - - r = sd_ipv4ll_set_index(link->ipv4ll, link->ifindex); - if (r < 0) - return r; - - r = sd_ipv4ll_set_callback(link->ipv4ll, ipv4ll_handler, link); - if (r < 0) - return r; - - return 0; -} diff --git a/src/network/networkd-link-bus.c b/src/network/networkd-link-bus.c deleted file mode 100644 index 1a1524dfb4..0000000000 --- a/src/network/networkd-link-bus.c +++ /dev/null @@ -1,138 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2015 Tom Gundersen - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#include "bus-util.h" -#include "strv.h" - -#include "networkd.h" -#include "networkd-link.h" - -static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_operational_state, link_operstate, LinkOperationalState); -static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_administrative_state, link_state, LinkState); - -const sd_bus_vtable link_vtable[] = { - SD_BUS_VTABLE_START(0), - - SD_BUS_PROPERTY("OperationalState", "s", property_get_operational_state, offsetof(Link, operstate), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), - SD_BUS_PROPERTY("AdministrativeState", "s", property_get_administrative_state, offsetof(Link, state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), - - SD_BUS_VTABLE_END -}; - -static char *link_bus_path(Link *link) { - _cleanup_free_ char *ifindex = NULL; - char *p; - int r; - - assert(link); - assert(link->ifindex > 0); - - if (asprintf(&ifindex, "%d", link->ifindex) < 0) - return NULL; - - r = sd_bus_path_encode("/org/freedesktop/network1/link", ifindex, &p); - if (r < 0) - return NULL; - - return p; -} - -int link_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) { - _cleanup_strv_free_ char **l = NULL; - Manager *m = userdata; - Link *link; - Iterator i; - int r; - - assert(bus); - assert(path); - assert(m); - assert(nodes); - - HASHMAP_FOREACH(link, m->links, i) { - char *p; - - p = link_bus_path(link); - if (!p) - return -ENOMEM; - - r = strv_consume(&l, p); - if (r < 0) - return r; - } - - *nodes = l; - l = NULL; - - return 1; -} - -int link_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) { - _cleanup_free_ char *identifier = NULL; - Manager *m = userdata; - Link *link; - int ifindex, r; - - assert(bus); - assert(path); - assert(interface); - assert(m); - assert(found); - - r = sd_bus_path_decode(path, "/org/freedesktop/network1/link", &identifier); - if (r < 0) - return 0; - - r = safe_atoi(identifier, &ifindex); - if (r < 0) - return 0; - - r = link_get(m, ifindex, &link); - if (r < 0) - return 0; - - *found = link; - - return 1; -} - -int link_send_changed(Link *link, const char *property, ...) { - _cleanup_free_ char *p = NULL; - char **l; - - assert(link); - assert(link->manager); - - if (!link->manager->bus) - return 0; /* replace with assert when we have kdbus */ - - l = strv_from_stdarg_alloca(property); - - p = link_bus_path(link); - if (!p) - return -ENOMEM; - - return sd_bus_emit_properties_changed_strv( - link->manager->bus, - p, - "org.freedesktop.network1.Link", - l); -} diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c deleted file mode 100644 index 3bd37d8087..0000000000 --- a/src/network/networkd-link.c +++ /dev/null @@ -1,2499 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2013 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#include <netinet/ether.h> -#include <linux/if.h> -#include <unistd.h> - -#include "util.h" -#include "virt.h" -#include "fileio.h" -#include "bus-util.h" -#include "udev-util.h" -#include "network-internal.h" -#include "networkd-link.h" -#include "networkd-netdev.h" - -bool link_dhcp6_enabled(Link *link) { - if (link->flags & IFF_LOOPBACK) - return false; - - if (!link->network) - return false; - - return IN_SET(link->network->dhcp, ADDRESS_FAMILY_IPV6, ADDRESS_FAMILY_YES); -} - -bool link_dhcp4_enabled(Link *link) { - if (link->flags & IFF_LOOPBACK) - return false; - - if (!link->network) - return false; - - return IN_SET(link->network->dhcp, ADDRESS_FAMILY_IPV4, ADDRESS_FAMILY_YES); -} - -bool link_dhcp4_server_enabled(Link *link) { - if (link->flags & IFF_LOOPBACK) - return false; - - if (!link->network) - return false; - - return link->network->dhcp_server; -} - -bool link_ipv4ll_enabled(Link *link) { - if (link->flags & IFF_LOOPBACK) - return false; - - if (!link->network) - return false; - - return IN_SET(link->network->link_local, ADDRESS_FAMILY_IPV4, ADDRESS_FAMILY_YES); -} - -bool link_ipv6ll_enabled(Link *link) { - if (link->flags & IFF_LOOPBACK) - return false; - - if (!link->network) - return false; - - return IN_SET(link->network->link_local, ADDRESS_FAMILY_IPV6, ADDRESS_FAMILY_YES); -} - -bool link_lldp_enabled(Link *link) { - if (link->flags & IFF_LOOPBACK) - return false; - - if (!link->network) - return false; - - if (link->network->bridge) - return false; - - return link->network->lldp; -} - -static bool link_ipv4_forward_enabled(Link *link) { - if (link->flags & IFF_LOOPBACK) - return false; - - if (!link->network) - return false; - - return IN_SET(link->network->ip_forward, ADDRESS_FAMILY_IPV4, ADDRESS_FAMILY_YES); -} - -static bool link_ipv6_forward_enabled(Link *link) { - if (link->flags & IFF_LOOPBACK) - return false; - - if (!link->network) - return false; - - return IN_SET(link->network->ip_forward, ADDRESS_FAMILY_IPV6, ADDRESS_FAMILY_YES); -} - -#define FLAG_STRING(string, flag, old, new) \ - (((old ^ new) & flag) \ - ? ((old & flag) ? (" -" string) : (" +" string)) \ - : "") - -static int link_update_flags(Link *link, sd_rtnl_message *m) { - unsigned flags, unknown_flags_added, unknown_flags_removed, unknown_flags; - uint8_t operstate; - int r; - - assert(link); - - r = sd_rtnl_message_link_get_flags(m, &flags); - if (r < 0) { - log_link_warning(link, "Could not get link flags"); - return r; - } - - r = sd_rtnl_message_read_u8(m, IFLA_OPERSTATE, &operstate); - if (r < 0) - /* if we got a message without operstate, take it to mean - the state was unchanged */ - operstate = link->kernel_operstate; - - if ((link->flags == flags) && (link->kernel_operstate == operstate)) - return 0; - - if (link->flags != flags) { - log_link_debug(link, "flags change:%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", - FLAG_STRING("LOOPBACK", IFF_LOOPBACK, link->flags, flags), - FLAG_STRING("MASTER", IFF_MASTER, link->flags, flags), - FLAG_STRING("SLAVE", IFF_SLAVE, link->flags, flags), - FLAG_STRING("UP", IFF_UP, link->flags, flags), - FLAG_STRING("DORMANT", IFF_DORMANT, link->flags, flags), - FLAG_STRING("LOWER_UP", IFF_LOWER_UP, link->flags, flags), - FLAG_STRING("RUNNING", IFF_RUNNING, link->flags, flags), - FLAG_STRING("MULTICAST", IFF_MULTICAST, link->flags, flags), - FLAG_STRING("BROADCAST", IFF_BROADCAST, link->flags, flags), - FLAG_STRING("POINTOPOINT", IFF_POINTOPOINT, link->flags, flags), - FLAG_STRING("PROMISC", IFF_PROMISC, link->flags, flags), - FLAG_STRING("ALLMULTI", IFF_ALLMULTI, link->flags, flags), - FLAG_STRING("PORTSEL", IFF_PORTSEL, link->flags, flags), - FLAG_STRING("AUTOMEDIA", IFF_AUTOMEDIA, link->flags, flags), - FLAG_STRING("DYNAMIC", IFF_DYNAMIC, link->flags, flags), - FLAG_STRING("NOARP", IFF_NOARP, link->flags, flags), - FLAG_STRING("NOTRAILERS", IFF_NOTRAILERS, link->flags, flags), - FLAG_STRING("DEBUG", IFF_DEBUG, link->flags, flags), - FLAG_STRING("ECHO", IFF_ECHO, link->flags, flags)); - - unknown_flags = ~(IFF_LOOPBACK | IFF_MASTER | IFF_SLAVE | IFF_UP | - IFF_DORMANT | IFF_LOWER_UP | IFF_RUNNING | - IFF_MULTICAST | IFF_BROADCAST | IFF_POINTOPOINT | - IFF_PROMISC | IFF_ALLMULTI | IFF_PORTSEL | - IFF_AUTOMEDIA | IFF_DYNAMIC | IFF_NOARP | - IFF_NOTRAILERS | IFF_DEBUG | IFF_ECHO); - unknown_flags_added = ((link->flags ^ flags) & flags & unknown_flags); - unknown_flags_removed = ((link->flags ^ flags) & link->flags & unknown_flags); - - /* link flags are currently at most 18 bits, let's align to - * printing 20 */ - if (unknown_flags_added) - log_link_debug(link, - "unknown link flags gained: %#.5x (ignoring)", - unknown_flags_added); - - if (unknown_flags_removed) - log_link_debug(link, - "unknown link flags lost: %#.5x (ignoring)", - unknown_flags_removed); - } - - link->flags = flags; - link->kernel_operstate = operstate; - - link_save(link); - - return 0; -} - -static int link_new(Manager *manager, sd_rtnl_message *message, Link **ret) { - _cleanup_link_unref_ Link *link = NULL; - uint16_t type; - const char *ifname; - int r, ifindex; - - assert(manager); - assert(message); - assert(ret); - - r = sd_rtnl_message_get_type(message, &type); - if (r < 0) - return r; - else if (type != RTM_NEWLINK) - return -EINVAL; - - r = sd_rtnl_message_link_get_ifindex(message, &ifindex); - if (r < 0) - return r; - else if (ifindex <= 0) - return -EINVAL; - - r = sd_rtnl_message_read_string(message, IFLA_IFNAME, &ifname); - if (r < 0) - return r; - - link = new0(Link, 1); - if (!link) - return -ENOMEM; - - link->n_ref = 1; - link->manager = manager; - link->state = LINK_STATE_PENDING; - link->ifindex = ifindex; - link->ifname = strdup(ifname); - if (!link->ifname) - return -ENOMEM; - - r = sd_rtnl_message_read_ether_addr(message, IFLA_ADDRESS, &link->mac); - if (r < 0) - log_link_debug(link, "MAC address not found for new device, continuing without"); - - r = asprintf(&link->state_file, "/run/systemd/netif/links/%d", - link->ifindex); - if (r < 0) - return -ENOMEM; - - r = asprintf(&link->lease_file, "/run/systemd/netif/leases/%d", - link->ifindex); - if (r < 0) - return -ENOMEM; - - r = asprintf(&link->lldp_file, "/run/systemd/netif/lldp/%d", - link->ifindex); - if (r < 0) - return -ENOMEM; - - - r = hashmap_ensure_allocated(&manager->links, NULL); - if (r < 0) - return r; - - r = hashmap_put(manager->links, INT_TO_PTR(link->ifindex), link); - if (r < 0) - return r; - - r = link_update_flags(link, message); - if (r < 0) - return r; - - *ret = link; - link = NULL; - - return 0; -} - -static void link_free(Link *link) { - Address *address; - Iterator i; - Link *carrier; - - if (!link) - return; - - while ((address = link->addresses)) { - LIST_REMOVE(addresses, link->addresses, address); - address_free(address); - } - - while ((address = link->pool_addresses)) { - LIST_REMOVE(addresses, link->pool_addresses, address); - address_free(address); - } - - sd_dhcp_server_unref(link->dhcp_server); - sd_dhcp_client_unref(link->dhcp_client); - sd_dhcp_lease_unref(link->dhcp_lease); - - free(link->lease_file); - - sd_lldp_free(link->lldp); - - free(link->lldp_file); - - sd_ipv4ll_unref(link->ipv4ll); - sd_dhcp6_client_unref(link->dhcp6_client); - sd_icmp6_nd_unref(link->icmp6_router_discovery); - - if (link->manager) - hashmap_remove(link->manager->links, INT_TO_PTR(link->ifindex)); - - free(link->ifname); - - free(link->state_file); - - udev_device_unref(link->udev_device); - - HASHMAP_FOREACH (carrier, link->bound_to_links, i) - hashmap_remove(link->bound_to_links, INT_TO_PTR(carrier->ifindex)); - hashmap_free(link->bound_to_links); - - HASHMAP_FOREACH (carrier, link->bound_by_links, i) - hashmap_remove(link->bound_by_links, INT_TO_PTR(carrier->ifindex)); - hashmap_free(link->bound_by_links); - - free(link); -} - -Link *link_unref(Link *link) { - if (link && (-- link->n_ref <= 0)) - link_free(link); - - return NULL; -} - -Link *link_ref(Link *link) { - if (link) - assert_se(++ link->n_ref >= 2); - - return link; -} - -int link_get(Manager *m, int ifindex, Link **ret) { - Link *link; - - assert(m); - assert(ifindex); - assert(ret); - - link = hashmap_get(m->links, INT_TO_PTR(ifindex)); - if (!link) - return -ENODEV; - - *ret = link; - - return 0; -} - -static void link_set_state(Link *link, LinkState state) { - assert(link); - - if (link->state == state) - return; - - link->state = state; - - link_send_changed(link, "AdministrativeState", NULL); - - return; -} - -static void link_enter_unmanaged(Link *link) { - assert(link); - - log_link_debug(link, "unmanaged"); - - link_set_state(link, LINK_STATE_UNMANAGED); - - link_save(link); -} - -static int link_stop_clients(Link *link) { - int r = 0, k; - - assert(link); - assert(link->manager); - assert(link->manager->event); - - if (!link->network) - return 0; - - if (link->dhcp_client) { - k = sd_dhcp_client_stop(link->dhcp_client); - if (k < 0) { - log_link_warning(link, "Could not stop DHCPv4 client: %s", - strerror(-r)); - r = k; - } - } - - if (link->ipv4ll) { - k = sd_ipv4ll_stop(link->ipv4ll); - if (k < 0) { - log_link_warning(link, "Could not stop IPv4 link-local: %s", - strerror(-r)); - r = k; - } - } - - if(link->icmp6_router_discovery) { - - if (link->dhcp6_client) { - k = sd_dhcp6_client_stop(link->dhcp6_client); - if (k < 0) { - log_link_warning(link, "Could not stop DHCPv6 client: %s", - strerror(-r)); - r = k; - } - } - - k = sd_icmp6_nd_stop(link->icmp6_router_discovery); - if (k < 0) { - log_link_warning(link, - "Could not stop ICMPv6 router discovery: %s", - strerror(-r)); - r = k; - } - } - - if (link->lldp) { - - k = sd_lldp_stop(link->lldp); - if (k < 0) { - log_link_warning(link, "Could not stop LLDP : %s", - strerror(-r)); - r = k; - } - } - - return r; -} - -void link_enter_failed(Link *link) { - assert(link); - - if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) - return; - - log_link_warning(link, "failed"); - - link_set_state(link, LINK_STATE_FAILED); - - link_stop_clients(link); - - link_save(link); -} - -static Address* link_find_dhcp_server_address(Link *link) { - Address *address; - - assert(link); - assert(link->network); - - /* The first statically configured address if there is any */ - LIST_FOREACH(addresses, address, link->network->static_addresses) { - - if (address->family != AF_INET) - continue; - - if (in_addr_is_null(address->family, &address->in_addr)) - continue; - - return address; - } - - /* If that didn't work, find a suitable address we got from the pool */ - LIST_FOREACH(addresses, address, link->pool_addresses) { - if (address->family != AF_INET) - continue; - - return address; - } - - return NULL; -} - -static int link_enter_configured(Link *link) { - assert(link); - assert(link->network); - assert(link->state == LINK_STATE_SETTING_ROUTES); - - log_link_info(link, "link configured"); - - link_set_state(link, LINK_STATE_CONFIGURED); - - link_save(link); - - return 0; -} - -void link_client_handler(Link *link) { - assert(link); - assert(link->network); - - if (!link->static_configured) - return; - - if (link_ipv4ll_enabled(link)) - if (!link->ipv4ll_address || - !link->ipv4ll_route) - return; - - if (link_dhcp4_enabled(link) && !link->dhcp4_configured) - return; - - if (link->state != LINK_STATE_CONFIGURED) - link_enter_configured(link); - - return; -} - -static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) { - _cleanup_link_unref_ Link *link = userdata; - int r; - - assert(link->link_messages > 0); - assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES, - LINK_STATE_SETTING_ROUTES, LINK_STATE_FAILED, - LINK_STATE_LINGER)); - - link->link_messages --; - - if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) - return 1; - - r = sd_rtnl_message_get_errno(m); - if (r < 0 && r != -EEXIST) - log_link_warning_errno(link, -r, "%-*s: could not set route: %m", IFNAMSIZ, link->ifname); - - if (link->link_messages == 0) { - log_link_debug(link, "routes set"); - link->static_configured = true; - link_client_handler(link); - } - - return 1; -} - -static int link_enter_set_routes(Link *link) { - Route *rt; - int r; - - assert(link); - assert(link->network); - assert(link->state == LINK_STATE_SETTING_ADDRESSES); - - link_set_state(link, LINK_STATE_SETTING_ROUTES); - - LIST_FOREACH(routes, rt, link->network->static_routes) { - r = route_configure(rt, link, &route_handler); - if (r < 0) { - log_link_warning(link, - "could not set routes: %s", - strerror(-r)); - link_enter_failed(link); - return r; - } - - link->link_messages ++; - } - - if (link->link_messages == 0) { - link->static_configured = true; - link_client_handler(link); - } else - log_link_debug(link, "setting routes"); - - return 0; -} - -int link_route_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) { - _cleanup_link_unref_ Link *link = userdata; - int r; - - assert(m); - assert(link); - assert(link->ifname); - - if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) - return 1; - - r = sd_rtnl_message_get_errno(m); - if (r < 0 && r != -ESRCH) - log_link_warning_errno(link, -r, "%-*s: could not drop route: %m", IFNAMSIZ, link->ifname); - - return 1; -} - -static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) { - _cleanup_link_unref_ Link *link = userdata; - int r; - - assert(rtnl); - assert(m); - assert(link); - assert(link->ifname); - assert(link->link_messages > 0); - assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES, - LINK_STATE_FAILED, LINK_STATE_LINGER)); - - link->link_messages --; - - if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) - return 1; - - r = sd_rtnl_message_get_errno(m); - if (r < 0 && r != -EEXIST) - log_link_warning_errno(link, -r, "%-*s: could not set address: %m", IFNAMSIZ, link->ifname); - else if (r >= 0) - link_rtnl_process_address(rtnl, m, link->manager); - - if (link->link_messages == 0) { - log_link_debug(link, "addresses set"); - link_enter_set_routes(link); - } - - return 1; -} - -static int link_enter_set_addresses(Link *link) { - Address *ad; - int r; - - assert(link); - assert(link->network); - assert(link->state != _LINK_STATE_INVALID); - - link_set_state(link, LINK_STATE_SETTING_ADDRESSES); - - LIST_FOREACH(addresses, ad, link->network->static_addresses) { - r = address_configure(ad, link, &address_handler); - if (r < 0) { - log_link_warning_errno(link, r, "Could not set addresses: %m"); - link_enter_failed(link); - return r; - } - - link->link_messages ++; - } - - /* now that we can figure out a default address for the dhcp server, - start it */ - if (link_dhcp4_server_enabled(link)) { - struct in_addr pool_start; - Address *address; - - address = link_find_dhcp_server_address(link); - if (!address) { - log_link_warning(link, - "Failed to find suitable address for DHCPv4 server instance."); - link_enter_failed(link); - return 0; - } - - r = sd_dhcp_server_set_address(link->dhcp_server, - &address->in_addr.in, - address->prefixlen); - if (r < 0) - return r; - - /* offer 32 addresses starting from the address following the server address */ - pool_start.s_addr = htobe32(be32toh(address->in_addr.in.s_addr) + 1); - r = sd_dhcp_server_set_lease_pool(link->dhcp_server, - &pool_start, 32); - if (r < 0) - return r; - - /* TODO: - r = sd_dhcp_server_set_router(link->dhcp_server, - &main_address->in_addr.in); - if (r < 0) - return r; - - r = sd_dhcp_server_set_prefixlen(link->dhcp_server, - main_address->prefixlen); - if (r < 0) - return r; - */ - - r = sd_dhcp_server_start(link->dhcp_server); - if (r < 0) { - log_link_warning(link, "could not start DHCPv4 server " - "instance: %s", strerror(-r)); - - link_enter_failed(link); - - return 0; - } - - log_link_debug(link, "offering DHCPv4 leases"); - } - - if (link->link_messages == 0) { - link_enter_set_routes(link); - } else - log_link_debug(link, "setting addresses"); - - return 0; -} - -int link_address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) { - _cleanup_link_unref_ Link *link = userdata; - int r; - - assert(m); - assert(link); - assert(link->ifname); - - if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) - return 1; - - r = sd_rtnl_message_get_errno(m); - if (r < 0 && r != -EADDRNOTAVAIL) - log_link_warning_errno(link, -r, "%-*s: could not drop address: %m", IFNAMSIZ, link->ifname); - - return 1; -} - -static int link_set_bridge_fdb(Link *const link) { - FdbEntry *fdb_entry; - int r = 0; - - LIST_FOREACH(static_fdb_entries, fdb_entry, link->network->static_fdb_entries) { - r = fdb_entry_configure(link, fdb_entry); - if(r < 0) { - log_link_error(link, "Failed to add MAC entry to static MAC table: %s", strerror(-r)); - break; - } - } - - return r; -} - -static int link_set_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) { - _cleanup_link_unref_ Link *link = userdata; - int r; - - log_link_debug(link, "set link"); - - r = sd_rtnl_message_get_errno(m); - if (r < 0 && r != -EEXIST) { - log_link_struct(link, LOG_ERR, - "MESSAGE=%-*s: could not join netdev: %s", - IFNAMSIZ, - link->ifname, strerror(-r), - "ERRNO=%d", -r, - NULL); - link_enter_failed(link); - return 1; - } - - return 0; -} - -static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata, - sd_bus_error *ret_error) { - _cleanup_link_unref_ Link *link = userdata; - int r; - - assert(link); - - if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) - return 1; - - r = sd_bus_message_get_errno(m); - if (r > 0) - log_link_warning(link, "Could not set hostname: %s", - strerror(r)); - - return 1; -} - -int link_set_hostname(Link *link, const char *hostname) { - _cleanup_bus_message_unref_ sd_bus_message *m = NULL; - int r = 0; - - assert(link); - assert(link->manager); - assert(hostname); - - log_link_debug(link, "Setting transient hostname: '%s'", hostname); - - if (!link->manager->bus) { - /* TODO: replace by assert when we can rely on kdbus */ - log_link_info(link, - "Not connected to system bus, ignoring transient hostname."); - return 0; - } - - r = sd_bus_message_new_method_call( - link->manager->bus, - &m, - "org.freedesktop.hostname1", - "/org/freedesktop/hostname1", - "org.freedesktop.hostname1", - "SetHostname"); - if (r < 0) - return r; - - r = sd_bus_message_append(m, "sb", hostname, false); - if (r < 0) - return r; - - r = sd_bus_call_async(link->manager->bus, NULL, m, set_hostname_handler, - link, 0); - if (r < 0) { - log_link_error(link, "Could not set transient hostname: %s", - strerror(-r)); - return r; - } - - link_ref(link); - - return 0; -} - -static int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) { - _cleanup_link_unref_ Link *link = userdata; - int r; - - assert(m); - assert(link); - assert(link->ifname); - - if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) - return 1; - - r = sd_rtnl_message_get_errno(m); - if (r < 0) - log_link_warning_errno(link, -r, "%-*s: could not set MTU: %m", IFNAMSIZ, link->ifname); - - return 1; -} - -int link_set_mtu(Link *link, uint32_t mtu) { - _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL; - int r; - - assert(link); - assert(link->manager); - assert(link->manager->rtnl); - - log_link_debug(link, "setting MTU: %" PRIu32, mtu); - - r = sd_rtnl_message_new_link(link->manager->rtnl, &req, - RTM_SETLINK, link->ifindex); - if (r < 0) { - log_link_error(link, "Could not allocate RTM_SETLINK message"); - return r; - } - - r = sd_rtnl_message_append_u32(req, IFLA_MTU, mtu); - if (r < 0) { - log_link_error(link, "Could not append MTU: %s", strerror(-r)); - return r; - } - - r = sd_rtnl_call_async(link->manager->rtnl, req, set_mtu_handler, link, - 0, NULL); - if (r < 0) { - log_link_error(link, - "Could not send rtnetlink message: %s", - strerror(-r)); - return r; - } - - link_ref(link); - - return 0; -} - -static int link_set_bridge(Link *link) { - _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL; - int r; - - assert(link); - assert(link->network); - - if(link->network->cost == 0) - return 0; - - r = sd_rtnl_message_new_link(link->manager->rtnl, &req, - RTM_SETLINK, link->ifindex); - if (r < 0) { - log_link_error(link, "Could not allocate RTM_SETLINK message"); - return r; - } - - r = sd_rtnl_message_link_set_family(req, PF_BRIDGE); - if (r < 0) { - log_link_error(link, - "Could not set message family %s", strerror(-r)); - return r; - } - - r = sd_rtnl_message_open_container(req, IFLA_PROTINFO); - if (r < 0) { - log_link_error(link, - "Could not append IFLA_PROTINFO attribute: %s", - strerror(-r)); - return r; - } - - if(link->network->cost != 0) { - r = sd_rtnl_message_append_u32(req, IFLA_BRPORT_COST, link->network->cost); - if (r < 0) { - log_link_error(link, - "Could not append IFLA_BRPORT_COST attribute: %s", - strerror(-r)); - return r; - } - } - - r = sd_rtnl_message_close_container(req); - if (r < 0) { - log_link_error(link, - "Could not append IFLA_LINKINFO attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_call_async(link->manager->rtnl, req, link_set_handler, link, 0, NULL); - if (r < 0) { - log_link_error(link, - "Could not send rtnetlink message: %s", - strerror(-r)); - return r; - } - - link_ref(link); - - return r; -} - -static void lldp_handler(sd_lldp *lldp, int event, void *userdata) { - Link *link = userdata; - int r; - - assert(link); - assert(link->network); - assert(link->manager); - - if (event != UPDATE_INFO) - return; - - r = sd_lldp_save(link->lldp, link->lldp_file); - if (r < 0) - log_link_warning(link, "could not save LLDP"); - -} - -static int link_acquire_conf(Link *link) { - int r; - - assert(link); - assert(link->network); - assert(link->manager); - assert(link->manager->event); - - if (link_ipv4ll_enabled(link)) { - assert(link->ipv4ll); - - log_link_debug(link, "acquiring IPv4 link-local address"); - - r = sd_ipv4ll_start(link->ipv4ll); - if (r < 0) { - log_link_warning(link, "could not acquire IPv4 " - "link-local address"); - return r; - } - } - - if (link_dhcp4_enabled(link)) { - assert(link->dhcp_client); - - log_link_debug(link, "acquiring DHCPv4 lease"); - - r = sd_dhcp_client_start(link->dhcp_client); - if (r < 0) { - log_link_warning(link, "could not acquire DHCPv4 " - "lease"); - return r; - } - } - - if (link_dhcp6_enabled(link)) { - assert(link->icmp6_router_discovery); - - log_link_debug(link, "discovering IPv6 routers"); - - r = sd_icmp6_router_solicitation_start(link->icmp6_router_discovery); - if (r < 0) { - log_link_warning(link, - "could not start IPv6 router discovery"); - return r; - } - } - - if (link_lldp_enabled(link)) { - assert(link->lldp); - - log_link_debug(link, "Starting LLDP"); - - r = sd_lldp_start(link->lldp); - if (r < 0) { - log_link_warning(link, "could not start LLDP "); - return r; - } - } - - return 0; -} - -bool link_has_carrier(Link *link) { - /* see Documentation/networking/operstates.txt in the kernel sources */ - - if (link->kernel_operstate == IF_OPER_UP) - return true; - - if (link->kernel_operstate == IF_OPER_UNKNOWN) - /* operstate may not be implemented, so fall back to flags */ - if ((link->flags & IFF_LOWER_UP) && !(link->flags & IFF_DORMANT)) - return true; - - return false; -} - -static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) { - _cleanup_link_unref_ Link *link = userdata; - int r; - - assert(link); - - if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) - return 1; - - r = sd_rtnl_message_get_errno(m); - if (r < 0) { - /* we warn but don't fail the link, as it may - be brought up later */ - log_link_warning_errno(link, -r, "%-*s: could not bring up interface: %m", IFNAMSIZ, link->ifname); - } - - return 1; -} - -static int link_up(Link *link) { - _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL; - uint8_t ipv6ll_mode; - int r; - - assert(link); - assert(link->network); - assert(link->manager); - assert(link->manager->rtnl); - - log_link_debug(link, "bringing link up"); - - r = sd_rtnl_message_new_link(link->manager->rtnl, &req, - RTM_SETLINK, link->ifindex); - if (r < 0) { - log_link_error(link, "Could not allocate RTM_SETLINK message"); - return r; - } - - r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP); - if (r < 0) { - log_link_error(link, "Could not set link flags: %s", - strerror(-r)); - return r; - } - - if (link->network->mac) { - r = sd_rtnl_message_append_ether_addr(req, IFLA_ADDRESS, link->network->mac); - if (r < 0) { - log_link_error(link, "Could not set MAC address: %s", strerror(-r)); - return r; - } - } - - if (link->network->mtu) { - r = sd_rtnl_message_append_u32(req, IFLA_MTU, link->network->mtu); - if (r < 0) { - log_link_error(link, "Could not set MTU: %s", strerror(-r)); - return r; - } - } - - r = sd_rtnl_message_open_container(req, IFLA_AF_SPEC); - if (r < 0) { - log_link_error(link, "Could not open IFLA_AF_SPEC container: %s", strerror(-r)); - return r; - } - - r = sd_rtnl_message_open_container(req, AF_INET6); - if (r < 0) { - log_link_error(link, "Could not open AF_INET6 container: %s", strerror(-r)); - return r; - } - - ipv6ll_mode = link_ipv6ll_enabled(link) ? IN6_ADDR_GEN_MODE_EUI64 : IN6_ADDR_GEN_MODE_NONE; - r = sd_rtnl_message_append_u8(req, IFLA_INET6_ADDR_GEN_MODE, ipv6ll_mode); - if (r < 0) { - log_link_error(link, "Could not append IFLA_INET6_ADDR_GEN_MODE: %s", strerror(-r)); - return r; - } - - if (!in_addr_is_null(AF_INET6, &link->network->ipv6_token)) { - r = sd_rtnl_message_append_in6_addr(req, IFLA_INET6_TOKEN, &link->network->ipv6_token.in6); - if (r < 0) { - log_link_error(link, "Could not append IFLA_INET6_TOKEN: %s", strerror(-r)); - return r; - } - } - - r = sd_rtnl_message_close_container(req); - if (r < 0) { - log_link_error(link, "Could not close AF_INET6 container: %s", strerror(-r)); - return r; - } - - r = sd_rtnl_message_close_container(req); - if (r < 0) { - log_link_error(link, "Could not close IFLA_AF_SPEC container: %s", strerror(-r)); - return r; - } - - r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link, - 0, NULL); - if (r < 0) { - log_link_error(link, - "Could not send rtnetlink message: %s", - strerror(-r)); - return r; - } - - link_ref(link); - - return 0; -} - -static int link_down_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) { - _cleanup_link_unref_ Link *link = userdata; - int r; - - assert(link); - - if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) - return 1; - - r = sd_rtnl_message_get_errno(m); - if (r < 0) - log_link_warning_errno(link, -r, "%-*s: could not bring down interface: %m", IFNAMSIZ, link->ifname); - - return 1; -} - -static int link_down(Link *link) { - _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL; - int r; - - assert(link); - assert(link->manager); - assert(link->manager->rtnl); - - log_link_debug(link, "bringing link down"); - - r = sd_rtnl_message_new_link(link->manager->rtnl, &req, - RTM_SETLINK, link->ifindex); - if (r < 0) { - log_link_error(link, "Could not allocate RTM_SETLINK message"); - return r; - } - - r = sd_rtnl_message_link_set_flags(req, 0, IFF_UP); - if (r < 0) { - log_link_error(link, "Could not set link flags: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_call_async(link->manager->rtnl, req, link_down_handler, link, - 0, NULL); - if (r < 0) { - log_link_error(link, - "Could not send rtnetlink message: %s", - strerror(-r)); - return r; - } - - link_ref(link); - - return 0; -} - -static int link_handle_bound_to_list(Link *link) { - Link *l; - Iterator i; - int r; - bool required_up = false; - bool link_is_up = false; - - assert(link); - - if (hashmap_isempty(link->bound_to_links)) - return 0; - - if (link->flags & IFF_UP) - link_is_up = true; - - HASHMAP_FOREACH (l, link->bound_to_links, i) - if (link_has_carrier(l)) { - required_up = true; - break; - } - - if (!required_up && link_is_up) { - r = link_down(link); - if (r < 0) - return r; - } else if (required_up && !link_is_up) { - r = link_up(link); - if (r < 0) - return r; - } - - return 0; -} - -static int link_handle_bound_by_list(Link *link) { - Iterator i; - Link *l; - int r; - - assert(link); - - if (hashmap_isempty(link->bound_by_links)) - return 0; - - HASHMAP_FOREACH (l, link->bound_by_links, i) { - r = link_handle_bound_to_list(l); - if (r < 0) - return r; - } - - return 0; -} - -static int link_put_carrier(Link *link, Link *carrier, Hashmap **h) { - int r; - - assert(link); - assert(carrier); - - if (link == carrier) - return 0; - - if (hashmap_get(*h, INT_TO_PTR(carrier->ifindex))) - return 0; - - r = hashmap_ensure_allocated(h, NULL); - if (r < 0) - return r; - - r = hashmap_put(*h, INT_TO_PTR(carrier->ifindex), carrier); - if (r < 0) - return r; - - return 0; -} - -static int link_new_bound_by_list(Link *link) { - Manager *m; - Link *carrier; - Iterator i; - int r; - bool list_updated = false; - - assert(link); - assert(link->manager); - - m = link->manager; - - HASHMAP_FOREACH (carrier, m->links, i) { - if (!carrier->network) - continue; - - if (strv_isempty(carrier->network->bind_carrier)) - continue; - - if (strv_fnmatch(carrier->network->bind_carrier, link->ifname, 0)) { - r = link_put_carrier(link, carrier, &link->bound_by_links); - if (r < 0) - return r; - - list_updated = true; - } - } - - if (list_updated) - link_save(link); - - HASHMAP_FOREACH (carrier, link->bound_by_links, i) { - r = link_put_carrier(carrier, link, &carrier->bound_to_links); - if (r < 0) - return r; - - link_save(carrier); - } - - return 0; -} - -static int link_new_bound_to_list(Link *link) { - Manager *m; - Link *carrier; - Iterator i; - int r; - bool list_updated = false; - - assert(link); - assert(link->manager); - - if (!link->network) - return 0; - - if (strv_isempty(link->network->bind_carrier)) - return 0; - - m = link->manager; - - HASHMAP_FOREACH (carrier, m->links, i) { - if (strv_fnmatch(link->network->bind_carrier, carrier->ifname, 0)) { - r = link_put_carrier(link, carrier, &link->bound_to_links); - if (r < 0) - return r; - - list_updated = true; - } - } - - if (list_updated) - link_save(link); - - HASHMAP_FOREACH (carrier, link->bound_to_links, i) { - r = link_put_carrier(carrier, link, &carrier->bound_by_links); - if (r < 0) - return r; - - link_save(carrier); - } - - return 0; -} - -static int link_new_carrier_maps(Link *link) { - int r; - - r = link_new_bound_by_list(link); - if (r < 0) - return r; - - r = link_handle_bound_by_list(link); - if (r < 0) - return r; - - r = link_new_bound_to_list(link); - if (r < 0) - return r; - - r = link_handle_bound_to_list(link); - if (r < 0) - return r; - - return 0; -} - -static void link_free_bound_to_list(Link *link) { - Link *bound_to; - Iterator i; - - HASHMAP_FOREACH (bound_to, link->bound_to_links, i) { - hashmap_remove(link->bound_to_links, INT_TO_PTR(bound_to->ifindex)); - - if (hashmap_remove(bound_to->bound_by_links, INT_TO_PTR(link->ifindex))) - link_save(bound_to); - } - - return; -} - -static void link_free_bound_by_list(Link *link) { - Link *bound_by; - Iterator i; - - HASHMAP_FOREACH (bound_by, link->bound_by_links, i) { - hashmap_remove(link->bound_by_links, INT_TO_PTR(bound_by->ifindex)); - - if (hashmap_remove(bound_by->bound_to_links, INT_TO_PTR(link->ifindex))) { - link_save(bound_by); - link_handle_bound_to_list(bound_by); - } - } - - return; -} - -static void link_free_carrier_maps(Link *link) { - bool list_updated = false; - - assert(link); - - if (!hashmap_isempty(link->bound_to_links)) { - link_free_bound_to_list(link); - list_updated = true; - } - - if (!hashmap_isempty(link->bound_by_links)) { - link_free_bound_by_list(link); - list_updated = true; - } - - if (list_updated) - link_save(link); - - return; -} - -void link_drop(Link *link) { - if (!link || link->state == LINK_STATE_LINGER) - return; - - link_set_state(link, LINK_STATE_LINGER); - - link_free_carrier_maps(link); - - log_link_debug(link, "link removed"); - - link_unref(link); - - return; -} - -static int link_joined(Link *link) { - int r; - - assert(link); - assert(link->network); - - if (!hashmap_isempty(link->bound_to_links)) { - r = link_handle_bound_to_list(link); - if (r < 0) - return r; - } else if (!(link->flags & IFF_UP)) { - r = link_up(link); - if (r < 0) { - link_enter_failed(link); - return r; - } - } - - if(link->network->bridge) { - r = link_set_bridge(link); - if (r < 0) { - log_link_error(link, - "Could not set bridge message: %s", - strerror(-r)); - } - } - - return link_enter_set_addresses(link); -} - -static int netdev_join_handler(sd_rtnl *rtnl, sd_rtnl_message *m, - void *userdata) { - _cleanup_link_unref_ Link *link = userdata; - int r; - - assert(link); - assert(link->network); - - link->enslaving --; - - if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) - return 1; - - r = sd_rtnl_message_get_errno(m); - if (r < 0 && r != -EEXIST) { - log_link_error_errno(link, -r, "%-*s: could not join netdev: %m", IFNAMSIZ, link->ifname); - link_enter_failed(link); - return 1; - } else - log_link_debug(link, "joined netdev"); - - if (link->enslaving <= 0) - link_joined(link); - - return 1; -} - -static int link_enter_join_netdev(Link *link) { - NetDev *netdev; - Iterator i; - int r; - - assert(link); - assert(link->network); - assert(link->state == LINK_STATE_PENDING); - - link_set_state(link, LINK_STATE_ENSLAVING); - - link_save(link); - - if (!link->network->bridge && - !link->network->bond && - hashmap_isempty(link->network->stacked_netdevs)) - return link_joined(link); - - if (link->network->bond) { - log_link_struct(link, LOG_DEBUG, - "MESSAGE=%-*s: enslaving by '%s'", - IFNAMSIZ, - link->ifname, link->network->bond->ifname, - NETDEVIF(link->network->bond), - NULL); - - r = netdev_join(link->network->bond, link, &netdev_join_handler); - if (r < 0) { - log_link_struct(link, LOG_WARNING, - "MESSAGE=%-*s: could not join netdev '%s': %s", - IFNAMSIZ, - link->ifname, link->network->bond->ifname, - strerror(-r), - NETDEVIF(link->network->bond), - NULL); - link_enter_failed(link); - return r; - } - - link->enslaving ++; - } - - if (link->network->bridge) { - log_link_struct(link, LOG_DEBUG, - "MESSAGE=%-*s: enslaving by '%s'", - IFNAMSIZ, - link->ifname, link->network->bridge->ifname, - NETDEVIF(link->network->bridge), - NULL); - - r = netdev_join(link->network->bridge, link, - &netdev_join_handler); - if (r < 0) { - log_link_struct(link, LOG_WARNING, - "MESSAGE=%-*s: could not join netdev '%s': %s", - IFNAMSIZ, - link->ifname, link->network->bridge->ifname, - strerror(-r), - NETDEVIF(link->network->bridge), - NULL); - link_enter_failed(link); - return r; - } - - link->enslaving ++; - } - - HASHMAP_FOREACH(netdev, link->network->stacked_netdevs, i) { - log_link_struct(link, LOG_DEBUG, - "MESSAGE=%-*s: enslaving by '%s'", - IFNAMSIZ, - link->ifname, netdev->ifname, NETDEVIF(netdev), - NULL); - - r = netdev_join(netdev, link, &netdev_join_handler); - if (r < 0) { - log_link_struct(link, LOG_WARNING, - "MESSAGE=%-*s: could not join netdev '%s': %s", - IFNAMSIZ, - link->ifname, netdev->ifname, - strerror(-r), - NETDEVIF(netdev), NULL); - link_enter_failed(link); - return r; - } - - link->enslaving ++; - } - - return 0; -} - -static int link_set_ipv4_forward(Link *link) { - const char *p = NULL; - bool b; - int r; - - b = link_ipv4_forward_enabled(link); - - p = strjoina("/proc/sys/net/ipv4/conf/", link->ifname, "/forwarding"); - r = write_string_file_no_create(p, one_zero(b)); - if (r < 0) - log_link_warning_errno(link, r, "Cannot configure IPv4 forwarding for interface %s: %m", link->ifname); - - if (b) { - _cleanup_free_ char *buf = NULL; - - /* If IP forwarding is turned on for this interface, - * then propagate this to the global setting. Given - * that turning this on has side-effects on other - * fields, we'll try to avoid doing this unless - * necessary, hence check the previous value - * first. Note that we never turn this option off - * again, since all interfaces we manage do not do - * forwarding anyway by default, and ownership rules - * of this control are so unclear. */ - - r = read_one_line_file("/proc/sys/net/ipv4/ip_forward", &buf); - if (r < 0) - log_link_warning_errno(link, r, "Cannot read /proc/sys/net/ipv4/ip_forward: %m"); - else if (!streq(buf, "1")) { - r = write_string_file_no_create("/proc/sys/net/ipv4/ip_forward", "1"); - if (r < 0) - log_link_warning_errno(link, r, "Cannot write /proc/sys/net/ipv4/ip_forward: %m"); - } - } - - return 0; -} - -static int link_set_ipv6_forward(Link *link) { - const char *p = NULL; - int r; - - p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/forwarding"); - r = write_string_file_no_create(p, one_zero(link_ipv6_forward_enabled(link))); - if (r < 0) - log_link_warning_errno(link, r, "Cannot configure IPv6 forwarding for interface: %m"); - - return 0; -} - -static int link_configure(Link *link) { - int r; - - assert(link); - assert(link->network); - assert(link->state == LINK_STATE_PENDING); - - r = link_set_bridge_fdb(link); - if (r < 0) - return r; - - r = link_set_ipv4_forward(link); - if (r < 0) - return r; - - r = link_set_ipv6_forward(link); - if (r < 0) - return r; - - if (link_ipv4ll_enabled(link)) { - r = ipv4ll_configure(link); - if (r < 0) - return r; - } - - if (link_dhcp4_enabled(link)) { - r = dhcp4_configure(link); - if (r < 0) - return r; - } - - if (link_dhcp4_server_enabled(link)) { - r = sd_dhcp_server_new(&link->dhcp_server, link->ifindex); - if (r < 0) - return r; - - r = sd_dhcp_server_attach_event(link->dhcp_server, NULL, 0); - if (r < 0) - return r; - } - - if (link_dhcp6_enabled(link)) { - r = icmp6_configure(link); - if (r < 0) - return r; - } - - if (link_lldp_enabled(link)) { - r = sd_lldp_new(link->ifindex, link->ifname, &link->mac, &link->lldp); - if (r < 0) - return r; - - r = sd_lldp_attach_event(link->lldp, NULL, 0); - if (r < 0) - return r; - - r = sd_lldp_set_callback(link->lldp, - lldp_handler, link); - if (r < 0) - return r; - } - - if (link_has_carrier(link)) { - r = link_acquire_conf(link); - if (r < 0) - return r; - } - - return link_enter_join_netdev(link); -} - -static int link_initialized_and_synced(sd_rtnl *rtnl, sd_rtnl_message *m, - void *userdata) { - _cleanup_link_unref_ Link *link = userdata; - Network *network; - int r; - - assert(link); - assert(link->ifname); - assert(link->manager); - - if (link->state != LINK_STATE_PENDING) - return 1; - - log_link_debug(link, "link state is up-to-date"); - - r = link_new_bound_by_list(link); - if (r < 0) - return r; - - r = link_handle_bound_by_list(link); - if (r < 0) - return r; - - r = network_get(link->manager, link->udev_device, link->ifname, - &link->mac, &network); - if (r == -ENOENT) { - link_enter_unmanaged(link); - return 1; - } else if (r < 0) - return r; - - if (link->flags & IFF_LOOPBACK) { - if (network->link_local != ADDRESS_FAMILY_NO) - log_link_debug(link, "ignoring link-local autoconfiguration for loopback link"); - - if (network->dhcp != ADDRESS_FAMILY_NO) - log_link_debug(link, "ignoring DHCP clients for loopback link"); - - if (network->dhcp_server) - log_link_debug(link, "ignoring DHCP server for loopback link"); - } - - r = network_apply(link->manager, network, link); - if (r < 0) - return r; - - r = link_new_bound_to_list(link); - if (r < 0) - return r; - - r = link_configure(link); - if (r < 0) - return r; - - return 1; -} - -int link_initialized(Link *link, struct udev_device *device) { - _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL; - int r; - - assert(link); - assert(link->manager); - assert(link->manager->rtnl); - assert(device); - - if (link->state != LINK_STATE_PENDING) - return 0; - - if (link->udev_device) - return 0; - - log_link_debug(link, "udev initialized link"); - - link->udev_device = udev_device_ref(device); - - /* udev has initialized the link, but we don't know if we have yet - * processed the NEWLINK messages with the latest state. Do a GETLINK, - * when it returns we know that the pending NEWLINKs have already been - * processed and that we are up-to-date */ - - r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_GETLINK, - link->ifindex); - if (r < 0) - return r; - - r = sd_rtnl_call_async(link->manager->rtnl, req, - link_initialized_and_synced, link, 0, NULL); - if (r < 0) - return r; - - link_ref(link); - - return 0; -} - -static Address* link_get_equal_address(Link *link, Address *needle) { - Address *i; - - assert(link); - assert(needle); - - LIST_FOREACH(addresses, i, link->addresses) - if (address_equal(i, needle)) - return i; - - return NULL; -} - -int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata) { - Manager *m = userdata; - Link *link = NULL; - uint16_t type; - _cleanup_address_free_ Address *address = NULL; - unsigned char flags; - Address *existing; - char buf[INET6_ADDRSTRLEN], valid_buf[FORMAT_TIMESPAN_MAX]; - const char *valid_str = NULL; - int r, ifindex; - - assert(rtnl); - assert(message); - assert(m); - - if (sd_rtnl_message_is_error(message)) { - r = sd_rtnl_message_get_errno(message); - if (r < 0) - log_warning_errno(r, "rtnl: failed to receive address: %m"); - - return 0; - } - - r = sd_rtnl_message_get_type(message, &type); - if (r < 0) { - log_warning("rtnl: could not get message type"); - return 0; - } else if (type != RTM_NEWADDR && type != RTM_DELADDR) { - log_warning("rtnl: received unexpected message type when processing address"); - return 0; - } - - r = sd_rtnl_message_addr_get_ifindex(message, &ifindex); - if (r < 0) { - log_warning_errno(r, "rtnl: could not get ifindex from address: %m"); - return 0; - } else if (ifindex <= 0) { - log_warning("rtnl: received address message with invalid ifindex: %d", ifindex); - return 0; - } else { - r = link_get(m, ifindex, &link); - if (r < 0 || !link) { - /* when enumerating we might be out of sync, but we will - * get the address again, so just ignore it */ - if (!m->enumerating) - log_warning("rtnl: received address for nonexistent link (%d), ignoring", ifindex); - return 0; - } - } - - r = address_new_dynamic(&address); - if (r < 0) - return r; - - r = sd_rtnl_message_addr_get_family(message, &address->family); - if (r < 0 || !IN_SET(address->family, AF_INET, AF_INET6)) { - log_link_warning(link, "rtnl: received address with invalid family, ignoring"); - return 0; - } - - r = sd_rtnl_message_addr_get_prefixlen(message, &address->prefixlen); - if (r < 0) { - log_link_warning(link, "rtnl: received address with invalid prefixlen, ignoring"); - return 0; - } - - r = sd_rtnl_message_addr_get_scope(message, &address->scope); - if (r < 0) { - log_link_warning(link, "rtnl: received address with invalid scope, ignoring"); - return 0; - } - - r = sd_rtnl_message_addr_get_flags(message, &flags); - if (r < 0) { - log_link_warning(link, "rtnl: received address with invalid flags, ignoring"); - return 0; - } - address->flags = flags; - - switch (address->family) { - case AF_INET: - r = sd_rtnl_message_read_in_addr(message, IFA_LOCAL, &address->in_addr.in); - if (r < 0) { - log_link_warning(link, "rtnl: received address without valid address, ignoring"); - return 0; - } - - break; - - case AF_INET6: - r = sd_rtnl_message_read_in6_addr(message, IFA_ADDRESS, &address->in_addr.in6); - if (r < 0) { - log_link_warning(link, "rtnl: received address without valid address, ignoring"); - return 0; - } - - break; - - default: - assert_not_reached("invalid address family"); - } - - if (!inet_ntop(address->family, &address->in_addr, buf, INET6_ADDRSTRLEN)) { - log_link_warning(link, "could not print address"); - return 0; - } - - r = sd_rtnl_message_read_cache_info(message, IFA_CACHEINFO, &address->cinfo); - if (r >= 0) { - if (address->cinfo.ifa_valid == CACHE_INFO_INFINITY_LIFE_TIME) - valid_str = "ever"; - else - valid_str = format_timespan(valid_buf, FORMAT_TIMESPAN_MAX, - address->cinfo.ifa_valid * USEC_PER_SEC, - USEC_PER_SEC); - } - - existing = link_get_equal_address(link, address); - - switch (type) { - case RTM_NEWADDR: - if (existing) { - log_link_debug(link, "Updating address: %s/%u (valid for %s)", buf, address->prefixlen, valid_str); - - - existing->scope = address->scope; - existing->flags = address->flags; - existing->cinfo = address->cinfo; - - } else { - log_link_debug(link, "Adding address: %s/%u (valid for %s)", buf, address->prefixlen, valid_str); - - LIST_PREPEND(addresses, link->addresses, address); - address_establish(address, link); - - address = NULL; - - link_save(link); - } - - break; - - case RTM_DELADDR: - - if (existing) { - log_link_debug(link, "Removing address: %s/%u (valid for %s)", buf, address->prefixlen, valid_str); - address_release(existing, link); - LIST_REMOVE(addresses, link->addresses, existing); - address_free(existing); - } else - log_link_warning(link, "Removing non-existent address: %s/%u (valid for %s)", buf, address->prefixlen, valid_str); - - break; - default: - assert_not_reached("Received invalid RTNL message type"); - } - - return 1; -} - -int link_add(Manager *m, sd_rtnl_message *message, Link **ret) { - Link *link; - _cleanup_udev_device_unref_ struct udev_device *device = NULL; - char ifindex_str[2 + DECIMAL_STR_MAX(int)]; - int r; - - assert(m); - assert(m->rtnl); - assert(message); - assert(ret); - - r = link_new(m, message, ret); - if (r < 0) - return r; - - link = *ret; - - log_link_debug(link, "link %d added", link->ifindex); - - if (detect_container(NULL) <= 0) { - /* not in a container, udev will be around */ - sprintf(ifindex_str, "n%d", link->ifindex); - device = udev_device_new_from_device_id(m->udev, ifindex_str); - if (!device) { - log_link_warning(link, - "could not find udev device: %m"); - return -errno; - } - - if (udev_device_get_is_initialized(device) <= 0) { - /* not yet ready */ - log_link_debug(link, "link pending udev initialization..."); - return 0; - } - - r = link_initialized(link, device); - if (r < 0) - return r; - } else { - /* we are calling a callback directly, so must take a ref */ - link_ref(link); - - r = link_initialized_and_synced(m->rtnl, NULL, link); - if (r < 0) - return r; - } - - return 0; -} - -static int link_carrier_gained(Link *link) { - int r; - - assert(link); - - if (link->network) { - r = link_acquire_conf(link); - if (r < 0) { - link_enter_failed(link); - return r; - } - } - - r = link_handle_bound_by_list(link); - if (r < 0) - return r; - - return 0; -} - -static int link_carrier_lost(Link *link) { - int r; - - assert(link); - - r = link_stop_clients(link); - if (r < 0) { - link_enter_failed(link); - return r; - } - - r = link_handle_bound_by_list(link); - if (r < 0) - return r; - - return 0; -} - -int link_carrier_reset(Link *link) { - int r; - - assert(link); - - if (link_has_carrier(link)) { - r = link_carrier_lost(link); - if (r < 0) - return r; - - r = link_carrier_gained(link); - if (r < 0) - return r; - - log_link_info(link, "reset carrier"); - } - - return 0; -} - - -int link_update(Link *link, sd_rtnl_message *m) { - struct ether_addr mac; - const char *ifname; - uint32_t mtu; - bool had_carrier, carrier_gained, carrier_lost; - int r; - - assert(link); - assert(link->ifname); - assert(m); - - if (link->state == LINK_STATE_LINGER) { - link_ref(link); - log_link_info(link, "link readded"); - link_set_state(link, LINK_STATE_ENSLAVING); - - r = link_new_carrier_maps(link); - if (r < 0) - return r; - } - - r = sd_rtnl_message_read_string(m, IFLA_IFNAME, &ifname); - if (r >= 0 && !streq(ifname, link->ifname)) { - log_link_info(link, "renamed to %s", ifname); - - link_free_carrier_maps(link); - - free(link->ifname); - link->ifname = strdup(ifname); - if (!link->ifname) - return -ENOMEM; - - r = link_new_carrier_maps(link); - if (r < 0) - return r; - } - - r = sd_rtnl_message_read_u32(m, IFLA_MTU, &mtu); - if (r >= 0 && mtu > 0) { - link->mtu = mtu; - if (!link->original_mtu) { - link->original_mtu = mtu; - log_link_debug(link, "saved original MTU: %" - PRIu32, link->original_mtu); - } - - if (link->dhcp_client) { - r = sd_dhcp_client_set_mtu(link->dhcp_client, - link->mtu); - if (r < 0) { - log_link_warning(link, - "Could not update MTU in DHCP client: %s", - strerror(-r)); - return r; - } - } - } - - /* The kernel may broadcast NEWLINK messages without the MAC address - set, simply ignore them. */ - r = sd_rtnl_message_read_ether_addr(m, IFLA_ADDRESS, &mac); - if (r >= 0) { - if (memcmp(link->mac.ether_addr_octet, mac.ether_addr_octet, - ETH_ALEN)) { - - memcpy(link->mac.ether_addr_octet, mac.ether_addr_octet, - ETH_ALEN); - - log_link_debug(link, "MAC address: " - "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", - mac.ether_addr_octet[0], - mac.ether_addr_octet[1], - mac.ether_addr_octet[2], - mac.ether_addr_octet[3], - mac.ether_addr_octet[4], - mac.ether_addr_octet[5]); - - if (link->ipv4ll) { - r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac); - if (r < 0) { - log_link_warning(link, - "Could not update MAC address in IPv4LL client: %s", - strerror(-r)); - return r; - } - } - - if (link->dhcp_client) { - r = sd_dhcp_client_set_mac(link->dhcp_client, - (const uint8_t *) &link->mac, - sizeof (link->mac), - ARPHRD_ETHER); - if (r < 0) { - log_link_warning(link, - "Could not update MAC address in DHCP client: %s", - strerror(-r)); - return r; - } - } - - if (link->dhcp6_client) { - r = sd_dhcp6_client_set_mac(link->dhcp6_client, - (const uint8_t *) &link->mac, - sizeof (link->mac), - ARPHRD_ETHER); - if (r < 0) { - log_link_warning(link, - "Could not update MAC address in DHCPv6 client: %s", - strerror(-r)); - return r; - } - } - } - } - - had_carrier = link_has_carrier(link); - - r = link_update_flags(link, m); - if (r < 0) - return r; - - carrier_gained = !had_carrier && link_has_carrier(link); - carrier_lost = had_carrier && !link_has_carrier(link); - - if (carrier_gained) { - log_link_info(link, "gained carrier"); - - r = link_carrier_gained(link); - if (r < 0) - return r; - } else if (carrier_lost) { - log_link_info(link, "lost carrier"); - - r = link_carrier_lost(link); - if (r < 0) - return r; - - } - - return 0; -} - -static void link_update_operstate(Link *link) { - LinkOperationalState operstate; - assert(link); - - if (link->kernel_operstate == IF_OPER_DORMANT) - operstate = LINK_OPERSTATE_DORMANT; - else if (link_has_carrier(link)) { - Address *address; - uint8_t scope = RT_SCOPE_NOWHERE; - - /* if we have carrier, check what addresses we have */ - LIST_FOREACH(addresses, address, link->addresses) { - if (address->flags & (IFA_F_TENTATIVE | IFA_F_DEPRECATED)) - continue; - - if (address->scope < scope) - scope = address->scope; - } - - if (scope < RT_SCOPE_SITE) - /* universally accessible addresses found */ - operstate = LINK_OPERSTATE_ROUTABLE; - else if (scope < RT_SCOPE_HOST) - /* only link or site local addresses found */ - operstate = LINK_OPERSTATE_DEGRADED; - else - /* no useful addresses found */ - operstate = LINK_OPERSTATE_CARRIER; - } else if (link->flags & IFF_UP) - operstate = LINK_OPERSTATE_NO_CARRIER; - else - operstate = LINK_OPERSTATE_OFF; - - if (link->operstate != operstate) { - link->operstate = operstate; - link_send_changed(link, "OperationalState", NULL); - } -} - -int link_save(Link *link) { - _cleanup_free_ char *temp_path = NULL; - _cleanup_fclose_ FILE *f = NULL; - const char *admin_state, *oper_state; - int r; - - assert(link); - assert(link->state_file); - assert(link->lease_file); - assert(link->manager); - - link_update_operstate(link); - - r = manager_save(link->manager); - if (r < 0) - return r; - - if (link->state == LINK_STATE_LINGER) { - unlink(link->state_file); - return 0; - } - - admin_state = link_state_to_string(link->state); - assert(admin_state); - - oper_state = link_operstate_to_string(link->operstate); - assert(oper_state); - - r = fopen_temporary(link->state_file, &f, &temp_path); - if (r < 0) - return r; - - fchmod(fileno(f), 0644); - - fprintf(f, - "# This is private data. Do not parse.\n" - "ADMIN_STATE=%s\n" - "OPER_STATE=%s\n", - admin_state, oper_state); - - if (link->network) { - char **address, **domain; - bool space; - - fprintf(f, "NETWORK_FILE=%s\n", link->network->filename); - - fputs("DNS=", f); - space = false; - STRV_FOREACH(address, link->network->dns) { - if (space) - fputc(' ', f); - fputs(*address, f); - space = true; - } - - if (link->network->dhcp_dns && - link->dhcp_lease) { - const struct in_addr *addresses; - - r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses); - if (r > 0) { - if (space) - fputc(' ', f); - serialize_in_addrs(f, addresses, r); - } - } - - fputs("\n", f); - - fprintf(f, "NTP="); - space = false; - STRV_FOREACH(address, link->network->ntp) { - if (space) - fputc(' ', f); - fputs(*address, f); - space = true; - } - - if (link->network->dhcp_ntp && - link->dhcp_lease) { - const struct in_addr *addresses; - - r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses); - if (r > 0) { - if (space) - fputc(' ', f); - serialize_in_addrs(f, addresses, r); - } - } - - fputs("\n", f); - - fprintf(f, "DOMAINS="); - space = false; - STRV_FOREACH(domain, link->network->domains) { - if (space) - fputc(' ', f); - fputs(*domain, f); - space = true; - } - - if (link->network->dhcp_domains && - link->dhcp_lease) { - const char *domainname; - - r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname); - if (r >= 0) { - if (space) - fputc(' ', f); - fputs(domainname, f); - } - } - - fputs("\n", f); - - fprintf(f, "WILDCARD_DOMAIN=%s\n", - yes_no(link->network->wildcard_domain)); - - fprintf(f, "LLMNR=%s\n", - llmnr_support_to_string(link->network->llmnr)); - } - - if (!hashmap_isempty(link->bound_to_links)) { - Link *carrier; - Iterator i; - bool space = false; - - fputs("CARRIER_BOUND_TO=", f); - HASHMAP_FOREACH(carrier, link->bound_to_links, i) { - if (space) - fputc(' ', f); - fputs(carrier->ifname, f); - space = true; - } - - fputs("\n", f); - } - - if (!hashmap_isempty(link->bound_by_links)) { - Link *carrier; - Iterator i; - bool space = false; - - fputs("CARRIER_BOUND_BY=", f); - space = false; - HASHMAP_FOREACH(carrier, link->bound_by_links, i) { - if (space) - fputc(' ', f); - fputs(carrier->ifname, f); - space = true; - } - - fputs("\n", f); - } - - if (link->dhcp_lease) { - assert(link->network); - - r = sd_dhcp_lease_save(link->dhcp_lease, link->lease_file); - if (r < 0) - goto fail; - - fprintf(f, - "DHCP_LEASE=%s\n", - link->lease_file); - } else - unlink(link->lease_file); - - if (link->lldp) { - assert(link->network); - - r = sd_lldp_save(link->lldp, link->lldp_file); - if (r < 0) - goto fail; - - fprintf(f, - "LLDP_FILE=%s\n", - link->lldp_file); - } else - unlink(link->lldp_file); - - r = fflush_and_check(f); - if (r < 0) - goto fail; - - if (rename(temp_path, link->state_file) < 0) { - r = -errno; - goto fail; - } - - return 0; -fail: - log_link_error(link, "Failed to save link data to %s: %s", link->state_file, strerror(-r)); - unlink(link->state_file); - unlink(temp_path); - return r; -} - -static const char* const link_state_table[_LINK_STATE_MAX] = { - [LINK_STATE_PENDING] = "pending", - [LINK_STATE_ENSLAVING] = "configuring", - [LINK_STATE_SETTING_ADDRESSES] = "configuring", - [LINK_STATE_SETTING_ROUTES] = "configuring", - [LINK_STATE_CONFIGURED] = "configured", - [LINK_STATE_UNMANAGED] = "unmanaged", - [LINK_STATE_FAILED] = "failed", - [LINK_STATE_LINGER] = "linger", -}; - -DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState); - -static const char* const link_operstate_table[_LINK_OPERSTATE_MAX] = { - [LINK_OPERSTATE_OFF] = "off", - [LINK_OPERSTATE_NO_CARRIER] = "no-carrier", - [LINK_OPERSTATE_DORMANT] = "dormant", - [LINK_OPERSTATE_CARRIER] = "carrier", - [LINK_OPERSTATE_DEGRADED] = "degraded", - [LINK_OPERSTATE_ROUTABLE] = "routable", -}; - -DEFINE_STRING_TABLE_LOOKUP(link_operstate, LinkOperationalState); diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h deleted file mode 100644 index 479098cb2b..0000000000 --- a/src/network/networkd-link.h +++ /dev/null @@ -1,164 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2013 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#pragma once - -#include <endian.h> - -#include "networkd.h" - -typedef enum LinkState { - LINK_STATE_PENDING, - LINK_STATE_ENSLAVING, - LINK_STATE_SETTING_ADDRESSES, - LINK_STATE_SETTING_ROUTES, - LINK_STATE_CONFIGURED, - LINK_STATE_UNMANAGED, - LINK_STATE_FAILED, - LINK_STATE_LINGER, - _LINK_STATE_MAX, - _LINK_STATE_INVALID = -1 -} LinkState; - -struct Link { - Manager *manager; - - int n_ref; - - int ifindex; - char *ifname; - char *state_file; - struct ether_addr mac; - uint32_t mtu; - struct udev_device *udev_device; - - unsigned flags; - uint8_t kernel_operstate; - - Network *network; - - LinkState state; - LinkOperationalState operstate; - - unsigned link_messages; - unsigned enslaving; - - LIST_HEAD(Address, addresses); - - sd_dhcp_client *dhcp_client; - sd_dhcp_lease *dhcp_lease; - char *lease_file; - uint16_t original_mtu; - unsigned dhcp4_messages; - bool dhcp4_configured; - - sd_ipv4ll *ipv4ll; - bool ipv4ll_address; - bool ipv4ll_route; - - bool static_configured; - - LIST_HEAD(Address, pool_addresses); - - sd_dhcp_server *dhcp_server; - - sd_icmp6_nd *icmp6_router_discovery; - sd_dhcp6_client *dhcp6_client; - - sd_lldp *lldp; - char *lldp_file; - - Hashmap *bound_by_links; - Hashmap *bound_to_links; -}; - -Link *link_unref(Link *link); -Link *link_ref(Link *link); -int link_get(Manager *m, int ifindex, Link **ret); -int link_add(Manager *manager, sd_rtnl_message *message, Link **ret); -void link_drop(Link *link); - -int link_address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata); -int link_route_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata); - -void link_enter_failed(Link *link); -int link_initialized(Link *link, struct udev_device *device); - -void link_client_handler(Link *link); - -int link_update(Link *link, sd_rtnl_message *message); -int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata); - -int link_save(Link *link); - -int link_carrier_reset(Link *link); -bool link_has_carrier(Link *link); - -int link_set_mtu(Link *link, uint32_t mtu); -int link_set_hostname(Link *link, const char *hostname); - -int ipv4ll_configure(Link *link); -int dhcp4_configure(Link *link); -int icmp6_configure(Link *link); - -bool link_lldp_enabled(Link *link); -bool link_ipv4ll_enabled(Link *link); -bool link_ipv6ll_enabled(Link *link); -bool link_dhcp4_server_enabled(Link *link); -bool link_dhcp4_enabled(Link *link); -bool link_dhcp6_enabled(Link *link); - -const char* link_state_to_string(LinkState s) _const_; -LinkState link_state_from_string(const char *s) _pure_; - -extern const sd_bus_vtable link_vtable[]; - -int link_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error); -int link_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error); -int link_send_changed(Link *link, const char *property, ...) _sentinel_; - -DEFINE_TRIVIAL_CLEANUP_FUNC(Link*, link_unref); -#define _cleanup_link_unref_ _cleanup_(link_unrefp) - -/* Macros which append INTERFACE= to the message */ - -#define log_link_full(link, level, error, fmt, ...) \ - log_object_internal(level, error, __FILE__, __LINE__, __func__, "INTERFACE=", link->ifname, "%-*s: " fmt, IFNAMSIZ, link->ifname, ##__VA_ARGS__) - -#define log_link_debug(link, ...) log_link_full(link, LOG_DEBUG, 0, ##__VA_ARGS__) -#define log_link_info(link, ...) log_link_full(link, LOG_INFO, 0, ##__VA_ARGS__) -#define log_link_notice(link, ...) log_link_full(link, LOG_NOTICE, 0, ##__VA_ARGS__) -#define log_link_warning(link, ...) log_link_full(link, LOG_WARNING, 0, ##__VA_ARGS__) -#define log_link_error(link, ...) log_link_full(link, LOG_ERR, 0, ##__VA_ARGS__) - -#define log_link_debug_errno(link, error, ...) log_link_full(link, LOG_DEBUG, error, ##__VA_ARGS__) -#define log_link_info_errno(link, error, ...) log_link_full(link, LOG_INFO, error, ##__VA_ARGS__) -#define log_link_notice_errno(link, error, ...) log_link_full(link, LOG_NOTICE, error, ##__VA_ARGS__) -#define log_link_warning_errno(link, error, ...) log_link_full(link, LOG_WARNING, error, ##__VA_ARGS__) -#define log_link_error_errno(link, error, ...) log_link_full(link, LOG_ERR, error, ##__VA_ARGS__) - -#define log_link_struct(link, level, ...) log_struct(level, "INTERFACE=%s", link->ifname, __VA_ARGS__) - -#define ADDRESS_FMT_VAL(address) \ - be32toh((address).s_addr) >> 24, \ - (be32toh((address).s_addr) >> 16) & 0xFFu, \ - (be32toh((address).s_addr) >> 8) & 0xFFu, \ - be32toh((address).s_addr) & 0xFFu diff --git a/src/network/networkd-manager-bus.c b/src/network/networkd-manager-bus.c deleted file mode 100644 index b281f4fdb6..0000000000 --- a/src/network/networkd-manager-bus.c +++ /dev/null @@ -1,51 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2015 Tom Gundersen - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#include "bus-util.h" - -#include "networkd.h" - -static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_operational_state, link_operstate, LinkOperationalState); - -const sd_bus_vtable manager_vtable[] = { - SD_BUS_VTABLE_START(0), - - SD_BUS_PROPERTY("OperationalState", "s", property_get_operational_state, offsetof(Manager, operational_state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), - - SD_BUS_VTABLE_END -}; - -int manager_send_changed(Manager *manager, const char *property, ...) { - char **l; - - assert(manager); - - if (!manager->bus) - return 0; /* replace by assert when we have kdbus */ - - l = strv_from_stdarg_alloca(property); - - return sd_bus_emit_properties_changed_strv( - manager->bus, - "/org/freedesktop/network1", - "org.freedesktop.network1.Manager", - l); -} diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c deleted file mode 100644 index 0e204ebae6..0000000000 --- a/src/network/networkd-manager.c +++ /dev/null @@ -1,880 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2013 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. - ***/ - -#include <sys/socket.h> -#include <linux/if.h> - -#include "conf-parser.h" -#include "path-util.h" -#include "networkd.h" -#include "networkd-netdev.h" -#include "networkd-link.h" -#include "libudev-private.h" -#include "udev-util.h" -#include "rtnl-util.h" -#include "bus-util.h" -#include "def.h" -#include "virt.h" - -#include "sd-rtnl.h" -#include "sd-daemon.h" - -/* use 8 MB for receive socket kernel queue. */ -#define RCVBUF_SIZE (8*1024*1024) - -const char* const network_dirs[] = { - "/etc/systemd/network", - "/run/systemd/network", - "/usr/lib/systemd/network", -#ifdef HAVE_SPLIT_USR - "/lib/systemd/network", -#endif - NULL}; - -static int setup_default_address_pool(Manager *m) { - AddressPool *p; - int r; - - assert(m); - - /* Add in the well-known private address ranges. */ - - r = address_pool_new_from_string(m, &p, AF_INET6, "fc00::", 7); - if (r < 0) - return r; - - r = address_pool_new_from_string(m, &p, AF_INET, "192.168.0.0", 16); - if (r < 0) - return r; - - r = address_pool_new_from_string(m, &p, AF_INET, "172.16.0.0", 12); - if (r < 0) - return r; - - r = address_pool_new_from_string(m, &p, AF_INET, "10.0.0.0", 8); - if (r < 0) - return r; - - return 0; -} - -static int on_bus_retry(sd_event_source *s, usec_t usec, void *userdata) { - Manager *m = userdata; - - assert(s); - assert(m); - - m->bus_retry_event_source = sd_event_source_unref(m->bus_retry_event_source); - - manager_connect_bus(m); - - return 0; -} - -static int manager_reset_all(Manager *m) { - Link *link; - Iterator i; - int r; - - assert(m); - - HASHMAP_FOREACH(link, m->links, i) { - r = link_carrier_reset(link); - if (r < 0) - log_link_warning_errno(link, r, "could not reset carrier: %m"); - } - - return 0; -} - -static int match_prepare_for_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *ret_error) { - Manager *m = userdata; - int b, r; - - assert(bus); - assert(bus); - - r = sd_bus_message_read(message, "b", &b); - if (r < 0) { - log_debug_errno(r, "Failed to parse PrepareForSleep signal: %m"); - return 0; - } - - if (b) - return 0; - - log_debug("Coming back from suspend, resetting all connections..."); - - manager_reset_all(m); - - return 0; -} - -int manager_connect_bus(Manager *m) { - int r; - - assert(m); - - r = sd_bus_default_system(&m->bus); - if (r == -ENOENT) { - /* We failed to connect? Yuck, we must be in early - * boot. Let's try in 5s again. As soon as we have - * kdbus we can stop doing this... */ - - log_debug_errno(r, "Failed to connect to bus, trying again in 5s: %m"); - - r = sd_event_add_time(m->event, &m->bus_retry_event_source, CLOCK_MONOTONIC, now(CLOCK_MONOTONIC) + 5*USEC_PER_SEC, 0, on_bus_retry, m); - if (r < 0) - return log_error_errno(r, "Failed to install bus reconnect time event: %m"); - - return 0; - } if (r < 0) - return r; - - r = sd_bus_add_match(m->bus, &m->prepare_for_sleep_slot, - "type='signal'," - "sender='org.freedesktop.login1'," - "interface='org.freedesktop.login1.Manager'," - "member='PrepareForSleep'," - "path='/org/freedesktop/login1'", - match_prepare_for_sleep, - m); - if (r < 0) - return log_error_errno(r, "Failed to add match for PrepareForSleep: %m"); - - r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/network1", "org.freedesktop.network1.Manager", manager_vtable, m); - if (r < 0) - return log_error_errno(r, "Failed to add manager object vtable: %m"); - - r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/network1/link", "org.freedesktop.network1.Link", link_vtable, link_object_find, m); - if (r < 0) - return log_error_errno(r, "Failed to add link object vtable: %m"); - - r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/network1/link", link_node_enumerator, m); - if (r < 0) - return log_error_errno(r, "Failed to add link enumerator: %m"); - - r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/network1/network", "org.freedesktop.network1.Network", network_vtable, network_object_find, m); - if (r < 0) - return log_error_errno(r, "Failed to add network object vtable: %m"); - - r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/network1/network", network_node_enumerator, m); - if (r < 0) - return log_error_errno(r, "Failed to add network enumerator: %m"); - - r = sd_bus_request_name(m->bus, "org.freedesktop.network1", 0); - if (r < 0) - return log_error_errno(r, "Failed to register name: %m"); - - r = sd_bus_attach_event(m->bus, m->event, 0); - if (r < 0) - return log_error_errno(r, "Failed to attach bus to event loop: %m"); - - return 0; -} - -static int manager_udev_process_link(Manager *m, struct udev_device *device) { - Link *link = NULL; - int r, ifindex; - - assert(m); - assert(device); - - if (!streq_ptr(udev_device_get_action(device), "add")) - return 0; - - ifindex = udev_device_get_ifindex(device); - if (ifindex <= 0) { - log_debug("ignoring udev ADD event for device with invalid ifindex"); - return 0; - } - - r = link_get(m, ifindex, &link); - if (r == -ENODEV) - return 0; - else if (r < 0) - return r; - - r = link_initialized(link, device); - if (r < 0) - return r; - - return 0; -} - -static int manager_dispatch_link_udev(sd_event_source *source, int fd, uint32_t revents, void *userdata) { - Manager *m = userdata; - struct udev_monitor *monitor = m->udev_monitor; - _cleanup_udev_device_unref_ struct udev_device *device = NULL; - - device = udev_monitor_receive_device(monitor); - if (!device) - return -ENOMEM; - - manager_udev_process_link(m, device); - return 0; -} - -static int manager_connect_udev(Manager *m) { - int r; - - /* udev does not initialize devices inside containers, - * so we rely on them being already initialized before - * entering the container */ - if (detect_container(NULL) > 0) - return 0; - - m->udev = udev_new(); - if (!m->udev) - return -ENOMEM; - - m->udev_monitor = udev_monitor_new_from_netlink(m->udev, "udev"); - if (!m->udev_monitor) - return -ENOMEM; - - r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_monitor, "net", NULL); - if (r < 0) - return log_error_errno(r, "Could not add udev monitor filter: %m"); - - r = udev_monitor_enable_receiving(m->udev_monitor); - if (r < 0) { - log_error("Could not enable udev monitor"); - return r; - } - - r = sd_event_add_io(m->event, - &m->udev_event_source, - udev_monitor_get_fd(m->udev_monitor), - EPOLLIN, manager_dispatch_link_udev, - m); - if (r < 0) - return r; - - r = sd_event_source_set_description(m->udev_event_source, "networkd-udev"); - if (r < 0) - return r; - - return 0; -} - -static int manager_rtnl_process_link(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata) { - Manager *m = userdata; - Link *link = NULL; - NetDev *netdev = NULL; - uint16_t type; - const char *name; - int r, ifindex; - - assert(rtnl); - assert(message); - assert(m); - - if (sd_rtnl_message_is_error(message)) { - r = sd_rtnl_message_get_errno(message); - if (r < 0) - log_warning_errno(r, "rtnl: could not receive link: %m"); - - return 0; - } - - r = sd_rtnl_message_get_type(message, &type); - if (r < 0) { - log_warning_errno(r, "rtnl: could not get message type: %m"); - return 0; - } else if (type != RTM_NEWLINK && type != RTM_DELLINK) { - log_warning("rtnl: received unexpected message type when processing link"); - return 0; - } - - r = sd_rtnl_message_link_get_ifindex(message, &ifindex); - if (r < 0) { - log_warning_errno(r, "rtnl: could not get ifindex from link: %m"); - return 0; - } else if (ifindex <= 0) { - log_warning("rtnl: received link message with invalid ifindex: %d", ifindex); - return 0; - } else - link_get(m, ifindex, &link); - - r = sd_rtnl_message_read_string(message, IFLA_IFNAME, &name); - if (r < 0) { - log_warning_errno(r, "rtnl: received link message without ifname: %m"); - return 0; - } else - netdev_get(m, name, &netdev); - - switch (type) { - case RTM_NEWLINK: - if (!link) { - /* link is new, so add it */ - r = link_add(m, message, &link); - if (r < 0) { - log_warning_errno(r, "could not add new link: %m"); - return 0; - } - } - - if (netdev) { - /* netdev exists, so make sure the ifindex matches */ - r = netdev_set_ifindex(netdev, message); - if (r < 0) { - log_warning_errno(r, "could not set ifindex on netdev: %m"); - return 0; - } - } - - r = link_update(link, message); - if (r < 0) - return 0; - - break; - - case RTM_DELLINK: - link_drop(link); - netdev_drop(netdev); - - break; - - default: - assert_not_reached("Received invalid RTNL message type."); - } - - return 1; -} - -static int systemd_netlink_fd(void) { - int n, fd, rtnl_fd = -EINVAL; - - n = sd_listen_fds(true); - if (n <= 0) - return -EINVAL; - - for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++) { - if (sd_is_socket(fd, AF_NETLINK, SOCK_RAW, -1) > 0) { - if (rtnl_fd >= 0) - return -EINVAL; - - rtnl_fd = fd; - } - } - - return rtnl_fd; -} - -static int manager_connect_rtnl(Manager *m) { - int fd, r; - - assert(m); - - fd = systemd_netlink_fd(); - if (fd < 0) - r = sd_rtnl_open(&m->rtnl, 3, RTNLGRP_LINK, RTNLGRP_IPV4_IFADDR, RTNLGRP_IPV6_IFADDR); - else - r = sd_rtnl_open_fd(&m->rtnl, fd, 0); - if (r < 0) - return r; - - r = sd_rtnl_inc_rcvbuf(m->rtnl, RCVBUF_SIZE); - if (r < 0) - return r; - - r = sd_rtnl_attach_event(m->rtnl, m->event, 0); - if (r < 0) - return r; - - r = sd_rtnl_add_match(m->rtnl, RTM_NEWLINK, &manager_rtnl_process_link, m); - if (r < 0) - return r; - - r = sd_rtnl_add_match(m->rtnl, RTM_DELLINK, &manager_rtnl_process_link, m); - if (r < 0) - return r; - - r = sd_rtnl_add_match(m->rtnl, RTM_NEWADDR, &link_rtnl_process_address, m); - if (r < 0) - return r; - - r = sd_rtnl_add_match(m->rtnl, RTM_DELADDR, &link_rtnl_process_address, m); - if (r < 0) - return r; - - return 0; -} - -int manager_new(Manager **ret) { - _cleanup_manager_free_ Manager *m = NULL; - int r; - - m = new0(Manager, 1); - if (!m) - return -ENOMEM; - - m->state_file = strdup("/run/systemd/netif/state"); - if (!m->state_file) - return -ENOMEM; - - r = sd_event_default(&m->event); - if (r < 0) - return r; - - sd_event_set_watchdog(m->event, true); - - sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL); - sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL); - - r = manager_connect_rtnl(m); - if (r < 0) - return r; - - r = manager_connect_udev(m); - if (r < 0) - return r; - - m->netdevs = hashmap_new(&string_hash_ops); - if (!m->netdevs) - return -ENOMEM; - - LIST_HEAD_INIT(m->networks); - - r = setup_default_address_pool(m); - if (r < 0) - return r; - - *ret = m; - m = NULL; - - return 0; -} - -void manager_free(Manager *m) { - Network *network; - NetDev *netdev; - Link *link; - AddressPool *pool; - - if (!m) - return; - - free(m->state_file); - - udev_monitor_unref(m->udev_monitor); - udev_unref(m->udev); - sd_bus_unref(m->bus); - sd_bus_slot_unref(m->prepare_for_sleep_slot); - sd_event_source_unref(m->udev_event_source); - sd_event_source_unref(m->bus_retry_event_source); - sd_event_unref(m->event); - - while ((link = hashmap_first(m->links))) - link_unref(link); - hashmap_free(m->links); - - while ((network = m->networks)) - network_free(network); - - hashmap_free(m->networks_by_name); - - while ((netdev = hashmap_first(m->netdevs))) - netdev_unref(netdev); - hashmap_free(m->netdevs); - - while ((pool = m->address_pools)) - address_pool_free(pool); - - sd_rtnl_unref(m->rtnl); - - free(m); -} - -static bool manager_check_idle(void *userdata) { - Manager *m = userdata; - Link *link; - Iterator i; - - assert(m); - - HASHMAP_FOREACH(link, m->links, i) { - /* we are not woken on udev activity, so let's just wait for the - * pending udev event */ - if (link->state == LINK_STATE_PENDING) - return false; - - if (!link->network) - continue; - - /* we are not woken on netork activity, so let's stay around */ - if (link_lldp_enabled(link) || - link_ipv4ll_enabled(link) || - link_dhcp4_server_enabled(link) || - link_dhcp4_enabled(link) || - link_dhcp6_enabled(link)) - return false; - } - - return true; -} - -int manager_run(Manager *m) { - assert(m); - - if (m->bus) - return bus_event_loop_with_idle( - m->event, - m->bus, - "org.freedesktop.network1", - DEFAULT_EXIT_USEC, - manager_check_idle, - m); - else - /* failed to connect to the bus, so we lose exit-on-idle logic, - this should not happen except if dbus is not around at all */ - return sd_event_loop(m->event); -} - -int manager_load_config(Manager *m) { - int r; - - /* update timestamp */ - paths_check_timestamp(network_dirs, &m->network_dirs_ts_usec, true); - - r = netdev_load(m); - if (r < 0) - return r; - - r = network_load(m); - if (r < 0) - return r; - - return 0; -} - -bool manager_should_reload(Manager *m) { - return paths_check_timestamp(network_dirs, &m->network_dirs_ts_usec, false); -} - -int manager_rtnl_enumerate_links(Manager *m) { - _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL; - sd_rtnl_message *link; - int r; - - assert(m); - assert(m->rtnl); - - r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0); - if (r < 0) - return r; - - r = sd_rtnl_message_request_dump(req, true); - if (r < 0) - return r; - - r = sd_rtnl_call(m->rtnl, req, 0, &reply); - if (r < 0) - return r; - - for (link = reply; link; link = sd_rtnl_message_next(link)) { - int k; - - m->enumerating = true; - - k = manager_rtnl_process_link(m->rtnl, link, m); - if (k < 0) - r = k; - - m->enumerating = false; - } - - return r; -} - -int manager_rtnl_enumerate_addresses(Manager *m) { - _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL; - sd_rtnl_message *addr; - int r; - - assert(m); - assert(m->rtnl); - - r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, 0, 0); - if (r < 0) - return r; - - r = sd_rtnl_message_request_dump(req, true); - if (r < 0) - return r; - - r = sd_rtnl_call(m->rtnl, req, 0, &reply); - if (r < 0) - return r; - - for (addr = reply; addr; addr = sd_rtnl_message_next(addr)) { - int k; - - m->enumerating = true; - - k = link_rtnl_process_address(m->rtnl, addr, m); - if (k < 0) - r = k; - - m->enumerating = false; - } - - return r; -} - -static int set_put_in_addr(Set *s, const struct in_addr *address) { - char *p; - int r; - - assert(s); - - r = in_addr_to_string(AF_INET, (const union in_addr_union*) address, &p); - if (r < 0) - return r; - - r = set_consume(s, p); - if (r == -EEXIST) - return 0; - - return r; -} - -static int set_put_in_addrv(Set *s, const struct in_addr *addresses, int n) { - int r, i, c = 0; - - assert(s); - assert(n <= 0 || addresses); - - for (i = 0; i < n; i++) { - r = set_put_in_addr(s, addresses+i); - if (r < 0) - return r; - - c += r; - } - - return c; -} - -static void print_string_set(FILE *f, const char *field, Set *s) { - bool space = false; - Iterator i; - char *p; - - if (set_isempty(s)) - return; - - fputs(field, f); - - SET_FOREACH(p, s, i) { - if (space) - fputc(' ', f); - fputs(p, f); - space = true; - } - fputc('\n', f); -} - -int manager_save(Manager *m) { - _cleanup_set_free_free_ Set *dns = NULL, *ntp = NULL, *domains = NULL; - Link *link; - Iterator i; - _cleanup_free_ char *temp_path = NULL; - _cleanup_fclose_ FILE *f = NULL; - LinkOperationalState operstate = LINK_OPERSTATE_OFF; - const char *operstate_str; - int r; - - assert(m); - assert(m->state_file); - - /* We add all NTP and DNS server to a set, to filter out duplicates */ - dns = set_new(&string_hash_ops); - if (!dns) - return -ENOMEM; - - ntp = set_new(&string_hash_ops); - if (!ntp) - return -ENOMEM; - - domains = set_new(&string_hash_ops); - if (!domains) - return -ENOMEM; - - HASHMAP_FOREACH(link, m->links, i) { - if (link->flags & IFF_LOOPBACK) - continue; - - if (link->operstate > operstate) - operstate = link->operstate; - - if (!link->network) - continue; - - /* First add the static configured entries */ - r = set_put_strdupv(dns, link->network->dns); - if (r < 0) - return r; - - r = set_put_strdupv(ntp, link->network->ntp); - if (r < 0) - return r; - - r = set_put_strdupv(domains, link->network->domains); - if (r < 0) - return r; - - if (!link->dhcp_lease) - continue; - - /* Secondly, add the entries acquired via DHCP */ - if (link->network->dhcp_dns) { - const struct in_addr *addresses; - - r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses); - if (r > 0) { - r = set_put_in_addrv(dns, addresses, r); - if (r < 0) - return r; - } else if (r < 0 && r != -ENOENT) - return r; - } - - if (link->network->dhcp_ntp) { - const struct in_addr *addresses; - - r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses); - if (r > 0) { - r = set_put_in_addrv(ntp, addresses, r); - if (r < 0) - return r; - } else if (r < 0 && r != -ENOENT) - return r; - } - - if (link->network->dhcp_domains) { - const char *domainname; - - r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname); - if (r >= 0) { - r = set_put_strdup(domains, domainname); - if (r < 0) - return r; - } else if (r != -ENOENT) - return r; - } - } - - operstate_str = link_operstate_to_string(operstate); - assert(operstate_str); - - r = fopen_temporary(m->state_file, &f, &temp_path); - if (r < 0) - return r; - - fchmod(fileno(f), 0644); - - fprintf(f, - "# This is private data. Do not parse.\n" - "OPER_STATE=%s\n", operstate_str); - - print_string_set(f, "DNS=", dns); - print_string_set(f, "NTP=", ntp); - print_string_set(f, "DOMAINS=", domains); - - r = fflush_and_check(f); - if (r < 0) - goto fail; - - if (rename(temp_path, m->state_file) < 0) { - r = -errno; - goto fail; - } - - if (m->operational_state != operstate) { - m->operational_state = operstate; - r = manager_send_changed(m, "OperationalState", NULL); - if (r < 0) - log_error_errno(r, "Could not emit changed OperationalState: %m"); - } - - return 0; - -fail: - log_error_errno(r, "Failed to save network state to %s: %m", m->state_file); - unlink(m->state_file); - unlink(temp_path); - return r; -} - -int manager_address_pool_acquire(Manager *m, int family, unsigned prefixlen, union in_addr_union *found) { - AddressPool *p; - int r; - - assert(m); - assert(prefixlen > 0); - assert(found); - - LIST_FOREACH(address_pools, p, m->address_pools) { - if (p->family != family) - continue; - - r = address_pool_acquire(p, prefixlen, found); - if (r != 0) - return r; - } - - return 0; -} - -const char *address_family_boolean_to_string(AddressFamilyBoolean b) { - if (b == ADDRESS_FAMILY_YES || - b == ADDRESS_FAMILY_NO) - return yes_no(b == ADDRESS_FAMILY_YES); - - if (b == ADDRESS_FAMILY_IPV4) - return "ipv4"; - if (b == ADDRESS_FAMILY_IPV6) - return "ipv6"; - - return NULL; -} - -AddressFamilyBoolean address_family_boolean_from_string(const char *s) { - int r; - - /* Make this a true superset of a boolean */ - - r = parse_boolean(s); - if (r > 0) - return ADDRESS_FAMILY_YES; - if (r == 0) - return ADDRESS_FAMILY_NO; - - if (streq(s, "ipv4")) - return ADDRESS_FAMILY_IPV4; - if (streq(s, "ipv6")) - return ADDRESS_FAMILY_IPV6; - - return _ADDRESS_FAMILY_BOOLEAN_INVALID; -} - -DEFINE_CONFIG_PARSE_ENUM(config_parse_address_family_boolean, address_family_boolean, AddressFamilyBoolean, "Failed to parse option"); diff --git a/src/network/networkd-netdev-bond.c b/src/network/networkd-netdev-bond.c deleted file mode 100644 index c9115516fd..0000000000 --- a/src/network/networkd-netdev-bond.c +++ /dev/null @@ -1,197 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2014 Tom Gundersen <teg@jklm.no> - Copyright 2014 Susant Sahani - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#include <netinet/ether.h> -#include <linux/if_bonding.h> - -#include "conf-parser.h" -#include "sd-rtnl.h" -#include "networkd-netdev-bond.h" -#include "missing.h" - -static const char* const bond_mode_table[_NETDEV_BOND_MODE_MAX] = { - [NETDEV_BOND_MODE_BALANCE_RR] = "balance-rr", - [NETDEV_BOND_MODE_ACTIVE_BACKUP] = "active-backup", - [NETDEV_BOND_MODE_BALANCE_XOR] = "balance-xor", - [NETDEV_BOND_MODE_BROADCAST] = "broadcast", - [NETDEV_BOND_MODE_802_3AD] = "802.3ad", - [NETDEV_BOND_MODE_BALANCE_TLB] = "balance-tlb", - [NETDEV_BOND_MODE_BALANCE_ALB] = "balance-alb", -}; - -DEFINE_STRING_TABLE_LOOKUP(bond_mode, BondMode); -DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_mode, bond_mode, BondMode, "Failed to parse bond mode"); - - -static const char* const bond_xmit_hash_policy_table[_NETDEV_BOND_XMIT_HASH_POLICY_MAX] = { - [NETDEV_BOND_XMIT_HASH_POLICY_LAYER2] = "layer2", - [NETDEV_BOND_XMIT_HASH_POLICY_LAYER34] = "layer3+4", - [NETDEV_BOND_XMIT_HASH_POLICY_LAYER23] = "layer2+3", - [NETDEV_BOND_XMIT_HASH_POLICY_ENCAP23] = "encap2+3", - [NETDEV_BOND_XMIT_HASH_POLICY_ENCAP34] = "encap3+4", -}; - -DEFINE_STRING_TABLE_LOOKUP(bond_xmit_hash_policy, BondXmitHashPolicy); -DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_xmit_hash_policy, - bond_xmit_hash_policy, - BondXmitHashPolicy, - "Failed to parse bond transmit hash policy") - -static const char* const bond_lacp_rate_table[_NETDEV_BOND_LACP_RATE_MAX] = { - [NETDEV_BOND_LACP_RATE_SLOW] = "slow", - [NETDEV_BOND_LACP_RATE_FAST] = "fast", -}; - -DEFINE_STRING_TABLE_LOOKUP(bond_lacp_rate, BondLacpRate); -DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_lacp_rate, bond_lacp_rate, BondLacpRate, "Failed to parse bond lacp rate") - -static uint8_t bond_mode_to_kernel(BondMode mode) { - switch (mode) { - case NETDEV_BOND_MODE_BALANCE_RR: - return BOND_MODE_ROUNDROBIN; - case NETDEV_BOND_MODE_ACTIVE_BACKUP: - return BOND_MODE_ACTIVEBACKUP; - case NETDEV_BOND_MODE_BALANCE_XOR: - return BOND_MODE_XOR; - case NETDEV_BOND_MODE_BROADCAST: - return BOND_MODE_BROADCAST; - case NETDEV_BOND_MODE_802_3AD: - return BOND_MODE_8023AD; - case NETDEV_BOND_MODE_BALANCE_TLB: - return BOND_MODE_TLB; - case NETDEV_BOND_MODE_BALANCE_ALB: - return BOND_MODE_ALB; - default: - return (uint8_t) -1; - } -} - -static uint8_t bond_xmit_hash_policy_to_kernel(BondXmitHashPolicy policy) { - switch (policy) { - case NETDEV_BOND_XMIT_HASH_POLICY_LAYER2: - return BOND_XMIT_POLICY_LAYER2; - case NETDEV_BOND_XMIT_HASH_POLICY_LAYER34: - return BOND_XMIT_POLICY_LAYER34; - case NETDEV_BOND_XMIT_HASH_POLICY_LAYER23: - return BOND_XMIT_POLICY_LAYER23; - case NETDEV_BOND_XMIT_HASH_POLICY_ENCAP23: - return BOND_XMIT_POLICY_ENCAP23; - case NETDEV_BOND_XMIT_HASH_POLICY_ENCAP34: - return BOND_XMIT_POLICY_ENCAP34; - default: - return (uint8_t) -1; - } -} - -static int netdev_bond_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) { - Bond *b = BOND(netdev); - int r; - - assert(netdev); - assert(!link); - assert(b); - assert(m); - - if (b->mode != _NETDEV_BOND_MODE_INVALID) { - r = sd_rtnl_message_append_u8(m, IFLA_BOND_MODE, - bond_mode_to_kernel(b->mode)); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_BOND_MODE attribute: %s", - strerror(-r)); - return r; - } - } - - if (b->xmit_hash_policy != _NETDEV_BOND_XMIT_HASH_POLICY_INVALID) { - r = sd_rtnl_message_append_u8(m, IFLA_BOND_XMIT_HASH_POLICY, - bond_xmit_hash_policy_to_kernel(b->xmit_hash_policy)); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_BOND_XMIT_HASH_POLICY attribute: %s", - strerror(-r)); - return r; - } - } - - if (b->lacp_rate != _NETDEV_BOND_LACP_RATE_INVALID && - b->mode == NETDEV_BOND_MODE_802_3AD) { - r = sd_rtnl_message_append_u8(m, IFLA_BOND_AD_LACP_RATE, b->lacp_rate ); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_BOND_AD_LACP_RATE attribute: %s", - strerror(-r)); - return r; - } - } - - if (b->miimon != 0) { - r = sd_rtnl_message_append_u32(m, IFLA_BOND_MIIMON, b->miimon / USEC_PER_MSEC); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_BOND_BOND_MIIMON attribute: %s", - strerror(-r)); - return r; - } - } - - if (b->downdelay != 0) { - r = sd_rtnl_message_append_u32(m, IFLA_BOND_DOWNDELAY, b->downdelay / USEC_PER_MSEC); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_BOND_DOWNDELAY attribute: %s", - strerror(-r)); - return r; - } - } - - if (b->updelay != 0) { - r = sd_rtnl_message_append_u32(m, IFLA_BOND_UPDELAY, b->updelay / USEC_PER_MSEC); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_BOND_UPDELAY attribute: %s", - strerror(-r)); - return r; - } - } - - return 0; -} - -static void bond_init(NetDev *netdev) { - Bond *b = BOND(netdev); - - assert(netdev); - assert(b); - - b->mode = _NETDEV_BOND_MODE_INVALID; - b->xmit_hash_policy = _NETDEV_BOND_XMIT_HASH_POLICY_INVALID; - b->lacp_rate = _NETDEV_BOND_LACP_RATE_INVALID; -} - -const NetDevVTable bond_vtable = { - .object_size = sizeof(Bond), - .init = bond_init, - .sections = "Match\0NetDev\0Bond\0", - .fill_message_create = netdev_bond_fill_message_create, - .create_type = NETDEV_CREATE_MASTER, -}; diff --git a/src/network/networkd-netdev-bond.h b/src/network/networkd-netdev-bond.h deleted file mode 100644 index c09af5fa52..0000000000 --- a/src/network/networkd-netdev-bond.h +++ /dev/null @@ -1,83 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2014 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#pragma once - -typedef struct Bond Bond; - -#include "networkd-netdev.h" - -typedef enum BondMode { - NETDEV_BOND_MODE_BALANCE_RR, - NETDEV_BOND_MODE_ACTIVE_BACKUP, - NETDEV_BOND_MODE_BALANCE_XOR, - NETDEV_BOND_MODE_BROADCAST, - NETDEV_BOND_MODE_802_3AD, - NETDEV_BOND_MODE_BALANCE_TLB, - NETDEV_BOND_MODE_BALANCE_ALB, - _NETDEV_BOND_MODE_MAX, - _NETDEV_BOND_MODE_INVALID = -1 -} BondMode; - -typedef enum BondXmitHashPolicy { - NETDEV_BOND_XMIT_HASH_POLICY_LAYER2, - NETDEV_BOND_XMIT_HASH_POLICY_LAYER34, - NETDEV_BOND_XMIT_HASH_POLICY_LAYER23, - NETDEV_BOND_XMIT_HASH_POLICY_ENCAP23, - NETDEV_BOND_XMIT_HASH_POLICY_ENCAP34, - _NETDEV_BOND_XMIT_HASH_POLICY_MAX, - _NETDEV_BOND_XMIT_HASH_POLICY_INVALID = -1 -} BondXmitHashPolicy; - - -typedef enum BondLacpRate { - NETDEV_BOND_LACP_RATE_SLOW, - NETDEV_BOND_LACP_RATE_FAST, - _NETDEV_BOND_LACP_RATE_MAX, - _NETDEV_BOND_LACP_RATE_INVALID = -1, -} BondLacpRate; - -struct Bond { - NetDev meta; - - BondMode mode; - BondXmitHashPolicy xmit_hash_policy; - BondLacpRate lacp_rate; - - usec_t miimon; - usec_t updelay; - usec_t downdelay; -}; - -extern const NetDevVTable bond_vtable; - -const char *bond_mode_to_string(BondMode d) _const_; -BondMode bond_mode_from_string(const char *d) _pure_; - -const char *bond_xmit_hash_policy_to_string(BondXmitHashPolicy d) _const_; -BondXmitHashPolicy bond_xmit_hash_policy_from_string(const char *d) _pure_; - -const char *bond_lacp_rate_to_string(BondLacpRate d) _const_; -BondLacpRate bond_lacp_rate_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); diff --git a/src/network/networkd-netdev-bridge.c b/src/network/networkd-netdev-bridge.c deleted file mode 100644 index fd6af7e99b..0000000000 --- a/src/network/networkd-netdev-bridge.c +++ /dev/null @@ -1,31 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2014 Tom Gundersen <teg@jklm.no> - Copyright 2014 Susant Sahani - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - - -#include "networkd-netdev-bridge.h" -#include "missing.h" - -const NetDevVTable bridge_vtable = { - .object_size = sizeof(Bridge), - .sections = "Match\0NetDev\0", - .create_type = NETDEV_CREATE_MASTER, -}; diff --git a/src/network/networkd-netdev-bridge.h b/src/network/networkd-netdev-bridge.h deleted file mode 100644 index a7d02b1c91..0000000000 --- a/src/network/networkd-netdev-bridge.h +++ /dev/null @@ -1,32 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2014 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#pragma once - -typedef struct Bridge Bridge; - -#include "networkd-netdev.h" - -struct Bridge { - NetDev meta; -}; - -extern const NetDevVTable bridge_vtable; diff --git a/src/network/networkd-netdev-dummy.c b/src/network/networkd-netdev-dummy.c deleted file mode 100644 index bb246a2be0..0000000000 --- a/src/network/networkd-netdev-dummy.c +++ /dev/null @@ -1,30 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2014 Susant Sahani <susant@redhat.com> - Copyright 2014 Tom Gundersen - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - - -#include "networkd-netdev-dummy.h" - -const NetDevVTable dummy_vtable = { - .object_size = sizeof(Dummy), - .sections = "Match\0NetDev\0", - .create_type = NETDEV_CREATE_INDEPENDENT, -}; diff --git a/src/network/networkd-netdev-dummy.h b/src/network/networkd-netdev-dummy.h deleted file mode 100644 index 0d321e5ae6..0000000000 --- a/src/network/networkd-netdev-dummy.h +++ /dev/null @@ -1,32 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2014 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#pragma once - -typedef struct Dummy Dummy; - -#include "networkd-netdev.h" - -struct Dummy { - NetDev meta; -}; - -extern const NetDevVTable dummy_vtable; diff --git a/src/network/networkd-netdev-gperf.gperf b/src/network/networkd-netdev-gperf.gperf deleted file mode 100644 index 963c47c3e5..0000000000 --- a/src/network/networkd-netdev-gperf.gperf +++ /dev/null @@ -1,66 +0,0 @@ -%{ -#include <stddef.h> -#include "conf-parser.h" -#include "networkd-netdev.h" -#include "networkd-netdev-tunnel.h" -#include "networkd-netdev-bond.h" -#include "networkd-netdev-macvlan.h" -#include "network-internal.h" -%} -struct ConfigPerfItem; -%null_strings -%language=ANSI-C -%define slot-name section_and_lvalue -%define hash-function-name network_netdev_gperf_hash -%define lookup-function-name network_netdev_gperf_lookup -%readonly-tables -%omit-struct-type -%struct-type -%includes -%% -Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(NetDev, match_host) -Match.Virtualization, config_parse_net_condition, CONDITION_VIRTUALIZATION, offsetof(NetDev, match_virt) -Match.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(NetDev, match_kernel) -Match.Architecture, config_parse_net_condition, CONDITION_ARCHITECTURE, offsetof(NetDev, match_arch) -NetDev.Description, config_parse_string, 0, offsetof(NetDev, description) -NetDev.Name, config_parse_ifname, 0, offsetof(NetDev, ifname) -NetDev.Kind, config_parse_netdev_kind, 0, offsetof(NetDev, kind) -NetDev.MTUBytes, config_parse_iec_size, 0, offsetof(NetDev, mtu) -NetDev.MACAddress, config_parse_hwaddr, 0, offsetof(NetDev, mac) -VLAN.Id, config_parse_uint64, 0, offsetof(VLan, id) -MACVLAN.Mode, config_parse_macvlan_mode, 0, offsetof(MacVlan, mode) -IPVLAN.Mode, config_parse_ipvlan_mode, 0, offsetof(IPVlan, mode) -Tunnel.Local, config_parse_tunnel_address, 0, offsetof(Tunnel, local) -Tunnel.Remote, config_parse_tunnel_address, 0, offsetof(Tunnel, remote) -Tunnel.TOS, config_parse_unsigned, 0, offsetof(Tunnel, tos) -Tunnel.TTL, config_parse_unsigned, 0, offsetof(Tunnel, ttl) -Tunnel.DiscoverPathMTU, config_parse_bool, 0, offsetof(Tunnel, pmtudisc) -Tunnel.Mode, config_parse_ip6tnl_mode, 0, offsetof(Tunnel, ip6tnl_mode) -Peer.Name, config_parse_ifname, 0, offsetof(Veth, ifname_peer) -Peer.MACAddress, config_parse_hwaddr, 0, offsetof(Veth, mac_peer) -VXLAN.Id, config_parse_uint64, 0, offsetof(VxLan, id) -VXLAN.Group, config_parse_vxlan_group_address, 0, offsetof(VxLan, group) -VXLAN.TOS, config_parse_unsigned, 0, offsetof(VxLan, tos) -VXLAN.TTL, config_parse_unsigned, 0, offsetof(VxLan, ttl) -VXLAN.MacLearning, config_parse_bool, 0, offsetof(VxLan, learning) -VXLAN.ARPProxy, config_parse_bool, 0, offsetof(VxLan, arp_proxy) -VXLAN.L2MissNotification, config_parse_bool, 0, offsetof(VxLan, l2miss) -VXLAN.L3MissNotification, config_parse_bool, 0, offsetof(VxLan, l3miss) -VXLAN.RouteShortCircuit, config_parse_bool, 0, offsetof(VxLan, route_short_circuit) -VXLAN.FDBAgeingSec, config_parse_sec, 0, offsetof(VxLan, fdb_ageing) -Tun.OneQueue, config_parse_bool, 0, offsetof(TunTap, one_queue) -Tun.MultiQueue, config_parse_bool, 0, offsetof(TunTap, multi_queue) -Tun.PacketInfo, config_parse_bool, 0, offsetof(TunTap, packet_info) -Tun.User, config_parse_string, 0, offsetof(TunTap, user_name) -Tun.Group, config_parse_string, 0, offsetof(TunTap, group_name) -Tap.OneQueue, config_parse_bool, 0, offsetof(TunTap, one_queue) -Tap.MultiQueue, config_parse_bool, 0, offsetof(TunTap, multi_queue) -Tap.PacketInfo, config_parse_bool, 0, offsetof(TunTap, packet_info) -Tap.User, config_parse_string, 0, offsetof(TunTap, user_name) -Tap.Group, config_parse_string, 0, offsetof(TunTap, group_name) -Bond.Mode, config_parse_bond_mode, 0, offsetof(Bond, mode) -Bond.TransmitHashPolicy, config_parse_bond_xmit_hash_policy, 0, offsetof(Bond, xmit_hash_policy) -Bond.LACPTransmitRate, config_parse_bond_lacp_rate, 0, offsetof(Bond, lacp_rate) -Bond.MIIMonitorSec, config_parse_sec, 0, offsetof(Bond, miimon) -Bond.UpDelaySec, config_parse_sec, 0, offsetof(Bond, updelay) -Bond.DownDelaySec, config_parse_sec, 0, offsetof(Bond, downdelay) diff --git a/src/network/networkd-netdev-ipvlan.c b/src/network/networkd-netdev-ipvlan.c deleted file mode 100644 index 5189000c1f..0000000000 --- a/src/network/networkd-netdev-ipvlan.c +++ /dev/null @@ -1,72 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2013-2015 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#include <net/if.h> - -#include "networkd-netdev-ipvlan.h" -#include "conf-parser.h" - -static const char* const ipvlan_mode_table[_NETDEV_IPVLAN_MODE_MAX] = { - [NETDEV_IPVLAN_MODE_L2] = "L2", - [NETDEV_IPVLAN_MODE_L3] = "L3", -}; - -DEFINE_STRING_TABLE_LOOKUP(ipvlan_mode, IPVlanMode); -DEFINE_CONFIG_PARSE_ENUM(config_parse_ipvlan_mode, ipvlan_mode, IPVlanMode, "Failed to parse ipvlan mode"); - -static int netdev_ipvlan_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *req) { - IPVlan *m = IPVLAN(netdev); - int r; - - assert(netdev); - assert(m); - assert(link); - assert(netdev->ifname); - - if (m->mode != _NETDEV_IPVLAN_MODE_INVALID) { - r = sd_rtnl_message_append_u16(req, IFLA_IPVLAN_MODE, m->mode); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_IPVLAN_MODE attribute: %s", - strerror(-r)); - return r; - } - } - - return 0; -} - -static void ipvlan_init(NetDev *n) { - IPVlan *m = IPVLAN(n); - - assert(n); - assert(m); - - m->mode = _NETDEV_IPVLAN_MODE_INVALID; -} - -const NetDevVTable ipvlan_vtable = { - .object_size = sizeof(IPVlan), - .init = ipvlan_init, - .sections = "Match\0NetDev\0IPVLAN\0", - .fill_message_create = netdev_ipvlan_fill_message_create, - .create_type = NETDEV_CREATE_STACKED, -}; diff --git a/src/network/networkd-netdev-ipvlan.h b/src/network/networkd-netdev-ipvlan.h deleted file mode 100644 index 408386f378..0000000000 --- a/src/network/networkd-netdev-ipvlan.h +++ /dev/null @@ -1,47 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2014-2015 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#pragma once - -typedef struct IPVlan IPVlan; - -#include "missing.h" -#include "networkd-netdev.h" - -typedef enum IPVlanMode { - NETDEV_IPVLAN_MODE_L2 = IPVLAN_MODE_L2, - NETDEV_IPVLAN_MODE_L3 = IPVLAN_MODE_L3, - _NETDEV_IPVLAN_MODE_MAX, - _NETDEV_IPVLAN_MODE_INVALID = -1 -} IPVlanMode; - -struct IPVlan { - NetDev meta; - - IPVlanMode mode; -}; - -extern const NetDevVTable ipvlan_vtable; - -const char *ipvlan_mode_to_string(IPVlanMode d) _const_; -IPVlanMode ipvlan_mode_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); diff --git a/src/network/networkd-netdev-macvlan.c b/src/network/networkd-netdev-macvlan.c deleted file mode 100644 index 5f41f1c865..0000000000 --- a/src/network/networkd-netdev-macvlan.c +++ /dev/null @@ -1,74 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2013 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#include <net/if.h> - -#include "networkd-netdev-macvlan.h" -#include "conf-parser.h" - -static const char* const macvlan_mode_table[_NETDEV_MACVLAN_MODE_MAX] = { - [NETDEV_MACVLAN_MODE_PRIVATE] = "private", - [NETDEV_MACVLAN_MODE_VEPA] = "vepa", - [NETDEV_MACVLAN_MODE_BRIDGE] = "bridge", - [NETDEV_MACVLAN_MODE_PASSTHRU] = "passthru", -}; - -DEFINE_STRING_TABLE_LOOKUP(macvlan_mode, MacVlanMode); -DEFINE_CONFIG_PARSE_ENUM(config_parse_macvlan_mode, macvlan_mode, MacVlanMode, "Failed to parse macvlan mode"); - -static int netdev_macvlan_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *req) { - MacVlan *m = MACVLAN(netdev); - int r; - - assert(netdev); - assert(m); - assert(link); - assert(netdev->ifname); - - if (m->mode != _NETDEV_MACVLAN_MODE_INVALID) { - r = sd_rtnl_message_append_u32(req, IFLA_MACVLAN_MODE, m->mode); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_MACVLAN_MODE attribute: %s", - strerror(-r)); - return r; - } - } - - return 0; -} - -static void macvlan_init(NetDev *n) { - MacVlan *m = MACVLAN(n); - - assert(n); - assert(m); - - m->mode = _NETDEV_MACVLAN_MODE_INVALID; -} - -const NetDevVTable macvlan_vtable = { - .object_size = sizeof(MacVlan), - .init = macvlan_init, - .sections = "Match\0NetDev\0MACVLAN\0", - .fill_message_create = netdev_macvlan_fill_message_create, - .create_type = NETDEV_CREATE_STACKED, -}; diff --git a/src/network/networkd-netdev-macvlan.h b/src/network/networkd-netdev-macvlan.h deleted file mode 100644 index d61efc16d4..0000000000 --- a/src/network/networkd-netdev-macvlan.h +++ /dev/null @@ -1,48 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2014 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#pragma once - -typedef struct MacVlan MacVlan; - -#include "networkd-netdev.h" - -typedef enum MacVlanMode { - NETDEV_MACVLAN_MODE_PRIVATE = MACVLAN_MODE_PRIVATE, - NETDEV_MACVLAN_MODE_VEPA = MACVLAN_MODE_VEPA, - NETDEV_MACVLAN_MODE_BRIDGE = MACVLAN_MODE_BRIDGE, - NETDEV_MACVLAN_MODE_PASSTHRU = MACVLAN_MODE_PASSTHRU, - _NETDEV_MACVLAN_MODE_MAX, - _NETDEV_MACVLAN_MODE_INVALID = -1 -} MacVlanMode; - -struct MacVlan { - NetDev meta; - - MacVlanMode mode; -}; - -extern const NetDevVTable macvlan_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); diff --git a/src/network/networkd-netdev-tunnel.c b/src/network/networkd-netdev-tunnel.c deleted file mode 100644 index 89ad3ee048..0000000000 --- a/src/network/networkd-netdev-tunnel.c +++ /dev/null @@ -1,605 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2014 Susant Sahani - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#include <arpa/inet.h> -#include <net/if.h> -#include <linux/ip.h> -#include <linux/if_tunnel.h> -#include <linux/ip6_tunnel.h> - -#include "sd-rtnl.h" -#include "networkd-netdev-tunnel.h" -#include "networkd-link.h" -#include "util.h" -#include "missing.h" -#include "conf-parser.h" - -#define DEFAULT_TNL_HOP_LIMIT 64 - -static const char* const ip6tnl_mode_table[_NETDEV_IP6_TNL_MODE_MAX] = { - [NETDEV_IP6_TNL_MODE_IP6IP6] = "ip6ip6", - [NETDEV_IP6_TNL_MODE_IPIP6] = "ipip6", - [NETDEV_IP6_TNL_MODE_ANYIP6] = "any", -}; - -DEFINE_STRING_TABLE_LOOKUP(ip6tnl_mode, Ip6TnlMode); -DEFINE_CONFIG_PARSE_ENUM(config_parse_ip6tnl_mode, ip6tnl_mode, Ip6TnlMode, "Failed to parse ip6 tunnel Mode"); - -static int netdev_ipip_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) { - Tunnel *t = IPIP(netdev); - int r; - - assert(netdev); - assert(link); - assert(m); - assert(t); - assert(t->family == AF_INET); - - r = sd_rtnl_message_append_u32(m, IFLA_IPTUN_LINK, link->ifindex); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_IPTUN_LINK attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_LOCAL, &t->local.in); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_IPTUN_LOCAL attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_REMOTE, &t->remote.in); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_IPTUN_REMOTE attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_TTL, t->ttl); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_IPTUN_TTL attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_PMTUDISC, t->pmtudisc); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_IPTUN_PMTUDISC attribute: %s", - strerror(-r)); - return r; - } - - return r; -} - -static int netdev_sit_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) { - Tunnel *t = SIT(netdev); - int r; - - assert(netdev); - assert(link); - assert(m); - assert(t); - assert(t->family == AF_INET); - - r = sd_rtnl_message_append_u32(m, IFLA_IPTUN_LINK, link->ifindex); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_IPTUN_LINK attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_LOCAL, &t->local.in); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_IPTUN_LOCAL attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_REMOTE, &t->remote.in); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_IPTUN_REMOTE attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_TTL, t->ttl); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_IPTUN_TTL attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_PMTUDISC, t->pmtudisc); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_IPTUN_PMTUDISC attribute: %s", - strerror(-r)); - return r; - } - - return r; -} - -static int netdev_gre_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) { - Tunnel *t; - int r; - - assert(netdev); - - if (netdev->kind == NETDEV_KIND_GRE) - t = GRE(netdev); - else - t = GRETAP(netdev); - - assert(t); - assert(t->family == AF_INET); - assert(link); - assert(m); - - r = sd_rtnl_message_append_u32(m, IFLA_GRE_LINK, link->ifindex); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_GRE_LINK attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_append_in_addr(m, IFLA_GRE_LOCAL, &t->local.in); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_GRE_LOCAL attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_append_in_addr(m, IFLA_GRE_REMOTE, &t->remote.in); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_GRE_REMOTE attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_append_u8(m, IFLA_GRE_TTL, t->ttl); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_GRE_TTL attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_append_u8(m, IFLA_GRE_TOS, t->tos); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_GRE_TOS attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_append_u8(m, IFLA_GRE_PMTUDISC, t->pmtudisc); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_GRE_PMTUDISC attribute: %s", - strerror(-r)); - return r; - } - - return r; -} - -static int netdev_ip6gre_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) { - Tunnel *t; - int r; - - assert(netdev); - - if (netdev->kind == NETDEV_KIND_IP6GRE) - t = IP6GRE(netdev); - else - t = IP6GRETAP(netdev); - - assert(t); - assert(t->family == AF_INET6); - assert(link); - assert(m); - - r = sd_rtnl_message_append_u32(m, IFLA_GRE_LINK, link->ifindex); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_GRE_LINK attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_append_in6_addr(m, IFLA_GRE_LOCAL, &t->local.in6); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_GRE_LOCAL attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_append_in6_addr(m, IFLA_GRE_REMOTE, &t->remote.in6); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_GRE_REMOTE attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_append_u8(m, IFLA_GRE_TTL, t->ttl); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_GRE_TTL attribute: %s", - strerror(-r)); - return r; - } - - return r; -} - -static int netdev_vti_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) { - Tunnel *t = VTI(netdev); - int r; - - assert(netdev); - assert(link); - assert(m); - assert(t); - assert(t->family == AF_INET); - - r = sd_rtnl_message_append_u32(m, IFLA_VTI_LINK, link->ifindex); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_IPTUN_LINK attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_append_in_addr(m, IFLA_VTI_LOCAL, &t->local.in); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_IPTUN_LOCAL attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_append_in_addr(m, IFLA_VTI_REMOTE, &t->remote.in); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_IPTUN_REMOTE attribute: %s", - strerror(-r)); - return r; - } - - return r; -} - -static int netdev_ip6tnl_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) { - Tunnel *t = IP6TNL(netdev); - uint8_t proto; - int r; - - assert(netdev); - assert(link); - assert(m); - assert(t); - assert(t->family == AF_INET6); - - r = sd_rtnl_message_append_u32(m, IFLA_IPTUN_LINK, link->ifindex); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_IPTUN_LINK attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_append_in6_addr(m, IFLA_IPTUN_LOCAL, &t->local.in6); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_IPTUN_LOCAL attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_append_in6_addr(m, IFLA_IPTUN_REMOTE, &t->remote.in6); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_IPTUN_REMOTE attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_TTL, t->ttl); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_IPTUN_TTL attribute: %s", - strerror(-r)); - return r; - } - - switch (t->ip6tnl_mode) { - case NETDEV_IP6_TNL_MODE_IP6IP6: - proto = IPPROTO_IPV6; - break; - case NETDEV_IP6_TNL_MODE_IPIP6: - proto = IPPROTO_IPIP; - break; - case NETDEV_IP6_TNL_MODE_ANYIP6: - default: - proto = 0; - break; - } - - r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_PROTO, proto); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_IPTUN_MODE attribute: %s", - strerror(-r)); - return r; - } - - return r; -} - -static int netdev_tunnel_verify(NetDev *netdev, const char *filename) { - Tunnel *t = NULL; - - assert(netdev); - assert(filename); - - switch (netdev->kind) { - case NETDEV_KIND_IPIP: - t = IPIP(netdev); - break; - case NETDEV_KIND_SIT: - t = SIT(netdev); - break; - case NETDEV_KIND_GRE: - t = GRE(netdev); - break; - case NETDEV_KIND_GRETAP: - t = GRETAP(netdev); - break; - case NETDEV_KIND_IP6GRE: - t = IP6GRE(netdev); - break; - case NETDEV_KIND_IP6GRETAP: - t = IP6GRETAP(netdev); - break; - case NETDEV_KIND_VTI: - t = VTI(netdev); - break; - case NETDEV_KIND_IP6TNL: - t = IP6TNL(netdev); - break; - default: - assert_not_reached("Invalid tunnel kind"); - } - - assert(t); - - if (t->remote.in.s_addr == INADDR_ANY) { - log_warning("Tunnel without remote address configured in %s. Ignoring", filename); - return -EINVAL; - } - - if (t->family != AF_INET && t->family != AF_INET6) { - log_warning("Tunnel with invalid address family configured in %s. Ignoring", filename); - return -EINVAL; - } - - if (netdev->kind == NETDEV_KIND_IP6TNL) { - if (t->ip6tnl_mode == _NETDEV_IP6_TNL_MODE_INVALID) { - log_warning("IP6 Tunnel without mode configured in %s. Ignoring", filename); - return -EINVAL; - } - } - - return 0; -} - -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) { - Tunnel *t = userdata; - union in_addr_union *addr = data, buffer; - int r, f; - - assert(filename); - assert(lvalue); - assert(rvalue); - assert(data); - - r = in_addr_from_string_auto(rvalue, &f, &buffer); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Tunnel address is invalid, ignoring assignment: %s", rvalue); - return 0; - } - - if (t->family != AF_UNSPEC && t->family != f) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Tunnel addresses incompatible, ignoring assignment: %s", rvalue); - return 0; - } - - t->family = f; - *addr = buffer; - - return 0; -} - -static void ipip_init(NetDev *n) { - Tunnel *t = IPIP(n); - - assert(n); - assert(t); - - t->pmtudisc = true; -} - -static void sit_init(NetDev *n) { - Tunnel *t = SIT(n); - - assert(n); - assert(t); - - t->pmtudisc = true; -} - -static void vti_init(NetDev *n) { - Tunnel *t = VTI(n); - - assert(n); - assert(t); - - t->pmtudisc = true; -} - -static void gre_init(NetDev *n) { - Tunnel *t; - - assert(n); - - if (n->kind == NETDEV_KIND_GRE) - t = GRE(n); - else - t = GRETAP(n); - - assert(t); - - t->pmtudisc = true; -} - -static void ip6gre_init(NetDev *n) { - Tunnel *t; - - assert(n); - - if (n->kind == NETDEV_KIND_IP6GRE) - t = IP6GRE(n); - else - t = IP6GRETAP(n); - - assert(t); - - t->ttl = DEFAULT_TNL_HOP_LIMIT; -} - -static void ip6tnl_init(NetDev *n) { - Tunnel *t = IP6TNL(n); - - assert(n); - assert(t); - - t->ttl = DEFAULT_TNL_HOP_LIMIT; - t->encap_limit = IPV6_DEFAULT_TNL_ENCAP_LIMIT; - t->ip6tnl_mode = _NETDEV_IP6_TNL_MODE_INVALID; -} - -const NetDevVTable ipip_vtable = { - .object_size = sizeof(Tunnel), - .init = ipip_init, - .sections = "Match\0NetDev\0Tunnel\0", - .fill_message_create = netdev_ipip_fill_message_create, - .create_type = NETDEV_CREATE_STACKED, - .config_verify = netdev_tunnel_verify, -}; - -const NetDevVTable sit_vtable = { - .object_size = sizeof(Tunnel), - .init = sit_init, - .sections = "Match\0NetDev\0Tunnel\0", - .fill_message_create = netdev_sit_fill_message_create, - .create_type = NETDEV_CREATE_STACKED, - .config_verify = netdev_tunnel_verify, -}; - -const NetDevVTable vti_vtable = { - .object_size = sizeof(Tunnel), - .init = vti_init, - .sections = "Match\0NetDev\0Tunnel\0", - .fill_message_create = netdev_vti_fill_message_create, - .create_type = NETDEV_CREATE_STACKED, - .config_verify = netdev_tunnel_verify, -}; - -const NetDevVTable gre_vtable = { - .object_size = sizeof(Tunnel), - .init = gre_init, - .sections = "Match\0NetDev\0Tunnel\0", - .fill_message_create = netdev_gre_fill_message_create, - .create_type = NETDEV_CREATE_STACKED, - .config_verify = netdev_tunnel_verify, -}; - -const NetDevVTable gretap_vtable = { - .object_size = sizeof(Tunnel), - .init = gre_init, - .sections = "Match\0NetDev\0Tunnel\0", - .fill_message_create = netdev_gre_fill_message_create, - .create_type = NETDEV_CREATE_STACKED, - .config_verify = netdev_tunnel_verify, -}; - -const NetDevVTable ip6gre_vtable = { - .object_size = sizeof(Tunnel), - .init = ip6gre_init, - .sections = "Match\0NetDev\0Tunnel\0", - .fill_message_create = netdev_ip6gre_fill_message_create, - .create_type = NETDEV_CREATE_STACKED, - .config_verify = netdev_tunnel_verify, -}; - -const NetDevVTable ip6gretap_vtable = { - .object_size = sizeof(Tunnel), - .init = ip6gre_init, - .sections = "Match\0NetDev\0Tunnel\0", - .fill_message_create = netdev_ip6gre_fill_message_create, - .create_type = NETDEV_CREATE_STACKED, - .config_verify = netdev_tunnel_verify, -}; - -const NetDevVTable ip6tnl_vtable = { - .object_size = sizeof(Tunnel), - .init = ip6tnl_init, - .sections = "Match\0NetDev\0Tunnel\0", - .fill_message_create = netdev_ip6tnl_fill_message_create, - .create_type = NETDEV_CREATE_STACKED, - .config_verify = netdev_tunnel_verify, -}; diff --git a/src/network/networkd-netdev-tunnel.h b/src/network/networkd-netdev-tunnel.h deleted file mode 100644 index 453d73c596..0000000000 --- a/src/network/networkd-netdev-tunnel.h +++ /dev/null @@ -1,71 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2014 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#pragma once - -typedef struct Tunnel Tunnel; - -#include "networkd-netdev.h" - -typedef enum Ip6TnlMode { - NETDEV_IP6_TNL_MODE_IP6IP6, - NETDEV_IP6_TNL_MODE_IPIP6, - NETDEV_IP6_TNL_MODE_ANYIP6, - _NETDEV_IP6_TNL_MODE_MAX, - _NETDEV_IP6_TNL_MODE_INVALID = -1, -} Ip6TnlMode; - -struct Tunnel { - NetDev meta; - - uint8_t encap_limit; - - int family; - - unsigned ttl; - unsigned tos; - unsigned flags; - - union in_addr_union local; - union in_addr_union remote; - - Ip6TnlMode ip6tnl_mode; - - bool pmtudisc; -}; - -extern const NetDevVTable ipip_vtable; -extern const NetDevVTable sit_vtable; -extern const NetDevVTable vti_vtable; -extern const NetDevVTable gre_vtable; -extern const NetDevVTable gretap_vtable; -extern const NetDevVTable ip6gre_vtable; -extern const NetDevVTable ip6gretap_vtable; -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); diff --git a/src/network/networkd-netdev-tuntap.c b/src/network/networkd-netdev-tuntap.c deleted file mode 100644 index 4f449aea48..0000000000 --- a/src/network/networkd-netdev-tuntap.c +++ /dev/null @@ -1,205 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2014 Susant Sahani <susant@redhat.com> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#include <sys/ioctl.h> -#include <net/if.h> -#include <linux/if_tun.h> - -#include "networkd-netdev-tuntap.h" - -#define TUN_DEV "/dev/net/tun" - -static int netdev_fill_tuntap_message(NetDev *netdev, struct ifreq *ifr) { - TunTap *t; - - assert(netdev); - assert(netdev->ifname); - assert(ifr); - - if (netdev->kind == NETDEV_KIND_TAP) { - t = TAP(netdev); - ifr->ifr_flags |= IFF_TAP; - } else { - t = TUN(netdev); - ifr->ifr_flags |= IFF_TUN; - } - - if (!t->packet_info) - ifr->ifr_flags |= IFF_NO_PI; - - if (t->one_queue) - ifr->ifr_flags |= IFF_ONE_QUEUE; - - if (t->multi_queue) - ifr->ifr_flags |= IFF_MULTI_QUEUE; - - strncpy(ifr->ifr_name, netdev->ifname, IFNAMSIZ-1); - - return 0; -} - -static int netdev_tuntap_add(NetDev *netdev, struct ifreq *ifr) { - _cleanup_close_ int fd; - TunTap *t = NULL; - const char *user; - const char *group; - uid_t uid; - gid_t gid; - int r; - - assert(netdev); - assert(ifr); - - fd = open(TUN_DEV, O_RDWR); - if (fd < 0) { - log_netdev_error(netdev, "Failed to open tun dev: %m"); - return -errno; - } - - r = ioctl(fd, TUNSETIFF, ifr); - if (r < 0) { - log_netdev_error(netdev, - "TUNSETIFF failed on tun dev: %s", - strerror(-r)); - return r; - } - - if (netdev->kind == NETDEV_KIND_TAP) - t = TAP(netdev); - else - t = TUN(netdev); - - assert(t); - - if(t->user_name) { - - user = t->user_name; - - r = get_user_creds(&user, &uid, NULL, NULL, NULL); - if (r < 0) { - log_error_errno(r, "Cannot resolve user name %s: %m", - t->user_name); - return 0; - } - - r = ioctl(fd, TUNSETOWNER, uid); - if ( r < 0) { - log_netdev_error(netdev, - "TUNSETOWNER failed on tun dev: %s", - strerror(-r)); - } - } - - if(t->group_name) { - - group = t->group_name; - - r = get_group_creds(&group, &gid); - if (r < 0) { - log_error_errno(r, "Cannot resolve group name %s: %m", - t->group_name); - return 0; - } - - r = ioctl(fd, TUNSETGROUP, gid); - if( r < 0) { - log_netdev_error(netdev, - "TUNSETGROUP failed on tun dev: %s", - strerror(-r)); - return r; - } - - } - - r = ioctl(fd, TUNSETPERSIST, 1); - if (r < 0) { - log_netdev_error(netdev, - "TUNSETPERSIST failed on tun dev: %s", - strerror(-r)); - return r; - } - - return 0; -} - -static int netdev_create_tuntap(NetDev *netdev) { - struct ifreq ifr = {}; - int r; - - r = netdev_fill_tuntap_message(netdev, &ifr); - if(r < 0) - return r; - - return netdev_tuntap_add(netdev, &ifr); -} - -static void tuntap_done(NetDev *netdev) { - TunTap *t = NULL; - - assert(netdev); - - if (netdev->kind == NETDEV_KIND_TUN) - t = TUN(netdev); - else - t = TAP(netdev); - - assert(t); - - free(t->user_name); - t->user_name = NULL; - - free(t->group_name); - t->group_name = NULL; -} - -static int tuntap_verify(NetDev *netdev, const char *filename) { - assert(netdev); - - if (netdev->mtu) { - log_warning_netdev(netdev, "MTU configured for %s, ignoring", - netdev_kind_to_string(netdev->kind)); - } - - if (netdev->mac) { - log_warning_netdev(netdev, "MAC configured for %s, ignoring", - netdev_kind_to_string(netdev->kind)); - } - - return 0; -} - -const NetDevVTable tun_vtable = { - .object_size = sizeof(TunTap), - .sections = "Match\0NetDev\0Tun\0", - .config_verify = tuntap_verify, - .done = tuntap_done, - .create = netdev_create_tuntap, - .create_type = NETDEV_CREATE_INDEPENDENT, -}; - -const NetDevVTable tap_vtable = { - .object_size = sizeof(TunTap), - .sections = "Match\0NetDev\0Tap\0", - .config_verify = tuntap_verify, - .done = tuntap_done, - .create = netdev_create_tuntap, - .create_type = NETDEV_CREATE_INDEPENDENT, -}; diff --git a/src/network/networkd-netdev-tuntap.h b/src/network/networkd-netdev-tuntap.h deleted file mode 100644 index b804875bbb..0000000000 --- a/src/network/networkd-netdev-tuntap.h +++ /dev/null @@ -1,39 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2014 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#pragma once - -typedef struct TunTap TunTap; - -#include "networkd-netdev.h" - -struct TunTap { - NetDev meta; - - char *user_name; - char *group_name; - bool one_queue; - bool multi_queue; - bool packet_info; -}; - -extern const NetDevVTable tun_vtable; -extern const NetDevVTable tap_vtable; diff --git a/src/network/networkd-netdev-veth.c b/src/network/networkd-netdev-veth.c deleted file mode 100644 index 9e9e1225e7..0000000000 --- a/src/network/networkd-netdev-veth.c +++ /dev/null @@ -1,115 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2014 Susant Sahani <susant@redhat.com> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#include <net/if.h> -#include <linux/veth.h> - -#include "sd-rtnl.h" -#include "networkd-netdev-veth.h" - -static int netdev_veth_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) { - Veth *v = VETH(netdev); - int r; - - assert(netdev); - assert(!link); - assert(v); - assert(m); - - r = sd_rtnl_message_open_container(m, VETH_INFO_PEER); - if (r < 0) { - log_netdev_error(netdev, - "Could not append VETH_INFO_PEER attribute: %s", - strerror(-r)); - return r; - } - - if (v->ifname_peer) { - r = sd_rtnl_message_append_string(m, IFLA_IFNAME, v->ifname_peer); - if (r < 0) - return log_error_errno(r, "Failed to add netlink interface name: %m"); - } - - if (v->mac_peer) { - r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, v->mac_peer); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_ADDRESS attribute: %s", - strerror(-r)); - return r; - } - } - - r = sd_rtnl_message_close_container(m); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_INFO_DATA attribute: %s", - strerror(-r)); - return r; - } - - return r; -} - -static int netdev_veth_verify(NetDev *netdev, const char *filename) { - Veth *v = VETH(netdev); - int r; - - assert(netdev); - assert(v); - assert(filename); - - if (!v->ifname_peer) { - log_warning("Veth NetDev without peer name configured in %s. Ignoring", - filename); - return -EINVAL; - } - - if (!v->mac_peer) { - r = netdev_get_mac(v->ifname_peer, &v->mac_peer); - if (r < 0) { - log_warning("Failed to generate predictable MAC address for %s. Ignoring", - v->ifname_peer); - return -EINVAL; - } - } - - return 0; -} - -static void veth_done(NetDev *n) { - Veth *v = VETH(n); - - assert(n); - assert(v); - - free(v->ifname_peer); - free(v->mac_peer); -} - -const NetDevVTable veth_vtable = { - .object_size = sizeof(Veth), - .sections = "Match\0NetDev\0Peer\0", - .done = veth_done, - .fill_message_create = netdev_veth_fill_message_create, - .create_type = NETDEV_CREATE_INDEPENDENT, - .config_verify = netdev_veth_verify, -}; diff --git a/src/network/networkd-netdev-veth.h b/src/network/networkd-netdev-veth.h deleted file mode 100644 index 85d8b49a75..0000000000 --- a/src/network/networkd-netdev-veth.h +++ /dev/null @@ -1,35 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2014 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#pragma once - -typedef struct Veth Veth; - -#include "networkd-netdev.h" - -struct Veth { - NetDev meta; - - char *ifname_peer; - struct ether_addr *mac_peer; -}; - -extern const NetDevVTable veth_vtable; diff --git a/src/network/networkd-netdev-vlan.c b/src/network/networkd-netdev-vlan.c deleted file mode 100644 index 0ed024b41d..0000000000 --- a/src/network/networkd-netdev-vlan.c +++ /dev/null @@ -1,79 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2013 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#include <net/if.h> - -#include "networkd-netdev-vlan.h" - -static int netdev_vlan_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *req) { - VLan *v = VLAN(netdev); - int r; - - assert(netdev); - assert(v); - assert(link); - assert(req); - - if (v->id <= VLANID_MAX) { - r = sd_rtnl_message_append_u16(req, IFLA_VLAN_ID, v->id); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_VLAN_ID attribute: %s", - strerror(-r)); - return r; - } - } - - return 0; -} - -static int netdev_vlan_verify(NetDev *netdev, const char *filename) { - VLan *v = VLAN(netdev); - - assert(netdev); - assert(v); - assert(filename); - - if (v->id > VLANID_MAX) { - log_warning("VLAN without valid Id (%"PRIu64") configured in %s. Ignoring", v->id, filename); - return -EINVAL; - } - - return 0; -} - -static void vlan_init(NetDev *netdev) { - VLan *v = VLAN(netdev); - - assert(netdev); - assert(v); - - v->id = VLANID_MAX + 1; -} - -const NetDevVTable vlan_vtable = { - .object_size = sizeof(VLan), - .init = vlan_init, - .sections = "Match\0NetDev\0VLAN\0", - .fill_message_create = netdev_vlan_fill_message_create, - .create_type = NETDEV_CREATE_STACKED, - .config_verify = netdev_vlan_verify, -}; diff --git a/src/network/networkd-netdev-vlan.h b/src/network/networkd-netdev-vlan.h deleted file mode 100644 index 0c0fbbe093..0000000000 --- a/src/network/networkd-netdev-vlan.h +++ /dev/null @@ -1,36 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2014 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#pragma once - -typedef struct VLan VLan; - -#include "networkd-netdev.h" - -#define VLANID_MAX 4094 - -struct VLan { - NetDev meta; - - uint64_t id; -}; - -extern const NetDevVTable vlan_vtable; diff --git a/src/network/networkd-netdev-vxlan.c b/src/network/networkd-netdev-vxlan.c deleted file mode 100644 index 4a3a51104f..0000000000 --- a/src/network/networkd-netdev-vxlan.c +++ /dev/null @@ -1,209 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2014 Susant Sahani <susant@redhat.com> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#include <net/if.h> - -#include "sd-rtnl.h" -#include "networkd-netdev-vxlan.h" -#include "networkd-link.h" -#include "conf-parser.h" -#include "missing.h" - -static int netdev_vxlan_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) { - VxLan *v = VXLAN(netdev); - int r; - - assert(netdev); - assert(v); - assert(link); - assert(m); - - - if (v->id <= VXLAN_VID_MAX) { - r = sd_rtnl_message_append_u32(m, IFLA_VXLAN_ID, v->id); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_VXLAN_ID attribute: %s", - strerror(-r)); - return r; - } - } - - r = sd_rtnl_message_append_in_addr(m, IFLA_VXLAN_GROUP, &v->group.in); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_VXLAN_GROUP attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_append_u32(m, IFLA_VXLAN_LINK, link->ifindex); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_VXLAN_LINK attribute: %s", - strerror(-r)); - return r; - } - - if(v->ttl) { - r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_TTL, v->ttl); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_VXLAN_TTL attribute: %s", - strerror(-r)); - return r; - } - } - - if(v->tos) { - r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_TOS, v->tos); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_VXLAN_TOS attribute: %s", - strerror(-r)); - return r; - } - } - - r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_LEARNING, v->learning); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_VXLAN_LEARNING attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_RSC, v->route_short_circuit); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_VXLAN_RSC attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_PROXY, v->arp_proxy); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_VXLAN_PROXY attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_L2MISS, v->l2miss); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_VXLAN_L2MISS attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_L3MISS, v->l3miss); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_VXLAN_L3MISS attribute: %s", - strerror(-r)); - return r; - } - - if(v->fdb_ageing) { - r = sd_rtnl_message_append_u32(m, IFLA_VXLAN_AGEING, v->fdb_ageing / USEC_PER_SEC); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_VXLAN_AGEING attribute: %s", - strerror(-r)); - return r; - } - } - - return r; -} - -int config_parse_vxlan_group_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) { - VxLan *v = userdata; - union in_addr_union *addr = data, buffer; - int r, f; - - assert(filename); - assert(lvalue); - assert(rvalue); - assert(data); - - r = in_addr_from_string_auto(rvalue, &f, &buffer); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "vxlan multicast group address is invalid, ignoring assignment: %s", rvalue); - return 0; - } - - if(v->family != AF_UNSPEC && v->family != f) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "vxlan multicast group incompatible, ignoring assignment: %s", rvalue); - return 0; - } - - v->family = f; - *addr = buffer; - - return 0; -} - -static int netdev_vxlan_verify(NetDev *netdev, const char *filename) { - VxLan *v = VXLAN(netdev); - - assert(netdev); - assert(v); - assert(filename); - - if (v->id > VXLAN_VID_MAX) { - log_warning("VXLAN without valid Id configured in %s. Ignoring", filename); - return -EINVAL; - } - - return 0; -} - -static void vxlan_init(NetDev *netdev) { - VxLan *v = VXLAN(netdev); - - assert(netdev); - assert(v); - - v->id = VXLAN_VID_MAX + 1; - v->learning = true; -} - -const NetDevVTable vxlan_vtable = { - .object_size = sizeof(VxLan), - .init = vxlan_init, - .sections = "Match\0NetDev\0VXLAN\0", - .fill_message_create = netdev_vxlan_fill_message_create, - .create_type = NETDEV_CREATE_STACKED, - .config_verify = netdev_vxlan_verify, -}; diff --git a/src/network/networkd-netdev-vxlan.h b/src/network/networkd-netdev-vxlan.h deleted file mode 100644 index 6339af9add..0000000000 --- a/src/network/networkd-netdev-vxlan.h +++ /dev/null @@ -1,52 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2014 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#pragma once - -typedef struct VxLan VxLan; - -#include "networkd-netdev.h" - -#include "in-addr-util.h" - -#define VXLAN_VID_MAX (1u << 24) - 1 - -struct VxLan { - NetDev meta; - - uint64_t id; - - int family; - union in_addr_union group; - - unsigned tos; - unsigned ttl; - - usec_t fdb_ageing; - - bool learning; - bool arp_proxy; - bool route_short_circuit; - bool l2miss; - bool l3miss; -}; - -extern const NetDevVTable vxlan_vtable; diff --git a/src/network/networkd-netdev.c b/src/network/networkd-netdev.c deleted file mode 100644 index e98040d6ec..0000000000 --- a/src/network/networkd-netdev.c +++ /dev/null @@ -1,767 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2013 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#include <net/if.h> - -#include "networkd-netdev.h" -#include "networkd-link.h" -#include "network-internal.h" -#include "conf-files.h" -#include "conf-parser.h" -#include "list.h" -#include "siphash24.h" - -const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX] = { - [NETDEV_KIND_BRIDGE] = &bridge_vtable, - [NETDEV_KIND_BOND] = &bond_vtable, - [NETDEV_KIND_VLAN] = &vlan_vtable, - [NETDEV_KIND_MACVLAN] = &macvlan_vtable, - [NETDEV_KIND_IPVLAN] = &ipvlan_vtable, - [NETDEV_KIND_VXLAN] = &vxlan_vtable, - [NETDEV_KIND_IPIP] = &ipip_vtable, - [NETDEV_KIND_GRE] = &gre_vtable, - [NETDEV_KIND_GRETAP] = &gretap_vtable, - [NETDEV_KIND_IP6GRE] = &ip6gre_vtable, - [NETDEV_KIND_IP6GRETAP] = &ip6gretap_vtable, - [NETDEV_KIND_SIT] = &sit_vtable, - [NETDEV_KIND_VTI] = &vti_vtable, - [NETDEV_KIND_VETH] = &veth_vtable, - [NETDEV_KIND_DUMMY] = &dummy_vtable, - [NETDEV_KIND_TUN] = &tun_vtable, - [NETDEV_KIND_TAP] = &tap_vtable, - [NETDEV_KIND_IP6TNL] = &ip6tnl_vtable, -}; - -static const char* const netdev_kind_table[_NETDEV_KIND_MAX] = { - [NETDEV_KIND_BRIDGE] = "bridge", - [NETDEV_KIND_BOND] = "bond", - [NETDEV_KIND_VLAN] = "vlan", - [NETDEV_KIND_MACVLAN] = "macvlan", - [NETDEV_KIND_IPVLAN] = "ipvlan", - [NETDEV_KIND_VXLAN] = "vxlan", - [NETDEV_KIND_IPIP] = "ipip", - [NETDEV_KIND_GRE] = "gre", - [NETDEV_KIND_GRETAP] = "gretap", - [NETDEV_KIND_IP6GRE] = "ip6gre", - [NETDEV_KIND_IP6GRETAP] = "ip6gretap", - [NETDEV_KIND_SIT] = "sit", - [NETDEV_KIND_VETH] = "veth", - [NETDEV_KIND_VTI] = "vti", - [NETDEV_KIND_DUMMY] = "dummy", - [NETDEV_KIND_TUN] = "tun", - [NETDEV_KIND_TAP] = "tap", - [NETDEV_KIND_IP6TNL] = "ip6tnl", -}; - -DEFINE_STRING_TABLE_LOOKUP(netdev_kind, NetDevKind); -DEFINE_CONFIG_PARSE_ENUM(config_parse_netdev_kind, netdev_kind, NetDevKind, "Failed to parse netdev kind"); - -static void netdev_cancel_callbacks(NetDev *netdev) { - _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL; - netdev_join_callback *callback; - - if (!netdev) - return; - - rtnl_message_new_synthetic_error(-ENODEV, 0, &m); - - while ((callback = netdev->callbacks)) { - if (m) { - assert(callback->link); - assert(callback->callback); - assert(netdev->manager); - assert(netdev->manager->rtnl); - - callback->callback(netdev->manager->rtnl, m, link); - } - - LIST_REMOVE(callbacks, netdev->callbacks, callback); - free(callback); - } -} - -static void netdev_free(NetDev *netdev) { - if (!netdev) - return; - - netdev_cancel_callbacks(netdev); - - if (netdev->ifname) - hashmap_remove(netdev->manager->netdevs, netdev->ifname); - - free(netdev->filename); - - free(netdev->description); - free(netdev->ifname); - free(netdev->mac); - - condition_free_list(netdev->match_host); - condition_free_list(netdev->match_virt); - condition_free_list(netdev->match_kernel); - condition_free_list(netdev->match_arch); - - if (NETDEV_VTABLE(netdev) && - NETDEV_VTABLE(netdev)->done) - NETDEV_VTABLE(netdev)->done(netdev); - - free(netdev); -} - -NetDev *netdev_unref(NetDev *netdev) { - if (netdev && (-- netdev->n_ref <= 0)) - netdev_free(netdev); - - return NULL; -} - -NetDev *netdev_ref(NetDev *netdev) { - if (netdev) - assert_se(++ netdev->n_ref >= 2); - - return netdev; -} - -void netdev_drop(NetDev *netdev) { - if (!netdev || netdev->state == NETDEV_STATE_LINGER) - return; - - netdev->state = NETDEV_STATE_LINGER; - - log_netdev_debug(netdev, "netdev removed"); - - netdev_cancel_callbacks(netdev); - - netdev_unref(netdev); - - return; -} - -int netdev_get(Manager *manager, const char *name, NetDev **ret) { - NetDev *netdev; - - assert(manager); - assert(name); - assert(ret); - - netdev = hashmap_get(manager->netdevs, name); - if (!netdev) { - *ret = NULL; - return -ENOENT; - } - - *ret = netdev; - - return 0; -} - -static int netdev_enter_failed(NetDev *netdev) { - netdev->state = NETDEV_STATE_FAILED; - - return 0; -} - -static int netdev_enslave_ready(NetDev *netdev, Link* link, sd_rtnl_message_handler_t callback) { - _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL; - int r; - - assert(netdev); - assert(netdev->state == NETDEV_STATE_READY); - assert(netdev->manager); - assert(netdev->manager->rtnl); - assert(IN_SET(netdev->kind, NETDEV_KIND_BRIDGE, NETDEV_KIND_BOND)); - assert(link); - assert(callback); - - r = sd_rtnl_message_new_link(netdev->manager->rtnl, &req, - RTM_SETLINK, link->ifindex); - if (r < 0) { - log_netdev_error(netdev, - "Could not allocate RTM_SETLINK message: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_append_u32(req, IFLA_MASTER, netdev->ifindex); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_MASTER attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_call_async(netdev->manager->rtnl, req, callback, link, 0, NULL); - if (r < 0) { - log_netdev_error(netdev, - "Could not send rtnetlink message: %s", - strerror(-r)); - return r; - } - - link_ref(link); - - log_netdev_debug(netdev, "enslaving link '%s'", link->ifname); - - return 0; -} - -static int netdev_enter_ready(NetDev *netdev) { - netdev_join_callback *callback, *callback_next; - int r; - - assert(netdev); - assert(netdev->ifname); - - if (netdev->state != NETDEV_STATE_CREATING) - return 0; - - netdev->state = NETDEV_STATE_READY; - - log_info_netdev(netdev, "netdev ready"); - - LIST_FOREACH_SAFE(callbacks, callback, callback_next, netdev->callbacks) { - /* enslave the links that were attempted to be enslaved before the - * link was ready */ - r = netdev_enslave_ready(netdev, callback->link, callback->callback); - if (r < 0) - return r; - - LIST_REMOVE(callbacks, netdev->callbacks, callback); - link_unref(callback->link); - free(callback); - } - - return 0; -} - -/* callback for netdev's created without a backing Link */ -static int netdev_create_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) { - _cleanup_netdev_unref_ NetDev *netdev = userdata; - int r; - - assert(netdev->state != _NETDEV_STATE_INVALID); - - r = sd_rtnl_message_get_errno(m); - if (r == -EEXIST) - log_info_netdev(netdev, "netdev exists, using existing without changing its parameters"); - else if (r < 0) { - log_warning_netdev(netdev, "netdev could not be created: %s", strerror(-r)); - netdev_drop(netdev); - - return 1; - } - - log_netdev_debug(netdev, "created"); - - return 1; -} - -int netdev_enslave(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback) { - int r; - - assert(netdev); - assert(IN_SET(netdev->kind, NETDEV_KIND_BRIDGE, NETDEV_KIND_BOND)); - - if (netdev->state == NETDEV_STATE_READY) { - r = netdev_enslave_ready(netdev, link, callback); - if (r < 0) - return r; - } else { - /* the netdev is not yet read, save this request for when it is */ - netdev_join_callback *cb; - - cb = new0(netdev_join_callback, 1); - if (!cb) - return log_oom(); - - cb->callback = callback; - cb->link = link; - link_ref(link); - - LIST_PREPEND(callbacks, netdev->callbacks, cb); - - log_netdev_debug(netdev, "will enslave '%s', when reday", - link->ifname); - } - - return 0; -} - -int netdev_set_ifindex(NetDev *netdev, sd_rtnl_message *message) { - uint16_t type; - const char *kind; - const char *received_kind; - const char *received_name; - int r, ifindex; - - assert(netdev); - assert(message); - - r = sd_rtnl_message_get_type(message, &type); - if (r < 0) { - log_netdev_error(netdev, "Could not get rtnl message type"); - return r; - } - - if (type != RTM_NEWLINK) { - log_netdev_error(netdev, "Can not set ifindex from unexpected rtnl message type"); - return -EINVAL; - } - - r = sd_rtnl_message_link_get_ifindex(message, &ifindex); - if (r < 0) { - log_netdev_error(netdev, "Could not get ifindex: %s", strerror(-r)); - netdev_enter_failed(netdev); - return r; - } else if (ifindex <= 0) { - log_netdev_error(netdev, "Got invalid ifindex: %d", ifindex); - netdev_enter_failed(netdev); - return r; - } - - if (netdev->ifindex > 0) { - if (netdev->ifindex != ifindex) { - log_netdev_error(netdev, "Could not set ifindex to %d, already set to %d", - ifindex, netdev->ifindex); - netdev_enter_failed(netdev); - return -EEXIST; - } else - /* ifindex already set to the same for this netdev */ - return 0; - } - - r = sd_rtnl_message_read_string(message, IFLA_IFNAME, &received_name); - if (r < 0) { - log_netdev_error(netdev, "Could not get IFNAME"); - return r; - } - - if (!streq(netdev->ifname, received_name)) { - log_netdev_error(netdev, "Received newlink with wrong IFNAME %s", - received_name); - netdev_enter_failed(netdev); - return r; - } - - r = sd_rtnl_message_enter_container(message, IFLA_LINKINFO); - if (r < 0) { - log_netdev_error(netdev, "Could not get LINKINFO"); - return r; - } - - r = sd_rtnl_message_read_string(message, IFLA_INFO_KIND, &received_kind); - if (r < 0) { - log_netdev_error(netdev, "Could not get KIND"); - return r; - } - - r = sd_rtnl_message_exit_container(message); - if (r < 0) { - log_netdev_error(netdev, "Could not exit container"); - return r; - } - - if (netdev->kind == NETDEV_KIND_TAP) - /* the kernel does not distinguish between tun and tap */ - kind = "tun"; - else { - kind = netdev_kind_to_string(netdev->kind); - if (!kind) { - log_netdev_error(netdev, "Could not get kind"); - netdev_enter_failed(netdev); - return -EINVAL; - } - } - - if (!streq(kind, received_kind)) { - log_netdev_error(netdev, - "Received newlink with wrong KIND %s, " - "expected %s", received_kind, kind); - netdev_enter_failed(netdev); - return r; - } - - netdev->ifindex = ifindex; - - log_netdev_debug(netdev, "netdev has index %d", netdev->ifindex); - - netdev_enter_ready(netdev); - - return 0; -} - -#define HASH_KEY SD_ID128_MAKE(52,e1,45,bd,00,6f,29,96,21,c6,30,6d,83,71,04,48) - -int netdev_get_mac(const char *ifname, struct ether_addr **ret) { - _cleanup_free_ struct ether_addr *mac = NULL; - uint8_t result[8]; - size_t l, sz; - uint8_t *v; - int r; - - assert(ifname); - assert(ret); - - mac = new0(struct ether_addr, 1); - if (!mac) - return -ENOMEM; - - l = strlen(ifname); - sz = sizeof(sd_id128_t) + l; - v = alloca(sz); - - /* fetch some persistent data unique to the machine */ - r = sd_id128_get_machine((sd_id128_t*) v); - if (r < 0) - return r; - - /* combine with some data unique (on this machine) to this - * netdev */ - memcpy(v + sizeof(sd_id128_t), ifname, l); - - /* Let's hash the host machine ID plus the container name. We - * use a fixed, but originally randomly created hash key here. */ - siphash24(result, v, sz, HASH_KEY.bytes); - - assert_cc(ETH_ALEN <= sizeof(result)); - memcpy(mac->ether_addr_octet, result, ETH_ALEN); - - /* see eth_random_addr in the kernel */ - mac->ether_addr_octet[0] &= 0xfe; /* clear multicast bit */ - mac->ether_addr_octet[0] |= 0x02; /* set local assignment bit (IEEE802) */ - - *ret = mac; - mac = NULL; - - return 0; -} - -static int netdev_create(NetDev *netdev, Link *link, - sd_rtnl_message_handler_t callback) { - int r; - - assert(netdev); - assert(!link || callback); - - /* create netdev */ - if (NETDEV_VTABLE(netdev)->create) { - assert(!link); - - r = NETDEV_VTABLE(netdev)->create(netdev); - if (r < 0) - return r; - - log_netdev_debug(netdev, "created"); - } else { - _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL; - - r = sd_rtnl_message_new_link(netdev->manager->rtnl, &m, RTM_NEWLINK, 0); - if (r < 0) { - log_netdev_error(netdev, - "Could not allocate RTM_NEWLINK message: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_IFNAME, attribute: %s", - strerror(-r)); - return r; - } - - if (netdev->mac) { - r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_ADDRESS attribute: %s", - strerror(-r)); - return r; - } - } - - if (netdev->mtu) { - r = sd_rtnl_message_append_u32(m, IFLA_MTU, netdev->mtu); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_MTU attribute: %s", - strerror(-r)); - return r; - } - } - - if (link) { - r = sd_rtnl_message_append_u32(m, IFLA_LINK, link->ifindex); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_LINK attribute: %s", - strerror(-r)); - return r; - } - } - - r = sd_rtnl_message_open_container(m, IFLA_LINKINFO); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_LINKINFO attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA, - netdev_kind_to_string(netdev->kind)); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_INFO_DATA attribute: %s", - strerror(-r)); - return r; - } - - if (NETDEV_VTABLE(netdev)->fill_message_create) { - r = NETDEV_VTABLE(netdev)->fill_message_create(netdev, link, m); - if (r < 0) - return r; - } - - r = sd_rtnl_message_close_container(m); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_LINKINFO attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_close_container(m); - if (r < 0) { - log_netdev_error(netdev, - "Could not append IFLA_LINKINFO attribute: %s", - strerror(-r)); - return r; - } - - - if (link) { - r = sd_rtnl_call_async(netdev->manager->rtnl, m, - callback, link, 0, NULL); - if (r < 0) { - log_netdev_error(netdev, - "Could not send rtnetlink message: %s", - strerror(-r)); - return r; - } - - link_ref(link); - } else { - r = sd_rtnl_call_async(netdev->manager->rtnl, m, - netdev_create_handler, netdev, 0, - NULL); - if (r < 0) { - log_netdev_error(netdev, - "Could not send rtnetlink message: %s", - strerror(-r)); - return r; - } - - netdev_ref(netdev); - } - - netdev->state = NETDEV_STATE_CREATING; - - log_netdev_debug(netdev, "creating"); - } - - return 0; -} - -/* the callback must be called, possibly after a timeout, as otherwise the Link will hang */ -int netdev_join(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback) { - int r; - - assert(netdev); - assert(netdev->manager); - assert(netdev->manager->rtnl); - assert(NETDEV_VTABLE(netdev)); - - switch (NETDEV_VTABLE(netdev)->create_type) { - case NETDEV_CREATE_MASTER: - r = netdev_enslave(netdev, link, callback); - if (r < 0) - return r; - - break; - case NETDEV_CREATE_STACKED: - r = netdev_create(netdev, link, callback); - if (r < 0) - return r; - - break; - default: - assert_not_reached("Can not join independent netdev"); - } - - return 0; -} - -static int netdev_load_one(Manager *manager, const char *filename) { - _cleanup_netdev_unref_ NetDev *netdev = NULL; - _cleanup_free_ NetDev *netdev_raw = NULL; - _cleanup_fclose_ FILE *file = NULL; - int r; - - assert(manager); - assert(filename); - - file = fopen(filename, "re"); - if (!file) { - if (errno == ENOENT) - return 0; - else - return -errno; - } - - if (null_or_empty_fd(fileno(file))) { - log_debug("Skipping empty file: %s", filename); - return 0; - } - - netdev_raw = new0(NetDev, 1); - if (!netdev_raw) - return log_oom(); - - netdev_raw->kind = _NETDEV_KIND_INVALID; - - r = config_parse(NULL, filename, file, - "Match\0NetDev\0", - config_item_perf_lookup, network_netdev_gperf_lookup, - true, false, true, netdev_raw); - if (r < 0) - return r; - - r = fseek(file, 0, SEEK_SET); - if (r < 0) - return -errno; - - /* skip out early if configuration does not match the environment */ - if (net_match_config(NULL, NULL, NULL, NULL, NULL, - netdev_raw->match_host, netdev_raw->match_virt, - netdev_raw->match_kernel, netdev_raw->match_arch, - NULL, NULL, NULL, NULL, NULL, NULL) <= 0) - return 0; - - if (!NETDEV_VTABLE(netdev_raw)) { - log_warning("NetDev with invalid Kind configured in %s. Ignoring", filename); - return 0; - } - - if (!netdev_raw->ifname) { - log_warning("NetDev without Name configured in %s. Ignoring", filename); - return 0; - } - - netdev = malloc0(NETDEV_VTABLE(netdev_raw)->object_size); - if (!netdev) - return log_oom(); - - netdev->n_ref = 1; - netdev->manager = manager; - netdev->state = _NETDEV_STATE_INVALID; - netdev->kind = netdev_raw->kind; - netdev->ifname = netdev_raw->ifname; - - if (NETDEV_VTABLE(netdev)->init) - NETDEV_VTABLE(netdev)->init(netdev); - - r = config_parse(NULL, filename, file, - NETDEV_VTABLE(netdev)->sections, - config_item_perf_lookup, network_netdev_gperf_lookup, - false, false, false, netdev); - if (r < 0) - return r; - - /* verify configuration */ - if (NETDEV_VTABLE(netdev)->config_verify) { - r = NETDEV_VTABLE(netdev)->config_verify(netdev, filename); - if (r < 0) - return 0; - } - - netdev->filename = strdup(filename); - if (!netdev->filename) - return log_oom(); - - if (!netdev->mac) { - r = netdev_get_mac(netdev->ifname, &netdev->mac); - if (r < 0) { - log_error("Failed to generate predictable MAC address for %s", - netdev->ifname); - return r; - } - } - - r = hashmap_put(netdev->manager->netdevs, netdev->ifname, netdev); - if (r < 0) - return r; - - LIST_HEAD_INIT(netdev->callbacks); - - log_netdev_debug(netdev, "loaded %s", netdev_kind_to_string(netdev->kind)); - - switch (NETDEV_VTABLE(netdev)->create_type) { - case NETDEV_CREATE_MASTER: - case NETDEV_CREATE_INDEPENDENT: - r = netdev_create(netdev, NULL, NULL); - if (r < 0) - return 0; - - break; - default: - break; - } - - netdev = NULL; - - return 0; -} - -int netdev_load(Manager *manager) { - NetDev *netdev; - char **files, **f; - int r; - - assert(manager); - - while ((netdev = hashmap_first(manager->netdevs))) - netdev_unref(netdev); - - r = conf_files_list_strv(&files, ".netdev", NULL, network_dirs); - if (r < 0) - return log_error_errno(r, "Failed to enumerate netdev files: %m"); - - STRV_FOREACH_BACKWARDS(f, files) { - r = netdev_load_one(manager, *f); - if (r < 0) - return r; - } - - strv_free(files); - - return 0; -} diff --git a/src/network/networkd-netdev.h b/src/network/networkd-netdev.h deleted file mode 100644 index 7fd83964a5..0000000000 --- a/src/network/networkd-netdev.h +++ /dev/null @@ -1,212 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2013 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#pragma once - -#include "networkd.h" -#include "list.h" - -typedef struct NetDevVTable NetDevVTable; - -typedef struct netdev_join_callback netdev_join_callback; - -struct netdev_join_callback { - sd_rtnl_message_handler_t callback; - Link *link; - - LIST_FIELDS(netdev_join_callback, callbacks); -}; - -typedef enum NetDevKind { - NETDEV_KIND_BRIDGE, - NETDEV_KIND_BOND, - NETDEV_KIND_VLAN, - NETDEV_KIND_MACVLAN, - NETDEV_KIND_IPVLAN, - NETDEV_KIND_VXLAN, - NETDEV_KIND_IPIP, - NETDEV_KIND_GRE, - NETDEV_KIND_GRETAP, - NETDEV_KIND_IP6GRE, - NETDEV_KIND_IP6GRETAP, - NETDEV_KIND_SIT, - NETDEV_KIND_VETH, - NETDEV_KIND_VTI, - NETDEV_KIND_IP6TNL, - NETDEV_KIND_DUMMY, - NETDEV_KIND_TUN, - NETDEV_KIND_TAP, - _NETDEV_KIND_MAX, - _NETDEV_KIND_INVALID = -1 -} NetDevKind; - -typedef enum NetDevState { - NETDEV_STATE_FAILED, - NETDEV_STATE_CREATING, - NETDEV_STATE_READY, - NETDEV_STATE_LINGER, - _NETDEV_STATE_MAX, - _NETDEV_STATE_INVALID = -1, -} NetDevState; - -typedef enum NetDevCreateType { - NETDEV_CREATE_INDEPENDENT, - NETDEV_CREATE_MASTER, - NETDEV_CREATE_STACKED, - _NETDEV_CREATE_MAX, - _NETDEV_CREATE_INVALID = -1, -} NetDevCreateType; - -struct NetDev { - Manager *manager; - - int n_ref; - - char *filename; - - Condition *match_host; - Condition *match_virt; - Condition *match_kernel; - Condition *match_arch; - - NetDevState state; - NetDevKind kind; - char *description; - char *ifname; - struct ether_addr *mac; - size_t mtu; - int ifindex; - - LIST_HEAD(netdev_join_callback, callbacks); -}; - -#include "networkd-netdev-bridge.h" -#include "networkd-netdev-bond.h" -#include "networkd-netdev-vlan.h" -#include "networkd-netdev-macvlan.h" -#include "networkd-netdev-ipvlan.h" -#include "networkd-netdev-vxlan.h" -#include "networkd-netdev-veth.h" -#include "networkd-netdev-tunnel.h" -#include "networkd-netdev-dummy.h" -#include "networkd-netdev-tuntap.h" - -struct NetDevVTable { - /* How much memory does an object of this unit type need */ - size_t object_size; - - /* Config file sections this netdev kind understands, separated - * by NUL chars */ - const char *sections; - - /* This should reset all type-specific variables. This should - * not allocate memory, and is called with zero-initialized - * data. It should hence only initialize variables that need - * to be set != 0. */ - void (*init)(NetDev *n); - - /* This should free all kind-specific variables. It should be - * idempotent. */ - void (*done)(NetDev *n); - - /* fill in message to create netdev */ - int (*fill_message_create)(NetDev *netdev, Link *link, sd_rtnl_message *message); - - /* specifies if netdev is independent, or a master device or a stacked device */ - NetDevCreateType create_type; - - /* create netdev, if not done via rtnl */ - int (*create)(NetDev *netdev); - - /* verify that compulsory configuration options were specified */ - int (*config_verify)(NetDev *netdev, const char *filename); -}; - -extern const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX]; - -#define NETDEV_VTABLE(n) netdev_vtable[(n)->kind] - -/* For casting a netdev into the various netdev kinds */ -#define DEFINE_CAST(UPPERCASE, MixedCase) \ - static inline MixedCase* UPPERCASE(NetDev *n) { \ - if (_unlikely_(!n || n->kind != NETDEV_KIND_##UPPERCASE)) \ - return NULL; \ - \ - return (MixedCase*) n; \ - } - -/* For casting the various netdev kinds into a netdev */ -#define NETDEV(n) (&(n)->meta) - -DEFINE_CAST(BRIDGE, Bridge); -DEFINE_CAST(BOND, Bond); -DEFINE_CAST(VLAN, VLan); -DEFINE_CAST(MACVLAN, MacVlan); -DEFINE_CAST(IPVLAN, IPVlan); -DEFINE_CAST(VXLAN, VxLan); -DEFINE_CAST(IPIP, Tunnel); -DEFINE_CAST(GRE, Tunnel); -DEFINE_CAST(GRETAP, Tunnel); -DEFINE_CAST(IP6GRE, Tunnel); -DEFINE_CAST(IP6GRETAP, Tunnel); -DEFINE_CAST(SIT, Tunnel); -DEFINE_CAST(VTI, Tunnel); -DEFINE_CAST(IP6TNL, Tunnel); -DEFINE_CAST(VETH, Veth); -DEFINE_CAST(DUMMY, Dummy); -DEFINE_CAST(TUN, TunTap); -DEFINE_CAST(TAP, TunTap); - -int netdev_load(Manager *manager); -void netdev_drop(NetDev *netdev); - -NetDev *netdev_unref(NetDev *netdev); -NetDev *netdev_ref(NetDev *netdev); - -DEFINE_TRIVIAL_CLEANUP_FUNC(NetDev*, netdev_unref); -#define _cleanup_netdev_unref_ _cleanup_(netdev_unrefp) - -int netdev_get(Manager *manager, const char *name, NetDev **ret); -int netdev_set_ifindex(NetDev *netdev, sd_rtnl_message *newlink); -int netdev_enslave(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback); -int netdev_get_mac(const char *ifname, struct ether_addr **ret); -int netdev_join(NetDev *netdev, Link *link, sd_rtnl_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); - -/* gperf */ -const struct ConfigPerfItem* network_netdev_gperf_lookup(const char *key, unsigned length); - -/* Macros which append INTERFACE= to the message */ - -#define log_full_netdev(level, netdev, fmt, ...) log_object_internal(level, 0, __FILE__, __LINE__, __func__, "INTERFACE=", netdev->ifname, "%-*s: " fmt, IFNAMSIZ, netdev->ifname, ##__VA_ARGS__) -#define log_netdev_debug(netdev, ...) log_full_netdev(LOG_DEBUG, netdev, ##__VA_ARGS__) -#define log_info_netdev(netdev, ...) log_full_netdev(LOG_INFO, netdev, ##__VA_ARGS__) -#define log_notice_netdev(netdev, ...) log_full_netdev(LOG_NOTICE, netdev, ##__VA_ARGS__) -#define log_warning_netdev(netdev, ...) log_full_netdev(LOG_WARNING, netdev,## __VA_ARGS__) -#define log_netdev_error(netdev, ...) log_full_netdev(LOG_ERR, netdev, ##__VA_ARGS__) - -#define log_struct_netdev(level, netdev, ...) log_struct(level, "INTERFACE=%s", netdev->ifname, __VA_ARGS__) - -#define NETDEVIF(netdev) "INTERFACE=%s", netdev->ifname diff --git a/src/network/networkd-network-bus.c b/src/network/networkd-network-bus.c deleted file mode 100644 index b5f8f5cfb2..0000000000 --- a/src/network/networkd-network-bus.c +++ /dev/null @@ -1,158 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2015 Tom Gundersen - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#include "strv.h" - -#include "networkd.h" - -static int property_get_ether_addrs( - sd_bus *bus, - const char *path, - const char *interface, - const char *property, - sd_bus_message *reply, - void *userdata, - sd_bus_error *error) { - - Network *n = userdata; - const char *ether = NULL; - int r; - - assert(bus); - assert(reply); - assert(n); - - if (n->match_mac) - ether = ether_ntoa(n->match_mac); - - r = sd_bus_message_open_container(reply, 'a', "s"); - if (r < 0) - return r; - - if (ether) { - r = sd_bus_message_append(reply, "s", strempty(ether)); - if (r < 0) - return r; - } - - r = sd_bus_message_close_container(reply); - if (r < 0) - return r; - - return 1; -} - -const sd_bus_vtable network_vtable[] = { - SD_BUS_VTABLE_START(0), - - SD_BUS_PROPERTY("Description", "s", NULL, offsetof(Network, description), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("SourcePath", "s", NULL, offsetof(Network, filename), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("MatchMAC", "as", property_get_ether_addrs, offsetof(Network, match_mac), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("MatchPath", "as", NULL, offsetof(Network, match_path), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("MatchDriver", "as", NULL, offsetof(Network, match_driver), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("MatchType", "as", NULL, offsetof(Network, match_type), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("MatchName", "as", NULL, offsetof(Network, match_name), SD_BUS_VTABLE_PROPERTY_CONST), - - SD_BUS_VTABLE_END -}; - -static char *network_bus_path(Network *network) { - _cleanup_free_ char *name = NULL; - char *networkname, *d, *path; - int r; - - assert(network); - assert(network->filename); - - name = strdup(network->filename); - if (!name) - return NULL; - - networkname = basename(name); - - d = strrchr(networkname, '.'); - if (!d) - return NULL; - - assert(streq(d, ".network")); - - *d = '\0'; - - r = sd_bus_path_encode("/org/freedesktop/network1/network", networkname, &path); - if (r < 0) - return NULL; - - return path; -} - -int network_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) { - _cleanup_strv_free_ char **l = NULL; - Manager *m = userdata; - Network *network; - int r; - - assert(bus); - assert(path); - assert(m); - assert(nodes); - - LIST_FOREACH(networks, network, m->networks) { - char *p; - - p = network_bus_path(network); - if (!p) - return -ENOMEM; - - r = strv_consume(&l, p); - if (r < 0) - return r; - } - - *nodes = l; - l = NULL; - - return 1; -} - -int network_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) { - Manager *m = userdata; - Network *network; - _cleanup_free_ char *name = NULL; - int r; - - assert(bus); - assert(path); - assert(interface); - assert(m); - assert(found); - - r = sd_bus_path_decode(path, "/org/freedesktop/network1/network", &name); - if (r < 0) - return 0; - - r = network_get_by_name(m, name, &network); - if (r < 0) - return 0; - - *found = network; - - return 1; -} diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf deleted file mode 100644 index 8abf5bcf2e..0000000000 --- a/src/network/networkd-network-gperf.gperf +++ /dev/null @@ -1,83 +0,0 @@ -%{ -#include <stddef.h> -#include "conf-parser.h" -#include "networkd.h" -#include "network-internal.h" -%} -struct ConfigPerfItem; -%null_strings -%language=ANSI-C -%define slot-name section_and_lvalue -%define hash-function-name network_network_gperf_hash -%define lookup-function-name network_network_gperf_lookup -%readonly-tables -%omit-struct-type -%struct-type -%includes -%% -Match.MACAddress, config_parse_hwaddr, 0, offsetof(Network, match_mac) -Match.Path, config_parse_strv, 0, offsetof(Network, match_path) -Match.Driver, config_parse_strv, 0, offsetof(Network, match_driver) -Match.Type, config_parse_strv, 0, offsetof(Network, match_type) -Match.Name, config_parse_ifnames, 0, offsetof(Network, match_name) -Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(Network, match_host) -Match.Virtualization, config_parse_net_condition, CONDITION_VIRTUALIZATION, offsetof(Network, match_virt) -Match.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(Network, match_kernel) -Match.Architecture, config_parse_net_condition, CONDITION_ARCHITECTURE, offsetof(Network, match_arch) -Link.MACAddress, config_parse_hwaddr, 0, offsetof(Network, mac) -Link.MTUBytes, config_parse_iec_size, 0, offsetof(Network, mtu) -Network.Description, config_parse_string, 0, offsetof(Network, description) -Network.Bridge, config_parse_netdev, 0, offsetof(Network, bridge) -Network.Bond, config_parse_netdev, 0, offsetof(Network, bond) -Network.VLAN, config_parse_netdev, 0, 0 -Network.MACVLAN, config_parse_netdev, 0, 0 -Network.IPVLAN, config_parse_netdev, 0, 0 -Network.VXLAN, config_parse_netdev, 0, 0 -Network.Tunnel, config_parse_tunnel, 0, 0 -Network.DHCP, config_parse_dhcp, 0, offsetof(Network, dhcp) -Network.DHCPServer, config_parse_bool, 0, offsetof(Network, dhcp_server) -Network.LinkLocalAddressing, config_parse_address_family_boolean,0, offsetof(Network, link_local) -Network.IPv4LLRoute, config_parse_bool, 0, offsetof(Network, ipv4ll_route) -Network.IPv6Token, config_parse_ipv6token, 0, offsetof(Network, ipv6_token) -Network.LLDP, config_parse_bool, 0, offsetof(Network, lldp) -Network.Address, config_parse_address, 0, 0 -Network.Gateway, config_parse_gateway, 0, 0 -Network.Domains, config_parse_domains, 0, offsetof(Network, domains) -Network.DNS, config_parse_strv, 0, offsetof(Network, dns) -Network.LLMNR, config_parse_llmnr, 0, offsetof(Network, llmnr) -Network.NTP, config_parse_strv, 0, offsetof(Network, ntp) -Network.IPForward, config_parse_address_family_boolean,0, offsetof(Network, ip_forward) -Network.IPMasquerade, config_parse_bool, 0, offsetof(Network, ip_masquerade) -Network.BindCarrier, config_parse_strv, 0, offsetof(Network, bind_carrier) -Address.Address, config_parse_address, 0, 0 -Address.Peer, config_parse_address, 0, 0 -Address.Broadcast, config_parse_broadcast, 0, 0 -Address.Label, config_parse_label, 0, 0 -Route.Gateway, config_parse_gateway, 0, 0 -Route.Destination, config_parse_destination, 0, 0 -Route.Source, config_parse_destination, 0, 0 -Route.Metric, config_parse_route_priority, 0, 0 -Route.Scope, config_parse_route_scope, 0, 0 -DHCP.ClientIdentifier, config_parse_dhcp_client_identifier,0, offsetof(Network, dhcp_client_identifier) -DHCP.UseDNS, config_parse_bool, 0, offsetof(Network, dhcp_dns) -DHCP.UseNTP, config_parse_bool, 0, offsetof(Network, dhcp_ntp) -DHCP.UseMTU, config_parse_bool, 0, offsetof(Network, dhcp_mtu) -DHCP.UseHostname, config_parse_bool, 0, offsetof(Network, dhcp_hostname) -DHCP.UseDomains, config_parse_bool, 0, offsetof(Network, dhcp_domains) -DHCP.UseRoutes, config_parse_bool, 0, offsetof(Network, dhcp_routes) -DHCP.SendHostname, config_parse_bool, 0, offsetof(Network, dhcp_sendhost) -DHCP.RequestBroadcast, config_parse_bool, 0, offsetof(Network, dhcp_broadcast) -DHCP.CriticalConnection, config_parse_bool, 0, offsetof(Network, dhcp_critical) -DHCP.VendorClassIdentifier, config_parse_string, 0, offsetof(Network, dhcp_vendor_class_identifier) -DHCP.RouteMetric, config_parse_unsigned, 0, offsetof(Network, dhcp_route_metric) -Bridge.Cost, config_parse_unsigned, 0, offsetof(Network, cost) -BridgeFDB.MACAddress, config_parse_fdb_hwaddr, 0, 0 -BridgeFDB.VLANId, config_parse_fdb_vlan_id, 0, 0 -/* backwards compatibility: do not add new entries to this section */ -Network.IPv4LL, config_parse_ipv4ll, 0, offsetof(Network, link_local) -DHCPv4.UseDNS, config_parse_bool, 0, offsetof(Network, dhcp_dns) -DHCPv4.UseMTU, config_parse_bool, 0, offsetof(Network, dhcp_mtu) -DHCPv4.UseHostname, config_parse_bool, 0, offsetof(Network, dhcp_hostname) -DHCP.UseDomainName, config_parse_bool, 0, offsetof(Network, dhcp_domains) -DHCPv4.UseDomainName, config_parse_bool, 0, offsetof(Network, dhcp_domains) -DHCPv4.CriticalConnection, config_parse_bool, 0, offsetof(Network, dhcp_critical) diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c deleted file mode 100644 index 78bbf74bff..0000000000 --- a/src/network/networkd-network.c +++ /dev/null @@ -1,715 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2013 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#include <ctype.h> -#include <net/if.h> - -#include "conf-files.h" -#include "conf-parser.h" -#include "util.h" -#include "networkd.h" -#include "networkd-netdev.h" -#include "networkd-link.h" -#include "network-internal.h" - -static int network_load_one(Manager *manager, const char *filename) { - _cleanup_network_free_ Network *network = NULL; - _cleanup_fclose_ FILE *file = NULL; - char *d; - Route *route; - Address *address; - int r; - - assert(manager); - assert(filename); - - file = fopen(filename, "re"); - if (!file) { - if (errno == ENOENT) - return 0; - else - return -errno; - } - - if (null_or_empty_fd(fileno(file))) { - log_debug("Skipping empty file: %s", filename); - return 0; - } - - network = new0(Network, 1); - if (!network) - return log_oom(); - - network->manager = manager; - - LIST_HEAD_INIT(network->static_addresses); - LIST_HEAD_INIT(network->static_routes); - LIST_HEAD_INIT(network->static_fdb_entries); - - network->stacked_netdevs = hashmap_new(&string_hash_ops); - if (!network->stacked_netdevs) - return log_oom(); - - network->addresses_by_section = hashmap_new(NULL); - if (!network->addresses_by_section) - return log_oom(); - - network->routes_by_section = hashmap_new(NULL); - if (!network->routes_by_section) - return log_oom(); - - network->fdb_entries_by_section = hashmap_new(NULL); - if (!network->fdb_entries_by_section) - return log_oom(); - - network->filename = strdup(filename); - if (!network->filename) - return log_oom(); - - network->name = strdup(basename(filename)); - if (!network->name) - return log_oom(); - - d = strrchr(network->name, '.'); - if (!d) - return -EINVAL; - - assert(streq(d, ".network")); - - *d = '\0'; - - network->dhcp = ADDRESS_FAMILY_NO; - network->dhcp_ntp = true; - network->dhcp_dns = true; - network->dhcp_hostname = true; - network->dhcp_routes = true; - network->dhcp_sendhost = true; - network->dhcp_route_metric = DHCP_ROUTE_METRIC; - network->dhcp_client_identifier = DHCP_CLIENT_ID_DUID; - - network->llmnr = LLMNR_SUPPORT_YES; - - network->link_local = ADDRESS_FAMILY_IPV6; - - r = config_parse(NULL, filename, file, - "Match\0" - "Link\0" - "Network\0" - "Address\0" - "Route\0" - "DHCP\0" - "DHCPv4\0" - "Bridge\0" - "BridgeFDB\0", - config_item_perf_lookup, network_network_gperf_lookup, - false, false, true, network); - if (r < 0) - return r; - - /* IPMasquerade=yes implies IPForward=yes */ - if (network->ip_masquerade) - network->ip_forward |= ADDRESS_FAMILY_IPV4; - - LIST_PREPEND(networks, manager->networks, network); - - r = hashmap_ensure_allocated(&manager->networks_by_name, &string_hash_ops); - if (r < 0) - return r; - - r = hashmap_put(manager->networks_by_name, network->name, network); - if (r < 0) - return r; - - LIST_FOREACH(routes, route, network->static_routes) { - if (!route->family) { - log_warning("Route section without Gateway field configured in %s. " - "Ignoring", filename); - return 0; - } - } - - LIST_FOREACH(addresses, address, network->static_addresses) { - if (!address->family) { - log_warning("Address section without Address field configured in %s. " - "Ignoring", filename); - return 0; - } - } - - network = NULL; - - return 0; -} - -int network_load(Manager *manager) { - Network *network; - _cleanup_strv_free_ char **files = NULL; - char **f; - int r; - - assert(manager); - - while ((network = manager->networks)) - network_free(network); - - r = conf_files_list_strv(&files, ".network", NULL, network_dirs); - if (r < 0) - return log_error_errno(r, "Failed to enumerate network files: %m"); - - STRV_FOREACH_BACKWARDS(f, files) { - r = network_load_one(manager, *f); - if (r < 0) - return r; - } - - return 0; -} - -void network_free(Network *network) { - NetDev *netdev; - Route *route; - Address *address; - FdbEntry *fdb_entry; - Iterator i; - - if (!network) - return; - - free(network->filename); - - free(network->match_mac); - strv_free(network->match_path); - strv_free(network->match_driver); - strv_free(network->match_type); - strv_free(network->match_name); - - free(network->description); - free(network->dhcp_vendor_class_identifier); - - free(network->mac); - - strv_free(network->ntp); - strv_free(network->dns); - strv_free(network->domains); - strv_free(network->bind_carrier); - - netdev_unref(network->bridge); - - netdev_unref(network->bond); - - HASHMAP_FOREACH(netdev, network->stacked_netdevs, i) { - hashmap_remove(network->stacked_netdevs, netdev->ifname); - netdev_unref(netdev); - } - hashmap_free(network->stacked_netdevs); - - while ((route = network->static_routes)) - route_free(route); - - while ((address = network->static_addresses)) - address_free(address); - - while ((fdb_entry = network->static_fdb_entries)) - fdb_entry_free(fdb_entry); - - hashmap_free(network->addresses_by_section); - hashmap_free(network->routes_by_section); - hashmap_free(network->fdb_entries_by_section); - - if (network->manager) { - if (network->manager->networks) - LIST_REMOVE(networks, network->manager->networks, network); - - if (network->manager->networks_by_name) - hashmap_remove(network->manager->networks_by_name, network->name); - } - - free(network->name); - - condition_free_list(network->match_host); - condition_free_list(network->match_virt); - condition_free_list(network->match_kernel); - condition_free_list(network->match_arch); - - free(network); -} - -int network_get_by_name(Manager *manager, const char *name, Network **ret) { - Network *network; - - assert(manager); - assert(name); - assert(ret); - - network = hashmap_get(manager->networks_by_name, name); - if (!network) - return -ENOENT; - - *ret = network; - - return 0; -} - -int network_get(Manager *manager, struct udev_device *device, - const char *ifname, const struct ether_addr *address, - Network **ret) { - Network *network; - struct udev_device *parent; - const char *path, *parent_driver, *driver, *devtype; - - assert(manager); - assert(ret); - assert(device); - - path = udev_device_get_property_value(device, "ID_PATH"); - - parent = udev_device_get_parent(device); - if (parent) - parent_driver = udev_device_get_driver(parent); - else - parent_driver = NULL; - - driver = udev_device_get_property_value(device, "ID_NET_DRIVER"); - - devtype = udev_device_get_devtype(device); - - LIST_FOREACH(networks, network, manager->networks) { - if (net_match_config(network->match_mac, network->match_path, - network->match_driver, network->match_type, - network->match_name, network->match_host, - network->match_virt, network->match_kernel, - network->match_arch, - address, path, parent_driver, driver, - devtype, ifname)) { - if (network->match_name) { - const char *attr; - uint8_t name_assign_type = NET_NAME_UNKNOWN; - - attr = udev_device_get_sysattr_value(device, "name_assign_type"); - if (attr) - (void) safe_atou8(attr, &name_assign_type); - - if (name_assign_type == NET_NAME_ENUM) - log_warning("%-*s: found matching network '%s', based on potentially unpredictable ifname", - IFNAMSIZ, ifname, network->filename); - else - log_debug("%-*s: found matching network '%s'", IFNAMSIZ, ifname, network->filename); - } else - log_debug("%-*s: found matching network '%s'", IFNAMSIZ, ifname, network->filename); - - *ret = network; - return 0; - } - } - - *ret = NULL; - - return -ENOENT; -} - -int network_apply(Manager *manager, Network *network, Link *link) { - int r; - - link->network = network; - - if (network->ipv4ll_route) { - Route *route; - - r = route_new_static(network, 0, &route); - if (r < 0) - return r; - - r = inet_pton(AF_INET, "169.254.0.0", &route->dst_addr.in); - if (r == 0) - return -EINVAL; - if (r < 0) - return -errno; - - route->family = AF_INET; - route->dst_prefixlen = 16; - route->scope = RT_SCOPE_LINK; - route->metrics = IPV4LL_ROUTE_METRIC; - route->protocol = RTPROT_STATIC; - } - - if (network->dns || network->ntp) { - r = link_save(link); - if (r < 0) - return r; - } - - return 0; -} - -int config_parse_netdev(const char *unit, - const char *filename, - unsigned line, - const char *section, - unsigned section_line, - const char *lvalue, - int ltype, - const char *rvalue, - void *data, - void *userdata) { - Network *network = userdata; - _cleanup_free_ char *kind_string = NULL; - char *p; - NetDev *netdev; - NetDevKind kind; - int r; - - assert(filename); - assert(lvalue); - assert(rvalue); - assert(data); - - kind_string = strdup(lvalue); - if (!kind_string) - return log_oom(); - - /* the keys are CamelCase versions of the kind */ - for (p = kind_string; *p; p++) - *p = tolower(*p); - - kind = netdev_kind_from_string(kind_string); - if (kind == _NETDEV_KIND_INVALID) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Invalid NetDev kind: %s", lvalue); - return 0; - } - - r = netdev_get(network->manager, rvalue, &netdev); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "%s could not be found, ignoring assignment: %s", lvalue, rvalue); - return 0; - } - - if (netdev->kind != kind) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "NetDev is not a %s, ignoring assignment: %s", lvalue, rvalue); - return 0; - } - - switch (kind) { - case NETDEV_KIND_BRIDGE: - network->bridge = netdev; - - break; - case NETDEV_KIND_BOND: - network->bond = netdev; - - break; - case NETDEV_KIND_VLAN: - case NETDEV_KIND_MACVLAN: - case NETDEV_KIND_IPVLAN: - case NETDEV_KIND_VXLAN: - r = hashmap_put(network->stacked_netdevs, netdev->ifname, netdev); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Can not add VLAN '%s' to network: %s", - rvalue, strerror(-r)); - return 0; - } - - break; - default: - assert_not_reached("Can not parse NetDev"); - } - - netdev_ref(netdev); - - return 0; -} - -int config_parse_domains(const char *unit, - const char *filename, - unsigned line, - const char *section, - unsigned section_line, - const char *lvalue, - int ltype, - const char *rvalue, - void *data, - void *userdata) { - Network *network = userdata; - char ***domains = data; - char **domain; - int r; - - r = config_parse_strv(unit, filename, line, section, section_line, - lvalue, ltype, rvalue, domains, userdata); - if (r < 0) - return r; - - strv_uniq(*domains); - network->wildcard_domain = !!strv_find(*domains, "*"); - - STRV_FOREACH(domain, *domains) { - if (is_localhost(*domain)) - log_syntax(unit, LOG_ERR, filename, line, EINVAL, "'localhost' domain names may not be configured, ignoring assignment: %s", *domain); - else if (!hostname_is_valid(*domain)) { - if (!streq(*domain, "*")) - log_syntax(unit, LOG_ERR, filename, line, EINVAL, "domain name is not valid, ignoring assignment: %s", *domain); - } else - continue; - - strv_remove(*domains, *domain); - - /* We removed one entry, make sure we don't skip the next one */ - domain--; - } - - return 0; -} - -int config_parse_tunnel(const char *unit, - const char *filename, - unsigned line, - const char *section, - unsigned section_line, - const char *lvalue, - int ltype, - const char *rvalue, - void *data, - void *userdata) { - Network *network = userdata; - NetDev *netdev; - int r; - - assert(filename); - assert(lvalue); - assert(rvalue); - assert(data); - - r = netdev_get(network->manager, rvalue, &netdev); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Tunnel is invalid, ignoring assignment: %s", rvalue); - return 0; - } - - if (netdev->kind != NETDEV_KIND_IPIP && - netdev->kind != NETDEV_KIND_SIT && - netdev->kind != NETDEV_KIND_GRE && - netdev->kind != NETDEV_KIND_GRETAP && - netdev->kind != NETDEV_KIND_IP6GRE && - netdev->kind != NETDEV_KIND_IP6GRETAP && - netdev->kind != NETDEV_KIND_VTI && - netdev->kind != NETDEV_KIND_IP6TNL - ) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "NetDev is not a tunnel, ignoring assignment: %s", rvalue); - return 0; - } - - r = hashmap_put(network->stacked_netdevs, netdev->ifname, netdev); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Can not add VLAN '%s' to network: %s", - rvalue, strerror(-r)); - return 0; - } - - netdev_ref(netdev); - - return 0; -} - -int config_parse_ipv4ll( - 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) { - - AddressFamilyBoolean *link_local = data; - - assert(filename); - assert(lvalue); - assert(rvalue); - assert(data); - - /* Note that this is mostly like - * config_parse_address_family_boolean(), except that it - * applies only to IPv4 */ - - if (parse_boolean(rvalue)) - *link_local |= ADDRESS_FAMILY_IPV4; - else - *link_local &= ~ADDRESS_FAMILY_IPV4; - - return 0; -} - -int config_parse_dhcp( - 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) { - - AddressFamilyBoolean *dhcp = data, s; - - assert(filename); - assert(lvalue); - assert(rvalue); - assert(data); - - /* Note that this is mostly like - * config_parse_address_family_boolean(), except that it - * understands some old names for the enum values */ - - s = address_family_boolean_from_string(rvalue); - if (s < 0) { - - /* Previously, we had a slightly different enum here, - * support its values for compatbility. */ - - if (streq(rvalue, "none")) - s = ADDRESS_FAMILY_NO; - else if (streq(rvalue, "v4")) - s = ADDRESS_FAMILY_IPV4; - else if (streq(rvalue, "v6")) - s = ADDRESS_FAMILY_IPV6; - else if (streq(rvalue, "both")) - s = ADDRESS_FAMILY_YES; - else { - log_syntax(unit, LOG_ERR, filename, line, s, "Failed to parse DHCP option, ignoring: %s", rvalue); - return 0; - } - } - - *dhcp = s; - return 0; -} - -static const char* const dhcp_client_identifier_table[_DHCP_CLIENT_ID_MAX] = { - [DHCP_CLIENT_ID_MAC] = "mac", - [DHCP_CLIENT_ID_DUID] = "duid" -}; - -DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(dhcp_client_identifier, DCHPClientIdentifier); -DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_client_identifier, dhcp_client_identifier, DCHPClientIdentifier, "Failed to parse client identifier type"); - -static const char* const llmnr_support_table[_LLMNR_SUPPORT_MAX] = { - [LLMNR_SUPPORT_NO] = "no", - [LLMNR_SUPPORT_YES] = "yes", - [LLMNR_SUPPORT_RESOLVE] = "resolve", -}; - -DEFINE_STRING_TABLE_LOOKUP(llmnr_support, LLMNRSupport); - -int config_parse_llmnr( - 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) { - - LLMNRSupport *llmnr = data; - int k; - - assert(filename); - assert(lvalue); - assert(rvalue); - assert(llmnr); - - /* Our enum shall be a superset of booleans, hence first try - * to parse as boolean, and then as enum */ - - k = parse_boolean(rvalue); - if (k > 0) - *llmnr = LLMNR_SUPPORT_YES; - else if (k == 0) - *llmnr = LLMNR_SUPPORT_NO; - else { - LLMNRSupport s; - - s = llmnr_support_from_string(rvalue); - if (s < 0){ - log_syntax(unit, LOG_ERR, filename, line, -s, "Failed to parse LLMNR option, ignoring: %s", rvalue); - return 0; - } - - *llmnr = s; - } - - return 0; -} - -int config_parse_ipv6token( - 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) { - - union in_addr_union buffer; - struct in6_addr *token = data; - int r; - - assert(filename); - assert(lvalue); - assert(rvalue); - assert(token); - - r = in_addr_from_string(AF_INET6, rvalue, &buffer); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, -r, "Failed to parse IPv6 token, ignoring: %s", rvalue); - return 0; - } - - r = in_addr_is_null(AF_INET6, &buffer); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, -r, "IPv6 token can not be the ANY address, ignoring: %s", rvalue); - return 0; - } - - if ((buffer.in6.s6_addr32[0] | buffer.in6.s6_addr32[1]) != 0) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, "IPv6 token can not be longer than 64 bits, ignoring: %s", rvalue); - return 0; - } - - *token = buffer.in6; - - return 0; -} diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c deleted file mode 100644 index 7f110a5217..0000000000 --- a/src/network/networkd-route.c +++ /dev/null @@ -1,467 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2013 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - - -#include "networkd.h" -#include "networkd-link.h" - -#include "util.h" -#include "conf-parser.h" - -int route_new_static(Network *network, unsigned section, Route **ret) { - _cleanup_route_free_ Route *route = NULL; - - if (section) { - route = hashmap_get(network->routes_by_section, - UINT_TO_PTR(section)); - if (route) { - *ret = route; - route = NULL; - - return 0; - } - } - - route = new0(Route, 1); - if (!route) - return -ENOMEM; - - route->family = AF_UNSPEC; - route->scope = RT_SCOPE_UNIVERSE; - route->protocol = RTPROT_STATIC; - - route->network = network; - - LIST_PREPEND(routes, network->static_routes, route); - - if (section) { - route->section = section; - hashmap_put(network->routes_by_section, - UINT_TO_PTR(route->section), route); - } - - *ret = route; - route = NULL; - - return 0; -} - -int route_new_dynamic(Route **ret, unsigned char rtm_protocol) { - _cleanup_route_free_ Route *route = NULL; - - route = new0(Route, 1); - if (!route) - return -ENOMEM; - - route->family = AF_UNSPEC; - route->scope = RT_SCOPE_UNIVERSE; - route->protocol = rtm_protocol; - - *ret = route; - route = NULL; - - return 0; -} - -void route_free(Route *route) { - if (!route) - return; - - if (route->network) { - LIST_REMOVE(routes, route->network->static_routes, route); - - if (route->section) - hashmap_remove(route->network->routes_by_section, - UINT_TO_PTR(route->section)); - } - - free(route); -} - -int route_drop(Route *route, Link *link, - sd_rtnl_message_handler_t callback) { - _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL; - int r; - - assert(link); - assert(link->manager); - assert(link->manager->rtnl); - assert(link->ifindex > 0); - assert(route->family == AF_INET || route->family == AF_INET6); - - r = sd_rtnl_message_new_route(link->manager->rtnl, &req, - RTM_DELROUTE, route->family, - route->protocol); - if (r < 0) - return log_error_errno(r, "Could not create RTM_DELROUTE message: %m"); - - if (!in_addr_is_null(route->family, &route->in_addr)) { - if (route->family == AF_INET) - r = sd_rtnl_message_append_in_addr(req, RTA_GATEWAY, &route->in_addr.in); - else if (route->family == AF_INET6) - r = sd_rtnl_message_append_in6_addr(req, RTA_GATEWAY, &route->in_addr.in6); - if (r < 0) - return log_error_errno(r, "Could not append RTA_GATEWAY attribute: %m"); - } - - if (route->dst_prefixlen) { - if (route->family == AF_INET) - r = sd_rtnl_message_append_in_addr(req, RTA_DST, &route->dst_addr.in); - else if (route->family == AF_INET6) - r = sd_rtnl_message_append_in6_addr(req, RTA_DST, &route->dst_addr.in6); - if (r < 0) - return log_error_errno(r, "Could not append RTA_DST attribute: %m"); - - r = sd_rtnl_message_route_set_dst_prefixlen(req, route->dst_prefixlen); - if (r < 0) - return log_error_errno(r, "Could not set destination prefix length: %m"); - } - - if (route->src_prefixlen) { - if (route->family == AF_INET) - r = sd_rtnl_message_append_in_addr(req, RTA_SRC, &route->src_addr.in); - else if (route->family == AF_INET6) - r = sd_rtnl_message_append_in6_addr(req, RTA_SRC, &route->src_addr.in6); - if (r < 0) - return log_error_errno(r, "Could not append RTA_DST attribute: %m"); - - r = sd_rtnl_message_route_set_src_prefixlen(req, route->src_prefixlen); - if (r < 0) - return log_error_errno(r, "Could not set source prefix length: %m"); - } - - if (!in_addr_is_null(route->family, &route->prefsrc_addr)) { - if (route->family == AF_INET) - r = sd_rtnl_message_append_in_addr(req, RTA_PREFSRC, &route->prefsrc_addr.in); - else if (route->family == AF_INET6) - r = sd_rtnl_message_append_in6_addr(req, RTA_PREFSRC, &route->prefsrc_addr.in6); - if (r < 0) - return log_error_errno(r, "Could not append RTA_PREFSRC attribute: %m"); - } - - r = sd_rtnl_message_route_set_scope(req, route->scope); - if (r < 0) - return log_error_errno(r, "Could not set scope: %m"); - - r = sd_rtnl_message_append_u32(req, RTA_PRIORITY, route->metrics); - if (r < 0) - return log_error_errno(r, "Could not append RTA_PRIORITY attribute: %m"); - - r = sd_rtnl_message_append_u32(req, RTA_OIF, link->ifindex); - if (r < 0) - return log_error_errno(r, "Could not append RTA_OIF attribute: %m"); - - r = sd_rtnl_call_async(link->manager->rtnl, req, callback, link, 0, NULL); - if (r < 0) - return log_error_errno(r, "Could not send rtnetlink message: %m"); - - link_ref(link); - - return 0; -} - -int route_configure(Route *route, Link *link, - sd_rtnl_message_handler_t callback) { - _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL; - int r; - - assert(link); - assert(link->manager); - assert(link->manager->rtnl); - assert(link->ifindex > 0); - assert(route->family == AF_INET || route->family == AF_INET6); - - r = sd_rtnl_message_new_route(link->manager->rtnl, &req, - RTM_NEWROUTE, route->family, - route->protocol); - if (r < 0) - return log_error_errno(r, "Could not create RTM_NEWROUTE message: %m"); - - if (!in_addr_is_null(route->family, &route->in_addr)) { - if (route->family == AF_INET) - r = sd_rtnl_message_append_in_addr(req, RTA_GATEWAY, &route->in_addr.in); - else if (route->family == AF_INET6) - r = sd_rtnl_message_append_in6_addr(req, RTA_GATEWAY, &route->in_addr.in6); - if (r < 0) - return log_error_errno(r, "Could not append RTA_GATEWAY attribute: %m"); - } - - if (route->dst_prefixlen) { - if (route->family == AF_INET) - r = sd_rtnl_message_append_in_addr(req, RTA_DST, &route->dst_addr.in); - else if (route->family == AF_INET6) - r = sd_rtnl_message_append_in6_addr(req, RTA_DST, &route->dst_addr.in6); - if (r < 0) - return log_error_errno(r, "Could not append RTA_DST attribute: %m"); - - r = sd_rtnl_message_route_set_dst_prefixlen(req, route->dst_prefixlen); - if (r < 0) - return log_error_errno(r, "Could not set destination prefix length: %m"); - } - - if (route->src_prefixlen) { - if (route->family == AF_INET) - r = sd_rtnl_message_append_in_addr(req, RTA_SRC, &route->src_addr.in); - else if (route->family == AF_INET6) - r = sd_rtnl_message_append_in6_addr(req, RTA_SRC, &route->src_addr.in6); - if (r < 0) - return log_error_errno(r, "Could not append RTA_SRC attribute: %m"); - - r = sd_rtnl_message_route_set_src_prefixlen(req, route->src_prefixlen); - if (r < 0) - return log_error_errno(r, "Could not set source prefix length: %m"); - } - - if (!in_addr_is_null(route->family, &route->prefsrc_addr)) { - if (route->family == AF_INET) - r = sd_rtnl_message_append_in_addr(req, RTA_PREFSRC, &route->prefsrc_addr.in); - else if (route->family == AF_INET6) - r = sd_rtnl_message_append_in6_addr(req, RTA_PREFSRC, &route->prefsrc_addr.in6); - if (r < 0) - return log_error_errno(r, "Could not append RTA_PREFSRC attribute: %m"); - } - - r = sd_rtnl_message_route_set_scope(req, route->scope); - if (r < 0) - return log_error_errno(r, "Could not set scope: %m"); - - r = sd_rtnl_message_append_u32(req, RTA_PRIORITY, route->metrics); - if (r < 0) - return log_error_errno(r, "Could not append RTA_PRIORITY attribute: %m"); - - r = sd_rtnl_message_append_u32(req, RTA_OIF, link->ifindex); - if (r < 0) - return log_error_errno(r, "Could not append RTA_OIF attribute: %m"); - - r = sd_rtnl_call_async(link->manager->rtnl, req, callback, link, 0, NULL); - if (r < 0) - return log_error_errno(r, "Could not send rtnetlink message: %m"); - - link_ref(link); - - return 0; -} - -int config_parse_gateway(const char *unit, - const char *filename, - unsigned line, - const char *section, - unsigned section_line, - const char *lvalue, - int ltype, - const char *rvalue, - void *data, - void *userdata) { - - Network *network = userdata; - _cleanup_route_free_ Route *n = NULL; - union in_addr_union buffer; - int r, f; - - assert(filename); - assert(section); - assert(lvalue); - assert(rvalue); - assert(data); - - if (streq(section, "Network")) { - /* we are not in an Route section, so treat - * this as the special '0' section */ - section_line = 0; - } - - r = route_new_static(network, section_line, &n); - if (r < 0) - return r; - - r = in_addr_from_string_auto(rvalue, &f, &buffer); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Route is invalid, ignoring assignment: %s", rvalue); - return 0; - } - - n->family = f; - n->in_addr = buffer; - n = NULL; - - return 0; -} - -int config_parse_destination(const char *unit, - const char *filename, - unsigned line, - const char *section, - unsigned section_line, - const char *lvalue, - int ltype, - const char *rvalue, - void *data, - void *userdata) { - - Network *network = userdata; - _cleanup_route_free_ Route *n = NULL; - const char *address, *e; - union in_addr_union buffer; - unsigned char prefixlen; - int r, f; - - assert(filename); - assert(section); - assert(lvalue); - assert(rvalue); - assert(data); - - r = route_new_static(network, section_line, &n); - if (r < 0) - return r; - - /* Destination|Source=address/prefixlen */ - - /* address */ - e = strchr(rvalue, '/'); - if (e) - address = strndupa(rvalue, e - rvalue); - else - address = rvalue; - - r = in_addr_from_string_auto(address, &f, &buffer); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Destination is invalid, ignoring assignment: %s", address); - return 0; - } - - if (f != AF_INET && f != AF_INET6) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Unknown address family, ignoring assignment: %s", address); - return 0; - } - - /* prefixlen */ - if (e) { - r = safe_atou8(e + 1, &prefixlen); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Route destination prefix length is invalid, ignoring assignment: %s", e + 1); - return 0; - } - } else { - switch (f) { - case AF_INET: - prefixlen = 32; - break; - case AF_INET6: - prefixlen = 128; - break; - } - } - - n->family = f; - if (streq(lvalue, "Destination")) { - n->dst_addr = buffer; - n->dst_prefixlen = prefixlen; - } else if (streq(lvalue, "Source")) { - n->src_addr = buffer; - n->src_prefixlen = prefixlen; - } else - assert_not_reached(lvalue); - - n = NULL; - - return 0; -} - -int config_parse_route_priority(const char *unit, - const char *filename, - unsigned line, - const char *section, - unsigned section_line, - const char *lvalue, - int ltype, - const char *rvalue, - void *data, - void *userdata) { - Network *network = userdata; - _cleanup_route_free_ Route *n = NULL; - int r; - - assert(filename); - assert(section); - assert(lvalue); - assert(rvalue); - assert(data); - - r = route_new_static(network, section_line, &n); - if (r < 0) - return r; - - r = config_parse_unsigned(unit, filename, line, section, - section_line, lvalue, ltype, - rvalue, &n->metrics, userdata); - if (r < 0) - return r; - - n = NULL; - - return 0; -} - -int config_parse_route_scope(const char *unit, - const char *filename, - unsigned line, - const char *section, - unsigned section_line, - const char *lvalue, - int ltype, - const char *rvalue, - void *data, - void *userdata) { - Network *network = userdata; - _cleanup_route_free_ Route *n = NULL; - int r; - - assert(filename); - assert(section); - assert(lvalue); - assert(rvalue); - assert(data); - - r = route_new_static(network, section_line, &n); - if (r < 0) - return r; - - if (streq(rvalue, "host")) - n->scope = RT_SCOPE_HOST; - else if (streq(rvalue, "link")) - n->scope = RT_SCOPE_LINK; - else if (streq(rvalue, "global")) - n->scope = RT_SCOPE_UNIVERSE; - else { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Unknown route scope: %s", rvalue); - return 0; - } - - n = NULL; - - return 0; -} diff --git a/src/network/networkd-wait-online-link.c b/src/network/networkd-wait-online-link.c deleted file mode 100644 index 341bcae3fb..0000000000 --- a/src/network/networkd-wait-online-link.c +++ /dev/null @@ -1,134 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2014 Lennart Poettering - Copyright 2014 Tom Gundersen - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - - -#include "sd-network.h" - -#include "networkd-wait-online-link.h" - -int link_new(Manager *m, Link **ret, int ifindex, const char *ifname) { - _cleanup_(link_freep) Link *l = NULL; - int r; - - assert(m); - assert(ifindex > 0); - - r = hashmap_ensure_allocated(&m->links, NULL); - if (r < 0) - return r; - - r = hashmap_ensure_allocated(&m->links_by_name, &string_hash_ops); - if (r < 0) - return r; - - l = new0(Link, 1); - if (!l) - return -ENOMEM; - - l->manager = m; - - l->ifname = strdup(ifname); - if (!l->ifname) - return -ENOMEM; - - r = hashmap_put(m->links_by_name, l->ifname, l); - if (r < 0) - return r; - - l->ifindex = ifindex; - - r = hashmap_put(m->links, INT_TO_PTR(ifindex), l); - if (r < 0) - return r; - - if (ret) - *ret = l; - l = NULL; - - return 0; -} - -Link *link_free(Link *l) { - - if (!l) - return NULL; - - if (l->manager) { - hashmap_remove(l->manager->links, INT_TO_PTR(l->ifindex)); - hashmap_remove(l->manager->links_by_name, l->ifname); - } - - free(l->ifname); - free(l); - return NULL; - } - -int link_update_rtnl(Link *l, sd_rtnl_message *m) { - const char *ifname; - int r; - - assert(l); - assert(l->manager); - assert(m); - - r = sd_rtnl_message_link_get_flags(m, &l->flags); - if (r < 0) - return r; - - r = sd_rtnl_message_read_string(m, IFLA_IFNAME, &ifname); - if (r < 0) - return r; - - if (!streq(l->ifname, ifname)) { - char *new_ifname; - - new_ifname = strdup(ifname); - if (!new_ifname) - return -ENOMEM; - - hashmap_remove(l->manager->links_by_name, l->ifname); - free(l->ifname); - l->ifname = new_ifname; - - r = hashmap_put(l->manager->links_by_name, l->ifname, l); - if (r < 0) - return r; - } - - return 0; -} - -int link_update_monitor(Link *l) { - assert(l); - - free(l->operational_state); - l->operational_state = NULL; - - sd_network_link_get_operational_state(l->ifindex, &l->operational_state); - - free(l->state); - l->state = NULL; - - sd_network_link_get_setup_state(l->ifindex, &l->state); - - return 0; -} diff --git a/src/network/networkd-wait-online-link.h b/src/network/networkd-wait-online-link.h deleted file mode 100644 index 90ea6b3405..0000000000 --- a/src/network/networkd-wait-online-link.h +++ /dev/null @@ -1,46 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -#pragma once - -/*** - This file is part of systemd. - - Copyright 2014 Lennart Poettering - Copyright 2014 Tom Gundersen - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -typedef struct Link Link; - -#include "networkd-wait-online.h" - -struct Link { - Manager *manager; - - int ifindex; - char *ifname; - unsigned flags; - - char *operational_state; - char *state; -}; - -int link_new(Manager *m, Link **ret, int ifindex, const char *ifname); -Link *link_free(Link *l); -int link_update_rtnl(Link *l, sd_rtnl_message *m); -int link_update_monitor(Link *l); -bool link_relevant(Link *l); - -DEFINE_TRIVIAL_CLEANUP_FUNC(Link*, link_free); diff --git a/src/network/networkd-wait-online-manager.c b/src/network/networkd-wait-online-manager.c deleted file mode 100644 index 1c997a50a4..0000000000 --- a/src/network/networkd-wait-online-manager.c +++ /dev/null @@ -1,332 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2013 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#include <netinet/ether.h> -#include <linux/if.h> -#include <fnmatch.h> - -#include "rtnl-util.h" - -#include "network-internal.h" -#include "networkd-wait-online-link.h" -#include "networkd-wait-online.h" - -#include "util.h" -#include "time-util.h" - -bool manager_ignore_link(Manager *m, Link *link) { - char **ignore; - - assert(m); - assert(link); - - if (link->flags & IFF_LOOPBACK) - return true; - - STRV_FOREACH(ignore, m->ignore) - if (fnmatch(*ignore, link->ifname, 0) == 0) - return true; - - return false; -} - -bool manager_all_configured(Manager *m) { - Iterator i; - Link *l; - char **ifname; - bool one_ready = false; - - /* wait for all the links given on the command line to appear */ - STRV_FOREACH(ifname, m->interfaces) { - l = hashmap_get(m->links_by_name, *ifname); - if (!l) { - log_debug("still waiting for %s", *ifname); - return false; - } - } - - /* wait for all links networkd manages to be in admin state 'configured' - and at least one link to gain a carrier */ - HASHMAP_FOREACH(l, m->links, i) { - if (manager_ignore_link(m, l)) { - log_info("ignoring: %s", l->ifname); - continue; - } - - if (!l->state) { - log_debug("link %s has not yet been processed by udev", - l->ifname); - return false; - } - - if (streq(l->state, "configuring")) { - log_debug("link %s is being processed by networkd", - l->ifname); - return false; - } - - if (l->operational_state && - STR_IN_SET(l->operational_state, "degraded", "routable")) - /* we wait for at least one link to be ready, - regardless of who manages it */ - one_ready = true; - } - - return one_ready; -} - -static int manager_process_link(sd_rtnl *rtnl, sd_rtnl_message *mm, void *userdata) { - Manager *m = userdata; - uint16_t type; - Link *l; - const char *ifname; - int ifindex, r; - - assert(rtnl); - assert(m); - assert(mm); - - r = sd_rtnl_message_get_type(mm, &type); - if (r < 0) - goto fail; - - r = sd_rtnl_message_link_get_ifindex(mm, &ifindex); - if (r < 0) - goto fail; - - r = sd_rtnl_message_read_string(mm, IFLA_IFNAME, &ifname); - if (r < 0) - goto fail; - - l = hashmap_get(m->links, INT_TO_PTR(ifindex)); - - switch (type) { - - case RTM_NEWLINK: - if (!l) { - log_debug("Found link %i", ifindex); - - r = link_new(m, &l, ifindex, ifname); - if (r < 0) - goto fail; - - r = link_update_monitor(l); - if (r < 0) - goto fail; - } - - r = link_update_rtnl(l, mm); - if (r < 0) - goto fail; - - break; - - case RTM_DELLINK: - if (l) { - log_debug("Removing link %i", l->ifindex); - link_free(l); - } - - break; - } - - return 0; - -fail: - log_warning_errno(r, "Failed to process RTNL link message: %m"); - return 0; -} - -static int on_rtnl_event(sd_rtnl *rtnl, sd_rtnl_message *mm, void *userdata) { - Manager *m = userdata; - int r; - - r = manager_process_link(rtnl, mm, m); - if (r < 0) - return r; - - if (manager_all_configured(m)) - sd_event_exit(m->event, 0); - - return 1; -} - -static int manager_rtnl_listen(Manager *m) { - _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL; - sd_rtnl_message *i; - int r; - - assert(m); - - /* First, subscribe to interfaces coming and going */ - r = sd_rtnl_open(&m->rtnl, 3, RTNLGRP_LINK, RTNLGRP_IPV4_IFADDR, RTNLGRP_IPV6_IFADDR); - if (r < 0) - return r; - - r = sd_rtnl_attach_event(m->rtnl, m->event, 0); - if (r < 0) - return r; - - r = sd_rtnl_add_match(m->rtnl, RTM_NEWLINK, on_rtnl_event, m); - if (r < 0) - return r; - - r = sd_rtnl_add_match(m->rtnl, RTM_DELLINK, on_rtnl_event, m); - if (r < 0) - return r; - - /* Then, enumerate all links */ - r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0); - if (r < 0) - return r; - - r = sd_rtnl_message_request_dump(req, true); - if (r < 0) - return r; - - r = sd_rtnl_call(m->rtnl, req, 0, &reply); - if (r < 0) - return r; - - for (i = reply; i; i = sd_rtnl_message_next(i)) { - r = manager_process_link(m->rtnl, i, m); - if (r < 0) - return r; - } - - return r; -} - -static int on_network_event(sd_event_source *s, int fd, uint32_t revents, void *userdata) { - Manager *m = userdata; - Iterator i; - Link *l; - int r; - - assert(m); - - sd_network_monitor_flush(m->network_monitor); - - HASHMAP_FOREACH(l, m->links, i) { - r = link_update_monitor(l); - if (r < 0) - log_warning_errno(r, "Failed to update monitor information for %i: %m", l->ifindex); - } - - if (manager_all_configured(m)) - sd_event_exit(m->event, 0); - - return 0; -} - -static int manager_network_monitor_listen(Manager *m) { - int r, fd, events; - - assert(m); - - r = sd_network_monitor_new(&m->network_monitor, NULL); - if (r < 0) - return r; - - fd = sd_network_monitor_get_fd(m->network_monitor); - if (fd < 0) - return fd; - - events = sd_network_monitor_get_events(m->network_monitor); - if (events < 0) - return events; - - r = sd_event_add_io(m->event, &m->network_monitor_event_source, - fd, events, &on_network_event, m); - if (r < 0) - return r; - - return 0; -} - -int manager_new(Manager **ret, char **interfaces, char **ignore, usec_t timeout) { - _cleanup_(manager_freep) Manager *m = NULL; - int r; - - assert(ret); - - m = new0(Manager, 1); - if (!m) - return -ENOMEM; - - m->interfaces = interfaces; - m->ignore = ignore; - - r = sd_event_default(&m->event); - if (r < 0) - return r; - - sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL); - sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL); - - if (timeout > 0) { - usec_t usec; - - usec = now(clock_boottime_or_monotonic()) + timeout; - - r = sd_event_add_time(m->event, NULL, clock_boottime_or_monotonic(), usec, 0, NULL, INT_TO_PTR(-ETIMEDOUT)); - if (r < 0) - return r; - } - - sd_event_set_watchdog(m->event, true); - - r = manager_network_monitor_listen(m); - if (r < 0) - return r; - - r = manager_rtnl_listen(m); - if (r < 0) - return r; - - *ret = m; - m = NULL; - - return 0; -} - -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(m->links_by_name); - - sd_event_source_unref(m->network_monitor_event_source); - sd_network_monitor_unref(m->network_monitor); - - sd_event_source_unref(m->rtnl_event_source); - sd_rtnl_unref(m->rtnl); - - sd_event_unref(m->event); - free(m); - - return; -} diff --git a/src/network/networkd-wait-online.c b/src/network/networkd-wait-online.c deleted file mode 100644 index f0ca6def87..0000000000 --- a/src/network/networkd-wait-online.c +++ /dev/null @@ -1,169 +0,0 @@ - -/*** - This file is part of systemd. - - Copyright 2013 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#include <getopt.h> - -#include "sd-daemon.h" - -#include "networkd-wait-online.h" - -#include "strv.h" -#include "build.h" - -static bool arg_quiet = false; -static usec_t arg_timeout = 120 * USEC_PER_SEC; -static char **arg_interfaces = NULL; -static char **arg_ignore = NULL; - -static void help(void) { - printf("%s [OPTIONS...]\n\n" - "Block until network is configured.\n\n" - " -h --help Show this help\n" - " --version Print version string\n" - " -q --quiet Do not show status information\n" - " -i --interface=INTERFACE Block until at least these interfaces have appeared\n" - " --ignore=INTERFACE Don't take these interfaces into account\n" - " --timeout=SECS Maximum time to wait for network connectivity\n" - , program_invocation_short_name); -} - -static int parse_argv(int argc, char *argv[]) { - - enum { - ARG_VERSION = 0x100, - ARG_IGNORE, - ARG_TIMEOUT, - }; - - static const struct option options[] = { - { "help", no_argument, NULL, 'h' }, - { "version", no_argument, NULL, ARG_VERSION }, - { "quiet", no_argument, NULL, 'q' }, - { "interface", required_argument, NULL, 'i' }, - { "ignore", required_argument, NULL, ARG_IGNORE }, - { "timeout", required_argument, NULL, ARG_TIMEOUT }, - {} - }; - - int c, r; - - assert(argc >= 0); - assert(argv); - - while ((c = getopt_long(argc, argv, "+hiq", options, NULL)) >= 0) - - switch (c) { - - case 'h': - help(); - return 0; - - case 'q': - arg_quiet = true; - break; - - case ARG_VERSION: - puts(PACKAGE_STRING); - puts(SYSTEMD_FEATURES); - return 0; - - case 'i': - if (strv_extend(&arg_interfaces, optarg) < 0) - return log_oom(); - - break; - - case ARG_IGNORE: - if (strv_extend(&arg_ignore, optarg) < 0) - return log_oom(); - - break; - - case ARG_TIMEOUT: - r = parse_sec(optarg, &arg_timeout); - if (r < 0) - return r; - - break; - - case '?': - return -EINVAL; - - default: - assert_not_reached("Unhandled option"); - } - - return 1; -} - -int main(int argc, char *argv[]) { - _cleanup_(manager_freep) Manager *m = NULL; - int r; - - log_set_target(LOG_TARGET_AUTO); - log_parse_environment(); - log_open(); - - umask(0022); - - r = parse_argv(argc, argv); - if (r <= 0) - return r; - - if (arg_quiet) - log_set_max_level(LOG_WARNING); - - assert_se(sigprocmask_many(SIG_BLOCK, SIGTERM, SIGINT, -1) == 0); - - r = manager_new(&m, arg_interfaces, arg_ignore, arg_timeout); - if (r < 0) { - log_error_errno(r, "Could not create manager: %m"); - goto finish; - } - - if (manager_all_configured(m)) { - r = 0; - goto finish; - } - - sd_notify(false, - "READY=1\n" - "STATUS=Waiting for network connections..."); - - r = sd_event_loop(m->event); - if (r < 0) { - log_error_errno(r, "Event loop failed: %m"); - goto finish; - } - -finish: - strv_free(arg_interfaces); - strv_free(arg_ignore); - - if (r >= 0) { - sd_notify(false, "STATUS=All interfaces configured..."); - - return EXIT_SUCCESS; - } else { - sd_notify(false, "STATUS=Failed waiting for network connectivity..."); - - return EXIT_FAILURE; - } -} diff --git a/src/network/networkd-wait-online.h b/src/network/networkd-wait-online.h deleted file mode 100644 index 73d129699d..0000000000 --- a/src/network/networkd-wait-online.h +++ /dev/null @@ -1,56 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2014 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#pragma once - -#include "sd-event.h" -#include "sd-rtnl.h" -#include "sd-network.h" - -#include "hashmap.h" - -typedef struct Manager Manager; - -#include "networkd-wait-online-link.h" - -struct Manager { - Hashmap *links; - Hashmap *links_by_name; - - char **interfaces; - char **ignore; - - sd_rtnl *rtnl; - sd_event_source *rtnl_event_source; - - sd_network_monitor *network_monitor; - sd_event_source *network_monitor_event_source; - - sd_event *event; -}; - -void manager_free(Manager *m); -int manager_new(Manager **ret, char **interfaces, char **ignore, usec_t timeout); - -DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free); - -bool manager_all_configured(Manager *m); -bool manager_ignore_link(Manager *m, Link *link); diff --git a/src/network/networkd.c b/src/network/networkd.c deleted file mode 100644 index 543a4e4d95..0000000000 --- a/src/network/networkd.c +++ /dev/null @@ -1,128 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2013 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#include "capability.h" -#include "sd-daemon.h" - -#include "networkd.h" - -int main(int argc, char *argv[]) { - _cleanup_manager_free_ Manager *m = NULL; - const char *user = "systemd-network"; - uid_t uid; - gid_t gid; - int r; - - log_set_target(LOG_TARGET_AUTO); - log_parse_environment(); - log_open(); - - umask(0022); - - if (argc != 1) { - log_error("This program takes no arguments."); - r = -EINVAL; - goto out; - } - - r = get_user_creds(&user, &uid, &gid, NULL, NULL); - if (r < 0) { - log_error_errno(r, "Cannot resolve user name %s: %m", user); - goto out; - } - - /* Always create the directories people can create inotify - * watches in. */ - r = mkdir_safe_label("/run/systemd/netif", 0755, uid, gid); - if (r < 0) - log_warning_errno(r, "Could not create runtime directory: %m"); - - r = mkdir_safe_label("/run/systemd/netif/links", 0755, uid, gid); - if (r < 0) - log_warning_errno(r, "Could not create runtime directory 'links': %m"); - - r = mkdir_safe_label("/run/systemd/netif/leases", 0755, uid, gid); - if (r < 0) - log_warning_errno(r, "Could not create runtime directory 'leases': %m"); - - r = mkdir_safe_label("/run/systemd/netif/lldp", 0755, uid, gid); - if (r < 0) - log_warning_errno(r, "Could not create runtime directory 'lldp': %m"); - - r = drop_privileges(uid, gid, - (1ULL << CAP_NET_ADMIN) | - (1ULL << CAP_NET_BIND_SERVICE) | - (1ULL << CAP_NET_BROADCAST) | - (1ULL << CAP_NET_RAW)); - if (r < 0) - goto out; - - assert_se(sigprocmask_many(SIG_BLOCK, SIGTERM, SIGINT, -1) == 0); - - r = manager_new(&m); - if (r < 0) { - log_error_errno(r, "Could not create manager: %m"); - goto out; - } - - r = manager_connect_bus(m); - if (r < 0) { - log_error_errno(r, "Could not connect to bus: %m"); - goto out; - } - - r = manager_load_config(m); - if (r < 0) { - log_error_errno(r, "Could not load configuration files: %m"); - goto out; - } - - r = manager_rtnl_enumerate_links(m); - if (r < 0) { - log_error_errno(r, "Could not enumerate links: %m"); - goto out; - } - - r = manager_rtnl_enumerate_addresses(m); - if (r < 0) { - log_error_errno(r, "Could not enumerate links: %m"); - goto out; - } - - log_info("Enumeration completed"); - - sd_notify(false, - "READY=1\n" - "STATUS=Processing requests..."); - - r = manager_run(m); - if (r < 0) { - log_error_errno(r, "Event loop failed: %m"); - goto out; - } - -out: - sd_notify(false, - "STOPPING=1\n" - "STATUS=Shutting down..."); - - return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; -} diff --git a/src/network/networkd.h b/src/network/networkd.h deleted file mode 100644 index c26d64e383..0000000000 --- a/src/network/networkd.h +++ /dev/null @@ -1,454 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2013 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#pragma once - -#include <arpa/inet.h> - -#include "sd-event.h" -#include "sd-rtnl.h" -#include "sd-bus.h" -#include "sd-dhcp-client.h" -#include "sd-dhcp-server.h" -#include "sd-ipv4ll.h" -#include "sd-icmp6-nd.h" -#include "sd-dhcp6-client.h" -#include "udev.h" -#include "sd-lldp.h" - -#include "rtnl-util.h" -#include "hashmap.h" -#include "list.h" -#include "set.h" -#include "condition.h" -#include "in-addr-util.h" - -#define CACHE_INFO_INFINITY_LIFE_TIME 0xFFFFFFFFU -#define DHCP_ROUTE_METRIC 1024 -#define IPV4LL_ROUTE_METRIC 2048 - -typedef struct NetDev NetDev; -typedef struct Network Network; -typedef struct Link Link; -typedef struct Address Address; -typedef struct Route Route; -typedef struct Manager Manager; -typedef struct AddressPool AddressPool; -typedef struct FdbEntry FdbEntry; - -typedef enum AddressFamilyBoolean { - /* This is a bitmask, though it usually doesn't feel that way! */ - ADDRESS_FAMILY_NO = 0, - ADDRESS_FAMILY_IPV4 = 1, - ADDRESS_FAMILY_IPV6 = 2, - ADDRESS_FAMILY_YES = 3, - _ADDRESS_FAMILY_BOOLEAN_MAX, - _ADDRESS_FAMILY_BOOLEAN_INVALID = -1, -} AddressFamilyBoolean; - -typedef enum LLMNRSupport { - LLMNR_SUPPORT_NO, - LLMNR_SUPPORT_YES, - LLMNR_SUPPORT_RESOLVE, - _LLMNR_SUPPORT_MAX, - _LLMNR_SUPPORT_INVALID = -1, -} LLMNRSupport; - -typedef enum LinkOperationalState { - LINK_OPERSTATE_OFF, - LINK_OPERSTATE_NO_CARRIER, - LINK_OPERSTATE_DORMANT, - LINK_OPERSTATE_CARRIER, - LINK_OPERSTATE_DEGRADED, - LINK_OPERSTATE_ROUTABLE, - _LINK_OPERSTATE_MAX, - _LINK_OPERSTATE_INVALID = -1 -} LinkOperationalState; - -typedef enum DCHPClientIdentifier { - DHCP_CLIENT_ID_MAC, - DHCP_CLIENT_ID_DUID, - _DHCP_CLIENT_ID_MAX, - _DHCP_CLIENT_ID_INVALID = -1, -} DCHPClientIdentifier; - -struct FdbEntry { - Network *network; - unsigned section; - - struct ether_addr *mac_addr; - uint16_t vlan_id; - - LIST_FIELDS(FdbEntry, static_fdb_entries); -}; - -struct Network { - Manager *manager; - - char *filename; - char *name; - - struct ether_addr *match_mac; - char **match_path; - char **match_driver; - char **match_type; - char **match_name; - - Condition *match_host; - Condition *match_virt; - Condition *match_kernel; - Condition *match_arch; - - char *description; - NetDev *bridge; - NetDev *bond; - Hashmap *stacked_netdevs; - AddressFamilyBoolean dhcp; - DCHPClientIdentifier dhcp_client_identifier; - char *dhcp_vendor_class_identifier; - bool dhcp_dns; - bool dhcp_ntp; - bool dhcp_mtu; - bool dhcp_hostname; - bool dhcp_domains; - bool dhcp_sendhost; - bool dhcp_broadcast; - bool dhcp_critical; - bool dhcp_routes; - unsigned dhcp_route_metric; - AddressFamilyBoolean link_local; - bool ipv4ll_route; - union in_addr_union ipv6_token; - - bool dhcp_server; - - unsigned cost; - - AddressFamilyBoolean ip_forward; - bool ip_masquerade; - - struct ether_addr *mac; - unsigned mtu; - - bool lldp; - - LIST_HEAD(Address, static_addresses); - LIST_HEAD(Route, static_routes); - LIST_HEAD(FdbEntry, static_fdb_entries); - - Hashmap *addresses_by_section; - Hashmap *routes_by_section; - Hashmap *fdb_entries_by_section; - - bool wildcard_domain; - char **domains, **dns, **ntp, **bind_carrier; - - LLMNRSupport llmnr; - - LIST_FIELDS(Network, networks); -}; - -struct Address { - Network *network; - unsigned section; - - int family; - unsigned char prefixlen; - unsigned char scope; - uint32_t flags; - char *label; - - struct in_addr broadcast; - struct ifa_cacheinfo cinfo; - - union in_addr_union in_addr; - union in_addr_union in_addr_peer; - - bool ip_masquerade_done; - - LIST_FIELDS(Address, addresses); -}; - -struct Route { - Network *network; - unsigned section; - - int family; - unsigned char dst_prefixlen; - unsigned char src_prefixlen; - unsigned char scope; - uint32_t metrics; - unsigned char protocol; /* RTPROT_* */ - - union in_addr_union in_addr; - union in_addr_union dst_addr; - union in_addr_union src_addr; - union in_addr_union prefsrc_addr; - - LIST_FIELDS(Route, routes); -}; - -struct AddressPool { - Manager *manager; - - int family; - unsigned prefixlen; - - union in_addr_union in_addr; - - LIST_FIELDS(AddressPool, address_pools); -}; - -struct Manager { - sd_rtnl *rtnl; - sd_event *event; - sd_event_source *bus_retry_event_source; - sd_bus *bus; - sd_bus_slot *prepare_for_sleep_slot; - struct udev *udev; - struct udev_monitor *udev_monitor; - sd_event_source *udev_event_source; - - bool enumerating; - - char *state_file; - LinkOperationalState operational_state; - - Hashmap *links; - Hashmap *netdevs; - Hashmap *networks_by_name; - LIST_HEAD(Network, networks); - LIST_HEAD(AddressPool, address_pools); - - usec_t network_dirs_ts_usec; -}; - -extern const char* const network_dirs[]; - -/* Manager */ - -extern const sd_bus_vtable manager_vtable[]; - -int manager_new(Manager **ret); -void manager_free(Manager *m); - -int manager_connect_bus(Manager *m); -int manager_run(Manager *m); - -int manager_load_config(Manager *m); -bool manager_should_reload(Manager *m); - -int manager_rtnl_enumerate_links(Manager *m); -int manager_rtnl_enumerate_addresses(Manager *m); - -int manager_send_changed(Manager *m, const char *property, ...) _sentinel_; -int manager_save(Manager *m); - -int manager_address_pool_acquire(Manager *m, int family, unsigned prefixlen, union in_addr_union *found); - -DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free); -#define _cleanup_manager_free_ _cleanup_(manager_freep) - -/* Network */ - -int network_load(Manager *manager); - -void network_free(Network *network); - -DEFINE_TRIVIAL_CLEANUP_FUNC(Network*, network_free); -#define _cleanup_network_free_ _cleanup_(network_freep) - -int network_get_by_name(Manager *manager, const char *name, Network **ret); -int network_get(Manager *manager, struct udev_device *device, - const char *ifname, const struct ether_addr *mac, - Network **ret); -int network_apply(Manager *manager, Network *network, Link *link); - -int config_parse_netdev(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_domains(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(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_vxlan_group_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); - -extern const sd_bus_vtable network_vtable[]; - -int network_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error); -int network_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error); - -/* gperf */ -const struct ConfigPerfItem* network_network_gperf_lookup(const char *key, unsigned length); - -/* Route */ -int route_new_static(Network *network, unsigned section, Route **ret); -int route_new_dynamic(Route **ret, unsigned char rtm_protocol); -void route_free(Route *route); -int route_configure(Route *route, Link *link, sd_rtnl_message_handler_t callback); -int route_drop(Route *route, Link *link, sd_rtnl_message_handler_t callback); - - -DEFINE_TRIVIAL_CLEANUP_FUNC(Route*, route_free); -#define _cleanup_route_free_ _cleanup_(route_freep) - -int config_parse_gateway(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_destination(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_route_priority(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_route_scope(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); -/* Address */ -int address_new_static(Network *network, unsigned section, Address **ret); -int address_new_dynamic(Address **ret); -void address_free(Address *address); -int address_configure(Address *address, Link *link, sd_rtnl_message_handler_t callback); -int address_update(Address *address, Link *link, sd_rtnl_message_handler_t callback); -int address_drop(Address *address, Link *link, sd_rtnl_message_handler_t callback); -int address_establish(Address *address, Link *link); -int address_release(Address *address, Link *link); -bool address_equal(Address *a1, Address *a2); - -DEFINE_TRIVIAL_CLEANUP_FUNC(Address*, address_free); -#define _cleanup_address_free_ _cleanup_(address_freep) - -int config_parse_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_broadcast(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_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); - -/* Forwarding database table. */ -int fdb_entry_configure(Link *const link, FdbEntry *const fdb_entry); -void fdb_entry_free(FdbEntry *fdb_entry); -int fdb_entry_new_static(Network *const network, const unsigned section, FdbEntry **ret); - -DEFINE_TRIVIAL_CLEANUP_FUNC(FdbEntry*, fdb_entry_free); -#define _cleanup_fdbentry_free_ _cleanup_(fdb_entry_freep) - -int config_parse_fdb_hwaddr(const char *unit, const char *filename, unsigned line, - const char *section, unsigned section_line, const char *lvalue, - int ltype, const char *rvalue, void *data, void *userdata); - -int config_parse_fdb_vlan_id(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); - -/* DHCP support */ - -int config_parse_dhcp(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_dhcp_client_identifier(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); - -/* IPv4LL support (legacy) */ - -int config_parse_ipv4ll(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); - -/* IPv6 support */ -int config_parse_ipv6token(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); - -/* LLMNR support */ - -const char* llmnr_support_to_string(LLMNRSupport i) _const_; -LLMNRSupport llmnr_support_from_string(const char *s) _pure_; - -int config_parse_llmnr(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); - -/* Address Pool */ - -int address_pool_new(Manager *m, AddressPool **ret, int family, const union in_addr_union *u, unsigned prefixlen); -int address_pool_new_from_string(Manager *m, AddressPool **ret, int family, const char *p, unsigned prefixlen); -void address_pool_free(AddressPool *p); - -int address_pool_acquire(AddressPool *p, unsigned prefixlen, union in_addr_union *found); - -const char *address_family_boolean_to_string(AddressFamilyBoolean b) _const_; -AddressFamilyBoolean address_family_boolean_from_string(const char *s) _const_; - -int config_parse_address_family_boolean(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); - -/* Opeartional State */ - -const char* link_operstate_to_string(LinkOperationalState s) _const_; -LinkOperationalState link_operstate_from_string(const char *s) _pure_; diff --git a/src/network/org.freedesktop.network1.conf b/src/network/org.freedesktop.network1.conf deleted file mode 100644 index 52dad33668..0000000000 --- a/src/network/org.freedesktop.network1.conf +++ /dev/null @@ -1,42 +0,0 @@ -<?xml version="1.0"?> <!--*-nxml-*--> -<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" - "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> - -<!-- - This file is part of systemd. - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. ---> - -<busconfig> - - <policy user="systemd-network"> - <allow own="org.freedesktop.network1"/> - <allow send_destination="org.freedesktop.network1"/> - <allow receive_sender="org.freedesktop.network1"/> - </policy> - - <policy context="default"> - <deny send_destination="org.freedesktop.network1"/> - - <allow send_destination="org.freedesktop.network1" - send_interface="org.freedesktop.DBus.Introspectable"/> - - <allow send_destination="org.freedesktop.network1" - send_interface="org.freedesktop.DBus.Peer"/> - - <allow send_destination="org.freedesktop.network1" - send_interface="org.freedesktop.DBus.Properties" - send_member="Get"/> - - <allow send_destination="org.freedesktop.network1" - send_interface="org.freedesktop.DBus.Properties" - send_member="GetAll"/> - - <allow receive_sender="org.freedesktop.network1"/> - </policy> - -</busconfig> diff --git a/src/network/org.freedesktop.network1.service b/src/network/org.freedesktop.network1.service deleted file mode 100644 index bea885fe53..0000000000 --- a/src/network/org.freedesktop.network1.service +++ /dev/null @@ -1,12 +0,0 @@ -# This file is part of systemd. -# -# systemd is free software; you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation; either version 2.1 of the License, or -# (at your option) any later version. - -[D-BUS Service] -Name=org.freedesktop.network1 -Exec=/bin/false -User=root -SystemdService=dbus-org.freedesktop.network1.service diff --git a/src/network/test-network-tables.c b/src/network/test-network-tables.c deleted file mode 100644 index 67fcca2ac0..0000000000 --- a/src/network/test-network-tables.c +++ /dev/null @@ -1,27 +0,0 @@ -#include "networkd.h" -#include "networkd-netdev-bond.h" -#include "networkd-netdev-macvlan.h" -#include "dhcp6-internal.h" -#include "dhcp6-protocol.h" -#include "rtnl-internal.h" -#include "ethtool-util.h" - -#include "test-tables.h" - -int main(int argc, char **argv) { - test_table(bond_mode, NETDEV_BOND_MODE); - /* test_table(link_state, LINK_STATE); -- not a reversible mapping */ - test_table(link_operstate, LINK_OPERSTATE); - test_table(address_family_boolean, ADDRESS_FAMILY_BOOLEAN); - test_table(netdev_kind, NETDEV_KIND); - test_table(dhcp6_message_status, DHCP6_STATUS); - test_table(duplex, DUP); - test_table(wol, WOL); - test_table(nl_union_link_info_data, NL_UNION_LINK_INFO_DATA); - - test_table_sparse(macvlan_mode, NETDEV_MACVLAN_MODE); - test_table_sparse(ipvlan_mode, NETDEV_IPVLAN_MODE); - test_table_sparse(dhcp6_message_type, DHCP6_MESSAGE); - - return EXIT_SUCCESS; -} diff --git a/src/network/test-network.c b/src/network/test-network.c deleted file mode 100644 index 5909cc790e..0000000000 --- a/src/network/test-network.c +++ /dev/null @@ -1,216 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2013 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#include "networkd.h" -#include "network-internal.h" -#include "dhcp-lease-internal.h" - -static void test_deserialize_in_addr(void) { - _cleanup_free_ struct in_addr *addresses = NULL; - _cleanup_free_ struct in6_addr *addresses6 = NULL; - struct in_addr a, b, c; - struct in6_addr d, e, f; - int size; - const char *addresses_string = "192.168.0.1 0:0:0:0:0:FFFF:204.152.189.116 192.168.0.2 ::1 192.168.0.3 1:0:0:0:0:0:0:8"; - - assert_se(inet_pton(AF_INET, "0:0:0:0:0:FFFF:204.152.189.116", &a) == 0); - assert_se(inet_pton(AF_INET6, "192.168.0.1", &d) == 0); - - assert_se(inet_pton(AF_INET, "192.168.0.1", &a) == 1); - assert_se(inet_pton(AF_INET, "192.168.0.2", &b) == 1); - assert_se(inet_pton(AF_INET, "192.168.0.3", &c) == 1); - assert_se(inet_pton(AF_INET6, "0:0:0:0:0:FFFF:204.152.189.116", &d) == 1); - assert_se(inet_pton(AF_INET6, "::1", &e) == 1); - assert_se(inet_pton(AF_INET6, "1:0:0:0:0:0:0:8", &f) == 1); - - assert_se((size = deserialize_in_addrs(&addresses, addresses_string)) >= 0); - assert_se(size == 3); - assert_se(!memcmp(&a, &addresses[0], sizeof(struct in_addr))); - assert_se(!memcmp(&b, &addresses[1], sizeof(struct in_addr))); - assert_se(!memcmp(&c, &addresses[2], sizeof(struct in_addr))); - - assert_se((size = deserialize_in6_addrs(&addresses6, addresses_string)) >= 0); - assert_se(size == 3); - assert_se(!memcmp(&d, &addresses6[0], sizeof(struct in6_addr))); - assert_se(!memcmp(&e, &addresses6[1], sizeof(struct in6_addr))); - assert_se(!memcmp(&f, &addresses6[2], sizeof(struct in6_addr))); -} - -static void test_deserialize_dhcp_routes(void) { - size_t size, allocated; - - { - _cleanup_free_ struct sd_dhcp_route *routes = NULL; - assert_se(deserialize_dhcp_routes(&routes, &size, &allocated, "") >= 0); - assert_se(size == 0); - } - - { - /* no errors */ - _cleanup_free_ struct sd_dhcp_route *routes = NULL; - const char *routes_string = "192.168.0.0/16,192.168.0.1 10.1.2.0/24,10.1.2.1 0.0.0.0/0,10.0.1.1"; - - assert_se(deserialize_dhcp_routes(&routes, &size, &allocated, routes_string) >= 0); - - assert_se(size == 3); - assert_se(routes[0].dst_addr.s_addr == inet_addr("192.168.0.0")); - assert_se(routes[0].gw_addr.s_addr == inet_addr("192.168.0.1")); - assert_se(routes[0].dst_prefixlen == 16); - - assert_se(routes[1].dst_addr.s_addr == inet_addr("10.1.2.0")); - assert_se(routes[1].gw_addr.s_addr == inet_addr("10.1.2.1")); - assert_se(routes[1].dst_prefixlen == 24); - - assert_se(routes[2].dst_addr.s_addr == inet_addr("0.0.0.0")); - assert_se(routes[2].gw_addr.s_addr == inet_addr("10.0.1.1")); - assert_se(routes[2].dst_prefixlen == 0); - } - - { - /* error in second word */ - _cleanup_free_ struct sd_dhcp_route *routes = NULL; - const char *routes_string = "192.168.0.0/16,192.168.0.1 10.1.2.0#24,10.1.2.1 0.0.0.0/0,10.0.1.1"; - - assert_se(deserialize_dhcp_routes(&routes, &size, &allocated, routes_string) >= 0); - - assert_se(size == 2); - assert_se(routes[0].dst_addr.s_addr == inet_addr("192.168.0.0")); - assert_se(routes[0].gw_addr.s_addr == inet_addr("192.168.0.1")); - assert_se(routes[0].dst_prefixlen == 16); - - assert_se(routes[1].dst_addr.s_addr == inet_addr("0.0.0.0")); - assert_se(routes[1].gw_addr.s_addr == inet_addr("10.0.1.1")); - assert_se(routes[1].dst_prefixlen == 0); - } - - { - /* error in every word */ - _cleanup_free_ struct sd_dhcp_route *routes = NULL; - const char *routes_string = "192.168.0.0/55,192.168.0.1 10.1.2.0#24,10.1.2.1 0.0.0.0/0,10.0.1.X"; - - assert_se(deserialize_dhcp_routes(&routes, &size, &allocated, routes_string) >= 0); - assert_se(size == 0); - } -} - -static int test_load_config(Manager *manager) { - int r; -/* TODO: should_reload, is false if the config dirs do not exist, so - * so we can't do this test here, move it to a test for paths_check_timestamps - * directly - * - * assert_se(network_should_reload(manager) == true); -*/ - - r = manager_load_config(manager); - if (r == -EPERM) - return r; - assert_se(r >= 0); - - assert_se(manager_should_reload(manager) == false); - - return 0; -} - -static void test_network_get(Manager *manager, struct udev_device *loopback) { - Network *network; - const struct ether_addr mac = {}; - - /* let's assume that the test machine does not have a .network file - that applies to the loopback device... */ - assert_se(network_get(manager, loopback, "lo", &mac, &network) == -ENOENT); - assert_se(!network); -} - -static void test_address_equality(void) { - _cleanup_address_free_ Address *a1 = NULL, *a2 = NULL; - - assert_se(address_new_dynamic(&a1) >= 0); - assert_se(address_new_dynamic(&a2) >= 0); - - assert_se(address_equal(NULL, NULL)); - assert_se(!address_equal(a1, NULL)); - assert_se(!address_equal(NULL, a2)); - assert_se(address_equal(a1, a2)); - - a1->family = AF_INET; - assert_se(!address_equal(a1, a2)); - - a2->family = AF_INET; - assert_se(address_equal(a1, a2)); - - assert_se(inet_pton(AF_INET, "192.168.3.9", &a1->in_addr.in)); - assert_se(address_equal(a1, a2)); - assert_se(inet_pton(AF_INET, "192.168.3.9", &a2->in_addr.in)); - assert_se(address_equal(a1, a2)); - a1->prefixlen = 10; - assert_se(!address_equal(a1, a2)); - a2->prefixlen = 10; - assert_se(address_equal(a1, a2)); - - assert_se(inet_pton(AF_INET, "192.168.3.10", &a2->in_addr.in)); - assert_se(address_equal(a1, a2)); - - a1->family = AF_INET6; - assert_se(!address_equal(a1, a2)); - - a2->family = AF_INET6; - assert_se(inet_pton(AF_INET6, "2001:4ca0:4f01::2", &a1->in_addr.in6)); - assert_se(inet_pton(AF_INET6, "2001:4ca0:4f01::2", &a2->in_addr.in6)); - assert_se(address_equal(a1, a2)); - - a2->prefixlen = 8; - assert_se(address_equal(a1, a2)); - - assert_se(inet_pton(AF_INET6, "2001:4ca0:4f01::1", &a2->in_addr.in6)); - assert_se(!address_equal(a1, a2)); -} - -int main(void) { - _cleanup_manager_free_ Manager *manager = NULL; - struct udev *udev; - struct udev_device *loopback; - int r; - - test_deserialize_in_addr(); - test_deserialize_dhcp_routes(); - test_address_equality(); - - assert_se(manager_new(&manager) >= 0); - - r = test_load_config(manager); - if (r == -EPERM) - return EXIT_TEST_SKIP; - - udev = udev_new(); - assert_se(udev); - - loopback = udev_device_new_from_syspath(udev, "/sys/class/net/lo"); - assert_se(loopback); - assert_se(udev_device_get_ifindex(loopback) == 1); - - test_network_get(manager, loopback); - - assert_se(manager_rtnl_enumerate_links(manager) >= 0); - - udev_device_unref(loopback); - udev_unref(udev); -} |