platform: add macvtap link creation support
This commit is contained in:
@@ -143,6 +143,7 @@ typedef enum {
|
|||||||
NMP_OBJECT_TYPE_LNK_IP6TNL,
|
NMP_OBJECT_TYPE_LNK_IP6TNL,
|
||||||
NMP_OBJECT_TYPE_LNK_IPIP,
|
NMP_OBJECT_TYPE_LNK_IPIP,
|
||||||
NMP_OBJECT_TYPE_LNK_MACVLAN,
|
NMP_OBJECT_TYPE_LNK_MACVLAN,
|
||||||
|
NMP_OBJECT_TYPE_LNK_MACVTAP,
|
||||||
NMP_OBJECT_TYPE_LNK_SIT,
|
NMP_OBJECT_TYPE_LNK_SIT,
|
||||||
NMP_OBJECT_TYPE_LNK_VLAN,
|
NMP_OBJECT_TYPE_LNK_VLAN,
|
||||||
NMP_OBJECT_TYPE_LNK_VXLAN,
|
NMP_OBJECT_TYPE_LNK_VXLAN,
|
||||||
|
@@ -1026,8 +1026,16 @@ _parse_lnk_macvlan (const char *kind, struct nlattr *info_data)
|
|||||||
struct nlattr *tb[IFLA_MACVLAN_MAX + 1];
|
struct nlattr *tb[IFLA_MACVLAN_MAX + 1];
|
||||||
int err;
|
int err;
|
||||||
NMPObject *obj;
|
NMPObject *obj;
|
||||||
|
gboolean tap;
|
||||||
|
|
||||||
if (!info_data || g_strcmp0 (kind, "macvlan"))
|
if (!info_data)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!g_strcmp0 (kind, "macvlan"))
|
||||||
|
tap = FALSE;
|
||||||
|
else if (!g_strcmp0 (kind, "macvtap"))
|
||||||
|
tap = TRUE;
|
||||||
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
err = nla_parse_nested (tb, IFLA_MACVLAN_MAX, info_data, policy);
|
err = nla_parse_nested (tb, IFLA_MACVLAN_MAX, info_data, policy);
|
||||||
@@ -1037,9 +1045,10 @@ _parse_lnk_macvlan (const char *kind, struct nlattr *info_data)
|
|||||||
if (!tb[IFLA_MACVLAN_MODE])
|
if (!tb[IFLA_MACVLAN_MODE])
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
obj = nmp_object_new (NMP_OBJECT_TYPE_LNK_MACVLAN, NULL);
|
obj = nmp_object_new (tap ? NMP_OBJECT_TYPE_LNK_MACVTAP : NMP_OBJECT_TYPE_LNK_MACVLAN, NULL);
|
||||||
props = &obj->lnk_macvlan;
|
props = &obj->lnk_macvlan;
|
||||||
props->mode = nla_get_u32 (tb[IFLA_MACVLAN_MODE]);
|
props->mode = nla_get_u32 (tb[IFLA_MACVLAN_MODE]);
|
||||||
|
props->tap = tap;
|
||||||
|
|
||||||
if (tb[IFLA_MACVLAN_FLAGS])
|
if (tb[IFLA_MACVLAN_FLAGS])
|
||||||
props->no_promisc = NM_FLAGS_HAS (nla_get_u16 (tb[IFLA_MACVLAN_FLAGS]), MACVLAN_FLAG_NOPROMISC);
|
props->no_promisc = NM_FLAGS_HAS (nla_get_u16 (tb[IFLA_MACVLAN_FLAGS]), MACVLAN_FLAG_NOPROMISC);
|
||||||
@@ -1475,6 +1484,7 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr
|
|||||||
lnk_data = _parse_lnk_ipip (nl_info_kind, nl_info_data);
|
lnk_data = _parse_lnk_ipip (nl_info_kind, nl_info_data);
|
||||||
break;
|
break;
|
||||||
case NM_LINK_TYPE_MACVLAN:
|
case NM_LINK_TYPE_MACVLAN:
|
||||||
|
case NM_LINK_TYPE_MACVTAP:
|
||||||
lnk_data = _parse_lnk_macvlan (nl_info_kind, nl_info_data);
|
lnk_data = _parse_lnk_macvlan (nl_info_kind, nl_info_data);
|
||||||
break;
|
break;
|
||||||
case NM_LINK_TYPE_SIT:
|
case NM_LINK_TYPE_SIT:
|
||||||
@@ -2889,6 +2899,7 @@ cache_pre_hook (NMPCache *cache, const NMPObject *old, const NMPObject *new, NMP
|
|||||||
case NM_LINK_TYPE_IP6TNL:
|
case NM_LINK_TYPE_IP6TNL:
|
||||||
case NM_LINK_TYPE_INFINIBAND:
|
case NM_LINK_TYPE_INFINIBAND:
|
||||||
case NM_LINK_TYPE_MACVLAN:
|
case NM_LINK_TYPE_MACVLAN:
|
||||||
|
case NM_LINK_TYPE_MACVTAP:
|
||||||
case NM_LINK_TYPE_SIT:
|
case NM_LINK_TYPE_SIT:
|
||||||
case NM_LINK_TYPE_VLAN:
|
case NM_LINK_TYPE_VLAN:
|
||||||
case NM_LINK_TYPE_VXLAN:
|
case NM_LINK_TYPE_VXLAN:
|
||||||
@@ -4366,7 +4377,8 @@ link_macvlan_add (NMPlatform *platform,
|
|||||||
struct nlattr *info;
|
struct nlattr *info;
|
||||||
struct nlattr *data;
|
struct nlattr *data;
|
||||||
|
|
||||||
_LOGD ("adding macvlan '%s' parent %u mode %u",
|
_LOGD ("adding %s '%s' parent %u mode %u",
|
||||||
|
props->tap ? "macvtap" : "macvlan",
|
||||||
name,
|
name,
|
||||||
parent,
|
parent,
|
||||||
props->mode);
|
props->mode);
|
||||||
@@ -4385,7 +4397,7 @@ link_macvlan_add (NMPlatform *platform,
|
|||||||
if (!(info = nla_nest_start (nlmsg, IFLA_LINKINFO)))
|
if (!(info = nla_nest_start (nlmsg, IFLA_LINKINFO)))
|
||||||
goto nla_put_failure;
|
goto nla_put_failure;
|
||||||
|
|
||||||
NLA_PUT_STRING (nlmsg, IFLA_INFO_KIND, "macvlan");
|
NLA_PUT_STRING (nlmsg, IFLA_INFO_KIND, props->tap ? "macvtap" : "macvlan");
|
||||||
|
|
||||||
if (!(data = nla_nest_start (nlmsg, IFLA_INFO_DATA)))
|
if (!(data = nla_nest_start (nlmsg, IFLA_INFO_DATA)))
|
||||||
goto nla_put_failure;
|
goto nla_put_failure;
|
||||||
@@ -4396,7 +4408,9 @@ link_macvlan_add (NMPlatform *platform,
|
|||||||
nla_nest_end (nlmsg, data);
|
nla_nest_end (nlmsg, data);
|
||||||
nla_nest_end (nlmsg, info);
|
nla_nest_end (nlmsg, info);
|
||||||
|
|
||||||
return do_add_link_with_lookup (platform, NM_LINK_TYPE_MACVLAN, name, nlmsg, out_link);
|
return do_add_link_with_lookup (platform,
|
||||||
|
props->tap ? NM_LINK_TYPE_MACVTAP : NM_LINK_TYPE_MACVLAN,
|
||||||
|
name, nlmsg, out_link);
|
||||||
nla_put_failure:
|
nla_put_failure:
|
||||||
g_return_val_if_reached (FALSE);
|
g_return_val_if_reached (FALSE);
|
||||||
}
|
}
|
||||||
|
@@ -1447,6 +1447,12 @@ nm_platform_link_get_lnk_macvlan (NMPlatform *self, int ifindex, const NMPlatfor
|
|||||||
return _link_get_lnk (self, ifindex, NM_LINK_TYPE_MACVLAN, out_link);
|
return _link_get_lnk (self, ifindex, NM_LINK_TYPE_MACVLAN, out_link);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const NMPlatformLnkMacvtap *
|
||||||
|
nm_platform_link_get_lnk_macvtap (NMPlatform *self, int ifindex, const NMPlatformLink **out_link)
|
||||||
|
{
|
||||||
|
return _link_get_lnk (self, ifindex, NM_LINK_TYPE_MACVTAP, out_link);
|
||||||
|
}
|
||||||
|
|
||||||
const NMPlatformLnkSit *
|
const NMPlatformLnkSit *
|
||||||
nm_platform_link_get_lnk_sit (NMPlatform *self, int ifindex, const NMPlatformLink **out_link)
|
nm_platform_link_get_lnk_sit (NMPlatform *self, int ifindex, const NMPlatformLink **out_link)
|
||||||
{
|
{
|
||||||
@@ -1950,7 +1956,7 @@ nm_platform_link_ipip_add (NMPlatform *self,
|
|||||||
* @props: interface properties
|
* @props: interface properties
|
||||||
* @out_link: on success, the link object
|
* @out_link: on success, the link object
|
||||||
*
|
*
|
||||||
* Create a MACVLAN device.
|
* Create a MACVLAN or MACVTAP device.
|
||||||
*/
|
*/
|
||||||
NMPlatformError
|
NMPlatformError
|
||||||
nm_platform_link_macvlan_add (NMPlatform *self,
|
nm_platform_link_macvlan_add (NMPlatform *self,
|
||||||
@@ -1960,17 +1966,21 @@ nm_platform_link_macvlan_add (NMPlatform *self,
|
|||||||
NMPlatformLink *out_link)
|
NMPlatformLink *out_link)
|
||||||
{
|
{
|
||||||
NMPlatformError plerr;
|
NMPlatformError plerr;
|
||||||
|
NMLinkType type;
|
||||||
|
|
||||||
_CHECK_SELF (self, klass, NM_PLATFORM_ERROR_BUG);
|
_CHECK_SELF (self, klass, NM_PLATFORM_ERROR_BUG);
|
||||||
|
|
||||||
g_return_val_if_fail (props, NM_PLATFORM_ERROR_BUG);
|
g_return_val_if_fail (props, NM_PLATFORM_ERROR_BUG);
|
||||||
g_return_val_if_fail (name, NM_PLATFORM_ERROR_BUG);
|
g_return_val_if_fail (name, NM_PLATFORM_ERROR_BUG);
|
||||||
|
|
||||||
plerr = _link_add_check_existing (self, name, NM_LINK_TYPE_MACVLAN, out_link);
|
type = props->tap ? NM_LINK_TYPE_MACVTAP : NM_LINK_TYPE_MACVLAN;
|
||||||
|
|
||||||
|
plerr = _link_add_check_existing (self, name, type, out_link);
|
||||||
if (plerr != NM_PLATFORM_ERROR_SUCCESS)
|
if (plerr != NM_PLATFORM_ERROR_SUCCESS)
|
||||||
return plerr;
|
return plerr;
|
||||||
|
|
||||||
_LOGD ("adding macvlan '%s' parent %u mode %u",
|
_LOGD ("adding %s '%s' parent %u mode %u",
|
||||||
|
props->tap ? "macvtap" : "macvlan",
|
||||||
name,
|
name,
|
||||||
parent,
|
parent,
|
||||||
props->mode);
|
props->mode);
|
||||||
|
@@ -402,8 +402,11 @@ typedef struct {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
guint mode;
|
guint mode;
|
||||||
gboolean no_promisc;
|
gboolean no_promisc;
|
||||||
|
gboolean tap;
|
||||||
} NMPlatformLnkMacvlan;
|
} NMPlatformLnkMacvlan;
|
||||||
|
|
||||||
|
typedef NMPlatformLnkMacvlan NMPlatformLnkMacvtap;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int parent_ifindex;
|
int parent_ifindex;
|
||||||
in_addr_t local;
|
in_addr_t local;
|
||||||
@@ -763,6 +766,7 @@ const NMPlatformLnkIpIp *nm_platform_link_get_lnk_ipip (NMPlatform *self, int if
|
|||||||
const NMPlatformLnkInfiniband *nm_platform_link_get_lnk_infiniband (NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
|
const NMPlatformLnkInfiniband *nm_platform_link_get_lnk_infiniband (NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
|
||||||
const NMPlatformLnkIpIp *nm_platform_link_get_lnk_ipip (NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
|
const NMPlatformLnkIpIp *nm_platform_link_get_lnk_ipip (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 NMPlatformLnkMacvlan *nm_platform_link_get_lnk_macvlan (NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
|
||||||
|
const NMPlatformLnkMacvtap *nm_platform_link_get_lnk_macvtap (NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
|
||||||
const NMPlatformLnkSit *nm_platform_link_get_lnk_sit (NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
|
const NMPlatformLnkSit *nm_platform_link_get_lnk_sit (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 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);
|
const NMPlatformLnkVxlan *nm_platform_link_get_lnk_vxlan (NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
|
||||||
|
@@ -2072,6 +2072,15 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = {
|
|||||||
.cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_macvlan_to_string,
|
.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,
|
.cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_macvlan_cmp,
|
||||||
},
|
},
|
||||||
|
[NMP_OBJECT_TYPE_LNK_MACVTAP - 1] = {
|
||||||
|
.obj_type = NMP_OBJECT_TYPE_LNK_MACVTAP,
|
||||||
|
.sizeof_data = sizeof (NMPObjectLnkMacvtap),
|
||||||
|
.sizeof_public = sizeof (NMPlatformLnkMacvtap),
|
||||||
|
.obj_type_name = "macvtap",
|
||||||
|
.lnk_link_type = NM_LINK_TYPE_MACVTAP,
|
||||||
|
.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_SIT - 1] = {
|
[NMP_OBJECT_TYPE_LNK_SIT - 1] = {
|
||||||
.obj_type = NMP_OBJECT_TYPE_LNK_SIT,
|
.obj_type = NMP_OBJECT_TYPE_LNK_SIT,
|
||||||
.sizeof_data = sizeof (NMPObjectLnkSit),
|
.sizeof_data = sizeof (NMPObjectLnkSit),
|
||||||
|
@@ -181,6 +181,8 @@ typedef struct {
|
|||||||
NMPlatformLnkMacvlan _public;
|
NMPlatformLnkMacvlan _public;
|
||||||
} NMPObjectLnkMacvlan;
|
} NMPObjectLnkMacvlan;
|
||||||
|
|
||||||
|
typedef NMPObjectLnkMacvlan NMPObjectLnkMacvtap;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
NMPlatformLnkSit _public;
|
NMPlatformLnkSit _public;
|
||||||
} NMPObjectLnkSit;
|
} NMPObjectLnkSit;
|
||||||
|
@@ -794,13 +794,14 @@ nmtstp_link_macvlan_add (gboolean external_command, const char *name, int parent
|
|||||||
g_assert (dev);
|
g_assert (dev);
|
||||||
g_assert_cmpint (lnk->mode, <, G_N_ELEMENTS (modes));
|
g_assert_cmpint (lnk->mode, <, G_N_ELEMENTS (modes));
|
||||||
|
|
||||||
success = !nmtstp_run_command ("ip link add name %s link %s type macvlan mode %s %s",
|
success = !nmtstp_run_command ("ip link add name %s link %s type %s mode %s %s",
|
||||||
name,
|
name,
|
||||||
dev,
|
dev,
|
||||||
|
lnk->tap ? "macvtap" : "macvlan",
|
||||||
modes[lnk->mode],
|
modes[lnk->mode],
|
||||||
lnk->no_promisc ? "nopromisc" : "");
|
lnk->no_promisc ? "nopromisc" : "");
|
||||||
if (success)
|
if (success)
|
||||||
nmtstp_assert_wait_for_link (name, NM_LINK_TYPE_MACVLAN, 100);
|
nmtstp_assert_wait_for_link (name, lnk->tap ? NM_LINK_TYPE_MACVTAP : NM_LINK_TYPE_MACVLAN, 100);
|
||||||
} else
|
} else
|
||||||
success = nm_platform_link_macvlan_add (NM_PLATFORM_GET, name, parent, lnk, NULL) == NM_PLATFORM_ERROR_SUCCESS;
|
success = nm_platform_link_macvlan_add (NM_PLATFORM_GET, name, parent, lnk, NULL) == NM_PLATFORM_ERROR_SUCCESS;
|
||||||
|
|
||||||
|
@@ -745,11 +745,23 @@ test_software_detect (gconstpointer user_data)
|
|||||||
|
|
||||||
lnk_macvlan.mode = MACVLAN_MODE_BRIDGE;
|
lnk_macvlan.mode = MACVLAN_MODE_BRIDGE;
|
||||||
lnk_macvlan.no_promisc = FALSE;
|
lnk_macvlan.no_promisc = FALSE;
|
||||||
|
lnk_macvlan.tap = FALSE;
|
||||||
|
|
||||||
if (!nmtstp_link_macvlan_add (EX, DEVICE_NAME, ifindex_parent, &lnk_macvlan))
|
if (!nmtstp_link_macvlan_add (EX, DEVICE_NAME, ifindex_parent, &lnk_macvlan))
|
||||||
g_error ("Failed adding MACVLAN interface");
|
g_error ("Failed adding MACVLAN interface");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case NM_LINK_TYPE_MACVTAP: {
|
||||||
|
NMPlatformLnkMacvtap lnk_macvtap = { };
|
||||||
|
|
||||||
|
lnk_macvtap.mode = MACVLAN_MODE_PRIVATE;
|
||||||
|
lnk_macvtap.no_promisc = FALSE;
|
||||||
|
lnk_macvtap.tap = TRUE;
|
||||||
|
|
||||||
|
if (!nmtstp_link_macvlan_add (EX, DEVICE_NAME, ifindex_parent, &lnk_macvtap))
|
||||||
|
g_error ("Failed adding MACVTAP interface");
|
||||||
|
break;
|
||||||
|
}
|
||||||
case NM_LINK_TYPE_SIT: {
|
case NM_LINK_TYPE_SIT: {
|
||||||
NMPlatformLnkSit lnk_sit = { };
|
NMPlatformLnkSit lnk_sit = { };
|
||||||
gboolean gracefully_skip = FALSE;
|
gboolean gracefully_skip = FALSE;
|
||||||
@@ -877,6 +889,14 @@ test_software_detect (gconstpointer user_data)
|
|||||||
g_assert_cmpint (plnk->mode, ==, MACVLAN_MODE_BRIDGE);
|
g_assert_cmpint (plnk->mode, ==, MACVLAN_MODE_BRIDGE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case NM_LINK_TYPE_MACVTAP: {
|
||||||
|
const NMPlatformLnkMacvtap *plnk = &lnk->lnk_macvlan;
|
||||||
|
|
||||||
|
g_assert (plnk == nm_platform_link_get_lnk_macvtap (NM_PLATFORM_GET, ifindex, NULL));
|
||||||
|
g_assert_cmpint (plnk->no_promisc, ==, FALSE);
|
||||||
|
g_assert_cmpint (plnk->mode, ==, MACVLAN_MODE_PRIVATE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case NM_LINK_TYPE_SIT: {
|
case NM_LINK_TYPE_SIT: {
|
||||||
const NMPlatformLnkSit *plnk = &lnk->lnk_sit;
|
const NMPlatformLnkSit *plnk = &lnk->lnk_sit;
|
||||||
|
|
||||||
@@ -1710,6 +1730,7 @@ setup_tests (void)
|
|||||||
test_software_detect_add ("/link/software/detect/ip6tnl", NM_LINK_TYPE_IP6TNL, 0);
|
test_software_detect_add ("/link/software/detect/ip6tnl", NM_LINK_TYPE_IP6TNL, 0);
|
||||||
test_software_detect_add ("/link/software/detect/ipip", NM_LINK_TYPE_IPIP, 0);
|
test_software_detect_add ("/link/software/detect/ipip", NM_LINK_TYPE_IPIP, 0);
|
||||||
test_software_detect_add ("/link/software/detect/macvlan", NM_LINK_TYPE_MACVLAN, 0);
|
test_software_detect_add ("/link/software/detect/macvlan", NM_LINK_TYPE_MACVLAN, 0);
|
||||||
|
test_software_detect_add ("/link/software/detect/macvtap", NM_LINK_TYPE_MACVTAP, 0);
|
||||||
test_software_detect_add ("/link/software/detect/sit", NM_LINK_TYPE_SIT, 0);
|
test_software_detect_add ("/link/software/detect/sit", NM_LINK_TYPE_SIT, 0);
|
||||||
test_software_detect_add ("/link/software/detect/vlan", NM_LINK_TYPE_VLAN, 0);
|
test_software_detect_add ("/link/software/detect/vlan", NM_LINK_TYPE_VLAN, 0);
|
||||||
test_software_detect_add ("/link/software/detect/vxlan/0", NM_LINK_TYPE_VXLAN, 0);
|
test_software_detect_add ("/link/software/detect/vxlan/0", NM_LINK_TYPE_VXLAN, 0);
|
||||||
|
Reference in New Issue
Block a user