kernel-netlink: Add helper functions for nested attributes
authorTobias Brunner <tobias@strongswan.org>
Fri, 8 Mar 2019 14:20:40 +0000 (15:20 +0100)
committerTobias Brunner <tobias@strongswan.org>
Thu, 4 Apr 2019 07:31:38 +0000 (09:31 +0200)
src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.c
src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.h

index 4014d3c..f1a9f7a 100644 (file)
@@ -1,7 +1,8 @@
 /*
  * Copyright (C) 2014 Martin Willi
  * Copyright (C) 2014 revosec AG
- * Copyright (C) 2008 Tobias Brunner
+ *
+ * Copyright (C) 2008-2019 Tobias Brunner
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -687,8 +688,8 @@ netlink_socket_t *netlink_socket_create(int protocol, enum_name_t *names,
        return &this->public;
 }
 
-/**
- * Described in header.
+/*
+ * Described in header
  */
 void netlink_add_attribute(struct nlmsghdr *hdr, int rta_type, chunk_t data,
                                                  size_t buflen)
@@ -709,9 +710,10 @@ void netlink_add_attribute(struct nlmsghdr *hdr, int rta_type, chunk_t data,
 }
 
 /**
- * Described in header.
+ * Add an attribute to the given Netlink message
  */
-void* netlink_reserve(struct nlmsghdr *hdr, int buflen, int type, int len)
+static struct rtattr *add_rtattr(struct nlmsghdr *hdr, int buflen, int type,
+                                                                int len)
 {
        struct rtattr *rta;
 
@@ -725,6 +727,43 @@ void* netlink_reserve(struct nlmsghdr *hdr, int buflen, int type, int len)
        rta->rta_type = type;
        rta->rta_len = RTA_LENGTH(len);
        hdr->nlmsg_len = NLMSG_ALIGN(hdr->nlmsg_len) + RTA_ALIGN(rta->rta_len);
+       return rta;
+}
 
+/*
+ * Described in header
+ */
+void *netlink_nested_start(struct nlmsghdr *hdr, size_t buflen, int type)
+{
+       return add_rtattr(hdr, buflen, type, 0);
+}
+
+/*
+ * Described in header
+ */
+void netlink_nested_end(struct nlmsghdr *hdr, void *attr)
+{
+       struct rtattr *rta = attr;
+       void *end;
+
+       if (attr)
+       {
+               end = (char*)hdr + NLMSG_ALIGN(hdr->nlmsg_len);
+               rta->rta_len = end - attr;
+       }
+}
+
+/*
+ * Described in header
+ */
+void *netlink_reserve(struct nlmsghdr *hdr, int buflen, int type, int len)
+{
+       struct rtattr *rta;
+
+       rta = add_rtattr(hdr, buflen, type, len);
+       if (!rta)
+       {
+               return NULL;
+       }
        return RTA_DATA(rta);
 }
index 82dce4c..d68a013 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Tobias Brunner
+ * Copyright (C) 2008-2019 Tobias Brunner
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -91,6 +91,28 @@ void netlink_add_attribute(struct nlmsghdr *hdr, int rta_type, chunk_t data,
                                                   size_t buflen);
 
 /**
+ * Creates an rtattr under which other rtattrs are nested to the given netlink
+ * message.
+ *
+ * The returned pointer has to be passed to netlink_nested_end() after the
+ * nested attributes have been added to the message.
+ *
+ * @param hdr                  netlink message
+ * @param buflen               size of full netlink buffer
+ * @param type                 RTA type
+ * @return                             attribute pointer
+ */
+void *netlink_nested_start(struct nlmsghdr *hdr, size_t buflen, int type);
+
+/**
+ * Updates the length of the given attribute after nested attributes were added.
+ *
+ * @param hdr                  netlink message
+ * @param attr                 attribute returned from netlink_nested_start()
+ */
+void netlink_nested_end(struct nlmsghdr *hdr, void *attr);
+
+/**
  * Reserve space in a netlink message for given size and type, returning buffer.
  *
  * @param hdr                  netlink message