Commit 76619e45 authored by Mu Qiao's avatar Mu Qiao Committed by Dan Williams
Browse files

ifnet: support reading openrc style

IP configuration like 192.168.1.{2..4} is not supported anymore.
parent 7735b8d7
......@@ -562,7 +562,7 @@ make_wired_connection_setting (NMConnection *connection,
nm_connection_add_setting (connection, NM_SETTING (s_wired));
}
/* add NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME,
/* add NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME,
* NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID in future*/
static void
make_ip4_setting (NMConnection *connection,
......@@ -591,19 +591,19 @@ make_ip4_setting (NMConnection *connection,
g_object_unref (ip4_setting);
return;
}
if (!strcmp (method, "dhcp"))
if (strstr (method, "dhcp"))
g_object_set (ip4_setting,
NM_SETTING_IP4_CONFIG_METHOD,
NM_SETTING_IP4_CONFIG_METHOD_AUTO,
NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, FALSE, NULL);
else if (!strcmp (method, "autoip")){
else if (strstr (method, "autoip")) {
g_object_set (ip4_setting,
NM_SETTING_IP4_CONFIG_METHOD,
NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL,
NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, FALSE, NULL);
nm_connection_add_setting (connection, NM_SETTING (ip4_setting));
return;
} else if (!strcmp (method, "shared")){
} else if (strstr (method, "shared")) {
g_object_set (ip4_setting,
NM_SETTING_IP4_CONFIG_METHOD,
NM_SETTING_IP4_CONFIG_METHOD_SHARED,
......@@ -658,7 +658,7 @@ make_ip4_setting (NMConnection *connection,
}
/* add dhcp hostname and client id */
if (!is_static_block && !strcmp (method, "dhcp")) {
if (!is_static_block && strstr (method, "dhcp")) {
gchar *dhcp_hostname, *client_id;
get_dhcp_hostname_and_client_id (&dhcp_hostname, &client_id);
......@@ -863,7 +863,7 @@ make_ip6_setting (NMConnection *connection,
nm_ip6_route_set_dest (route, iblock->ip);
nm_ip6_route_set_next_hop (route, iblock->next_hop);
nm_ip6_route_set_prefix (route, iblock->prefix);
/* metric is not per routes configuration right now
/* metric is not per routes configuration right now
* global metric is also supported (metric="x") */
if ((metric_str = ifnet_get_data (conn_name, "metric")) != NULL) {
metric = strtol (metric_str, NULL, 10);
......@@ -990,7 +990,7 @@ make_wireless_connection_setting (const char *conn_name,
goto error;
}
/* mode=0: infrastructure
/* mode=0: infrastructure
* mode=1: adhoc */
value = wpa_get_value (conn_name, "mode");
if (value)
......
......@@ -169,12 +169,10 @@ init_block_by_line (gchar * buf)
conn = add_new_connection_config ("wireless", pos);
}
data = g_strdup (key_value[1]);
tmp = strip_string (data, '(');
tmp = strip_string (tmp, ')');
strip_string (tmp, '"');
tmp = strip_string (data, '"');
strip_string (tmp, '\'');
if (conn)
g_hash_table_insert (conn, g_strdup (key_value[0]),
g_hash_table_insert (conn, strip_string (g_strdup (key_value[0]), ' '),
g_strdup (tmp));
g_free (data);
g_strfreev (key_value);
......@@ -288,6 +286,20 @@ is_function (gchar * line)
return FALSE;
}
static void
append_line (GString *buf, gchar* line)
{
gchar *pos = NULL;
if ((pos = strchr (line, '#')) != NULL)
*pos = '\0';
g_strstrip (line);
if (line[0] != '\0')
g_string_append_printf (buf, " %s", line);
g_free (line);
}
gboolean
ifnet_init (gchar * config_file)
{
......@@ -297,6 +309,8 @@ ifnet_init (gchar * config_file)
/* Handle multiple lines with brackets */
gboolean complete = TRUE;
gboolean openrc_style = TRUE;
/* line buffer */
GString *buf;
......@@ -324,36 +338,60 @@ ifnet_init (gchar * config_file)
strip_function (channel, line);
continue;
}
if (line[0] != '#' && line[0] != '\0') {
gchar *pos = NULL;
// New openrc style, bash arrays are not allowed. We only care about '"'
if (openrc_style && line[0] != '#' && line[0] != '\0'
&& !strchr (line, '(') && !strchr (line, ')')) {
gchar *tmp = line;
while ((tmp = strchr (tmp, '"')) != NULL) {
complete = !complete;
++tmp;
}
append_line (buf, line);
// Add "(separator) for routes. It will be easier for later parsing
if (strstr (buf->str, "via"))
g_string_append_printf (buf, "\"");
if (!complete)
continue;
strip_string (buf->str, '"');
init_block_by_line (buf->str);
g_string_free (buf, TRUE);
buf = g_string_new (NULL);
}
// Old bash arrays for baselayout-1, to be deleted
else if (line[0] != '#' && line[0] != '\0') {
if (!complete) {
complete =
g_strrstr (line,
")") == NULL ? FALSE : TRUE;
if ((pos = strchr (line, '#')) != NULL)
*pos = '\0';
g_strstrip (line);
if (line[0] != '\0') {
g_string_append_printf (buf,
" %s", line);
}
g_free (line);
if (!complete)
append_line (buf, line);
if (!complete) {
openrc_style = FALSE;
continue;
}
else {
openrc_style = TRUE;
}
} else {
complete =
(g_strrstr (line, "(") != NULL
&& g_strrstr (line, ")") != NULL)
|| g_strrstr (line, "(") == NULL;
if ((pos = strchr (line, '#')) != NULL)
*pos = '\0';
g_strstrip (line);
if (line[0] != '\0')
g_string_append (buf, line);
g_free (line);
append_line (buf, line);
if (!complete)
{
openrc_style = FALSE;
continue;
} else {
openrc_style = TRUE;
}
}
init_block_by_line (buf->str);
g_string_free (buf, TRUE);
......@@ -396,7 +434,7 @@ ifnet_set_data (const char *conn_name, const char *key, const char *value)
}
/* Remove existing key value pair */
if (g_hash_table_lookup_extended (conn, key, &old_key, &old_value)) {
if (stripped && !strcmp(old_value, stripped)){
if (stripped && !strcmp (old_value, stripped)) {
g_free (stripped);
return;
}
......
......@@ -352,6 +352,49 @@ is_ip6_address (const char *in_address)
}
// 'c' is only used for openrc style
static gchar **
split_addresses_by_char (const gchar *addresses, const gchar *c)
{
gchar **ipset;
if (addresses == NULL)
return NULL;
if (strchr (addresses, '(') != NULL) { // old baselayout style
gchar *tmp = g_strdup (addresses);
strip_string (tmp, '(');
strip_string (tmp, ')');
strip_string (tmp, '"');
strip_string (tmp, '\'');
ipset = g_strsplit (tmp, "\" \"", 0);
g_free(tmp);
} else { // openrc style
if (strstr (addresses, "netmask"))
// There is only one ip address if "netmask" is specified.
// '\n' is not used in config so there will be only one split.
ipset = g_strsplit (addresses, "\n", 0);
else
ipset = g_strsplit (addresses, c, 0);
}
return ipset;
}
static gchar **
split_addresses (const gchar* addresses)
{
// " " is only used by openrc style
return split_addresses_by_char (addresses, " ");
}
static gchar **
split_routes (const gchar* routes)
{
// "\"" is only used by openrc style
return split_addresses_by_char (routes, "\"");
}
gboolean
has_ip6_address (const char *conn_name)
{
......@@ -360,7 +403,7 @@ has_ip6_address (const char *conn_name)
guint i;
g_return_val_if_fail (conn_name != NULL, FALSE);
ipset = g_strsplit (ifnet_get_data (conn_name, "config"), "\" \"", 0);
ipset = split_addresses (ifnet_get_data (conn_name, "config"));
length = g_strv_length (ipset);
for (i = 0; i < length; i++) {
if (!is_ip6_address (ipset[i]))
......@@ -512,8 +555,11 @@ get_ip4_gateway (gchar * gateway)
tmp = g_strdup (tmp);
strip_string (tmp, ' ');
strip_string (tmp, '"');
// Only one gateway is selected
if ((split = strstr (tmp, "\"")) != NULL)
*split = '\0';
if (!inet_pton (AF_INET, tmp, &tmp_ip4_addr))
goto error;
g_free (tmp);
......@@ -567,14 +613,11 @@ convert_ip4_config_block (const char *conn_name)
gchar *ip;
guint32 def_gateway = 0;
const char *routes;
gchar *pos;
ip_block *start = NULL, *current = NULL, *iblock = NULL;
const char *pattern =
"((\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.)\\{(\\d{1,3})\\.\\.(\\d{1,3})\\}(/\\d{1,2}))";
g_return_val_if_fail (conn_name != NULL, NULL);
ipset = g_strsplit (ifnet_get_data (conn_name, "config"), "\" \"", 0);
ipset = split_addresses (ifnet_get_data (conn_name, "config"));
length = g_strv_length (ipset);
routes = ifnet_get_data (conn_name, "routes");
......@@ -584,73 +627,16 @@ convert_ip4_config_block (const char *conn_name)
for (i = 0; i < length; i++) {
ip = ipset[i];
ip = strip_string (ip, '"');
//Handle ip like 192.168.4.{1..3}
if ((pos = strchr (ip, '{')) != NULL) {
gchar *ip_start, *ip_prefix;
gchar *begin_str, *end_str;
int begin, end, j;
GRegex *regex;
GMatchInfo *match_info;
regex = g_regex_new (pattern, 0, 0, NULL);
g_regex_match (regex, ip, 0, &match_info);
g_regex_unref (regex);
if (!g_match_info_matches (match_info)) {
g_match_info_free (match_info);
continue;
}
begin_str = g_match_info_fetch (match_info, 3);
end_str = g_match_info_fetch (match_info, 4);
begin = atoi (begin_str);
end = atoi (end_str);
ip_start = g_match_info_fetch (match_info, 2);
ip_prefix = g_match_info_fetch (match_info, 5);
if (end < begin || begin < 1 || end > 254) {
g_match_info_free (match_info);
continue;
}
for (j = begin; j <= end; j++) {
char suf[4];
gchar *newip;
sprintf (suf, "%d", j);
newip =
g_strconcat (ip_start, suf, ip_prefix,
NULL);
iblock = create_ip4_block (newip);
if (iblock == NULL) {
g_free (newip);
continue;
}
if (!iblock->gateway && def_gateway != 0)
iblock->gateway = def_gateway;
if (start == NULL)
start = current = iblock;
else {
current->next = iblock;
current = iblock;
}
g_free (newip);
}
g_free (begin_str);
g_free (end_str);
g_free (ip_start);
g_free (ip_prefix);
g_match_info_free (match_info);
} else {
iblock = create_ip4_block (ip);
if (iblock == NULL)
continue;
if (!iblock->gateway && def_gateway != 0)
iblock->gateway = def_gateway;
if (start == NULL)
start = current = iblock;
else {
current->next = iblock;
current = iblock;
}
iblock = create_ip4_block (ip);
if (iblock == NULL)
continue;
if (!iblock->gateway && def_gateway != 0)
iblock->gateway = def_gateway;
if (start == NULL)
start = current = iblock;
else {
current->next = iblock;
current = iblock;
}
}
g_strfreev (ipset);
......@@ -667,7 +653,7 @@ convert_ip6_config_block (const char *conn_name)
ip6_block *start = NULL, *current = NULL, *iblock = NULL;
g_return_val_if_fail (conn_name != NULL, NULL);
ipset = g_strsplit (ifnet_get_data (conn_name, "config"), "\" \"", 0);
ipset = split_addresses (ifnet_get_data (conn_name, "config"));
length = g_strv_length (ipset);
for (i = 0; i < length; i++) {
ip = ipset[i];
......@@ -693,15 +679,11 @@ convert_ip4_routes_block (const char *conn_name)
guint length;
guint i;
gchar *ip;
const char *routes;
ip_block *start = NULL, *current = NULL, *iblock = NULL;
g_return_val_if_fail (conn_name != NULL, NULL);
routes = ifnet_get_data (conn_name, "routes");
if (!routes)
return NULL;
ipset = g_strsplit (routes, "\" \"", 0);
ipset = split_routes (ifnet_get_data (conn_name, "routes"));
length = g_strv_length (ipset);
for (i = 0; i < length; i++) {
ip = ipset[i];
......@@ -731,15 +713,11 @@ convert_ip6_routes_block (const char *conn_name)
guint length;
guint i;
gchar *ip, *tmp_addr;
const char *routes;
ip6_block *start = NULL, *current = NULL, *iblock = NULL;
struct in6_addr *tmp_ip6_addr;
g_return_val_if_fail (conn_name != NULL, NULL);
routes = ifnet_get_data (conn_name, "routes");
if (!routes)
return NULL;
ipset = g_strsplit (routes, "\" \"", 0);
ipset = split_routes (ifnet_get_data (conn_name, "routes"));
length = g_strv_length (ipset);
for (i = 0; i < length; i++) {
ip = ipset[i];
......
......@@ -27,10 +27,9 @@ config_eth2=(
routes_eth2=("default via 4321:0:1:2:3:4:567:89ab")
enable_ipv6_eth2="true"
config_eth3=("nufjlsjlll")
managed_eth4=("false")
managed_eth4="false"
routes_eth4=("default via 4321:0:1:2:3:4:567:89ab")
config_eth5=("dhcp")
config_eth6=("192.168.4.{1..101}/24")
config_eth7=( "dhcp" )
auto_eth7="true"
......@@ -38,6 +37,14 @@ auto_eth7="true"
# missing config_eth8
auto_eth8="true"
#new openrc style
config_eth9="202.117.16.10/24 202.117.17.10/24"
routes_eth9="default via 202.117.16.1
10.0.0.0/8 via 192.168.0.1
"
config_eth10="202.117.16.2 netmask 255.255.255.0"
routes_eth10="10.0.0.0/8 via 192.168.0.1"
config_myxjtu2=("202.117.16.121/24 brd 202.117.16.255")
routes_myxjtu2=("default via 202.117.16.1")
dns_servers_myxjtu2="202.117.0.20 202.117.0.21"
......
......@@ -37,7 +37,7 @@ static void
test_getdata ()
{
ASSERT (ifnet_get_data ("eth1", "config")
&& strcmp (ifnet_get_data ("eth1", "config"), "dhcp") == 0,
&& strcmp (ifnet_get_data ("eth1", "config"), "( \"dhcp\" )") == 0,
"get data", "config_eth1 is not correct");
ASSERT (ifnet_get_data ("ppp0", "username")
&& strcmp (ifnet_get_data ("ppp0", "username"), "user") == 0,
......@@ -84,7 +84,7 @@ test_is_static ()
ASSERT (is_static_ip4 ("eth0") == TRUE, "is static",
"a static interface is recognized as dhcp");
ASSERT (!is_static_ip6 ("eth0") == TRUE, "is static",
"a static interface is recognized as dhcp");
"a dhcp interface is recognized as static");
}
static void
......@@ -182,10 +182,6 @@ test_convert_ipv4_config_block ()
ASSERT (iblock == NULL, "convert config_block",
"convert error configuration");
destroy_ip_block (iblock);
iblock = convert_ip4_config_block ("eth6");
ASSERT (iblock != NULL, "convert config_block",
"convert error configuration");
destroy_ip_block (iblock);
}
static void
......@@ -200,6 +196,16 @@ test_convert_ipv4_routes_block ()
destroy_ip_block (tmp);
ASSERT (iblock == NULL, "convert ip4 routes",
"should only get one route");
iblock = convert_ip4_routes_block ("eth9");
tmp = iblock;
ASSERT (iblock != NULL, "convert ip4 routes", "should get one route");
check_ip_block (iblock, "10.0.0.0", "255.0.0.0", "192.168.0.1");
iblock = iblock->next;
destroy_ip_block (tmp);
ASSERT (iblock == NULL, "convert ip4 routes",
"should only get one route");
}
static void
......@@ -272,6 +278,18 @@ test_new_connection ()
"new connection failed: %s",
error ? error->message : "NONE");
g_object_unref (connection);
connection = ifnet_update_connection_from_config_block ("eth9", &error);
ASSERT (connection != NULL, "new connection",
"new connection(eth9) failed: %s",
error ? error->message : "NONE");
g_object_unref (connection);
connection = ifnet_update_connection_from_config_block ("eth10", &error);
ASSERT (connection != NULL, "new connection",
"new connection(eth10) failed: %s",
error ? error->message : "NONE");
g_object_unref (connection);
}
#define NET_GEN_NAME "net.generate"
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment