Re: [PATCH 2/6] VLAN: add ifcfg-vlan parser
- From: Dan Williams <dcbw redhat com>
- To: Weiping Pan <wpan redhat com>
- Cc: networkmanager-list gnome org
- Subject: Re: [PATCH 2/6] VLAN: add ifcfg-vlan parser
- Date: Thu, 17 Nov 2011 13:14:16 -0600
On Wed, 2011-11-16 at 16:21 +0800, Weiping Pan wrote:
> On 11/16/2011 01:35 PM, Dan Williams wrote:
> > On Fri, 2011-10-21 at 09:52 +0800, Weiping Pan wrote:
> >> The example of ifcfg-vlan is as followed:
> >>
> >> VLAN=yes
> >> TYPE=vlan
> >> DEVICE=vlan43
> >> PHYSDEV=eth9
> > Ideally here we also accept a MAC address or NM connection UUID as
> > PHYSDEV so you don't have to manually keep all the interface names in
> > sync.
> >
> Yes. I will put it in TODO list.
> >> REORDER_HDR=0
> >> VLAN_FLAGS=GVRP,LOOSE_BINDING
> >> VLAN_INGRESS_PRIORITY_MAP=0:1,2:5
> >> VLAN_EGRESS_PRIORITY_MAP=12:3,14:7
> > Are these new variables? ifup (F16) seems to think the only ones that
> > exist are VLAN (yes/no), REORDER_HDR, and GVRP.
> >
> But vconfig supports ingress/egress priority mapping,
> so I think NetworkManager should support them, too.
Yes, no objection to the support, I was just curious about it as I
couldn't find anywhere in the existing ifcfg scripts that this value was
defined. So having NM define that as an ifcfg variable is fine.
> >> ONBOOT=yes
> >> BOOTPROTO=static
> >> IPADDR=192.168.43.149
> >> NETMASK=255.255.255.0
> >>
> >> And we try to make it compitable with the format used by initscripts,
> >> and there is no need to change anything in ifcfg-eth9.
> >>
> >> Pay attention the format of DEVICE here is 'vlan+id', and id is 0-4095.
> >>
> >> Signed-off-by: Weiping Pan<wpan redhat com>
> >> ---
> >> libnm-util/Makefile.am | 2 +
> >> libnm-util/libnm-util.ver | 11 +
> >> libnm-util/nm-connection.c | 25 ++-
> >> libnm-util/nm-connection.h | 2 +
> >> libnm-util/nm-setting-vlan.c | 351 ++++++++++++++++++++
> >> libnm-util/nm-setting-vlan.h | 93 +++++
> >> src/settings/plugins/ifcfg-rh/common.h | 1 +
> >> src/settings/plugins/ifcfg-rh/reader.c | 143 ++++++++-
> >> .../network-scripts/ifcfg-test-vlan-interface | 11 +-
> >> 9 files changed, 622 insertions(+), 17 deletions(-)
> >> create mode 100644 libnm-util/nm-setting-vlan.c
> >> create mode 100644 libnm-util/nm-setting-vlan.h
> >>
> >> diff --git a/libnm-util/Makefile.am b/libnm-util/Makefile.am
> >> index 1529b4a..a6cf684 100644
> >> --- a/libnm-util/Makefile.am
> >> +++ b/libnm-util/Makefile.am
> >> @@ -17,6 +17,7 @@ libnm_util_include_HEADERS = \
> >> nm-setting-bluetooth.h \
> >> nm-setting-connection.h \
> >> nm-setting-ip4-config.h \
> >> + nm-setting-vlan.h \
> >> nm-setting-ip6-config.h \
> >> nm-setting-ppp.h \
> >> nm-setting-pppoe.h \
> >> @@ -46,6 +47,7 @@ libnm_util_la_csources = \
> >> nm-setting-bluetooth.c \
> >> nm-setting-connection.c \
> >> nm-setting-ip4-config.c \
> >> + nm-setting-vlan.c \
> >> nm-setting-ip6-config.c \
> >> nm-setting-ppp.c \
> >> nm-setting-pppoe.c \
> >> diff --git a/libnm-util/libnm-util.ver b/libnm-util/libnm-util.ver
> >> index 53c2482..9f3033e 100644
> >> --- a/libnm-util/libnm-util.ver
> >> +++ b/libnm-util/libnm-util.ver
> >> @@ -30,6 +30,7 @@ global:
> >> nm_connection_get_setting_wired;
> >> nm_connection_get_setting_wireless;
> >> nm_connection_get_setting_wireless_security;
> >> + nm_connection_get_setting_vlan;
> >> nm_connection_get_type;
> >> nm_connection_get_uuid;
> >> nm_connection_is_type;
> >> @@ -449,6 +450,16 @@ global:
> >> nm_utils_wifi_find_next_channel;
> >> nm_utils_wifi_freq_to_channel;
> >> nm_utils_wifi_is_channel_valid;
> >> + nm_setting_vlan_error_get_type;
> >> + nm_setting_vlan_error_quark;
> >> + nm_setting_vlan_get_type;
> >> + nm_setting_vlan_new;
> >> + nm_setting_vlan_get_interface_name;
> >> + nm_setting_vlan_get_vlan_slave;
> >> + nm_setting_vlan_get_vlan_id;
> >> + nm_setting_vlan_get_vlan_flags;
> >> + nm_setting_vlan_get_vlan_priority_ingress_map;
> >> + nm_setting_vlan_get_vlan_priority_egress_map;
> > We probably want to kill the second 'vlan' here since these functions
> > are already part of the vlan setting, we can just name them:
> >
> > nm_setting_vlan_get_slave;
> > nm_setting_vlan_get_id;
> > nm_setting_vlan_get_flags;
> > nm_setting_vlan_get_priority_ingress_map;
> > nm_setting_vlan_get_priority_egress_map;
> >
> Ok. I will remove the duplicate "vlan".
>
> >> local:
> >> *;
> >> };
> >> diff --git a/libnm-util/nm-connection.c b/libnm-util/nm-connection.c
> >> index e3bbeae..2137352 100644
> >> --- a/libnm-util/nm-connection.c
> >> +++ b/libnm-util/nm-connection.c
> >> @@ -44,6 +44,7 @@
> >> #include "nm-setting-wireless-security.h"
> >> #include "nm-setting-vpn.h"
> >> #include "nm-setting-olpc-mesh.h"
> >> +#include "nm-setting-vlan.h"
> >>
> >> #include "nm-setting-serial.h"
> >> #include "nm-setting-gsm.h"
> >> @@ -135,7 +136,7 @@ static guint signals[LAST_SIGNAL] = { 0 };
> >>
> >> static GHashTable *registered_settings = NULL;
> >>
> >> -#define DEFAULT_MAP_SIZE 16
> >> +#define DEFAULT_MAP_SIZE 17
> >>
> >> static struct SettingInfo {
> >> const char *name;
> >> @@ -242,6 +243,11 @@ register_default_settings (void)
> >> NM_SETTING_WIMAX_ERROR,
> >> 1, TRUE);
> >>
> >> + register_one_setting (NM_SETTING_VLAN_SETTING_NAME,
> >> + NM_TYPE_SETTING_VLAN,
> >> + NM_SETTING_VLAN_ERROR,
> >> + 1, TRUE);
> >> +
> >> register_one_setting (NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
> >> NM_TYPE_SETTING_WIRELESS_SECURITY,
> >> NM_SETTING_WIRELESS_SECURITY_ERROR,
> >> @@ -1543,6 +1549,23 @@ nm_connection_get_setting_wireless_security (NMConnection *connection)
> >> return (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY);
> >> }
> >>
> >> +/**
> >> + * nm_connection_get_setting_vlan:
> >> + * @connection: the #NMConnection
> >> + *
> >> + * A shortcut to return any #NMSettingVLAN the connection might contain.
> >> + *
> >> + * Returns: (transfer none): an #NMSettingVLAN if the connection contains one, otherwise NULL
> >> + **/
> >> +NMSettingVLAN *
> >> +nm_connection_get_setting_vlan (NMConnection *connection)
> >> +{
> >> + g_return_val_if_fail (connection != NULL, NULL);
> >> + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
> >> +
> >> + return (NMSettingVLAN *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VLAN);
> >> +}
> >> +
> >> /*************************************************************/
> >>
> >> static void
> >> diff --git a/libnm-util/nm-connection.h b/libnm-util/nm-connection.h
> >> index 069dc84..e573b8c 100644
> >> --- a/libnm-util/nm-connection.h
> >> +++ b/libnm-util/nm-connection.h
> >> @@ -45,6 +45,7 @@
> >> #include<nm-setting-wired.h>
> >> #include<nm-setting-wireless.h>
> >> #include<nm-setting-wireless-security.h>
> >> +#include<nm-setting-vlan.h>
> >>
> >> G_BEGIN_DECLS
> >>
> >> @@ -196,6 +197,7 @@ NMSettingWimax * nm_connection_get_setting_wimax (NMConnec
> >> NMSettingWired * nm_connection_get_setting_wired (NMConnection *connection);
> >> NMSettingWireless * nm_connection_get_setting_wireless (NMConnection *connection);
> >> NMSettingWirelessSecurity *nm_connection_get_setting_wireless_security (NMConnection *connection);
> >> +NMSettingVLAN * nm_connection_get_setting_vlan (NMConnection *connection);
> >>
> >> G_END_DECLS
> >>
> >> diff --git a/libnm-util/nm-setting-vlan.c b/libnm-util/nm-setting-vlan.c
> >> new file mode 100644
> >> index 0000000..7f104b3
> >> --- /dev/null
> >> +++ b/libnm-util/nm-setting-vlan.c
> >> @@ -0,0 +1,351 @@
> >> +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
> >> +
> >> +/*
> >> + * Weiping Pan<wpan redhat com>
> >> + *
> >> + * This library is free software; you can redistribute it and/or
> >> + * modify it under the terms of the GNU Lesser General Public
> >> + * License as published by the Free Software Foundation; either
> >> + * version 2 of the License, or (at your option) any later version.
> >> + *
> >> + * This library is distributed in the hope that it will be useful,
> >> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> >> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> >> + * Lesser General Public License for more details.
> >> + *
> >> + * You should have received a copy of the GNU Lesser General Public
> >> + * License along with this library; if not, write to the
> >> + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
> >> + * Boston, MA 02110-1301 USA.
> >> + *
> >> + * (C) Copyright 2011 Red Hat, Inc.
> >> + */
> >> +#include<stdio.h>
> >> +#include<string.h>
> >> +
> >> +#include<dbus/dbus-glib.h>
> >> +#include "nm-setting-vlan.h"
> >> +#include "nm-param-spec-specialized.h"
> >> +#include "nm-utils.h"
> >> +#include "nm-dbus-glib-types.h"
> >> +
> >> +/**
> >> + * SECTION:nm-setting-vlan
> >> + * @short_description: Describes connection properties for VLAN devices
> >> + * @include: nm-setting-vlan.h
> >> + *
> >> + * The #NMSettingVLAN object is a #NMSetting subclass that describes properties
> >> + * necessary for connection to VLAN devices.
> >> + **/
> >> +
> >> +/**
> >> + * nm_setting_vlan_error_quark:
> >> + * Registers an error quark for #NMSettingVLAN if necessary.
> >> + * Returns: the error quark used for #NMSettingVLAN errors.
> >> + **/
> >> +GQuark
> >> +nm_setting_vlan_error_quark (void)
> >> +{
> >> + static GQuark quark;
> >> +
> >> + if (G_UNLIKELY (!quark))
> >> + quark = g_quark_from_static_string ("nm-setting-vlan-error-quark");
> >> + return quark;
> >> +}
> >> +
> >> +/* This should really be standard. */
> >> +#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC }
> >> +
> >> +GType
> >> +nm_setting_vlan_error_get_type (void)
> >> +{
> >> + static GType etype = 0;
> >> +
> >> + if (etype == 0) {
> >> + static const GEnumValue values[] = {
> >> + /* Unknown error. */
> >> + ENUM_ENTRY (NM_SETTING_VLAN_ERROR_UNKNOWN, "UnknownError"),
> >> + /* The specified property was invalid. */
> >> + ENUM_ENTRY (NM_SETTING_VLAN_ERROR_INVALID_PROPERTY, "InvalidProperty"),
> >> + /* The specified property was missing and is required. */
> >> + ENUM_ENTRY (NM_SETTING_VLAN_ERROR_MISSING_PROPERTY, "MissingProperty"),
> >> + { 0, 0, 0 }
> >> + };
> >> + etype = g_enum_register_static ("NMSettingVLANError", values);
> >> + }
> >> + return etype;
> >> +}
> >> +
> >> +G_DEFINE_TYPE (NMSettingVLAN, nm_setting_vlan, NM_TYPE_SETTING)
> > Lets actually use NMSettingVlan here instead of VLAN to keep consistency
> > with others like NMSettingWimax, NMSettingWifi, etc. I made a mistake
> > with NMSettingVPN...
> Ok, I will use "vlan" and "XXXVlan" to keep consistency in the future.
> >> +#define NM_SETTING_VLAN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_VLAN, NMSettingVLANPrivate))
> >> +
> >> +typedef struct {
> >> + char *interface_name;
> >> + char *vlan_slave;
> >> + guint32 vlan_id;
> >> + guint32 vlan_flags;
> >> + char *vlan_priority_ingress_map;
> >> + char *vlan_priority_egress_map;
> > I'll comment on this later, but we probably want to store these
> > differently; instead of a string, if the format will always be
> > "<uint>:<uint>" it might make sense to store them that way so that at
> > least we can manipulate them as tuples rather than having to parse
> > strings in the future. Will the ingress/egress mappings always be
> > <uint>:<uint> or are there other possibilities?
> The ingress/egress mappings will always be <uint>:<uint>.
Ok, great. Makes our life simpler.
> >> +} NMSettingVLANPrivate;
> >> +
> >> +enum {
> >> + PROP_0,
> >> + PROP_VLAN_DEVICE,
> >> + PROP_VLAN_SLAVE,
> >> + PROP_VLAN_ID,
> >> + PROP_VLAN_FLAGS,
> >> + PROP_VLAN_NAME_TYPE,
> >> + PROP_VLAN_PRIORITY_INGRESS_MAP,
> >> + PROP_VLAN_PRIORITY_EGRESS_MAP,
> >> + LAST_PROP
> >> +};
> >> +
> >> +/**
> >> + * nm_setting_vlan_new:
> >> + *
> >> + * Creates a new #NMSettingVLAN object with default values.
> >> + *
> >> + * Returns: (transfer full): the new empty #NMSettingVLAN object
> >> + **/
> >> +NMSetting *
> >> +nm_setting_vlan_new (void)
> >> +{
> >> + return (NMSetting *)g_object_new(NM_TYPE_SETTING_VLAN, NULL);
> >> +}
> >> +
> >> +/**
> >> + * nm_setting_vlan_get_interface_name:
> >> + * @setting: the #NMSettingVLAN
> >> + *
> >> + * Returns: the #NMSettingVLAN:interface_name property of the setting
> >> + **/
> >> +const char *
> >> +nm_setting_vlan_get_interface_name(NMSettingVLAN *setting)
> >> +{
> >> + g_return_val_if_fail (NM_IS_SETTING_VLAN(setting), NULL);
> >> + return NM_SETTING_VLAN_GET_PRIVATE(setting)->interface_name;
> >> +}
> >> +
> >> +/**
> >> + * nm_setting_vlan_get_vlan_slave:
> >> + * @setting: the #NMSettingVLAN
> >> + *
> >> + * Returns: the #NMSettingVLAN:vlan_slave property of the setting
> >> + **/
> >> +const char *
> >> +nm_setting_vlan_get_vlan_slave(NMSettingVLAN *setting)
> >> +{
> >> + g_return_val_if_fail (NM_IS_SETTING_VLAN(setting), NULL);
> >> + return NM_SETTING_VLAN_GET_PRIVATE(setting)->vlan_slave;
> >> +}
> >> +
> >> +/**
> >> + * nm_setting_vlan_get_vlan_id:
> >> + * @setting: the #NMSettingVLAN
> >> + *
> >> + * Returns: the #NMSettingVLAN:vlan_id property of the setting
> >> + **/
> >> +guint32
> >> +nm_setting_vlan_get_vlan_id(NMSettingVLAN *setting)
> >> +{
> >> + g_return_val_if_fail (NM_IS_SETTING_VLAN(setting), 0);
> >> + return NM_SETTING_VLAN_GET_PRIVATE(setting)->vlan_id;
> >> +}
> >> +
> >> +/**
> >> + * nm_setting_vlan_get_vlan_flags:
> >> + * @setting: the #NMSettingVLAN
> >> + *
> >> + * Returns: the #NMSettingVLAN:vlan_flags property of the setting
> >> + **/
> >> +guint32
> >> +nm_setting_vlan_get_vlan_flags(NMSettingVLAN *setting)
> >> +{
> >> + g_return_val_if_fail (NM_IS_SETTING_VLAN(setting), 0);
> >> + return NM_SETTING_VLAN_GET_PRIVATE(setting)->vlan_flags;
> >> +}
> >> +
> >> +/**
> >> + * nm_setting_vlan_get_vlan_priority_ingress_map:
> >> + * @setting: the #NMSettingVLAN
> >> + *
> >> + * Returns: the #NMSettingVLAN:vlan_priority_ingress_map property of the setting
> >> + **/
> >> +const char *
> >> +nm_setting_vlan_get_vlan_priority_ingress_map(NMSettingVLAN *setting)
> >> +{
> >> + g_return_val_if_fail (NM_IS_SETTING_VLAN(setting), NULL);
> >> + return NM_SETTING_VLAN_GET_PRIVATE(setting)->vlan_priority_ingress_map;
> >> +}
> >> +
> >> +/**
> >> + * nm_setting_vlan_get_vlan_priority_egress_map:
> >> + * @setting: the #NMSettingVLAN
> >> + *
> >> + * Returns: the #NMSettingVLAN:vlan_priority_egress_map property of the setting
> >> + **/
> >> +const char *
> >> +nm_setting_vlan_get_vlan_priority_egress_map(NMSettingVLAN *setting)
> >> +{
> >> + g_return_val_if_fail (NM_IS_SETTING_VLAN(setting), NULL);
> >> + return NM_SETTING_VLAN_GET_PRIVATE(setting)->vlan_priority_egress_map;
> >> +}
> >> +
> >> +static void
> >> +nm_setting_vlan_init (NMSettingVLAN *setting)
> >> +{
> >> + NMSettingVLANPrivate *priv = NULL;
> >> +
> >> + priv = NM_SETTING_VLAN_GET_PRIVATE(setting);
> >> + priv->vlan_id = 0;
> >> + priv->vlan_flags = 0;
> >> +
> >> + priv->vlan_priority_ingress_map = NULL;
> > The private structure actually gets memset() to 0, so we don't need to
> > explicitly initialize anything. Properties can also get explicitly set
> > to their default value during construction if you pass G_PARAM_CONSTRUCT
> > as one of the flags when calling g_param_spec_xxxx().
> >
> Ok.
> >> +
> >> + priv->vlan_priority_egress_map = NULL;
> >> + g_object_set (setting, NM_SETTING_NAME, NM_SETTING_VLAN_SETTING_NAME, NULL);
> >> +
> >> + return;
> >> +}
> >> +
> >> +static void
> >> +finalize (GObject *object)
> >> +{
> >> + NMSettingVLAN *setting = NM_SETTING_VLAN (object);
> >> + NMSettingVLANPrivate *priv = NM_SETTING_VLAN_GET_PRIVATE (setting);
> >> +
> >> + g_free(priv->interface_name);
> >> + g_free(priv->vlan_slave);
> >> + g_free(priv->vlan_priority_ingress_map);
> >> + g_free(priv->vlan_priority_egress_map);
> >> + return;
> >> +}
> >> +
> >> +static void
> >> +set_property (GObject *object, guint prop_id,
> >> + const GValue *value, GParamSpec *pspec)
> >> +{
> >> + NMSettingVLAN *setting = NM_SETTING_VLAN (object);
> >> + NMSettingVLANPrivate *priv = NM_SETTING_VLAN_GET_PRIVATE (setting);
> >> +
> >> + switch (prop_id) {
> >> + case PROP_VLAN_DEVICE:
> >> + g_free (priv->interface_name);
> >> + priv->interface_name = g_value_dup_string (value);
> >> + break;
> >> + case PROP_VLAN_SLAVE:
> >> + g_free (priv->vlan_slave);
> >> + priv->vlan_slave = g_value_dup_string (value);
> >> + break;
> >> + case PROP_VLAN_ID:
> >> + priv->vlan_id = g_value_get_uint(value);
> >> + break;
> >> + case PROP_VLAN_FLAGS:
> >> + priv->vlan_flags |= g_value_get_uint(value);
> > You probably just want "priv->vlan_flags = xxx" here instead of OR-ing
> > with the existing value.
> >
> Ok.
> >> + break;
> >> + case PROP_VLAN_PRIORITY_INGRESS_MAP:
> >> + priv->vlan_priority_ingress_map = g_value_dup_string(value);
> >> + break;
> >> + case PROP_VLAN_PRIORITY_EGRESS_MAP:
> >> + priv->vlan_priority_egress_map = g_value_dup_string(value);
> >> + break;
> >> + default:
> >> + break;
> >> + }
> >> +}
> >> +
> >> +static void
> >> +get_property (GObject *object, guint prop_id,
> >> + GValue *value, GParamSpec *pspec)
> >> +{
> >> + NMSettingVLAN *setting = NM_SETTING_VLAN (object);
> >> +
> >> + switch (prop_id) {
> >> + case PROP_VLAN_DEVICE:
> >> + g_value_set_string(value, nm_setting_vlan_get_interface_name(setting));
> >> + break;
> >> + case PROP_VLAN_SLAVE:
> >> + g_value_set_string(value, nm_setting_vlan_get_vlan_slave(setting));
> >> + break;
> >> + case PROP_VLAN_ID:
> >> + g_value_set_uint(value, nm_setting_vlan_get_vlan_id(setting));
> >> + break;
> >> + case PROP_VLAN_FLAGS:
> >> + g_value_set_uint(value, nm_setting_vlan_get_vlan_flags(setting));
> >> + break;
> >> + case PROP_VLAN_PRIORITY_INGRESS_MAP:
> >> + g_value_set_string(value, nm_setting_vlan_get_vlan_priority_ingress_map(setting));
> >> + break;
> >> + case PROP_VLAN_PRIORITY_EGRESS_MAP:
> >> + g_value_set_string(value, nm_setting_vlan_get_vlan_priority_egress_map(setting));
> >> + break;
> >> + default:
> >> + break;
> >> + }
> >> +}
> >> +
> >> +static void
> >> +nm_setting_vlan_class_init (NMSettingVLANClass *setting_class)
> >> +{
> >> + GObjectClass *object_class = G_OBJECT_CLASS (setting_class);
> >> + g_type_class_add_private (setting_class, sizeof (NMSettingVLANPrivate));
> >> +
> >> + /* virtual methods */
> >> + object_class->set_property = set_property;
> >> + object_class->get_property = get_property;
> >> + object_class->finalize = finalize;
> >> +
> >> + /* Properties */
> >> + g_object_class_install_property
> >> + (object_class, PROP_VLAN_DEVICE,
> >> + g_param_spec_string( NM_SETTING_VLAN_INTERFACE_NAME,
> >> + "InterfaceName",
> >> + "The vlan device name in kernel",
> >> + NULL,
> >> + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE));
> >> +
> >> + g_object_class_install_property
> >> + (object_class, PROP_VLAN_SLAVE,
> >> + g_param_spec_string( NM_SETTING_VLAN_VLAN_SLAVE,
> >> + "vlan slave",
> >> + "The underlying physical ethernet device",
> >> + NULL,
> >> + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE));
> >> +
> >> + g_object_class_install_property
> >> + (object_class, PROP_VLAN_ID,
> >> + g_param_spec_uint (NM_SETTING_VLAN_VLAN_ID,
> >> + "vlan id",
> >> + "vlan id",
> >> + 0,
> >> + G_MAXUINT32,
> >> + 0,
> >> + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE));
> >> +
> >> + g_object_class_install_property
> >> + (object_class, PROP_VLAN_FLAGS,
> >> + g_param_spec_uint (NM_SETTING_VLAN_VLAN_FLAGS,
> >> + "vlan flags",
> >> + "vlan flags",
> >> + 0,
> >> + G_MAXUINT32,
> >> + 0,
> >> + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE));
> >> +
> >> + g_object_class_install_property
> >> + (object_class, PROP_VLAN_PRIORITY_INGRESS_MAP,
> >> + g_param_spec_string( NM_SETTING_VLAN_VLAN_INGRESS_PRIORITY_MAP,
> >> + "vlan ingress priority mapping",
> >> + "vlan ingress priority mapping",
> >> + NULL,
> >> + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE));
> >> +
> >> + g_object_class_install_property
> >> + (object_class, PROP_VLAN_PRIORITY_EGRESS_MAP,
> >> + g_param_spec_string( NM_SETTING_VLAN_VLAN_EGRESS_PRIORITY_MAP,
> >> + "vlan egress priority mapping",
> >> + "vlan egress priority mapping",
> >> + NULL,
> >> + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE));
> >> +}
> >> diff --git a/libnm-util/nm-setting-vlan.h b/libnm-util/nm-setting-vlan.h
> >> new file mode 100644
> >> index 0000000..c354db8
> >> --- /dev/null
> >> +++ b/libnm-util/nm-setting-vlan.h
> >> @@ -0,0 +1,93 @@
> >> +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
> >> +
> >> +/*
> >> + * Weiping Pan<wpan redhat com>
> >> + *
> >> + * This library is free software; you can redistribute it and/or
> >> + * modify it under the terms of the GNU Lesser General Public
> >> + * License as published by the Free Software Foundation; either
> >> + * version 2 of the License, or (at your option) any later version.
> >> + *
> >> + * This library is distributed in the hope that it will be useful,
> >> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> >> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> >> + * Lesser General Public License for more details.
> >> + *
> >> + * You should have received a copy of the GNU Lesser General Public
> >> + * License along with this library; if not, write to the
> >> + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
> >> + * Boston, MA 02110-1301 USA.
> >> + *
> >> + * (C) Copyright 2011 Red Hat, Inc.
> >> + */
> >> +
> >> +#ifndef NM_SETTING_VLAN_H
> >> +#define NM_SETTING_VLAN_H
> >> +
> >> +#include "nm-setting.h"
> >> +#include<linux/if_vlan.h>
> >> +
> >> +G_BEGIN_DECLS
> >> +
> >> +#define NM_TYPE_SETTING_VLAN (nm_setting_vlan_get_type ())
> >> +#define NM_SETTING_VLAN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_VLAN, NMSettingVLAN))
> >> +#define NM_SETTING_VLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_VLANCONFIG, NMSettingVLANClass))
> >> +#define NM_IS_SETTING_VLAN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_VLAN))
> >> +#define NM_IS_SETTING_VLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_SETTING_VLAN))
> >> +#define NM_SETTING_VLAN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_VLAN, NMSettingVLANClass))
> >> +
> >> +#define NM_SETTING_VLAN_SETTING_NAME "VLAN"
> > Lowercase here, ie 'vlan', for consistency with the rest of the
> > settings.
> >
> >> +/**
> >> + * NMSettingVlanError:
> >> + * @NM_SETTING_VLAN_ERROR_UNKNOWN: unknown or unclassified error
> >> + * @NM_SETTING_VLAN_ERROR_INVALID_PROPERTY: the property was invalid
> >> + * @NM_SETTING_VLAN_ERROR_MISSING_PROPERTY: the property was missing and is
> >> + * required
> >> + */
> >> +typedef enum {
> >> + NM_SETTING_VLAN_ERROR_UNKNOWN = 0,
> >> + NM_SETTING_VLAN_ERROR_INVALID_PROPERTY,
> >> + NM_SETTING_VLAN_ERROR_MISSING_PROPERTY
> >> +} NMSettingVlanError;
> >> +
> >> +#define NM_TYPE_SETTING_VLAN_ERROR (nm_setting_vlan_error_get_type ())
> >> +GType nm_setting_vlan_error_get_type (void);
> >> +
> >> +#define NM_SETTING_VLAN_ERROR nm_setting_vlan_error_quark ()
> >> +GQuark nm_setting_vlan_error_quark (void);
> >> +
> >> +GType nm_setting_vlan_get_type (void);
> >> +
> >> +#define NM_SETTING_VLAN_INTERFACE_NAME "interface-name"
> >> +#define NM_SETTING_VLAN_VLAN_SLAVE "vlan-slave"
> >> +#define NM_SETTING_VLAN_VLAN_ID "vlan-id"
> >> +#define NM_SETTING_VLAN_VLAN_FLAGS "vlan-flags"
> >> +#define NM_SETTING_VLAN_VLAN_INGRESS_PRIORITY_MAP "vlan-priority-ingress-map"
> >> +#define NM_SETTING_VLAN_VLAN_EGRESS_PRIORITY_MAP "vlan-priority-egress-map"
> > Same thing as with the accessor functions for these, lets just name them
> > as follows since they are already namespaced as part of the VLAN
> > setting:
> >
> > #define NM_SETTING_VLAN_SLAVE "slave"
> > #define NM_SETTING_VLAN_ID "id"
> > #define NM_SETTING_VLAN_FLAGS "flags"
> >
> > We should also probably have an enum for the 'flags' somewhere, ie
> > called NMVlanFlags; I see later patches use VLAN_FLAG_REORDER_HDR but I
> > can't find a definition of that anywhere? And lets make it a typedef
> > too so we don't have to keep writing 'enum NMVlanFlags' everywhere.
> >
> The definition is in /usr/include/linux/if_vlan.h.
> 33 enum vlan_flags {
> 34 VLAN_FLAG_REORDER_HDR = 0x1,
> 35 VLAN_FLAG_GVRP = 0x2,
> 36 VLAN_FLAG_LOOSE_BINDING = 0x4,
> 37 };
Ok, but that's kernel headers and we're letting that leak into the NM
public API. I don't expect this to change in the future, but since it's
a "private" kernel header (things like this have changed before, ex WEXT
-> nl80211 for wifi) we should probably define an NM-specific enum type
for these flags and mirror the kernel definitions. I'd rather to do
that now than have to deal with the kernel stuff changing in the future.
> So we can make use of it instead of creating another 'enum NMVlanFlags'.
> >> +typedef struct {
> >> + NMSetting parent;
> >> +} NMSettingVLAN;
> >> +
> >> +typedef struct {
> >> + NMSettingClass parent;
> >> +
> >> + /* Padding for future expansion */
> >> + void (*_reserved1) (void);
> >> + void (*_reserved2) (void);
> >> + void (*_reserved3) (void);
> >> + void (*_reserved4) (void);
> >> +} NMSettingVLANClass;
> >> +
> >> +NMSetting *nm_setting_vlan_new(void);
> >> +const char *nm_setting_vlan_get_interface_name(NMSettingVLAN *setting);
> >> +const char *nm_setting_vlan_get_vlan_slave(NMSettingVLAN *setting);
> >> +guint32 nm_setting_vlan_get_vlan_id(NMSettingVLAN *setting);
> >> +guint32 nm_setting_vlan_get_vlan_flags(NMSettingVLAN *setting);
> > Once we get an enum for flags, we should return that enum type from
> > nm_setting_vlan_get_vlan_flags() too.
> But this flag is the OR of three different enum type, so maybe
> nm_setting_vlan_get_vlan_flags()
> should return gunit32.
True. Leave it as a guint32 then.
Dan
> >> +const char *nm_setting_vlan_get_vlan_priority_ingress_map(NMSettingVLAN *setting);
> >> +const char *nm_setting_vlan_get_vlan_priority_egress_map(NMSettingVLAN *setting);
> >> +
> >> +G_END_DECLS
> >> +
> >> +#endif /* NM_SETTING_VLAN_H */
> >> diff --git a/src/settings/plugins/ifcfg-rh/common.h b/src/settings/plugins/ifcfg-rh/common.h
> >> index 74a77c4..90f9584 100644
> >> --- a/src/settings/plugins/ifcfg-rh/common.h
> >> +++ b/src/settings/plugins/ifcfg-rh/common.h
> >> @@ -44,6 +44,7 @@
> >> #define TYPE_ETHERNET "Ethernet"
> >> #define TYPE_WIRELESS "Wireless"
> >> #define TYPE_BRIDGE "Bridge"
> >> +#define TYPE_VLAN "VLAN"
> >>
> >> #define SECRET_FLAG_AGENT "user"
> >> #define SECRET_FLAG_NOT_SAVED "ask"
> >> diff --git a/src/settings/plugins/ifcfg-rh/reader.c b/src/settings/plugins/ifcfg-rh/reader.c
> >> index 910cca3..7ba9509 100644
> >> --- a/src/settings/plugins/ifcfg-rh/reader.c
> >> +++ b/src/settings/plugins/ifcfg-rh/reader.c
> >> @@ -46,6 +46,7 @@
> >> #include<NetworkManager.h>
> >> #include<nm-setting-connection.h>
> >> #include<nm-setting-ip4-config.h>
> >> +#include<nm-setting-vlan.h>
> >> #include<nm-setting-ip6-config.h>
> >> #include<nm-setting-wired.h>
> >> #include<nm-setting-wireless.h>
> >> @@ -3298,6 +3299,130 @@ wired_connection_from_ifcfg (const char *file,
> >> return connection;
> >> }
> >>
> >> +static NMSetting *
> >> +make_vlan_setting (shvarFile *ifcfg,
> >> + const char *file,
> >> + gboolean nm_controlled,
> >> + char **unmanaged,
> >> + NMSetting8021x **s_8021x,
> >> + GError **error)
> >> +{
> >> + NMSettingVLAN *s_vlan = NULL;
> >> + char *value = NULL;
> >> + char *interface_name = NULL;
> >> + char *vlan_slave = NULL;
> >> + char *p = NULL;
> >> + guint32 vlan_id = 0;
> >> + guint32 vlan_flags = 0;
> >> + char *vlan_priority_ingress_map = NULL;
> >> + char *vlan_priority_egress_map = NULL;
> >> +
> >> +
> >> + s_vlan = NM_SETTING_VLAN(nm_setting_vlan_new());
> >> +
> >> + interface_name = svGetValue (ifcfg, "DEVICE", FALSE);
> >> + if (!interface_name)
> >> + goto error_return;
> >> + else {
> >> + if (!g_str_has_prefix(interface_name, "vlan"))
> >> + goto free_interface_name;
> >> +
> >> + g_object_set(s_vlan, NM_SETTING_VLAN_INTERFACE_NAME, interface_name, NULL);
> >> +
> >> + p = interface_name + 4;
> >> + vlan_id = g_ascii_strtoull(p, NULL, 10);
> >> + if (vlan_id>= 0&& vlan_id< 4096)
> >> + g_object_set(s_vlan, NM_SETTING_VLAN_VLAN_ID, vlan_id, NULL);
> >> + else
> >> + goto free_interface_name;
> >> + }
> >> +
> >> + vlan_slave = svGetValue (ifcfg, "PHYSDEV", FALSE);
> >> + if (vlan_slave) {
> >> + g_object_set(s_vlan, NM_SETTING_VLAN_VLAN_SLAVE, vlan_slave, NULL);
> >> + g_free(vlan_slave);
> >> + }
> >> +
> >> + value = svGetValue (ifcfg, "REORDER_HDR", FALSE);
> >> + if (value)
> >> + vlan_flags |= VLAN_FLAG_REORDER_HDR;
> > I couldn't find the definition of VLAN_FLAG_REORDER_HDR; did I just miss
> > that?
> >
> The definition is in /usr/include/linux/if_vlan.h.
> >> + g_free(value);
> >> +
> >> + value = svGetValue (ifcfg, "VLAN_FLAGS", FALSE);
> >> + if (g_strcmp0("VLAN_FLAG_GVRP", value)) {
> >> + vlan_flags |= VLAN_FLAG_GVRP;
> >> + } else if (g_strcmp0("VLAN_FLAG_LOOSE_BINDING", value)) {
> >> + vlan_flags |= VLAN_FLAG_LOOSE_BINDING;
> >> + }
> >> + g_object_set(s_vlan, NM_SETTING_VLAN_VLAN_FLAGS, vlan_flags, NULL);
> >> + g_free(value);
> >> +
> >> + vlan_priority_ingress_map = svGetValue (ifcfg, "VLAN_INGRESS_PRIORITY_MAP", FALSE);
> >> + if (vlan_priority_ingress_map) {
> >> + g_object_set(s_vlan, NM_SETTING_VLAN_VLAN_INGRESS_PRIORITY_MAP, vlan_priority_ingress_map, NULL);
> >> + g_free(vlan_priority_ingress_map);
> >> + }
> > So like I was talking about earlier, it's probably just easier to parse
> > the ingress/egress priorities when reading the ifcfg file in, rather
> > than having them as a string. That probably means adding list iterator
> > functions like we have for IP addresses, nameservers, etc, and creating
> > a small opaque structure for them (though we could just store them
> > internally as a 32-bit number and pack both of the<uint>:<uint> into
> > that, and save a lot of allocation). So we'd then get something like:
> >
> > guint32 nm_setting_vlan_get_num_ingress_priorities (NMSettingVlan *setting);
> > gboolean nm_setting_vlan_get_ingress_priority (NMSettingVlan *setting, guint32 i, guint32 *out_a, guint32 *out_b);
> > gboolean nm_setting_vlan_add_ingress_priority (NMSettingVlan *setting, guint32 a, b);
> > void nm_setting_vlan_remove_ingress_priority (NMSettingVlan *setting, guint32 i);
> > void nm_setting_vlan_clear_ingress_priorities (NMSettingVlan *setting);
> >
> > for both ingress and egress; that'll be a lot easier to work with
> > internally in NM since we'll only have to parse it once and then we can
> > just iterate through and pull them out.
> >
> > It's a bit more complicated than that for the actual GObject properties
> > though (and thus D-Bus marshalling). I vote we keep it simple and make
> > the GObject property type DBUS_TYPE_G_LIST_OF_STRING. This makes it
> > easier to use from D-Bus, but it also means we need converters for the
> > get_property() and set_property() functions in nm-setting-vlan.c. These
> > would take a GSList<string> and parse each "<uint>:<uint>" element into
> > the right integers to pass to nm_setting_vlan_add_ingress_priority().
> > Then in set_property() we'd do the reverse and build up a GSList of
> > allocated strings using the ingress/egress priorites and use that in the
> > call to g_value_set_boxed (). There are some examples of that in
> > various places, like the IPv4 config where we box/unbox (ie
> > marshall/demarshall) the property. I can explain more here if you want.
> >
> > Thanks,
> > Dan
> >
> Ok, thanks
> Weiping Pan
> >> + vlan_priority_egress_map = svGetValue (ifcfg, "VLAN_EGRESS_PRIORITY_MAP", FALSE);
> >> + if (vlan_priority_egress_map) {
> >> + g_object_set(s_vlan, NM_SETTING_VLAN_VLAN_EGRESS_PRIORITY_MAP, vlan_priority_egress_map, NULL);
> >> + g_free(vlan_priority_egress_map);
> >> + }
> >> + return (NMSetting *) s_vlan;
> >> +
> >> +free_interface_name:
> >> + g_free(interface_name);
> >> +error_return:
> >> + g_object_unref(s_vlan);
> >> + return NULL;
> >> +}
> >> +
> >> +static NMConnection *
> >> +vlan_connection_from_ifcfg (const char *file,
> >> + shvarFile *ifcfg,
> >> + gboolean nm_controlled,
> >> + char **unmanaged,
> >> + GError **error)
> >> +{
> >> + NMConnection *connection = NULL;
> >> + NMSetting *con_setting = NULL;
> >> + NMSetting *vlan_setting = NULL;
> >> + NMSetting8021x *s_8021x = NULL;
> >> +
> >> + g_return_val_if_fail (file != NULL, NULL);
> >> + g_return_val_if_fail (ifcfg != NULL, NULL);
> >> +
> >> + connection = nm_connection_new ();
> >> + if (!connection) {
> >> + g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
> >> + "Failed to allocate new connection for %s.", file);
> >> + return NULL;
> >> + }
> >> +
> >> + con_setting = make_connection_setting (file, ifcfg, NM_SETTING_VLAN_SETTING_NAME, NULL);
> >> + if (!con_setting) {
> >> + g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
> >> + "Failed to create connection setting.");
> >> + g_object_unref (connection);
> >> + return NULL;
> >> + }
> >> + nm_connection_add_setting (connection, con_setting);
> >> +
> >> + vlan_setting = make_vlan_setting (ifcfg, file, nm_controlled, unmanaged,&s_8021x, error);
> >> + if (!vlan_setting) {
> >> + g_object_unref (connection);
> >> + return NULL;
> >> + }
> >> + nm_connection_add_setting (connection, vlan_setting);
> >> +
> >> + if (!nm_connection_verify (connection, error)) {
> >> + g_object_unref (connection);
> >> + return NULL;
> >> + }
> >> +
> >> + return connection;
> >> +}
> >> +
> >> static gboolean
> >> is_wireless_device (const char *iface)
> >> {
> >> @@ -3342,7 +3467,6 @@ is_wireless_device (const char *iface)
> >> enum {
> >> IGNORE_REASON_NONE = 0x00,
> >> IGNORE_REASON_BRIDGE = 0x01,
> >> - IGNORE_REASON_VLAN = 0x02,
> >> };
> >>
> >> NMConnection *
> >> @@ -3456,7 +3580,7 @@ connection_from_file (const char *filename,
> >> g_free (lower);
> >> }
> >>
> >> - /* Ignore BRIDGE= and VLAN= connections for now too (rh #619863) */
> >> + /* Ignore BRIDGE= connections for now too (rh #619863) */
> >> tmp = svGetValue (parsed, "BRIDGE", FALSE);
> >> if (tmp) {
> >> g_free (tmp);
> >> @@ -3464,24 +3588,17 @@ connection_from_file (const char *filename,
> >> ignore_reason = IGNORE_REASON_BRIDGE;
> >> }
> >>
> >> - if (nm_controlled) {
> >> - tmp = svGetValue (parsed, "VLAN", FALSE);
> >> - if (tmp) {
> >> - g_free (tmp);
> >> - nm_controlled = FALSE;
> >> - ignore_reason = IGNORE_REASON_VLAN;
> >> - }
> >> - }
> >> -
> >> /* Construct the connection */
> >> if (!strcasecmp (type, TYPE_ETHERNET))
> >> connection = wired_connection_from_ifcfg (filename, parsed, nm_controlled, unmanaged,&error);
> >> else if (!strcasecmp (type, TYPE_WIRELESS))
> >> connection = wireless_connection_from_ifcfg (filename, parsed, nm_controlled, unmanaged,&error);
> >> - else if (!strcasecmp (type, TYPE_BRIDGE)) {
> >> + else if (!strcasecmp (type, TYPE_BRIDGE))
> >> g_set_error (&error, IFCFG_PLUGIN_ERROR, 0,
> >> "Bridge connections are not yet supported");
> >> - } else {
> >> + else if (!strcasecmp (type, TYPE_VLAN))
> >> + connection = vlan_connection_from_ifcfg (filename, parsed, nm_controlled, unmanaged,&error);
> >> + else {
> >> g_set_error (&error, IFCFG_PLUGIN_ERROR, 0,
> >> "Unknown connection type '%s'", type);
> >> }
> >> diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-interface b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-interface
> >> index 6c84185..d6d3f99 100644
> >> --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-interface
> >> +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-interface
> >> @@ -1,7 +1,12 @@
> >> -DEVICE=eth1.43
> >> VLAN=yes
> >> +TYPE=vlan
> >> +DEVICE=vlan43
> >> +PHYSDEV=eth9
> >> +REORDER_HDR=0
> >> +VLAN_FLAGS=GVRP,LOOSE_BINDING
> >> +VLAN_INGRESS_PRIORITY_MAP=0:1,2:5
> >> +VLAN_EGRESS_PRIORITY_MAP=12:3,14:7
> >> ONBOOT=yes
> >> -BOOTPROTO=none
> >> +BOOTPROTO=static
> >> IPADDR=192.168.43.149
> >> NETMASK=255.255.255.0
> >> -
> >
>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]