summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2015-10-12 15:15:21 +0200
committerThomas Haller <thaller@redhat.com>2015-11-01 17:28:09 +0100
commit07550f8daebca9f0eb8321b0f1d0c8822111b447 (patch)
treeab38d2e3422fd4b8bfc454a970a44013f00e061f
parent3d3762cee318777f931c56d0264fdd45fade182a (diff)
downloadNetworkManager-07550f8daebca9f0eb8321b0f1d0c8822111b447.tar.gz
platform: implement macvlan properties as lnk data
-rw-r--r--src/devices/nm-device-macvlan.c24
-rw-r--r--src/nm-types.h1
-rw-r--r--src/platform/nm-fake-platform.c7
-rw-r--r--src/platform/nm-linux-platform.c136
-rw-r--r--src/platform/nm-platform.c40
-rw-r--r--src/platform/nm-platform.h8
-rw-r--r--src/platform/nmp-object.c8
-rw-r--r--src/platform/nmp-object.h7
-rw-r--r--src/platform/tests/platform.c12
9 files changed, 136 insertions, 107 deletions
diff --git a/src/devices/nm-device-macvlan.c b/src/devices/nm-device-macvlan.c
index 26ea0be9b7..e2dd891c1a 100644
--- a/src/devices/nm-device-macvlan.c
+++ b/src/devices/nm-device-macvlan.c
@@ -39,7 +39,8 @@ G_DEFINE_TYPE (NMDeviceMacvlan, nm_device_macvlan, NM_TYPE_DEVICE_GENERIC)
#define NM_DEVICE_MACVLAN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_MACVLAN, NMDeviceMacvlanPrivate))
typedef struct {
- NMPlatformMacvlanProperties props;
+ int parent_ifindex;
+ NMPlatformLnkMacvlan props;
} NMDeviceMacvlanPrivate;
enum {
@@ -61,23 +62,26 @@ update_properties (NMDevice *device)
NMDeviceMacvlan *self = NM_DEVICE_MACVLAN (device);
NMDeviceMacvlanPrivate *priv = NM_DEVICE_MACVLAN_GET_PRIVATE (device);
GObject *object = G_OBJECT (device);
- NMPlatformMacvlanProperties props;
+ const NMPlatformLnkMacvlan *props;
+ const NMPlatformLink *plink;
- if (!nm_platform_macvlan_get_properties (NM_PLATFORM_GET, nm_device_get_ifindex (device), &props)) {
- _LOGW (LOGD_HW, "could not read macvlan properties");
+ props = nm_platform_link_get_lnk_macvlan (NM_PLATFORM_GET, nm_device_get_ifindex (device), &plink);
+ if (!props) {
+ _LOGW (LOGD_HW, "could not get macvlan properties");
return;
}
g_object_freeze_notify (object);
- if (priv->props.parent_ifindex != props.parent_ifindex)
+ if (priv->parent_ifindex != plink->parent)
g_object_notify (object, NM_DEVICE_MACVLAN_PARENT);
- if (g_strcmp0 (priv->props.mode, props.mode) != 0)
+ if (g_strcmp0 (priv->props.mode, props->mode) != 0)
g_object_notify (object, NM_DEVICE_MACVLAN_MODE);
- if (priv->props.no_promisc != props.no_promisc)
+ if (priv->props.no_promisc != props->no_promisc)
g_object_notify (object, NM_DEVICE_MACVLAN_NO_PROMISC);
- memcpy (&priv->props, &props, sizeof (NMPlatformMacvlanProperties));
+ priv->parent_ifindex = plink->parent;
+ priv->props = *props;
g_object_thaw_notify (object);
}
@@ -113,8 +117,8 @@ get_property (GObject *object, guint prop_id,
switch (prop_id) {
case PROP_PARENT:
- if (priv->props.parent_ifindex > 0)
- parent = nm_manager_get_device_by_ifindex (nm_manager_get (), priv->props.parent_ifindex);
+ if (priv->parent_ifindex > 0)
+ parent = nm_manager_get_device_by_ifindex (nm_manager_get (), priv->parent_ifindex);
else
parent = NULL;
nm_utils_g_value_set_object_path (value, parent);
diff --git a/src/nm-types.h b/src/nm-types.h
index fdcc4dbd6c..e84341bbe9 100644
--- a/src/nm-types.h
+++ b/src/nm-types.h
@@ -132,6 +132,7 @@ typedef enum {
NMP_OBJECT_TYPE_IP6_ROUTE,
NMP_OBJECT_TYPE_LNK_GRE,
+ NMP_OBJECT_TYPE_LNK_MACVLAN,
NMP_OBJECT_TYPE_LNK_VLAN,
NMP_OBJECT_TYPE_LNK_VXLAN,
diff --git a/src/platform/nm-fake-platform.c b/src/platform/nm-fake-platform.c
index ba7f0694d6..1616af46ec 100644
--- a/src/platform/nm-fake-platform.c
+++ b/src/platform/nm-fake-platform.c
@@ -724,12 +724,6 @@ veth_get_properties (NMPlatform *platform, int ifindex, NMPlatformVethProperties
}
static gboolean
-macvlan_get_properties (NMPlatform *platform, int ifindex, NMPlatformMacvlanProperties *props)
-{
- return FALSE;
-}
-
-static gboolean
wifi_get_capabilities (NMPlatform *platform, int ifindex, NMDeviceWifiCapabilities *caps)
{
NMFakePlatformLink *device = link_get (platform, ifindex);
@@ -1462,7 +1456,6 @@ nm_fake_platform_class_init (NMFakePlatformClass *klass)
platform_class->infiniband_get_info = infiniband_get_info;
platform_class->veth_get_properties = veth_get_properties;
- platform_class->macvlan_get_properties = macvlan_get_properties;
platform_class->wifi_get_capabilities = wifi_get_capabilities;
platform_class->wifi_get_bssid = wifi_get_bssid;
diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c
index 0336cdcec9..6d75778777 100644
--- a/src/platform/nm-linux-platform.c
+++ b/src/platform/nm-linux-platform.c
@@ -86,6 +86,13 @@
#define IFA_FLAGS 8
#define __IFA_MAX 9
+#define IFLA_MACVLAN_FLAGS 2
+#define __IFLA_MACVLAN_MAX 3
+
+#ifndef MACVLAN_FLAG_NOPROMISC
+#define MACVLAN_FLAG_NOPROMISC 1
+#endif
+
/*********************************************************************************************/
#define _NMLOG_PREFIX_NAME "platform-linux"
@@ -928,6 +935,58 @@ _parse_lnk_gre (const char *kind, struct nlattr *info_data)
/*****************************************************************************/
+static NMPObject *
+_parse_lnk_macvlan (const char *kind, struct nlattr *info_data)
+{
+ static struct nla_policy policy[IFLA_MACVLAN_MAX + 1] = {
+ [IFLA_MACVLAN_MODE] = { .type = NLA_U32 },
+ [IFLA_MACVLAN_FLAGS] = { .type = NLA_U16 },
+ };
+ NMPlatformLnkMacvlan *props;
+ struct nlattr *tb[IFLA_MACVLAN_MAX + 1];
+ int err;
+ NMPObject *obj;
+ const char *mode;
+
+ if (!info_data || g_strcmp0 (kind, "macvlan"))
+ return NULL;
+
+ err = nla_parse_nested (tb, IFLA_MACVLAN_MAX, info_data, policy);
+ if (err < 0)
+ return NULL;
+
+ if (!tb[IFLA_MACVLAN_MODE])
+ return NULL;
+
+ switch (nla_get_u32 (tb[IFLA_MACVLAN_MODE])) {
+ case MACVLAN_MODE_PRIVATE:
+ mode = "private";
+ break;
+ case MACVLAN_MODE_VEPA:
+ mode = "vepa";
+ break;
+ case MACVLAN_MODE_BRIDGE:
+ mode = "bridge";
+ break;
+ case MACVLAN_MODE_PASSTHRU:
+ mode = "passthru";
+ break;
+ default:
+ return NULL;
+ }
+
+ obj = nmp_object_new (NMP_OBJECT_TYPE_LNK_MACVLAN, NULL);
+ props = &obj->lnk_macvlan;
+ props->mode = mode;
+
+ if (tb[IFLA_MACVLAN_FLAGS])
+ props->no_promisc = NM_FLAGS_HAS (nla_get_u16 (tb[IFLA_MACVLAN_FLAGS]), MACVLAN_FLAG_NOPROMISC);
+
+ return obj;
+}
+
+/*****************************************************************************/
+
/* Copied and heavily modified from libnl3's vlan_parse() */
static NMPObject *
_parse_lnk_vlan (const char *kind, struct nlattr *info_data)
@@ -1225,6 +1284,9 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr
case NM_LINK_TYPE_GRE:
lnk_data = _parse_lnk_gre (nl_info_kind, nl_info_data);
break;
+ case NM_LINK_TYPE_MACVLAN:
+ lnk_data = _parse_lnk_macvlan (nl_info_kind, nl_info_data);
+ break;
case NM_LINK_TYPE_VLAN:
lnk_data = _parse_lnk_vlan (nl_info_kind, nl_info_data);
break;
@@ -3215,6 +3277,10 @@ link_get_lnk (NMPlatform *platform, int ifindex, NMLinkType link_type, const NMP
if (NMP_OBJECT_GET_TYPE (obj->_link.netlink.lnk) == NMP_OBJECT_TYPE_LNK_GRE)
return &obj->_link.netlink.lnk->lnk_gre;
break;
+ case NM_LINK_TYPE_MACVLAN:
+ if (NMP_OBJECT_GET_TYPE (obj->_link.netlink.lnk) == NMP_OBJECT_TYPE_LNK_MACVLAN)
+ return &obj->_link.netlink.lnk->lnk_macvlan;
+ break;
case NM_LINK_TYPE_VLAN:
if (NMP_OBJECT_GET_TYPE (obj->_link.netlink.lnk) == NMP_OBJECT_TYPE_LNK_VLAN)
return &obj->_link.netlink.lnk->lnk_vlan;
@@ -4043,75 +4109,6 @@ veth_get_properties (NMPlatform *platform, int ifindex, NMPlatformVethProperties
/******************************************************************/
-static const struct nla_policy macvlan_info_policy[IFLA_MACVLAN_MAX + 1] = {
- [IFLA_MACVLAN_MODE] = { .type = NLA_U32 },
-#ifdef MACVLAN_FLAG_NOPROMISC
- [IFLA_MACVLAN_FLAGS] = { .type = NLA_U16 },
-#endif
-};
-
-static int
-macvlan_info_data_parser (struct nlattr *info_data, gpointer parser_data)
-{
- NMPlatformMacvlanProperties *props = parser_data;
- struct nlattr *tb[IFLA_MACVLAN_MAX + 1];
- int err;
-
- err = nla_parse_nested (tb, IFLA_MACVLAN_MAX, info_data,
- (struct nla_policy *) macvlan_info_policy);
- if (err < 0)
- return err;
-
- switch (nla_get_u32 (tb[IFLA_MACVLAN_MODE])) {
- case MACVLAN_MODE_PRIVATE:
- props->mode = "private";
- break;
- case MACVLAN_MODE_VEPA:
- props->mode = "vepa";
- break;
- case MACVLAN_MODE_BRIDGE:
- props->mode = "bridge";
- break;
- case MACVLAN_MODE_PASSTHRU:
- props->mode = "passthru";
- break;
- default:
- return -NLE_PARSE_ERR;
- }
-
-#ifdef MACVLAN_FLAG_NOPROMISC
- props->no_promisc = !!(nla_get_u16 (tb[IFLA_MACVLAN_FLAGS]) & MACVLAN_FLAG_NOPROMISC);
-#else
- props->no_promisc = FALSE;
-#endif
-
- return 0;
-}
-
-static gboolean
-macvlan_get_properties (NMPlatform *platform, int ifindex, NMPlatformMacvlanProperties *props)
-{
- NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform);
- int err;
- const NMPObject *obj;
-
- obj = cache_lookup_link (platform, ifindex);
- if (!obj)
- return FALSE;
-
- props->parent_ifindex = obj->link.parent;
-
- err = _nl_link_parse_info_data (priv->nlh, ifindex,
- macvlan_info_data_parser, props);
- if (err != 0) {
- _LOGW ("(%s) could not read properties: %s",
- obj->link.name, nl_geterror (err));
- }
- return (err == 0);
-}
-
-/******************************************************************/
-
static WifiData *
wifi_get_wifi_data (NMPlatform *platform, int ifindex)
{
@@ -5341,7 +5338,6 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass)
platform_class->infiniband_get_info = infiniband_get_info;
platform_class->veth_get_properties = veth_get_properties;
- platform_class->macvlan_get_properties = macvlan_get_properties;
platform_class->wifi_get_capabilities = wifi_get_capabilities;
platform_class->wifi_get_bssid = wifi_get_bssid;
diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c
index 42c93ab65e..20695cbd37 100644
--- a/src/platform/nm-platform.c
+++ b/src/platform/nm-platform.c
@@ -1406,6 +1406,12 @@ nm_platform_link_get_lnk_gre (NMPlatform *self, int ifindex, const NMPlatformLin
return nm_platform_link_get_lnk (self, ifindex, NM_LINK_TYPE_GRE, out_link);
}
+const NMPlatformLnkMacvlan *
+nm_platform_link_get_lnk_macvlan (NMPlatform *self, int ifindex, const NMPlatformLink **out_link)
+{
+ return nm_platform_link_get_lnk (self, ifindex, NM_LINK_TYPE_MACVLAN, out_link);
+}
+
const NMPlatformLnkVlan *
nm_platform_link_get_lnk_vlan (NMPlatform *self, int ifindex, const NMPlatformLink **out_link)
{
@@ -1710,17 +1716,6 @@ nm_platform_tun_get_properties (NMPlatform *self, int ifindex, NMPlatformTunProp
}
gboolean
-nm_platform_macvlan_get_properties (NMPlatform *self, int ifindex, NMPlatformMacvlanProperties *props)
-{
- _CHECK_SELF (self, klass, FALSE);
-
- g_return_val_if_fail (ifindex > 0, FALSE);
- g_return_val_if_fail (props != NULL, FALSE);
-
- return klass->macvlan_get_properties (self, ifindex, props);
-}
-
-gboolean
nm_platform_wifi_get_capabilities (NMPlatform *self, int ifindex, NMDeviceWifiCapabilities *caps)
{
_CHECK_SELF (self, klass, FALSE);
@@ -2601,6 +2596,20 @@ nm_platform_lnk_gre_to_string (const NMPlatformLnkGre *lnk, char *buf, gsize len
}
const char *
+nm_platform_lnk_macvlan_to_string (const NMPlatformLnkMacvlan *lnk, char *buf, gsize len)
+{
+ if (!_to_string_buffer_init (lnk, &buf, &len))
+ return buf;
+
+ g_snprintf (buf, len,
+ "macvlan%s%s%s",
+ lnk->mode ? " mode " : "",
+ lnk->mode ?: "",
+ lnk->no_promisc ? " not-promisc" : " promisc");
+ return buf;
+}
+
+const char *
nm_platform_lnk_vlan_to_string (const NMPlatformLnkVlan *lnk, char *buf, gsize len)
{
if (!_to_string_buffer_init (lnk, &buf, &len))
@@ -3079,6 +3088,15 @@ nm_platform_lnk_gre_cmp (const NMPlatformLnkGre *a, const NMPlatformLnkGre *b)
}
int
+nm_platform_lnk_macvlan_cmp (const NMPlatformLnkMacvlan *a, const NMPlatformLnkMacvlan *b)
+{
+ _CMP_SELF (a, b);
+ _CMP_FIELD_STR_INTERNED (a, b, mode);
+ _CMP_FIELD_BOOL (a, b, no_promisc);
+ return 0;
+}
+
+int
nm_platform_lnk_vlan_cmp (const NMPlatformLnkVlan *a, const NMPlatformLnkVlan *b)
{
_CMP_SELF (a, b);
diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h
index f3ff8be029..d853829974 100644
--- a/src/platform/nm-platform.h
+++ b/src/platform/nm-platform.h
@@ -359,10 +359,9 @@ typedef struct {
} NMPlatformTunProperties;
typedef struct {
- int parent_ifindex;
const char *mode;
gboolean no_promisc;
-} NMPlatformMacvlanProperties;
+} NMPlatformLnkMacvlan;
typedef struct {
int parent_ifindex;
@@ -506,7 +505,6 @@ typedef struct {
const char **mode);
gboolean (*veth_get_properties) (NMPlatform *, int ifindex, NMPlatformVethProperties *properties);
- gboolean (*macvlan_get_properties) (NMPlatform *, int ifindex, NMPlatformMacvlanProperties *props);
gboolean (*wifi_get_capabilities) (NMPlatform *, int ifindex, NMDeviceWifiCapabilities *caps);
gboolean (*wifi_get_bssid) (NMPlatform *, int ifindex, guint8 *bssid);
@@ -691,6 +689,7 @@ char *nm_platform_slave_get_option (NMPlatform *self, int ifindex, const char *o
gconstpointer nm_platform_link_get_lnk (NMPlatform *self, int ifindex, NMLinkType link_type, const NMPlatformLink **out_link);
const NMPlatformLnkGre *nm_platform_link_get_lnk_gre (NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
+const NMPlatformLnkMacvlan *nm_platform_link_get_lnk_macvlan (NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
const NMPlatformLnkVlan *nm_platform_link_get_lnk_vlan (NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
const NMPlatformLnkVxlan *nm_platform_link_get_lnk_vxlan (NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
@@ -703,7 +702,6 @@ gboolean nm_platform_infiniband_get_info (NMPlatform *self, int ifindex, int *pa
gboolean nm_platform_veth_get_properties (NMPlatform *self, int ifindex, NMPlatformVethProperties *properties);
gboolean nm_platform_tun_get_properties (NMPlatform *self, int ifindex, NMPlatformTunProperties *properties);
-gboolean nm_platform_macvlan_get_properties (NMPlatform *self, int ifindex, NMPlatformMacvlanProperties *props);
gboolean nm_platform_tun_get_properties_ifname (NMPlatform *platform, const char *ifname, NMPlatformTunProperties *props);
@@ -770,6 +768,7 @@ extern char _nm_platform_to_string_buffer[1024];
const char *nm_platform_link_to_string (const NMPlatformLink *link, char *buf, gsize len);
const char *nm_platform_lnk_gre_to_string (const NMPlatformLnkGre *lnk, char *buf, gsize len);
+const char *nm_platform_lnk_macvlan_to_string (const NMPlatformLnkMacvlan *lnk, char *buf, gsize len);
const char *nm_platform_lnk_vlan_to_string (const NMPlatformLnkVlan *lnk, char *buf, gsize len);
const char *nm_platform_lnk_vxlan_to_string (const NMPlatformLnkVxlan *lnk, char *buf, gsize len);
const char *nm_platform_ip4_address_to_string (const NMPlatformIP4Address *address, char *buf, gsize len);
@@ -779,6 +778,7 @@ const char *nm_platform_ip6_route_to_string (const NMPlatformIP6Route *route, ch
int nm_platform_link_cmp (const NMPlatformLink *a, const NMPlatformLink *b);
int nm_platform_lnk_gre_cmp (const NMPlatformLnkGre *a, const NMPlatformLnkGre *b);
+int nm_platform_lnk_macvlan_cmp (const NMPlatformLnkMacvlan *a, const NMPlatformLnkMacvlan *b);
int nm_platform_lnk_vlan_cmp (const NMPlatformLnkVlan *a, const NMPlatformLnkVlan *b);
int nm_platform_lnk_vxlan_cmp (const NMPlatformLnkVxlan *a, const NMPlatformLnkVxlan *b);
int nm_platform_ip4_address_cmp (const NMPlatformIP4Address *a, const NMPlatformIP4Address *b);
diff --git a/src/platform/nmp-object.c b/src/platform/nmp-object.c
index bce94dc7eb..97b9b8cfae 100644
--- a/src/platform/nmp-object.c
+++ b/src/platform/nmp-object.c
@@ -1905,6 +1905,14 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = {
.cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_gre_to_string,
.cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_gre_cmp,
},
+ [NMP_OBJECT_TYPE_LNK_MACVLAN - 1] = {
+ .obj_type = NMP_OBJECT_TYPE_LNK_MACVLAN,
+ .sizeof_data = sizeof (NMPObjectLnkMacvlan),
+ .sizeof_public = sizeof (NMPlatformLnkMacvlan),
+ .obj_type_name = "macvlan",
+ .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_macvlan_to_string,
+ .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_macvlan_cmp,
+ },
[NMP_OBJECT_TYPE_LNK_VLAN - 1] = {
.obj_type = NMP_OBJECT_TYPE_LNK_VLAN,
.sizeof_data = sizeof (NMPObjectLnkVlan),
diff --git a/src/platform/nmp-object.h b/src/platform/nmp-object.h
index 157d335c4e..de7eea318f 100644
--- a/src/platform/nmp-object.h
+++ b/src/platform/nmp-object.h
@@ -162,6 +162,10 @@ typedef struct {
} NMPObjectLnkGre;
typedef struct {
+ NMPlatformLnkMacvlan _public;
+} NMPObjectLnkMacvlan;
+
+typedef struct {
NMPlatformLnkVlan _public;
} NMPObjectLnkVlan;
@@ -198,6 +202,9 @@ struct _NMPObject {
NMPlatformLnkGre lnk_gre;
NMPObjectLnkGre _lnk_gre;
+ NMPlatformLnkMacvlan lnk_macvlan;
+ NMPObjectLnkMacvlan _lnk_macvlan;
+
NMPlatformLnkVlan lnk_vlan;
NMPObjectLnkVlan _lnk_vlan;
diff --git a/src/platform/tests/platform.c b/src/platform/tests/platform.c
index 7868e3cbc0..860717baed 100644
--- a/src/platform/tests/platform.c
+++ b/src/platform/tests/platform.c
@@ -402,15 +402,17 @@ static gboolean
do_macvlan_get_properties (char **argv)
{
int ifindex = parse_ifindex (*argv++);
- NMPlatformMacvlanProperties props;
+ const NMPlatformLink *plink;
+ const NMPlatformLnkMacvlan *props;
- if (!nm_platform_macvlan_get_properties (NM_PLATFORM_GET, ifindex, &props))
+ props = nm_platform_link_get_lnk_macvlan (NM_PLATFORM_GET, ifindex, &plink);
+ if (!props)
return FALSE;
- printf ("parent: %d\n", props.parent_ifindex);
- printf ("mode: %s\n", props.mode);
+ printf ("parent: %d\n", plink->parent);
+ printf ("mode: %s\n", props->mode);
printf ("no-promisc: ");
- print_boolean (props.no_promisc);
+ print_boolean (props->no_promisc);
return TRUE;
}