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
