route: introduce weight property for ipv4 routes
Introduce the weight property for IPv4 ECMP routes. The value will be ignored if there is only a single nexthop.
This commit is contained in:
@@ -1382,6 +1382,7 @@ nm_utils_ip_route_attribute_to_platform(int addr_family,
|
|||||||
|
|
||||||
GET_ATTR(NM_IP_ROUTE_ATTRIBUTE_TOS, r4->tos, BYTE, byte, 0);
|
GET_ATTR(NM_IP_ROUTE_ATTRIBUTE_TOS, r4->tos, BYTE, byte, 0);
|
||||||
GET_ATTR(NM_IP_ROUTE_ATTRIBUTE_SCOPE, scope, BYTE, byte, RT_SCOPE_NOWHERE);
|
GET_ATTR(NM_IP_ROUTE_ATTRIBUTE_SCOPE, scope, BYTE, byte, RT_SCOPE_NOWHERE);
|
||||||
|
GET_ATTR(NM_IP_ROUTE_ATTRIBUTE_WEIGHT, r4->weight, BYTE, byte, 0);
|
||||||
r4->scope_inv = nm_platform_route_scope_inv(scope);
|
r4->scope_inv = nm_platform_route_scope_inv(scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -887,6 +887,7 @@ enum {
|
|||||||
PARSE_LINE_ATTR_ROUTE_ADVMSS,
|
PARSE_LINE_ATTR_ROUTE_ADVMSS,
|
||||||
PARSE_LINE_ATTR_ROUTE_RTO_MIN,
|
PARSE_LINE_ATTR_ROUTE_RTO_MIN,
|
||||||
PARSE_LINE_ATTR_ROUTE_QUICKACK,
|
PARSE_LINE_ATTR_ROUTE_QUICKACK,
|
||||||
|
PARSE_LINE_ATTR_ROUTE_WEIGHT,
|
||||||
|
|
||||||
/* iproute2 arguments that only matter when parsing the file. */
|
/* iproute2 arguments that only matter when parsing the file. */
|
||||||
PARSE_LINE_ATTR_ROUTE_TO,
|
PARSE_LINE_ATTR_ROUTE_TO,
|
||||||
@@ -966,6 +967,12 @@ parse_route_line(const char *line,
|
|||||||
.int_base_16 = TRUE,
|
.int_base_16 = TRUE,
|
||||||
.ignore = PARSE_LINE_AF_FLAG_FOR_IPV6,
|
.ignore = PARSE_LINE_AF_FLAG_FOR_IPV6,
|
||||||
},
|
},
|
||||||
|
[PARSE_LINE_ATTR_ROUTE_WEIGHT] =
|
||||||
|
{
|
||||||
|
.key = NM_IP_ROUTE_ATTRIBUTE_WEIGHT,
|
||||||
|
.type = PARSE_LINE_TYPE_UINT8,
|
||||||
|
.disabled = PARSE_LINE_AF_FLAG_FOR_IPV6,
|
||||||
|
},
|
||||||
[PARSE_LINE_ATTR_ROUTE_SCOPE] =
|
[PARSE_LINE_ATTR_ROUTE_SCOPE] =
|
||||||
{
|
{
|
||||||
.key = NM_IP_ROUTE_ATTRIBUTE_SCOPE,
|
.key = NM_IP_ROUTE_ATTRIBUTE_SCOPE,
|
||||||
|
@@ -2360,7 +2360,9 @@ get_route_attributes_string(NMIPRoute *route, int family)
|
|||||||
/* we also have a corresponding attribute with the numeric value. The
|
/* we also have a corresponding attribute with the numeric value. The
|
||||||
* lock setting is handled above. */
|
* lock setting is handled above. */
|
||||||
}
|
}
|
||||||
} else if (nm_streq(names[i], NM_IP_ROUTE_ATTRIBUTE_SCOPE)) {
|
} else if (NM_IN_STRSET(names[i],
|
||||||
|
NM_IP_ROUTE_ATTRIBUTE_SCOPE,
|
||||||
|
NM_IP_ROUTE_ATTRIBUTE_WEIGHT)) {
|
||||||
g_string_append_printf(str, "%s %u", names[i], (unsigned) g_variant_get_byte(attr));
|
g_string_append_printf(str, "%s %u", names[i], (unsigned) g_variant_get_byte(attr));
|
||||||
} else if (nm_streq(names[i], NM_IP_ROUTE_ATTRIBUTE_TOS)) {
|
} else if (nm_streq(names[i], NM_IP_ROUTE_ATTRIBUTE_TOS)) {
|
||||||
g_string_append_printf(str, "%s 0x%02x", names[i], (unsigned) g_variant_get_byte(attr));
|
g_string_append_printf(str, "%s 0x%02x", names[i], (unsigned) g_variant_get_byte(attr));
|
||||||
|
@@ -6,7 +6,7 @@ ADDRESS1=44.55.66.77
|
|||||||
NETMASK1=255.255.255.255
|
NETMASK1=255.255.255.255
|
||||||
GATEWAY1=192.168.1.7
|
GATEWAY1=192.168.1.7
|
||||||
METRIC1=3
|
METRIC1=3
|
||||||
OPTIONS1="mtu lock 9000 cwnd 12 src 1.1.1.1 tos 0x28 window 30000 scope 10 initcwnd lock 13 initrwnd 14 rto_min 300 advmss 1300 quickack 1"
|
OPTIONS1="mtu lock 9000 cwnd 12 src 1.1.1.1 tos 0x28 window 30000 scope 10 initcwnd lock 13 initrwnd 14 rto_min 300 advmss 1300 quickack 1 weight 5"
|
||||||
|
|
||||||
ADDRESS2=44.55.66.78
|
ADDRESS2=44.55.66.78
|
||||||
NETMASK2=255.255.255.255
|
NETMASK2=255.255.255.255
|
||||||
|
@@ -1365,6 +1365,7 @@ test_read_wired_static_routes(void)
|
|||||||
nmtst_assert_route_attribute_byte(ip4_route, NM_IP_ROUTE_ATTRIBUTE_TOS, 0x28);
|
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_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_CWND, 12);
|
||||||
|
nmtst_assert_route_attribute_byte(ip4_route, NM_IP_ROUTE_ATTRIBUTE_WEIGHT, 5);
|
||||||
nmtst_assert_route_attribute_uint32(ip4_route, NM_IP_ROUTE_ATTRIBUTE_INITCWND, 13);
|
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_INITRWND, 14);
|
||||||
nmtst_assert_route_attribute_uint32(ip4_route, NM_IP_ROUTE_ATTRIBUTE_MTU, 9000);
|
nmtst_assert_route_attribute_uint32(ip4_route, NM_IP_ROUTE_ATTRIBUTE_MTU, 9000);
|
||||||
@@ -4279,6 +4280,7 @@ static void
|
|||||||
test_write_wired_static(void)
|
test_write_wired_static(void)
|
||||||
{
|
{
|
||||||
nmtst_auto_unlinkfile char *testfile = NULL;
|
nmtst_auto_unlinkfile char *testfile = NULL;
|
||||||
|
nmtst_auto_unlinkfile char *route4file = NULL;
|
||||||
nmtst_auto_unlinkfile char *route6file = NULL;
|
nmtst_auto_unlinkfile char *route6file = NULL;
|
||||||
gs_unref_object NMConnection *connection = NULL;
|
gs_unref_object NMConnection *connection = NULL;
|
||||||
gs_unref_object NMConnection *reread = NULL;
|
gs_unref_object NMConnection *reread = NULL;
|
||||||
@@ -4288,6 +4290,7 @@ test_write_wired_static(void)
|
|||||||
NMSettingIPConfig *s_ip6, *reread_s_ip6;
|
NMSettingIPConfig *s_ip6, *reread_s_ip6;
|
||||||
NMIPAddress *addr;
|
NMIPAddress *addr;
|
||||||
NMIPAddress *addr6;
|
NMIPAddress *addr6;
|
||||||
|
NMIPRoute *route4;
|
||||||
NMIPRoute *route6;
|
NMIPRoute *route6;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
@@ -4392,6 +4395,13 @@ test_write_wired_static(void)
|
|||||||
nm_setting_ip_config_add_route(s_ip6, route6);
|
nm_setting_ip_config_add_route(s_ip6, route6);
|
||||||
nm_ip_route_unref(route6);
|
nm_ip_route_unref(route6);
|
||||||
|
|
||||||
|
route4 = nm_ip_route_new(AF_INET, "1.1.1.1", 24, "1.2.3.4", 99, &error);
|
||||||
|
g_assert_no_error(error);
|
||||||
|
nm_ip_route_set_attribute(route4, NM_IP_ROUTE_ATTRIBUTE_CWND, g_variant_new_uint32(100));
|
||||||
|
nm_ip_route_set_attribute(route4, NM_IP_ROUTE_ATTRIBUTE_WEIGHT, g_variant_new_byte(5));
|
||||||
|
nm_setting_ip_config_add_route(s_ip4, route4);
|
||||||
|
nm_ip_route_unref(route4);
|
||||||
|
|
||||||
/* DNS servers */
|
/* DNS servers */
|
||||||
nm_setting_ip_config_add_dns(s_ip6, "fade:0102:0103::face");
|
nm_setting_ip_config_add_dns(s_ip6, "fade:0102:0103::face");
|
||||||
nm_setting_ip_config_add_dns(s_ip6, "cafe:ffff:eeee:dddd:cccc:bbbb:aaaa:feed");
|
nm_setting_ip_config_add_dns(s_ip6, "cafe:ffff:eeee:dddd:cccc:bbbb:aaaa:feed");
|
||||||
@@ -4403,7 +4413,9 @@ test_write_wired_static(void)
|
|||||||
nmtst_assert_connection_verifies(connection);
|
nmtst_assert_connection_verifies(connection);
|
||||||
|
|
||||||
_writer_new_connection(connection, TEST_SCRATCH_DIR, &testfile);
|
_writer_new_connection(connection, TEST_SCRATCH_DIR, &testfile);
|
||||||
|
|
||||||
route6file = utils_get_route6_path(testfile);
|
route6file = utils_get_route6_path(testfile);
|
||||||
|
route4file = utils_get_route_path(testfile);
|
||||||
|
|
||||||
reread = _connection_from_file(testfile, NULL, TYPE_ETHERNET, NULL);
|
reread = _connection_from_file(testfile, NULL, TYPE_ETHERNET, NULL);
|
||||||
|
|
||||||
|
@@ -36,7 +36,7 @@ routes9=1.1.1.9/19,0.0.0.0,0
|
|||||||
route10=1.1.1.10/21,,0
|
route10=1.1.1.10/21,,0
|
||||||
routes10=1.1.1.10/20,,0
|
routes10=1.1.1.10/20,,0
|
||||||
routes11=1.1.1.11/21,,21
|
routes11=1.1.1.11/21,,21
|
||||||
routes11_options=cwnd=10,lock-cwnd=true,mtu=1430,src=7.7.7.7,type=unicast
|
routes11_options=cwnd=10,lock-cwnd=true,mtu=1430,src=7.7.7.7,type=unicast,weight=5
|
||||||
routes12=1.2.3.4/32
|
routes12=1.2.3.4/32
|
||||||
routes12_options=type=local
|
routes12_options=type=local
|
||||||
address30=1.2.3.30/24
|
address30=1.2.3.30/24
|
||||||
|
@@ -311,6 +311,7 @@ test_read_valid_wired_connection(void)
|
|||||||
|
|
||||||
nmtst_assert_route_attribute_uint32(route, NM_IP_ROUTE_ATTRIBUTE_CWND, 10);
|
nmtst_assert_route_attribute_uint32(route, NM_IP_ROUTE_ATTRIBUTE_CWND, 10);
|
||||||
nmtst_assert_route_attribute_uint32(route, NM_IP_ROUTE_ATTRIBUTE_MTU, 1430);
|
nmtst_assert_route_attribute_uint32(route, NM_IP_ROUTE_ATTRIBUTE_MTU, 1430);
|
||||||
|
nmtst_assert_route_attribute_byte(route, NM_IP_ROUTE_ATTRIBUTE_WEIGHT, 5);
|
||||||
nmtst_assert_route_attribute_boolean(route, NM_IP_ROUTE_ATTRIBUTE_LOCK_CWND, TRUE);
|
nmtst_assert_route_attribute_boolean(route, NM_IP_ROUTE_ATTRIBUTE_LOCK_CWND, TRUE);
|
||||||
nmtst_assert_route_attribute_string(route, NM_IP_ROUTE_ATTRIBUTE_SRC, "7.7.7.7");
|
nmtst_assert_route_attribute_string(route, NM_IP_ROUTE_ATTRIBUTE_SRC, "7.7.7.7");
|
||||||
nmtst_assert_route_attribute_string(route, NM_IP_ROUTE_ATTRIBUTE_TYPE, "unicast");
|
nmtst_assert_route_attribute_string(route, NM_IP_ROUTE_ATTRIBUTE_TYPE, "unicast");
|
||||||
@@ -495,6 +496,7 @@ test_write_wired_connection(void)
|
|||||||
g_assert_no_error(error);
|
g_assert_no_error(error);
|
||||||
nm_ip_route_set_attribute(rt, NM_IP_ROUTE_ATTRIBUTE_CWND, g_variant_new_uint32(10));
|
nm_ip_route_set_attribute(rt, NM_IP_ROUTE_ATTRIBUTE_CWND, g_variant_new_uint32(10));
|
||||||
nm_ip_route_set_attribute(rt, NM_IP_ROUTE_ATTRIBUTE_MTU, g_variant_new_uint32(1492));
|
nm_ip_route_set_attribute(rt, NM_IP_ROUTE_ATTRIBUTE_MTU, g_variant_new_uint32(1492));
|
||||||
|
nm_ip_route_set_attribute(rt, NM_IP_ROUTE_ATTRIBUTE_WEIGHT, g_variant_new_byte(5));
|
||||||
nm_ip_route_set_attribute(rt, NM_IP_ROUTE_ATTRIBUTE_SRC, g_variant_new_string("1.2.3.4"));
|
nm_ip_route_set_attribute(rt, NM_IP_ROUTE_ATTRIBUTE_SRC, g_variant_new_string("1.2.3.4"));
|
||||||
g_assert(nm_setting_ip_config_add_route(s_ip4, rt));
|
g_assert(nm_setting_ip_config_add_route(s_ip4, rt));
|
||||||
nm_ip_route_unref(rt);
|
nm_ip_route_unref(rt);
|
||||||
|
@@ -1278,6 +1278,9 @@ static const NMVariantAttributeSpec *const ip_route_attribute_spec[] = {
|
|||||||
.v4 = TRUE,
|
.v4 = TRUE,
|
||||||
.v6 = TRUE,
|
.v6 = TRUE,
|
||||||
.type_detail = 'T', ),
|
.type_detail = 'T', ),
|
||||||
|
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE(NM_IP_ROUTE_ATTRIBUTE_WEIGHT,
|
||||||
|
G_VARIANT_TYPE_BYTE,
|
||||||
|
.v4 = TRUE, ),
|
||||||
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE(NM_IP_ROUTE_ATTRIBUTE_WINDOW,
|
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE(NM_IP_ROUTE_ATTRIBUTE_WINDOW,
|
||||||
G_VARIANT_TYPE_UINT32,
|
G_VARIANT_TYPE_UINT32,
|
||||||
.v4 = TRUE,
|
.v4 = TRUE,
|
||||||
|
@@ -2501,6 +2501,9 @@ test_setting_ip_route_attributes(void)
|
|||||||
TEST_ATTR("tos", byte, 127, AF_INET, TRUE, TRUE);
|
TEST_ATTR("tos", byte, 127, AF_INET, TRUE, TRUE);
|
||||||
TEST_ATTR("tos", string, "0x28", AF_INET, FALSE, TRUE);
|
TEST_ATTR("tos", string, "0x28", AF_INET, FALSE, TRUE);
|
||||||
|
|
||||||
|
TEST_ATTR("weight", byte, 100, AF_INET, TRUE, TRUE);
|
||||||
|
TEST_ATTR("weight", string, "100", AF_INET, FALSE, TRUE);
|
||||||
|
|
||||||
TEST_ATTR("advmss", uint32, 1400, AF_INET, TRUE, TRUE);
|
TEST_ATTR("advmss", uint32, 1400, AF_INET, TRUE, TRUE);
|
||||||
TEST_ATTR("advmss", string, "1400", AF_INET, FALSE, TRUE);
|
TEST_ATTR("advmss", string, "1400", AF_INET, FALSE, TRUE);
|
||||||
|
|
||||||
@@ -9971,7 +9974,7 @@ test_route_attributes_parse(void)
|
|||||||
g_assert(!ht);
|
g_assert(!ht);
|
||||||
g_clear_error(&error);
|
g_clear_error(&error);
|
||||||
|
|
||||||
ht = nm_utils_parse_variant_attributes("mtu.1400 src.1\\.2\\.3\\.4 ",
|
ht = nm_utils_parse_variant_attributes("mtu.1400 weight.5 src.1\\.2\\.3\\.4 ",
|
||||||
' ',
|
' ',
|
||||||
'.',
|
'.',
|
||||||
FALSE,
|
FALSE,
|
||||||
@@ -9984,6 +9987,11 @@ test_route_attributes_parse(void)
|
|||||||
g_assert(g_variant_is_of_type(variant, G_VARIANT_TYPE_UINT32));
|
g_assert(g_variant_is_of_type(variant, G_VARIANT_TYPE_UINT32));
|
||||||
g_assert_cmpuint(g_variant_get_uint32(variant), ==, 1400);
|
g_assert_cmpuint(g_variant_get_uint32(variant), ==, 1400);
|
||||||
|
|
||||||
|
variant = g_hash_table_lookup(ht, NM_IP_ROUTE_ATTRIBUTE_WEIGHT);
|
||||||
|
g_assert(variant);
|
||||||
|
g_assert(g_variant_is_of_type(variant, G_VARIANT_TYPE_BYTE));
|
||||||
|
g_assert_cmpuint(g_variant_get_byte(variant), ==, 5);
|
||||||
|
|
||||||
variant = g_hash_table_lookup(ht, NM_IP_ROUTE_ATTRIBUTE_SRC);
|
variant = g_hash_table_lookup(ht, NM_IP_ROUTE_ATTRIBUTE_SRC);
|
||||||
g_assert(variant);
|
g_assert(variant);
|
||||||
g_assert(g_variant_is_of_type(variant, G_VARIANT_TYPE_STRING));
|
g_assert(g_variant_is_of_type(variant, G_VARIANT_TYPE_STRING));
|
||||||
|
@@ -144,6 +144,7 @@ gboolean nm_ip_route_attribute_validate(const char *name,
|
|||||||
#define NM_IP_ROUTE_ATTRIBUTE_TOS "tos"
|
#define NM_IP_ROUTE_ATTRIBUTE_TOS "tos"
|
||||||
#define NM_IP_ROUTE_ATTRIBUTE_TYPE "type"
|
#define NM_IP_ROUTE_ATTRIBUTE_TYPE "type"
|
||||||
#define NM_IP_ROUTE_ATTRIBUTE_WINDOW "window"
|
#define NM_IP_ROUTE_ATTRIBUTE_WINDOW "window"
|
||||||
|
#define NM_IP_ROUTE_ATTRIBUTE_WEIGHT "weight"
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user