mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-02-05 12:20:36 +01:00
cleanup: remove unused netlink/system code
This commit is contained in:
parent
70916c79eb
commit
393346b4fc
5 changed files with 0 additions and 1167 deletions
|
|
@ -237,8 +237,6 @@ nm_sources = \
|
|||
nm-manager.h \
|
||||
nm-netlink-monitor.c \
|
||||
nm-netlink-monitor.h \
|
||||
nm-netlink-utils.c \
|
||||
nm-netlink-utils.h \
|
||||
nm-policy-hosts.c \
|
||||
nm-policy-hosts.h \
|
||||
nm-policy.c \
|
||||
|
|
|
|||
|
|
@ -1,476 +0,0 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||
/* NetworkManager -- Network link manager
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright (C) 2011 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#include "nm-logging.h"
|
||||
#include "nm-platform.h"
|
||||
#include "nm-netlink-utils.h"
|
||||
#include "nm-netlink-monitor.h"
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netlink/route/addr.h>
|
||||
|
||||
typedef struct {
|
||||
int ifindex;
|
||||
int family;
|
||||
void *addr;
|
||||
int addrlen;
|
||||
int prefix;
|
||||
gboolean found;
|
||||
} FindAddrInfo;
|
||||
|
||||
static void
|
||||
find_one_address (struct nl_object *object, void *user_data)
|
||||
{
|
||||
FindAddrInfo *info = user_data;
|
||||
struct rtnl_addr *addr = (struct rtnl_addr *) object;
|
||||
struct nl_addr *local;
|
||||
void *binaddr;
|
||||
|
||||
if (info->found)
|
||||
return;
|
||||
|
||||
if (rtnl_addr_get_ifindex (addr) != info->ifindex)
|
||||
return;
|
||||
if (rtnl_addr_get_family (addr) != info->family)
|
||||
return;
|
||||
|
||||
if (rtnl_addr_get_prefixlen (addr) != info->prefix)
|
||||
return;
|
||||
|
||||
local = rtnl_addr_get_local (addr);
|
||||
if (nl_addr_get_family (local) != info->family)
|
||||
return;
|
||||
if (nl_addr_get_len (local) != info->addrlen)
|
||||
return;
|
||||
binaddr = nl_addr_get_binary_addr (local);
|
||||
if (binaddr) {
|
||||
if (memcmp (binaddr, info->addr, info->addrlen) == 0)
|
||||
info->found = TRUE; /* Yay, found it */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_netlink_find_address:
|
||||
* @ifindex: interface index
|
||||
* @family: address family, either AF_INET or AF_INET6
|
||||
* @addr: binary address, either struct in_addr* or struct in6_addr*
|
||||
* @prefix: prefix length
|
||||
*
|
||||
* Searches for a matching address on the given interface.
|
||||
*
|
||||
* Returns: %TRUE if the given address was found on the interface, %FALSE if it
|
||||
* was not found or an error occurred.
|
||||
**/
|
||||
gboolean
|
||||
nm_netlink_find_address (int ifindex,
|
||||
int family,
|
||||
void *addr, /* struct in_addr or struct in6_addr */
|
||||
int prefix)
|
||||
{
|
||||
struct nl_sock *nlh = NULL;
|
||||
struct nl_cache *cache = NULL;
|
||||
FindAddrInfo info;
|
||||
|
||||
g_return_val_if_fail (ifindex > 0, FALSE);
|
||||
g_return_val_if_fail (family == AF_INET || family == AF_INET6, FALSE);
|
||||
g_return_val_if_fail (addr != NULL, FALSE);
|
||||
g_return_val_if_fail (prefix >= 0, FALSE);
|
||||
|
||||
memset (&info, 0, sizeof (info));
|
||||
info.ifindex = ifindex;
|
||||
info.family = family;
|
||||
info.prefix = prefix;
|
||||
info.addr = addr;
|
||||
if (family == AF_INET)
|
||||
info.addrlen = sizeof (struct in_addr);
|
||||
else if (family == AF_INET6)
|
||||
info.addrlen = sizeof (struct in6_addr);
|
||||
else
|
||||
g_assert_not_reached ();
|
||||
|
||||
nlh = nm_netlink_get_default_handle ();
|
||||
if (nlh) {
|
||||
rtnl_addr_alloc_cache(nlh, &cache);
|
||||
if (cache) {
|
||||
nl_cache_mngt_provide (cache);
|
||||
nl_cache_foreach (cache, find_one_address, &info);
|
||||
nl_cache_free (cache);
|
||||
}
|
||||
}
|
||||
return info.found;
|
||||
}
|
||||
|
||||
struct rtnl_route *
|
||||
nm_netlink_route_new (int ifindex,
|
||||
int family,
|
||||
int mss,
|
||||
...)
|
||||
{
|
||||
va_list var_args;
|
||||
struct rtnl_route *route;
|
||||
struct rtnl_nexthop *nexthop;
|
||||
NmNlProp prop = NMNL_PROP_INVALID;
|
||||
int value;
|
||||
|
||||
route = rtnl_route_alloc ();
|
||||
g_return_val_if_fail (route != NULL, NULL);
|
||||
|
||||
if (ifindex > 0) {
|
||||
nexthop = rtnl_route_nh_alloc();
|
||||
rtnl_route_nh_set_ifindex (nexthop, ifindex);
|
||||
rtnl_route_add_nexthop (route, nexthop);
|
||||
}
|
||||
if (family != AF_UNSPEC)
|
||||
rtnl_route_set_family (route, family);
|
||||
if (mss > 0)
|
||||
rtnl_route_set_metric (route, RTAX_ADVMSS, mss);
|
||||
|
||||
va_start (var_args, mss);
|
||||
prop = va_arg (var_args, NmNlProp);
|
||||
while (prop != NMNL_PROP_INVALID) {
|
||||
value = va_arg (var_args, int);
|
||||
|
||||
if (prop == NMNL_PROP_PROT && value != RTPROT_UNSPEC)
|
||||
rtnl_route_set_protocol (route, value);
|
||||
else if (prop == NMNL_PROP_TABLE && value != RT_TABLE_UNSPEC)
|
||||
rtnl_route_set_table (route, value);
|
||||
else if (prop == NMNL_PROP_SCOPE && value != RT_SCOPE_NOWHERE)
|
||||
rtnl_route_set_scope (route, value);
|
||||
else if (prop == NMNL_PROP_PRIO && value > 0)
|
||||
rtnl_route_set_priority (route, value);
|
||||
|
||||
prop = va_arg (var_args, NmNlProp);
|
||||
}
|
||||
va_end (var_args);
|
||||
|
||||
return route;
|
||||
}
|
||||
|
||||
/**
|
||||
* _route_add:
|
||||
* @route: the route to add
|
||||
* @family: address family, either %AF_INET or %AF_INET6
|
||||
* @dest: the route destination address, either a struct in_addr or a struct
|
||||
* in6_addr depending on @family
|
||||
* @dest_prefix: the CIDR prefix of @dest
|
||||
* @gateway: the gateway through which to reach @dest, if any; given as a
|
||||
* struct in_addr or struct in6_addr depending on @family
|
||||
* @flags: flags to pass to rtnl_route_add(), eg %NLM_F_REPLACE
|
||||
*
|
||||
* Returns: zero if succeeded or the netlink error otherwise.
|
||||
**/
|
||||
static int
|
||||
_route_add (struct rtnl_route *route,
|
||||
int family,
|
||||
const void *dest, /* in_addr or in6_addr */
|
||||
int dest_prefix,
|
||||
const void *gateway, /* in_addr or in6_addr */
|
||||
int flags)
|
||||
{
|
||||
struct nl_sock *sk;
|
||||
struct nl_addr *dest_addr, *gw_addr;
|
||||
void *tmp_addr;
|
||||
int addrlen, err, log;
|
||||
|
||||
if (family == AF_INET) {
|
||||
addrlen = sizeof (struct in_addr);
|
||||
log = LOGD_IP4;
|
||||
} else if (family == AF_INET6) {
|
||||
addrlen = sizeof (struct in6_addr);
|
||||
log = LOGD_IP6;
|
||||
} else
|
||||
g_assert_not_reached ();
|
||||
|
||||
sk = nm_netlink_get_default_handle ();
|
||||
|
||||
/* Build up the destination address */
|
||||
if (dest) {
|
||||
/* Copy to preserve const */
|
||||
tmp_addr = g_malloc0 (addrlen);
|
||||
memcpy (tmp_addr, dest, addrlen);
|
||||
|
||||
dest_addr = nl_addr_build (family, tmp_addr, addrlen);
|
||||
g_free (tmp_addr);
|
||||
|
||||
g_return_val_if_fail (dest_addr != NULL, -NLE_INVAL);
|
||||
nl_addr_set_prefixlen (dest_addr, dest_prefix);
|
||||
|
||||
rtnl_route_set_dst (route, dest_addr);
|
||||
nl_addr_put (dest_addr);
|
||||
}
|
||||
|
||||
/* Build up the gateway address */
|
||||
if (gateway) {
|
||||
tmp_addr = g_malloc0 (addrlen);
|
||||
memcpy (tmp_addr, gateway, addrlen);
|
||||
|
||||
gw_addr = nl_addr_build (family, tmp_addr, addrlen);
|
||||
g_free (tmp_addr);
|
||||
|
||||
if (gw_addr) {
|
||||
nl_addr_set_prefixlen (gw_addr, 0);
|
||||
if (rtnl_route_get_nnexthops (route) == 1)
|
||||
rtnl_route_nh_set_gateway (rtnl_route_nexthop_n (route, 0), gw_addr);
|
||||
else
|
||||
nm_log_warn (LOGD_DEVICE, "Netlink didn't have exactly one nexthop.");
|
||||
rtnl_route_set_scope (route, RT_SCOPE_UNIVERSE);
|
||||
nl_addr_put (gw_addr);
|
||||
} else
|
||||
nm_log_err (LOGD_DEVICE | log, "Invalid gateway");
|
||||
}
|
||||
|
||||
err = rtnl_route_add (sk, route, flags);
|
||||
|
||||
/* LIBNL Bug: Aliased ESRCH */
|
||||
if (err == -NLE_FAILURE)
|
||||
err = -NLE_OBJ_NOTFOUND;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_netlink_route4_add:
|
||||
* @route: the route to add
|
||||
* @dest: the route destination address in network byte order
|
||||
* @dest_prefix: the CIDR prefix of @dest
|
||||
* @gateway: the gateway through which to reach @dest, if any, in network byte order
|
||||
* @flags: flags to pass to rtnl_route_add(), eg %NLM_F_REPLACE
|
||||
*
|
||||
* Adds an IPv4 route with the given parameters.
|
||||
*
|
||||
* Returns: zero if succeeded or the netlink error otherwise.
|
||||
**/
|
||||
int
|
||||
nm_netlink_route4_add (struct rtnl_route *route,
|
||||
guint32 *dst,
|
||||
int prefix,
|
||||
guint32 *gw,
|
||||
int flags)
|
||||
{
|
||||
return _route_add (route, AF_INET, dst, prefix, gw, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_netlink_route6_add:
|
||||
* @route: the route to add
|
||||
* @dest: the route destination address
|
||||
* @dest_prefix: the CIDR prefix of @dest
|
||||
* @gateway: the gateway through which to reach @dest, if any
|
||||
* @flags: flags to pass to rtnl_route_add(), eg %NLM_F_REPLACE
|
||||
*
|
||||
* Adds an IPv6 route with the given parameters.
|
||||
*
|
||||
* Returns: zero if succeeded or the netlink error otherwise.
|
||||
**/
|
||||
int
|
||||
nm_netlink_route6_add (struct rtnl_route *route,
|
||||
const struct in6_addr *dst,
|
||||
int prefix,
|
||||
const struct in6_addr *gw,
|
||||
int flags)
|
||||
{
|
||||
return _route_add (route, AF_INET6, dst, prefix, gw, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_netlink_route_delete:
|
||||
* @route: the route to delete
|
||||
*
|
||||
* Returns: %TRUE if the request was successful, %FALSE if it failed
|
||||
**/
|
||||
gboolean
|
||||
nm_netlink_route_delete (struct rtnl_route *route)
|
||||
{
|
||||
struct nl_sock *nlh;
|
||||
int err = 0;
|
||||
|
||||
g_return_val_if_fail (route != NULL, FALSE);
|
||||
|
||||
nlh = nm_netlink_get_default_handle ();
|
||||
err = rtnl_route_delete (nlh, route, 0);
|
||||
|
||||
if (err)
|
||||
nm_log_dbg (LOGD_IP4 | LOGD_IP6, "%s (%d)", nl_geterror(err), err);
|
||||
|
||||
/* Workaround libnl BUG: ESRCH is aliased to generic NLE_FAILURE
|
||||
* See: http://git.kernel.org/?p=libs/netlink/libnl.git;a=commit;h=7e9d5f */
|
||||
if (err == -NLE_FAILURE)
|
||||
err = -NLE_OBJ_NOTFOUND;
|
||||
|
||||
return (err && (err != -NLE_OBJ_NOTFOUND) && (err != -NLE_RANGE) ) ? FALSE : TRUE;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
dump_route (struct rtnl_route *route)
|
||||
{
|
||||
char buf6[INET6_ADDRSTRLEN];
|
||||
char buf4[INET_ADDRSTRLEN];
|
||||
struct nl_addr *nl;
|
||||
struct in6_addr *addr6 = NULL;
|
||||
struct in_addr *addr4 = NULL;
|
||||
int prefixlen = 0;
|
||||
const char *sf = "UNSPEC";
|
||||
int family = rtnl_route_get_family (route);
|
||||
guint32 log_level = LOGD_IP4 | LOGD_IP6;
|
||||
|
||||
memset (buf6, 0, sizeof (buf6));
|
||||
memset (buf4, 0, sizeof (buf4));
|
||||
nl = rtnl_route_get_dst (route);
|
||||
if (nl) {
|
||||
if (nl_addr_get_family (nl) == AF_INET) {
|
||||
addr4 = nl_addr_get_binary_addr (nl);
|
||||
if (addr4)
|
||||
inet_ntop (AF_INET, addr4, &buf4[0], sizeof (buf4));
|
||||
} else if (nl_addr_get_family (nl) == AF_INET6) {
|
||||
addr6 = nl_addr_get_binary_addr (nl);
|
||||
if (addr6)
|
||||
inet_ntop (AF_INET6, addr6, &buf6[0], sizeof (buf6));
|
||||
}
|
||||
prefixlen = nl_addr_get_prefixlen (nl);
|
||||
}
|
||||
|
||||
if (family == AF_INET) {
|
||||
sf = "INET";
|
||||
log_level = LOGD_IP4;
|
||||
} else if (family == AF_INET6) {
|
||||
sf = "INET6";
|
||||
log_level = LOGD_IP6;
|
||||
}
|
||||
|
||||
nm_log_dbg (log_level, " route idx %d family %s (%d) addr %s/%d",
|
||||
rtnl_route_nh_get_ifindex (rtnl_route_nexthop_n (route, 0)),
|
||||
sf, family,
|
||||
strlen (buf4) ? buf4 : (strlen (buf6) ? buf6 : "<unknown>"),
|
||||
prefixlen);
|
||||
}
|
||||
|
||||
|
||||
typedef struct {
|
||||
int ifindex;
|
||||
int family;
|
||||
int scope;
|
||||
gboolean ignore_inet6_ll_mc;
|
||||
char *iface;
|
||||
NlRouteForeachFunc callback;
|
||||
gpointer user_data;
|
||||
struct rtnl_route *out_route;
|
||||
} ForeachRouteInfo;
|
||||
|
||||
static void
|
||||
foreach_route_cb (struct nl_object *object, void *user_data)
|
||||
{
|
||||
ForeachRouteInfo *info = user_data;
|
||||
struct rtnl_route *route = (struct rtnl_route *) object;
|
||||
struct nl_addr *dst;
|
||||
|
||||
if (info->out_route)
|
||||
return;
|
||||
|
||||
/* Only care about single-nexthop routes */
|
||||
if (rtnl_route_get_nnexthops (route) != 1)
|
||||
return;
|
||||
|
||||
if (nm_logging_level_enabled (LOGL_DEBUG))
|
||||
dump_route (route);
|
||||
|
||||
if ( info->ifindex > 0
|
||||
&& rtnl_route_nh_get_ifindex (rtnl_route_nexthop_n (route, 0)) != info->ifindex)
|
||||
return;
|
||||
|
||||
if ( info->scope != RT_SCOPE_UNIVERSE
|
||||
&& rtnl_route_get_scope (route) != info->scope)
|
||||
return;
|
||||
|
||||
if ( info->family != AF_UNSPEC
|
||||
&& rtnl_route_get_family (route) != info->family)
|
||||
return;
|
||||
|
||||
dst = rtnl_route_get_dst (route);
|
||||
|
||||
/* Check for IPv6 LL and MC routes that might need to be ignored */
|
||||
if ( (info->family == AF_INET6 || info->family == AF_UNSPEC)
|
||||
&& (rtnl_route_get_family (route) == AF_INET6)) {
|
||||
struct in6_addr *addr = NULL;
|
||||
|
||||
if (dst)
|
||||
addr = nl_addr_get_binary_addr (dst);
|
||||
if (addr) {
|
||||
if ( IN6_IS_ADDR_LINKLOCAL (addr)
|
||||
|| IN6_IS_ADDR_MC_LINKLOCAL (addr)
|
||||
|| (IN6_IS_ADDR_MULTICAST (addr) && (nl_addr_get_prefixlen (dst) == 8)))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
info->out_route = info->callback (route, dst, info->iface, info->user_data);
|
||||
if (info->out_route) {
|
||||
/* Ref the route so it sticks around after the cache is cleared */
|
||||
rtnl_route_get (info->out_route);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_netlink_foreach_route:
|
||||
* @ifindex: the interface index to filter routes for
|
||||
* @family: the address family to filter routes for
|
||||
* @scope: route scope, eg RT_SCOPE_LINK
|
||||
* @ignore_inet6_ll_mc: if %TRUE ignore IPv6 link-local and multi-cast routes
|
||||
* @callback: function called when a route matches the filter
|
||||
* @user_data: data passed to @callback
|
||||
*
|
||||
* Filters each route in the routing table against the given @ifindex and
|
||||
* @family (if given) and calls @callback for each matching route.
|
||||
*
|
||||
* Returns: a route if @callback returned one; the caller must dispose of the
|
||||
* route using rtnl_route_put() when it is no longer required.
|
||||
**/
|
||||
struct rtnl_route *
|
||||
nm_netlink_foreach_route (int ifindex,
|
||||
int family,
|
||||
int scope,
|
||||
gboolean ignore_inet6_ll_mc,
|
||||
NlRouteForeachFunc callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
struct nl_cache *cache;
|
||||
ForeachRouteInfo info;
|
||||
|
||||
memset (&info, 0, sizeof (info));
|
||||
info.ifindex = ifindex;
|
||||
info.family = family;
|
||||
info.scope = scope;
|
||||
info.ignore_inet6_ll_mc = ignore_inet6_ll_mc;
|
||||
info.callback = callback;
|
||||
info.user_data = user_data;
|
||||
info.iface = g_strdup (nm_platform_link_get_name (ifindex));
|
||||
|
||||
rtnl_route_alloc_cache (nm_netlink_get_default_handle (), family, 0, &cache);
|
||||
g_warn_if_fail (cache != NULL);
|
||||
if (cache) {
|
||||
nl_cache_foreach (cache, foreach_route_cb, &info);
|
||||
nl_cache_free (cache);
|
||||
}
|
||||
g_free (info.iface);
|
||||
return info.out_route;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,83 +0,0 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||
/* NetworkManager -- Network link manager
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright (C) 2011 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef NM_NETLINK_UTILS_H
|
||||
#define NM_NETLINK_UTILS_H
|
||||
|
||||
#include <netlink/route/route.h>
|
||||
|
||||
gboolean nm_netlink_find_address (int ifindex,
|
||||
int family,
|
||||
void *addr, /* struct in_addr or struct in6_addr */
|
||||
int prefix_);
|
||||
|
||||
typedef enum {
|
||||
NMNL_PROP_INVALID = 0,
|
||||
NMNL_PROP_PROT,
|
||||
NMNL_PROP_SCOPE,
|
||||
NMNL_PROP_TABLE,
|
||||
NMNL_PROP_PRIO,
|
||||
} NmNlProp;
|
||||
|
||||
struct rtnl_route * nm_netlink_route_new (int ifindex,
|
||||
int family,
|
||||
int mss,
|
||||
...) __attribute__((__sentinel__));
|
||||
|
||||
int nm_netlink_route4_add (struct rtnl_route *route,
|
||||
guint32 *dst,
|
||||
int prefix,
|
||||
guint32 *gw,
|
||||
int flags);
|
||||
|
||||
int nm_netlink_route6_add (struct rtnl_route *route,
|
||||
const struct in6_addr *dst,
|
||||
int prefix,
|
||||
const struct in6_addr *gw,
|
||||
int flags);
|
||||
|
||||
gboolean nm_netlink_route_delete (struct rtnl_route *route);
|
||||
|
||||
/**
|
||||
* NlRouteForeachFunc:
|
||||
* @route: the route being processed
|
||||
* @dst: the route's destination address
|
||||
* @iface: the interface name of the index passed to nm_netlink_foreach_route()
|
||||
* @in_family: the address family passed to nm_netlink_foreach_route()
|
||||
* @user_data: the user data pointer passed to nm_netlink_foreach_route()
|
||||
*
|
||||
* Returns: a route to return to the caller of nm_netlink_foreach_route() which
|
||||
* terminates routing table iteration, or NULL to continue iterating the
|
||||
* routing table.
|
||||
**/
|
||||
typedef struct rtnl_route * (*NlRouteForeachFunc) (struct rtnl_route *route,
|
||||
struct nl_addr *dst,
|
||||
const char *iface,
|
||||
gpointer user_data);
|
||||
|
||||
struct rtnl_route * nm_netlink_foreach_route (int ifindex,
|
||||
int family,
|
||||
int scope,
|
||||
gboolean ignore_inet6_ll_mc,
|
||||
NlRouteForeachFunc callback,
|
||||
gpointer user_data);
|
||||
|
||||
#endif /* NM_NETLINK_UTILS_H */
|
||||
|
||||
568
src/nm-system.c
568
src/nm-system.c
|
|
@ -42,9 +42,6 @@
|
|||
#include <glib.h>
|
||||
#include <linux/if.h>
|
||||
#include <linux/sockios.h>
|
||||
#include <linux/if_bonding.h>
|
||||
#include <linux/if_vlan.h>
|
||||
#include <linux/if_bridge.h>
|
||||
|
||||
#include "nm-system.h"
|
||||
#include "nm-platform.h"
|
||||
|
|
@ -52,20 +49,6 @@
|
|||
#include "NetworkManagerUtils.h"
|
||||
#include "nm-utils.h"
|
||||
#include "nm-logging.h"
|
||||
#include "nm-netlink-monitor.h"
|
||||
#include "nm-netlink-utils.h"
|
||||
|
||||
#include <netlink/route/addr.h>
|
||||
#include <netlink/route/route.h>
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/utils.h>
|
||||
#include <netlink/route/link.h>
|
||||
#include <netlink/route/link/bonding.h>
|
||||
#include <netlink/route/link/vlan.h>
|
||||
|
||||
static void nm_system_device_set_priority (int ifindex,
|
||||
NMIP4Config *config,
|
||||
int priority);
|
||||
|
||||
static gboolean
|
||||
ip4_dest_in_same_subnet (NMIP4Config *config, guint32 dest, guint32 dest_prefix)
|
||||
|
|
@ -230,61 +213,6 @@ nm_system_apply_ip4_config (int ifindex,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
int
|
||||
nm_system_set_ip6_route (int ifindex,
|
||||
const struct in6_addr *ip6_dest,
|
||||
guint32 ip6_prefix,
|
||||
const struct in6_addr *ip6_gateway,
|
||||
guint32 metric,
|
||||
int mss,
|
||||
int protocol,
|
||||
int table,
|
||||
struct rtnl_route **out_route)
|
||||
{
|
||||
struct nl_sock *nlh;
|
||||
struct rtnl_route *route;
|
||||
int err = 0;
|
||||
|
||||
g_return_val_if_fail (ifindex > 0, -1);
|
||||
|
||||
nlh = nm_netlink_get_default_handle ();
|
||||
g_return_val_if_fail (nlh != NULL, -1);
|
||||
|
||||
route = nm_netlink_route_new (ifindex, AF_INET6, mss,
|
||||
NMNL_PROP_PROT, protocol,
|
||||
NMNL_PROP_PRIO, metric,
|
||||
NMNL_PROP_TABLE, table,
|
||||
NULL);
|
||||
g_return_val_if_fail (route != NULL, -1);
|
||||
|
||||
/* Add the route */
|
||||
err = nm_netlink_route6_add (route, ip6_dest, ip6_prefix, ip6_gateway, 0);
|
||||
if (err == -NLE_OBJ_NOTFOUND && ip6_gateway) {
|
||||
/* Gateway might be over a bridge; try adding a route to gateway first */
|
||||
struct rtnl_route *route2;
|
||||
|
||||
route2 = nm_netlink_route_new (ifindex, AF_INET6, mss, NULL);
|
||||
if (route2) {
|
||||
err = nm_netlink_route6_add (route, ip6_gateway, 128, NULL, 0);
|
||||
/* Add route to gateway over bridge */
|
||||
if (!err) {
|
||||
/* Try adding the route again */
|
||||
err = nm_netlink_route6_add (route, ip6_dest, ip6_prefix, ip6_gateway, 0);
|
||||
if (err)
|
||||
nm_netlink_route_delete (route2);
|
||||
}
|
||||
rtnl_route_put (route2);
|
||||
}
|
||||
}
|
||||
|
||||
if (out_route)
|
||||
*out_route = route;
|
||||
else
|
||||
rtnl_route_put (route);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ip6_dest_in_same_subnet (NMIP6Config *config, const struct in6_addr *dest, guint32 dest_prefix)
|
||||
{
|
||||
|
|
@ -460,502 +388,6 @@ nm_system_apply_ip6_config (int ifindex,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static struct rtnl_route *
|
||||
add_ip4_route_to_gateway (int ifindex, guint32 gw, guint32 mss)
|
||||
{
|
||||
struct nl_sock *nlh;
|
||||
struct rtnl_route *route = NULL;
|
||||
int err;
|
||||
|
||||
nlh = nm_netlink_get_default_handle ();
|
||||
g_return_val_if_fail (nlh != NULL, NULL);
|
||||
|
||||
/* Gateway might be over a bridge; try adding a route to gateway first */
|
||||
route = nm_netlink_route_new (ifindex, AF_INET, mss,
|
||||
NMNL_PROP_SCOPE, RT_SCOPE_LINK,
|
||||
NMNL_PROP_TABLE, RT_TABLE_MAIN,
|
||||
NULL);
|
||||
g_return_val_if_fail (route != NULL, NULL);
|
||||
|
||||
/* Add direct route to the gateway */
|
||||
err = nm_netlink_route4_add (route, &gw, 32, NULL, 0);
|
||||
if (err) {
|
||||
nm_log_err (LOGD_DEVICE | LOGD_IP4,
|
||||
"(%s): failed to add IPv4 route to gateway (%d)",
|
||||
nm_platform_link_get_name (ifindex), err);
|
||||
goto error;
|
||||
}
|
||||
|
||||
return route;
|
||||
|
||||
error:
|
||||
rtnl_route_put (route);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
replace_default_ip4_route (int ifindex, guint32 gw, guint32 mss)
|
||||
{
|
||||
struct rtnl_route *route = NULL;
|
||||
struct nl_sock *nlh;
|
||||
int err = -1;
|
||||
guint32 dst = 0;
|
||||
|
||||
g_return_val_if_fail (ifindex > 0, -ENODEV);
|
||||
|
||||
nlh = nm_netlink_get_default_handle ();
|
||||
g_return_val_if_fail (nlh != NULL, -ENOMEM);
|
||||
|
||||
route = nm_netlink_route_new (ifindex, AF_INET, mss,
|
||||
NMNL_PROP_SCOPE, RT_SCOPE_UNIVERSE,
|
||||
NMNL_PROP_TABLE, RT_TABLE_MAIN,
|
||||
NULL);
|
||||
g_return_val_if_fail (route != NULL, -ENOMEM);
|
||||
|
||||
/* Add the new default route */
|
||||
err = nm_netlink_route4_add (route, &dst, 0, &gw, NLM_F_REPLACE);
|
||||
if (err == -NLE_EXIST)
|
||||
err = 0;
|
||||
|
||||
rtnl_route_put (route);
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* nm_system_replace_default_ip4_route_vpn
|
||||
*
|
||||
* Replace default IPv4 route with one via the current device
|
||||
*
|
||||
*/
|
||||
gboolean
|
||||
nm_system_replace_default_ip4_route_vpn (int ifindex,
|
||||
guint32 ext_gw,
|
||||
guint32 int_gw,
|
||||
guint32 mss,
|
||||
int parent_ifindex,
|
||||
guint32 parent_mss)
|
||||
{
|
||||
struct rtnl_route *gw_route = NULL;
|
||||
struct nl_sock *nlh;
|
||||
gboolean success = FALSE;
|
||||
int err;
|
||||
const char *iface;
|
||||
|
||||
nlh = nm_netlink_get_default_handle ();
|
||||
g_return_val_if_fail (nlh != NULL, FALSE);
|
||||
|
||||
err = replace_default_ip4_route (ifindex, int_gw, mss);
|
||||
if (err == 0)
|
||||
return TRUE;
|
||||
|
||||
iface = nm_platform_link_get_name (ifindex);
|
||||
if (!iface)
|
||||
goto out;
|
||||
|
||||
if ((err != -NLE_OBJ_NOTFOUND) && (err != -NLE_FAILURE)) {
|
||||
nm_log_err (LOGD_DEVICE | LOGD_VPN | LOGD_IP4,
|
||||
"(%s): failed to set IPv4 default route: %d",
|
||||
iface, err);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Try adding a direct route to the gateway first */
|
||||
gw_route = add_ip4_route_to_gateway (parent_ifindex, ext_gw, parent_mss);
|
||||
if (!gw_route)
|
||||
goto out;
|
||||
|
||||
/* Try adding the original route again */
|
||||
err = replace_default_ip4_route (ifindex, int_gw, mss);
|
||||
if (err != 0) {
|
||||
nm_netlink_route_delete (gw_route);
|
||||
nm_log_err (LOGD_DEVICE | LOGD_VPN | LOGD_IP4,
|
||||
"(%s): failed to set IPv4 default route (pass #2): %d",
|
||||
iface, err);
|
||||
} else
|
||||
success = TRUE;
|
||||
|
||||
out:
|
||||
if (gw_route)
|
||||
rtnl_route_put (gw_route);
|
||||
return success;
|
||||
}
|
||||
|
||||
/*
|
||||
* nm_system_replace_default_ip4_route
|
||||
*
|
||||
* Replace default IPv4 route with one via the current device
|
||||
*
|
||||
*/
|
||||
gboolean
|
||||
nm_system_replace_default_ip4_route (int ifindex, guint32 gw, guint32 mss)
|
||||
{
|
||||
struct rtnl_route *gw_route = NULL;
|
||||
gboolean success = FALSE;
|
||||
const char *iface;
|
||||
int err;
|
||||
|
||||
err = replace_default_ip4_route (ifindex, gw, mss);
|
||||
if (err == 0)
|
||||
return TRUE;
|
||||
|
||||
iface = nm_platform_link_get_name (ifindex);
|
||||
if (!iface)
|
||||
goto out;
|
||||
|
||||
if (err != -NLE_OBJ_NOTFOUND) {
|
||||
nm_log_err (LOGD_DEVICE | LOGD_IP4,
|
||||
"(%s): failed to set IPv4 default route: %d",
|
||||
iface, err);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Try adding a direct route to the gateway first */
|
||||
gw_route = add_ip4_route_to_gateway (ifindex, gw, mss);
|
||||
if (!gw_route)
|
||||
goto out;
|
||||
|
||||
/* Try adding the original route again */
|
||||
err = replace_default_ip4_route (ifindex, gw, mss);
|
||||
if (err != 0) {
|
||||
nm_netlink_route_delete (gw_route);
|
||||
nm_log_err (LOGD_DEVICE | LOGD_IP4,
|
||||
"(%s): failed to set IPv4 default route (pass #2): %d",
|
||||
iface, err);
|
||||
} else
|
||||
success = TRUE;
|
||||
|
||||
out:
|
||||
if (gw_route)
|
||||
rtnl_route_put (gw_route);
|
||||
return success;
|
||||
}
|
||||
|
||||
static struct rtnl_route *
|
||||
add_ip6_route_to_gateway (int ifindex, const struct in6_addr *gw, int mss)
|
||||
{
|
||||
struct nl_sock *nlh;
|
||||
struct rtnl_route *route = NULL;
|
||||
int err;
|
||||
|
||||
nlh = nm_netlink_get_default_handle ();
|
||||
g_return_val_if_fail (nlh != NULL, NULL);
|
||||
|
||||
/* Gateway might be over a bridge; try adding a route to gateway first */
|
||||
route = nm_netlink_route_new (ifindex, AF_INET6, mss,
|
||||
NMNL_PROP_SCOPE, RT_SCOPE_LINK,
|
||||
NMNL_PROP_TABLE, RT_TABLE_MAIN,
|
||||
NULL);
|
||||
g_return_val_if_fail (route != NULL, NULL);
|
||||
|
||||
/* Add direct route to the gateway */
|
||||
err = nm_netlink_route6_add (route, gw, 128, NULL, 0);
|
||||
if (err) {
|
||||
nm_log_err (LOGD_DEVICE | LOGD_IP6,
|
||||
"(%s): failed to add IPv6 route to gateway (%d)",
|
||||
nm_platform_link_get_name (ifindex), err);
|
||||
|
||||
rtnl_route_put (route);
|
||||
route = NULL;
|
||||
}
|
||||
|
||||
return route;
|
||||
}
|
||||
|
||||
static int
|
||||
add_default_ip6_route (int ifindex, const struct in6_addr *gw, int mss)
|
||||
{
|
||||
struct rtnl_route *route = NULL;
|
||||
struct nl_sock *nlh;
|
||||
int err = -1;
|
||||
|
||||
g_return_val_if_fail (ifindex > 0, FALSE);
|
||||
|
||||
nlh = nm_netlink_get_default_handle ();
|
||||
g_return_val_if_fail (nlh != NULL, -ENOMEM);
|
||||
|
||||
route = nm_netlink_route_new (ifindex, AF_INET6, mss,
|
||||
NMNL_PROP_SCOPE, RT_SCOPE_UNIVERSE,
|
||||
NMNL_PROP_TABLE, RT_TABLE_MAIN,
|
||||
NMNL_PROP_PRIO, 1,
|
||||
NULL);
|
||||
g_return_val_if_fail (route != NULL, -ENOMEM);
|
||||
|
||||
/* Add the new default route */
|
||||
err = nm_netlink_route6_add (route, &in6addr_any, 0, gw, NLM_F_CREATE | NLM_F_REPLACE);
|
||||
if (err == -NLE_EXIST)
|
||||
err = 0;
|
||||
|
||||
rtnl_route_put (route);
|
||||
return err;
|
||||
}
|
||||
|
||||
static struct rtnl_route *
|
||||
find_static_default_routes (struct rtnl_route *route,
|
||||
struct nl_addr *dst,
|
||||
const char *iface,
|
||||
gpointer user_data)
|
||||
{
|
||||
GList **def_routes = user_data;
|
||||
|
||||
if ( nl_addr_get_prefixlen (dst) == 0
|
||||
&& rtnl_route_get_protocol (route) == RTPROT_STATIC) {
|
||||
rtnl_route_get (route);
|
||||
*def_routes = g_list_prepend (*def_routes, route);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
replace_default_ip6_route (int ifindex, const struct in6_addr *gw, int mss)
|
||||
{
|
||||
GList *def_routes, *iter;
|
||||
struct rtnl_route *route;
|
||||
char gw_str[INET6_ADDRSTRLEN + 1];
|
||||
|
||||
g_return_val_if_fail (ifindex > 0, FALSE);
|
||||
|
||||
if (nm_logging_level_enabled (LOGL_DEBUG)) {
|
||||
if (gw) {
|
||||
memset (gw_str, 0, sizeof (gw_str));
|
||||
if (inet_ntop (AF_INET6, gw, gw_str, sizeof (gw_str) - 1))
|
||||
nm_log_dbg (LOGD_IP6, "Setting IPv6 default route via %s", gw_str);
|
||||
} else {
|
||||
nm_log_dbg (LOGD_IP6, "Setting IPv6 default route via %s",
|
||||
nm_platform_link_get_name (ifindex));
|
||||
}
|
||||
}
|
||||
|
||||
/* We can't just use NLM_F_REPLACE here like in the IPv4 case, because
|
||||
* the kernel doesn't like it if we replace the default routes it
|
||||
* creates. (See rh#785772.) So we delete any non-kernel default routes,
|
||||
* and then add a new default route of our own with a lower metric than
|
||||
* the kernel ones.
|
||||
*/
|
||||
def_routes = NULL;
|
||||
nm_netlink_foreach_route (ifindex, AF_INET6, RT_SCOPE_UNIVERSE, TRUE,
|
||||
find_static_default_routes, &def_routes);
|
||||
for (iter = def_routes; iter; iter = iter->next) {
|
||||
route = iter->data;
|
||||
if (!nm_netlink_route_delete (route)) {
|
||||
nm_log_err (LOGD_DEVICE | LOGD_IP6,
|
||||
"(%s): failed to delete existing IPv6 default route",
|
||||
nm_platform_link_get_name (ifindex));
|
||||
}
|
||||
rtnl_route_put (route);
|
||||
}
|
||||
g_list_free (def_routes);
|
||||
|
||||
return add_default_ip6_route (ifindex, gw, mss);
|
||||
}
|
||||
|
||||
/*
|
||||
* nm_system_replace_default_ip6_route
|
||||
*
|
||||
* Replace default IPv6 route with one via the given gateway
|
||||
*
|
||||
*/
|
||||
gboolean
|
||||
nm_system_replace_default_ip6_route (int ifindex, const struct in6_addr *gw)
|
||||
{
|
||||
struct rtnl_route *gw_route = NULL;
|
||||
gboolean success = FALSE;
|
||||
const char *iface;
|
||||
int err;
|
||||
|
||||
err = replace_default_ip6_route (ifindex, gw, 0);
|
||||
if (err == 0 || err == -NLE_EXIST)
|
||||
return TRUE;
|
||||
|
||||
iface = nm_platform_link_get_name (ifindex);
|
||||
if (!iface)
|
||||
goto out;
|
||||
|
||||
if (err != -NLE_OBJ_NOTFOUND) {
|
||||
nm_log_err (LOGD_DEVICE | LOGD_IP6,
|
||||
"(%s): failed to set IPv6 default route: %d",
|
||||
iface, err);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Try adding a direct route to the gateway first */
|
||||
gw_route = add_ip6_route_to_gateway (ifindex, gw, 0);
|
||||
if (!gw_route)
|
||||
goto out;
|
||||
|
||||
/* Try adding the original route again */
|
||||
err = replace_default_ip6_route (ifindex, gw, 0);
|
||||
if (err != 0) {
|
||||
nm_netlink_route_delete (gw_route);
|
||||
nm_log_err (LOGD_DEVICE | LOGD_IP6,
|
||||
"(%s): failed to set IPv6 default route (pass #2): %d",
|
||||
iface, err);
|
||||
} else
|
||||
success = TRUE;
|
||||
|
||||
out:
|
||||
if (gw_route)
|
||||
rtnl_route_put (gw_route);
|
||||
return success;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_system_replace_default_ip6_route_vpn (int ifindex,
|
||||
const struct in6_addr *ext_gw,
|
||||
const struct in6_addr *int_gw,
|
||||
guint32 mss,
|
||||
int parent_ifindex,
|
||||
guint32 parent_mss)
|
||||
{
|
||||
struct rtnl_route *gw_route = NULL;
|
||||
struct nl_sock *nlh;
|
||||
gboolean success = FALSE;
|
||||
int err;
|
||||
const char *iface;
|
||||
|
||||
nlh = nm_netlink_get_default_handle ();
|
||||
g_return_val_if_fail (nlh != NULL, FALSE);
|
||||
|
||||
err = replace_default_ip6_route (ifindex, int_gw, mss);
|
||||
if (err == 0)
|
||||
return TRUE;
|
||||
|
||||
iface = nm_platform_link_get_name (ifindex);
|
||||
if (!iface)
|
||||
goto out;
|
||||
|
||||
if ((err != -NLE_OBJ_NOTFOUND) && (err != -NLE_FAILURE)) {
|
||||
nm_log_err (LOGD_DEVICE | LOGD_VPN | LOGD_IP6,
|
||||
"(%s): failed to set IPv6 default route: %d",
|
||||
iface, err);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Try adding a direct route to the gateway first */
|
||||
gw_route = add_ip6_route_to_gateway (parent_ifindex, ext_gw, parent_mss);
|
||||
if (!gw_route)
|
||||
goto out;
|
||||
|
||||
/* Try adding the original route again */
|
||||
err = replace_default_ip6_route (ifindex, int_gw, mss);
|
||||
if (err != 0) {
|
||||
nm_netlink_route_delete (gw_route);
|
||||
nm_log_err (LOGD_DEVICE | LOGD_VPN | LOGD_IP6,
|
||||
"(%s): failed to set IPv6 default route (pass #2): %d",
|
||||
iface, err);
|
||||
} else
|
||||
success = TRUE;
|
||||
|
||||
out:
|
||||
if (gw_route)
|
||||
rtnl_route_put (gw_route);
|
||||
return success;
|
||||
}
|
||||
|
||||
static struct rtnl_route *
|
||||
delete_one_route (struct rtnl_route *route,
|
||||
struct nl_addr *dst,
|
||||
const char *iface,
|
||||
gpointer user_data)
|
||||
{
|
||||
guint32 log_level = GPOINTER_TO_UINT (user_data);
|
||||
|
||||
nm_log_dbg (log_level, " deleting route");
|
||||
if (!nm_netlink_route_delete (route))
|
||||
nm_log_err (LOGD_DEVICE, "(%s): failed to delete route", iface);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_system_iface_flush_routes:
|
||||
* @ifindex: interface index
|
||||
* @family: address family, i.e. AF_INET, AF_INET6, or AF_UNSPEC
|
||||
*
|
||||
* Flush all network addresses associated with a network device.
|
||||
*
|
||||
* Returns: %TRUE on success, %FALSE on failure
|
||||
**/
|
||||
gboolean
|
||||
nm_system_iface_flush_routes (int ifindex, int family)
|
||||
{
|
||||
guint32 log_level = LOGD_IP4 | LOGD_IP6;
|
||||
const char *sf = "UNSPEC";
|
||||
const char *iface;
|
||||
|
||||
g_return_val_if_fail (ifindex > 0, FALSE);
|
||||
|
||||
iface = nm_platform_link_get_name (ifindex);
|
||||
g_return_val_if_fail (iface != NULL, FALSE);
|
||||
|
||||
if (family == AF_INET) {
|
||||
log_level = LOGD_IP4;
|
||||
sf = "INET";
|
||||
} else if (family == AF_INET6) {
|
||||
log_level = LOGD_IP6;
|
||||
sf = "INET6";
|
||||
}
|
||||
nm_log_dbg (log_level, "(%s): flushing routes ifindex %d family %s (%d)",
|
||||
iface, ifindex, sf, family);
|
||||
|
||||
/* We don't want to flush IPv6 link-local routes that may exist on the
|
||||
* the interface since the LL address and routes should normally stay
|
||||
* assigned all the time.
|
||||
*/
|
||||
nm_netlink_foreach_route (ifindex, family, RT_SCOPE_UNIVERSE, TRUE, delete_one_route, GUINT_TO_POINTER (log_level));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static struct rtnl_route *
|
||||
find_route (struct rtnl_route *route,
|
||||
struct nl_addr *dst,
|
||||
const char *iface,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMIP4Config *config = user_data;
|
||||
struct in_addr *dst_addr;
|
||||
int num;
|
||||
int i;
|
||||
|
||||
if (dst && (nl_addr_get_family (dst) != AF_INET))
|
||||
return NULL;
|
||||
|
||||
/* Find the first route that handles a subnet of at least one of the
|
||||
* device's IPv4 addresses.
|
||||
*/
|
||||
dst_addr = nl_addr_get_binary_addr (dst);
|
||||
num = nm_ip4_config_get_num_addresses (config);
|
||||
for (i = 0; i < num; i++) {
|
||||
NMIP4Address *addr = nm_ip4_config_get_address (config, i);
|
||||
guint32 prefix = nm_ip4_address_get_prefix (addr);
|
||||
guint32 address = nm_ip4_address_get_address (addr);
|
||||
|
||||
if ( prefix == nl_addr_get_prefixlen (dst)
|
||||
&& (address & nm_utils_ip4_prefix_to_netmask (prefix)) == dst_addr->s_addr)
|
||||
return route;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
nm_system_device_set_priority (int ifindex,
|
||||
NMIP4Config *config,
|
||||
int priority)
|
||||
{
|
||||
struct nl_sock *nlh;
|
||||
struct rtnl_route *found;
|
||||
|
||||
found = nm_netlink_foreach_route (ifindex, AF_INET, RT_SCOPE_LINK, FALSE, find_route, config);
|
||||
if (found) {
|
||||
nlh = nm_netlink_get_default_handle ();
|
||||
nm_netlink_route_delete (found);
|
||||
rtnl_route_set_priority (found, priority);
|
||||
rtnl_route_add (nlh, found, 0);
|
||||
rtnl_route_put (found);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct {
|
||||
const char *option;
|
||||
const char *default_value;
|
||||
|
|
|
|||
|
|
@ -22,59 +22,21 @@
|
|||
#ifndef NETWORK_MANAGER_SYSTEM_H
|
||||
#define NETWORK_MANAGER_SYSTEM_H
|
||||
|
||||
#include <glib.h>
|
||||
#include <netlink/route/route.h>
|
||||
|
||||
#include "nm-platform.h"
|
||||
#include "nm-device.h"
|
||||
#include "nm-ip4-config.h"
|
||||
#include "nm-setting-bond.h"
|
||||
|
||||
gboolean nm_system_iface_flush_routes (int ifindex, int family);
|
||||
|
||||
gboolean nm_system_replace_default_ip4_route (int ifindex,
|
||||
guint32 gw,
|
||||
guint32 mss);
|
||||
|
||||
gboolean nm_system_replace_default_ip6_route (int ifindex,
|
||||
const struct in6_addr *gw);
|
||||
|
||||
gboolean nm_system_replace_default_ip4_route_vpn (int ifindex,
|
||||
guint32 ext_gw,
|
||||
guint32 int_gw,
|
||||
guint32 mss,
|
||||
int parent_ifindex,
|
||||
guint32 parent_mss);
|
||||
|
||||
gboolean nm_system_replace_default_ip6_route_vpn (int ifindex,
|
||||
const struct in6_addr *ext_gw,
|
||||
const struct in6_addr *int_gw,
|
||||
guint32 mss,
|
||||
int parent_ifindex,
|
||||
guint32 parent_mss);
|
||||
|
||||
NMPlatformIP4Route *nm_system_add_ip4_vpn_gateway_route (NMDevice *parent_device,
|
||||
guint32 vpn_gw);
|
||||
NMPlatformIP6Route *nm_system_add_ip6_vpn_gateway_route (NMDevice *parent_device,
|
||||
const struct in6_addr *vpn_gw);
|
||||
|
||||
gboolean nm_system_iface_flush_addresses (int ifindex, int family);
|
||||
|
||||
gboolean nm_system_apply_ip4_config (int ifindex,
|
||||
NMIP4Config *config,
|
||||
int priority,
|
||||
NMIP4ConfigCompareFlags flags);
|
||||
|
||||
int nm_system_set_ip6_route (int ifindex,
|
||||
const struct in6_addr *ip6_dest,
|
||||
guint32 ip6_prefix,
|
||||
const struct in6_addr *ip6_gateway,
|
||||
guint32 metric,
|
||||
int mss,
|
||||
int protocol,
|
||||
int table,
|
||||
struct rtnl_route **out_route);
|
||||
|
||||
gboolean nm_system_apply_ip6_config (int ifindex,
|
||||
NMIP6Config *config,
|
||||
int priority,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue