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"
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.");
222 /* Let's unset the socket fd in the monitor object before we destroy it so that the fd passed in is
223 * not closed on failure. */
230 _public_
int sd_device_monitor_new(sd_device_monitor
**ret
) {
231 return device_monitor_new_full(ret
, MONITOR_GROUP_UDEV
, -1);
234 _public_
int sd_device_monitor_stop(sd_device_monitor
*m
) {
235 assert_return(m
, -EINVAL
);
237 m
->event_source
= sd_event_source_unref(m
->event_source
);
238 (void) device_monitor_disconnect(m
);
243 static int device_monitor_event_handler(sd_event_source
*s
, int fd
, uint32_t revents
, void *userdata
) {
244 _cleanup_(sd_device_unrefp
) sd_device
*device
= NULL
;
245 _unused_
_cleanup_(log_context_unrefp
) LogContext
*c
= NULL
;
246 sd_device_monitor
*m
= ASSERT_PTR(userdata
);
248 if (device_monitor_receive_device(m
, &device
) <= 0)
251 if (log_context_enabled())
252 c
= log_context_new_strv_consume(device_make_log_fields(device
));
255 return m
->callback(m
, device
, m
->userdata
);
260 _public_
int sd_device_monitor_start(sd_device_monitor
*m
, sd_device_monitor_handler_t callback
, void *userdata
) {
263 assert_return(m
, -EINVAL
);
266 r
= sd_device_monitor_attach_event(m
, NULL
);
271 r
= device_monitor_enable_receiving(m
);
275 m
->callback
= callback
;
276 m
->userdata
= userdata
;
278 r
= sd_event_add_io(m
->event
, &m
->event_source
, m
->sock
, EPOLLIN
, device_monitor_event_handler
, m
);
282 (void) sd_event_source_set_description(m
->event_source
, m
->description
?: "sd-device-monitor");
287 _public_
int sd_device_monitor_detach_event(sd_device_monitor
*m
) {
288 assert_return(m
, -EINVAL
);
290 (void) sd_device_monitor_stop(m
);
291 m
->event
= sd_event_unref(m
->event
);
296 _public_
int sd_device_monitor_attach_event(sd_device_monitor
*m
, sd_event
*event
) {
299 assert_return(m
, -EINVAL
);
300 assert_return(!m
->event
, -EBUSY
);
303 m
->event
= sd_event_ref(event
);
305 r
= sd_event_default(&m
->event
);
313 _public_ sd_event
*sd_device_monitor_get_event(sd_device_monitor
*m
) {
314 assert_return(m
, NULL
);
319 _public_ sd_event_source
*sd_device_monitor_get_event_source(sd_device_monitor
*m
) {
320 assert_return(m
, NULL
);
322 return m
->event_source
;
325 _public_
int sd_device_monitor_set_description(sd_device_monitor
*m
, const char *description
) {
328 assert_return(m
, -EINVAL
);
330 r
= free_and_strdup(&m
->description
, description
);
335 (void) sd_event_source_set_description(m
->event_source
, description
);
340 _public_
int sd_device_monitor_get_description(sd_device_monitor
*m
, const char **ret
) {
341 assert_return(m
, -EINVAL
);
342 assert_return(ret
, -EINVAL
);
344 *ret
= m
->description
;
348 int device_monitor_enable_receiving(sd_device_monitor
*m
) {
353 r
= sd_device_monitor_filter_update(m
);
355 return log_monitor_errno(m
, r
, "Failed to update filter: %m");
358 /* enable receiving of sender credentials */
359 r
= setsockopt_int(m
->sock
, SOL_SOCKET
, SO_PASSCRED
, true);
361 return log_monitor_errno(m
, r
, "Failed to set socket option SO_PASSCRED: %m");
363 if (bind(m
->sock
, &m
->snl
.sa
, sizeof(struct sockaddr_nl
)) < 0)
364 return log_monitor_errno(m
, errno
, "Failed to bind monitoring socket: %m");
368 r
= monitor_set_nl_address(m
);
370 return log_monitor_errno(m
, r
, "Failed to set address: %m");
376 static sd_device_monitor
*device_monitor_free(sd_device_monitor
*m
) {
379 (void) sd_device_monitor_detach_event(m
);
381 uid_range_free(m
->mapped_userns_uid_range
);
382 free(m
->description
);
383 hashmap_free(m
->subsystem_filter
);
384 set_free(m
->tag_filter
);
385 hashmap_free(m
->match_sysattr_filter
);
386 hashmap_free(m
->nomatch_sysattr_filter
);
387 set_free(m
->match_parent_filter
);
388 set_free(m
->nomatch_parent_filter
);
393 DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(sd_device_monitor
, sd_device_monitor
, device_monitor_free
);
395 static int check_subsystem_filter(sd_device_monitor
*m
, sd_device
*device
) {
396 const char *s
, *subsystem
, *d
, *devtype
= NULL
;
402 if (hashmap_isempty(m
->subsystem_filter
))
405 r
= sd_device_get_subsystem(device
, &subsystem
);
409 r
= sd_device_get_devtype(device
, &devtype
);
410 if (r
< 0 && r
!= -ENOENT
)
413 HASHMAP_FOREACH_KEY(d
, s
, m
->subsystem_filter
) {
414 if (!streq(s
, subsystem
))
417 if (!d
|| streq_ptr(d
, devtype
))
424 static bool check_tag_filter(sd_device_monitor
*m
, sd_device
*device
) {
430 if (set_isempty(m
->tag_filter
))
433 SET_FOREACH(tag
, m
->tag_filter
)
434 if (sd_device_has_tag(device
, tag
) > 0)
440 static int passes_filter(sd_device_monitor
*m
, sd_device
*device
) {
446 r
= check_subsystem_filter(m
, device
);
450 if (!check_tag_filter(m
, device
))
453 if (!device_match_sysattr(device
, m
->match_sysattr_filter
, m
->nomatch_sysattr_filter
))
456 return device_match_parent(device
, m
->match_parent_filter
, m
->nomatch_parent_filter
);
459 static bool check_sender_uid(sd_device_monitor
*m
, uid_t uid
) {
464 /* Always trust messages from uid 0. */
468 /* Trust messages sent by the same UID we are running. Currently, such situation happens only for
469 * unicast messages. */
470 if (uid
== getuid() || uid
== geteuid())
473 if (!m
->mapped_userns_uid_range
) {
474 r
= uid_range_load_userns(&m
->mapped_userns_uid_range
, NULL
);
476 log_monitor_errno(m
, r
, "Failed to load UID ranges mapped to the current user namespace, ignoring: %m");
479 /* Trust messages come from outside of the current user namespace. */
480 if (!uid_range_contains(m
->mapped_userns_uid_range
, uid
))
483 /* Otherwise, refuse messages. */
487 int device_monitor_receive_device(sd_device_monitor
*m
, sd_device
**ret
) {
488 _cleanup_(sd_device_unrefp
) sd_device
*device
= NULL
;
489 _cleanup_free_
uint8_t *buf_alloc
= NULL
;
491 monitor_netlink_header
*nlh
;
496 CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct ucred
))) control
;
497 union sockaddr_union snl
;
498 struct msghdr smsg
= {
501 .msg_control
= &control
,
502 .msg_controllen
= sizeof(control
),
504 .msg_namelen
= sizeof(snl
),
509 bool is_initialized
= false;
515 n
= next_datagram_size_fd(m
->sock
);
517 if (!ERRNO_IS_TRANSIENT(n
))
518 log_monitor_errno(m
, n
, "Failed to get the received message size: %m");
522 if ((size_t) n
< ALLOCA_MAX
/ sizeof(uint8_t) / 2)
523 message
.buf
= newa(uint8_t, n
);
525 buf_alloc
= new(uint8_t, n
);
527 return log_oom_debug();
529 message
.buf
= buf_alloc
;
532 iov
= IOVEC_MAKE(message
.buf
, n
);
534 n
= recvmsg(m
->sock
, &smsg
, 0);
536 if (!ERRNO_IS_TRANSIENT(errno
))
537 log_monitor_errno(m
, errno
, "Failed to receive message: %m");
541 if (smsg
.msg_flags
& MSG_TRUNC
)
542 return log_monitor_errno(m
, SYNTHETIC_ERRNO(EINVAL
), "Received truncated message, ignoring message.");
545 return log_monitor_errno(m
, SYNTHETIC_ERRNO(EINVAL
), "Invalid message length (%zi), ignoring message.", n
);
547 if (snl
.nl
.nl_groups
== MONITOR_GROUP_NONE
) {
548 /* unicast message, check if we trust the sender */
549 if (m
->snl_trusted_sender
.nl
.nl_pid
== 0 ||
550 snl
.nl
.nl_pid
!= m
->snl_trusted_sender
.nl
.nl_pid
)
551 return log_monitor_errno(m
, SYNTHETIC_ERRNO(EAGAIN
),
552 "Unicast netlink message ignored.");
554 } else if (snl
.nl
.nl_groups
== MONITOR_GROUP_KERNEL
) {
555 if (snl
.nl
.nl_pid
> 0)
556 return log_monitor_errno(m
, SYNTHETIC_ERRNO(EAGAIN
),
557 "Multicast kernel netlink message from PID %"PRIu32
" ignored.",
561 cred
= CMSG_FIND_DATA(&smsg
, SOL_SOCKET
, SCM_CREDENTIALS
, struct ucred
);
563 return log_monitor_errno(m
, SYNTHETIC_ERRNO(EAGAIN
),
564 "No sender credentials received, ignoring message.");
566 if (!check_sender_uid(m
, cred
->uid
))
567 return log_monitor_errno(m
, SYNTHETIC_ERRNO(EAGAIN
),
568 "Sender uid="UID_FMT
", message ignored.", cred
->uid
);
570 if (!memchr(message
.buf
, 0, n
))
571 return log_monitor_errno(m
, SYNTHETIC_ERRNO(EAGAIN
), "Received message without NUL, ignoring message.");
573 if (streq(message
.nulstr
, "libudev")) {
574 /* udev message needs proper version magic */
575 if (message
.nlh
->magic
!= htobe32(UDEV_MONITOR_MAGIC
))
576 return log_monitor_errno(m
, SYNTHETIC_ERRNO(EAGAIN
),
577 "Invalid message signature (%x != %x).",
578 message
.nlh
->magic
, htobe32(UDEV_MONITOR_MAGIC
));
580 if (message
.nlh
->properties_off
+ 32 > (size_t) n
)
581 return log_monitor_errno(m
, SYNTHETIC_ERRNO(EAGAIN
),
582 "Invalid offset for properties (%u > %zi).",
583 message
.nlh
->properties_off
+ 32, n
);
585 offset
= message
.nlh
->properties_off
;
587 /* devices received from udev are always initialized */
588 is_initialized
= true;
591 /* check kernel message header */
592 if (!strstr(message
.nulstr
, "@/"))
593 return log_monitor_errno(m
, SYNTHETIC_ERRNO(EAGAIN
), "Invalid message header.");
595 offset
= strlen(message
.nulstr
) + 1;
596 if (offset
>= (size_t) n
)
597 return log_monitor_errno(m
, SYNTHETIC_ERRNO(EAGAIN
), "Invalid message length.");
600 r
= device_new_from_nulstr(&device
, message
.nulstr
+ offset
, n
- offset
);
602 return log_monitor_errno(m
, r
, "Failed to create device from received message: %m");
605 device_set_is_initialized(device
);
607 /* Skip device, if it does not pass the current filter */
608 r
= passes_filter(m
, device
);
610 return log_device_monitor_errno(device
, m
, r
, "Failed to check received device passing filter: %m");
612 log_device_monitor(device
, m
, "Received device does not pass filter, ignoring.");
614 *ret
= TAKE_PTR(device
);
619 static uint32_t string_hash32(const char *str
) {
620 return MurmurHash2(str
, strlen(str
), 0);
623 /* Get a bunch of bit numbers out of the hash, and set the bits in our bit field */
624 static uint64_t string_bloom64(const char *str
) {
626 uint32_t hash
= string_hash32(str
);
628 bits
|= UINT64_C(1) << (hash
& 63);
629 bits
|= UINT64_C(1) << ((hash
>> 6) & 63);
630 bits
|= UINT64_C(1) << ((hash
>> 12) & 63);
631 bits
|= UINT64_C(1) << ((hash
>> 18) & 63);
635 int device_monitor_send_device(
636 sd_device_monitor
*m
,
637 sd_device_monitor
*destination
,
640 monitor_netlink_header nlh
= {
642 .magic
= htobe32(UDEV_MONITOR_MAGIC
),
643 .header_size
= sizeof nlh
,
645 struct iovec iov
[2] = {
646 { .iov_base
= &nlh
, .iov_len
= sizeof nlh
},
648 struct msghdr smsg
= {
652 /* default destination for sending */
653 union sockaddr_union default_destination
= {
654 .nl
.nl_family
= AF_NETLINK
,
655 .nl
.nl_groups
= MONITOR_GROUP_UDEV
,
657 uint64_t tag_bloom_bits
;
658 const char *buf
, *val
;
666 r
= device_get_properties_nulstr(device
, &buf
, &blen
);
668 return log_device_monitor_errno(device
, m
, r
, "Failed to get device properties: %m");
670 return log_device_monitor_errno(device
, m
, SYNTHETIC_ERRNO(EINVAL
),
671 "Length of device property nulstr is too small to contain valid device information.");
673 /* fill in versioned header */
674 r
= sd_device_get_subsystem(device
, &val
);
676 return log_device_monitor_errno(device
, m
, r
, "Failed to get device subsystem: %m");
677 nlh
.filter_subsystem_hash
= htobe32(string_hash32(val
));
679 if (sd_device_get_devtype(device
, &val
) >= 0)
680 nlh
.filter_devtype_hash
= htobe32(string_hash32(val
));
682 /* add tag bloom filter */
684 FOREACH_DEVICE_TAG(device
, val
)
685 tag_bloom_bits
|= string_bloom64(val
);
687 if (tag_bloom_bits
> 0) {
688 nlh
.filter_tag_bloom_hi
= htobe32(tag_bloom_bits
>> 32);
689 nlh
.filter_tag_bloom_lo
= htobe32(tag_bloom_bits
& 0xffffffff);
692 /* add properties list */
693 nlh
.properties_off
= iov
[0].iov_len
;
694 nlh
.properties_len
= blen
;
695 iov
[1] = IOVEC_MAKE((char*) buf
, blen
);
698 * Use custom address for target, or the default one.
700 * If we send to a multicast group, we will get
701 * ECONNREFUSED, which is expected.
703 smsg
.msg_name
= destination
? &destination
->snl
: &default_destination
;
704 smsg
.msg_namelen
= sizeof(struct sockaddr_nl
);
705 count
= sendmsg(m
->sock
, &smsg
, 0);
707 if (!destination
&& errno
== ECONNREFUSED
) {
708 log_device_monitor(device
, m
, "Passed to netlink monitor.");
711 return log_device_monitor_errno(device
, m
, errno
, "Failed to send device to netlink monitor: %m");
714 log_device_monitor(device
, m
, "Passed %zi byte to netlink monitor.", count
);
718 static void bpf_stmt(struct sock_filter
*ins
, unsigned *i
,
719 unsigned short code
, unsigned data
) {
720 ins
[(*i
)++] = (struct sock_filter
) {
726 static void bpf_jmp(struct sock_filter
*ins
, unsigned *i
,
727 unsigned short code
, unsigned data
,
728 unsigned short jt
, unsigned short jf
) {
729 ins
[(*i
)++] = (struct sock_filter
) {
737 _public_
int sd_device_monitor_filter_update(sd_device_monitor
*m
) {
738 struct sock_filter ins
[512] = {};
739 struct sock_fprog filter
;
740 const char *subsystem
, *devtype
, *tag
;
743 assert_return(m
, -EINVAL
);
745 if (m
->filter_uptodate
)
748 if (m
->snl
.nl
.nl_groups
== MONITOR_GROUP_KERNEL
||
749 (hashmap_isempty(m
->subsystem_filter
) &&
750 set_isempty(m
->tag_filter
))) {
751 m
->filter_uptodate
= true;
755 /* load magic in A */
756 bpf_stmt(ins
, &i
, BPF_LD
|BPF_W
|BPF_ABS
, offsetof(monitor_netlink_header
, magic
));
757 /* jump if magic matches */
758 bpf_jmp(ins
, &i
, BPF_JMP
|BPF_JEQ
|BPF_K
, UDEV_MONITOR_MAGIC
, 1, 0);
759 /* wrong magic, pass packet */
760 bpf_stmt(ins
, &i
, BPF_RET
|BPF_K
, 0xffffffff);
762 if (!set_isempty(m
->tag_filter
)) {
763 int tag_matches
= set_size(m
->tag_filter
);
765 /* add all tags matches */
766 SET_FOREACH(tag
, m
->tag_filter
) {
767 uint64_t tag_bloom_bits
= string_bloom64(tag
);
768 uint32_t tag_bloom_hi
= tag_bloom_bits
>> 32;
769 uint32_t tag_bloom_lo
= tag_bloom_bits
& 0xffffffff;
771 /* load device bloom bits in A */
772 bpf_stmt(ins
, &i
, BPF_LD
|BPF_W
|BPF_ABS
, offsetof(monitor_netlink_header
, filter_tag_bloom_hi
));
773 /* clear bits (tag bits & bloom bits) */
774 bpf_stmt(ins
, &i
, BPF_ALU
|BPF_AND
|BPF_K
, tag_bloom_hi
);
775 /* jump to next tag if it does not match */
776 bpf_jmp(ins
, &i
, BPF_JMP
|BPF_JEQ
|BPF_K
, tag_bloom_hi
, 0, 3);
778 /* load device bloom bits in A */
779 bpf_stmt(ins
, &i
, BPF_LD
|BPF_W
|BPF_ABS
, offsetof(monitor_netlink_header
, filter_tag_bloom_lo
));
780 /* clear bits (tag bits & bloom bits) */
781 bpf_stmt(ins
, &i
, BPF_ALU
|BPF_AND
|BPF_K
, tag_bloom_lo
);
782 /* jump behind end of tag match block if tag matches */
784 bpf_jmp(ins
, &i
, BPF_JMP
|BPF_JEQ
|BPF_K
, tag_bloom_lo
, 1 + (tag_matches
* 6), 0);
787 /* nothing matched, drop packet */
788 bpf_stmt(ins
, &i
, BPF_RET
|BPF_K
, 0);
791 /* add all subsystem matches */
792 if (!hashmap_isempty(m
->subsystem_filter
)) {
793 HASHMAP_FOREACH_KEY(devtype
, subsystem
, m
->subsystem_filter
) {
794 uint32_t hash
= string_hash32(subsystem
);
796 /* load device subsystem value in A */
797 bpf_stmt(ins
, &i
, BPF_LD
|BPF_W
|BPF_ABS
, offsetof(monitor_netlink_header
, filter_subsystem_hash
));
799 /* jump if subsystem does not match */
800 bpf_jmp(ins
, &i
, BPF_JMP
|BPF_JEQ
|BPF_K
, hash
, 0, 1);
802 /* jump if subsystem does not match */
803 bpf_jmp(ins
, &i
, BPF_JMP
|BPF_JEQ
|BPF_K
, hash
, 0, 3);
804 /* load device devtype value in A */
805 bpf_stmt(ins
, &i
, BPF_LD
|BPF_W
|BPF_ABS
, offsetof(monitor_netlink_header
, filter_devtype_hash
));
806 /* jump if value does not match */
807 hash
= string_hash32(devtype
);
808 bpf_jmp(ins
, &i
, BPF_JMP
|BPF_JEQ
|BPF_K
, hash
, 0, 1);
811 /* matched, pass packet */
812 bpf_stmt(ins
, &i
, BPF_RET
|BPF_K
, 0xffffffff);
814 if (i
+1 >= ELEMENTSOF(ins
))
818 /* nothing matched, drop packet */
819 bpf_stmt(ins
, &i
, BPF_RET
|BPF_K
, 0);
822 /* matched, pass packet */
823 bpf_stmt(ins
, &i
, BPF_RET
|BPF_K
, 0xffffffff);
826 filter
= (struct sock_fprog
) {
830 if (setsockopt(m
->sock
, SOL_SOCKET
, SO_ATTACH_FILTER
, &filter
, sizeof(filter
)) < 0)
833 m
->filter_uptodate
= true;
837 _public_
int sd_device_monitor_filter_add_match_subsystem_devtype(sd_device_monitor
*m
, const char *subsystem
, const char *devtype
) {
840 assert_return(m
, -EINVAL
);
841 assert_return(subsystem
, -EINVAL
);
843 /* Do not use string_has_ops_free_free or hashmap_put_strdup() here, as this may be called
844 * multiple times with the same subsystem but different devtypes. */
845 r
= hashmap_put_strdup_full(&m
->subsystem_filter
, &trivial_hash_ops_free_free
, subsystem
, devtype
);
849 m
->filter_uptodate
= false;
853 _public_
int sd_device_monitor_filter_add_match_tag(sd_device_monitor
*m
, const char *tag
) {
856 assert_return(m
, -EINVAL
);
857 assert_return(tag
, -EINVAL
);
859 r
= set_put_strdup(&m
->tag_filter
, tag
);
863 m
->filter_uptodate
= false;
867 _public_
int sd_device_monitor_filter_add_match_sysattr(sd_device_monitor
*m
, const char *sysattr
, const char *value
, int match
) {
870 assert_return(m
, -EINVAL
);
871 assert_return(sysattr
, -EINVAL
);
874 hashmap
= &m
->match_sysattr_filter
;
876 hashmap
= &m
->nomatch_sysattr_filter
;
878 /* TODO: unset m->filter_uptodate on success when we support this filter on BPF. */
879 return update_match_strv(hashmap
, sysattr
, value
, /* clear_on_null = */ true);
882 _public_
int sd_device_monitor_filter_add_match_parent(sd_device_monitor
*m
, sd_device
*device
, int match
) {
887 assert_return(m
, -EINVAL
);
888 assert_return(device
, -EINVAL
);
890 r
= sd_device_get_syspath(device
, &syspath
);
895 set
= &m
->match_parent_filter
;
897 set
= &m
->nomatch_parent_filter
;
899 /* TODO: unset m->filter_uptodate on success when we support this filter on BPF. */
900 return set_put_strdup(set
, syspath
);
903 _public_
int sd_device_monitor_filter_remove(sd_device_monitor
*m
) {
904 static const struct sock_fprog filter
= { 0, NULL
};
906 assert_return(m
, -EINVAL
);
908 m
->subsystem_filter
= hashmap_free(m
->subsystem_filter
);
909 m
->tag_filter
= set_free(m
->tag_filter
);
910 m
->match_sysattr_filter
= hashmap_free(m
->match_sysattr_filter
);
911 m
->nomatch_sysattr_filter
= hashmap_free(m
->nomatch_sysattr_filter
);
912 m
->match_parent_filter
= set_free(m
->match_parent_filter
);
913 m
->nomatch_parent_filter
= set_free(m
->nomatch_parent_filter
);
915 if (setsockopt(m
->sock
, SOL_SOCKET
, SO_DETACH_FILTER
, &filter
, sizeof(filter
)) < 0)
918 m
->filter_uptodate
= true;