From 13a462b9d5dc9ccbbabdf8a37fd4b97c2e048d43 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 8 Nov 2023 03:49:12 +0900 Subject: [PATCH 1/5] network-generator: relax requirement for peer address, route destination, and gateway No functional changes, as the caller already sets them. --- src/network/generator/network-generator.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/network/generator/network-generator.c b/src/network/generator/network-generator.c index 9bc7aa19eb..3a067004dd 100644 --- a/src/network/generator/network-generator.c +++ b/src/network/generator/network-generator.c @@ -119,7 +119,7 @@ static int address_new(Network *network, int family, unsigned char prefixlen, .family = family, .prefixlen = prefixlen, .address = *addr, - .peer = *peer, + .peer = peer ? *peer : IN_ADDR_NULL, }; LIST_PREPEND(addresses, network->addresses, address); @@ -146,6 +146,8 @@ static int route_new(Network *network, int family, unsigned char prefixlen, Route *route; assert(network); + assert(IN_SET(family, AF_INET, AF_INET6)); + assert(dest || gateway); route = new(Route, 1); if (!route) @@ -155,7 +157,7 @@ static int route_new(Network *network, int family, unsigned char prefixlen, .family = family, .prefixlen = prefixlen, .dest = dest ? *dest : IN_ADDR_NULL, - .gateway = *gateway, + .gateway = gateway ? *gateway : IN_ADDR_NULL, }; LIST_PREPEND(routes, network->routes, route); @@ -426,7 +428,8 @@ static int network_set_route(Context *context, const char *ifname, int family, u Network *network; int r; - if (!in_addr_is_set(family, gateway)) + if (!(dest && in_addr_is_set(family, dest)) && + !(gateway && in_addr_is_set(family, gateway))) return 0; network = network_get(context, ifname); @@ -1150,8 +1153,9 @@ static int route_dump(Route *route, FILE *f) { if (in_addr_is_set(route->family, &route->dest)) fprintf(f, "Destination=%s\n", IN_ADDR_PREFIX_TO_STRING(route->family, &route->dest, route->prefixlen)); - fprintf(f, "Gateway=%s\n", - IN_ADDR_TO_STRING(route->family, &route->gateway)); + if (in_addr_is_set(route->family, &route->gateway)) + fprintf(f, "Gateway=%s\n", + IN_ADDR_TO_STRING(route->family, &route->gateway)); return 0; } From 0b0865f50921a562d6dee454ad05567f875de8fe Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 8 Nov 2023 03:54:50 +0900 Subject: [PATCH 2/5] network-generator: drop unused family argument --- src/network/generator/network-generator.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/network/generator/network-generator.c b/src/network/generator/network-generator.c index 3a067004dd..6a1902b31c 100644 --- a/src/network/generator/network-generator.c +++ b/src/network/generator/network-generator.c @@ -389,14 +389,17 @@ static int network_set_hostname(Context *context, const char *ifname, const char return free_and_strdup(&network->hostname, hostname); } -static int network_set_mtu(Context *context, const char *ifname, int family, const char *mtu) { +static int network_set_mtu(Context *context, const char *ifname, const char *mtu) { Network *network; + if (isempty(mtu)) + return 0; + network = network_get(context, ifname); if (!network) return -ENODEV; - return parse_mtu(family, mtu, &network->mtu); + return parse_mtu(AF_UNSPEC, mtu, &network->mtu); } static int network_set_mac_address(Context *context, const char *ifname, const char *mac) { @@ -519,7 +522,7 @@ static int network_set_bond(Context *context, const char *ifname, const char *va return free_and_strdup(&network->bond, value); } -static int parse_cmdline_ip_mtu_mac(Context *context, const char *ifname, int family, const char *value) { +static int parse_cmdline_ip_mtu_mac(Context *context, const char *ifname, const char *value) { const char *mtu, *p; int r; @@ -531,11 +534,9 @@ static int parse_cmdline_ip_mtu_mac(Context *context, const char *ifname, int fa else mtu = strndupa_safe(value, p - value); - if (!isempty(mtu)) { - r = network_set_mtu(context, ifname, family, mtu); - if (r < 0) - return r; - } + r = network_set_mtu(context, ifname, mtu); + if (r < 0) + return r; if (!p || isempty(p + 1)) return 0; @@ -726,7 +727,7 @@ static int parse_cmdline_ip_address(Context *context, int family, const char *va return 0; /* First, try [][:] */ - r = parse_cmdline_ip_mtu_mac(context, ifname, AF_UNSPEC, p + 1); + r = parse_cmdline_ip_mtu_mac(context, ifname, p + 1); if (r >= 0) return 0; @@ -768,7 +769,7 @@ static int parse_cmdline_ip_interface(Context *context, const char *value) { if (!p) return 0; - return parse_cmdline_ip_mtu_mac(context, ifname, AF_UNSPEC, p + 1); + return parse_cmdline_ip_mtu_mac(context, ifname, p + 1); } static int parse_cmdline_ip(Context *context, const char *key, const char *value) { From 8ae81a1e00eb4ade24c86bc77cdd594d8dcb8d6a Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 8 Nov 2023 03:56:53 +0900 Subject: [PATCH 3/5] network-generator: add missing assertions --- src/network/generator/network-generator.c | 108 +++++++++++++++++++++- 1 file changed, 106 insertions(+), 2 deletions(-) diff --git a/src/network/generator/network-generator.c b/src/network/generator/network-generator.c index 6a1902b31c..ea02bbf180 100644 --- a/src/network/generator/network-generator.c +++ b/src/network/generator/network-generator.c @@ -110,6 +110,8 @@ static int address_new(Network *network, int family, unsigned char prefixlen, Address *address; assert(network); + assert(IN_SET(family, AF_INET, AF_INET6)); + assert(addr); address = new(Address, 1); if (!address) @@ -250,6 +252,7 @@ static int netdev_new(Context *context, const char *_kind, const char *_ifname, int r; assert(context); + assert(_kind); if (!ifname_valid(_ifname)) return -EINVAL; @@ -364,6 +367,10 @@ static int network_set_dhcp_type(Context *context, const char *ifname, const cha DHCPType t; int r; + assert(context); + assert(ifname); + assert(dhcp_type); + t = dracut_dhcp_type_from_string(dhcp_type); if (t < 0) return t; @@ -382,6 +389,9 @@ static int network_set_dhcp_type(Context *context, const char *ifname, const cha static int network_set_hostname(Context *context, const char *ifname, const char *hostname) { Network *network; + assert(context); + assert(ifname); + network = network_get(context, ifname); if (!network) return -ENODEV; @@ -392,6 +402,9 @@ static int network_set_hostname(Context *context, const char *ifname, const char static int network_set_mtu(Context *context, const char *ifname, const char *mtu) { Network *network; + assert(context); + assert(ifname); + if (isempty(mtu)) return 0; @@ -405,6 +418,10 @@ static int network_set_mtu(Context *context, const char *ifname, const char *mtu static int network_set_mac_address(Context *context, const char *ifname, const char *mac) { Network *network; + assert(context); + assert(ifname); + assert(mac); + network = network_get(context, ifname); if (!network) return -ENODEV; @@ -416,6 +433,11 @@ static int network_set_address(Context *context, const char *ifname, int family, union in_addr_union *addr, union in_addr_union *peer) { Network *network; + assert(context); + assert(ifname); + assert(IN_SET(family, AF_INET, AF_INET6)); + assert(addr); + if (!in_addr_is_set(family, addr)) return 0; @@ -431,6 +453,10 @@ static int network_set_route(Context *context, const char *ifname, int family, u Network *network; int r; + assert(context); + assert(ifname); + assert(IN_SET(family, AF_INET, AF_INET6)); + if (!(dest && in_addr_is_set(family, dest)) && !(gateway && in_addr_is_set(family, gateway))) return 0; @@ -450,6 +476,10 @@ static int network_set_dns(Context *context, const char *ifname, const char *dns Network *network; int family, r; + assert(context); + assert(ifname); + assert(dns); + r = in_addr_from_string_auto(dns, &family, &a); if (r < 0) return r; @@ -468,6 +498,9 @@ static int network_set_dhcp_use_dns(Context *context, const char *ifname, bool v Network *network; int r; + assert(context); + assert(ifname); + network = network_get(context, ifname); if (!network) { r = network_new(context, ifname, &network); @@ -484,6 +517,9 @@ static int network_set_vlan(Context *context, const char *ifname, const char *va Network *network; int r; + assert(context); + assert(ifname); + network = network_get(context, ifname); if (!network) { r = network_new(context, ifname, &network); @@ -498,6 +534,9 @@ static int network_set_bridge(Context *context, const char *ifname, const char * Network *network; int r; + assert(context); + assert(ifname); + network = network_get(context, ifname); if (!network) { r = network_new(context, ifname, &network); @@ -512,6 +551,9 @@ static int network_set_bond(Context *context, const char *ifname, const char *va Network *network; int r; + assert(context); + assert(ifname); + network = network_get(context, ifname); if (!network) { r = network_new(context, ifname, &network); @@ -526,6 +568,10 @@ static int parse_cmdline_ip_mtu_mac(Context *context, const char *ifname, const const char *mtu, *p; int r; + assert(context); + assert(ifname); + assert(value); + /* [][:] */ p = strchr(value, ':'); @@ -549,9 +595,15 @@ static int parse_cmdline_ip_mtu_mac(Context *context, const char *ifname, const } static int parse_ip_address_one(int family, const char **value, union in_addr_union *ret) { - const char *p = *value, *q, *buf; + const char *p, *q, *buf; int r; + assert(IN_SET(family, AF_INET, AF_INET6)); + assert(value); + assert(ret); + + p = ASSERT_PTR(*value); + if (p[0] == ':') { *value = p + 1; return 0; @@ -592,6 +644,11 @@ static int parse_netmask_or_prefixlen(int family, const char **value, unsigned c const char *p, *q; int r; + assert(IN_SET(family, AF_INET, AF_INET6)); + assert(value); + assert(*value); + assert(ret); + r = parse_ip_address_one(family, value, &netmask); if (r > 0) { if (family == AF_INET6) @@ -618,9 +675,16 @@ static int parse_netmask_or_prefixlen(int family, const char **value, unsigned c } static int parse_ip_dns_address_one(Context *context, const char *ifname, int family, const char **value) { - const char *p = *value, *q, *buf; + const char *p, *q, *buf; int r; + assert(context); + assert(ifname); + assert(IN_SET(family, AF_INET, AF_INET6)); + assert(value); + + p = ASSERT_PTR(*value); + if (isempty(p)) return 0; @@ -661,6 +725,10 @@ static int parse_cmdline_ip_address(Context *context, int family, const char *va unsigned char prefixlen; int r; + assert(context); + assert(IN_SET(family, AF_INET, AF_INET6)); + assert(value); + /* ip=:[]:::::{none|off|dhcp|on|any|dhcp6|auto6|ibft|link6}[:[][:]] * ip=:[]:::::{none|off|dhcp|on|any|dhcp6|auto6|ibft|link6}[:[][:]] */ @@ -747,6 +815,9 @@ static int parse_cmdline_ip_interface(Context *context, const char *value) { const char *ifname, *dhcp_type, *p; int r; + assert(context); + assert(value); + /* ip=:{dhcp|on|any|dhcp6|auto6|link6}[:[][:]] */ p = strchr(value, ':'); @@ -776,6 +847,9 @@ static int parse_cmdline_ip(Context *context, const char *key, const char *value const char *p; int r; + assert(context); + assert(key); + if (proc_cmdline_value_missing(key, value)) return -EINVAL; @@ -800,6 +874,9 @@ static int parse_cmdline_rd_route(Context *context, const char *key, const char const char *buf, *p; int family, r; + assert(context); + assert(key); + /* rd.route=/:[:] */ if (proc_cmdline_value_missing(key, value)) @@ -842,6 +919,9 @@ static int parse_cmdline_rd_route(Context *context, const char *key, const char } static int parse_cmdline_nameserver(Context *context, const char *key, const char *value) { + assert(context); + assert(key); + if (proc_cmdline_value_missing(key, value)) return -EINVAL; @@ -851,6 +931,9 @@ static int parse_cmdline_nameserver(Context *context, const char *key, const cha static int parse_cmdline_rd_peerdns(Context *context, const char *key, const char *value) { int r; + assert(context); + assert(key); + if (proc_cmdline_value_missing(key, value)) return network_set_dhcp_use_dns(context, "", true); @@ -866,6 +949,9 @@ static int parse_cmdline_vlan(Context *context, const char *key, const char *val NetDev *netdev; int r; + assert(context); + assert(key); + if (proc_cmdline_value_missing(key, value)) return -EINVAL; @@ -890,6 +976,9 @@ static int parse_cmdline_bridge(Context *context, const char *key, const char *v NetDev *netdev; int r; + assert(context); + assert(key); + if (proc_cmdline_value_missing(key, value)) return -EINVAL; @@ -928,6 +1017,9 @@ static int parse_cmdline_bond(Context *context, const char *key, const char *val NetDev *netdev; int r; + assert(context); + assert(key); + if (proc_cmdline_value_missing(key, value)) return -EINVAL; @@ -985,6 +1077,9 @@ static int parse_cmdline_ifname(Context *context, const char *key, const char *v const char *name, *p; int r; + assert(context); + assert(key); + /* ifname=: */ if (proc_cmdline_value_missing(key, value)) @@ -1009,6 +1104,9 @@ static int parse_cmdline_ifname_policy(Context *context, const char *key, const Link *link; int r; + assert(context); + assert(key); + /* net.ifname-policy=policy1[,policy2,...][,] */ if (proc_cmdline_value_missing(key, value)) @@ -1139,6 +1237,9 @@ void context_clear(Context *context) { } static int address_dump(Address *address, FILE *f) { + assert(address); + assert(f); + fprintf(f, "\n[Address]\n" "Address=%s\n", @@ -1150,6 +1251,9 @@ static int address_dump(Address *address, FILE *f) { } static int route_dump(Route *route, FILE *f) { + assert(route); + assert(f); + fputs("\n[Route]\n", f); if (in_addr_is_set(route->family, &route->dest)) fprintf(f, "Destination=%s\n", From 816c269e55220924c4f8b712afd976e83ec0359e Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 8 Nov 2023 04:09:48 +0900 Subject: [PATCH 4/5] network-generator: allow to specify both IPv4 and IPv6 DNS servers Follow-up for 923599523c10d8897551e081e6b00cd8002309c3. --- src/network/generator/network-generator.c | 32 +++++++++++++---------- test/test-network-generator-conversion.sh | 1 + 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/network/generator/network-generator.c b/src/network/generator/network-generator.c index ea02bbf180..2863511b6c 100644 --- a/src/network/generator/network-generator.c +++ b/src/network/generator/network-generator.c @@ -471,16 +471,20 @@ static int network_set_route(Context *context, const char *ifname, int family, u return route_new(network, family, prefixlen, dest, gateway, NULL); } -static int network_set_dns(Context *context, const char *ifname, const char *dns) { +static int network_set_dns(Context *context, const char *ifname, int family, const char *dns) { union in_addr_union a; Network *network; - int family, r; + int r; assert(context); assert(ifname); + assert(IN_SET(family, AF_UNSPEC, AF_INET, AF_INET6)); assert(dns); - r = in_addr_from_string_auto(dns, &family, &a); + if (family == AF_UNSPEC) + r = in_addr_from_string_auto(dns, &family, &a); + else + r = in_addr_from_string(family, dns, &a); if (r < 0) return r; @@ -674,13 +678,12 @@ static int parse_netmask_or_prefixlen(int family, const char **value, unsigned c return 0; } -static int parse_ip_dns_address_one(Context *context, const char *ifname, int family, const char **value) { +static int parse_ip_dns_address_one(Context *context, const char *ifname, const char **value) { const char *p, *q, *buf; - int r; + int r, family; assert(context); assert(ifname); - assert(IN_SET(family, AF_INET, AF_INET6)); assert(value); p = ASSERT_PTR(*value); @@ -688,16 +691,16 @@ static int parse_ip_dns_address_one(Context *context, const char *ifname, int fa if (isempty(p)) return 0; - if (family == AF_INET6) { - if (p[0] != '[') - return -EINVAL; - + if (p[0] == '[') { q = strchr(p + 1, ']'); if (!q) return -EINVAL; + if (!IN_SET(q[1], ':', '\0')) + return -EINVAL; buf = strndupa_safe(p + 1, q - p - 1); p = q + 1; + family = AF_INET6; } else { q = strchr(p, ':'); if (!q) @@ -706,9 +709,10 @@ static int parse_ip_dns_address_one(Context *context, const char *ifname, int fa buf = strndupa_safe(*value, q - *value); p += strlen(buf); + family = AF_INET; } - r = network_set_dns(context, ifname, buf); + r = network_set_dns(context, ifname, family, buf); if (r < 0) return r; @@ -801,10 +805,10 @@ static int parse_cmdline_ip_address(Context *context, int family, const char *va /* Next, try [][:] */ value = p + 1; - r = parse_ip_dns_address_one(context, ifname, family, &value); + r = parse_ip_dns_address_one(context, ifname, &value); if (r < 0) return r; - r = parse_ip_dns_address_one(context, ifname, family, &value); + r = parse_ip_dns_address_one(context, ifname, &value); if (r < 0) return r; @@ -925,7 +929,7 @@ static int parse_cmdline_nameserver(Context *context, const char *key, const cha if (proc_cmdline_value_missing(key, value)) return -EINVAL; - return network_set_dns(context, "", value); + return network_set_dns(context, "", AF_UNSPEC, value); } static int parse_cmdline_rd_peerdns(Context *context, const char *key, const char *value) { diff --git a/test/test-network-generator-conversion.sh b/test/test-network-generator-conversion.sh index 7c853e8987..a9ab1b0e7f 100755 --- a/test/test-network-generator-conversion.sh +++ b/test/test-network-generator-conversion.sh @@ -280,6 +280,7 @@ COMMAND_LINES=( "ip=:::::dhcp99:dhcp6:666:52:54:00:a7:8f:ac" "ip=:::::dhcp99:dhcp6:10.0.0.128" "ip=:::::dhcp99:dhcp6:10.0.0.128:10.0.0.129" + "ip=:::::dhcp99:dhcp6:10.0.0.128:[fdef:c400:bd01:1096::bbbb]" "ip=::::::any" "ip=::::::ibft" ) From b86f60bfb3340a9fa27cb6f127fba7c827481b50 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 8 Nov 2023 04:28:02 +0900 Subject: [PATCH 5/5] network-generator: refuse unexpected trailing strings --- src/network/generator/network-generator.c | 9 ++++++--- test/test-network-generator-conversion.sh | 3 +++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/network/generator/network-generator.c b/src/network/generator/network-generator.c index 2863511b6c..48527a2c73 100644 --- a/src/network/generator/network-generator.c +++ b/src/network/generator/network-generator.c @@ -716,9 +716,6 @@ static int parse_ip_dns_address_one(Context *context, const char *ifname, const if (r < 0) return r; - if (p[0] == ':') - p++; - *value = p; return 0; } @@ -808,10 +805,16 @@ static int parse_cmdline_ip_address(Context *context, int family, const char *va r = parse_ip_dns_address_one(context, ifname, &value); if (r < 0) return r; + + value += *value == ':'; r = parse_ip_dns_address_one(context, ifname, &value); if (r < 0) return r; + /* refuse unexpected trailing strings */ + if (!isempty(value)) + return -EINVAL; + return 0; } diff --git a/test/test-network-generator-conversion.sh b/test/test-network-generator-conversion.sh index a9ab1b0e7f..f03847c1fa 100755 --- a/test/test-network-generator-conversion.sh +++ b/test/test-network-generator-conversion.sh @@ -302,6 +302,9 @@ INVALID_COMMAND_LINES=( "ip=fdef:c400:bd01:1096::2::[fdef:c400:bd01:1096::1]:64::ipv6:off:[fdef:c400:bd01:1096::aaaa]" "ip=[fdef:c400:bd01:1096::2]::[fdef:c400:bd01:1096::1]:64::ipv6:off:foo" "ip=[fdef:c400:bd01:1096::2]::[fdef:c400:bd01:1096::1]:64::ipv6:off:[fdef:c400:bd01:1096::aaaa]:foo" + "ip=[fdef:c400:bd01:1096::2]::[fdef:c400:bd01:1096::1]:64::ipv6:off:[fdef:c400:bd01:1096::aaaa]:[fdef:c400:bd01:1096::bbbb]:" + "ip=:::::dhcp99:dhcp6:10.0.0.128:10.0.0.129:" + "ip=:::::dhcp99:dhcp6:10.0.0.128:[fdef:c400:bd01:1096::bbbb]:" ) for cmdline in "${INVALID_COMMAND_LINES[@]}"; do (! SYSTEMD_LOG_LEVEL=debug SYSTEMD_PROC_CMDLINE="$cmdline" "$GENERATOR_BIN")