mirror of
https://github.com/systemd/systemd
synced 2024-10-06 16:21:34 +00:00
networkd: route - track routes
This commit is contained in:
parent
cab974b035
commit
1c8e710c2b
|
@ -85,6 +85,8 @@ struct Link {
|
||||||
|
|
||||||
Set *addresses;
|
Set *addresses;
|
||||||
Set *addresses_foreign;
|
Set *addresses_foreign;
|
||||||
|
Set *routes;
|
||||||
|
Set *routes_foreign;
|
||||||
|
|
||||||
sd_dhcp_client *dhcp_client;
|
sd_dhcp_client *dhcp_client;
|
||||||
sd_dhcp_lease *dhcp_lease;
|
sd_dhcp_lease *dhcp_lease;
|
||||||
|
|
|
@ -279,6 +279,196 @@ static int manager_connect_udev(Manager *m) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int manager_rtnl_process_route(sd_netlink *rtnl, sd_netlink_message *message, void *userdata) {
|
||||||
|
Manager *m = userdata;
|
||||||
|
Link *link = NULL;
|
||||||
|
uint16_t type;
|
||||||
|
uint32_t ifindex, priority = 0;
|
||||||
|
unsigned char protocol, scope, tos, table;
|
||||||
|
int family;
|
||||||
|
unsigned char dst_prefixlen, src_prefixlen;
|
||||||
|
union in_addr_union dst = {}, gw = {}, src = {}, prefsrc = {};
|
||||||
|
Route *route = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(rtnl);
|
||||||
|
assert(message);
|
||||||
|
assert(m);
|
||||||
|
|
||||||
|
if (sd_netlink_message_is_error(message)) {
|
||||||
|
r = sd_netlink_message_get_errno(message);
|
||||||
|
if (r < 0)
|
||||||
|
log_warning_errno(r, "rtnl: failed to receive route: %m");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = sd_netlink_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_NEWROUTE && type != RTM_DELROUTE) {
|
||||||
|
log_warning("rtnl: received unexpected message type when processing route");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = sd_netlink_message_read_u32(message, RTA_OIF, &ifindex);
|
||||||
|
if (r == -ENODATA) {
|
||||||
|
log_debug("rtnl: received route without ifindex, ignoring");
|
||||||
|
return 0;
|
||||||
|
} else if (r < 0) {
|
||||||
|
log_warning_errno(r, "rtnl: could not get ifindex from route, ignoring: %m");
|
||||||
|
return 0;
|
||||||
|
} else if (ifindex <= 0) {
|
||||||
|
log_warning("rtnl: received route message with invalid ifindex, ignoring: %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 route again, so just ignore it */
|
||||||
|
if (!m->enumerating)
|
||||||
|
log_warning("rtnl: received route for nonexistent link (%d), ignoring", ifindex);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
r = sd_rtnl_message_route_get_family(message, &family);
|
||||||
|
if (r < 0 || !IN_SET(family, AF_INET, AF_INET6)) {
|
||||||
|
log_link_warning(link, "rtnl: received address with invalid family, ignoring.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = sd_rtnl_message_route_get_protocol(message, &protocol);
|
||||||
|
if (r < 0) {
|
||||||
|
log_warning_errno(r, "rtnl: could not get route protocol: %m");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (family) {
|
||||||
|
case AF_INET:
|
||||||
|
r = sd_netlink_message_read_in_addr(message, RTA_DST, &dst.in);
|
||||||
|
if (r < 0 && r != -ENODATA) {
|
||||||
|
log_link_warning_errno(link, r, "rtnl: received route without valid destination, ignoring: %m");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = sd_netlink_message_read_in_addr(message, RTA_GATEWAY, &gw.in);
|
||||||
|
if (r < 0 && r != -ENODATA) {
|
||||||
|
log_link_warning_errno(link, r, "rtnl: received route with invalid gateway, ignoring: %m");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = sd_netlink_message_read_in_addr(message, RTA_SRC, &src.in);
|
||||||
|
if (r < 0 && r != -ENODATA) {
|
||||||
|
log_link_warning_errno(link, r, "rtnl: received route with invalid source, ignoring: %m");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = sd_netlink_message_read_in_addr(message, RTA_PREFSRC, &prefsrc.in);
|
||||||
|
if (r < 0 && r != -ENODATA) {
|
||||||
|
log_link_warning_errno(link, r, "rtnl: received route with invalid preferred source, ignoring: %m");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AF_INET6:
|
||||||
|
r = sd_netlink_message_read_in6_addr(message, RTA_DST, &dst.in6);
|
||||||
|
if (r < 0 && r != -ENODATA) {
|
||||||
|
log_link_warning_errno(link, r, "rtnl: received route without valid destination, ignoring: %m");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = sd_netlink_message_read_in6_addr(message, RTA_GATEWAY, &gw.in6);
|
||||||
|
if (r < 0 && r != -ENODATA) {
|
||||||
|
log_link_warning_errno(link, r, "rtnl: received route with invalid gateway, ignoring: %m");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = sd_netlink_message_read_in6_addr(message, RTA_SRC, &src.in6);
|
||||||
|
if (r < 0 && r != -ENODATA) {
|
||||||
|
log_link_warning_errno(link, r, "rtnl: received route with invalid source, ignoring: %m");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = sd_netlink_message_read_in6_addr(message, RTA_PREFSRC, &prefsrc.in6);
|
||||||
|
if (r < 0 && r != -ENODATA) {
|
||||||
|
log_link_warning_errno(link, r, "rtnl: received route with invalid preferred source, ignoring: %m");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
log_link_debug(link, "rtnl: ignoring unsupported address family: %d", family);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = sd_rtnl_message_route_get_dst_prefixlen(message, &dst_prefixlen);
|
||||||
|
if (r < 0) {
|
||||||
|
log_link_warning_errno(link, r, "rtnl: received route with invalid destination prefixlen, ignoring: %m");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = sd_rtnl_message_route_get_src_prefixlen(message, &src_prefixlen);
|
||||||
|
if (r < 0) {
|
||||||
|
log_link_warning_errno(link, r, "rtnl: received route with invalid source prefixlen, ignoring: %m");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = sd_rtnl_message_route_get_scope(message, &scope);
|
||||||
|
if (r < 0) {
|
||||||
|
log_link_warning_errno(link, r, "rtnl: received route with invalid scope, ignoring: %m");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = sd_rtnl_message_route_get_tos(message, &tos);
|
||||||
|
if (r < 0) {
|
||||||
|
log_link_warning_errno(link, r, "rtnl: received route with invalid tos, ignoring: %m");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = sd_rtnl_message_route_get_table(message, &table);
|
||||||
|
if (r < 0) {
|
||||||
|
log_link_warning_errno(link, r, "rtnl: received route with invalid table, ignoring: %m");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = sd_netlink_message_read_u32(message, RTA_PRIORITY, &priority);
|
||||||
|
if (r < 0 && r != -ENODATA) {
|
||||||
|
log_link_warning_errno(link, r, "rtnl: received route with invalid priority, ignoring: %m");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
route_get(link, family, &dst, dst_prefixlen, tos, priority, table, &route);
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case RTM_NEWROUTE:
|
||||||
|
if (!route) {
|
||||||
|
/* A route appeared that we did not request */
|
||||||
|
r = route_add_foreign(link, family, &dst, dst_prefixlen, tos, priority, table, &route);
|
||||||
|
if (r < 0)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
route_update(route, &src, src_prefixlen, &gw, &prefsrc, scope, protocol);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RTM_DELROUTE:
|
||||||
|
|
||||||
|
if (route)
|
||||||
|
route_drop(route);
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert_not_reached("Received invalid RTNL message type");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message, void *userdata) {
|
int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message, void *userdata) {
|
||||||
Manager *m = userdata;
|
Manager *m = userdata;
|
||||||
Link *link = NULL;
|
Link *link = NULL;
|
||||||
|
@ -377,7 +567,7 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert_not_reached("invalid address family");
|
log_link_debug(link, "rtnl: ignoring unsupported address family: %d", family);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!inet_ntop(family, &in_addr, buf, INET6_ADDRSTRLEN)) {
|
if (!inet_ntop(family, &in_addr, buf, INET6_ADDRSTRLEN)) {
|
||||||
|
@ -572,6 +762,14 @@ static int manager_connect_rtnl(Manager *m) {
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
r = sd_netlink_add_match(m->rtnl, RTM_NEWROUTE, &manager_rtnl_process_route, m);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = sd_netlink_add_match(m->rtnl, RTM_DELROUTE, &manager_rtnl_process_route, m);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1019,6 +1217,41 @@ int manager_rtnl_enumerate_addresses(Manager *m) {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int manager_rtnl_enumerate_routes(Manager *m) {
|
||||||
|
_cleanup_netlink_message_unref_ sd_netlink_message *req = NULL, *reply = NULL;
|
||||||
|
sd_netlink_message *route;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(m);
|
||||||
|
assert(m->rtnl);
|
||||||
|
|
||||||
|
r = sd_rtnl_message_new_route(m->rtnl, &req, RTM_GETROUTE, 0, 0);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = sd_netlink_message_request_dump(req, true);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = sd_netlink_call(m->rtnl, req, 0, &reply);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
for (route = reply; route; route = sd_netlink_message_next(route)) {
|
||||||
|
int k;
|
||||||
|
|
||||||
|
m->enumerating = true;
|
||||||
|
|
||||||
|
k = manager_rtnl_process_route(m->rtnl, route, m);
|
||||||
|
if (k < 0)
|
||||||
|
r = k;
|
||||||
|
|
||||||
|
m->enumerating = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
int manager_address_pool_acquire(Manager *m, int family, unsigned prefixlen, union in_addr_union *found) {
|
int manager_address_pool_acquire(Manager *m, int family, unsigned prefixlen, union in_addr_union *found) {
|
||||||
AddressPool *p;
|
AddressPool *p;
|
||||||
int r;
|
int r;
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "networkd-route.h"
|
#include "networkd-route.h"
|
||||||
#include "networkd.h"
|
#include "networkd.h"
|
||||||
#include "parse-util.h"
|
#include "parse-util.h"
|
||||||
|
#include "set.h"
|
||||||
#include "string-util.h"
|
#include "string-util.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
@ -95,6 +96,11 @@ void route_free(Route *route) {
|
||||||
UINT_TO_PTR(route->section));
|
UINT_TO_PTR(route->section));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (route->link) {
|
||||||
|
set_remove(route->link->routes, route);
|
||||||
|
set_remove(route->link->routes_foreign, route);
|
||||||
|
}
|
||||||
|
|
||||||
free(route);
|
free(route);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,6 +172,162 @@ static const struct hash_ops route_hash_ops = {
|
||||||
.compare = route_compare_func
|
.compare = route_compare_func
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int route_get(Link *link,
|
||||||
|
int family,
|
||||||
|
union in_addr_union *dst,
|
||||||
|
unsigned char dst_prefixlen,
|
||||||
|
unsigned char tos,
|
||||||
|
uint32_t priority,
|
||||||
|
unsigned char table,
|
||||||
|
Route **ret) {
|
||||||
|
Route route = {
|
||||||
|
.family = family,
|
||||||
|
.dst_prefixlen = dst_prefixlen,
|
||||||
|
.tos = tos,
|
||||||
|
.priority = priority,
|
||||||
|
.table = table,
|
||||||
|
}, *existing;
|
||||||
|
|
||||||
|
assert(link);
|
||||||
|
assert(dst);
|
||||||
|
assert(ret);
|
||||||
|
|
||||||
|
route.dst = *dst;
|
||||||
|
|
||||||
|
existing = set_get(link->routes, &route);
|
||||||
|
if (existing) {
|
||||||
|
*ret = existing;
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
existing = set_get(link->routes_foreign, &route);
|
||||||
|
if (!existing)
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ret = existing;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int route_add_internal(Link *link, Set **routes,
|
||||||
|
int family,
|
||||||
|
union in_addr_union *dst,
|
||||||
|
unsigned char dst_prefixlen,
|
||||||
|
unsigned char tos,
|
||||||
|
uint32_t priority,
|
||||||
|
unsigned char table, Route **ret) {
|
||||||
|
_cleanup_route_free_ Route *route = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(link);
|
||||||
|
assert(routes);
|
||||||
|
assert(dst);
|
||||||
|
|
||||||
|
r = route_new(&route);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
route->family = family;
|
||||||
|
route->dst = *dst;
|
||||||
|
route->dst_prefixlen = dst_prefixlen;
|
||||||
|
route->tos = tos;
|
||||||
|
route->priority = priority;
|
||||||
|
route->table = table;
|
||||||
|
|
||||||
|
r = set_ensure_allocated(routes, &route_hash_ops);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = set_put(*routes, route);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
route->link = link;
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
*ret = route;
|
||||||
|
|
||||||
|
route = NULL;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int route_add_foreign(Link *link,
|
||||||
|
int family,
|
||||||
|
union in_addr_union *dst,
|
||||||
|
unsigned char dst_prefixlen,
|
||||||
|
unsigned char tos,
|
||||||
|
uint32_t priority,
|
||||||
|
unsigned char table, Route **ret) {
|
||||||
|
return route_add_internal(link, &link->routes_foreign, family, dst, dst_prefixlen, tos, priority, table, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
int route_add(Link *link,
|
||||||
|
int family,
|
||||||
|
union in_addr_union *dst,
|
||||||
|
unsigned char dst_prefixlen,
|
||||||
|
unsigned char tos,
|
||||||
|
uint32_t priority,
|
||||||
|
unsigned char table, Route **ret) {
|
||||||
|
Route *route;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
r = route_get(link, family, dst, dst_prefixlen, tos, priority, table, &route);
|
||||||
|
if (r == -ENOENT) {
|
||||||
|
/* Route does not exist, create a new one */
|
||||||
|
r = route_add_internal(link, &link->routes, family, dst, dst_prefixlen, tos, priority, table, &route);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
} else if (r == 0) {
|
||||||
|
/* Take over a foreign route */
|
||||||
|
r = set_ensure_allocated(&link->routes, &route_hash_ops);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = set_put(link->routes, route);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
set_remove(link->routes_foreign, route);
|
||||||
|
} else if (r == 1) {
|
||||||
|
/* Route exists, do nothing */
|
||||||
|
;
|
||||||
|
} else
|
||||||
|
return r;
|
||||||
|
|
||||||
|
*ret = route;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int route_update(Route *route,
|
||||||
|
union in_addr_union *src,
|
||||||
|
unsigned char src_prefixlen,
|
||||||
|
union in_addr_union *gw,
|
||||||
|
union in_addr_union *prefsrc,
|
||||||
|
unsigned char scope,
|
||||||
|
unsigned char protocol) {
|
||||||
|
assert(route);
|
||||||
|
assert(src);
|
||||||
|
assert(gw);
|
||||||
|
assert(prefsrc);
|
||||||
|
|
||||||
|
route->src = *src;
|
||||||
|
route->src_prefixlen = src_prefixlen;
|
||||||
|
route->gw = *gw;
|
||||||
|
route->prefsrc = *prefsrc;
|
||||||
|
route->scope = scope;
|
||||||
|
route->protocol = protocol;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void route_drop(Route *route) {
|
||||||
|
assert(route);
|
||||||
|
|
||||||
|
route_free(route);
|
||||||
|
}
|
||||||
|
|
||||||
int route_remove(Route *route, Link *link,
|
int route_remove(Route *route, Link *link,
|
||||||
sd_netlink_message_handler_t callback) {
|
sd_netlink_message_handler_t callback) {
|
||||||
_cleanup_netlink_message_unref_ sd_netlink_message *req = NULL;
|
_cleanup_netlink_message_unref_ sd_netlink_message *req = NULL;
|
||||||
|
@ -327,6 +489,10 @@ int route_configure(Route *route, Link *link,
|
||||||
|
|
||||||
link_ref(link);
|
link_ref(link);
|
||||||
|
|
||||||
|
r = route_add(link, route->family, &route->dst, route->dst_prefixlen, route->tos, route->priority, route->table, NULL);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Could not add route: %m");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,8 @@ struct Route {
|
||||||
Network *network;
|
Network *network;
|
||||||
unsigned section;
|
unsigned section;
|
||||||
|
|
||||||
|
Link *link;
|
||||||
|
|
||||||
int family;
|
int family;
|
||||||
unsigned char dst_prefixlen;
|
unsigned char dst_prefixlen;
|
||||||
unsigned char src_prefixlen;
|
unsigned char src_prefixlen;
|
||||||
|
@ -53,6 +55,12 @@ void route_free(Route *route);
|
||||||
int route_configure(Route *route, Link *link, sd_netlink_message_handler_t callback);
|
int route_configure(Route *route, Link *link, sd_netlink_message_handler_t callback);
|
||||||
int route_remove(Route *route, Link *link, sd_netlink_message_handler_t callback);
|
int route_remove(Route *route, Link *link, sd_netlink_message_handler_t callback);
|
||||||
|
|
||||||
|
int route_get(Link *link, int family, union in_addr_union *dst, unsigned char dst_prefixlen, unsigned char tos, uint32_t priority, unsigned char table, Route **ret);
|
||||||
|
int route_add(Link *link, int family, union in_addr_union *dst, unsigned char dst_prefixlen, unsigned char tos, uint32_t priority, unsigned char table, Route **ret);
|
||||||
|
int route_add_foreign(Link *link, int family, union in_addr_union *dst, unsigned char dst_prefixlen, unsigned char tos, uint32_t priority, unsigned char table, Route **ret);
|
||||||
|
int route_update(Route *route, union in_addr_union *src, unsigned char src_prefixlen, union in_addr_union *gw, union in_addr_union *prefsrc, unsigned char scope, unsigned char protocol);
|
||||||
|
void route_drop(Route *route);
|
||||||
|
|
||||||
DEFINE_TRIVIAL_CLEANUP_FUNC(Route*, route_free);
|
DEFINE_TRIVIAL_CLEANUP_FUNC(Route*, route_free);
|
||||||
#define _cleanup_route_free_ _cleanup_(route_freep)
|
#define _cleanup_route_free_ _cleanup_(route_freep)
|
||||||
|
|
||||||
|
|
|
@ -109,6 +109,12 @@ int main(int argc, char *argv[]) {
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
r = manager_rtnl_enumerate_routes(m);
|
||||||
|
if (r < 0) {
|
||||||
|
log_error_errno(r, "Could not enumerate routes: %m");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
log_info("Enumeration completed");
|
log_info("Enumeration completed");
|
||||||
|
|
||||||
sd_notify(false,
|
sd_notify(false,
|
||||||
|
|
|
@ -82,8 +82,10 @@ bool manager_should_reload(Manager *m);
|
||||||
|
|
||||||
int manager_rtnl_enumerate_links(Manager *m);
|
int manager_rtnl_enumerate_links(Manager *m);
|
||||||
int manager_rtnl_enumerate_addresses(Manager *m);
|
int manager_rtnl_enumerate_addresses(Manager *m);
|
||||||
|
int manager_rtnl_enumerate_routes(Manager *m);
|
||||||
|
|
||||||
int manager_rtnl_process_address(sd_netlink *nl, sd_netlink_message *message, void *userdata);
|
int manager_rtnl_process_address(sd_netlink *nl, sd_netlink_message *message, void *userdata);
|
||||||
|
int manager_rtnl_process_route(sd_netlink *nl, sd_netlink_message *message, void *userdata);
|
||||||
|
|
||||||
int manager_send_changed(Manager *m, const char *property, ...) _sentinel_;
|
int manager_send_changed(Manager *m, const char *property, ...) _sentinel_;
|
||||||
void manager_dirty(Manager *m);
|
void manager_dirty(Manager *m);
|
||||||
|
|
|
@ -14,7 +14,7 @@ Before=sockets.target
|
||||||
|
|
||||||
[Socket]
|
[Socket]
|
||||||
ReceiveBuffer=8M
|
ReceiveBuffer=8M
|
||||||
ListenNetlink=route 273
|
ListenNetlink=route 1361
|
||||||
PassCredentials=yes
|
PassCredentials=yes
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
|
|
Loading…
Reference in a new issue