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