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:
Fernando Fernandez Mancera
2022-09-29 12:15:30 +02:00
parent 59f68a8d4e
commit af26b19dae
10 changed files with 40 additions and 4 deletions

View File

@@ -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_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);
}

View File

@@ -887,6 +887,7 @@ enum {
PARSE_LINE_ATTR_ROUTE_ADVMSS,
PARSE_LINE_ATTR_ROUTE_RTO_MIN,
PARSE_LINE_ATTR_ROUTE_QUICKACK,
PARSE_LINE_ATTR_ROUTE_WEIGHT,
/* iproute2 arguments that only matter when parsing the file. */
PARSE_LINE_ATTR_ROUTE_TO,
@@ -966,6 +967,12 @@ parse_route_line(const char *line,
.int_base_16 = TRUE,
.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] =
{
.key = NM_IP_ROUTE_ATTRIBUTE_SCOPE,

View File

@@ -2360,7 +2360,9 @@ get_route_attributes_string(NMIPRoute *route, int family)
/* we also have a corresponding attribute with the numeric value. The
* 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));
} 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));

View File

@@ -6,7 +6,7 @@ ADDRESS1=44.55.66.77
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 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
NETMASK2=255.255.255.255

View File

@@ -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_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_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_INITRWND, 14);
nmtst_assert_route_attribute_uint32(ip4_route, NM_IP_ROUTE_ATTRIBUTE_MTU, 9000);
@@ -4279,6 +4280,7 @@ static void
test_write_wired_static(void)
{
nmtst_auto_unlinkfile char *testfile = NULL;
nmtst_auto_unlinkfile char *route4file = NULL;
nmtst_auto_unlinkfile char *route6file = NULL;
gs_unref_object NMConnection *connection = NULL;
gs_unref_object NMConnection *reread = NULL;
@@ -4288,6 +4290,7 @@ test_write_wired_static(void)
NMSettingIPConfig *s_ip6, *reread_s_ip6;
NMIPAddress *addr;
NMIPAddress *addr6;
NMIPRoute *route4;
NMIPRoute *route6;
GError *error = NULL;
@@ -4392,6 +4395,13 @@ test_write_wired_static(void)
nm_setting_ip_config_add_route(s_ip6, 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 */
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");
@@ -4403,7 +4413,9 @@ test_write_wired_static(void)
nmtst_assert_connection_verifies(connection);
_writer_new_connection(connection, TEST_SCRATCH_DIR, &testfile);
route6file = utils_get_route6_path(testfile);
route4file = utils_get_route_path(testfile);
reread = _connection_from_file(testfile, NULL, TYPE_ETHERNET, NULL);

View File

@@ -36,7 +36,7 @@ routes9=1.1.1.9/19,0.0.0.0,0
route10=1.1.1.10/21,,0
routes10=1.1.1.10/20,,0
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_options=type=local
address30=1.2.3.30/24

View File

@@ -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_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_string(route, NM_IP_ROUTE_ATTRIBUTE_SRC, "7.7.7.7");
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);
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_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"));
g_assert(nm_setting_ip_config_add_route(s_ip4, rt));
nm_ip_route_unref(rt);

View File

@@ -1278,6 +1278,9 @@ static const NMVariantAttributeSpec *const ip_route_attribute_spec[] = {
.v4 = TRUE,
.v6 = TRUE,
.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,
G_VARIANT_TYPE_UINT32,
.v4 = TRUE,

View File

@@ -2501,6 +2501,9 @@ test_setting_ip_route_attributes(void)
TEST_ATTR("tos", byte, 127, AF_INET, TRUE, 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", string, "1400", AF_INET, FALSE, TRUE);
@@ -9971,7 +9974,7 @@ test_route_attributes_parse(void)
g_assert(!ht);
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,
@@ -9984,6 +9987,11 @@ test_route_attributes_parse(void)
g_assert(g_variant_is_of_type(variant, G_VARIANT_TYPE_UINT32));
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);
g_assert(variant);
g_assert(g_variant_is_of_type(variant, G_VARIANT_TYPE_STRING));

View File

@@ -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_TYPE "type"
#define NM_IP_ROUTE_ATTRIBUTE_WINDOW "window"
#define NM_IP_ROUTE_ATTRIBUTE_WEIGHT "weight"
/*****************************************************************************/