On Mon, 2011-11-21 at 08:20 -0500, Weiping Pan wrote:
> We make use of libnl (>=3.2.1) to create/delete kernel vlan device,
> and it can set vlan id, vlan flags and ingress/egress priority mapping.

This patch looks fine.

Dan

> V3:
> 1 nm_netlink_iface_to_index() should use slave name
> 
> V2:
> 1 use existing nm_netlink_iface_to_index()
> 
> Signed-off-by: Weiping Pan <[email protected]>
> ---
>  src/nm-system.c |  156 
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  src/nm-system.h |    5 ++-
>  2 files changed, 160 insertions(+), 1 deletions(-)
> 
> diff --git a/src/nm-system.c b/src/nm-system.c
> index 709a08b..9b4b22b 100644
> --- a/src/nm-system.c
> +++ b/src/nm-system.c
> @@ -59,6 +59,7 @@
>  #include <netlink/netlink.h>
>  #include <netlink/utils.h>
>  #include <netlink/route/link.h>
> +#include <netlink/route/link/vlan.h>
>  
>  #ifdef HAVE_LIBNL3
>  #include <netlink/route/link/bonding.h>
> @@ -1453,3 +1454,158 @@ nm_system_get_link_type (const char *name)
>       return type;
>  }
>  
> +static void ingress_priority_iterator(gpointer data, gpointer user_data)
> +{
> +     struct rtnl_link *new_link = (struct rtnl_link *)user_data;
> +     vlan_priority_map *item = (vlan_priority_map *)data;
> +
> +     g_return_if_fail (item != NULL);
> +     g_return_if_fail (new_link!= NULL);
> +
> +     if ((item->from < 0) || (item->from > 7))
> +             return;
> +     rtnl_link_vlan_set_ingress_map(new_link, item->from, item->to);
> +}
> +
> +static void egress_priority_iterator(gpointer data, gpointer user_data)
> +{
> +     struct rtnl_link *new_link = (struct rtnl_link *)user_data;
> +     vlan_priority_map *item = (vlan_priority_map *)data;
> +
> +     g_return_if_fail (item != NULL);
> +     g_return_if_fail (new_link!= NULL);
> +
> +     if ((item->to < 0) || (item->to > 7))
> +             return;
> +
> +     rtnl_link_vlan_set_egress_map(new_link, item->from, item->to);
> +}
> +
> +/**
> + * nm_system_add_vlan_device:
> + * @setting: NMSettingVlan
> + *
> + * Add a VLAN device specified in setting.
> + *
> + * Returns: %TRUE on success, or %FALSE
> + */
> +gboolean
> +nm_system_add_vlan_device(NMSettingVlan *setting)
> +{
> +     int ret = 0;
> +     int if_index = 0;
> +     struct rtnl_link *new_link = NULL;
> +     struct nl_sock *nlh = NULL;
> +     const GSList *list = NULL;
> +
> +     const char *interface_name = NULL;
> +     const char *vlan_slave = NULL;
> +     guint32 vlan_id = 0;
> +     guint32 vlan_flags = 0;
> +
> +     g_return_val_if_fail (NM_IS_SETTING_VLAN (setting), FALSE);
> +
> +     vlan_slave = nm_setting_vlan_get_slave(setting);
> +     g_return_val_if_fail (vlan_slave != NULL, FALSE);
> +
> +     vlan_id = nm_setting_vlan_get_id(setting);
> +     g_return_val_if_fail (vlan_id != 0, FALSE);
> +     g_return_val_if_fail (vlan_id < 4096, FALSE);
> +
> +     nlh = nm_netlink_get_default_handle();
> +     g_return_val_if_fail (nlh != NULL, FALSE);
> +
> +     interface_name = nm_setting_vlan_get_interface_name(setting);
> +     g_return_val_if_fail (interface_name != NULL, FALSE);
> +
> +     if_index = nm_netlink_iface_to_index(vlan_slave);
> +     g_return_val_if_fail (if_index > 0, FALSE);
> +
> +     new_link = rtnl_link_alloc();
> +     g_return_val_if_fail (new_link != NULL, FALSE);
> +
> +     ret = rtnl_link_set_type(new_link, "vlan");
> +     if (ret < 0)
> +             goto free_new_link;
> +
> +     rtnl_link_set_link(new_link, if_index);
> +     rtnl_link_set_name(new_link, interface_name);
> +     rtnl_link_vlan_set_id(new_link, vlan_id);
> +
> +     vlan_flags = nm_setting_vlan_get_flags(setting);
> +     if (vlan_flags)
> +             rtnl_link_vlan_set_flags(new_link, vlan_flags);
> +
> +     list = nm_setting_vlan_get_ingress_priority_map(setting);
> +     if (list != NULL)
> +             g_slist_foreach((GSList *)list, 
> (GFunc)ingress_priority_iterator, (gpointer)new_link);
> +
> +     list = nm_setting_vlan_get_egress_priority_map(setting);
> +     if (list != NULL)
> +             g_slist_foreach((GSList *)list, 
> (GFunc)egress_priority_iterator, (gpointer)new_link);
> +
> +     ret = rtnl_link_add(nlh, new_link, NLM_F_CREATE);
> +     if (ret < 0)
> +             goto free_new_link;
> +
> +     rtnl_link_put(new_link);
> +
> +     return TRUE;
> +
> +free_new_link:
> +     rtnl_link_put(new_link);
> +
> +     return FALSE;
> +}
> +
> +/**
> + * nm_system_del_vlan_device:
> + * @setting: NMSettingVlan
> + *
> + * Delete a VLAN device specified in setting.
> + *
> + * Returns: %TRUE on success, or %FALSE
> + */
> +gboolean
> +nm_system_del_vlan_device(NMSettingVlan *setting)
> +{
> +     int ret = 0;
> +     struct nl_sock *nlh = NULL;
> +     struct nl_cache *cache = NULL;
> +     struct rtnl_link *new_link = NULL;
> +     const char *interface_name = NULL;
> +
> +     interface_name = nm_setting_vlan_get_interface_name(setting);
> +     if (!interface_name)
> +             return FALSE;
> +
> +     nlh = nm_netlink_get_default_handle();
> +     if (!nlh)
> +             return FALSE;
> +
> +     ret = rtnl_link_alloc_cache(nlh, &cache);
> +     if (ret < 0)
> +             return FALSE;
> +
> +     if (!cache)
> +             return FALSE;
> +
> +     new_link = rtnl_link_get_by_name(cache, interface_name);
> +     if (!new_link)
> +             goto free_cache;
> +
> +     ret = rtnl_link_delete(nlh, new_link);
> +     if (ret < 0)
> +             goto free_new_link;
> +
> +     rtnl_link_put(new_link);
> +
> +     return TRUE;
> +
> +free_new_link:
> +     rtnl_link_put(new_link);
> +
> +free_cache:
> +     nl_cache_free(cache);
> +     return FALSE;
> +}
> diff --git a/src/nm-system.h b/src/nm-system.h
> index 339dfa7..5527b7d 100644
> --- a/src/nm-system.h
> +++ b/src/nm-system.h
> @@ -31,6 +31,7 @@
>  #include "nm-device.h"
>  #include "nm-ip4-config.h"
>  #include "nm-setting-bond.h"
> +#include "nm-setting-vlan.h"
>  
>  /* Prototypes for system/distribution dependent functions,
>   * implemented in the backend files in backends/ directory
> @@ -90,11 +91,13 @@ gboolean        nm_system_iface_is_up                   
> (int ifindex);
>  gboolean             nm_system_iface_set_mtu                 (int ifindex, 
> guint32 mtu);
>  
>  gboolean             nm_system_iface_set_mac                 (int ifindex, 
> const struct ether_addr *mac);
> -
>  gboolean             nm_system_add_bonding_master    (NMSettingBond 
> *setting);
>  gboolean             nm_system_iface_enslave         (NMDevice *slave, 
> NMDevice *master);
>  gboolean             nm_system_iface_release         (NMDevice *slave, 
> NMDevice *master);
>  
>  char *                       nm_system_get_link_type         (const char 
> *name);
>  
> +gboolean             nm_system_add_vlan_device(NMSettingVlan *setting);
> +gboolean             nm_system_del_vlan_device(NMSettingVlan *setting);
> +
>  #endif


_______________________________________________
networkmanager-list mailing list
[email protected]
http://mail.gnome.org/mailman/listinfo/networkmanager-list

Reply via email to