1 /* SPDX-License-Identifier: LGPL-2.1-or-later */ 2 #pragma once 3 4 #include <linux/netlink.h> 5 6 #include "sd-netlink.h" 7 8 #include "list.h" 9 #include "netlink-types.h" 10 #include "prioq.h" 11 #include "time-util.h" 12 13 #define NETLINK_DEFAULT_TIMEOUT_USEC ((usec_t) (25 * USEC_PER_SEC)) 14 15 #define NETLINK_RQUEUE_MAX 64*1024 16 17 #define NETLINK_CONTAINER_DEPTH 32 18 19 struct reply_callback { 20 sd_netlink_message_handler_t callback; 21 usec_t timeout; 22 uint32_t serial; 23 unsigned prioq_idx; 24 }; 25 26 struct match_callback { 27 sd_netlink_message_handler_t callback; 28 uint32_t *groups; 29 size_t n_groups; 30 uint16_t type; 31 uint8_t cmd; /* used by genl */ 32 33 LIST_FIELDS(struct match_callback, match_callbacks); 34 }; 35 36 typedef enum NetlinkSlotType { 37 NETLINK_REPLY_CALLBACK, 38 NETLINK_MATCH_CALLBACK, 39 _NETLINK_SLOT_INVALID = -EINVAL, 40 } NetlinkSlotType; 41 42 struct sd_netlink_slot { 43 unsigned n_ref; 44 NetlinkSlotType type:8; 45 bool floating; 46 sd_netlink *netlink; 47 void *userdata; 48 sd_netlink_destroy_t destroy_callback; 49 50 char *description; 51 52 LIST_FIELDS(sd_netlink_slot, slots); 53 54 union { 55 struct reply_callback reply_callback; 56 struct match_callback match_callback; 57 }; 58 }; 59 60 struct sd_netlink { 61 unsigned n_ref; 62 63 int fd; 64 65 union { 66 struct sockaddr sa; 67 struct sockaddr_nl nl; 68 } sockaddr; 69 70 int protocol; 71 72 Hashmap *broadcast_group_refs; 73 bool broadcast_group_dont_leave:1; /* until we can rely on 4.2 */ 74 75 sd_netlink_message **rqueue; 76 unsigned rqueue_size; 77 78 sd_netlink_message **rqueue_partial; 79 unsigned rqueue_partial_size; 80 81 struct nlmsghdr *rbuffer; 82 83 bool processing:1; 84 85 uint32_t serial; 86 87 struct Prioq *reply_callbacks_prioq; 88 Hashmap *reply_callbacks; 89 90 LIST_HEAD(struct match_callback, match_callbacks); 91 92 LIST_HEAD(sd_netlink_slot, slots); 93 94 pid_t original_pid; 95 96 sd_event_source *io_event_source; 97 sd_event_source *time_event_source; 98 sd_event_source *exit_event_source; 99 sd_event *event; 100 101 Hashmap *genl_family_by_name; 102 Hashmap *genl_family_by_id; 103 }; 104 105 struct netlink_attribute { 106 size_t offset; /* offset from hdr to attribute */ 107 bool nested:1; 108 bool net_byteorder:1; 109 }; 110 111 struct netlink_container { 112 const struct NLTypeSystem *type_system; /* the type system of the container */ 113 size_t offset; /* offset from hdr to the start of the container */ 114 struct netlink_attribute *attributes; 115 uint16_t max_attribute; /* the maximum attribute in container */ 116 }; 117 118 struct sd_netlink_message { 119 unsigned n_ref; 120 121 int protocol; 122 123 struct nlmsghdr *hdr; 124 struct netlink_container containers[NETLINK_CONTAINER_DEPTH]; 125 unsigned n_containers; /* number of containers */ 126 uint32_t multicast_group; 127 bool sealed:1; 128 129 sd_netlink_message *next; /* next in a chain of multi-part messages */ 130 }; 131 132 int message_new_empty(sd_netlink *nl, sd_netlink_message **ret); 133 int message_new_full( 134 sd_netlink *nl, 135 uint16_t nlmsg_type, 136 const NLTypeSystem *type_system, 137 size_t header_size, 138 sd_netlink_message **ret); 139 int message_new(sd_netlink *nl, sd_netlink_message **ret, uint16_t type); 140 int message_new_synthetic_error(sd_netlink *nl, int error, uint32_t serial, sd_netlink_message **ret); 141 uint32_t message_get_serial(sd_netlink_message *m); 142 void message_seal(sd_netlink_message *m); 143 144 int netlink_open_family(sd_netlink **ret, int family); 145 bool netlink_pid_changed(sd_netlink *nl); 146 int netlink_rqueue_make_room(sd_netlink *nl); 147 int netlink_rqueue_partial_make_room(sd_netlink *nl); 148 149 int socket_open(int family); 150 int socket_bind(sd_netlink *nl); 151 int socket_broadcast_group_ref(sd_netlink *nl, unsigned group); 152 int socket_broadcast_group_unref(sd_netlink *nl, unsigned group); 153 int socket_write_message(sd_netlink *nl, sd_netlink_message *m); 154 int socket_writev_message(sd_netlink *nl, sd_netlink_message **m, size_t msgcount); 155 int socket_read_message(sd_netlink *nl); 156 157 int netlink_add_match_internal( 158 sd_netlink *nl, 159 sd_netlink_slot **ret_slot, 160 const uint32_t *groups, 161 size_t n_groups, 162 uint16_t type, 163 uint8_t cmd, 164 sd_netlink_message_handler_t callback, 165 sd_netlink_destroy_t destroy_callback, 166 void *userdata, 167 const char *description); 168 169 /* Make sure callbacks don't destroy the netlink connection */ 170 #define NETLINK_DONT_DESTROY(nl) \ 171 _cleanup_(sd_netlink_unrefp) _unused_ sd_netlink *_dont_destroy_##nl = sd_netlink_ref(nl) 172