ip6: correctly handle routes with no gateways
For these we don't need to set any gateway at all, and the kernel assumes that it's a default route without a next hop.
This commit is contained in:
@@ -993,9 +993,7 @@ replace_default_ip6_route (const char *iface, const struct in6_addr *gw)
|
|||||||
{
|
{
|
||||||
struct rtnl_route *route = NULL;
|
struct rtnl_route *route = NULL;
|
||||||
struct nl_handle *nlh;
|
struct nl_handle *nlh;
|
||||||
struct nl_addr *dst_addr = NULL;
|
|
||||||
struct nl_addr *gw_addr = NULL;
|
struct nl_addr *gw_addr = NULL;
|
||||||
struct in6_addr dst;
|
|
||||||
int iface_idx, err = -1;
|
int iface_idx, err = -1;
|
||||||
|
|
||||||
g_return_val_if_fail (iface != NULL, -ENODEV);
|
g_return_val_if_fail (iface != NULL, -ENODEV);
|
||||||
@@ -1015,31 +1013,28 @@ replace_default_ip6_route (const char *iface, const struct in6_addr *gw)
|
|||||||
rtnl_route_set_scope (route, RT_SCOPE_UNIVERSE);
|
rtnl_route_set_scope (route, RT_SCOPE_UNIVERSE);
|
||||||
rtnl_route_set_oif (route, iface_idx);
|
rtnl_route_set_oif (route, iface_idx);
|
||||||
|
|
||||||
/* Build up the destination address */
|
if (gw && !IN6_IS_ADDR_UNSPECIFIED (gw)) {
|
||||||
memset (&dst, 0, sizeof (dst));
|
|
||||||
dst_addr = nl_addr_build (AF_INET6, &dst, sizeof (dst));
|
|
||||||
if (!dst_addr) {
|
|
||||||
err = -ENOMEM;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
nl_addr_set_prefixlen (dst_addr, 0);
|
|
||||||
rtnl_route_set_dst (route, dst_addr);
|
|
||||||
|
|
||||||
/* Build up the gateway address */
|
/* Build up the gateway address */
|
||||||
gw_addr = nl_addr_build (AF_INET6, (void *) gw, sizeof (*gw));
|
gw_addr = nl_addr_build (AF_INET6, (void *) gw, sizeof (*gw));
|
||||||
if (!gw_addr) {
|
if (!gw_addr) {
|
||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
nl_addr_set_prefixlen (gw_addr, 0);
|
nl_addr_set_prefixlen (gw_addr, -1);
|
||||||
rtnl_route_set_gateway (route, gw_addr);
|
rtnl_route_set_gateway (route, gw_addr);
|
||||||
|
}
|
||||||
|
|
||||||
/* Add the new default route */
|
/* Add the new default route */
|
||||||
err = rtnl_route_add (nlh, route, NLM_F_REPLACE);
|
err = rtnl_route_add (nlh, route, NLM_F_REPLACE);
|
||||||
|
if (err == -EEXIST) {
|
||||||
|
/* FIXME: even though we use NLM_F_REPLACE the kernel won't replace
|
||||||
|
* the route if it's the same. Should try to remove it first, then
|
||||||
|
* add the new one again here.
|
||||||
|
*/
|
||||||
|
err = 0;
|
||||||
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (dst_addr)
|
|
||||||
nl_addr_put (dst_addr);
|
|
||||||
if (gw_addr)
|
if (gw_addr)
|
||||||
nl_addr_put (gw_addr);
|
nl_addr_put (gw_addr);
|
||||||
rtnl_route_put (route);
|
rtnl_route_put (route);
|
||||||
|
Reference in New Issue
Block a user