summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2010-05-26 16:28:51 -0700
committerDan Williams <dcbw@redhat.com>2010-05-26 16:28:51 -0700
commit5f03706a6b1ad3db3b9bce5852b1ed885039d719 (patch)
tree0caf92b522f99410efc34f2f8f6667c2d7db4fdc /src
parent9c45b52f38b22927ba6a2d79f0666350fa0b7d6b (diff)
downloadNetworkManager-5f03706a6b1ad3db3b9bce5852b1ed885039d719.tar.gz
ethernet: handle zvm-subchannels unmanaged spec (rh #591533)
Diffstat (limited to 'src')
-rw-r--r--src/NetworkManagerUtils.c96
-rw-r--r--src/NetworkManagerUtils.h3
-rw-r--r--src/nm-device-ethernet.c5
3 files changed, 103 insertions, 1 deletions
diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c
index 22cf2fa0d8..86f66f76d2 100644
--- a/src/NetworkManagerUtils.c
+++ b/src/NetworkManagerUtils.c
@@ -25,6 +25,7 @@
#include <stdio.h>
#include <string.h>
#include <unistd.h>
+#include <ctype.h>
#include "NetworkManagerUtils.h"
#include "nm-utils.h"
@@ -487,6 +488,101 @@ nm_match_spec_hwaddr (const GSList *specs, const char *hwaddr)
return FALSE;
}
+#define BUFSIZE 10
+
+static gboolean
+parse_subchannels (const char *subchannels, guint32 *a, guint32 *b, guint32 *c)
+{
+ long unsigned int tmp;
+ char buf[BUFSIZE + 1];
+ const char *p = subchannels;
+ int i = 0;
+ char *pa = NULL, *pb = NULL, *pc = NULL;
+
+ g_return_val_if_fail (subchannels != NULL, FALSE);
+ g_return_val_if_fail (a != NULL, FALSE);
+ g_return_val_if_fail (*a == 0, FALSE);
+ g_return_val_if_fail (b != NULL, FALSE);
+ g_return_val_if_fail (*b == 0, FALSE);
+ g_return_val_if_fail (c != NULL, FALSE);
+ g_return_val_if_fail (*c == 0, FALSE);
+
+ /* sanity check */
+ if (!isxdigit (subchannels[0]))
+ return FALSE;
+
+ /* Get the first channel */
+ while (*p && (*p != ',')) {
+ if (!isxdigit (*p) && (*p != '.'))
+ return FALSE; /* Invalid chars */
+ if (i >= BUFSIZE)
+ return FALSE; /* Too long to be a subchannel */
+ buf[i++] = *p++;
+ }
+ buf[i] = '\0';
+
+ /* and grab each of its elements, there should be 3 */
+ pa = &buf[0];
+ pb = strchr (buf, '.');
+ if (pb)
+ pc = strchr (pb + 1, '.');
+ if (!pa || !pb || !pc)
+ return FALSE;
+
+ /* Split the string */
+ *pb++ = '\0';
+ *pc++ = '\0';
+
+ errno = 0;
+ tmp = strtoul (pa, NULL, 16);
+ if (errno)
+ return FALSE;
+ *a = (guint32) tmp;
+
+ errno = 0;
+ tmp = strtoul (pb, NULL, 16);
+ if (errno)
+ return FALSE;
+ *b = (guint32) tmp;
+
+ errno = 0;
+ tmp = strtoul (pc, NULL, 16);
+ if (errno)
+ return FALSE;
+ *c = (guint32) tmp;
+
+ return TRUE;
+}
+
+#define SUBCHAN_TAG "zvm-subchannels:"
+
+gboolean
+nm_match_spec_zvm_subchannels (const GSList *specs, const char *subchannels)
+{
+ const GSList *iter;
+ guint32 a = 0, b = 0, c = 0;
+ guint32 spec_a = 0, spec_b = 0, spec_c = 0;
+
+ g_return_val_if_fail (subchannels != NULL, FALSE);
+
+ if (!parse_subchannels (subchannels, &a, &b, &c))
+ return FALSE;
+
+ for (iter = specs; iter; iter = g_slist_next (iter)) {
+ const char *spec = iter->data;
+
+ if (!strncmp (spec, SUBCHAN_TAG, strlen (SUBCHAN_TAG))) {
+ spec += strlen (SUBCHAN_TAG);
+ if (parse_subchannels (spec, &spec_a, &spec_b, &spec_c)) {
+ if (a == spec_a && b == spec_b && c == spec_c)
+ return TRUE;
+ }
+ }
+ }
+
+ return FALSE;
+}
+
/*********************************/
static void
diff --git a/src/NetworkManagerUtils.h b/src/NetworkManagerUtils.h
index e3d1793b4d..93a11c31cb 100644
--- a/src/NetworkManagerUtils.h
+++ b/src/NetworkManagerUtils.h
@@ -15,7 +15,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
- * Copyright (C) 2004 - 2008 Red Hat, Inc.
+ * Copyright (C) 2004 - 2010 Red Hat, Inc.
* Copyright (C) 2005 - 2008 Novell, Inc.
*/
@@ -48,6 +48,7 @@ void nm_utils_call_dispatcher (const char *action,
const char *vpn_iface);
gboolean nm_match_spec_hwaddr (const GSList *specs, const char *hwaddr);
+gboolean nm_match_spec_zvm_subchannels (const GSList *specs, const char *subchannels);
GHashTable *value_hash_create (void);
diff --git a/src/nm-device-ethernet.c b/src/nm-device-ethernet.c
index be6d4e2f3c..5af9ec5f50 100644
--- a/src/nm-device-ethernet.c
+++ b/src/nm-device-ethernet.c
@@ -105,6 +105,7 @@ typedef struct {
gboolean disposed;
struct ether_addr hw_addr;
+ char * zvm_subchannels;
gboolean carrier;
NMNetlinkMonitor * monitor;
@@ -1519,6 +1520,7 @@ real_check_connection_compatible (NMDevice *device,
static gboolean
spec_match_list (NMDevice *device, const GSList *specs)
{
+ NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device);
struct ether_addr ether;
char *hwaddr;
gboolean matched;
@@ -1528,6 +1530,9 @@ spec_match_list (NMDevice *device, const GSList *specs)
matched = nm_match_spec_hwaddr (specs, hwaddr);
g_free (hwaddr);
+ if (!matched && priv->zvm_subchannels)
+ matched = nm_match_spec_zvm_subchannels (specs, priv->zvm_subchannels);
+
return matched;
}