platform: add nm_platform_link_veth_add() to create VETH links

This commit is contained in:
Thomas Haller 2017-05-26 14:00:29 +02:00
parent b14c07f70e
commit 6ab2288c28
4 changed files with 68 additions and 18 deletions

View file

@ -323,12 +323,14 @@ static gboolean
link_add (NMPlatform *platform,
const char *name,
NMLinkType type,
const char *veth_peer,
const void *address,
size_t address_len,
const NMPlatformLink **out_link)
{
NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE ((NMFakePlatform *) platform);
NMFakePlatformLink device;
NMFakePlatformLink device_veth = { };
NMFakePlatformLink *new_device;
link_init (&device, priv->links->len, type, name);
@ -342,14 +344,29 @@ link_add (NMPlatform *platform,
g_array_append_val (priv->links, device);
new_device = &g_array_index (priv->links, NMFakePlatformLink, priv->links->len - 1);
if (veth_peer) {
link_init (&device_veth, priv->links->len, type, veth_peer);
g_array_append_val (priv->links, device_veth);
new_device = &g_array_index (priv->links, NMFakePlatformLink, priv->links->len - 2);
} else
g_assert (type != NM_LINK_TYPE_VETH);
if (out_link)
*out_link = &new_device->link;
if (device.link.ifindex) {
g_signal_emit_by_name (platform, NM_PLATFORM_SIGNAL_LINK_CHANGED, (int) NMP_OBJECT_TYPE_LINK, device.link.ifindex, &device, (int) NM_PLATFORM_SIGNAL_ADDED);
link_changed (platform, new_device, FALSE);
}
if (veth_peer) {
g_signal_emit_by_name (platform, NM_PLATFORM_SIGNAL_LINK_CHANGED, (int) NMP_OBJECT_TYPE_LINK, device_veth.link.ifindex, &device_veth, (int) NM_PLATFORM_SIGNAL_ADDED);
link_changed (platform, &g_array_index (priv->links, NMFakePlatformLink, priv->links->len - 1), FALSE);
}
if (out_link)
*out_link = &new_device->link;
return TRUE;
}
@ -702,7 +719,7 @@ vlan_add (NMPlatform *platform, const char *name, int parent, int vlan_id, guint
{
NMFakePlatformLink *device;
if (!link_add (platform, name, NM_LINK_TYPE_VLAN, NULL, 0, out_link))
if (!link_add (platform, name, NM_LINK_TYPE_VLAN, NULL, NULL, 0, out_link))
return FALSE;
device = link_get (platform, nm_platform_link_get_ifindex (platform, name));
@ -742,7 +759,7 @@ link_vxlan_add (NMPlatform *platform,
{
NMFakePlatformLink *device;
if (!link_add (platform, name, NM_LINK_TYPE_VXLAN, NULL, 0, out_link))
if (!link_add (platform, name, NM_LINK_TYPE_VXLAN, NULL, NULL, 0, out_link))
return FALSE;
device = link_get (platform, nm_platform_link_get_ifindex (platform, name));
@ -770,7 +787,7 @@ infiniband_partition_add (NMPlatform *platform, int parent, int p_key, const NMP
nm_utils_new_infiniband_name (name, parent_device->link.name, p_key);
if (!link_add (platform, name, NM_LINK_TYPE_INFINIBAND, NULL, 0, out_link))
if (!link_add (platform, name, NM_LINK_TYPE_INFINIBAND, NULL, NULL, 0, out_link))
return FALSE;
device = link_get (platform, nm_platform_link_get_ifindex (platform, name));
@ -1428,15 +1445,15 @@ nm_fake_platform_setup (void)
nm_platform_setup (platform);
/* skip zero element */
link_add (platform, NULL, NM_LINK_TYPE_NONE, NULL, 0, NULL);
link_add (platform, NULL, NM_LINK_TYPE_NONE, NULL, NULL, 0, NULL);
/* add loopback interface */
link_add (platform, "lo", NM_LINK_TYPE_LOOPBACK, NULL, 0, NULL);
link_add (platform, "lo", NM_LINK_TYPE_LOOPBACK, NULL, NULL, 0, NULL);
/* add some ethernets */
link_add (platform, "eth0", NM_LINK_TYPE_ETHERNET, NULL, 0, NULL);
link_add (platform, "eth1", NM_LINK_TYPE_ETHERNET, NULL, 0, NULL);
link_add (platform, "eth2", NM_LINK_TYPE_ETHERNET, NULL, 0, NULL);
link_add (platform, "eth0", NM_LINK_TYPE_ETHERNET, NULL, NULL, 0, NULL);
link_add (platform, "eth1", NM_LINK_TYPE_ETHERNET, NULL, NULL, 0, NULL);
link_add (platform, "eth2", NM_LINK_TYPE_ETHERNET, NULL, NULL, 0, NULL);
}
static void

View file

@ -2135,12 +2135,14 @@ nla_put_failure:
static gboolean
_nl_msg_new_link_set_linkinfo (struct nl_msg *msg,
NMLinkType link_type)
NMLinkType link_type,
const char *veth_peer)
{
struct nlattr *info;
const char *kind;
nm_assert (msg);
nm_assert (!!veth_peer == (link_type == NM_LINK_TYPE_VETH));
kind = nm_link_type_to_rtnl_type_string (link_type);
if (!kind)
@ -2151,11 +2153,26 @@ _nl_msg_new_link_set_linkinfo (struct nl_msg *msg,
NLA_PUT_STRING (msg, IFLA_INFO_KIND, kind);
if (veth_peer) {
struct ifinfomsg ifi = { };
struct nlattr *data, *info_peer;
if (!(data = nla_nest_start (msg, IFLA_INFO_DATA)))
goto nla_put_failure;
if (!(info_peer = nla_nest_start (msg, 1 /*VETH_INFO_PEER*/)))
goto nla_put_failure;
if (nlmsg_append (msg, &ifi, sizeof (ifi), NLMSG_ALIGNTO) < 0)
goto nla_put_failure;
NLA_PUT_STRING (msg, IFLA_IFNAME, veth_peer);
nla_nest_end (msg, info_peer);
nla_nest_end (msg, data);
}
nla_nest_end (msg, info);
return TRUE;
nla_put_failure:
return FALSE;
g_return_val_if_reached (FALSE);
}
static gboolean
@ -4319,6 +4336,7 @@ static gboolean
link_add (NMPlatform *platform,
const char *name,
NMLinkType type,
const char *veth_peer,
const void *address,
size_t address_len,
const NMPlatformLink **out_link)
@ -4352,7 +4370,7 @@ link_add (NMPlatform *platform,
if (address && address_len)
NLA_PUT (nlmsg, IFLA_ADDRESS, address_len, address);
if (!_nl_msg_new_link_set_linkinfo (nlmsg, type))
if (!_nl_msg_new_link_set_linkinfo (nlmsg, type, veth_peer))
return FALSE;
return do_add_link_with_lookup (platform, type, name, nlmsg, out_link);

View file

@ -662,6 +662,7 @@ _link_add_check_existing (NMPlatform *self, const char *name, NMLinkType type, c
* @self: platform instance
* @name: Interface name
* @type: Interface type
* @veth_peer: For veths, the peer name
* @address: (allow-none): set the mac address of the link
* @address_len: the length of the @address
* @out_link: on success, the link object
@ -680,6 +681,7 @@ static NMPlatformError
nm_platform_link_add (NMPlatform *self,
const char *name,
NMLinkType type,
const char *veth_peer,
const void *address,
size_t address_len,
const NMPlatformLink **out_link)
@ -690,17 +692,27 @@ nm_platform_link_add (NMPlatform *self,
g_return_val_if_fail (name, NM_PLATFORM_ERROR_BUG);
g_return_val_if_fail ( (address != NULL) ^ (address_len == 0) , NM_PLATFORM_ERROR_BUG);
g_return_val_if_fail ((!!veth_peer) == (type == NM_LINK_TYPE_VETH), NM_PLATFORM_ERROR_BUG);
plerr = _link_add_check_existing (self, name, type, out_link);
if (plerr != NM_PLATFORM_ERROR_SUCCESS)
return plerr;
_LOGD ("link: adding %s '%s'", nm_link_type_to_string (type), name);
if (!klass->link_add (self, name, type, address, address_len, out_link))
if (!klass->link_add (self, name, type, veth_peer, address, address_len, out_link))
return NM_PLATFORM_ERROR_UNSPECIFIED;
return NM_PLATFORM_ERROR_SUCCESS;
}
NMPlatformError
nm_platform_link_veth_add (NMPlatform *self,
const char *name,
const char *peer,
const NMPlatformLink **out_link)
{
return nm_platform_link_add (self, name, NM_LINK_TYPE_VETH, peer, NULL, 0, out_link);
}
/**
* nm_platform_link_dummy_add:
* @self: platform instance
@ -714,7 +726,7 @@ nm_platform_link_dummy_add (NMPlatform *self,
const char *name,
const NMPlatformLink **out_link)
{
return nm_platform_link_add (self, name, NM_LINK_TYPE_DUMMY, NULL, 0, out_link);
return nm_platform_link_add (self, name, NM_LINK_TYPE_DUMMY, NULL, NULL, 0, out_link);
}
/**
@ -1616,7 +1628,7 @@ nm_platform_link_bridge_add (NMPlatform *self,
size_t address_len,
const NMPlatformLink **out_link)
{
return nm_platform_link_add (self, name, NM_LINK_TYPE_BRIDGE, address, address_len, out_link);
return nm_platform_link_add (self, name, NM_LINK_TYPE_BRIDGE, NULL, address, address_len, out_link);
}
/**
@ -1632,7 +1644,7 @@ nm_platform_link_bond_add (NMPlatform *self,
const char *name,
const NMPlatformLink **out_link)
{
return nm_platform_link_add (self, name, NM_LINK_TYPE_BOND, NULL, 0, out_link);
return nm_platform_link_add (self, name, NM_LINK_TYPE_BOND, NULL, NULL, 0, out_link);
}
/**
@ -1648,7 +1660,7 @@ nm_platform_link_team_add (NMPlatform *self,
const char *name,
const NMPlatformLink **out_link)
{
return nm_platform_link_add (self, name, NM_LINK_TYPE_TEAM, NULL, 0, out_link);
return nm_platform_link_add (self, name, NM_LINK_TYPE_TEAM, NULL, NULL, 0, out_link);
}
/**

View file

@ -527,6 +527,7 @@ typedef struct {
gboolean (*link_add) (NMPlatform *,
const char *name,
NMLinkType type,
const char *veth_peer,
const void *address,
size_t address_len,
const NMPlatformLink **out_link);
@ -768,6 +769,8 @@ NMPlatformError nm_platform_link_dummy_add (NMPlatform *self, const char *name,
NMPlatformError nm_platform_link_bridge_add (NMPlatform *self, const char *name, const void *address, size_t address_len, const NMPlatformLink **out_link);
NMPlatformError nm_platform_link_bond_add (NMPlatform *self, const char *name, const NMPlatformLink **out_link);
NMPlatformError nm_platform_link_team_add (NMPlatform *self, const char *name, const NMPlatformLink **out_link);
NMPlatformError nm_platform_link_veth_add (NMPlatform *self, const char *name, const char *peer, const NMPlatformLink **out_link);
gboolean nm_platform_link_delete (NMPlatform *self, int ifindex);
gboolean nm_platform_link_set_netns (NMPlatform *self, int ifindex, int netns_fd);