mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-02-13 17:30:33 +01:00
platform: add support for bridge vlans
This commit is contained in:
parent
be2fbd0c69
commit
fafde171ea
3 changed files with 121 additions and 1 deletions
|
|
@ -29,6 +29,7 @@
|
|||
#include <linux/fib_rules.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/if_arp.h>
|
||||
#include <linux/if_bridge.h>
|
||||
#include <linux/if_link.h>
|
||||
#include <linux/if_tun.h>
|
||||
#include <linux/if_tunnel.h>
|
||||
|
|
@ -277,6 +278,14 @@ struct _ifla_vf_vlan_info {
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
/* Appeared in in kernel 4.0 dated April 12, 2015 */
|
||||
#ifndef BRIDGE_VLAN_INFO_RANGE_BEGIN
|
||||
#define BRIDGE_VLAN_INFO_RANGE_BEGIN (1 << 3) /* VLAN is start of vlan range */
|
||||
#define BRIDGE_VLAN_INFO_RANGE_END (1 << 4) /* VLAN is end of vlan range */
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef enum {
|
||||
INFINIBAND_ACTION_CREATE_CHILD,
|
||||
INFINIBAND_ACTION_DELETE_CHILD,
|
||||
|
|
@ -3858,7 +3867,7 @@ _nl_msg_new_link_full (int nlmsg_type,
|
|||
.ifi_index = ifindex,
|
||||
};
|
||||
|
||||
nm_assert (NM_IN_SET (nlmsg_type, RTM_DELLINK, RTM_NEWLINK, RTM_GETLINK));
|
||||
nm_assert (NM_IN_SET (nlmsg_type, RTM_DELLINK, RTM_NEWLINK, RTM_GETLINK, RTM_SETLINK));
|
||||
|
||||
msg = nlmsg_alloc_simple (nlmsg_type, nlmsg_flags);
|
||||
|
||||
|
|
@ -6781,6 +6790,67 @@ nla_put_failure:
|
|||
g_return_val_if_reached (FALSE);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
link_set_bridge_vlans (NMPlatform *platform,
|
||||
int ifindex,
|
||||
gboolean on_master,
|
||||
const NMPlatformBridgeVlan *const *vlans)
|
||||
{
|
||||
nm_auto_nlmsg struct nl_msg *nlmsg = NULL;
|
||||
struct nlattr *list;
|
||||
struct bridge_vlan_info vinfo = { };
|
||||
guint i;
|
||||
|
||||
nlmsg = _nl_msg_new_link_full (vlans ? RTM_SETLINK : RTM_DELLINK,
|
||||
0,
|
||||
ifindex,
|
||||
NULL,
|
||||
AF_BRIDGE,
|
||||
0,
|
||||
0);
|
||||
if (!nlmsg)
|
||||
g_return_val_if_reached (-NME_BUG);
|
||||
|
||||
if (!(list = nla_nest_start (nlmsg, IFLA_AF_SPEC)))
|
||||
goto nla_put_failure;
|
||||
|
||||
NLA_PUT_U16 (nlmsg,
|
||||
IFLA_BRIDGE_FLAGS,
|
||||
on_master ? BRIDGE_FLAGS_MASTER : BRIDGE_FLAGS_SELF);
|
||||
|
||||
if (vlans) {
|
||||
/* Add VLANs */
|
||||
for (i = 0; vlans[i]; i++) {
|
||||
const NMPlatformBridgeVlan *vlan = vlans[i];
|
||||
|
||||
vinfo.vid = vlan->vid;
|
||||
vinfo.flags = 0;
|
||||
|
||||
if (vlan->untagged)
|
||||
vinfo.flags |= BRIDGE_VLAN_INFO_UNTAGGED;
|
||||
if (vlan->pvid)
|
||||
vinfo.flags |= BRIDGE_VLAN_INFO_PVID;
|
||||
|
||||
NLA_PUT (nlmsg, IFLA_BRIDGE_VLAN_INFO, sizeof (vinfo), &vinfo);
|
||||
}
|
||||
} else {
|
||||
/* Flush existing VLANs */
|
||||
vinfo.vid = 1;
|
||||
vinfo.flags = BRIDGE_VLAN_INFO_RANGE_BEGIN;
|
||||
NLA_PUT (nlmsg, IFLA_BRIDGE_VLAN_INFO, sizeof (vinfo), &vinfo);
|
||||
|
||||
vinfo.vid = 4094;
|
||||
vinfo.flags = BRIDGE_VLAN_INFO_RANGE_END;
|
||||
NLA_PUT (nlmsg, IFLA_BRIDGE_VLAN_INFO, sizeof (vinfo), &vinfo);
|
||||
}
|
||||
|
||||
nla_nest_end (nlmsg, list);
|
||||
|
||||
return (do_change_link (platform, CHANGE_LINK_TYPE_UNSPEC, ifindex, nlmsg, NULL) >= 0);
|
||||
nla_put_failure:
|
||||
g_return_val_if_reached (FALSE);
|
||||
}
|
||||
|
||||
static char *
|
||||
link_get_physical_port_id (NMPlatform *platform, int ifindex)
|
||||
{
|
||||
|
|
@ -8921,6 +8991,7 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass)
|
|||
platform_class->link_set_name = link_set_name;
|
||||
platform_class->link_set_sriov_params = link_set_sriov_params;
|
||||
platform_class->link_set_sriov_vfs = link_set_sriov_vfs;
|
||||
platform_class->link_set_bridge_vlans = link_set_bridge_vlans;
|
||||
|
||||
platform_class->link_get_physical_port_id = link_get_physical_port_id;
|
||||
platform_class->link_get_dev_id = link_get_dev_id;
|
||||
|
|
|
|||
|
|
@ -1518,6 +1518,28 @@ nm_platform_link_set_sriov_vfs (NMPlatform *self, int ifindex, const NMPlatformV
|
|||
return klass->link_set_sriov_vfs (self, ifindex, vfs);
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_platform_link_set_bridge_vlans (NMPlatform *self, int ifindex, gboolean on_master, const NMPlatformBridgeVlan *const *vlans)
|
||||
{
|
||||
guint i;
|
||||
_CHECK_SELF (self, klass, FALSE);
|
||||
|
||||
g_return_val_if_fail (ifindex > 0, FALSE);
|
||||
|
||||
_LOG3D ("link: %s bridge VLANs on %s",
|
||||
vlans ? "setting" : "clearing",
|
||||
on_master ? "master" : "self");
|
||||
if (vlans) {
|
||||
for (i = 0; vlans[i]; i++) {
|
||||
const NMPlatformBridgeVlan *vlan = vlans[i];
|
||||
|
||||
_LOG3D ("link: bridge VLAN %s", nm_platform_bridge_vlan_to_string (vlan, NULL, 0));
|
||||
}
|
||||
}
|
||||
|
||||
return klass->link_set_bridge_vlans (self, ifindex, on_master, vlans);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_platform_link_set_up:
|
||||
* @self: platform instance
|
||||
|
|
@ -6506,6 +6528,24 @@ nm_platform_vf_to_string (const NMPlatformVF *vf, char *buf, gsize len)
|
|||
return buf;
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
nm_platform_bridge_vlan_to_string (const NMPlatformBridgeVlan *vlan, char *buf, gsize len)
|
||||
{
|
||||
if (!nm_utils_to_string_buffer_init_null (vlan, &buf, &len))
|
||||
return buf;
|
||||
|
||||
g_snprintf (buf, len,
|
||||
"%u"
|
||||
"%s"
|
||||
"%s",
|
||||
vlan->vid,
|
||||
vlan->pvid ? " PVID" : "",
|
||||
vlan->untagged ? " untagged" : "");
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
void
|
||||
nm_platform_link_hash_update (const NMPlatformLink *obj, NMHashState *h)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -670,6 +670,12 @@ typedef struct {
|
|||
gint8 trust;
|
||||
} NMPlatformVF;
|
||||
|
||||
typedef struct {
|
||||
guint16 vid;
|
||||
bool untagged:1;
|
||||
bool pvid:1;
|
||||
} NMPlatformBridgeVlan;
|
||||
|
||||
typedef struct {
|
||||
in_addr_t local;
|
||||
in_addr_t remote;
|
||||
|
|
@ -893,6 +899,7 @@ typedef struct {
|
|||
gboolean (*link_set_name) (NMPlatform *, int ifindex, const char *name);
|
||||
gboolean (*link_set_sriov_params) (NMPlatform *, int ifindex, guint num_vfs, int autoprobe);
|
||||
gboolean (*link_set_sriov_vfs) (NMPlatform *self, int ifindex, const NMPlatformVF *const *vfs);
|
||||
gboolean (*link_set_bridge_vlans) (NMPlatform *self, int ifindex, gboolean on_master, const NMPlatformBridgeVlan *const *vlans);
|
||||
|
||||
char * (*link_get_physical_port_id) (NMPlatform *, int ifindex);
|
||||
guint (*link_get_dev_id) (NMPlatform *, int ifindex);
|
||||
|
|
@ -1326,6 +1333,7 @@ int nm_platform_link_set_mtu (NMPlatform *self, int ifindex, guint32 mtu);
|
|||
gboolean nm_platform_link_set_name (NMPlatform *self, int ifindex, const char *name);
|
||||
gboolean nm_platform_link_set_sriov_params (NMPlatform *self, int ifindex, guint num_vfs, int autoprobe);
|
||||
gboolean nm_platform_link_set_sriov_vfs (NMPlatform *self, int ifindex, const NMPlatformVF *const *vfs);
|
||||
gboolean nm_platform_link_set_bridge_vlans (NMPlatform *self, int ifindex, gboolean on_master, const NMPlatformBridgeVlan *const *vlans);
|
||||
|
||||
char *nm_platform_link_get_physical_port_id (NMPlatform *self, int ifindex);
|
||||
guint nm_platform_link_get_dev_id (NMPlatform *self, int ifindex);
|
||||
|
|
@ -1585,6 +1593,7 @@ const char *nm_platform_routing_rule_to_string (const NMPlatformRoutingRule *rou
|
|||
const char *nm_platform_qdisc_to_string (const NMPlatformQdisc *qdisc, char *buf, gsize len);
|
||||
const char *nm_platform_tfilter_to_string (const NMPlatformTfilter *tfilter, char *buf, gsize len);
|
||||
const char *nm_platform_vf_to_string (const NMPlatformVF *vf, char *buf, gsize len);
|
||||
const char *nm_platform_bridge_vlan_to_string (const NMPlatformBridgeVlan *vlan, char *buf, gsize len);
|
||||
|
||||
const char *nm_platform_vlan_qos_mapping_to_string (const char *name,
|
||||
const NMVlanQosMapping *map,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue