[lldp-devel] [PATCH] rtnl netlink message construction support

Thomas Richter tmricht at linux.vnet.ibm.com
Tue Nov 12 12:48:38 UTC 2013


Add some more helper functions to construct and parse
a netlink message. The new functions follow the scheme
introduced with commit 2710e03e21f4aaa712cd664f35dda79c81599119.

Signed-off-by: Thomas Richter <tmricht at linux.vnet.ibm.com>
---
 include/lldp_rtnl.h | 14 ++++++++
 lldp_rtnl.c         | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 107 insertions(+)

diff --git a/include/lldp_rtnl.h b/include/lldp_rtnl.h
index 6b88db6..2bb09b1 100644
--- a/include/lldp_rtnl.h
+++ b/include/lldp_rtnl.h
@@ -39,8 +39,22 @@
 void mynla_nest_end(struct nlmsghdr *, struct nlattr *);
 struct nlattr *mynla_nest_start(struct nlmsghdr *, int);
 void mynla_put(struct nlmsghdr *, int, size_t, void *);
+void mynla_put_u8(struct nlmsghdr *, int, __u8);
 void mynla_put_u16(struct nlmsghdr *, int, __u16);
 void mynla_put_u32(struct nlmsghdr *, int, __u32);
+void mynla_put_s32(struct nlmsghdr *nlh, int type, __s32);
+__u8 mynla_get_u8(const struct nlattr *);
+__u16 mynla_get_u16(const struct nlattr *);
+__u32 mynla_get_u32(const struct nlattr *);
+__s32 mynla_get_s32(const struct nlattr *);
+void mynla_get(const struct nlattr *, size_t, void *);
+void *mynla_data(const struct nlattr *);
+int mynla_payload(const struct nlattr *);
+int mynla_type(const struct nlattr *);
+int mynla_ok(const struct nlattr *, int);
+int mynla_total_size(int);
+struct nlattr *mynla_next(const struct nlattr *, int *);
+int mynla_parse(struct nlattr **, size_t, struct nlattr *, int);
 
 int get_operstate(char *ifname);
 int set_operstate(char *ifname, __u8 operstate);
diff --git a/lldp_rtnl.c b/lldp_rtnl.c
index d4049e2..dffc0ba 100644
--- a/lldp_rtnl.c
+++ b/lldp_rtnl.c
@@ -75,6 +75,11 @@ void mynla_put(struct nlmsghdr *nlh, int type, size_t len, void *data)
 	nlh->nlmsg_len += NLA_HDRLEN + NLA_ALIGN(len);
 }
 
+void mynla_put_u8(struct nlmsghdr *nlh, int type, __u8 data)
+{
+	mynla_put(nlh, type, sizeof data, &data);
+}
+
 void mynla_put_u16(struct nlmsghdr *nlh, int type, __u16 data)
 {
 	mynla_put(nlh, type, sizeof data, &data);
@@ -85,6 +90,94 @@ void mynla_put_u32(struct nlmsghdr *nlh, int type, __u32 data)
 	mynla_put(nlh, type, sizeof data, &data);
 }
 
+void mynla_put_s32(struct nlmsghdr *nlh, int type, __s32 data)
+{
+	mynla_put(nlh, type, sizeof data, &data);
+}
+
+void mynla_get(const struct nlattr *nla, size_t len, void *data)
+{
+	memcpy(data, mynla_data(nla), len);
+}
+
+__s32 mynla_get_s32(const struct nlattr *nla)
+{
+	return *(__u32 *)mynla_data(nla);
+}
+
+__u32 mynla_get_u32(const struct nlattr *nla)
+{
+	return *(__u32 *)mynla_data(nla);
+}
+
+__u16 mynla_get_u16(const struct nlattr *nla)
+{
+	return *(__u16 *)mynla_data(nla);
+}
+
+__u8 mynla_get_u8(const struct nlattr *nla)
+{
+	return *(__u8 *)mynla_data(nla);
+}
+
+void *mynla_data(const struct nlattr *nla)
+{
+	return (char *)nla + NLA_HDRLEN;
+}
+
+int mynla_payload(const struct nlattr *nla)
+{
+	return nla->nla_len - NLA_HDRLEN;
+}
+
+int mynla_type(const struct nlattr *nla)
+{
+	return nla->nla_type & ~NLA_F_NESTED;
+}
+
+int mynla_ok(const struct nlattr *nla, int rest)
+{
+	return rest >= (int) sizeof(*nla) &&
+	       nla->nla_len >= sizeof(*nla) && nla->nla_len <= rest;
+}
+
+struct nlattr *mynla_next(const struct nlattr *nla, int *rest)
+{
+	int len = NLA_ALIGN(nla->nla_len);
+
+	*rest -= len;
+	return (struct nlattr *)((char *)nla + len);
+}
+
+static inline int mynla_attr_size(int payload)
+{
+	return NLA_HDRLEN + payload;
+}
+
+int mynla_total_size(int payload)
+{
+	return NLA_ALIGN(mynla_attr_size(payload));
+}
+
+/*
+ * Parse a list of netlink attributes.
+ * Return 0 on success and errno when the parsing fails.
+ */
+int mynla_parse(struct nlattr **tb, size_t tb_len, struct nlattr *pos,
+		int attrlen)
+{
+	unsigned short nla_type;
+
+	while (mynla_ok(pos, attrlen)) {
+		nla_type = mynla_type(pos);
+		if (nla_type < tb_len)
+			tb[nla_type] = (struct nlattr *)pos;
+		pos = mynla_next(pos, &attrlen);
+	}
+	return (attrlen) ? -EINVAL : 0;
+}
+
+
 typedef int rtnl_handler(struct nlmsghdr *nh, void *arg);
 
 /**
-- 
1.8.3.1



More information about the lldp-devel mailing list