diff options
author | Beniamino Galvani <bgalvani@redhat.com> | 2015-11-11 18:41:48 +0100 |
---|---|---|
committer | Beniamino Galvani <bgalvani@redhat.com> | 2015-11-12 17:31:08 +0100 |
commit | f81209812fe522595349d12ad495bfa881f93156 (patch) | |
tree | a2927b22a84bf659d8adcc15bb0c0cdbb0ffda36 | |
parent | 2ebee315e3982a5cc6fce43363801493a157d570 (diff) | |
download | NetworkManager-f81209812fe522595349d12ad495bfa881f93156.tar.gz |
platform: add basic SIT support
-rw-r--r-- | src/nm-types.h | 2 | ||||
-rw-r--r-- | src/platform/nm-linux-platform.c | 107 | ||||
-rw-r--r-- | src/platform/nm-platform.c | 97 | ||||
-rw-r--r-- | src/platform/nm-platform.h | 18 | ||||
-rw-r--r-- | src/platform/nmp-object.c | 9 | ||||
-rw-r--r-- | src/platform/nmp-object.h | 7 |
6 files changed, 240 insertions, 0 deletions
diff --git a/src/nm-types.h b/src/nm-types.h index 6dbd3b3b45..63efd6438b 100644 --- a/src/nm-types.h +++ b/src/nm-types.h @@ -108,6 +108,7 @@ typedef enum { NM_LINK_TYPE_GRE, NM_LINK_TYPE_GRETAP, NM_LINK_TYPE_IFB, + NM_LINK_TYPE_SIT, NM_LINK_TYPE_LOOPBACK, NM_LINK_TYPE_MACVLAN, NM_LINK_TYPE_MACVTAP, @@ -134,6 +135,7 @@ typedef enum { NMP_OBJECT_TYPE_IP6_ROUTE, NMP_OBJECT_TYPE_LNK_GRE, + NMP_OBJECT_TYPE_LNK_SIT, NMP_OBJECT_TYPE_LNK_INFINIBAND, NMP_OBJECT_TYPE_LNK_MACVLAN, NMP_OBJECT_TYPE_LNK_VLAN, diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index f03ab575b2..7452800a80 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -85,6 +85,19 @@ #define IFLA_MACVLAN_FLAGS 2 #define __IFLA_MACVLAN_MAX 3 +#define IFLA_IPTUN_LINK 1 +#define IFLA_IPTUN_LOCAL 2 +#define IFLA_IPTUN_REMOTE 3 +#define IFLA_IPTUN_TTL 4 +#define IFLA_IPTUN_TOS 5 +#define IFLA_IPTUN_FLAGS 8 +#define IFLA_IPTUN_PROTO 9 +#define IFLA_IPTUN_PMTUDISC 10 +#define __IFLA_IPTUN_MAX 19 +#ifndef IFLA_IPTUN_MAX +#define IFLA_IPTUN_MAX (__IFLA_IPTUN_MAX - 1) +#endif + #ifndef MACVLAN_FLAG_NOPROMISC #define MACVLAN_FLAG_NOPROMISC 1 #endif @@ -313,6 +326,7 @@ static const LinkDesc linktypes[] = { { NM_LINK_TYPE_DUMMY, "dummy", "dummy", NULL }, { NM_LINK_TYPE_GRE, "gre", "gre", NULL }, { NM_LINK_TYPE_GRETAP, "gretap", "gretap", NULL }, + { NM_LINK_TYPE_SIT, "sit", "sit", NULL }, { NM_LINK_TYPE_IFB, "ifb", "ifb", NULL }, { NM_LINK_TYPE_LOOPBACK, "loopback", NULL, NULL }, { NM_LINK_TYPE_MACVLAN, "macvlan", "macvlan", NULL }, @@ -836,6 +850,48 @@ _parse_lnk_gre (const char *kind, struct nlattr *info_data) /*****************************************************************************/ +static NMPObject * +_parse_lnk_sit (const char *kind, struct nlattr *info_data) +{ + static struct nla_policy policy[IFLA_IPTUN_MAX + 1] = { + [IFLA_IPTUN_LINK] = { .type = NLA_U32 }, + [IFLA_IPTUN_LOCAL] = { .type = NLA_U32 }, + [IFLA_IPTUN_REMOTE] = { .type = NLA_U32 }, + [IFLA_IPTUN_TTL] = { .type = NLA_U8 }, + [IFLA_IPTUN_TOS] = { .type = NLA_U8 }, + [IFLA_IPTUN_PMTUDISC] = { .type = NLA_U8 }, + [IFLA_IPTUN_FLAGS] = { .type = NLA_U16 }, + [IFLA_IPTUN_PROTO] = { .type = NLA_U8 }, + }; + struct nlattr *tb[IFLA_IPTUN_MAX + 1]; + int err; + NMPObject *obj; + NMPlatformLnkSit *props; + + if (!info_data || g_strcmp0 (kind, "sit")) + return NULL; + + err = nla_parse_nested (tb, IFLA_IPTUN_MAX, info_data, policy); + if (err < 0) + return NULL; + + obj = nmp_object_new (NMP_OBJECT_TYPE_LNK_SIT, NULL); + props = &obj->lnk_sit; + + props->parent_ifindex = tb[IFLA_IPTUN_LINK] ? nla_get_u32 (tb[IFLA_IPTUN_LINK]) : 0; + props->local = tb[IFLA_IPTUN_LOCAL] ? nla_get_u32 (tb[IFLA_IPTUN_LOCAL]) : 0; + props->remote = tb[IFLA_IPTUN_REMOTE] ? nla_get_u32 (tb[IFLA_IPTUN_REMOTE]) : 0; + props->tos = tb[IFLA_IPTUN_TOS] ? nla_get_u8 (tb[IFLA_IPTUN_TOS]) : 0; + props->ttl = tb[IFLA_IPTUN_TTL] ? nla_get_u8 (tb[IFLA_IPTUN_TTL]) : 0; + props->path_mtu_discovery = !tb[IFLA_IPTUN_PMTUDISC] || !!nla_get_u8 (tb[IFLA_IPTUN_PMTUDISC]); + props->flags = tb[IFLA_IPTUN_FLAGS] ? nla_get_u16 (tb[IFLA_IPTUN_FLAGS]) : 0; + props->proto = tb[IFLA_IPTUN_PROTO] ? nla_get_u8 (tb[IFLA_IPTUN_PROTO]) : 0; + + return obj; +} + +/*****************************************************************************/ + /* IFLA_IPOIB_* were introduced in the 3.7 kernel, but the kernel headers * we're building against might not have those properties even though the * running kernel might. @@ -1322,6 +1378,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_SIT: + lnk_data = _parse_lnk_sit (nl_info_kind, nl_info_data); + break; case NM_LINK_TYPE_INFINIBAND: lnk_data = _parse_lnk_infiniband (nl_info_kind, nl_info_data); break; @@ -4116,6 +4175,53 @@ nla_put_failure: g_return_val_if_reached (FALSE); } +static int +sit_add (NMPlatform *platform, + const char *name, + NMPlatformLnkSit *lnk_gre, + NMPlatformLink *out_link) +{ + nm_auto_nlmsg struct nl_msg *nlmsg = NULL; + struct nlattr *info; + struct nlattr *data; + char buffer[INET_ADDRSTRLEN]; + + _LOGD ("link: add sit '%s', local %s, remote %s", + name, + nm_utils_inet4_ntop (lnk_gre->local, NULL), + nm_utils_inet4_ntop (lnk_gre->remote, buffer)); + + nlmsg = _nl_msg_new_link (RTM_NEWLINK, + NLM_F_CREATE, + 0, + name, + 0, + 0); + if (!nlmsg) + return FALSE; + + if (!(info = nla_nest_start (nlmsg, IFLA_LINKINFO))) + goto nla_put_failure; + + NLA_PUT_STRING (nlmsg, IFLA_INFO_KIND, "sit"); + + if (!(data = nla_nest_start (nlmsg, IFLA_INFO_DATA))) + goto nla_put_failure; + + NLA_PUT_U32 (nlmsg, IFLA_IPTUN_LOCAL, lnk_gre->local); + NLA_PUT_U32 (nlmsg, IFLA_IPTUN_REMOTE, lnk_gre->remote); + NLA_PUT_U8 (nlmsg, IFLA_IPTUN_TTL, lnk_gre->ttl); + NLA_PUT_U8 (nlmsg, IFLA_IPTUN_TOS, lnk_gre->tos); + NLA_PUT_U8 (nlmsg, IFLA_IPTUN_PMTUDISC, !!lnk_gre->path_mtu_discovery); + + nla_nest_end (nlmsg, data); + nla_nest_end (nlmsg, info); + + return do_add_link_with_lookup (platform, NM_LINK_TYPE_SIT, name, nlmsg, out_link); +nla_put_failure: + g_return_val_if_reached (FALSE); +} + static void _vlan_change_vlan_qos_mapping_create (gboolean is_ingress_map, gboolean reset_all, @@ -5513,6 +5619,7 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass) platform_class->mesh_set_ssid = mesh_set_ssid; platform_class->gre_add = gre_add; + platform_class->sit_add = sit_add; platform_class->ip4_address_get = ip4_address_get; platform_class->ip6_address_get = ip6_address_get; diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index ceef133373..e12d33f42f 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -1419,6 +1419,12 @@ nm_platform_link_get_lnk_gre (NMPlatform *self, int ifindex, const NMPlatformLin return _link_get_lnk (self, ifindex, NM_LINK_TYPE_GRE, out_link); } +const NMPlatformLnkSit * +nm_platform_link_get_lnk_sit (NMPlatform *self, int ifindex, const NMPlatformLink **out_link) +{ + return _link_get_lnk (self, ifindex, NM_LINK_TYPE_SIT, out_link); +} + const NMPlatformLnkInfiniband * nm_platform_link_get_lnk_infiniband (NMPlatform *self, int ifindex, const NMPlatformLink **out_link) { @@ -1707,6 +1713,44 @@ nm_platform_gre_add (NMPlatform *self, return NM_PLATFORM_ERROR_SUCCESS; } +/** + * nm_platform_sit_add: + * @self: platform instance + * @name: name of the new interface + * @lnk_sit: interface properties + * @out_link: on success, the link object + * + * Create a software SIT device. + */ +NMPlatformError +nm_platform_sit_add (NMPlatform *self, + const char *name, + NMPlatformLnkSit *lnk_sit, + NMPlatformLink *out_link) +{ + NMPlatformError plerr; + char buffer[INET_ADDRSTRLEN]; + + _CHECK_SELF (self, klass, NM_PLATFORM_ERROR_BUG); + + g_return_val_if_fail (lnk_sit, NM_PLATFORM_ERROR_BUG); + g_return_val_if_fail (name, NM_PLATFORM_ERROR_BUG); + g_return_val_if_fail (klass->sit_add, NM_PLATFORM_ERROR_BUG); + + plerr = _link_add_check_existing (self, name, NM_LINK_TYPE_SIT, out_link); + if (plerr != NM_PLATFORM_ERROR_SUCCESS) + return plerr; + + _LOGD ("link: adding sit '%s' local %s remote %s", + name, + nm_utils_inet4_ntop (lnk_sit->local, NULL), + nm_utils_inet4_ntop (lnk_sit->remote, buffer)); + + if (!klass->sit_add (self, name, lnk_sit, out_link)) + return NM_PLATFORM_ERROR_UNSPECIFIED; + return NM_PLATFORM_ERROR_SUCCESS; +} + NMPlatformError nm_platform_infiniband_partition_add (NMPlatform *self, int parent, int p_key, NMPlatformLink *out_link) { @@ -2788,6 +2832,44 @@ nm_platform_lnk_gre_to_string (const NMPlatformLnkGre *lnk, char *buf, gsize len } const char * +nm_platform_lnk_sit_to_string (const NMPlatformLnkSit *lnk, char *buf, gsize len) +{ + char str_local[30]; + char str_local1[NM_UTILS_INET_ADDRSTRLEN]; + char str_remote[30]; + char str_remote1[NM_UTILS_INET_ADDRSTRLEN]; + char str_ttl[30]; + char str_tos[30]; + char str_flags[30]; + char str_proto[30]; + char str_parent_ifindex[30]; + + if (!nm_utils_to_string_buffer_init_null (lnk, &buf, &len)) + return buf; + + g_snprintf (buf, len, + "sit" + "%s" /* remote */ + "%s" /* local */ + "%s" /* parent_ifindex */ + "%s" /* ttl */ + "%s" /* tos */ + "%s" /* path_mtu_discovery */ + "%s" /* flags */ + "%s" /* proto */ + "", + lnk->remote ? nm_sprintf_buf (str_remote, " remote %s", nm_utils_inet4_ntop (lnk->remote, str_remote1)) : "", + lnk->local ? nm_sprintf_buf (str_local, " local %s", nm_utils_inet4_ntop (lnk->local, str_local1)) : "", + lnk->parent_ifindex ? nm_sprintf_buf (str_parent_ifindex, " dev %d", lnk->parent_ifindex) : "", + lnk->ttl ? nm_sprintf_buf (str_ttl, " ttl %u", lnk->ttl) : " ttl inherit", + lnk->tos ? (lnk->tos == 1 ? " tos inherit" : nm_sprintf_buf (str_tos, " tos 0x%x", lnk->tos)) : "", + lnk->path_mtu_discovery ? "" : " nopmtudisc", + lnk->flags ? nm_sprintf_buf (str_flags, " flags 0x%x", lnk->flags) : "", + lnk->proto ? nm_sprintf_buf (str_proto, " proto 0x%x", lnk->proto) : ""); + return buf; +} + +const char * nm_platform_lnk_infiniband_to_string (const NMPlatformLnkInfiniband *lnk, char *buf, gsize len) { char str_p_key[64]; @@ -3353,6 +3435,21 @@ nm_platform_lnk_gre_cmp (const NMPlatformLnkGre *a, const NMPlatformLnkGre *b) } int +nm_platform_lnk_sit_cmp (const NMPlatformLnkSit *a, const NMPlatformLnkSit *b) +{ + _CMP_SELF (a, b); + _CMP_FIELD (a, b, parent_ifindex); + _CMP_FIELD (a, b, local); + _CMP_FIELD (a, b, remote); + _CMP_FIELD (a, b, ttl); + _CMP_FIELD (a, b, tos); + _CMP_FIELD_BOOL (a, b, path_mtu_discovery); + _CMP_FIELD (a, b, flags); + _CMP_FIELD (a, b, proto); + return 0; +} + +int nm_platform_lnk_infiniband_cmp (const NMPlatformLnkInfiniband *a, const NMPlatformLnkInfiniband *b) { _CMP_SELF (a, b); diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h index 77fc10b328..8ab6435578 100644 --- a/src/platform/nm-platform.h +++ b/src/platform/nm-platform.h @@ -370,6 +370,17 @@ typedef struct { } NMPlatformLnkGre; typedef struct { + int parent_ifindex; + in_addr_t local; + in_addr_t remote; + guint8 ttl; + guint8 tos; + gboolean path_mtu_discovery; + guint16 flags; + guint8 proto; +} NMPlatformLnkSit; + +typedef struct { int p_key; const char *mode; } NMPlatformLnkInfiniband; @@ -525,6 +536,8 @@ typedef struct { gboolean (*gre_add) (NMPlatform *, const char *name, NMPlatformLnkGre *lnk_gre, NMPlatformLink *out_link); + gboolean (*sit_add) (NMPlatform *, const char *name, NMPlatformLnkSit *lnk_sit, + NMPlatformLink *out_link); gboolean (*infiniband_partition_add) (NMPlatform *, int parent, int p_key, NMPlatformLink *out_link); @@ -711,6 +724,7 @@ char *nm_platform_slave_get_option (NMPlatform *self, int ifindex, const char *o const NMPObject *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 NMPlatformLnkSit *nm_platform_link_get_lnk_sit (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 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); @@ -761,6 +775,8 @@ const NMPlatformIP4Address *nm_platform_ip4_address_get (NMPlatform *self, int i NMPlatformError nm_platform_gre_add (NMPlatform *self, const char *name, NMPlatformLnkGre *lnk_gre, NMPlatformLink *out_link); +NMPlatformError nm_platform_sit_add (NMPlatform *self, const char *name, NMPlatformLnkSit *lnk_sit, + NMPlatformLink *out_link); const NMPlatformIP6Address *nm_platform_ip6_address_get (NMPlatform *self, int ifindex, struct in6_addr address, int plen); GArray *nm_platform_ip4_address_get_all (NMPlatform *self, int ifindex); @@ -802,6 +818,7 @@ gboolean nm_platform_ip6_route_delete (NMPlatform *self, int ifindex, struct in6 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_sit_to_string (const NMPlatformLnkSit *lnk, char *buf, gsize len); const char *nm_platform_lnk_infiniband_to_string (const NMPlatformLnkInfiniband *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); @@ -819,6 +836,7 @@ const char *nm_platform_vlan_qos_mapping_to_string (const char *name, 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_sit_cmp (const NMPlatformLnkSit *a, const NMPlatformLnkSit *b); int nm_platform_lnk_infiniband_cmp (const NMPlatformLnkInfiniband *a, const NMPlatformLnkInfiniband *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); diff --git a/src/platform/nmp-object.c b/src/platform/nmp-object.c index 2264c9cd62..768eab1797 100644 --- a/src/platform/nmp-object.c +++ b/src/platform/nmp-object.c @@ -2031,6 +2031,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_gre_to_string, .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_gre_cmp, }, + [NMP_OBJECT_TYPE_LNK_SIT - 1] = { + .obj_type = NMP_OBJECT_TYPE_LNK_SIT, + .sizeof_data = sizeof (NMPObjectLnkSit), + .sizeof_public = sizeof (NMPlatformLnkSit), + .obj_type_name = "sit", + .lnk_link_type = NM_LINK_TYPE_SIT, + .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_sit_to_string, + .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_sit_cmp, + }, [NMP_OBJECT_TYPE_LNK_INFINIBAND - 1] = { .obj_type = NMP_OBJECT_TYPE_LNK_INFINIBAND, .sizeof_data = sizeof (NMPObjectLnkInfiniband), diff --git a/src/platform/nmp-object.h b/src/platform/nmp-object.h index e49d358675..ca28887084 100644 --- a/src/platform/nmp-object.h +++ b/src/platform/nmp-object.h @@ -165,6 +165,10 @@ typedef struct { } NMPObjectLnkGre; typedef struct { + NMPlatformLnkSit _public; +} NMPObjectLnkSit; + +typedef struct { NMPlatformLnkInfiniband _public; } NMPObjectLnkInfiniband; @@ -214,6 +218,9 @@ struct _NMPObject { NMPlatformLnkGre lnk_gre; NMPObjectLnkGre _lnk_gre; + NMPlatformLnkSit lnk_sit; + NMPObjectLnkSit _lnk_sit; + NMPlatformLnkInfiniband lnk_infiniband; NMPObjectLnkInfiniband _lnk_infiniband; |