dhcp: cleanup ip4_process_dhclient_rfc3442_routes()
- use nm_utils_strsplit_set_full() instead of g_strsplit_set() to avoid allocating a full strv array. - refactor the code to return early and use cleanup attribute for freeing memory. - return TRUE/FALSE from process_dhclient_rfc3442_route(). It's simpler to understand than returning the moved pointer and a success output variable.
This commit is contained in:
@@ -100,67 +100,56 @@ out:
|
|||||||
return have_routes;
|
return have_routes;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char **
|
static gboolean
|
||||||
process_dhclient_rfc3442_route (const char **octets,
|
process_dhclient_rfc3442_route (const char *const**p_octets,
|
||||||
NMPlatformIP4Route *route,
|
NMPlatformIP4Route *route)
|
||||||
gboolean *success)
|
|
||||||
{
|
{
|
||||||
const char **o = octets;
|
const char *const*o = *p_octets;
|
||||||
int addr_len = 0, i = 0;
|
gs_free char *next_hop = NULL;
|
||||||
long int tmp;
|
int addr_len;
|
||||||
char *next_hop;
|
int v_plen;
|
||||||
guint32 tmp_addr;
|
in_addr_t tmp_addr;
|
||||||
|
in_addr_t v_network = 0;
|
||||||
|
|
||||||
*success = FALSE;
|
v_plen = _nm_utils_ascii_str_to_int64 (*o, 10, 0, 32, -1);
|
||||||
|
if (v_plen == -1)
|
||||||
if (!*o)
|
return FALSE;
|
||||||
return o; /* no prefix */
|
|
||||||
|
|
||||||
tmp = strtol (*o, NULL, 10);
|
|
||||||
if (tmp < 0 || tmp > 32) /* 32 == max IP4 prefix length */
|
|
||||||
return o;
|
|
||||||
|
|
||||||
memset (route, 0, sizeof (*route));
|
|
||||||
route->plen = tmp;
|
|
||||||
o++;
|
o++;
|
||||||
|
|
||||||
if (tmp > 0)
|
addr_len = v_plen > 0
|
||||||
addr_len = ((tmp - 1) / 8) + 1;
|
? ((v_plen - 1) / 8) + 1
|
||||||
|
: 0;
|
||||||
|
|
||||||
/* ensure there's at least the address + next hop left */
|
/* ensure there's at least the address + next hop left */
|
||||||
if (g_strv_length ((char **) o) < addr_len + 4)
|
if (NM_PTRARRAY_LEN (o) < addr_len + 4)
|
||||||
goto error;
|
return FALSE;
|
||||||
|
|
||||||
if (tmp) {
|
if (v_plen > 0) {
|
||||||
const char *addr[4] = { "0", "0", "0", "0" };
|
const char *addr[4] = { "0", "0", "0", "0" };
|
||||||
char *str_addr;
|
gs_free char *str_addr = NULL;
|
||||||
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < addr_len; i++)
|
for (i = 0; i < addr_len; i++)
|
||||||
addr[i] = *o++;
|
addr[i] = *o++;
|
||||||
|
|
||||||
str_addr = g_strjoin (".", addr[0], addr[1], addr[2], addr[3], NULL);
|
str_addr = g_strjoin (".", addr[0], addr[1], addr[2], addr[3], NULL);
|
||||||
if (inet_pton (AF_INET, str_addr, &tmp_addr) <= 0) {
|
if (inet_pton (AF_INET, str_addr, &tmp_addr) <= 0)
|
||||||
g_free (str_addr);
|
return FALSE;
|
||||||
goto error;
|
v_network = nm_utils_ip4_address_clear_host_address (tmp_addr, v_plen);
|
||||||
}
|
|
||||||
g_free (str_addr);
|
|
||||||
route->network = nm_utils_ip4_address_clear_host_address (tmp_addr, tmp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle next hop */
|
|
||||||
next_hop = g_strjoin (".", o[0], o[1], o[2], o[3], NULL);
|
next_hop = g_strjoin (".", o[0], o[1], o[2], o[3], NULL);
|
||||||
if (inet_pton (AF_INET, next_hop, &tmp_addr) <= 0) {
|
o += 4;
|
||||||
g_free (next_hop);
|
if (inet_pton (AF_INET, next_hop, &tmp_addr) <= 0)
|
||||||
goto error;
|
return FALSE;
|
||||||
}
|
|
||||||
route->gateway = tmp_addr;
|
|
||||||
g_free (next_hop);
|
|
||||||
|
|
||||||
*success = TRUE;
|
*route = (NMPlatformIP4Route) {
|
||||||
return o + 4; /* advance to past the next hop */
|
.network = v_network,
|
||||||
|
.plen = v_plen,
|
||||||
error:
|
.gateway = tmp_addr,
|
||||||
return o;
|
};
|
||||||
|
*p_octets = o;
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@@ -171,23 +160,23 @@ ip4_process_dhclient_rfc3442_routes (const char *iface,
|
|||||||
NMIP4Config *ip4_config,
|
NMIP4Config *ip4_config,
|
||||||
guint32 *gwaddr)
|
guint32 *gwaddr)
|
||||||
{
|
{
|
||||||
char **octets, **o;
|
gs_free const char **octets = NULL;
|
||||||
|
const char *const*o;
|
||||||
gboolean have_routes = FALSE;
|
gboolean have_routes = FALSE;
|
||||||
NMPlatformIP4Route route;
|
|
||||||
gboolean success;
|
|
||||||
|
|
||||||
o = octets = g_strsplit_set (str, " .", 0);
|
octets = nm_utils_strsplit_set_with_empty (str, " .");
|
||||||
if (g_strv_length (octets) < 5) {
|
if (NM_PTRARRAY_LEN (octets) < 5) {
|
||||||
_LOG2W (LOGD_DHCP4, iface, "ignoring invalid classless static routes '%s'", str);
|
_LOG2W (LOGD_DHCP4, iface, "ignoring invalid classless static routes '%s'", str);
|
||||||
goto out;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
o = octets;
|
||||||
while (*o) {
|
while (*o) {
|
||||||
memset (&route, 0, sizeof (route));
|
NMPlatformIP4Route route;
|
||||||
o = (char **) process_dhclient_rfc3442_route ((const char **) o, &route, &success);
|
|
||||||
if (!success) {
|
if (!process_dhclient_rfc3442_route (&o, &route)) {
|
||||||
_LOG2W (LOGD_DHCP4, iface, "ignoring invalid classless static routes");
|
_LOG2W (LOGD_DHCP4, iface, "ignoring invalid classless static routes");
|
||||||
break;
|
return have_routes;
|
||||||
}
|
}
|
||||||
|
|
||||||
have_routes = TRUE;
|
have_routes = TRUE;
|
||||||
@@ -211,8 +200,6 @@ ip4_process_dhclient_rfc3442_routes (const char *iface,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
|
||||||
g_strfreev (octets);
|
|
||||||
return have_routes;
|
return have_routes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user