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