]>
Commit | Line | Data |
---|---|---|
53e1b683 | 1 | /* SPDX-License-Identifier: LGPL-2.1+ */ |
a2cdd907 LP |
2 | #pragma once |
3 | ||
65f568bb TG |
4 | /*** |
5 | This file is part of systemd. | |
6 | ||
7 | Copyright 2013 Tom Gundersen <teg@jklm.no> | |
8 | ||
9 | systemd is free software; you can redistribute it and/or modify it | |
10 | under the terms of the GNU Lesser General Public License as published by | |
11 | the Free Software Foundation; either version 2.1 of the License, or | |
12 | (at your option) any later version. | |
13 | ||
14 | systemd is distributed in the hope that it will be useful, but | |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
17 | Lesser General Public License for more details. | |
18 | ||
19 | You should have received a copy of the GNU Lesser General Public License | |
20 | along with systemd; If not, see <http://www.gnu.org/licenses/>. | |
21 | ***/ | |
22 | ||
a33dece5 LP |
23 | #include <linux/netlink.h> |
24 | ||
1c4baffc | 25 | #include "sd-netlink.h" |
e16bcf98 | 26 | |
07630cea | 27 | #include "list.h" |
1c4baffc | 28 | #include "netlink-types.h" |
07630cea LP |
29 | #include "prioq.h" |
30 | #include "refcnt.h" | |
d8e538ec | 31 | |
59a7a684 | 32 | #define RTNL_DEFAULT_TIMEOUT ((usec_t) (25 * USEC_PER_SEC)) |
3815f36f TG |
33 | |
34 | #define RTNL_WQUEUE_MAX 1024 | |
35 | #define RTNL_RQUEUE_MAX 64*1024 | |
36 | ||
37 | #define RTNL_CONTAINER_DEPTH 32 | |
38 | ||
e16bcf98 | 39 | struct reply_callback { |
1c4baffc | 40 | sd_netlink_message_handler_t callback; |
e16bcf98 TG |
41 | void *userdata; |
42 | usec_t timeout; | |
43 | uint64_t serial; | |
44 | unsigned prioq_idx; | |
45 | }; | |
65f568bb | 46 | |
8cec01b9 | 47 | struct match_callback { |
1c4baffc | 48 | sd_netlink_message_handler_t callback; |
23a7f0f7 | 49 | uint16_t type; |
8cec01b9 TG |
50 | void *userdata; |
51 | ||
52 | LIST_FIELDS(struct match_callback, match_callbacks); | |
53 | }; | |
54 | ||
1c4baffc | 55 | struct sd_netlink { |
65f568bb TG |
56 | RefCount n_ref; |
57 | ||
58 | int fd; | |
59 | ||
60 | union { | |
61 | struct sockaddr sa; | |
62 | struct sockaddr_nl nl; | |
63 | } sockaddr; | |
64 | ||
9c5a882b TG |
65 | Hashmap *broadcast_group_refs; |
66 | bool broadcast_group_dont_leave:1; /* until we can rely on 4.2 */ | |
67 | ||
1c4baffc | 68 | sd_netlink_message **rqueue; |
4555ec72 | 69 | unsigned rqueue_size; |
77768cba | 70 | size_t rqueue_allocated; |
4555ec72 | 71 | |
1c4baffc | 72 | sd_netlink_message **rqueue_partial; |
4e996881 TG |
73 | unsigned rqueue_partial_size; |
74 | size_t rqueue_partial_allocated; | |
75 | ||
a88f77c4 TG |
76 | struct nlmsghdr *rbuffer; |
77 | size_t rbuffer_allocated; | |
78 | ||
4555ec72 TG |
79 | bool processing:1; |
80 | ||
d4bbdb77 TG |
81 | uint32_t serial; |
82 | ||
e16bcf98 TG |
83 | struct Prioq *reply_callbacks_prioq; |
84 | Hashmap *reply_callbacks; | |
85 | ||
8cec01b9 TG |
86 | LIST_HEAD(struct match_callback, match_callbacks); |
87 | ||
adf412b9 | 88 | pid_t original_pid; |
b4f2a5b1 TG |
89 | |
90 | sd_event_source *io_event_source; | |
91 | sd_event_source *time_event_source; | |
6203e07a | 92 | sd_event_source *exit_event_source; |
b4f2a5b1 | 93 | sd_event *event; |
65f568bb | 94 | }; |
98dd77e8 | 95 | |
f663aeb8 | 96 | struct netlink_attribute { |
aa6b0ac4 | 97 | size_t offset; /* offset from hdr to attribute */ |
4c641e99 TG |
98 | bool nested:1; |
99 | bool net_byteorder:1; | |
f663aeb8 TG |
100 | }; |
101 | ||
102 | struct netlink_container { | |
103 | const struct NLTypeSystem *type_system; /* the type system of the container */ | |
104 | size_t offset; /* offset from hdr to the start of the container */ | |
105 | struct netlink_attribute *attributes; | |
106 | unsigned short n_attributes; /* number of attributes in container */ | |
107 | }; | |
108 | ||
1c4baffc | 109 | struct sd_netlink_message { |
3815f36f | 110 | RefCount n_ref; |
4555ec72 | 111 | |
1c4baffc | 112 | sd_netlink *rtnl; |
4fb7242c | 113 | |
3815f36f | 114 | struct nlmsghdr *hdr; |
f663aeb8 | 115 | struct netlink_container containers[RTNL_CONTAINER_DEPTH]; |
3815f36f | 116 | unsigned n_containers; /* number of containers */ |
3815f36f | 117 | bool sealed:1; |
3f42446d | 118 | bool broadcast:1; |
1403f45a | 119 | |
1c4baffc | 120 | sd_netlink_message *next; /* next in a chain of multi-part messages */ |
3815f36f | 121 | }; |
9d0db178 | 122 | |
1c4baffc | 123 | int message_new(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t type); |
89489ef7 | 124 | int message_new_empty(sd_netlink *rtnl, sd_netlink_message **ret); |
9d0db178 | 125 | |
b95cc756 TG |
126 | int socket_open(int family); |
127 | int socket_bind(sd_netlink *nl); | |
9c5a882b TG |
128 | int socket_broadcast_group_ref(sd_netlink *nl, unsigned group); |
129 | int socket_broadcast_group_unref(sd_netlink *nl, unsigned group); | |
1c4baffc TG |
130 | int socket_write_message(sd_netlink *nl, sd_netlink_message *m); |
131 | int socket_read_message(sd_netlink *nl); | |
1b89cf56 | 132 | |
1c4baffc TG |
133 | int rtnl_rqueue_make_room(sd_netlink *rtnl); |
134 | int rtnl_rqueue_partial_make_room(sd_netlink *rtnl); | |
e16bcf98 TG |
135 | |
136 | /* Make sure callbacks don't destroy the rtnl connection */ | |
4afd3348 LP |
137 | #define NETLINK_DONT_DESTROY(rtnl) \ |
138 | _cleanup_(sd_netlink_unrefp) _unused_ sd_netlink *_dont_destroy_##rtnl = sd_netlink_ref(rtnl) |