diff --git a/keepalived/core/keepalived_netlink.c b/keepalived/core/keepalived_netlink.c index 198d0e10f..da3596fdb 100644 --- a/keepalived/core/keepalived_netlink.c +++ b/keepalived/core/keepalived_netlink.c @@ -276,9 +276,10 @@ compare_route(struct rtattr *tb[RTA_MAX + 1], ip_route_t *route, uint32_t table, if (route->oif) { if (!tb[RTA_OIF] || route->oif->ifindex != *PTR_CAST(uint32_t, RTA_DATA(tb[RTA_OIF]))) return false; - } else { - if (route->set && route->configured_ifindex && - (!tb[RTA_OIF] || route->configured_ifindex != *PTR_CAST(uint32_t, RTA_DATA(tb[RTA_OIF])))) + } else if (route->set) { + if (!tb[RTA_OIF] != !route->configured_ifindex) + return false; + if (tb[RTA_OIF] && route->configured_ifindex != *PTR_CAST(uint32_t, RTA_DATA(tb[RTA_OIF]))) return false; } @@ -2360,9 +2361,8 @@ netlink_route_filter(__attribute__((unused)) struct sockaddr_nl *snl, struct nlm route->configured_ifindex = *PTR_CAST(uint32_t, RTA_DATA(tb[RTA_OIF])); if (route->oif && route->oif->ifindex != route->configured_ifindex) log_message(LOG_INFO, "route added index %" PRIu32 " != config index %u", route->configured_ifindex, route->oif->ifindex); - } - else - log_message(LOG_INFO, "New route doesn't have i/f index"); + } else + route->configured_ifindex = 0; return 0; } diff --git a/keepalived/include/vrrp_iproute.h b/keepalived/include/vrrp_iproute.h index 632c06b8c..50b455dbb 100644 --- a/keepalived/include/vrrp_iproute.h +++ b/keepalived/include/vrrp_iproute.h @@ -154,8 +154,8 @@ enum ip_route { IPROUTE_PREF, IPROUTE_FASTOPEN_NO_COOKIE, IPROUTE_TTL_PROPAGATE, - IPROUTE_ADD, - IPROUTE_APPEND + IPROUTE_ADD_ROUTE, + IPROUTE_APPEND_ROUTE }; #define IPROUTE_BIT_DSFIELD (1<vroutes)) - vrrp_handle_iproutes(vrrp, IPROUTE_DEL, false); + vrrp_handle_iproutes(vrrp, IPROUTE_DEL, force); /* empty the delayed arp list */ vrrp_remove_delayed_arp(vrrp); diff --git a/keepalived/vrrp/vrrp_iproute.c b/keepalived/vrrp/vrrp_iproute.c index c2791945e..913118002 100644 --- a/keepalived/vrrp/vrrp_iproute.c +++ b/keepalived/vrrp/vrrp_iproute.c @@ -531,9 +531,10 @@ netlink_rtlist(list_head_t *rt_list, int cmd, bool force) list_for_each_entry(ip_route, rt_list, e_list) { if ((cmd == IPROUTE_DEL) == ip_route->set || force) { - if (!netlink_route(ip_route, cmd)) - ip_route->set = (cmd == IPROUTE_ADD); - else if (cmd != IPROUTE_ADD) + if (!netlink_route(ip_route, cmd)) { + if (cmd == IPROUTE_DEL) + ip_route->set = false; + } else if (cmd != IPROUTE_ADD) ip_route->set = false; } } @@ -1871,21 +1872,6 @@ alloc_route(list_head_t *rt_list, const vector_t *strvec, bool allow_track_group report_config_error(CONFIG_GENERAL_ERROR, "Route cannot be tracked if protocol is not RTPROT_KEEPALIVED(%d), resetting protocol", RTPROT_KEEPALIVED); new->protocol = RTPROT_KEEPALIVED; new->mask |= IPROUTE_BIT_PROTOCOL; - - if (!new->oif) { - /* Alternative is to track oif from when route last added. - * The interface will need to be added temporarily. tracking_obj_t will need - * a flag to specify permanent track, and a counter for number of temporary - * trackers. If the termporary tracker count becomes 0 and there is no permanent - * track, then the tracking_obj_t will need to be removed. - * - * We also have a problem if using nexthop, since the route will only be deleted - * when the interfaces for all of the hops have gone down. We would need to track - * all of the interfaces being used, and only mark the route as down if all the - * interfaces are down. */ - report_config_error(CONFIG_GENERAL_ERROR, "Warning - cannot track route %s with no interface specified, not tracking", dest); - new->dont_track = true; - } } if (new->track_group && !new->oif) { diff --git a/keepalived/vrrp/vrrp_scheduler.c b/keepalived/vrrp/vrrp_scheduler.c index fc40d59de..8c1747c6e 100644 --- a/keepalived/vrrp/vrrp_scheduler.c +++ b/keepalived/vrrp/vrrp_scheduler.c @@ -65,6 +65,8 @@ #ifdef _WITH_LVS_ #include "ipvswrapper.h" #endif +#include "keepalived_netlink.h" + /* For load testing recvmsg() */ /* #define DEBUG_RECVMSG */ @@ -266,7 +268,9 @@ vrrp_init_state(list_head_t *l) #endif /* Set interface state */ - vrrp_restore_interface(vrrp, false, false); + netlink_error_ignore = ESRCH; // returned if route does not exist + vrrp_restore_interface(vrrp, false, true); + netlink_error_ignore = 0; if (is_up && new_state != VRRP_STATE_FAULT && !vrrp->num_script_init &&