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