mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-25 04:50:07 +01:00
all: merge branch 'th/platform-routes-onlink-rh1428334'
https://bugzilla.redhat.com/show_bug.cgi?id=1428334
This commit is contained in:
commit
d44a3eb80c
22 changed files with 570 additions and 296 deletions
|
|
@ -2104,6 +2104,7 @@ EXTRA_DIST += \
|
|||
src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wifi_LEAP.cexpected \
|
||||
src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wifi_WEP_104_ASCII.cexpected \
|
||||
src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wired_Auto-Negotiate.cexpected \
|
||||
src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wired_Static_Routes.cexpected \
|
||||
src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wired_Wake-on-LAN.cexpected \
|
||||
src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Vlan_test-vlan-interface.cexpected \
|
||||
src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-dcb-test.cexpected \
|
||||
|
|
|
|||
16
configure.ac
16
configure.ac
|
|
@ -1227,6 +1227,22 @@ fi
|
|||
|
||||
AC_SUBST(SANITIZERS, [$sanitizers])
|
||||
|
||||
AC_MSG_CHECKING([CC support C11 _Generic()])
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[int foo(void); int foo() { int a = 0; int b = _Generic (a, int: 4); return b + a; }]],
|
||||
[[foo();]])],
|
||||
[cc_support_generic=1],
|
||||
[cc_support_generic=0])
|
||||
AC_MSG_RESULT($cc_support_generic)
|
||||
AC_DEFINE_UNQUOTED(_NM_CC_SUPPORT_GENERIC, $cc_support_generic, [Define whether the compiler supports C11 _Generic()])
|
||||
|
||||
AC_MSG_CHECKING([CC support gcc __auto_type])
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[int foo(void); int foo() { int a = 0; __auto_type b = a; return b + a; }]],
|
||||
[[foo();]])],
|
||||
[cc_support_auto_type=1],
|
||||
[cc_support_auto_type=0])
|
||||
AC_MSG_RESULT($cc_support_auto_type)
|
||||
AC_DEFINE_UNQUOTED(_NM_CC_SUPPORT_AUTO_TYPE, $cc_support_auto_type, [Define whether the compiler support gcc __auto_type])
|
||||
|
||||
dnl -------------------------
|
||||
dnl Vala bindings
|
||||
dnl -------------------------
|
||||
|
|
|
|||
|
|
@ -1245,6 +1245,7 @@ static const NMVariantAttributeSpec * const ip_route_attribute_spec[] = {
|
|||
ATTR_SPEC_PTR (NM_IP_ROUTE_ATTRIBUTE_SRC, G_VARIANT_TYPE_STRING, TRUE, TRUE, 'a'),
|
||||
ATTR_SPEC_PTR (NM_IP_ROUTE_ATTRIBUTE_FROM, G_VARIANT_TYPE_STRING, FALSE, TRUE, 'p'),
|
||||
ATTR_SPEC_PTR (NM_IP_ROUTE_ATTRIBUTE_TOS, G_VARIANT_TYPE_BYTE, TRUE, FALSE, 0 ),
|
||||
ATTR_SPEC_PTR (NM_IP_ROUTE_ATTRIBUTE_ONLINK, G_VARIANT_TYPE_BOOLEAN, TRUE, FALSE, 0 ),
|
||||
ATTR_SPEC_PTR (NM_IP_ROUTE_ATTRIBUTE_WINDOW, G_VARIANT_TYPE_UINT32, TRUE, TRUE, 0 ),
|
||||
ATTR_SPEC_PTR (NM_IP_ROUTE_ATTRIBUTE_CWND, G_VARIANT_TYPE_UINT32, TRUE, TRUE, 0 ),
|
||||
ATTR_SPEC_PTR (NM_IP_ROUTE_ATTRIBUTE_INITCWND, G_VARIANT_TYPE_UINT32, TRUE, TRUE, 0 ),
|
||||
|
|
|
|||
|
|
@ -146,6 +146,7 @@ gboolean nm_ip_route_attribute_validate (const char *name,
|
|||
#define NM_IP_ROUTE_ATTRIBUTE_SRC "src"
|
||||
#define NM_IP_ROUTE_ATTRIBUTE_FROM "from"
|
||||
#define NM_IP_ROUTE_ATTRIBUTE_TOS "tos"
|
||||
#define NM_IP_ROUTE_ATTRIBUTE_ONLINK "onlink"
|
||||
#define NM_IP_ROUTE_ATTRIBUTE_WINDOW "window"
|
||||
#define NM_IP_ROUTE_ATTRIBUTE_CWND "cwnd"
|
||||
#define NM_IP_ROUTE_ATTRIBUTE_INITCWND "initcwnd"
|
||||
|
|
|
|||
|
|
@ -263,11 +263,25 @@ NM_G_ERROR_MSG (GError *error)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
#if (defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 9 ))) || (defined (__clang__))
|
||||
#ifndef _NM_CC_SUPPORT_AUTO_TYPE
|
||||
#if (defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9 )))
|
||||
#define _NM_CC_SUPPORT_AUTO_TYPE 1
|
||||
#else
|
||||
#define _NM_CC_SUPPORT_AUTO_TYPE 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef _NM_CC_SUPPORT_GENERIC
|
||||
#if (defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9 ))) || (defined (__clang__))
|
||||
#define _NM_CC_SUPPORT_GENERIC 1
|
||||
#else
|
||||
#define _NM_CC_SUPPORT_GENERIC 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if _NM_CC_SUPPORT_AUTO_TYPE
|
||||
#define _nm_auto_type __auto_type
|
||||
#endif
|
||||
|
||||
#if _NM_CC_SUPPORT_GENERIC
|
||||
#define _NM_CONSTCAST_FULL_1(type, obj_expr, obj) \
|
||||
|
|
@ -372,6 +386,16 @@ NM_G_ERROR_MSG (GError *error)
|
|||
#define _NM_ENSURE_TYPE(type, value) (value)
|
||||
#endif
|
||||
|
||||
#if _NM_CC_SUPPORT_GENERIC
|
||||
#define NM_PROPAGATE_CONST(test_expr, ptr) \
|
||||
(_Generic ((test_expr), \
|
||||
const typeof (*(test_expr)) *: ((const typeof (*(ptr)) *) (ptr)), \
|
||||
default: (_Generic ((test_expr), \
|
||||
typeof (*(test_expr)) *: (ptr)))))
|
||||
#else
|
||||
#define NM_PROPAGATE_CONST(test_expr, ptr) (ptr)
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define _NM_IN_SET_EVAL_1( op, _x, y) (_x == (y))
|
||||
|
|
@ -651,8 +675,17 @@ _notify (obj_type *obj, _PropertyEnums prop) \
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define _NM_GET_PRIVATE( self, type, is_check, ...) (&(NM_GOBJECT_CAST_NON_NULL (type, (self), is_check, ##__VA_ARGS__)->_priv))
|
||||
#define _NM_GET_PRIVATE_PTR( self, type, is_check, ...) ( (NM_GOBJECT_CAST_NON_NULL (type, (self), is_check, ##__VA_ARGS__)->_priv))
|
||||
#define _NM_GET_PRIVATE(self, type, is_check, ...) (&(NM_GOBJECT_CAST_NON_NULL (type, (self), is_check, ##__VA_ARGS__)->_priv))
|
||||
#if _NM_CC_SUPPORT_AUTO_TYPE
|
||||
#define _NM_GET_PRIVATE_PTR(self, type, is_check, ...) \
|
||||
({ \
|
||||
_nm_auto_type _self = NM_GOBJECT_CAST_NON_NULL (type, (self), is_check, ##__VA_ARGS__); \
|
||||
\
|
||||
NM_PROPAGATE_CONST (_self, _self->_priv); \
|
||||
})
|
||||
#else
|
||||
#define _NM_GET_PRIVATE_PTR(self, type, is_check, ...) (NM_GOBJECT_CAST_NON_NULL (type, (self), is_check, ##__VA_ARGS__)->_priv)
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
|
|||
|
|
@ -26,23 +26,6 @@
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
guint8 addr_ptr[1];
|
||||
in_addr_t addr4;
|
||||
struct in6_addr addr6;
|
||||
|
||||
/* NMIPAddr is really a union for IP addresses.
|
||||
* However, as ethernet addresses fit in here nicely, use
|
||||
* it also for an ethernet MAC address. */
|
||||
guint8 addr_eth[6 /*ETH_ALEN*/];
|
||||
};
|
||||
} NMIPAddr;
|
||||
|
||||
extern const NMIPAddr nm_ip_addr_zero;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static inline char
|
||||
nm_utils_addr_family_to_char (int addr_family)
|
||||
{
|
||||
|
|
@ -68,6 +51,36 @@ nm_utils_addr_family_to_size (int addr_family)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
guint8 addr_ptr[1];
|
||||
in_addr_t addr4;
|
||||
struct in6_addr addr6;
|
||||
|
||||
/* NMIPAddr is really a union for IP addresses.
|
||||
* However, as ethernet addresses fit in here nicely, use
|
||||
* it also for an ethernet MAC address. */
|
||||
guint8 addr_eth[6 /*ETH_ALEN*/];
|
||||
};
|
||||
} NMIPAddr;
|
||||
|
||||
extern const NMIPAddr nm_ip_addr_zero;
|
||||
|
||||
static inline void
|
||||
nm_ip_addr_set (int addr_family, gpointer dst, const NMIPAddr *src)
|
||||
{
|
||||
nm_assert_addr_family (addr_family);
|
||||
nm_assert (dst);
|
||||
nm_assert (src);
|
||||
|
||||
if (addr_family != AF_INET6)
|
||||
*((in_addr_t *) dst) = src->addr4;
|
||||
else
|
||||
*((struct in6_addr *) dst) = src->addr6;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define NM_CMP_RETURN(c) \
|
||||
G_STMT_START { \
|
||||
const int _cc = (c); \
|
||||
|
|
|
|||
|
|
@ -1164,9 +1164,9 @@ nm_device_get_ip_iface (NMDevice *self)
|
|||
}
|
||||
|
||||
int
|
||||
nm_device_get_ip_ifindex (NMDevice *self)
|
||||
nm_device_get_ip_ifindex (const NMDevice *self)
|
||||
{
|
||||
NMDevicePrivate *priv;
|
||||
const NMDevicePrivate *priv;
|
||||
|
||||
g_return_val_if_fail (self != NULL, 0);
|
||||
|
||||
|
|
|
|||
|
|
@ -438,7 +438,7 @@ int nm_device_get_ifindex (NMDevice *dev);
|
|||
gboolean nm_device_is_software (NMDevice *dev);
|
||||
gboolean nm_device_is_real (NMDevice *dev);
|
||||
const char * nm_device_get_ip_iface (NMDevice *dev);
|
||||
int nm_device_get_ip_ifindex (NMDevice *dev);
|
||||
int nm_device_get_ip_ifindex (const NMDevice *dev);
|
||||
const char * nm_device_get_driver (NMDevice *dev);
|
||||
const char * nm_device_get_driver_version (NMDevice *dev);
|
||||
const char * nm_device_get_type_desc (NMDevice *dev);
|
||||
|
|
|
|||
|
|
@ -806,44 +806,87 @@ nm_ip4_config_commit (const NMIP4Config *self,
|
|||
return success;
|
||||
}
|
||||
|
||||
static void
|
||||
merge_route_attributes (NMIPRoute *s_route,
|
||||
NMPlatformIP4Route *r,
|
||||
guint32 route_table)
|
||||
void
|
||||
_nm_ip_config_merge_route_attributes (int addr_family,
|
||||
NMIPRoute *s_route,
|
||||
NMPlatformIPRoute *r,
|
||||
guint32 route_table)
|
||||
{
|
||||
GVariant *variant;
|
||||
guint32 u32;
|
||||
in_addr_t addr;
|
||||
guint32 table;
|
||||
NMIPAddr addr;
|
||||
NMPlatformIP4Route *r4 = (NMPlatformIP4Route *) r;
|
||||
NMPlatformIP6Route *r6 = (NMPlatformIP6Route *) r;
|
||||
gboolean onlink;
|
||||
|
||||
#define GET_ATTR(name, field, variant_type, type) \
|
||||
variant = nm_ip_route_get_attribute (s_route, name); \
|
||||
if (variant && g_variant_is_of_type (variant, G_VARIANT_TYPE_ ## variant_type)) \
|
||||
r->field = g_variant_get_ ## type (variant);
|
||||
nm_assert (s_route);
|
||||
nm_assert_addr_family (addr_family);
|
||||
nm_assert (r);
|
||||
|
||||
variant = nm_ip_route_get_attribute (s_route, NM_IP_ROUTE_ATTRIBUTE_TABLE);
|
||||
u32 = variant && g_variant_is_of_type (variant, G_VARIANT_TYPE_UINT32)
|
||||
? g_variant_get_uint32 (variant)
|
||||
: 0;
|
||||
r->table_coerced = nm_platform_route_table_coerce (u32 ?: (route_table ?: RT_TABLE_MAIN));
|
||||
#define GET_ATTR(name, dst, variant_type, type, dflt) \
|
||||
G_STMT_START { \
|
||||
GVariant *_variant = nm_ip_route_get_attribute (s_route, ""name""); \
|
||||
\
|
||||
if ( _variant \
|
||||
&& g_variant_is_of_type (_variant, G_VARIANT_TYPE_ ## variant_type)) \
|
||||
(dst) = g_variant_get_ ## type (_variant); \
|
||||
else \
|
||||
(dst) = (dflt); \
|
||||
} G_STMT_END
|
||||
|
||||
GET_ATTR (NM_IP_ROUTE_ATTRIBUTE_TOS, tos, BYTE, byte);
|
||||
GET_ATTR (NM_IP_ROUTE_ATTRIBUTE_WINDOW, window, UINT32, uint32);
|
||||
GET_ATTR (NM_IP_ROUTE_ATTRIBUTE_CWND, cwnd, UINT32, uint32);
|
||||
GET_ATTR (NM_IP_ROUTE_ATTRIBUTE_INITCWND, initcwnd, UINT32, uint32);
|
||||
GET_ATTR (NM_IP_ROUTE_ATTRIBUTE_INITRWND, initrwnd, UINT32, uint32);
|
||||
GET_ATTR (NM_IP_ROUTE_ATTRIBUTE_MTU, mtu, UINT32, uint32);
|
||||
GET_ATTR (NM_IP_ROUTE_ATTRIBUTE_LOCK_WINDOW, lock_window, BOOLEAN, boolean);
|
||||
GET_ATTR (NM_IP_ROUTE_ATTRIBUTE_LOCK_CWND, lock_cwnd, BOOLEAN, boolean);
|
||||
GET_ATTR (NM_IP_ROUTE_ATTRIBUTE_LOCK_INITCWND, lock_initcwnd, BOOLEAN, boolean);
|
||||
GET_ATTR (NM_IP_ROUTE_ATTRIBUTE_LOCK_INITRWND, lock_initrwnd, BOOLEAN, boolean);
|
||||
GET_ATTR (NM_IP_ROUTE_ATTRIBUTE_LOCK_MTU, lock_mtu, BOOLEAN, boolean);
|
||||
GET_ATTR (NM_IP_ROUTE_ATTRIBUTE_TABLE, table, UINT32, uint32, 0);
|
||||
r->table_coerced = nm_platform_route_table_coerce (table ?: (route_table ?: RT_TABLE_MAIN));
|
||||
|
||||
if (addr_family == AF_INET) {
|
||||
GET_ATTR (NM_IP_ROUTE_ATTRIBUTE_TOS, r4->tos, BYTE, byte, 0);
|
||||
GET_ATTR (NM_IP_ROUTE_ATTRIBUTE_ONLINK, onlink, BOOLEAN, boolean, FALSE);
|
||||
} else
|
||||
onlink = FALSE;
|
||||
|
||||
r->r_rtm_flags = 0;
|
||||
if (onlink)
|
||||
r->r_rtm_flags = RTNH_F_ONLINK;
|
||||
|
||||
GET_ATTR (NM_IP_ROUTE_ATTRIBUTE_WINDOW, r->window, UINT32, uint32, 0);
|
||||
GET_ATTR (NM_IP_ROUTE_ATTRIBUTE_CWND, r->cwnd, UINT32, uint32, 0);
|
||||
GET_ATTR (NM_IP_ROUTE_ATTRIBUTE_INITCWND, r->initcwnd, UINT32, uint32, 0);
|
||||
GET_ATTR (NM_IP_ROUTE_ATTRIBUTE_INITRWND, r->initrwnd, UINT32, uint32, 0);
|
||||
GET_ATTR (NM_IP_ROUTE_ATTRIBUTE_MTU, r->mtu, UINT32, uint32, 0);
|
||||
GET_ATTR (NM_IP_ROUTE_ATTRIBUTE_LOCK_WINDOW, r->lock_window, BOOLEAN, boolean, FALSE);
|
||||
GET_ATTR (NM_IP_ROUTE_ATTRIBUTE_LOCK_CWND, r->lock_cwnd, BOOLEAN, boolean, FALSE);
|
||||
GET_ATTR (NM_IP_ROUTE_ATTRIBUTE_LOCK_INITCWND, r->lock_initcwnd, BOOLEAN, boolean, FALSE);
|
||||
GET_ATTR (NM_IP_ROUTE_ATTRIBUTE_LOCK_INITRWND, r->lock_initrwnd, BOOLEAN, boolean, FALSE);
|
||||
GET_ATTR (NM_IP_ROUTE_ATTRIBUTE_LOCK_MTU, r->lock_mtu, BOOLEAN, boolean, FALSE);
|
||||
|
||||
if ( (variant = nm_ip_route_get_attribute (s_route, NM_IP_ROUTE_ATTRIBUTE_SRC))
|
||||
&& g_variant_is_of_type (variant, G_VARIANT_TYPE_STRING)) {
|
||||
if (inet_pton (AF_INET, g_variant_get_string (variant, NULL), &addr) == 1)
|
||||
r->pref_src = addr;
|
||||
if (inet_pton (addr_family, g_variant_get_string (variant, NULL), &addr) == 1) {
|
||||
if (addr_family == AF_INET)
|
||||
r4->pref_src = addr.addr4;
|
||||
else
|
||||
r6->pref_src = addr.addr6;
|
||||
}
|
||||
}
|
||||
|
||||
if ( addr_family == AF_INET6
|
||||
&& (variant = nm_ip_route_get_attribute (s_route, NM_IP_ROUTE_ATTRIBUTE_FROM))
|
||||
&& g_variant_is_of_type (variant, G_VARIANT_TYPE_STRING)) {
|
||||
gs_free char *string = NULL;
|
||||
guint8 plen = 128;
|
||||
char *sep;
|
||||
|
||||
string = g_variant_dup_string (variant, NULL);
|
||||
sep = strchr (string, '/');
|
||||
if (sep) {
|
||||
*sep = 0;
|
||||
plen = _nm_utils_ascii_str_to_int64 (sep + 1, 10, 1, 128, 255);
|
||||
}
|
||||
if ( plen <= 128
|
||||
&& inet_pton (AF_INET6, string, &addr) == 1) {
|
||||
r6->src = addr.addr6;
|
||||
r6->src_plen = plen;
|
||||
}
|
||||
}
|
||||
#undef GET_ATTR
|
||||
}
|
||||
|
||||
|
|
@ -939,7 +982,10 @@ nm_ip4_config_merge_setting (NMIP4Config *self,
|
|||
|
||||
route.network = nm_utils_ip4_address_clear_host_address (route.network, route.plen);
|
||||
|
||||
merge_route_attributes (s_route, &route, route_table);
|
||||
_nm_ip_config_merge_route_attributes (AF_INET,
|
||||
s_route,
|
||||
NM_PLATFORM_IP_ROUTE_CAST (&route),
|
||||
route_table);
|
||||
_add_route (self, NULL, &route, NULL);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -113,6 +113,11 @@ const NMDedupMultiEntry *_nm_ip_config_lookup_ip_route (const NMDedupMultiIndex
|
|||
const NMPObject *needle,
|
||||
NMPlatformIPRouteCmpType cmp_type);
|
||||
|
||||
void _nm_ip_config_merge_route_attributes (int addr_family,
|
||||
NMIPRoute *s_route,
|
||||
NMPlatformIPRoute *r,
|
||||
guint32 route_table);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define NM_TYPE_IP4_CONFIG (nm_ip4_config_get_type ())
|
||||
|
|
@ -272,41 +277,57 @@ gboolean nm_ip4_config_equal (const NMIP4Config *a, const NMIP4Config *b);
|
|||
|
||||
#include "nm-ip6-config.h"
|
||||
|
||||
#if _NM_CC_SUPPORT_GENERIC
|
||||
#define NM_IP_CONFIG_CAST(config) \
|
||||
({ \
|
||||
const void *const _config = (config); \
|
||||
\
|
||||
nm_assert (_Generic ((config), \
|
||||
const void *: (NM_IS_IP4_CONFIG (_config) || NM_IS_IP6_CONFIG (_config)), \
|
||||
void *: (NM_IS_IP4_CONFIG (_config) || NM_IS_IP6_CONFIG (_config)), \
|
||||
const NMIPConfig *: (NM_IS_IP4_CONFIG (_config) || NM_IS_IP6_CONFIG (_config)), \
|
||||
NMIPConfig *: (NM_IS_IP4_CONFIG (_config) || NM_IS_IP6_CONFIG (_config)), \
|
||||
const NMIP4Config *: (NM_IS_IP4_CONFIG (_config)), \
|
||||
NMIP4Config *: (NM_IS_IP4_CONFIG (_config)), \
|
||||
const NMIP6Config *: (NM_IS_IP6_CONFIG (_config)), \
|
||||
NMIP6Config *: (NM_IS_IP6_CONFIG (_config)))); \
|
||||
\
|
||||
_Generic ((config), \
|
||||
const void *: ((const NMIPConfig *) _config), \
|
||||
void *: (( NMIPConfig *) _config), \
|
||||
const NMIPConfig *: ((const NMIPConfig *) _config), \
|
||||
NMIPConfig *: (( NMIPConfig *) _config), \
|
||||
const NMIP4Config *: ((const NMIPConfig *) _config), \
|
||||
NMIP4Config *: (( NMIPConfig *) _config), \
|
||||
const NMIP6Config *: ((const NMIPConfig *) _config), \
|
||||
NMIP6Config *: (( NMIPConfig *) _config)); \
|
||||
})
|
||||
#else
|
||||
#define NM_IP_CONFIG_CAST(config) ((NMIPConfig *) (config))
|
||||
#endif
|
||||
|
||||
static inline gboolean
|
||||
NM_IS_IP_CONFIG (gconstpointer config)
|
||||
{
|
||||
return NM_IS_IP4_CONFIG (config) || NM_IS_IP6_CONFIG (config);
|
||||
}
|
||||
|
||||
#if _NM_CC_SUPPORT_GENERIC
|
||||
/* _NM_IS_IP_CONFIG() is a bit unusual. If _Generic() is supported,
|
||||
* it checks whether @config is either NM_IS_IP4_CONFIG() or NM_IS_IP6_CONFIG(),
|
||||
* depending on the pointer type of @config.
|
||||
*
|
||||
* For example, with _Generic() support, the following assertions would fail:
|
||||
* NMIP6Config *ptr = (NMIP6Config *) nm_ip4_config_new(...);
|
||||
* g_assert (_NM_IS_IP_CONFIG (ptr, ptr));
|
||||
* but the following would pass:
|
||||
* NMIP4Config *ptr = nm_ip4_config_new(...);
|
||||
* g_assert (_NM_IS_IP_CONFIG (ptr, ptr));
|
||||
*/
|
||||
#define _NM_IS_IP_CONFIG(typeexpr, config) \
|
||||
({ \
|
||||
const void *const _config = (config); \
|
||||
_Generic ((typeexpr), \
|
||||
const void *const: (NM_IS_IP4_CONFIG (_config) || NM_IS_IP6_CONFIG (_config)), \
|
||||
const void * : (NM_IS_IP4_CONFIG (_config) || NM_IS_IP6_CONFIG (_config)), \
|
||||
void *const: (NM_IS_IP4_CONFIG (_config) || NM_IS_IP6_CONFIG (_config)), \
|
||||
void * : (NM_IS_IP4_CONFIG (_config) || NM_IS_IP6_CONFIG (_config)), \
|
||||
const NMIPConfig *const: (NM_IS_IP4_CONFIG (_config) || NM_IS_IP6_CONFIG (_config)), \
|
||||
const NMIPConfig * : (NM_IS_IP4_CONFIG (_config) || NM_IS_IP6_CONFIG (_config)), \
|
||||
NMIPConfig *const: (NM_IS_IP4_CONFIG (_config) || NM_IS_IP6_CONFIG (_config)), \
|
||||
NMIPConfig * : (NM_IS_IP4_CONFIG (_config) || NM_IS_IP6_CONFIG (_config)), \
|
||||
const NMIP4Config *const: (NM_IS_IP4_CONFIG (_config)), \
|
||||
const NMIP4Config * : (NM_IS_IP4_CONFIG (_config)), \
|
||||
NMIP4Config *const: (NM_IS_IP4_CONFIG (_config)), \
|
||||
NMIP4Config * : (NM_IS_IP4_CONFIG (_config)), \
|
||||
const NMIP6Config *const: (NM_IS_IP6_CONFIG (_config)), \
|
||||
const NMIP6Config * : (NM_IS_IP6_CONFIG (_config)), \
|
||||
NMIP6Config *const: (NM_IS_IP6_CONFIG (_config)), \
|
||||
NMIP6Config * : (NM_IS_IP6_CONFIG (_config))); \
|
||||
})
|
||||
#else
|
||||
#define _NM_IS_IP_CONFIG(typeexpr, config) NM_IS_IP_CONFIG(config)
|
||||
#endif
|
||||
|
||||
#define NM_IP_CONFIG_CAST(config) \
|
||||
({ \
|
||||
const void *const _configx = (config); \
|
||||
\
|
||||
nm_assert (!_configx || _NM_IS_IP_CONFIG ((config), _configx)); \
|
||||
NM_CONSTCAST_FULL (NMIPConfig, (config), _configx, NMIP4Config, NMIP6Config); \
|
||||
})
|
||||
|
||||
static inline int
|
||||
nm_ip_config_get_addr_family (const NMIPConfig *config)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -571,65 +571,6 @@ nm_ip6_config_commit (const NMIP6Config *self,
|
|||
return success;
|
||||
}
|
||||
|
||||
static void
|
||||
merge_route_attributes (NMIPRoute *s_route,
|
||||
NMPlatformIP6Route *r,
|
||||
guint32 route_table)
|
||||
{
|
||||
GVariant *variant;
|
||||
guint32 u32;
|
||||
struct in6_addr addr;
|
||||
|
||||
#define GET_ATTR(name, field, variant_type, type) \
|
||||
variant = nm_ip_route_get_attribute (s_route, name); \
|
||||
if (variant && g_variant_is_of_type (variant, G_VARIANT_TYPE_ ## variant_type)) \
|
||||
r->field = g_variant_get_ ## type (variant);
|
||||
|
||||
variant = nm_ip_route_get_attribute (s_route, NM_IP_ROUTE_ATTRIBUTE_TABLE);
|
||||
u32 = variant && g_variant_is_of_type (variant, G_VARIANT_TYPE_UINT32)
|
||||
? g_variant_get_uint32 (variant)
|
||||
: 0;
|
||||
r->table_coerced = nm_platform_route_table_coerce (u32 ?: (route_table ?: RT_TABLE_MAIN));
|
||||
|
||||
GET_ATTR (NM_IP_ROUTE_ATTRIBUTE_WINDOW, window, UINT32, uint32);
|
||||
GET_ATTR (NM_IP_ROUTE_ATTRIBUTE_CWND, cwnd, UINT32, uint32);
|
||||
GET_ATTR (NM_IP_ROUTE_ATTRIBUTE_INITCWND, initcwnd, UINT32, uint32);
|
||||
GET_ATTR (NM_IP_ROUTE_ATTRIBUTE_INITRWND, initrwnd, UINT32, uint32);
|
||||
GET_ATTR (NM_IP_ROUTE_ATTRIBUTE_MTU, mtu, UINT32, uint32);
|
||||
GET_ATTR (NM_IP_ROUTE_ATTRIBUTE_LOCK_WINDOW, lock_window, BOOLEAN, boolean);
|
||||
GET_ATTR (NM_IP_ROUTE_ATTRIBUTE_LOCK_CWND, lock_cwnd, BOOLEAN, boolean);
|
||||
GET_ATTR (NM_IP_ROUTE_ATTRIBUTE_LOCK_INITCWND, lock_initcwnd, BOOLEAN, boolean);
|
||||
GET_ATTR (NM_IP_ROUTE_ATTRIBUTE_LOCK_INITRWND, lock_initrwnd, BOOLEAN, boolean);
|
||||
GET_ATTR (NM_IP_ROUTE_ATTRIBUTE_LOCK_MTU, lock_mtu, BOOLEAN, boolean);
|
||||
|
||||
|
||||
if ( (variant = nm_ip_route_get_attribute (s_route, NM_IP_ROUTE_ATTRIBUTE_SRC))
|
||||
&& g_variant_is_of_type (variant, G_VARIANT_TYPE_STRING)) {
|
||||
if (inet_pton (AF_INET6, g_variant_get_string (variant, NULL), &addr) == 1)
|
||||
r->pref_src = addr;
|
||||
}
|
||||
|
||||
if ( (variant = nm_ip_route_get_attribute (s_route, NM_IP_ROUTE_ATTRIBUTE_FROM))
|
||||
&& g_variant_is_of_type (variant, G_VARIANT_TYPE_STRING)) {
|
||||
gs_free char *string = NULL;
|
||||
guint8 plen = 128;
|
||||
char *sep;
|
||||
|
||||
string = g_variant_dup_string (variant, NULL);
|
||||
sep = strchr (string, '/');
|
||||
if (sep) {
|
||||
*sep = 0;
|
||||
plen = _nm_utils_ascii_str_to_int64 (sep + 1, 10, 1, 128, 255);
|
||||
}
|
||||
if ( plen <= 128
|
||||
&& inet_pton (AF_INET6, string, &addr) == 1) {
|
||||
r->src = addr;
|
||||
r->src_plen = plen;
|
||||
}
|
||||
}
|
||||
#undef GET_ATTR
|
||||
}
|
||||
|
||||
void
|
||||
nm_ip6_config_merge_setting (NMIP6Config *self,
|
||||
NMSettingIPConfig *setting,
|
||||
|
|
@ -716,7 +657,10 @@ nm_ip6_config_merge_setting (NMIP6Config *self,
|
|||
|
||||
nm_utils_ip6_address_clear_host_address (&route.network, &route.network, route.plen);
|
||||
|
||||
merge_route_attributes (s_route, &route, route_table);
|
||||
_nm_ip_config_merge_route_attributes (AF_INET,
|
||||
s_route,
|
||||
NM_PLATFORM_IP_ROUTE_CAST (&route),
|
||||
route_table);
|
||||
_add_route (self, NULL, &route, NULL);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2291,17 +2291,7 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only)
|
|||
obj->ip6_route.rt_pref = nla_get_u8 (tb[RTA_PREF]);
|
||||
}
|
||||
|
||||
if (NM_FLAGS_HAS (rtm->rtm_flags, RTM_F_CLONED)) {
|
||||
/* we must not straight way reject cloned routes, because we might have cached
|
||||
* a non-cloned route. If we now receive an update of the route with the route
|
||||
* being cloned, we must still return the object, so that we can remove the old
|
||||
* one from the cache.
|
||||
*
|
||||
* This happens, because this route is not nmp_object_is_alive().
|
||||
* */
|
||||
obj->ip_route.rt_cloned = TRUE;
|
||||
}
|
||||
|
||||
obj->ip_route.r_rtm_flags = rtm->rtm_flags;
|
||||
obj->ip_route.rt_source = nmp_utils_ip_config_source_from_rtprot (rtm->rtm_protocol);
|
||||
|
||||
obj_result = obj;
|
||||
|
|
@ -2700,7 +2690,9 @@ _nl_msg_new_route (int nlmsg_type,
|
|||
? nm_platform_route_scope_inv (obj->ip4_route.scope_inv)
|
||||
: RT_SCOPE_NOWHERE,
|
||||
.rtm_type = RTN_UNICAST,
|
||||
.rtm_flags = 0,
|
||||
.rtm_flags = obj->ip_route.r_rtm_flags & (is_v4
|
||||
? (unsigned) (RTNH_F_ONLINK)
|
||||
: (unsigned) 0),
|
||||
.rtm_dst_len = obj->ip_route.plen,
|
||||
.rtm_src_len = is_v4
|
||||
? 0
|
||||
|
|
@ -4189,7 +4181,7 @@ event_valid_msg (NMPlatform *platform, struct nl_msg *msg, gboolean handle_event
|
|||
gboolean resync_required = FALSE;
|
||||
gboolean only_dirty = FALSE;
|
||||
|
||||
if (obj->ip_route.rt_cloned) {
|
||||
if (NM_FLAGS_HAS (obj->ip_route.r_rtm_flags, RTM_F_CLONED)) {
|
||||
/* a cloned route might be a response for RTM_GETROUTE. Check, whether it is. */
|
||||
nm_assert (!nmp_object_is_alive (obj));
|
||||
priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform);
|
||||
|
|
|
|||
|
|
@ -4976,6 +4976,40 @@ nm_platform_ip6_address_to_string (const NMPlatformIP6Address *address, char *bu
|
|||
return buf;
|
||||
}
|
||||
|
||||
NM_UTILS_FLAGS2STR_DEFINE_STATIC (_rtm_flags_to_string, unsigned,
|
||||
NM_UTILS_FLAGS2STR (RTNH_F_DEAD, "dead"),
|
||||
NM_UTILS_FLAGS2STR (RTNH_F_PERVASIVE, "pervasive"),
|
||||
NM_UTILS_FLAGS2STR (RTNH_F_ONLINK, "onlink"),
|
||||
NM_UTILS_FLAGS2STR (8 /*RTNH_F_OFFLOAD*/, "offload"),
|
||||
NM_UTILS_FLAGS2STR (16 /*RTNH_F_LINKDOWN*/, "linkdown"),
|
||||
NM_UTILS_FLAGS2STR (32 /*RTNH_F_UNRESOLVED*/, "unresolved"),
|
||||
|
||||
NM_UTILS_FLAGS2STR (RTM_F_NOTIFY, "notify"),
|
||||
NM_UTILS_FLAGS2STR (RTM_F_CLONED, "cloned"),
|
||||
NM_UTILS_FLAGS2STR (RTM_F_EQUALIZE, "equalize"),
|
||||
NM_UTILS_FLAGS2STR (RTM_F_PREFIX, "prefix"),
|
||||
NM_UTILS_FLAGS2STR (0x1000 /*RTM_F_LOOKUP_TABLE*/, "lookup-table"),
|
||||
NM_UTILS_FLAGS2STR (0x2000 /*RTM_F_FIB_MATCH*/, "fib-match"),
|
||||
);
|
||||
|
||||
#define _RTM_FLAGS_TO_STRING_MAXLEN 200
|
||||
|
||||
static const char *
|
||||
_rtm_flags_to_string_full (char *buf, gsize buf_size, unsigned rtm_flags)
|
||||
{
|
||||
const char *buf0 = buf;
|
||||
|
||||
nm_assert (buf_size >= _RTM_FLAGS_TO_STRING_MAXLEN);
|
||||
|
||||
if (!rtm_flags)
|
||||
return "";
|
||||
|
||||
nm_utils_strbuf_append_str (&buf, &buf_size, " rtm_flags ");
|
||||
_rtm_flags_to_string (rtm_flags, buf, buf_size);
|
||||
nm_assert (strlen (buf) < buf_size);
|
||||
return buf0;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_platform_ip4_route_to_string:
|
||||
* @route: pointer to NMPlatformIP4Route route structure
|
||||
|
|
@ -4997,6 +5031,7 @@ nm_platform_ip4_route_to_string (const NMPlatformIP4Route *route, char *buf, gsi
|
|||
char str_table[30];
|
||||
char str_scope[30], s_source[50];
|
||||
char str_tos[32], str_window[32], str_cwnd[32], str_initcwnd[32], str_initrwnd[32], str_mtu[32];
|
||||
char str_rtm_flags[_RTM_FLAGS_TO_STRING_MAXLEN];
|
||||
|
||||
if (!nm_utils_to_string_buffer_init_null (route, &buf, &len))
|
||||
return buf;
|
||||
|
|
@ -5015,7 +5050,7 @@ nm_platform_ip4_route_to_string (const NMPlatformIP4Route *route, char *buf, gsi
|
|||
" metric %"G_GUINT32_FORMAT
|
||||
" mss %"G_GUINT32_FORMAT
|
||||
" rt-src %s" /* protocol */
|
||||
"%s" /* cloned */
|
||||
"%s" /* rtm_flags */
|
||||
"%s%s" /* scope */
|
||||
"%s%s" /* pref-src */
|
||||
"%s" /* tos */
|
||||
|
|
@ -5033,7 +5068,7 @@ nm_platform_ip4_route_to_string (const NMPlatformIP4Route *route, char *buf, gsi
|
|||
route->metric,
|
||||
route->mss,
|
||||
nmp_utils_ip_config_source_to_string (route->rt_source, s_source, sizeof (s_source)),
|
||||
route->rt_cloned ? " cloned" : "",
|
||||
_rtm_flags_to_string_full (str_rtm_flags, sizeof (str_rtm_flags), route->r_rtm_flags),
|
||||
route->scope_inv ? " scope " : "",
|
||||
route->scope_inv ? (nm_platform_route_scope2str (nm_platform_route_scope_inv (route->scope_inv), str_scope, sizeof (str_scope))) : "",
|
||||
route->pref_src ? " pref-src " : "",
|
||||
|
|
@ -5069,6 +5104,7 @@ nm_platform_ip6_route_to_string (const NMPlatformIP6Route *route, char *buf, gsi
|
|||
char str_pref2[30];
|
||||
char str_dev[TO_STRING_DEV_BUF_SIZE], s_source[50];
|
||||
char str_window[32], str_cwnd[32], str_initcwnd[32], str_initrwnd[32], str_mtu[32];
|
||||
char str_rtm_flags[_RTM_FLAGS_TO_STRING_MAXLEN];
|
||||
|
||||
if (!nm_utils_to_string_buffer_init_null (route, &buf, &len))
|
||||
return buf;
|
||||
|
|
@ -5092,7 +5128,7 @@ nm_platform_ip6_route_to_string (const NMPlatformIP6Route *route, char *buf, gsi
|
|||
" mss %"G_GUINT32_FORMAT
|
||||
" rt-src %s" /* protocol */
|
||||
"%s" /* source */
|
||||
"%s" /* cloned */
|
||||
"%s" /* rtm_flags */
|
||||
"%s%s" /* pref-src */
|
||||
"%s" /* window */
|
||||
"%s" /* cwnd */
|
||||
|
|
@ -5112,7 +5148,7 @@ nm_platform_ip6_route_to_string (const NMPlatformIP6Route *route, char *buf, gsi
|
|||
route->src_plen || !IN6_IS_ADDR_UNSPECIFIED (&route->src)
|
||||
? nm_sprintf_buf (s_src_all, " src %s/%u", nm_utils_inet6_ntop (&route->src, s_src), (unsigned) route->src_plen)
|
||||
: "",
|
||||
route->rt_cloned ? " cloned" : "",
|
||||
_rtm_flags_to_string_full (str_rtm_flags, sizeof (str_rtm_flags), route->r_rtm_flags),
|
||||
s_pref_src[0] ? " pref-src " : "",
|
||||
s_pref_src[0] ? s_pref_src : "",
|
||||
route->window || route->lock_window ? nm_sprintf_buf (str_window, " window %s%"G_GUINT32_FORMAT, route->lock_window ? "lock " : "", route->window) : "",
|
||||
|
|
@ -5538,6 +5574,7 @@ nm_platform_ip4_route_hash_update (const NMPlatformIP4Route *obj, NMPlatformIPRo
|
|||
obj->initcwnd,
|
||||
obj->initrwnd,
|
||||
obj->mtu,
|
||||
obj->r_rtm_flags & RTNH_F_ONLINK,
|
||||
NM_HASH_COMBINE_BOOLS (guint8,
|
||||
obj->lock_window,
|
||||
obj->lock_cwnd,
|
||||
|
|
@ -5563,8 +5600,8 @@ nm_platform_ip4_route_hash_update (const NMPlatformIP4Route *obj, NMPlatformIPRo
|
|||
obj->initcwnd,
|
||||
obj->initrwnd,
|
||||
obj->mtu,
|
||||
obj->r_rtm_flags & (RTM_F_CLONED | RTNH_F_ONLINK),
|
||||
NM_HASH_COMBINE_BOOLS (guint8,
|
||||
obj->rt_cloned,
|
||||
obj->lock_window,
|
||||
obj->lock_cwnd,
|
||||
obj->lock_initcwnd,
|
||||
|
|
@ -5589,8 +5626,8 @@ nm_platform_ip4_route_hash_update (const NMPlatformIP4Route *obj, NMPlatformIPRo
|
|||
obj->initcwnd,
|
||||
obj->initrwnd,
|
||||
obj->mtu,
|
||||
obj->r_rtm_flags,
|
||||
NM_HASH_COMBINE_BOOLS (guint8,
|
||||
obj->rt_cloned,
|
||||
obj->lock_window,
|
||||
obj->lock_cwnd,
|
||||
obj->lock_initcwnd,
|
||||
|
|
@ -5627,6 +5664,8 @@ nm_platform_ip4_route_cmp (const NMPlatformIP4Route *a, const NMPlatformIP4Route
|
|||
NM_CMP_FIELD (a, b, initcwnd);
|
||||
NM_CMP_FIELD (a, b, initrwnd);
|
||||
NM_CMP_FIELD (a, b, mtu);
|
||||
NM_CMP_DIRECT (a->r_rtm_flags & RTNH_F_ONLINK,
|
||||
b->r_rtm_flags & RTNH_F_ONLINK);
|
||||
NM_CMP_FIELD_UNSAFE (a, b, lock_window);
|
||||
NM_CMP_FIELD_UNSAFE (a, b, lock_cwnd);
|
||||
NM_CMP_FIELD_UNSAFE (a, b, lock_initcwnd);
|
||||
|
|
@ -5660,7 +5699,11 @@ nm_platform_ip4_route_cmp (const NMPlatformIP4Route *a, const NMPlatformIP4Route
|
|||
}
|
||||
NM_CMP_FIELD (a, b, mss);
|
||||
NM_CMP_FIELD (a, b, pref_src);
|
||||
NM_CMP_FIELD_UNSAFE (a, b, rt_cloned);
|
||||
if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) {
|
||||
NM_CMP_DIRECT (a->r_rtm_flags & (RTM_F_CLONED | RTNH_F_ONLINK),
|
||||
b->r_rtm_flags & (RTM_F_CLONED | RTNH_F_ONLINK));
|
||||
} else
|
||||
NM_CMP_FIELD (a, b, r_rtm_flags);
|
||||
NM_CMP_FIELD (a, b, tos);
|
||||
NM_CMP_FIELD_UNSAFE (a, b, lock_window);
|
||||
NM_CMP_FIELD_UNSAFE (a, b, lock_cwnd);
|
||||
|
|
@ -5717,8 +5760,8 @@ nm_platform_ip6_route_hash_update (const NMPlatformIP6Route *obj, NMPlatformIPRo
|
|||
obj->src_plen,
|
||||
nmp_utils_ip_config_source_round_trip_rtprot (obj->rt_source),
|
||||
obj->mss,
|
||||
obj->r_rtm_flags & RTM_F_CLONED,
|
||||
NM_HASH_COMBINE_BOOLS (guint8,
|
||||
obj->rt_cloned,
|
||||
obj->lock_window,
|
||||
obj->lock_cwnd,
|
||||
obj->lock_initcwnd,
|
||||
|
|
@ -5744,8 +5787,8 @@ nm_platform_ip6_route_hash_update (const NMPlatformIP6Route *obj, NMPlatformIPRo
|
|||
obj->src_plen,
|
||||
obj->rt_source,
|
||||
obj->mss,
|
||||
obj->r_rtm_flags,
|
||||
NM_HASH_COMBINE_BOOLS (guint8,
|
||||
obj->rt_cloned,
|
||||
obj->lock_window,
|
||||
obj->lock_cwnd,
|
||||
obj->lock_initcwnd,
|
||||
|
|
@ -5810,7 +5853,11 @@ nm_platform_ip6_route_cmp (const NMPlatformIP6Route *a, const NMPlatformIP6Route
|
|||
NM_CMP_FIELD (a, b, rt_source);
|
||||
}
|
||||
NM_CMP_FIELD (a, b, mss);
|
||||
NM_CMP_FIELD_UNSAFE (a, b, rt_cloned);
|
||||
if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) {
|
||||
NM_CMP_DIRECT (a->r_rtm_flags & RTM_F_CLONED,
|
||||
b->r_rtm_flags & RTM_F_CLONED);
|
||||
} else
|
||||
NM_CMP_FIELD (a, b, r_rtm_flags);
|
||||
NM_CMP_FIELD_UNSAFE (a, b, lock_window);
|
||||
NM_CMP_FIELD_UNSAFE (a, b, lock_cwnd);
|
||||
NM_CMP_FIELD_UNSAFE (a, b, lock_initcwnd);
|
||||
|
|
|
|||
|
|
@ -375,13 +375,6 @@ typedef union {
|
|||
\
|
||||
guint8 plen; \
|
||||
\
|
||||
/* the route has rtm_flags set to RTM_F_CLONED. Such a route
|
||||
* is hidden by platform and does not exist from the point-of-view
|
||||
* of platform users. This flag is internal to track those hidden
|
||||
* routes. Such a route is not alive, according to nmp_object_is_alive(). */ \
|
||||
bool rt_cloned:1; \
|
||||
\
|
||||
\
|
||||
/* RTA_METRICS:
|
||||
*
|
||||
* For IPv4 routes, these properties are part of their
|
||||
|
|
@ -401,6 +394,18 @@ typedef union {
|
|||
bool lock_initrwnd:1; \
|
||||
bool lock_mtu:1; \
|
||||
\
|
||||
/* rtnh_flags
|
||||
*
|
||||
* Routes with rtm_flags RTM_F_CLONED are hidden by platform and
|
||||
* do not exist from the point-of-view of platform users.
|
||||
* Such a route is not alive, according to nmp_object_is_alive().
|
||||
*
|
||||
* XXX: currently we ignore all flags except RTM_F_CLONED
|
||||
* and RTNH_F_ONLINK for IPv4.
|
||||
* We also may not properly consider the flags as part of the ID
|
||||
* in route-cmp. */ \
|
||||
unsigned r_rtm_flags; \
|
||||
\
|
||||
/* RTA_METRICS.RTAX_ADVMSS (iproute2: advmss) */ \
|
||||
guint32 mss; \
|
||||
\
|
||||
|
|
@ -441,23 +446,11 @@ typedef struct {
|
|||
};
|
||||
} NMPlatformIPRoute;
|
||||
|
||||
#if _NM_CC_SUPPORT_GENERIC
|
||||
#define NM_PLATFORM_IP_ROUTE_CAST(route) \
|
||||
NM_CONSTCAST (NMPlatformIPRoute, (route), NMPlatformIPXRoute, NMPlatformIP4Route, NMPlatformIP6Route)
|
||||
|
||||
#define NM_PLATFORM_IP_ROUTE_IS_DEFAULT(route) \
|
||||
(_Generic ((route), \
|
||||
const NMPlatformIPRoute *: ((const NMPlatformIPRoute *) (route))->plen, \
|
||||
NMPlatformIPRoute *: ((const NMPlatformIPRoute *) (route))->plen, \
|
||||
const NMPlatformIPXRoute *: ((const NMPlatformIPRoute *) (route))->plen, \
|
||||
NMPlatformIPXRoute *: ((const NMPlatformIPRoute *) (route))->plen, \
|
||||
const NMPlatformIP4Route *: ((const NMPlatformIPRoute *) (route))->plen, \
|
||||
NMPlatformIP4Route *: ((const NMPlatformIPRoute *) (route))->plen, \
|
||||
const NMPlatformIP6Route *: ((const NMPlatformIPRoute *) (route))->plen, \
|
||||
NMPlatformIP6Route *: ((const NMPlatformIPRoute *) (route))->plen, \
|
||||
const void *: ((const NMPlatformIPRoute *) (route))->plen, \
|
||||
void *: ((const NMPlatformIPRoute *) (route))->plen) == 0)
|
||||
#else
|
||||
#define NM_PLATFORM_IP_ROUTE_IS_DEFAULT(route) \
|
||||
( ((const NMPlatformIPRoute *) (route))->plen <= 0 )
|
||||
#endif
|
||||
(NM_PLATFORM_IP_ROUTE_CAST (route)->plen <= 0)
|
||||
|
||||
struct _NMPlatformIP4Route {
|
||||
__NMPlatformIPRoute_COMMON;
|
||||
|
|
|
|||
|
|
@ -1170,7 +1170,8 @@ _vt_cmd_obj_is_alive_ipx_route (const NMPObject *obj)
|
|||
* Instead we create a dead object, and nmp_cache_update_netlink()
|
||||
* will remove the old version of the update.
|
||||
**/
|
||||
return obj->object.ifindex > 0 && !obj->ip_route.rt_cloned;
|
||||
return obj->object.ifindex > 0
|
||||
&& !NM_FLAGS_HAS (obj->ip_route.r_rtm_flags, RTM_F_CLONED);
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
|
|
|||
|
|
@ -30,6 +30,42 @@
|
|||
#define DEVICE_IFINDEX NMTSTP_ENV1_IFINDEX
|
||||
#define EX NMTSTP_ENV1_EX
|
||||
|
||||
static void
|
||||
_wait_for_ipv4_addr_device_route (NMPlatform *platform,
|
||||
gint64 timeout_ms,
|
||||
int ifindex,
|
||||
in_addr_t addr,
|
||||
guint8 plen)
|
||||
{
|
||||
/* Wait that the addresses gets a device-route. After adding a address,
|
||||
* the device route is not added immediately. It takes a moment... */
|
||||
|
||||
addr = nm_utils_ip4_address_clear_host_address (addr, plen);
|
||||
NMTST_WAIT_ASSERT (400, {
|
||||
NMDedupMultiIter iter;
|
||||
NMPLookup lookup;
|
||||
const NMPObject *o;
|
||||
|
||||
nmp_cache_iter_for_each (&iter,
|
||||
nm_platform_lookup (platform,
|
||||
nmp_lookup_init_addrroute (&lookup,
|
||||
NMP_OBJECT_TYPE_IP4_ROUTE,
|
||||
ifindex)),
|
||||
&o) {
|
||||
const NMPlatformIP4Route *r = NMP_OBJECT_CAST_IP4_ROUTE (o);
|
||||
|
||||
if ( r->plen == plen
|
||||
&& addr == nm_utils_ip4_address_clear_host_address (r->network, plen)
|
||||
&& r->metric == 0
|
||||
&& r->scope_inv == nm_platform_route_scope_inv (RT_SCOPE_LINK)
|
||||
&& r->rt_source == NM_IP_CONFIG_SOURCE_RTPROT_KERNEL)
|
||||
return;
|
||||
}
|
||||
nmtstp_assert_wait_for_signal (platform,
|
||||
(nmtst_wait_end_us - g_get_monotonic_time ()) / 1000);
|
||||
});
|
||||
}
|
||||
|
||||
static void
|
||||
_wait_for_ipv6_addr_non_tentative (NMPlatform *platform,
|
||||
gint64 timeout_ms,
|
||||
|
|
@ -44,7 +80,7 @@ _wait_for_ipv6_addr_non_tentative (NMPlatform *platform,
|
|||
* small amount of time, which prevents the immediate addition of the route
|
||||
* with RTA_PREFSRC */
|
||||
|
||||
NMTST_WAIT_ASSERT (400, {
|
||||
NMTST_WAIT_ASSERT (timeout_ms, {
|
||||
gboolean should_wait = FALSE;
|
||||
const NMPlatformIP6Address *plt_addr;
|
||||
|
||||
|
|
@ -63,7 +99,6 @@ _wait_for_ipv6_addr_non_tentative (NMPlatform *platform,
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ip4_route_callback (NMPlatform *platform, int obj_type_i, int ifindex, const NMPlatformIP4Route *received, int change_type_i, SignalData *data)
|
||||
{
|
||||
|
|
@ -417,7 +452,7 @@ test_ip_route_get (void)
|
|||
g_assert (!NMP_OBJECT_IS_STACKINIT (route));
|
||||
g_assert (route->parent._ref_count == 1);
|
||||
r = NMP_OBJECT_CAST_IP4_ROUTE (route);
|
||||
g_assert (r->rt_cloned);
|
||||
g_assert (NM_FLAGS_HAS (r->r_rtm_flags, RTM_F_CLONED));
|
||||
g_assert (r->ifindex == ifindex);
|
||||
g_assert (r->network == a);
|
||||
g_assert (r->plen == 32);
|
||||
|
|
@ -448,63 +483,114 @@ test_ip4_zero_gateway (void)
|
|||
}
|
||||
|
||||
static void
|
||||
test_ip4_route_options (void)
|
||||
test_ip4_route_options (gconstpointer test_data)
|
||||
{
|
||||
int ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME);
|
||||
NMPlatformIP4Route route = { };
|
||||
in_addr_t network;
|
||||
GPtrArray *routes;
|
||||
NMPlatformIP4Route rts[1];
|
||||
const int TEST_IDX = GPOINTER_TO_INT (test_data);
|
||||
const int IFINDEX = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME);
|
||||
gs_unref_ptrarray GPtrArray *routes = NULL;
|
||||
#define RTS_MAX 3
|
||||
NMPlatformIP4Route rts_add[RTS_MAX] = { };
|
||||
NMPlatformIP4Route rts_cmp[RTS_MAX] = { };
|
||||
NMPlatformIP4Address addr[1] = { };
|
||||
guint i;
|
||||
guint rts_n = 0;
|
||||
guint addr_n = 0;
|
||||
|
||||
inet_pton (AF_INET, "172.16.1.0", &network);
|
||||
switch (TEST_IDX) {
|
||||
case 1:
|
||||
rts_add[rts_n++] = ((NMPlatformIP4Route) {
|
||||
.ifindex = IFINDEX,
|
||||
.rt_source = NM_IP_CONFIG_SOURCE_USER,
|
||||
.network = nmtst_inet4_from_string ("172.16.1.0"),
|
||||
.plen = 24,
|
||||
.metric = 20,
|
||||
.tos = 0x28,
|
||||
.window = 10000,
|
||||
.cwnd = 16,
|
||||
.initcwnd = 30,
|
||||
.initrwnd = 50,
|
||||
.mtu = 1350,
|
||||
.lock_cwnd = TRUE,
|
||||
});
|
||||
break;
|
||||
case 2:
|
||||
addr[addr_n++] = ((NMPlatformIP4Address) {
|
||||
.ifindex = IFINDEX,
|
||||
.address = nmtst_inet4_from_string ("172.16.1.5"),
|
||||
.peer_address = nmtst_inet4_from_string ("172.16.1.5"),
|
||||
.plen = 24,
|
||||
.lifetime = NM_PLATFORM_LIFETIME_PERMANENT,
|
||||
.preferred = NM_PLATFORM_LIFETIME_PERMANENT,
|
||||
.n_ifa_flags = 0,
|
||||
});
|
||||
rts_add[rts_n++] = ((NMPlatformIP4Route) {
|
||||
.ifindex = IFINDEX,
|
||||
.rt_source = NM_IP_CONFIG_SOURCE_USER,
|
||||
.network = nmtst_inet4_from_string ("172.17.1.0"),
|
||||
.gateway = nmtst_inet4_from_string ("172.16.1.1"),
|
||||
.plen = 24,
|
||||
.metric = 20,
|
||||
});
|
||||
rts_add[rts_n++] = ((NMPlatformIP4Route) {
|
||||
.ifindex = IFINDEX,
|
||||
.rt_source = NM_IP_CONFIG_SOURCE_USER,
|
||||
.network = nmtst_inet4_from_string ("172.19.1.0"),
|
||||
.gateway = nmtst_inet4_from_string ("172.18.1.1"),
|
||||
.r_rtm_flags = RTNH_F_ONLINK,
|
||||
.plen = 24,
|
||||
.metric = 20,
|
||||
});
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
g_assert (rts_n <= G_N_ELEMENTS (rts_add));
|
||||
g_assert (addr_n <= G_N_ELEMENTS (addr));
|
||||
|
||||
route.ifindex = ifindex;
|
||||
route.rt_source = NM_IP_CONFIG_SOURCE_USER;
|
||||
route.network = network;
|
||||
route.plen = 24;
|
||||
route.metric = 20;
|
||||
route.tos = 0x28;
|
||||
route.window = 10000;
|
||||
route.cwnd = 16;
|
||||
route.initcwnd = 30;
|
||||
route.initrwnd = 50;
|
||||
route.mtu = 1350;
|
||||
route.lock_cwnd = TRUE;
|
||||
for (i = 0; i < addr_n; i++) {
|
||||
const NMPlatformIP4Address *a = &addr[i];
|
||||
|
||||
g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, NMP_NLM_FLAG_REPLACE, &route) == NM_PLATFORM_ERROR_SUCCESS);
|
||||
g_assert (a->ifindex == IFINDEX);
|
||||
g_assert (nm_platform_ip4_address_add (NM_PLATFORM_GET,
|
||||
a->ifindex,
|
||||
a->address,
|
||||
a->plen,
|
||||
a->peer_address,
|
||||
a->lifetime,
|
||||
a->preferred,
|
||||
a->n_ifa_flags,
|
||||
a->label));
|
||||
if (a->peer_address == a->address)
|
||||
_wait_for_ipv4_addr_device_route (NM_PLATFORM_GET, 200, a->ifindex, a->address, a->plen);
|
||||
}
|
||||
|
||||
/* Test route listing */
|
||||
routes = nmtstp_ip4_route_get_all (NM_PLATFORM_GET, ifindex);
|
||||
memset (rts, 0, sizeof (rts));
|
||||
rts[0].rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER);
|
||||
rts[0].scope_inv = nm_platform_route_scope_inv (RT_SCOPE_LINK);
|
||||
rts[0].network = network;
|
||||
rts[0].plen = 24;
|
||||
rts[0].ifindex = ifindex;
|
||||
rts[0].metric = 20;
|
||||
rts[0].tos = 0x28;
|
||||
rts[0].window = 10000;
|
||||
rts[0].cwnd = 16;
|
||||
rts[0].initcwnd = 30;
|
||||
rts[0].initrwnd = 50;
|
||||
rts[0].mtu = 1350;
|
||||
rts[0].lock_cwnd = TRUE;
|
||||
g_assert_cmpint (routes->len, ==, 1);
|
||||
nmtst_platform_ip4_routes_equal_aptr ((const NMPObject *const*) routes->pdata, rts, routes->len, TRUE);
|
||||
for (i = 0; i < rts_n; i++)
|
||||
g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, NMP_NLM_FLAG_REPLACE, &rts_add[i]) == NM_PLATFORM_ERROR_SUCCESS);
|
||||
|
||||
/* Remove route */
|
||||
g_assert (nm_platform_ip_route_delete (NM_PLATFORM_GET, routes->pdata[0]));
|
||||
for (i = 0; i < rts_n; i++) {
|
||||
rts_cmp[i] = rts_add[i];
|
||||
nm_platform_ip_route_normalize (AF_INET, NM_PLATFORM_IP_ROUTE_CAST (&rts_cmp[i]));
|
||||
}
|
||||
|
||||
g_ptr_array_unref (routes);
|
||||
routes = nmtstp_ip4_route_get_all (NM_PLATFORM_GET, IFINDEX);
|
||||
g_assert_cmpint (routes->len, ==, rts_n);
|
||||
nmtst_platform_ip4_routes_equal_aptr ((const NMPObject *const*) routes->pdata, rts_cmp, routes->len, TRUE);
|
||||
|
||||
for (i = 0; i < rts_n; i++) {
|
||||
g_assert (nmtstp_platform_ip4_route_delete (NM_PLATFORM_GET, IFINDEX,
|
||||
rts_add[i].network, rts_add[i].plen,
|
||||
rts_add[i].metric));
|
||||
}
|
||||
#undef RTS_MAX
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
test_ip6_route_options (gconstpointer test_data)
|
||||
{
|
||||
const int TEST_IDX = GPOINTER_TO_INT (test_data);
|
||||
const int IFINDEX = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME);
|
||||
GPtrArray *routes;
|
||||
gs_unref_ptrarray GPtrArray *routes = NULL;
|
||||
#define RTS_MAX 3
|
||||
NMPlatformIP6Route rts_add[RTS_MAX] = { };
|
||||
NMPlatformIP6Route rts_cmp[RTS_MAX] = { };
|
||||
|
|
@ -582,6 +668,8 @@ test_ip6_route_options (gconstpointer test_data)
|
|||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
g_assert (rts_n <= G_N_ELEMENTS (rts_add));
|
||||
g_assert (addr_n <= G_N_ELEMENTS (addr));
|
||||
|
||||
for (i = 0; i < addr_n; i++) {
|
||||
g_assert (addr[i].ifindex == IFINDEX);
|
||||
|
|
@ -595,28 +683,19 @@ test_ip6_route_options (gconstpointer test_data)
|
|||
addr[i].preferred,
|
||||
addr[i].n_ifa_flags));
|
||||
}
|
||||
|
||||
_wait_for_ipv6_addr_non_tentative (NM_PLATFORM_GET, 400, IFINDEX, addr_n, addr_in6);
|
||||
|
||||
for (i = 0; i < rts_n; i++)
|
||||
g_assert (nm_platform_ip6_route_add (NM_PLATFORM_GET, NMP_NLM_FLAG_REPLACE, &rts_add[i]) == NM_PLATFORM_ERROR_SUCCESS);
|
||||
|
||||
routes = nmtstp_ip6_route_get_all (NM_PLATFORM_GET, IFINDEX);
|
||||
switch (TEST_IDX) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
for (i = 0; i < rts_n; i++) {
|
||||
rts_cmp[i] = rts_add[i];
|
||||
rts_cmp[i].rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
for (i = 0; i < rts_n; i++) {
|
||||
rts_cmp[i] = rts_add[i];
|
||||
nm_platform_ip_route_normalize (AF_INET6, NM_PLATFORM_IP_ROUTE_CAST (&rts_cmp[i]));
|
||||
}
|
||||
|
||||
routes = nmtstp_ip6_route_get_all (NM_PLATFORM_GET, IFINDEX);
|
||||
g_assert_cmpint (routes->len, ==, rts_n);
|
||||
nmtst_platform_ip6_routes_equal_aptr ((const NMPObject *const*) routes->pdata, rts_cmp, routes->len, TRUE);
|
||||
g_ptr_array_unref (routes);
|
||||
|
||||
for (i = 0; i < rts_n; i++) {
|
||||
g_assert (nmtstp_platform_ip6_route_delete (NM_PLATFORM_GET, IFINDEX,
|
||||
|
|
@ -631,6 +710,7 @@ test_ip6_route_options (gconstpointer test_data)
|
|||
rts_add[i].network,
|
||||
rts_add[i].plen);
|
||||
}
|
||||
#undef RTS_MAX
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -771,7 +851,9 @@ _nmtstp_setup_tests (void)
|
|||
add_test_func ("/route/ip4", test_ip4_route);
|
||||
add_test_func ("/route/ip6", test_ip6_route);
|
||||
add_test_func ("/route/ip4_metric0", test_ip4_route_metric0);
|
||||
add_test_func ("/route/ip4_options", test_ip4_route_options);
|
||||
add_test_func_data ("/route/ip4_options/1", test_ip4_route_options, GINT_TO_POINTER (1));
|
||||
if (nmtstp_is_root_test ())
|
||||
add_test_func_data ("/route/ip4_options/2", test_ip4_route_options, GINT_TO_POINTER (2));
|
||||
add_test_func_data ("/route/ip6_options/1", test_ip6_route_options, GINT_TO_POINTER (1));
|
||||
add_test_func_data ("/route/ip6_options/2", test_ip6_route_options, GINT_TO_POINTER (2));
|
||||
add_test_func_data ("/route/ip6_options/3", test_ip6_route_options, GINT_TO_POINTER (3));
|
||||
|
|
|
|||
|
|
@ -512,13 +512,13 @@ typedef struct {
|
|||
|
||||
bool int_base_16:1;
|
||||
|
||||
/* the type, one of PARSE_LINE_TYPE_* */
|
||||
char type;
|
||||
|
||||
/* whether the command line option was found, and @v is
|
||||
* initialized. */
|
||||
bool has:1;
|
||||
|
||||
/* the type, one of PARSE_LINE_TYPE_* */
|
||||
char type;
|
||||
|
||||
union {
|
||||
guint8 uint8;
|
||||
guint32 uint32;
|
||||
|
|
@ -541,6 +541,7 @@ enum {
|
|||
PARSE_LINE_ATTR_ROUTE_SRC,
|
||||
PARSE_LINE_ATTR_ROUTE_FROM,
|
||||
PARSE_LINE_ATTR_ROUTE_TOS,
|
||||
PARSE_LINE_ATTR_ROUTE_ONLINK,
|
||||
PARSE_LINE_ATTR_ROUTE_WINDOW,
|
||||
PARSE_LINE_ATTR_ROUTE_CWND,
|
||||
PARSE_LINE_ATTR_ROUTE_INITCWND,
|
||||
|
|
@ -562,6 +563,7 @@ enum {
|
|||
#define PARSE_LINE_TYPE_ADDR 'a'
|
||||
#define PARSE_LINE_TYPE_ADDR_WITH_PREFIX 'p'
|
||||
#define PARSE_LINE_TYPE_IFNAME 'i'
|
||||
#define PARSE_LINE_TYPE_FLAG 'f'
|
||||
|
||||
/**
|
||||
* parse_route_line:
|
||||
|
|
@ -601,42 +603,45 @@ parse_route_line (const char *line,
|
|||
char buf1[256];
|
||||
char buf2[256];
|
||||
ParseLineInfo infos[] = {
|
||||
[PARSE_LINE_ATTR_ROUTE_TABLE] = { .key = NM_IP_ROUTE_ATTRIBUTE_TABLE,
|
||||
.type = PARSE_LINE_TYPE_UINT32, },
|
||||
[PARSE_LINE_ATTR_ROUTE_SRC] = { .key = NM_IP_ROUTE_ATTRIBUTE_SRC,
|
||||
.type = PARSE_LINE_TYPE_ADDR, },
|
||||
[PARSE_LINE_ATTR_ROUTE_FROM] = { .key = NM_IP_ROUTE_ATTRIBUTE_FROM,
|
||||
.type = PARSE_LINE_TYPE_ADDR_WITH_PREFIX,
|
||||
.disabled = (addr_family != AF_INET6), },
|
||||
[PARSE_LINE_ATTR_ROUTE_TOS] = { .key = NM_IP_ROUTE_ATTRIBUTE_TOS,
|
||||
.type = PARSE_LINE_TYPE_UINT8,
|
||||
.int_base_16 = TRUE,
|
||||
.ignore = (addr_family != AF_INET), },
|
||||
[PARSE_LINE_ATTR_ROUTE_WINDOW] = { .key = NM_IP_ROUTE_ATTRIBUTE_WINDOW,
|
||||
.type = PARSE_LINE_TYPE_UINT32_WITH_LOCK, },
|
||||
[PARSE_LINE_ATTR_ROUTE_CWND] = { .key = NM_IP_ROUTE_ATTRIBUTE_CWND,
|
||||
.type = PARSE_LINE_TYPE_UINT32_WITH_LOCK, },
|
||||
[PARSE_LINE_ATTR_ROUTE_INITCWND] = { .key = NM_IP_ROUTE_ATTRIBUTE_INITCWND,
|
||||
.type = PARSE_LINE_TYPE_UINT32_WITH_LOCK, },
|
||||
[PARSE_LINE_ATTR_ROUTE_INITRWND] = { .key = NM_IP_ROUTE_ATTRIBUTE_INITRWND,
|
||||
.type = PARSE_LINE_TYPE_UINT32_WITH_LOCK, },
|
||||
[PARSE_LINE_ATTR_ROUTE_MTU] = { .key = NM_IP_ROUTE_ATTRIBUTE_MTU,
|
||||
.type = PARSE_LINE_TYPE_UINT32_WITH_LOCK, },
|
||||
[PARSE_LINE_ATTR_ROUTE_TABLE] = { .key = NM_IP_ROUTE_ATTRIBUTE_TABLE,
|
||||
.type = PARSE_LINE_TYPE_UINT32, },
|
||||
[PARSE_LINE_ATTR_ROUTE_SRC] = { .key = NM_IP_ROUTE_ATTRIBUTE_SRC,
|
||||
.type = PARSE_LINE_TYPE_ADDR, },
|
||||
[PARSE_LINE_ATTR_ROUTE_FROM] = { .key = NM_IP_ROUTE_ATTRIBUTE_FROM,
|
||||
.type = PARSE_LINE_TYPE_ADDR_WITH_PREFIX,
|
||||
.disabled = (addr_family != AF_INET6), },
|
||||
[PARSE_LINE_ATTR_ROUTE_TOS] = { .key = NM_IP_ROUTE_ATTRIBUTE_TOS,
|
||||
.type = PARSE_LINE_TYPE_UINT8,
|
||||
.int_base_16 = TRUE,
|
||||
.ignore = (addr_family != AF_INET), },
|
||||
[PARSE_LINE_ATTR_ROUTE_ONLINK] = { .key = NM_IP_ROUTE_ATTRIBUTE_ONLINK,
|
||||
.type = PARSE_LINE_TYPE_FLAG,
|
||||
.ignore = (addr_family != AF_INET), },
|
||||
[PARSE_LINE_ATTR_ROUTE_WINDOW] = { .key = NM_IP_ROUTE_ATTRIBUTE_WINDOW,
|
||||
.type = PARSE_LINE_TYPE_UINT32_WITH_LOCK, },
|
||||
[PARSE_LINE_ATTR_ROUTE_CWND] = { .key = NM_IP_ROUTE_ATTRIBUTE_CWND,
|
||||
.type = PARSE_LINE_TYPE_UINT32_WITH_LOCK, },
|
||||
[PARSE_LINE_ATTR_ROUTE_INITCWND] = { .key = NM_IP_ROUTE_ATTRIBUTE_INITCWND,
|
||||
.type = PARSE_LINE_TYPE_UINT32_WITH_LOCK, },
|
||||
[PARSE_LINE_ATTR_ROUTE_INITRWND] = { .key = NM_IP_ROUTE_ATTRIBUTE_INITRWND,
|
||||
.type = PARSE_LINE_TYPE_UINT32_WITH_LOCK, },
|
||||
[PARSE_LINE_ATTR_ROUTE_MTU] = { .key = NM_IP_ROUTE_ATTRIBUTE_MTU,
|
||||
.type = PARSE_LINE_TYPE_UINT32_WITH_LOCK, },
|
||||
|
||||
[PARSE_LINE_ATTR_ROUTE_TO] = { .key = "to",
|
||||
.type = PARSE_LINE_TYPE_ADDR_WITH_PREFIX,
|
||||
.disabled = (options_route != NULL), },
|
||||
[PARSE_LINE_ATTR_ROUTE_VIA] = { .key = "via",
|
||||
.type = PARSE_LINE_TYPE_ADDR,
|
||||
.disabled = (options_route != NULL), },
|
||||
[PARSE_LINE_ATTR_ROUTE_METRIC] = { .key = "metric",
|
||||
.type = PARSE_LINE_TYPE_UINT32,
|
||||
.disabled = (options_route != NULL), },
|
||||
[PARSE_LINE_ATTR_ROUTE_TO] = { .key = "to",
|
||||
.type = PARSE_LINE_TYPE_ADDR_WITH_PREFIX,
|
||||
.disabled = (options_route != NULL), },
|
||||
[PARSE_LINE_ATTR_ROUTE_VIA] = { .key = "via",
|
||||
.type = PARSE_LINE_TYPE_ADDR,
|
||||
.disabled = (options_route != NULL), },
|
||||
[PARSE_LINE_ATTR_ROUTE_METRIC] = { .key = "metric",
|
||||
.type = PARSE_LINE_TYPE_UINT32,
|
||||
.disabled = (options_route != NULL), },
|
||||
|
||||
[PARSE_LINE_ATTR_ROUTE_DEV] = { .key = "dev",
|
||||
.type = PARSE_LINE_TYPE_IFNAME,
|
||||
.ignore = TRUE,
|
||||
.disabled = (options_route != NULL), },
|
||||
[PARSE_LINE_ATTR_ROUTE_DEV] = { .key = "dev",
|
||||
.type = PARSE_LINE_TYPE_IFNAME,
|
||||
.ignore = TRUE,
|
||||
.disabled = (options_route != NULL), },
|
||||
};
|
||||
|
||||
nm_assert (line);
|
||||
|
|
@ -705,6 +710,9 @@ parse_route_line (const char *line,
|
|||
case PARSE_LINE_TYPE_IFNAME:
|
||||
i_words++;
|
||||
goto parse_line_type_ifname;
|
||||
case PARSE_LINE_TYPE_FLAG:
|
||||
i_words++;
|
||||
goto next;
|
||||
default:
|
||||
nm_assert_not_reached ();
|
||||
}
|
||||
|
|
@ -913,6 +921,15 @@ next:
|
|||
? nm_sprintf_buf (buf2, "/%u", (unsigned) info->v.addr.plen)
|
||||
: ""));
|
||||
break;
|
||||
case PARSE_LINE_TYPE_FLAG:
|
||||
/* XXX: the flag (for "onlink") only allows to explictly set "TRUE".
|
||||
* There is no way to express an explicit "FALSE" setting
|
||||
* of this attribute, hence, the file format cannot encode
|
||||
* that configuration. */
|
||||
nm_ip_route_set_attribute (route,
|
||||
info->key,
|
||||
g_variant_new_boolean (TRUE));
|
||||
break;
|
||||
default:
|
||||
nm_assert_not_reached ();
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1928,8 +1928,11 @@ get_route_attributes_string (NMIPRoute *route, int family)
|
|||
g_string_append_printf (str, "%s 0x%02x", names[i], (unsigned) g_variant_get_byte (attr));
|
||||
} else if (nm_streq (names[i], NM_IP_ROUTE_ATTRIBUTE_TABLE)) {
|
||||
g_string_append_printf (str, "%s %u", names[i], (unsigned) g_variant_get_uint32 (attr));
|
||||
} else if ( nm_streq (names[i], NM_IP_ROUTE_ATTRIBUTE_SRC)
|
||||
|| nm_streq (names[i], NM_IP_ROUTE_ATTRIBUTE_FROM)) {
|
||||
} else if (nm_streq (names[i], NM_IP_ROUTE_ATTRIBUTE_ONLINK)) {
|
||||
if (g_variant_get_boolean (attr))
|
||||
g_string_append (str, "onlink");
|
||||
} else if (NM_IN_STRSET (names[i], NM_IP_ROUTE_ATTRIBUTE_SRC,
|
||||
NM_IP_ROUTE_ATTRIBUTE_FROM)) {
|
||||
char *arg = nm_streq (names[i], NM_IP_ROUTE_ATTRIBUTE_SRC) ? "src" : "from";
|
||||
|
||||
g_string_append_printf (str, "%s %s", arg, g_variant_get_string (attr, NULL));
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
HWADDR=31:33:33:37:BE:CD
|
||||
MTU=1492
|
||||
TYPE=Ethernet
|
||||
PROXY_METHOD=none
|
||||
BROWSER_ONLY=no
|
||||
BOOTPROTO=none
|
||||
IPADDR=1.1.1.3
|
||||
PREFIX=24
|
||||
IPADDR1=1.1.1.5
|
||||
PREFIX1=24
|
||||
GATEWAY=1.1.1.1
|
||||
DNS1=4.2.2.1
|
||||
DNS2=4.2.2.2
|
||||
DOMAIN="foobar.com lab.foobar.com"
|
||||
DEFROUTE=yes
|
||||
IPV4_FAILURE_FATAL=no
|
||||
IPV6INIT=no
|
||||
NAME="Test Write Wired Static Routes"
|
||||
UUID=${UUID}
|
||||
ONBOOT=yes
|
||||
|
|
@ -7,3 +7,9 @@ NETMASK1=255.255.255.255
|
|||
GATEWAY1=192.168.1.7
|
||||
METRIC1=3
|
||||
OPTIONS1="mtu lock 9000 cwnd 12 src 1.1.1.1 tos 0x28 window 30000 initcwnd lock 13 initrwnd 14"
|
||||
|
||||
ADDRESS2=44.55.66.78
|
||||
NETMASK2=255.255.255.255
|
||||
GATEWAY2=192.168.1.8
|
||||
METRIC2=3
|
||||
OPTIONS2="mtu lock 9000 cwnd 12 src 1.1.1.1 tos 0x28 onlink window 30000 initcwnd lock 13 initrwnd 14"
|
||||
|
|
|
|||
|
|
@ -1318,7 +1318,7 @@ test_read_wired_static_routes (void)
|
|||
g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_MANUAL);
|
||||
|
||||
/* Routes */
|
||||
g_assert_cmpint (nm_setting_ip_config_get_num_routes (s_ip4), ==, 2);
|
||||
g_assert_cmpint (nm_setting_ip_config_get_num_routes (s_ip4), ==, 3);
|
||||
|
||||
ip4_route = nm_setting_ip_config_get_route (s_ip4, 0);
|
||||
g_assert (ip4_route);
|
||||
|
|
@ -1343,6 +1343,23 @@ test_read_wired_static_routes (void)
|
|||
nmtst_assert_route_attribute_boolean (ip4_route, NM_IP_ROUTE_ATTRIBUTE_LOCK_INITCWND, TRUE);
|
||||
nmtst_assert_route_attribute_string (ip4_route, NM_IP_ROUTE_ATTRIBUTE_SRC, "1.1.1.1");
|
||||
|
||||
ip4_route = nm_setting_ip_config_get_route (s_ip4, 2);
|
||||
g_assert (ip4_route);
|
||||
g_assert_cmpstr (nm_ip_route_get_dest (ip4_route), ==, "44.55.66.78");
|
||||
g_assert_cmpint (nm_ip_route_get_prefix (ip4_route), ==, 32);
|
||||
g_assert_cmpstr (nm_ip_route_get_next_hop (ip4_route), ==, "192.168.1.8");
|
||||
g_assert_cmpint (nm_ip_route_get_metric (ip4_route), ==, 3);
|
||||
nmtst_assert_route_attribute_byte (ip4_route, NM_IP_ROUTE_ATTRIBUTE_TOS, 0x28);
|
||||
nmtst_assert_route_attribute_uint32 (ip4_route, NM_IP_ROUTE_ATTRIBUTE_WINDOW, 30000);
|
||||
nmtst_assert_route_attribute_uint32 (ip4_route, NM_IP_ROUTE_ATTRIBUTE_CWND, 12);
|
||||
nmtst_assert_route_attribute_uint32 (ip4_route, NM_IP_ROUTE_ATTRIBUTE_INITCWND, 13);
|
||||
nmtst_assert_route_attribute_uint32 (ip4_route, NM_IP_ROUTE_ATTRIBUTE_INITRWND, 14);
|
||||
nmtst_assert_route_attribute_uint32 (ip4_route, NM_IP_ROUTE_ATTRIBUTE_MTU, 9000);
|
||||
nmtst_assert_route_attribute_boolean (ip4_route, NM_IP_ROUTE_ATTRIBUTE_LOCK_MTU, TRUE);
|
||||
nmtst_assert_route_attribute_boolean (ip4_route, NM_IP_ROUTE_ATTRIBUTE_LOCK_INITCWND, TRUE);
|
||||
nmtst_assert_route_attribute_string (ip4_route, NM_IP_ROUTE_ATTRIBUTE_SRC, "1.1.1.1");
|
||||
nmtst_assert_route_attribute_boolean (ip4_route, NM_IP_ROUTE_ATTRIBUTE_ONLINK, TRUE);
|
||||
|
||||
g_object_unref (connection);
|
||||
}
|
||||
|
||||
|
|
@ -4748,6 +4765,7 @@ test_write_wired_static_routes (void)
|
|||
NMIPAddress *addr;
|
||||
NMIPRoute *route;
|
||||
GError *error = NULL;
|
||||
gboolean reread_same = FALSE;
|
||||
|
||||
connection = nm_simple_connection_new ();
|
||||
|
||||
|
|
@ -4792,11 +4810,15 @@ test_write_wired_static_routes (void)
|
|||
|
||||
/* Write out routes */
|
||||
route = nm_ip_route_new (AF_INET, "1.2.3.0", 24, "222.173.190.239", 0, &error);
|
||||
nm_ip_route_set_attribute (route, NM_IP_ROUTE_ATTRIBUTE_WINDOW, g_variant_new_uint32 (3455));
|
||||
nm_ip_route_set_attribute (route, NM_IP_ROUTE_ATTRIBUTE_ONLINK, g_variant_new_boolean (TRUE));
|
||||
g_assert_no_error (error);
|
||||
nm_setting_ip_config_add_route (s_ip4, route);
|
||||
nm_ip_route_unref (route);
|
||||
|
||||
route = nm_ip_route_new (AF_INET, "3.2.1.0", 24, "202.254.186.190", 77, &error);
|
||||
nm_ip_route_set_attribute (route, NM_IP_ROUTE_ATTRIBUTE_WINDOW, g_variant_new_uint32 (30000));
|
||||
nm_ip_route_set_attribute (route, NM_IP_ROUTE_ATTRIBUTE_ONLINK, g_variant_new_boolean (FALSE));
|
||||
g_assert_no_error (error);
|
||||
nm_setting_ip_config_add_route (s_ip4, route);
|
||||
nm_ip_route_unref (route);
|
||||
|
|
@ -4818,15 +4840,28 @@ test_write_wired_static_routes (void)
|
|||
|
||||
nmtst_assert_connection_verifies (connection);
|
||||
|
||||
_writer_new_connection (connection,
|
||||
TEST_SCRATCH_DIR "/network-scripts/",
|
||||
&testfile);
|
||||
|
||||
reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL);
|
||||
|
||||
routefile = utils_get_route_path (testfile);
|
||||
_writer_new_connection_reread (connection,
|
||||
TEST_SCRATCH_DIR "/network-scripts/",
|
||||
&testfile,
|
||||
TEST_IFCFG_DIR "/network-scripts/ifcfg-Test_Write_Wired_Static_Routes.cexpected",
|
||||
&reread,
|
||||
&reread_same);
|
||||
/* ifcfg does not support setting onlink=0. It gets lost during write+re-read.
|
||||
* Assert that it's missing, and patch it to check whether the rest of the
|
||||
* connection equals. */
|
||||
g_assert (!reread_same);
|
||||
nmtst_assert_connection_verifies_without_normalization (reread);
|
||||
s_ip4 = nm_connection_get_setting_ip4_config (reread);
|
||||
g_assert (s_ip4);
|
||||
g_assert_cmpint (nm_setting_ip_config_get_num_routes (s_ip4), ==, 2);
|
||||
route = nm_setting_ip_config_get_route (s_ip4, 1);
|
||||
g_assert (route);
|
||||
g_assert (!nm_ip_route_get_attribute (route, NM_IP_ROUTE_ATTRIBUTE_ONLINK));
|
||||
nm_ip_route_set_attribute (route, NM_IP_ROUTE_ATTRIBUTE_ONLINK, g_variant_new_boolean (FALSE));
|
||||
|
||||
nmtst_assert_connection_equals (connection, TRUE, reread, FALSE);
|
||||
|
||||
routefile = utils_get_route_path (testfile);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@ build_test_config (void)
|
|||
/* Build up the config to subtract */
|
||||
config = nmtst_ip4_config_new (1);
|
||||
|
||||
nm_assert (NM_IP_CONFIG_CAST (config));
|
||||
|
||||
addr = *nmtst_platform_ip4_address ("192.168.1.10", "1.2.3.4", 24);
|
||||
nm_ip4_config_add_address (config, &addr);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue