summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/netlink-private/types.h1
-rw-r--r--include/netlink/route/link.h3
-rw-r--r--lib/route/link.c86
-rw-r--r--libnl-route-3.sym2
4 files changed, 82 insertions, 10 deletions
diff --git a/include/netlink-private/types.h b/include/netlink-private/types.h
index 4824a8f6..209f0999 100644
--- a/include/netlink-private/types.h
+++ b/include/netlink-private/types.h
@@ -215,6 +215,7 @@ struct rtnl_link
uint8_t l_linkmode;
/* 2 byte hole */
char * l_info_kind;
+ char * l_info_slave_kind;
struct rtnl_link_info_ops * l_info_ops;
void * l_af_data[AF_MAX];
void * l_info;
diff --git a/include/netlink/route/link.h b/include/netlink/route/link.h
index 5f941d5f..8fd0994f 100644
--- a/include/netlink/route/link.h
+++ b/include/netlink/route/link.h
@@ -223,6 +223,9 @@ extern int rtnl_link_set_stat(struct rtnl_link *, rtnl_link_stat_id_t,
extern int rtnl_link_set_type(struct rtnl_link *, const char *);
extern char * rtnl_link_get_type(struct rtnl_link *);
+extern int rtnl_link_set_slave_type(struct rtnl_link *, const char *);
+extern const char * rtnl_link_get_slave_type(const struct rtnl_link *);
+
extern void rtnl_link_set_promiscuity(struct rtnl_link *, uint32_t);
extern uint32_t rtnl_link_get_promiscuity(struct rtnl_link *);
diff --git a/lib/route/link.c b/lib/route/link.c
index ec19bb51..7dc36da4 100644
--- a/lib/route/link.c
+++ b/lib/route/link.c
@@ -71,6 +71,7 @@
#define LINK_ATTR_PHYS_SWITCH_ID ((uint64_t) 1 << 36)
#define LINK_ATTR_GSO_MAX_SEGS ((uint64_t) 1 << 37)
#define LINK_ATTR_GSO_MAX_SIZE ((uint64_t) 1 << 38)
+#define LINK_ATTR_LINKINFO_SLAVE_KIND ((uint64_t) 1 << 39)
static struct nl_cache_ops rtnl_link_ops;
static struct nl_object_ops link_obj_ops;
@@ -276,6 +277,7 @@ static void link_free_data(struct nl_object *c)
free(link->l_ifalias);
free(link->l_info_kind);
+ free(link->l_info_slave_kind);
do_foreach_af(link, af_free, NULL);
@@ -309,6 +311,10 @@ static int link_clone(struct nl_object *_dst, struct nl_object *_src)
if (!(dst->l_info_kind = strdup(src->l_info_kind)))
return -NLE_NOMEM;
+ if (src->l_info_slave_kind)
+ if (!(dst->l_info_slave_kind = strdup(src->l_info_slave_kind)))
+ return -NLE_NOMEM;
+
if (src->l_info_ops && src->l_info_ops->io_clone) {
err = src->l_info_ops->io_clone(dst, src);
if (err < 0)
@@ -520,7 +526,7 @@ int rtnl_link_info_parse(struct rtnl_link *link, struct nlattr **tb)
}
if (tb[IFLA_MAP]) {
- nla_memcpy(&link->l_map, tb[IFLA_MAP],
+ nla_memcpy(&link->l_map, tb[IFLA_MAP],
sizeof(struct rtnl_link_ifmap));
link->ce_mask |= LINK_ATTR_MAP;
}
@@ -645,7 +651,7 @@ static int link_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
if (li[IFLA_INFO_KIND]) {
struct rtnl_link_info_ops *ops;
- char *kind = nla_get_string(li[IFLA_INFO_KIND]);
+ const char *kind = nla_get_string(li[IFLA_INFO_KIND]);
int af;
err = rtnl_link_set_type(link, kind);
@@ -676,8 +682,19 @@ static int link_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
/* XXX: Warn about unparsed info? */
}
}
+
+ link->ce_mask |= LINK_ATTR_LINKINFO;
+ }
+
+ if (li[IFLA_INFO_SLAVE_KIND]) {
+ const char *kind = nla_get_string(li[IFLA_INFO_SLAVE_KIND]);
+
+ err = rtnl_link_set_slave_type(link, kind);
+ if (err < 0)
+ goto errout;
+
+ link->ce_mask |= LINK_ATTR_LINKINFO_SLAVE_KIND;
}
- link->ce_mask |= LINK_ATTR_LINKINFO;
}
if (tb[IFLA_PROTINFO] && af_ops && af_ops->ao_parse_protinfo) {
@@ -1580,18 +1597,24 @@ static int build_link_msg(int cmd, struct ifinfomsg *hdr,
if (link->ce_mask & LINK_ATTR_GROUP)
NLA_PUT_U32(msg, IFLA_GROUP, link->l_group);
- if (link->ce_mask & LINK_ATTR_LINKINFO) {
+ if (link->ce_mask & (LINK_ATTR_LINKINFO|LINK_ATTR_LINKINFO_SLAVE_KIND)) {
struct nlattr *info;
if (!(info = nla_nest_start(msg, IFLA_LINKINFO)))
goto nla_put_failure;
- NLA_PUT_STRING(msg, IFLA_INFO_KIND, link->l_info_kind);
+ if (link->ce_mask & LINK_ATTR_LINKINFO) {
+ NLA_PUT_STRING(msg, IFLA_INFO_KIND, link->l_info_kind);
+
+ if (link->l_info_ops) {
+ if (link->l_info_ops->io_put_attrs &&
+ link->l_info_ops->io_put_attrs(msg, link) < 0)
+ goto nla_put_failure;
+ }
+ }
- if (link->l_info_ops) {
- if (link->l_info_ops->io_put_attrs &&
- link->l_info_ops->io_put_attrs(msg, link) < 0)
- goto nla_put_failure;
+ if (link->ce_mask & LINK_ATTR_LINKINFO_SLAVE_KIND) {
+ NLA_PUT_STRING(msg, IFLA_INFO_SLAVE_KIND, link->l_info_slave_kind);
}
nla_nest_end(msg, info);
@@ -2539,7 +2562,7 @@ int rtnl_link_set_stat(struct rtnl_link *link, rtnl_link_stat_id_t id,
* be released with all link type specific attributes lost.
*
* @route_doc{link_modules, Link Modules}
- * @return 0 on success or a negative errror code.
+ * @return 0 on success or a negative error code.
*/
int rtnl_link_set_type(struct rtnl_link *link, const char *type)
{
@@ -2589,6 +2612,49 @@ char *rtnl_link_get_type(struct rtnl_link *link)
}
/**
+ * Set type of slave link object
+ * @arg link Link object (slave)
+ * @arg type Name of link type
+ *
+ * If a slave type has been assigned already it will be released.
+ *
+ * @route_doc{link_modules, Link Modules}
+ * @return 0 on success or a negative error code.
+ */
+int rtnl_link_set_slave_type(struct rtnl_link *link, const char *type)
+{
+ char *kind;
+
+ free(link->l_info_slave_kind);
+ link->ce_mask &= ~LINK_ATTR_LINKINFO_SLAVE_KIND;
+
+ if (!type)
+ return 0;
+
+ kind = strdup(type);
+ if (!kind)
+ return -NLE_NOMEM;
+
+ link->l_info_slave_kind = kind;
+ link->ce_mask |= LINK_ATTR_LINKINFO_SLAVE_KIND;
+
+ return 0;
+}
+
+/**
+ * Return type of enslaved link
+ * @arg link Link object
+ *
+ * @route_doc{link_modules, Link Modules}
+ * @return Name of enslaved link type or NULL if not specified.
+ */
+const char *rtnl_link_get_slave_type(const struct rtnl_link *link)
+{
+ return link->l_info_slave_kind;
+}
+
+
+/**
* Set link promiscuity count
* @arg link Link object
* @arg count New promiscuity count
diff --git a/libnl-route-3.sym b/libnl-route-3.sym
index 02aae7a6..5a82d857 100644
--- a/libnl-route-3.sym
+++ b/libnl-route-3.sym
@@ -1087,7 +1087,9 @@ global:
rtnl_link_geneve_set_udp_csum;
rtnl_link_geneve_set_udp_zero_csum6_rx;
rtnl_link_geneve_set_udp_zero_csum6_tx;
+ rtnl_link_get_slave_type;
rtnl_link_is_geneve;
+ rtnl_link_set_slave_type;
rtnl_mall_append_action;
rtnl_mall_del_action;
rtnl_mall_get_classid;