diff options
author | Beniamino Galvani <bgalvani@redhat.com> | 2015-12-04 09:49:39 +0100 |
---|---|---|
committer | Beniamino Galvani <bgalvani@redhat.com> | 2015-12-09 14:30:08 +0100 |
commit | 387105601980a69b02cfdbfcea63edfd2f801d73 (patch) | |
tree | 3025c3675ac14569514cf9499bedc72049688d46 | |
parent | 62c1f2c6a8d426dae365258ed728defec89ec3d0 (diff) | |
download | NetworkManager-387105601980a69b02cfdbfcea63edfd2f801d73.tar.gz |
platform: add macvtap link creation support
-rw-r--r-- | src/nm-types.h | 1 | ||||
-rw-r--r-- | src/platform/nm-linux-platform.c | 24 | ||||
-rw-r--r-- | src/platform/nm-platform.c | 16 | ||||
-rw-r--r-- | src/platform/nm-platform.h | 4 | ||||
-rw-r--r-- | src/platform/nmp-object.c | 9 | ||||
-rw-r--r-- | src/platform/nmp-object.h | 2 | ||||
-rw-r--r-- | src/platform/tests/test-common.c | 5 | ||||
-rw-r--r-- | src/platform/tests/test-link.c | 21 |
8 files changed, 72 insertions, 10 deletions
diff --git a/src/nm-types.h b/src/nm-types.h index 65d6193be2..7934fcbbed 100644 --- a/src/nm-types.h +++ b/src/nm-types.h @@ -143,6 +143,7 @@ typedef enum { NMP_OBJECT_TYPE_LNK_IP6TNL, NMP_OBJECT_TYPE_LNK_IPIP, NMP_OBJECT_TYPE_LNK_MACVLAN, + NMP_OBJECT_TYPE_LNK_MACVTAP, NMP_OBJECT_TYPE_LNK_SIT, NMP_OBJECT_TYPE_LNK_VLAN, NMP_OBJECT_TYPE_LNK_VXLAN, diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index cafed814a6..d7417b76d6 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -1026,8 +1026,16 @@ _parse_lnk_macvlan (const char *kind, struct nlattr *info_data) struct nlattr *tb[IFLA_MACVLAN_MAX + 1]; int err; 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; 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]) 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->mode = nla_get_u32 (tb[IFLA_MACVLAN_MODE]); + props->tap = tap; if (tb[IFLA_MACVLAN_FLAGS]) 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); break; case NM_LINK_TYPE_MACVLAN: + case NM_LINK_TYPE_MACVTAP: lnk_data = _parse_lnk_macvlan (nl_info_kind, nl_info_data); break; 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_INFINIBAND: case NM_LINK_TYPE_MACVLAN: + case NM_LINK_TYPE_MACVTAP: case NM_LINK_TYPE_SIT: case NM_LINK_TYPE_VLAN: case NM_LINK_TYPE_VXLAN: @@ -4366,7 +4377,8 @@ link_macvlan_add (NMPlatform *platform, struct nlattr *info; struct nlattr *data; - _LOGD ("adding macvlan '%s' parent %u mode %u", + _LOGD ("adding %s '%s' parent %u mode %u", + props->tap ? "macvtap" : "macvlan", name, parent, props->mode); @@ -4385,7 +4397,7 @@ link_macvlan_add (NMPlatform *platform, if (!(info = nla_nest_start (nlmsg, IFLA_LINKINFO))) 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))) goto nla_put_failure; @@ -4396,7 +4408,9 @@ link_macvlan_add (NMPlatform *platform, nla_nest_end (nlmsg, data); 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: g_return_val_if_reached (FALSE); } diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index e48bc9c24f..f4e24d78e1 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -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); } +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 * 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 * @out_link: on success, the link object * - * Create a MACVLAN device. + * Create a MACVLAN or MACVTAP device. */ NMPlatformError nm_platform_link_macvlan_add (NMPlatform *self, @@ -1960,17 +1966,21 @@ nm_platform_link_macvlan_add (NMPlatform *self, NMPlatformLink *out_link) { NMPlatformError plerr; + NMLinkType type; _CHECK_SELF (self, klass, NM_PLATFORM_ERROR_BUG); g_return_val_if_fail (props, 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) return plerr; - _LOGD ("adding macvlan '%s' parent %u mode %u", + _LOGD ("adding %s '%s' parent %u mode %u", + props->tap ? "macvtap" : "macvlan", name, parent, props->mode); diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h index 4e3a497744..de20e842a3 100644 --- a/src/platform/nm-platform.h +++ b/src/platform/nm-platform.h @@ -402,8 +402,11 @@ typedef struct { typedef struct { guint mode; gboolean no_promisc; + gboolean tap; } NMPlatformLnkMacvlan; +typedef NMPlatformLnkMacvlan NMPlatformLnkMacvtap; + typedef struct { int parent_ifindex; 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 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 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 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); diff --git a/src/platform/nmp-object.c b/src/platform/nmp-object.c index cb605c28f4..2b1ec2127f 100644 --- a/src/platform/nmp-object.c +++ b/src/platform/nmp-object.c @@ -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_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] = { .obj_type = NMP_OBJECT_TYPE_LNK_SIT, .sizeof_data = sizeof (NMPObjectLnkSit), diff --git a/src/platform/nmp-object.h b/src/platform/nmp-object.h index 38224acd30..5acde46075 100644 --- a/src/platform/nmp-object.h +++ b/src/platform/nmp-object.h @@ -181,6 +181,8 @@ typedef struct { NMPlatformLnkMacvlan _public; } NMPObjectLnkMacvlan; +typedef NMPObjectLnkMacvlan NMPObjectLnkMacvtap; + typedef struct { NMPlatformLnkSit _public; } NMPObjectLnkSit; diff --git a/src/platform/tests/test-common.c b/src/platform/tests/test-common.c index c7d0c40f75..f593c9cb80 100644 --- a/src/platform/tests/test-common.c +++ b/src/platform/tests/test-common.c @@ -794,13 +794,14 @@ nmtstp_link_macvlan_add (gboolean external_command, const char *name, int parent g_assert (dev); 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, dev, + lnk->tap ? "macvtap" : "macvlan", modes[lnk->mode], lnk->no_promisc ? "nopromisc" : ""); 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 success = nm_platform_link_macvlan_add (NM_PLATFORM_GET, name, parent, lnk, NULL) == NM_PLATFORM_ERROR_SUCCESS; diff --git a/src/platform/tests/test-link.c b/src/platform/tests/test-link.c index 0986adf0d6..47e1af48b2 100644 --- a/src/platform/tests/test-link.c +++ b/src/platform/tests/test-link.c @@ -745,11 +745,23 @@ test_software_detect (gconstpointer user_data) lnk_macvlan.mode = MACVLAN_MODE_BRIDGE; lnk_macvlan.no_promisc = FALSE; + lnk_macvlan.tap = FALSE; if (!nmtstp_link_macvlan_add (EX, DEVICE_NAME, ifindex_parent, &lnk_macvlan)) g_error ("Failed adding MACVLAN interface"); 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: { NMPlatformLnkSit lnk_sit = { }; gboolean gracefully_skip = FALSE; @@ -877,6 +889,14 @@ test_software_detect (gconstpointer user_data) g_assert_cmpint (plnk->mode, ==, MACVLAN_MODE_BRIDGE); 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: { 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/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/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/vlan", NM_LINK_TYPE_VLAN, 0); test_software_detect_add ("/link/software/detect/vxlan/0", NM_LINK_TYPE_VXLAN, 0); |