From 5f03706a6b1ad3db3b9bce5852b1ed885039d719 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 26 May 2010 16:28:51 -0700 Subject: ethernet: handle zvm-subchannels unmanaged spec (rh #591533) --- src/NetworkManagerUtils.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++ src/NetworkManagerUtils.h | 3 +- src/nm-device-ethernet.c | 5 +++ 3 files changed, 103 insertions(+), 1 deletion(-) (limited to 'src') 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 #include #include +#include #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; } -- cgit v1.2.1