]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/network/networkd-network.c
networkd: Introduce l2tp tunnel
[thirdparty/systemd.git] / src / network / networkd-network.c
index 341b6335d6c098a5875f05b71db5405396ca2b40..33055d9e3d8a6f509a9f59e7b5c8be04d5de4518 100644 (file)
@@ -70,14 +70,15 @@ static int network_resolve_netdev_one(Network *network, const char *name, NetDev
         NetDev *netdev;
         int r;
 
+        /* For test-networkd-conf, the check must be earlier than the assertions. */
+        if (!name)
+                return 0;
+
         assert(network);
         assert(network->manager);
         assert(network->filename);
         assert(ret_netdev);
 
-        if (!name)
-                return 0;
-
         if (kind == _NETDEV_KIND_TUNNEL)
                 kind_string = "tunnel";
         else {
@@ -159,9 +160,14 @@ static uint32_t network_get_stacked_netdevs_mtu(Network *network) {
         return mtu;
 }
 
-static int network_verify(Network *network) {
+int network_verify(Network *network) {
         Address *address, *address_next;
         Route *route, *route_next;
+        FdbEntry *fdb, *fdb_next;
+        Neighbor *neighbor, *neighbor_next;
+        AddressLabel *label, *label_next;
+        Prefix *prefix, *prefix_next;
+        RoutingPolicyRule *rule, *rule_next;
         uint32_t mtu;
 
         assert(network);
@@ -249,34 +255,32 @@ static int network_verify(Network *network) {
         }
 
         LIST_FOREACH_SAFE(addresses, address, address_next, network->static_addresses)
-                if (address->family == AF_UNSPEC) {
-                        log_warning("%s: Address section without Address= field configured. "
-                                    "Ignoring [Address] section from line %u.",
-                                    network->filename, address->section->line);
-
+                if (address_section_verify(address) < 0)
                         address_free(address);
-                }
-
-        LIST_FOREACH_SAFE(routes, route, route_next, network->static_routes) {
-                if (route->family == AF_UNSPEC) {
-                        log_warning("%s: Route section without Gateway=, Destination=, Source=, "
-                                    "or PreferredSource= field configured. "
-                                    "Ignoring [Route] section from line %u.",
-                                    network->filename, route->section->line);
 
+        LIST_FOREACH_SAFE(routes, route, route_next, network->static_routes)
+                if (route_section_verify(route, network) < 0)
                         route_free(route);
-                        continue;
-                }
 
-                if (network->n_static_addresses == 0 &&
-                    in_addr_is_null(route->family, &route->gw) == 0 &&
-                    route->gateway_onlink < 0) {
-                        log_warning("%s: Gateway= without static address configured. "
-                                    "Enabling GatewayOnLink= option.",
-                                    network->filename);
-                        route->gateway_onlink = true;
-                }
-        }
+        LIST_FOREACH_SAFE(static_fdb_entries, fdb, fdb_next, network->static_fdb_entries)
+                if (section_is_invalid(fdb->section))
+                        fdb_entry_free(fdb);
+
+        LIST_FOREACH_SAFE(neighbors, neighbor, neighbor_next, network->neighbors)
+                if (section_is_invalid(neighbor->section))
+                        neighbor_free(neighbor);
+
+        LIST_FOREACH_SAFE(labels, label, label_next, network->address_labels)
+                if (section_is_invalid(label->section))
+                        address_label_free(label);
+
+        LIST_FOREACH_SAFE(prefixes, prefix, prefix_next, network->static_prefixes)
+                if (section_is_invalid(prefix->section))
+                        prefix_free(prefix);
+
+        LIST_FOREACH_SAFE(rules, rule, rule_next, network->rules)
+                if (section_is_invalid(rule->section))
+                        routing_policy_rule_free(rule);
 
         return 0;
 }
@@ -330,6 +334,7 @@ int network_load_one(Manager *manager, const char *filename) {
                 .name = TAKE_PTR(name),
 
                 .required_for_online = true,
+                .required_operstate_for_online = LINK_OPERSTATE_DEGRADED,
                 .dhcp = ADDRESS_FAMILY_NO,
                 .dhcp_use_ntp = true,
                 .dhcp_use_dns = true,
@@ -363,7 +368,10 @@ int network_load_one(Manager *manager, const char *filename) {
                 .fast_leave = -1,
                 .allow_port_to_be_root = -1,
                 .unicast_flood = -1,
+                .multicast_flood = -1,
                 .multicast_to_unicast = -1,
+                .neighbor_suppression = -1,
+                .learning = -1,
                 .priority = LINK_BRIDGE_PORT_PRIORITY_INVALID,
 
                 .lldp_mode = LLDP_MODE_ROUTERS_ONLY,
@@ -423,6 +431,10 @@ int network_load_one(Manager *manager, const char *filename) {
 
         network_apply_anonymize_if_set(network);
 
+        r = network_add_ipv4ll_route(network);
+        if (r < 0)
+                log_warning_errno(r, "%s: Failed to add IPv4LL route, ignoring: %m", network->filename);
+
         LIST_PREPEND(networks, manager->networks, network);
         network->manager = manager;
 
@@ -637,33 +649,11 @@ int network_get(Manager *manager, sd_device *device,
 }
 
 int network_apply(Network *network, Link *link) {
-        int r;
-
         assert(network);
         assert(link);
 
         link->network = network;
 
-        if (network->ipv4ll_route) {
-                Route *route;
-
-                r = route_new_static(network, NULL, 0, &route);
-                if (r < 0)
-                        return r;
-
-                r = inet_pton(AF_INET, "169.254.0.0", &route->dst.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->priority = IPV4LL_ROUTE_METRIC;
-                route->protocol = RTPROT_STATIC;
-        }
-
         if (network->n_dns > 0 ||
             !strv_isempty(network->ntp) ||
             !ordered_set_isempty(network->search_domains) ||
@@ -707,7 +697,8 @@ int config_parse_stacked_netdev(const char *unit,
         assert(data);
         assert(IN_SET(kind,
                       NETDEV_KIND_VLAN, NETDEV_KIND_MACVLAN, NETDEV_KIND_MACVTAP,
-                      NETDEV_KIND_IPVLAN, NETDEV_KIND_VXLAN, _NETDEV_KIND_TUNNEL));
+                      NETDEV_KIND_IPVLAN, NETDEV_KIND_VXLAN, NETDEV_KIND_L2TP,
+                      _NETDEV_KIND_TUNNEL));
 
         if (!ifname_valid(rvalue)) {
                 log_syntax(unit, LOG_ERR, filename, line, 0,
@@ -1618,3 +1609,46 @@ int config_parse_iaid(const char *unit,
 
         return 0;
 }
+
+int config_parse_required_for_online(
+                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 = data;
+        LinkOperationalState s;
+        bool required = true;
+        int r;
+
+        if (isempty(rvalue)) {
+                network->required_for_online = true;
+                network->required_operstate_for_online = LINK_OPERSTATE_DEGRADED;
+                return 0;
+        }
+
+        s = link_operstate_from_string(rvalue);
+        if (s < 0) {
+                r = parse_boolean(rvalue);
+                if (r < 0) {
+                        log_syntax(unit, LOG_ERR, filename, line, r,
+                                   "Failed to parse %s= setting, ignoring assignment: %s",
+                                   lvalue, rvalue);
+                        return 0;
+                }
+
+                required = r;
+                s = LINK_OPERSTATE_DEGRADED;
+        }
+
+        network->required_for_online = required;
+        network->required_operstate_for_online = s;
+
+        return 0;
+}