All routes added by networkd are currently set RTPROT_BOOT, which according
to the kernel means "Route installed during boot" (rtnetlink.h). But this
is not always the case as networkd changes routing after boot too. Since
the kernel gives more detailed protocols, use them.
With this patch, user-configured static routes now use RTPROT_STATIC (which
they are) and DHCP routes use RTPROT_DHCP. There is no define for IPv4LL
yet, so those are installed as RTPROT_STATIC (though perhaps RTPROT_RA is
better?).
[tomegun: fixup
src/network/networkd-link.c:972:33: error: too few arguments to function 'route_new_dynamic']
}
int sd_rtnl_message_new_route(sd_rtnl *rtnl, sd_rtnl_message **ret,
}
int sd_rtnl_message_new_route(sd_rtnl *rtnl, sd_rtnl_message **ret,
- uint16_t nlmsg_type, int rtm_family) {
+ uint16_t nlmsg_type, int rtm_family,
+ unsigned char rtm_protocol) {
struct rtmsg *rtm;
int r;
struct rtmsg *rtm;
int r;
rtm->rtm_scope = RT_SCOPE_UNIVERSE;
rtm->rtm_type = RTN_UNICAST;
rtm->rtm_table = RT_TABLE_MAIN;
rtm->rtm_scope = RT_SCOPE_UNIVERSE;
rtm->rtm_type = RTN_UNICAST;
rtm->rtm_table = RT_TABLE_MAIN;
- rtm->rtm_protocol = RTPROT_BOOT;
+ rtm->rtm_protocol = rtm_protocol;
uint32_t index = 2, u32_data;
int r;
uint32_t index = 2, u32_data;
int r;
- r = sd_rtnl_message_new_route(NULL, &req, RTM_NEWROUTE, AF_INET);
+ r = sd_rtnl_message_new_route(NULL, &req, RTM_NEWROUTE, AF_INET, RTPROT_STATIC);
if (r < 0) {
log_error("Could not create RTM_NEWROUTE message: %s", strerror(-r));
return;
if (r < 0) {
log_error("Could not create RTM_NEWROUTE message: %s", strerror(-r));
return;
for (i = 0; i < n; i++) {
_cleanup_route_free_ Route *route = NULL;
for (i = 0; i < n; i++) {
_cleanup_route_free_ Route *route = NULL;
- r = route_new_dynamic(&route);
+ r = route_new_dynamic(&route, RTPROT_DHCP);
if (r < 0) {
log_error_link(link, "Could not allocate route: %s",
strerror(-r));
if (r < 0) {
log_error_link(link, "Could not allocate route: %s",
strerror(-r));
- r = route_new_dynamic(&route);
+ r = route_new_dynamic(&route, RTPROT_STATIC);
if (r < 0) {
log_error_link(link, "Could not allocate route: %s",
strerror(-r));
if (r < 0) {
log_error_link(link, "Could not allocate route: %s",
strerror(-r));
- r = route_new_dynamic(&route);
+ r = route_new_dynamic(&route, RTPROT_DHCP);
if (r < 0) {
log_error_link(link, "Could not allocate route: %s",
strerror(-r));
return r;
}
if (r < 0) {
log_error_link(link, "Could not allocate route: %s",
strerror(-r));
return r;
}
- r = route_new_dynamic(&route_gw);
+ r = route_new_dynamic(&route_gw, RTPROT_DHCP);
if (r < 0) {
log_error_link(link, "Could not allocate route: %s",
strerror(-r));
if (r < 0) {
log_error_link(link, "Could not allocate route: %s",
strerror(-r));
for (i = 0; i < n; i++) {
_cleanup_route_free_ Route *route = NULL;
for (i = 0; i < n; i++) {
_cleanup_route_free_ Route *route = NULL;
- r = route_new_dynamic(&route);
+ r = route_new_dynamic(&route, RTPROT_UNSPEC);
if (r >= 0) {
route->family = AF_INET;
route->in_addr.in = routes[i].gw_addr;
if (r >= 0) {
route->family = AF_INET;
route->in_addr.in = routes[i].gw_addr;
_cleanup_route_free_ Route *route_gw = NULL;
_cleanup_route_free_ Route *route = NULL;
_cleanup_route_free_ Route *route_gw = NULL;
_cleanup_route_free_ Route *route = NULL;
- r = route_new_dynamic(&route_gw);
+ r = route_new_dynamic(&route_gw, RTPROT_UNSPEC);
if (r >= 0) {
route_gw->family = AF_INET;
route_gw->dst_addr.in = gateway;
if (r >= 0) {
route_gw->family = AF_INET;
route_gw->dst_addr.in = gateway;
route_drop(route_gw, link, &route_drop_handler);
}
route_drop(route_gw, link, &route_drop_handler);
}
- r = route_new_dynamic(&route);
+ r = route_new_dynamic(&route, RTPROT_UNSPEC);
if (r >= 0) {
route->family = AF_INET;
route->in_addr.in = gateway;
if (r >= 0) {
route->family = AF_INET;
route->in_addr.in = gateway;
address_drop(address, link, &address_drop_handler);
address_drop(address, link, &address_drop_handler);
- r = route_new_dynamic(&route);
+ r = route_new_dynamic(&route, RTPROT_UNSPEC);
if (r < 0) {
log_error_link(link, "Could not allocate route: %s",
strerror(-r));
if (r < 0) {
log_error_link(link, "Could not allocate route: %s",
strerror(-r));
route->family = AF_UNSPEC;
route->scope = RT_SCOPE_UNIVERSE;
route->family = AF_UNSPEC;
route->scope = RT_SCOPE_UNIVERSE;
+ route->protocol = RTPROT_STATIC;
route->network = network;
route->network = network;
-int route_new_dynamic(Route **ret) {
+int route_new_dynamic(Route **ret, unsigned char rtm_protocol) {
_cleanup_route_free_ Route *route = NULL;
route = new0(Route, 1);
_cleanup_route_free_ Route *route = NULL;
route = new0(Route, 1);
route->family = AF_UNSPEC;
route->scope = RT_SCOPE_UNIVERSE;
route->family = AF_UNSPEC;
route->scope = RT_SCOPE_UNIVERSE;
+ route->protocol = rtm_protocol;
*ret = route;
route = NULL;
*ret = route;
route = NULL;
assert(route->family == AF_INET || route->family == AF_INET6);
r = sd_rtnl_message_new_route(link->manager->rtnl, &req,
assert(route->family == AF_INET || route->family == AF_INET6);
r = sd_rtnl_message_new_route(link->manager->rtnl, &req,
- RTM_DELROUTE, route->family);
+ RTM_DELROUTE, route->family,
+ route->protocol);
if (r < 0) {
log_error("Could not create RTM_DELROUTE message: %s", strerror(-r));
return r;
if (r < 0) {
log_error("Could not create RTM_DELROUTE message: %s", strerror(-r));
return r;
assert(route->family == AF_INET || route->family == AF_INET6);
r = sd_rtnl_message_new_route(link->manager->rtnl, &req,
assert(route->family == AF_INET || route->family == AF_INET6);
r = sd_rtnl_message_new_route(link->manager->rtnl, &req,
- RTM_NEWROUTE, route->family);
+ RTM_NEWROUTE, route->family,
+ route->protocol);
if (r < 0) {
log_error("Could not create RTM_NEWROUTE message: %s", strerror(-r));
return r;
if (r < 0) {
log_error("Could not create RTM_NEWROUTE message: %s", strerror(-r));
return r;
unsigned char dst_prefixlen;
unsigned char scope;
uint32_t metrics;
unsigned char dst_prefixlen;
unsigned char scope;
uint32_t metrics;
+ unsigned char protocol; /* RTPROT_* */
union in_addr_union in_addr;
union in_addr_union dst_addr;
union in_addr_union in_addr;
union in_addr_union dst_addr;
/* Route */
int route_new_static(Network *network, unsigned section, Route **ret);
/* Route */
int route_new_static(Network *network, unsigned section, Route **ret);
-int route_new_dynamic(Route **ret);
+int route_new_dynamic(Route **ret, unsigned char rtm_protocol);
void route_free(Route *route);
int route_configure(Route *route, Link *link, sd_rtnl_message_handler_t callback);
int route_drop(Route *route, Link *link, sd_rtnl_message_handler_t callback);
void route_free(Route *route);
int route_configure(Route *route, Link *link, sd_rtnl_message_handler_t callback);
int route_drop(Route *route, Link *link, sd_rtnl_message_handler_t callback);
int sd_rtnl_message_new_addr(sd_rtnl *rtnl, sd_rtnl_message **ret, uint16_t msg_type, int index,
int family);
int sd_rtnl_message_new_route(sd_rtnl *rtnl, sd_rtnl_message **ret, uint16_t nlmsg_type,
int sd_rtnl_message_new_addr(sd_rtnl *rtnl, sd_rtnl_message **ret, uint16_t msg_type, int index,
int family);
int sd_rtnl_message_new_route(sd_rtnl *rtnl, sd_rtnl_message **ret, uint16_t nlmsg_type,
+ int rtm_family, unsigned char rtm_protocol);
sd_rtnl_message *sd_rtnl_message_ref(sd_rtnl_message *m);
sd_rtnl_message *sd_rtnl_message_unref(sd_rtnl_message *m);
sd_rtnl_message *sd_rtnl_message_ref(sd_rtnl_message *m);
sd_rtnl_message *sd_rtnl_message_unref(sd_rtnl_message *m);