mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-07-22 18:54:36 +00:00
merge: branch 'lr/rp-filter'
https://bugzilla.gnome.org/show_bug.cgi?id=780155
This commit is contained in:
commit
edaa7d064e
|
@ -339,6 +339,8 @@ typedef struct _NMDevicePrivate {
|
|||
NMPlatformIP4Route v4;
|
||||
NMPlatformIP6Route v6;
|
||||
} default_route;
|
||||
bool v4_has_shadowed_routes;
|
||||
const char *ip4_rp_filter;
|
||||
|
||||
/* DHCPv4 tracking */
|
||||
struct {
|
||||
|
@ -704,6 +706,38 @@ init_ip6_config_dns_priority (NMDevice *self, NMIP6Config *config)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
static gboolean
|
||||
nm_device_ipv4_sysctl_set (NMDevice *self, const char *property, const char *value)
|
||||
{
|
||||
NMPlatform *platform = NM_PLATFORM_GET;
|
||||
gs_free char *value_to_free = NULL;
|
||||
const char *value_to_set;
|
||||
|
||||
if (value) {
|
||||
value_to_set = value;
|
||||
} else {
|
||||
/* Set to a default value when we've got a NULL @value. */
|
||||
value_to_free = nm_platform_sysctl_get (platform,
|
||||
NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_ip4_property_path ("default", property)));
|
||||
value_to_set = value_to_free;
|
||||
}
|
||||
|
||||
return nm_platform_sysctl_set (platform,
|
||||
NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_ip4_property_path (nm_device_get_ip_iface (self), property)),
|
||||
value_to_set);
|
||||
}
|
||||
|
||||
static guint32
|
||||
nm_device_ipv4_sysctl_get_uint32 (NMDevice *self, const char *property, guint32 fallback)
|
||||
{
|
||||
return nm_platform_sysctl_get_int_checked (NM_PLATFORM_GET,
|
||||
NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_ip4_property_path (nm_device_get_ip_iface (self), property)),
|
||||
10,
|
||||
0,
|
||||
G_MAXUINT32,
|
||||
fallback);
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_device_ipv6_sysctl_set (NMDevice *self, const char *property, const char *value)
|
||||
{
|
||||
|
@ -2361,6 +2395,45 @@ link_changed_cb (NMPlatform *platform,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ip4_rp_filter_update (NMDevice *self)
|
||||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
const char *ip4_rp_filter;
|
||||
|
||||
if ( priv->v4_has_shadowed_routes
|
||||
|| priv->default_route.v4_has) {
|
||||
if (nm_device_ipv4_sysctl_get_uint32 (self, "rp_filter", 0) != 1) {
|
||||
/* Don't touch the rp_filter if it's not strict. */
|
||||
return;
|
||||
}
|
||||
/* Loose rp_filter */
|
||||
ip4_rp_filter = "2";
|
||||
} else {
|
||||
/* Default rp_filter */
|
||||
ip4_rp_filter = NULL;
|
||||
}
|
||||
|
||||
if (ip4_rp_filter != priv->ip4_rp_filter) {
|
||||
nm_device_ipv4_sysctl_set (self, "rp_filter", ip4_rp_filter);
|
||||
priv->ip4_rp_filter = ip4_rp_filter;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ip4_routes_changed_changed_cb (NMRouteManager *route_manager, NMDevice *self)
|
||||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
int ifindex = nm_device_get_ip_ifindex (self);
|
||||
|
||||
if (nm_device_sys_iface_state_is_external_or_assume (self))
|
||||
return;
|
||||
|
||||
priv->v4_has_shadowed_routes = nm_route_manager_ip4_routes_shadowed (route_manager,
|
||||
ifindex);
|
||||
ip4_rp_filter_update (self);
|
||||
}
|
||||
|
||||
static void
|
||||
link_changed (NMDevice *self, const NMPlatformLink *pllink)
|
||||
{
|
||||
|
@ -9410,6 +9483,8 @@ nm_device_set_ip4_config (NMDevice *self,
|
|||
}
|
||||
|
||||
nm_default_route_manager_ip4_update_default_route (nm_default_route_manager_get (), self);
|
||||
if (!nm_device_sys_iface_state_is_external_or_assume (self))
|
||||
ip4_rp_filter_update (self);
|
||||
|
||||
if (has_changes) {
|
||||
NMSettingsConnection *settings_connection;
|
||||
|
@ -13343,6 +13418,9 @@ constructed (GObject *object)
|
|||
g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED, G_CALLBACK (device_ipx_changed), self);
|
||||
g_signal_connect (platform, NM_PLATFORM_SIGNAL_LINK_CHANGED, G_CALLBACK (link_changed_cb), self);
|
||||
|
||||
g_signal_connect (nm_route_manager_get (), NM_ROUTE_MANAGER_IP4_ROUTES_CHANGED,
|
||||
G_CALLBACK (ip4_routes_changed_changed_cb), self);
|
||||
|
||||
priv->settings = g_object_ref (NM_SETTINGS_GET);
|
||||
g_assert (priv->settings);
|
||||
|
||||
|
@ -13381,6 +13459,9 @@ dispose (GObject *object)
|
|||
g_signal_handlers_disconnect_by_func (platform, G_CALLBACK (device_ipx_changed), self);
|
||||
g_signal_handlers_disconnect_by_func (platform, G_CALLBACK (link_changed_cb), self);
|
||||
|
||||
g_signal_handlers_disconnect_by_func (nm_route_manager_get (),
|
||||
G_CALLBACK (ip4_routes_changed_changed_cb), self);
|
||||
|
||||
g_slist_free_full (priv->arping.dad_list, (GDestroyNotify) nm_arping_manager_destroy);
|
||||
priv->arping.dad_list = NULL;
|
||||
|
||||
|
|
|
@ -63,6 +63,12 @@ typedef struct {
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
enum {
|
||||
IP4_ROUTES_CHANGED,
|
||||
LAST_SIGNAL,
|
||||
};
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
NM_GOBJECT_PROPERTIES_DEFINE_BASE (
|
||||
PROP_PLATFORM,
|
||||
);
|
||||
|
@ -904,6 +910,9 @@ next:
|
|||
}
|
||||
}
|
||||
|
||||
if (vtable->vt->is_ip4 && ipx_routes_changed)
|
||||
g_signal_emit (self, signals[IP4_ROUTES_CHANGED], 0);
|
||||
|
||||
g_free (known_routes_idx);
|
||||
g_free (plat_routes_idx);
|
||||
g_array_unref (plat_routes);
|
||||
|
@ -967,6 +976,33 @@ nm_route_manager_route_flush (NMRouteManager *self, int ifindex)
|
|||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_route_manager_ip4_routes_shadowed:
|
||||
* @ifindex: Interface index
|
||||
*
|
||||
* Returns: %TRUE if some other link has a route to the same destination
|
||||
* with a lower metric.
|
||||
*/
|
||||
gboolean
|
||||
nm_route_manager_ip4_routes_shadowed (NMRouteManager *self, int ifindex)
|
||||
{
|
||||
NMRouteManagerPrivate *priv = NM_ROUTE_MANAGER_GET_PRIVATE (self);
|
||||
RouteIndex *index = priv->ip4_routes.index;
|
||||
const NMPlatformIP4Route *route;
|
||||
guint i;
|
||||
|
||||
for (i = 1; i < index->len; i++) {
|
||||
route = (const NMPlatformIP4Route *) index->entries[i];
|
||||
|
||||
if (route->ifindex != ifindex)
|
||||
continue;
|
||||
if (_v4_route_dest_cmp (route, (const NMPlatformIP4Route *) index->entries[i - 1]) == 0)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static gboolean
|
||||
|
@ -1258,4 +1294,11 @@ nm_route_manager_class_init (NMRouteManagerClass *klass)
|
|||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
|
||||
|
||||
signals[IP4_ROUTES_CHANGED] =
|
||||
g_signal_new (NM_ROUTE_MANAGER_IP4_ROUTES_CHANGED,
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
0, NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
}
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
|
||||
#define NM_ROUTE_MANAGER_PLATFORM "platform"
|
||||
|
||||
#define NM_ROUTE_MANAGER_IP4_ROUTES_CHANGED "ip4-routes-changed"
|
||||
|
||||
typedef struct _NMRouteManagerClass NMRouteManagerClass;
|
||||
|
||||
GType nm_route_manager_get_type (void);
|
||||
|
@ -38,6 +40,7 @@ gboolean nm_route_manager_ip4_route_sync (NMRouteManager *self, int ifindex, con
|
|||
gboolean nm_route_manager_ip6_route_sync (NMRouteManager *self, int ifindex, const GArray *known_routes, gboolean ignore_kernel_routes, gboolean full_sync);
|
||||
gboolean nm_route_manager_route_flush (NMRouteManager *self, int ifindex);
|
||||
|
||||
gboolean nm_route_manager_ip4_routes_shadowed (NMRouteManager *self, int ifindex);
|
||||
void nm_route_manager_ip4_route_register_device_route_purge_list (NMRouteManager *self, GArray *device_route_purge_list);
|
||||
|
||||
NMRouteManager *nm_route_manager_get (void);
|
||||
|
|
Loading…
Reference in a new issue