1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
4 #include <linux/filter.h>
5 #include <linux/netlink.h>
6 #include <linux/sockios.h>
10 #include "sd-device.h"
13 #include "MurmurHash2.h"
14 #include "alloc-util.h"
15 #include "device-filter.h"
16 #include "device-monitor-private.h"
17 #include "device-private.h"
18 #include "device-util.h"
19 #include "errno-util.h"
21 #include "format-util.h"
23 #include "iovec-util.h"
24 #include "missing_socket.h"
25 #include "mountpoint-util.h"
27 #include "socket-util.h"
28 #include "stat-util.h"
29 #include "string-util.h"
31 #include "uid-range.h"
33 #define log_monitor(m, format, ...) \
34 log_debug("sd-device-monitor(%s): " format, strna(m ? m->description : NULL), ##__VA_ARGS__)
35 #define log_monitor_errno(m, r, format, ...) \
36 log_debug_errno(r, "sd-device-monitor(%s): " format, strna(m ? m->description : NULL), ##__VA_ARGS__)
37 #define log_device_monitor(d, m, format, ...) \
38 log_device_debug(d, "sd-device-monitor(%s): " format, strna(m ? m->description : NULL), ##__VA_ARGS__)
39 #define log_device_monitor_errno(d, m, r, format, ...) \
40 log_device_debug_errno(d, r, "sd-device-monitor(%s): " format, strna(m ? m->description : NULL), ##__VA_ARGS__)
42 struct sd_device_monitor
{
46 union sockaddr_union snl
;
47 union sockaddr_union snl_trusted_sender
;
50 UidRange
*mapped_userns_uid_range
;
52 Hashmap
*subsystem_filter
;
54 Hashmap
*match_sysattr_filter
;
55 Hashmap
*nomatch_sysattr_filter
;
56 Set
*match_parent_filter
;
57 Set
*nomatch_parent_filter
;
61 sd_event_source
*event_source
;
63 sd_device_monitor_handler_t callback
;
67 #define UDEV_MONITOR_MAGIC 0xfeedcafe
69 typedef struct monitor_netlink_header
{
70 /* "libudev" prefix to distinguish libudev and kernel messages */
72 /* Magic to protect against daemon <-> Library message format mismatch
73 * Used in the kernel from socket filter rules; needs to be stored in network order */
75 /* Total length of header structure known to the sender */
77 /* Properties string buffer */
78 unsigned properties_off
;
79 unsigned properties_len
;
80 /* Hashes of primary device properties strings, to let libudev subscribers
81 * use in-kernel socket filters; values need to be stored in network order */
82 unsigned filter_subsystem_hash
;
83 unsigned filter_devtype_hash
;
84 unsigned filter_tag_bloom_hi
;
85 unsigned filter_tag_bloom_lo
;
86 } monitor_netlink_header
;
88 static int monitor_set_nl_address(sd_device_monitor
*m
) {
89 union sockaddr_union snl
;
94 /* Get the address the kernel has assigned us.
95 * It is usually, but not necessarily the pid. */
96 addrlen
= sizeof(struct sockaddr_nl
);
97 if (getsockname(m
->sock
, &snl
.sa
, &addrlen
) < 0)
100 m
->snl
.nl
.nl_pid
= snl
.nl
.nl_pid
;
104 int device_monitor_allow_unicast_sender(sd_device_monitor
*m
, sd_device_monitor
*sender
) {
108 m
->snl_trusted_sender
.nl
.nl_pid
= sender
->snl
.nl
.nl_pid
;
112 _public_
int sd_device_monitor_set_receive_buffer_size(sd_device_monitor
*m
, size_t size
) {
113 assert_return(m
, -EINVAL
);
115 return fd_set_rcvbuf(m
->sock
, size
, false);
118 int device_monitor_disconnect(sd_device_monitor
*m
) {
121 m
->sock
= safe_close(m
->sock
);
125 int device_monitor_get_fd(sd_device_monitor
*m
) {
131 int device_monitor_new_full(sd_device_monitor
**ret
, MonitorNetlinkGroup group
, int fd
) {
132 _cleanup_(sd_device_monitor_unrefp
) sd_device_monitor
*m
= NULL
;
133 _cleanup_close_
int sock
= -EBADF
;
136 assert(group
>= 0 && group
< _MONITOR_NETLINK_GROUP_MAX
);
137 assert_return(ret
, -EINVAL
);
139 if (group
== MONITOR_GROUP_UDEV
&&
140 access("/run/udev/control", F_OK
) < 0 &&
141 dev_is_devtmpfs() <= 0) {
144 * We do not support subscribing to uevents if no instance of
145 * udev is running. Uevents would otherwise broadcast the
146 * processing data of the host into containers, which is not
149 * Containers will currently not get any udev uevents, until
150 * a supporting infrastructure is available.
152 * We do not set a netlink multicast group here, so the socket
153 * will not receive any messages.
156 log_monitor(m
, "The udev service seems not to be active, disabling the monitor.");
157 group
= MONITOR_GROUP_NONE
;
161 sock
= socket(AF_NETLINK
, SOCK_RAW
|SOCK_CLOEXEC
|SOCK_NONBLOCK
, NETLINK_KOBJECT_UEVENT
);
163 return log_monitor_errno(m
, errno
, "Failed to create socket: %m");
166 m
= new(sd_device_monitor
, 1);
170 *m
= (sd_device_monitor
) {
172 .sock
= fd
>= 0 ? fd
: TAKE_FD(sock
),
174 .snl
.nl
.nl_family
= AF_NETLINK
,
175 .snl
.nl
.nl_groups
= group
,
179 r
= monitor_set_nl_address(m
);
181 log_monitor_errno(m
, r
, "Failed to set netlink address: %m");
187 _cleanup_close_
int netns
= -EBADF
;
189 /* So here's the thing: only AF_NETLINK sockets from the main network namespace will get
190 * hardware events. Let's check if ours is from there, and if not generate a debug message,
191 * since we cannot possibly work correctly otherwise. This is just a safety check to make
192 * things easier to debug. */
194 netns
= ioctl(m
->sock
, SIOCGSKNS
);
196 log_monitor_errno(m
, errno
, "Unable to get network namespace of udev netlink socket, unable to determine if we are in host netns, ignoring: %m");
200 if (fstat(netns
, &a
) < 0) {
201 r
= log_monitor_errno(m
, errno
, "Failed to stat netns of udev netlink socket: %m");
205 if (stat("/proc/1/ns/net", &b
) < 0) {
206 if (ERRNO_IS_PRIVILEGE(errno
))
207 /* If we can't access PID1's netns info due to permissions, it's fine, this is a
208 * safety check only after all. */
209 log_monitor_errno(m
, errno
, "No permission to stat PID1's netns, unable to determine if we are in host netns, ignoring: %m");
211 log_monitor_errno(m
, errno
, "Failed to stat PID1's netns, ignoring: %m");
213 } else if (!stat_inode_same(&a
, &b
))
214 log_monitor(m
, "Netlink socket we listen on is not from host netns, we won't see device events.");
218 /* Let's bump the receive buffer size, but only if we are not called via socket activation, as in
219 * that case the service manager sets the receive buffer size for us, and the value in the .socket
220 * unit should take full effect. */
222 r
= sd_device_monitor_set_receive_buffer_size(m
, 128*1024*1024);
224 log_monitor_errno(m
, r
, "Failed to increase receive buffer size, ignoring: %m");
231 /* Let's unset the socket fd in the monitor object before we destroy it so that the fd passed in is
232 * not closed on failure. */
239 _public_
int sd_device_monitor_new(sd_device_monitor
**ret
) {
240 return device_monitor_new_full(ret
, MONITOR_GROUP_UDEV
, -1);
243 _public_
int sd_device_monitor_stop(sd_device_monitor
*m
) {
244 assert_return(m
, -EINVAL
);
246 m
->event_source
= sd_event_source_unref(m
->event_source
);
247 (void) device_monitor_disconnect(m
);
252 static int device_monitor_event_handler(sd_event_source
*s
, int fd
, uint32_t revents
, void *userdata
) {
253 _cleanup_(sd_device_unrefp
) sd_device
*device
= NULL
;
254 _unused_
_cleanup_(log_context_unrefp
) LogContext
*c
= NULL
;
255 sd_device_monitor
*m
= ASSERT_PTR(userdata
);
257 if (device_monitor_receive_device(m
, &device
) <= 0)
260 if (log_context_enabled())
261 c
= log_context_new_strv_consume(device_make_log_fields(device
));
264 return m
->callback(m
, device
, m
->userdata
);
269 _public_
int sd_device_monitor_start(sd_device_monitor
*m
, sd_device_monitor_handler_t callback
, void *userdata
) {
272 assert_return(m
, -EINVAL
);
275 r
= sd_device_monitor_attach_event(m
, NULL
);
280 r
= device_monitor_enable_receiving(m
);
284 m
->callback
= callback
;
285 m
->userdata
= userdata
;
287 r
= sd_event_add_io(m
->event
, &m
->event_source
, m
->sock
, EPOLLIN
, device_monitor_event_handler
, m
);
291 (void) sd_event_source_set_description(m
->event_source
, m
->description
?: "sd-device-monitor");
296 _public_
int sd_device_monitor_detach_event(sd_device_monitor
*m
) {
297 assert_return(m
, -EINVAL
);
299 (void) sd_device_monitor_stop(m
);
300 m
->event
= sd_event_unref(m
->event
);
305 _public_
int sd_device_monitor_attach_event(sd_device_monitor
*m
, sd_event
*event
) {
308 assert_return(m
, -EINVAL
);
309 assert_return(!m
->event
, -EBUSY
);
312 m
->event
= sd_event_ref(event
);
314 r
= sd_event_default(&m
->event
);
322 _public_ sd_event
*sd_device_monitor_get_event(sd_device_monitor
*m
) {
323 assert_return(m
, NULL
);
328 _public_ sd_event_source
*sd_device_monitor_get_event_source(sd_device_monitor
*m
) {
329 assert_return(m
, NULL
);
331 return m
->event_source
;
334 _public_
int sd_device_monitor_set_description(sd_device_monitor
*m
, const char *description
) {
337 assert_return(m
, -EINVAL
);
339 r
= free_and_strdup(&m
->description
, description
);
344 (void) sd_event_source_set_description(m
->event_source
, description
);
349 _public_
int sd_device_monitor_get_description(sd_device_monitor
*m
, const char **ret
) {
350 assert_return(m
, -EINVAL
);
351 assert_return(ret
, -EINVAL
);
353 *ret
= m
->description
;
357 int device_monitor_enable_receiving(sd_device_monitor
*m
) {
362 r
= sd_device_monitor_filter_update(m
);
364 return log_monitor_errno(m
, r
, "Failed to update filter: %m");
367 /* enable receiving of sender credentials */
368 r
= setsockopt_int(m
->sock
, SOL_SOCKET
, SO_PASSCRED
, true);
370 return log_monitor_errno(m
, r
, "Failed to set socket option SO_PASSCRED: %m");
372 if (bind(m
->sock
, &m
->snl
.sa
, sizeof(struct sockaddr_nl
)) < 0)
373 return log_monitor_errno(m
, errno
, "Failed to bind monitoring socket: %m");
377 r
= monitor_set_nl_address(m
);
379 return log_monitor_errno(m
, r
, "Failed to set address: %m");
385 static sd_device_monitor
*device_monitor_free(sd_device_monitor
*m
) {
388 (void) sd_device_monitor_detach_event(m
);
390 uid_range_free(m
->mapped_userns_uid_range
);
391 free(m
->description
);
392 hashmap_free(m
->subsystem_filter
);
393 set_free(m
->tag_filter
);
394 hashmap_free(m
->match_sysattr_filter
);
395 hashmap_free(m
->nomatch_sysattr_filter
);
396 set_free(m
->match_parent_filter
);
397 set_free(m
->nomatch_parent_filter
);
402 DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(sd_device_monitor
, sd_device_monitor
, device_monitor_free
);
404 static int check_subsystem_filter(sd_device_monitor
*m
, sd_device
*device
) {
410 if (hashmap_isempty(m
->subsystem_filter
))
413 HASHMAP_FOREACH_KEY(d
, s
, m
->subsystem_filter
) {
414 if (!device_in_subsystem(device
, s
))
417 if (d
&& !device_is_devtype(device
, d
))
426 static bool check_tag_filter(sd_device_monitor
*m
, sd_device
*device
) {
432 if (set_isempty(m
->tag_filter
))
435 SET_FOREACH(tag
, m
->tag_filter
)
436 if (sd_device_has_tag(device
, tag
) > 0)
442 static int passes_filter(sd_device_monitor
*m
, sd_device
*device
) {
448 r
= check_subsystem_filter(m
, device
);
452 if (!check_tag_filter(m
, device
))
455 if (!device_match_sysattr(device
, m
->match_sysattr_filter
, m
->nomatch_sysattr_filter
))
458 return device_match_parent(device
, m
->match_parent_filter
, m
->nomatch_parent_filter
);
461 static bool check_sender_uid(sd_device_monitor
*m
, uid_t uid
) {
466 /* Always trust messages from uid 0. */
470 /* Trust messages sent by the same UID we are running. Currently, such situation happens only for
471 * unicast messages. */
472 if (uid
== getuid() || uid
== geteuid())
475 if (!m
->mapped_userns_uid_range
) {
476 r
= uid_range_load_userns(&m
->mapped_userns_uid_range
, NULL
);
478 log_monitor_errno(m
, r
, "Failed to load UID ranges mapped to the current user namespace, ignoring: %m");
481 /* Trust messages come from outside of the current user namespace. */
482 if (!uid_range_contains(m
->mapped_userns_uid_range
, uid
))
485 /* Otherwise, refuse messages. */
489 int device_monitor_receive_device(sd_device_monitor
*m
, sd_device
**ret
) {
490 _cleanup_(sd_device_unrefp
) sd_device
*device
= NULL
;
491 _cleanup_free_
uint8_t *buf_alloc
= NULL
;
493 monitor_netlink_header
*nlh
;
498 CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct ucred
))) control
;
499 union sockaddr_union snl
;
500 struct msghdr smsg
= {
503 .msg_control
= &control
,
504 .msg_controllen
= sizeof(control
),
506 .msg_namelen
= sizeof(snl
),
511 bool is_initialized
= false;
517 n
= next_datagram_size_fd(m
->sock
);
519 if (!ERRNO_IS_TRANSIENT(n
))
520 log_monitor_errno(m
, n
, "Failed to get the received message size: %m");
524 if ((size_t) n
< ALLOCA_MAX
/ sizeof(uint8_t) / 2)
525 message
.buf
= newa(uint8_t, n
);
527 buf_alloc
= new(uint8_t, n
);
529 return log_oom_debug();
531 message
.buf
= buf_alloc
;
534 iov
= IOVEC_MAKE(message
.buf
, n
);
536 n
= recvmsg(m
->sock
, &smsg
, 0);
538 if (!ERRNO_IS_TRANSIENT(errno
))
539 log_monitor_errno(m
, errno
, "Failed to receive message: %m");
543 if (smsg
.msg_flags
& MSG_TRUNC
)
544 return log_monitor_errno(m
, SYNTHETIC_ERRNO(EINVAL
), "Received truncated message, ignoring message.");
547 return log_monitor_errno(m
, SYNTHETIC_ERRNO(EINVAL
), "Invalid message length (%zi), ignoring message.", n
);
549 if (snl
.nl
.nl_groups
== MONITOR_GROUP_NONE
) {
550 /* unicast message, check if we trust the sender */
551 if (m
->snl_trusted_sender
.nl
.nl_pid
== 0 ||
552 snl
.nl
.nl_pid
!= m
->snl_trusted_sender
.nl
.nl_pid
)
553 return log_monitor_errno(m
, SYNTHETIC_ERRNO(EAGAIN
),
554 "Unicast netlink message ignored.");
556 } else if (snl
.nl
.nl_groups
== MONITOR_GROUP_KERNEL
) {
557 if (snl
.nl
.nl_pid
> 0)
558 return log_monitor_errno(m
, SYNTHETIC_ERRNO(EAGAIN
),
559 "Multicast kernel netlink message from PID %"PRIu32
" ignored.",
563 cred
= CMSG_FIND_DATA(&smsg
, SOL_SOCKET
, SCM_CREDENTIALS
, struct ucred
);
565 return log_monitor_errno(m
, SYNTHETIC_ERRNO(EAGAIN
),
566 "No sender credentials received, ignoring message.");
568 if (!check_sender_uid(m
, cred
->uid
))
569 return log_monitor_errno(m
, SYNTHETIC_ERRNO(EAGAIN
),
570 "Sender uid="UID_FMT
", message ignored.", cred
->uid
);
572 if (!memchr(message
.buf
, 0, n
))
573 return log_monitor_errno(m
, SYNTHETIC_ERRNO(EAGAIN
), "Received message without NUL, ignoring message.");
575 if (streq(message
.nulstr
, "libudev")) {
576 /* udev message needs proper version magic */
577 if (message
.nlh
->magic
!= htobe32(UDEV_MONITOR_MAGIC
))
578 return log_monitor_errno(m
, SYNTHETIC_ERRNO(EAGAIN
),
579 "Invalid message signature (%x != %x).",
580 message
.nlh
->magic
, htobe32(UDEV_MONITOR_MAGIC
));
582 if (message
.nlh
->properties_off
+ 32 > (size_t) n
)
583 return log_monitor_errno(m
, SYNTHETIC_ERRNO(EAGAIN
),
584 "Invalid offset for properties (%u > %zi).",
585 message
.nlh
->properties_off
+ 32, n
);
587 offset
= message
.nlh
->properties_off
;
589 /* devices received from udev are always initialized */
590 is_initialized
= true;
593 /* check kernel message header */
594 if (!strstr(message
.nulstr
, "@/"))
595 return log_monitor_errno(m
, SYNTHETIC_ERRNO(EAGAIN
), "Invalid message header.");
597 offset
= strlen(message
.nulstr
) + 1;
598 if (offset
>= (size_t) n
)
599 return log_monitor_errno(m
, SYNTHETIC_ERRNO(EAGAIN
), "Invalid message length.");
602 r
= device_new_from_nulstr(&device
, message
.nulstr
+ offset
, n
- offset
);
604 return log_monitor_errno(m
, r
, "Failed to create device from received message: %m");
607 device_set_is_initialized(device
);
609 /* Skip device, if it does not pass the current filter */
610 r
= passes_filter(m
, device
);
612 return log_device_monitor_errno(device
, m
, r
, "Failed to check received device passing filter: %m");
614 log_device_monitor(device
, m
, "Received device does not pass filter, ignoring.");
616 *ret
= TAKE_PTR(device
);
621 static uint32_t string_hash32(const char *str
) {
622 return MurmurHash2(str
, strlen(str
), 0);
625 /* Get a bunch of bit numbers out of the hash, and set the bits in our bit field */
626 static uint64_t string_bloom64(const char *str
) {
628 uint32_t hash
= string_hash32(str
);
630 bits
|= UINT64_C(1) << (hash
& 63);
631 bits
|= UINT64_C(1) << ((hash
>> 6) & 63);
632 bits
|= UINT64_C(1) << ((hash
>> 12) & 63);
633 bits
|= UINT64_C(1) << ((hash
>> 18) & 63);
637 int device_monitor_send_device(
638 sd_device_monitor
*m
,
639 sd_device_monitor
*destination
,
642 monitor_netlink_header nlh
= {
644 .magic
= htobe32(UDEV_MONITOR_MAGIC
),
645 .header_size
= sizeof nlh
,
647 struct iovec iov
[2] = {
648 { .iov_base
= &nlh
, .iov_len
= sizeof nlh
},
650 struct msghdr smsg
= {
654 /* default destination for sending */
655 union sockaddr_union default_destination
= {
656 .nl
.nl_family
= AF_NETLINK
,
657 .nl
.nl_groups
= MONITOR_GROUP_UDEV
,
659 uint64_t tag_bloom_bits
;
660 const char *buf
, *val
;
668 r
= device_get_properties_nulstr(device
, &buf
, &blen
);
670 return log_device_monitor_errno(device
, m
, r
, "Failed to get device properties: %m");
672 return log_device_monitor_errno(device
, m
, SYNTHETIC_ERRNO(EINVAL
),
673 "Length of device property nulstr is too small to contain valid device information.");
675 /* fill in versioned header */
676 r
= sd_device_get_subsystem(device
, &val
);
678 return log_device_monitor_errno(device
, m
, r
, "Failed to get device subsystem: %m");
679 nlh
.filter_subsystem_hash
= htobe32(string_hash32(val
));
681 if (sd_device_get_devtype(device
, &val
) >= 0)
682 nlh
.filter_devtype_hash
= htobe32(string_hash32(val
));
684 /* add tag bloom filter */
686 FOREACH_DEVICE_TAG(device
, tag
)
687 tag_bloom_bits
|= string_bloom64(tag
);
689 if (tag_bloom_bits
> 0) {
690 nlh
.filter_tag_bloom_hi
= htobe32(tag_bloom_bits
>> 32);
691 nlh
.filter_tag_bloom_lo
= htobe32(tag_bloom_bits
& 0xffffffff);
694 /* add properties list */
695 nlh
.properties_off
= iov
[0].iov_len
;
696 nlh
.properties_len
= blen
;
697 iov
[1] = IOVEC_MAKE((char*) buf
, blen
);
700 * Use custom address for target, or the default one.
702 * If we send to a multicast group, we will get
703 * ECONNREFUSED, which is expected.
705 smsg
.msg_name
= destination
? &destination
->snl
: &default_destination
;
706 smsg
.msg_namelen
= sizeof(struct sockaddr_nl
);
707 count
= sendmsg(m
->sock
, &smsg
, 0);
709 if (!destination
&& errno
== ECONNREFUSED
) {
710 log_device_monitor(device
, m
, "Passed to netlink monitor.");
713 return log_device_monitor_errno(device
, m
, errno
, "Failed to send device to netlink monitor: %m");
716 log_device_monitor(device
, m
, "Passed %zi byte to netlink monitor.", count
);
720 static void bpf_stmt(struct sock_filter
*ins
, unsigned *i
,
721 unsigned short code
, unsigned data
) {
722 ins
[(*i
)++] = (struct sock_filter
) {
728 static void bpf_jmp(struct sock_filter
*ins
, unsigned *i
,
729 unsigned short code
, unsigned data
,
730 unsigned short jt
, unsigned short jf
) {
731 ins
[(*i
)++] = (struct sock_filter
) {
739 _public_
int sd_device_monitor_filter_update(sd_device_monitor
*m
) {
740 struct sock_filter ins
[512] = {};
741 struct sock_fprog filter
;
742 const char *subsystem
, *devtype
, *tag
;
745 assert_return(m
, -EINVAL
);
747 if (m
->filter_uptodate
)
750 if (m
->snl
.nl
.nl_groups
== MONITOR_GROUP_KERNEL
||
751 (hashmap_isempty(m
->subsystem_filter
) &&
752 set_isempty(m
->tag_filter
))) {
753 m
->filter_uptodate
= true;
757 /* load magic in A */
758 bpf_stmt(ins
, &i
, BPF_LD
|BPF_W
|BPF_ABS
, offsetof(monitor_netlink_header
, magic
));
759 /* jump if magic matches */
760 bpf_jmp(ins
, &i
, BPF_JMP
|BPF_JEQ
|BPF_K
, UDEV_MONITOR_MAGIC
, 1, 0);
761 /* wrong magic, pass packet */
762 bpf_stmt(ins
, &i
, BPF_RET
|BPF_K
, 0xffffffff);
764 if (!set_isempty(m
->tag_filter
)) {
765 int tag_matches
= set_size(m
->tag_filter
);
767 /* add all tags matches */
768 SET_FOREACH(tag
, m
->tag_filter
) {
769 uint64_t tag_bloom_bits
= string_bloom64(tag
);
770 uint32_t tag_bloom_hi
= tag_bloom_bits
>> 32;
771 uint32_t tag_bloom_lo
= tag_bloom_bits
& 0xffffffff;
773 /* load device bloom bits in A */
774 bpf_stmt(ins
, &i
, BPF_LD
|BPF_W
|BPF_ABS
, offsetof(monitor_netlink_header
, filter_tag_bloom_hi
));
775 /* clear bits (tag bits & bloom bits) */
776 bpf_stmt(ins
, &i
, BPF_ALU
|BPF_AND
|BPF_K
, tag_bloom_hi
);
777 /* jump to next tag if it does not match */
778 bpf_jmp(ins
, &i
, BPF_JMP
|BPF_JEQ
|BPF_K
, tag_bloom_hi
, 0, 3);
780 /* load device bloom bits in A */
781 bpf_stmt(ins
, &i
, BPF_LD
|BPF_W
|BPF_ABS
, offsetof(monitor_netlink_header
, filter_tag_bloom_lo
));
782 /* clear bits (tag bits & bloom bits) */
783 bpf_stmt(ins
, &i
, BPF_ALU
|BPF_AND
|BPF_K
, tag_bloom_lo
);
784 /* jump behind end of tag match block if tag matches */
786 bpf_jmp(ins
, &i
, BPF_JMP
|BPF_JEQ
|BPF_K
, tag_bloom_lo
, 1 + (tag_matches
* 6), 0);
789 /* nothing matched, drop packet */
790 bpf_stmt(ins
, &i
, BPF_RET
|BPF_K
, 0);
793 /* add all subsystem matches */
794 if (!hashmap_isempty(m
->subsystem_filter
)) {
795 HASHMAP_FOREACH_KEY(devtype
, subsystem
, m
->subsystem_filter
) {
796 uint32_t hash
= string_hash32(subsystem
);
798 /* load device subsystem value in A */
799 bpf_stmt(ins
, &i
, BPF_LD
|BPF_W
|BPF_ABS
, offsetof(monitor_netlink_header
, filter_subsystem_hash
));
801 /* jump if subsystem does not match */
802 bpf_jmp(ins
, &i
, BPF_JMP
|BPF_JEQ
|BPF_K
, hash
, 0, 1);
804 /* jump if subsystem does not match */
805 bpf_jmp(ins
, &i
, BPF_JMP
|BPF_JEQ
|BPF_K
, hash
, 0, 3);
806 /* load device devtype value in A */
807 bpf_stmt(ins
, &i
, BPF_LD
|BPF_W
|BPF_ABS
, offsetof(monitor_netlink_header
, filter_devtype_hash
));
808 /* jump if value does not match */
809 hash
= string_hash32(devtype
);
810 bpf_jmp(ins
, &i
, BPF_JMP
|BPF_JEQ
|BPF_K
, hash
, 0, 1);
813 /* matched, pass packet */
814 bpf_stmt(ins
, &i
, BPF_RET
|BPF_K
, 0xffffffff);
816 if (i
+1 >= ELEMENTSOF(ins
))
820 /* nothing matched, drop packet */
821 bpf_stmt(ins
, &i
, BPF_RET
|BPF_K
, 0);
824 /* matched, pass packet */
825 bpf_stmt(ins
, &i
, BPF_RET
|BPF_K
, 0xffffffff);
828 filter
= (struct sock_fprog
) {
832 if (setsockopt(m
->sock
, SOL_SOCKET
, SO_ATTACH_FILTER
, &filter
, sizeof(filter
)) < 0)
835 m
->filter_uptodate
= true;
839 _public_
int sd_device_monitor_filter_add_match_subsystem_devtype(sd_device_monitor
*m
, const char *subsystem
, const char *devtype
) {
842 assert_return(m
, -EINVAL
);
843 assert_return(subsystem
, -EINVAL
);
845 /* Do not use string_has_ops_free_free or hashmap_put_strdup() here, as this may be called
846 * multiple times with the same subsystem but different devtypes. */
847 r
= hashmap_put_strdup_full(&m
->subsystem_filter
, &trivial_hash_ops_free_free
, subsystem
, devtype
);
851 m
->filter_uptodate
= false;
855 _public_
int sd_device_monitor_filter_add_match_tag(sd_device_monitor
*m
, const char *tag
) {
858 assert_return(m
, -EINVAL
);
859 assert_return(tag
, -EINVAL
);
861 r
= set_put_strdup(&m
->tag_filter
, tag
);
865 m
->filter_uptodate
= false;
869 _public_
int sd_device_monitor_filter_add_match_sysattr(sd_device_monitor
*m
, const char *sysattr
, const char *value
, int match
) {
872 assert_return(m
, -EINVAL
);
873 assert_return(sysattr
, -EINVAL
);
876 hashmap
= &m
->match_sysattr_filter
;
878 hashmap
= &m
->nomatch_sysattr_filter
;
880 /* TODO: unset m->filter_uptodate on success when we support this filter on BPF. */
881 return update_match_strv(hashmap
, sysattr
, value
, /* clear_on_null = */ true);
884 _public_
int sd_device_monitor_filter_add_match_parent(sd_device_monitor
*m
, sd_device
*device
, int match
) {
889 assert_return(m
, -EINVAL
);
890 assert_return(device
, -EINVAL
);
892 r
= sd_device_get_syspath(device
, &syspath
);
897 set
= &m
->match_parent_filter
;
899 set
= &m
->nomatch_parent_filter
;
901 /* TODO: unset m->filter_uptodate on success when we support this filter on BPF. */
902 return set_put_strdup(set
, syspath
);
905 _public_
int sd_device_monitor_filter_remove(sd_device_monitor
*m
) {
906 static const struct sock_fprog filter
= { 0, NULL
};
908 assert_return(m
, -EINVAL
);
910 m
->subsystem_filter
= hashmap_free(m
->subsystem_filter
);
911 m
->tag_filter
= set_free(m
->tag_filter
);
912 m
->match_sysattr_filter
= hashmap_free(m
->match_sysattr_filter
);
913 m
->nomatch_sysattr_filter
= hashmap_free(m
->nomatch_sysattr_filter
);
914 m
->match_parent_filter
= set_free(m
->match_parent_filter
);
915 m
->nomatch_parent_filter
= set_free(m
->nomatch_parent_filter
);
917 if (setsockopt(m
->sock
, SOL_SOCKET
, SO_DETACH_FILTER
, &filter
, sizeof(filter
)) < 0)
920 m
->filter_uptodate
= true;