1 /* SPDX-License-Identifier: GPL-2.0-or-later 2 * Copyright (c) 2021 Linux Test Project 3 */ 4 5 #ifndef TST_NETLINK_H 6 #define TST_NETLINK_H 7 8 #include <linux/netlink.h> 9 10 struct tst_netlink_context; 11 12 struct tst_netlink_attr_list { 13 unsigned short type; 14 const void *data; 15 ssize_t len; 16 const struct tst_netlink_attr_list *sublist; 17 }; 18 19 struct tst_netlink_message { 20 struct nlmsghdr *header; 21 struct nlmsgerr *err; 22 void *payload; 23 size_t payload_size; 24 }; 25 26 extern int tst_netlink_errno; 27 28 /* Open a netlink socket */ 29 struct tst_netlink_context *tst_netlink_create_context(const char *file, 30 const int lineno, int protocol); 31 #define NETLINK_CREATE_CONTEXT(protocol) \ 32 tst_netlink_create_context(__FILE__, __LINE__, (protocol)) 33 34 /* Free a tst_netlink_message array returned by tst_netlink_recv() */ 35 void tst_netlink_free_message(struct tst_netlink_message *msg); 36 #define NETLINK_FREE_MESSAGE tst_netlink_free_message 37 38 /* Close netlink socket */ 39 void tst_netlink_destroy_context(const char *file, const int lineno, 40 struct tst_netlink_context *ctx); 41 #define NETLINK_DESTROY_CONTEXT(ctx) \ 42 tst_netlink_destroy_context(__FILE__, __LINE__, (ctx)) 43 44 /* Send all messages in given buffer */ 45 int tst_netlink_send(const char *file, const int lineno, 46 struct tst_netlink_context *ctx); 47 #define NETLINK_SEND(ctx) tst_netlink_send(__FILE__, __LINE__, (ctx)) 48 49 /* Send all messages in given buffer and validate kernel response */ 50 int tst_netlink_send_validate(const char *file, const int lineno, 51 struct tst_netlink_context *ctx); 52 #define NETLINK_SEND_VALIDATE(ctx) \ 53 tst_netlink_send_validate(__FILE__, __LINE__, (ctx)) 54 55 /* Wait until data is available for reading from the netlink socket */ 56 int tst_netlink_wait(struct tst_netlink_context *ctx); 57 #define NETLINK_WAIT tst_netlink_wait 58 59 /* 60 * Read from netlink socket and return an array of partially parsed messages. 61 * header == NULL indicates end of array. 62 */ 63 struct tst_netlink_message *tst_netlink_recv(const char *file, const int lineno, 64 struct tst_netlink_context *ctx); 65 #define NETLINK_RECV(ctx) tst_netlink_recv(__FILE__, __LINE__, (ctx)) 66 67 /* Add new message to buffer */ 68 int tst_netlink_add_message(const char *file, const int lineno, 69 struct tst_netlink_context *ctx, const struct nlmsghdr *header, 70 const void *payload, size_t payload_size); 71 #define NETLINK_ADD_MESSAGE(ctx, header, payload, psize) \ 72 tst_netlink_add_message(__FILE__, __LINE__, (ctx), (header), \ 73 (payload), (psize)) 74 75 /* Add arbitrary nlattr attribute to last message */ 76 int tst_netlink_add_attr(const char *file, const int lineno, 77 struct tst_netlink_context *ctx, unsigned short type, const void *data, 78 unsigned short len); 79 #define NETLINK_ADD_ATTR(ctx, type, data, len) \ 80 tst_netlink_add_attr(__FILE__, __LINE__, (ctx), (type), (data), (len)) 81 82 /* Add string nlattr attribute to last message */ 83 int tst_netlink_add_attr_string(const char *file, const int lineno, 84 struct tst_netlink_context *ctx, unsigned short type, const char *data); 85 #define NETLINK_ADD_ATTR_STRING(ctx, type, data) \ 86 tst_netlink_add_attr_string(__FILE__, __LINE__, (ctx), (type), (data)) 87 88 /* 89 * Add list of arbitrary nlattr attributes to last message. The list is 90 * terminated by attribute with negative length. Nested sublists are supported. 91 */ 92 int tst_netlink_add_attr_list(const char *file, const int lineno, 93 struct tst_netlink_context *ctx, 94 const struct tst_netlink_attr_list *list); 95 #define NETLINK_ADD_ATTR_LIST(ctx, list) \ 96 tst_netlink_add_attr_list(__FILE__, __LINE__, (ctx), (list)) 97 98 /* Add arbitrary rtattr attribute to last message */ 99 int tst_rtnl_add_attr(const char *file, const int lineno, 100 struct tst_netlink_context *ctx, unsigned short type, const void *data, 101 unsigned short len); 102 #define RTNL_ADD_ATTR(ctx, type, data, len) \ 103 tst_rtnl_add_attr(__FILE__, __LINE__, (ctx), (type), (data), (len)) 104 105 /* Add string rtattr attribute to last message */ 106 int tst_rtnl_add_attr_string(const char *file, const int lineno, 107 struct tst_netlink_context *ctx, unsigned short type, const char *data); 108 #define RTNL_ADD_ATTR_STRING(ctx, type, data) \ 109 tst_rtnl_add_attr_string(__FILE__, __LINE__, (ctx), (type), (data)) 110 111 /* 112 * Add list of arbitrary rtattr attributes to last message. The list is 113 * terminated by attribute with negative length. Nested sublists are supported. 114 */ 115 int tst_rtnl_add_attr_list(const char *file, const int lineno, 116 struct tst_netlink_context *ctx, 117 const struct tst_netlink_attr_list *list); 118 #define RTNL_ADD_ATTR_LIST(ctx, list) \ 119 tst_rtnl_add_attr_list(__FILE__, __LINE__, (ctx), (list)) 120 121 /* Check that all sent messages with NLM_F_ACK flag have been acked without 122 * error. Usage: 123 * 124 * tst_netlink_send(ctx); 125 * tst_netlink_wait(ctx); 126 * response = tst_netlink_recv(ctx); 127 * if (!tst_netlink_check_acks(ctx, response)) { ... } 128 * tst_netlink_free_message(response); 129 */ 130 int tst_netlink_check_acks(const char *file, const int lineno, 131 struct tst_netlink_context *ctx, struct tst_netlink_message *response); 132 #define NETLINK_CHECK_ACKS(ctx, response) \ 133 tst_netlink_check_acks(__FILE__, __LINE__, (ctx), (response)) 134 135 #endif /* TST_NETLINK_H */ 136