mirror of
https://github.com/systemd/systemd
synced 2024-07-22 10:44:58 +00:00
Merge pull request #19458 from yuwata/network-route-remove
network: fix route removal logic a bit
This commit is contained in:
commit
c3a5240e3a
|
@ -1274,7 +1274,9 @@ static int dhcp4_handler(sd_dhcp_client *client, int event, void *userdata) {
|
|||
if (link->network->dhcp_send_release) {
|
||||
r = sd_dhcp_client_send_release(client);
|
||||
if (r < 0)
|
||||
log_link_warning_errno(link, r, "Failed to send DHCP RELEASE, ignoring: %m");
|
||||
log_link_full_errno(link,
|
||||
ERRNO_IS_DISCONNECT(r) ? LOG_DEBUG : LOG_WARNING,
|
||||
r, "Failed to send DHCP RELEASE, ignoring: %m");
|
||||
}
|
||||
|
||||
r = dhcp_lease_lost(link);
|
||||
|
|
|
@ -2967,15 +2967,3 @@ static const char* const link_state_table[_LINK_STATE_MAX] = {
|
|||
};
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);
|
||||
|
||||
int log_link_message_full_errno(Link *link, sd_netlink_message *m, int level, int err, const char *msg) {
|
||||
const char *err_msg = NULL;
|
||||
|
||||
(void) sd_netlink_message_read_string(m, NLMSGERR_ATTR_MSG, &err_msg);
|
||||
return log_link_full_errno(link, level, err,
|
||||
"%s: %s%s%s%m",
|
||||
msg,
|
||||
strempty(err_msg),
|
||||
err_msg && !endswith(err_msg, ".") ? "." : "",
|
||||
err_msg ? " " : "");
|
||||
}
|
||||
|
|
|
@ -237,10 +237,3 @@ int link_reconfigure(Link *link, bool force);
|
|||
|
||||
int manager_udev_process_link(sd_device_monitor *monitor, sd_device *device, void *userdata);
|
||||
int manager_rtnl_process_link(sd_netlink *rtnl, sd_netlink_message *message, Manager *m);
|
||||
|
||||
int log_link_message_full_errno(Link *link, sd_netlink_message *m, int level, int err, const char *msg);
|
||||
#define log_link_message_error_errno(link, m, err, msg) log_link_message_full_errno(link, m, LOG_ERR, err, msg)
|
||||
#define log_link_message_warning_errno(link, m, err, msg) log_link_message_full_errno(link, m, LOG_WARNING, err, msg)
|
||||
#define log_link_message_notice_errno(link, m, err, msg) log_link_message_full_errno(link, m, LOG_NOTICE, err, msg)
|
||||
#define log_link_message_info_errno(link, m, err, msg) log_link_message_full_errno(link, m, LOG_INFO, err, msg)
|
||||
#define log_link_message_debug_errno(link, m, err, msg) log_link_message_full_errno(link, m, LOG_DEBUG, err, msg)
|
||||
|
|
|
@ -87,8 +87,8 @@ struct Manager {
|
|||
usec_t speed_meter_usec_new;
|
||||
usec_t speed_meter_usec_old;
|
||||
|
||||
bool dhcp4_prefix_root_cannot_set_table:1;
|
||||
bool bridge_mdb_on_master_not_supported:1;
|
||||
bool dhcp4_prefix_root_cannot_set_table;
|
||||
bool bridge_mdb_on_master_not_supported;
|
||||
|
||||
FirewallContext *fw_ctx;
|
||||
};
|
||||
|
|
|
@ -645,7 +645,7 @@ static int route_set_netlink_message(const Route *route, sd_netlink_message *req
|
|||
|
||||
/* link may be NULL */
|
||||
|
||||
if (in_addr_is_set(route->gw_family, &route->gw)) {
|
||||
if (in_addr_is_set(route->gw_family, &route->gw) && route->nexthop_id == 0) {
|
||||
if (route->gw_family == route->family) {
|
||||
r = netlink_message_append_in_addr_union(req, RTA_GATEWAY, route->gw_family, &route->gw);
|
||||
if (r < 0)
|
||||
|
@ -717,10 +717,6 @@ static int route_set_netlink_message(const Route *route, sd_netlink_message *req
|
|||
}
|
||||
}
|
||||
|
||||
r = sd_rtnl_message_route_set_type(req, route->type);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not set route type: %m");
|
||||
|
||||
if (!route_type_is_reject(route) && route->nexthop_id == 0) {
|
||||
assert(link); /* Those routes must be attached to a specific link */
|
||||
|
||||
|
@ -769,6 +765,7 @@ int route_remove(
|
|||
link_netlink_message_handler_t callback) {
|
||||
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
|
||||
unsigned char type;
|
||||
int r;
|
||||
|
||||
assert(link || manager);
|
||||
|
@ -786,6 +783,21 @@ int route_remove(
|
|||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not create RTM_DELROUTE message: %m");
|
||||
|
||||
if (route->family == AF_INET && route->nexthop_id > 0 && route->type == RTN_BLACKHOLE)
|
||||
/* When IPv4 route has nexthop id and the nexthop type is blackhole, even though kernel
|
||||
* sends RTM_NEWROUTE netlink message with blackhole type, kernel's internal route type
|
||||
* fib_rt_info::type may not be blackhole. Thus, we cannot know the internal value.
|
||||
* Moreover, on route removal, the matching is done with the hidden value if we set
|
||||
* non-zero type in RTM_DELROUTE message. Note, sd_rtnl_message_new_route() sets
|
||||
* RTN_UNICAST by default. So, we need to clear the type here. */
|
||||
type = RTN_UNSPEC;
|
||||
else
|
||||
type = route->type;
|
||||
|
||||
r = sd_rtnl_message_route_set_type(req, type);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not set route type: %m");
|
||||
|
||||
r = route_set_netlink_message(route, req, link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
@ -842,6 +854,9 @@ static int manager_drop_routes_internal(Manager *manager, bool foreign, const Li
|
|||
|
||||
routes = foreign ? manager->routes_foreign : manager->routes;
|
||||
SET_FOREACH(route, routes) {
|
||||
if (route->removing)
|
||||
continue;
|
||||
|
||||
/* Do not touch routes managed by the kernel. */
|
||||
if (route->protocol == RTPROT_KERNEL)
|
||||
continue;
|
||||
|
@ -855,6 +870,8 @@ static int manager_drop_routes_internal(Manager *manager, bool foreign, const Li
|
|||
k = route_remove(route, manager, NULL, NULL);
|
||||
if (k < 0 && r >= 0)
|
||||
r = k;
|
||||
|
||||
route->removing = true;
|
||||
}
|
||||
|
||||
return r;
|
||||
|
@ -1083,8 +1100,8 @@ int route_configure(
|
|||
Route **ret) {
|
||||
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
|
||||
int r, k = 0;
|
||||
Route *nr;
|
||||
int r, k;
|
||||
|
||||
assert(link);
|
||||
assert(link->manager);
|
||||
|
@ -1106,6 +1123,10 @@ int route_configure(
|
|||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not create RTM_NEWROUTE message: %m");
|
||||
|
||||
r = sd_rtnl_message_route_set_type(req, route->type);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not set route type: %m");
|
||||
|
||||
r = route_set_netlink_message(route, req, link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
@ -1167,19 +1188,22 @@ int route_configure(
|
|||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append RTA_METRICS attribute: %m");
|
||||
|
||||
r = append_nexthops(route, req);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append RTA_MULTIPATH attribute: %m");
|
||||
|
||||
if (ordered_set_isempty(route->multipath_routes)) {
|
||||
if (route->nexthop_id != 0 ||
|
||||
in_addr_is_set(route->gw_family, &route->gw) ||
|
||||
ordered_set_isempty(route->multipath_routes)) {
|
||||
k = route_add_and_setup_timer(link, route, NULL, &nr);
|
||||
if (k < 0)
|
||||
return k;
|
||||
} else {
|
||||
MultipathRoute *m;
|
||||
|
||||
r = append_nexthops(route, req);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append RTA_MULTIPATH attribute: %m");
|
||||
|
||||
assert(!ret);
|
||||
|
||||
k = 0;
|
||||
ORDERED_SET_FOREACH(m, route->multipath_routes) {
|
||||
r = route_add_and_setup_timer(link, route, m, NULL);
|
||||
if (r < 0)
|
||||
|
@ -2745,8 +2769,17 @@ static int route_section_verify(Route *route, Network *network) {
|
|||
route->section->filename, route->section->line);
|
||||
}
|
||||
|
||||
if ((route->gateway_from_dhcp_or_ra ||
|
||||
in_addr_is_set(route->gw_family, &route->gw)) &&
|
||||
!ordered_set_isempty(route->multipath_routes))
|
||||
return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"%s: Gateway= cannot be specified with MultiPathRoute=. "
|
||||
"Ignoring [Route] section from line %u.",
|
||||
route->section->filename, route->section->line);
|
||||
|
||||
if (route->nexthop_id > 0 &&
|
||||
(in_addr_is_set(route->gw_family, &route->gw) ||
|
||||
(route->gateway_from_dhcp_or_ra ||
|
||||
in_addr_is_set(route->gw_family, &route->gw) ||
|
||||
!ordered_set_isempty(route->multipath_routes)))
|
||||
return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"%s: NextHopId= cannot be specified with Gateway= or MultiPathRoute=. "
|
||||
|
|
|
@ -52,6 +52,7 @@ typedef struct Route {
|
|||
bool protocol_set:1;
|
||||
bool pref_set:1;
|
||||
bool gateway_from_dhcp_or_ra:1;
|
||||
bool removing:1;
|
||||
|
||||
union in_addr_union gw;
|
||||
union in_addr_union dst;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "condition.h"
|
||||
#include "conf-parser.h"
|
||||
#include "networkd-link.h"
|
||||
#include "networkd-util.h"
|
||||
#include "parse-util.h"
|
||||
#include "string-table.h"
|
||||
|
@ -223,3 +224,17 @@ unsigned hashmap_find_free_section_line(Hashmap *hashmap) {
|
|||
|
||||
return n + 1;
|
||||
}
|
||||
|
||||
int log_link_message_full_errno(Link *link, sd_netlink_message *m, int level, int err, const char *msg) {
|
||||
const char *err_msg = NULL;
|
||||
|
||||
/* link may be NULL. */
|
||||
|
||||
(void) sd_netlink_message_read_string(m, NLMSGERR_ATTR_MSG, &err_msg);
|
||||
return log_link_full_errno(link, level, err,
|
||||
"%s: %s%s%s%m",
|
||||
msg,
|
||||
strempty(err_msg),
|
||||
err_msg && !endswith(err_msg, ".") ? "." : "",
|
||||
err_msg ? " " : "");
|
||||
}
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
#include "network-util.h"
|
||||
#include "string-util.h"
|
||||
|
||||
typedef struct Link Link;
|
||||
|
||||
typedef struct NetworkConfigSection {
|
||||
unsigned line;
|
||||
bool invalid;
|
||||
|
@ -73,9 +75,15 @@ static inline bool section_is_invalid(NetworkConfigSection *section) {
|
|||
DEFINE_TRIVIAL_CLEANUP_FUNC(type*, free_func); \
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(type*, free_func##_or_set_invalid);
|
||||
|
||||
static inline int log_message_warning_errno(sd_netlink_message *m, int err, const char *msg) {
|
||||
const char *err_msg = NULL;
|
||||
|
||||
(void) sd_netlink_message_read_string(m, NLMSGERR_ATTR_MSG, &err_msg);
|
||||
return log_warning_errno(err, "%s: %s%s%m", msg, strempty(err_msg), err_msg ? " " : "");
|
||||
}
|
||||
int log_link_message_full_errno(Link *link, sd_netlink_message *m, int level, int err, const char *msg);
|
||||
#define log_link_message_error_errno(link, m, err, msg) log_link_message_full_errno(link, m, LOG_ERR, err, msg)
|
||||
#define log_link_message_warning_errno(link, m, err, msg) log_link_message_full_errno(link, m, LOG_WARNING, err, msg)
|
||||
#define log_link_message_notice_errno(link, m, err, msg) log_link_message_full_errno(link, m, LOG_NOTICE, err, msg)
|
||||
#define log_link_message_info_errno(link, m, err, msg) log_link_message_full_errno(link, m, LOG_INFO, err, msg)
|
||||
#define log_link_message_debug_errno(link, m, err, msg) log_link_message_full_errno(link, m, LOG_DEBUG, err, msg)
|
||||
#define log_message_full_errno(m, level, err, msg) log_link_message_full_errno(NULL, m, level, err, msg)
|
||||
#define log_message_error_errno(m, err, msg) log_message_full_errno(m, LOG_ERR, err, msg)
|
||||
#define log_message_warning_errno(m, err, msg) log_message_full_errno(m, LOG_WARNING, err, msg)
|
||||
#define log_message_notice_errno(m, err, msg) log_message_full_errno(m, LOG_NOTICE, err, msg)
|
||||
#define log_message_info_errno(m, err, msg) log_message_full_errno(m, LOG_INFO, err, msg)
|
||||
#define log_message_debug_errno(m, err, msg) log_message_full_errno(m, LOG_DEBUG, err, msg)
|
||||
|
|
Loading…
Reference in a new issue