summaryrefslogtreecommitdiff
path: root/src/network/networkd-route.c
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2018-06-22 13:38:31 +0200
committerMichael Biebl <biebl@debian.org>2018-06-22 13:38:31 +0200
commitb012e92123bdc9fa10c2f079ec5bd9313b23e21a (patch)
tree94b74f04796e0da187092db7c2487aaf30f0faf1 /src/network/networkd-route.c
parent98393f852f2f66a74f7370aa63c07b26d610343c (diff)
downloadsystemd-b012e92123bdc9fa10c2f079ec5bd9313b23e21a.tar.gz
New upstream version 239
Diffstat (limited to 'src/network/networkd-route.c')
-rw-r--r--src/network/networkd-route.c386
1 files changed, 204 insertions, 182 deletions
diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c
index 70dca5219b..b335fdb1bb 100644
--- a/src/network/networkd-route.c
+++ b/src/network/networkd-route.c
@@ -1,22 +1,4 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
-/***
- 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 <linux/icmpv6.h>
@@ -62,7 +44,7 @@ static unsigned routes_max(void) {
}
int route_new(Route **ret) {
- _cleanup_route_free_ Route *route = NULL;
+ _cleanup_(route_freep) Route *route = NULL;
route = new0(Route, 1);
if (!route)
@@ -76,15 +58,14 @@ int route_new(Route **ret) {
route->lifetime = USEC_INFINITY;
route->quickack = -1;
- *ret = route;
- route = NULL;
+ *ret = TAKE_PTR(route);
return 0;
}
int route_new_static(Network *network, const char *filename, unsigned section_line, Route **ret) {
- _cleanup_network_config_section_free_ NetworkConfigSection *n = NULL;
- _cleanup_route_free_ Route *route = NULL;
+ _cleanup_(network_config_section_freep) NetworkConfigSection *n = NULL;
+ _cleanup_(route_freep) Route *route = NULL;
int r;
assert(network);
@@ -98,8 +79,7 @@ int route_new_static(Network *network, const char *filename, unsigned section_li
route = hashmap_get(network->routes_by_section, n);
if (route) {
- *ret = route;
- route = NULL;
+ *ret = TAKE_PTR(route);
return 0;
}
@@ -115,8 +95,7 @@ int route_new_static(Network *network, const char *filename, unsigned section_li
route->protocol = RTPROT_STATIC;
if (filename) {
- route->section = n;
- n = NULL;
+ route->section = TAKE_PTR(n);
r = hashmap_put(network->routes_by_section, route->section, route);
if (r < 0)
@@ -127,8 +106,7 @@ int route_new_static(Network *network, const char *filename, unsigned section_li
LIST_PREPEND(routes, network->static_routes, route);
network->n_static_routes++;
- *ret = route;
- route = NULL;
+ *ret = TAKE_PTR(route);
return 0;
}
@@ -278,7 +256,7 @@ static int route_add_internal(
uint32_t table,
Route **ret) {
- _cleanup_route_free_ Route *route = NULL;
+ _cleanup_(route_freep) Route *route = NULL;
int r;
assert(link);
@@ -327,8 +305,7 @@ int route_add_foreign(
return route_add_internal(link, &link->routes_foreign, family, dst, dst_prefixlen, tos, priority, table, ret);
}
-int route_add(
- Link *link,
+int route_add(Link *link,
int family,
const union in_addr_union *dst,
unsigned char dst_prefixlen,
@@ -370,30 +347,29 @@ int route_add(
}
void route_update(Route *route,
- const union in_addr_union *src,
- unsigned char src_prefixlen,
- const union in_addr_union *gw,
- const union in_addr_union *prefsrc,
- unsigned char scope,
- unsigned char protocol,
- unsigned char type) {
+ const union in_addr_union *src,
+ unsigned char src_prefixlen,
+ const union in_addr_union *gw,
+ const union in_addr_union *prefsrc,
+ unsigned char scope,
+ unsigned char protocol,
+ unsigned char type) {
assert(route);
- assert(src);
- assert(gw);
- assert(prefsrc);
+ assert(src || src_prefixlen == 0);
- route->src = *src;
+ route->src = src ? *src : (union in_addr_union) {};
route->src_prefixlen = src_prefixlen;
- route->gw = *gw;
- route->prefsrc = *prefsrc;
+ route->gw = gw ? *gw : (union in_addr_union) {};
+ route->prefsrc = prefsrc ? *prefsrc : (union in_addr_union) {};
route->scope = scope;
route->protocol = protocol;
route->type = type;
}
int route_remove(Route *route, Link *link,
- sd_netlink_message_handler_t callback) {
+ sd_netlink_message_handler_t callback) {
+
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
int r;
@@ -617,6 +593,13 @@ int route_configure(
if (r < 0)
return log_error_errno(r, "Could not append RTA_PREF attribute: %m");
+ if (route->lifetime != USEC_INFINITY && kernel_route_expiration_supported()) {
+ r = sd_netlink_message_append_u32(req, RTA_EXPIRES,
+ DIV_ROUND_UP(usec_sub_unsigned(route->lifetime, now(clock_boottime_or_monotonic())), USEC_PER_SEC));
+ if (r < 0)
+ return log_error_errno(r, "Could not append RTA_EXPIRES attribute: %m");
+ }
+
r = sd_rtnl_message_route_set_type(req, route->type);
if (r < 0)
return log_error_errno(r, "Could not set route type: %m");
@@ -674,7 +657,7 @@ int route_configure(
/* TODO: drop expiration handling once it can be pushed into the kernel */
route->lifetime = lifetime;
- if (route->lifetime != USEC_INFINITY) {
+ if (route->lifetime != USEC_INFINITY && !kernel_route_expiration_supported()) {
r = sd_event_add_time(link->manager->event, &expire, clock_boottime_or_monotonic(),
route->lifetime, 0, route_expire_handler, route);
if (r < 0)
@@ -682,13 +665,13 @@ int route_configure(
}
sd_event_source_unref(route->expire);
- route->expire = expire;
- expire = NULL;
+ route->expire = TAKE_PTR(expire);
return 0;
}
-int config_parse_gateway(const char *unit,
+int config_parse_gateway(
+ const char *unit,
const char *filename,
unsigned line,
const char *section,
@@ -700,7 +683,7 @@ int config_parse_gateway(const char *unit,
void *userdata) {
Network *network = userdata;
- _cleanup_route_free_ Route *n = NULL;
+ _cleanup_(route_freep) Route *n = NULL;
union in_addr_union buffer;
int r, f;
@@ -728,12 +711,13 @@ int config_parse_gateway(const char *unit,
n->family = f;
n->gw = buffer;
- n = NULL;
+ TAKE_PTR(n);
return 0;
}
-int config_parse_preferred_src(const char *unit,
+int config_parse_preferred_src(
+ const char *unit,
const char *filename,
unsigned line,
const char *section,
@@ -745,7 +729,7 @@ int config_parse_preferred_src(const char *unit,
void *userdata) {
Network *network = userdata;
- _cleanup_route_free_ Route *n = NULL;
+ _cleanup_(route_freep) Route *n = NULL;
union in_addr_union buffer;
int r, f;
@@ -768,12 +752,13 @@ int config_parse_preferred_src(const char *unit,
n->family = f;
n->prefsrc = buffer;
- n = NULL;
+ TAKE_PTR(n);
return 0;
}
-int config_parse_destination(const char *unit,
+int config_parse_destination(
+ const char *unit,
const char *filename,
unsigned line,
const char *section,
@@ -785,7 +770,7 @@ int config_parse_destination(const char *unit,
void *userdata) {
Network *network = userdata;
- _cleanup_route_free_ Route *n = NULL;
+ _cleanup_(route_freep) Route *n = NULL;
union in_addr_union buffer;
unsigned char prefixlen;
int r;
@@ -823,24 +808,24 @@ int config_parse_destination(const char *unit,
} else
assert_not_reached(lvalue);
- n = NULL;
-
+ TAKE_PTR(n);
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) {
+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;
- uint32_t k;
+ _cleanup_(route_freep) Route *n = NULL;
int r;
assert(filename);
@@ -853,31 +838,31 @@ int config_parse_route_priority(const char *unit,
if (r < 0)
return r;
- r = safe_atou32(rvalue, &k);
+ r = safe_atou32(rvalue, &n->priority);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Could not parse route priority \"%s\", ignoring assignment: %m", rvalue);
return 0;
}
- n->priority = k;
- n = NULL;
-
+ TAKE_PTR(n);
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) {
+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;
+ _cleanup_(route_freep) Route *n = NULL;
int r;
assert(filename);
@@ -901,24 +886,24 @@ int config_parse_route_scope(const char *unit,
return 0;
}
- n = NULL;
-
+ TAKE_PTR(n);
return 0;
}
-int config_parse_route_table(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) {
- _cleanup_route_free_ Route *n = NULL;
+int config_parse_route_table(
+ 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) {
+
+ _cleanup_(route_freep) Route *n = NULL;
Network *network = userdata;
- uint32_t k;
int r;
assert(filename);
@@ -931,32 +916,31 @@ int config_parse_route_table(const char *unit,
if (r < 0)
return r;
- r = safe_atou32(rvalue, &k);
+ r = safe_atou32(rvalue, &n->table);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Could not parse route table number \"%s\", ignoring assignment: %m", rvalue);
return 0;
}
- n->table = k;
-
- n = NULL;
-
+ TAKE_PTR(n);
return 0;
}
-int config_parse_gateway_onlink(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_gateway_onlink(
+ 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;
+ _cleanup_(route_freep) Route *n = NULL;
int r;
assert(filename);
@@ -977,23 +961,24 @@ int config_parse_gateway_onlink(const char *unit,
}
SET_FLAG(n->flags, RTNH_F_ONLINK, r);
- n = NULL;
-
+ TAKE_PTR(n);
return 0;
}
-int config_parse_ipv6_route_preference(const char *unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
+int config_parse_ipv6_route_preference(
+ 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;
+ _cleanup_(route_freep) Route *n = NULL;
int r;
r = route_new_static(network, filename, section_line, &n);
@@ -1011,23 +996,24 @@ int config_parse_ipv6_route_preference(const char *unit,
return 0;
}
- n = NULL;
-
+ TAKE_PTR(n);
return 0;
}
-int config_parse_route_protocol(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_protocol(
+ 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;
+ _cleanup_(route_freep) Route *n = NULL;
int r;
r = route_new_static(network, filename, section_line, &n);
@@ -1048,23 +1034,24 @@ int config_parse_route_protocol(const char *unit,
}
}
- n = NULL;
-
+ TAKE_PTR(n);
return 0;
}
-int config_parse_route_type(const char *unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
+int config_parse_route_type(
+ const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+
Network *network = userdata;
- _cleanup_route_free_ Route *n = NULL;
+ _cleanup_(route_freep) Route *n = NULL;
int r;
r = route_new_static(network, filename, section_line, &n);
@@ -1084,22 +1071,23 @@ int config_parse_route_type(const char *unit,
return 0;
}
- n = NULL;
-
+ TAKE_PTR(n);
return 0;
}
-int config_parse_tcp_window(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) {
- _cleanup_route_free_ Route *n = NULL;
+int config_parse_tcp_window(
+ 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) {
+
+ _cleanup_(route_freep) Route *n = NULL;
Network *network = userdata;
uint64_t k;
int r;
@@ -1130,22 +1118,23 @@ int config_parse_tcp_window(const char *unit,
return 0;
}
- n = NULL;
-
+ TAKE_PTR(n);
return 0;
}
-int config_parse_quickack(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) {
- _cleanup_route_free_ Route *n = NULL;
+int config_parse_quickack(
+ 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) {
+
+ _cleanup_(route_freep) Route *n = NULL;
Network *network = userdata;
int k, r;
@@ -1166,7 +1155,40 @@ int config_parse_quickack(const char *unit,
}
n->quickack = !!k;
- n = NULL;
+ TAKE_PTR(n);
+ return 0;
+}
+
+int config_parse_route_mtu(
+ 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_freep) Route *n = NULL;
+ int r;
+
+ assert(filename);
+ assert(section);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ r = route_new_static(network, filename, section_line, &n);
+ if (r < 0)
+ return r;
+
+ r = config_parse_mtu(unit, filename, line, section, section_line, lvalue, ltype, rvalue, &n->mtu, userdata);
+ if (r < 0)
+ return r;
+ TAKE_PTR(n);
return 0;
}