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-monitor-private.h"
16 #include "device-private.h"
17 #include "device-util.h"
18 #include "errno-util.h"
20 #include "format-util.h"
23 #include "missing_socket.h"
24 #include "mountpoint-util.h"
26 #include "socket-util.h"
27 #include "string-util.h"
30 struct sd_device_monitor
{
34 union sockaddr_union snl
;
35 union sockaddr_union snl_trusted_sender
;
38 Hashmap
*subsystem_filter
;
43 sd_event_source
*event_source
;
44 sd_device_monitor_handler_t callback
;
48 #define UDEV_MONITOR_MAGIC 0xfeedcafe
50 typedef struct monitor_netlink_header
{
51 /* "libudev" prefix to distinguish libudev and kernel messages */
53 /* Magic to protect against daemon <-> Library message format mismatch
54 * Used in the kernel from socket filter rules; needs to be stored in network order */
56 /* Total length of header structure known to the sender */
58 /* Properties string buffer */
59 unsigned properties_off
;
60 unsigned properties_len
;
61 /* Hashes of primary device properties strings, to let libudev subscribers
62 * use in-kernel socket filters; values need to be stored in network order */
63 unsigned filter_subsystem_hash
;
64 unsigned filter_devtype_hash
;
65 unsigned filter_tag_bloom_hi
;
66 unsigned filter_tag_bloom_lo
;
67 } monitor_netlink_header
;
69 static int monitor_set_nl_address(sd_device_monitor
*m
) {
70 union sockaddr_union snl
;
75 /* Get the address the kernel has assigned us.
76 * It is usually, but not necessarily the pid. */
77 addrlen
= sizeof(struct sockaddr_nl
);
78 if (getsockname(m
->sock
, &snl
.sa
, &addrlen
) < 0)
81 m
->snl
.nl
.nl_pid
= snl
.nl
.nl_pid
;
85 int device_monitor_allow_unicast_sender(sd_device_monitor
*m
, sd_device_monitor
*sender
) {
86 assert_return(m
, -EINVAL
);
87 assert_return(sender
, -EINVAL
);
89 m
->snl_trusted_sender
.nl
.nl_pid
= sender
->snl
.nl
.nl_pid
;
93 _public_
int sd_device_monitor_set_receive_buffer_size(sd_device_monitor
*m
, size_t size
) {
94 assert_return(m
, -EINVAL
);
96 return fd_set_rcvbuf(m
->sock
, size
, false);
99 int device_monitor_disconnect(sd_device_monitor
*m
) {
102 m
->sock
= safe_close(m
->sock
);
106 int device_monitor_get_fd(sd_device_monitor
*m
) {
107 assert_return(m
, -EINVAL
);
112 int device_monitor_new_full(sd_device_monitor
**ret
, MonitorNetlinkGroup group
, int fd
) {
113 _cleanup_(sd_device_monitor_unrefp
) sd_device_monitor
*m
= NULL
;
114 _cleanup_close_
int sock
= -1;
117 assert_return(ret
, -EINVAL
);
118 assert_return(group
>= 0 && group
< _MONITOR_NETLINK_GROUP_MAX
, -EINVAL
);
120 if (group
== MONITOR_GROUP_UDEV
&&
121 access("/run/udev/control", F_OK
) < 0 &&
122 dev_is_devtmpfs() <= 0) {
125 * We do not support subscribing to uevents if no instance of
126 * udev is running. Uevents would otherwise broadcast the
127 * processing data of the host into containers, which is not
130 * Containers will currently not get any udev uevents, until
131 * a supporting infrastructure is available.
133 * We do not set a netlink multicast group here, so the socket
134 * will not receive any messages.
137 log_debug("sd-device-monitor: The udev service seems not to be active, disabling the monitor");
138 group
= MONITOR_GROUP_NONE
;
142 sock
= socket(PF_NETLINK
, SOCK_RAW
|SOCK_CLOEXEC
|SOCK_NONBLOCK
, NETLINK_KOBJECT_UEVENT
);
144 return log_debug_errno(errno
, "sd-device-monitor: Failed to create socket: %m");
147 m
= new(sd_device_monitor
, 1);
151 *m
= (sd_device_monitor
) {
153 .sock
= fd
>= 0 ? fd
: TAKE_FD(sock
),
155 .snl
.nl
.nl_family
= AF_NETLINK
,
156 .snl
.nl
.nl_groups
= group
,
160 r
= monitor_set_nl_address(m
);
162 log_debug_errno(r
, "sd-device-monitor: Failed to set netlink address: %m");
168 _cleanup_close_
int netns
= -1;
170 /* So here's the thing: only AF_NETLINK sockets from the main network namespace will get
171 * hardware events. Let's check if ours is from there, and if not generate a debug message,
172 * since we cannot possibly work correctly otherwise. This is just a safety check to make
173 * things easier to debug. */
175 netns
= ioctl(m
->sock
, SIOCGSKNS
);
177 log_debug_errno(errno
, "sd-device-monitor: Unable to get network namespace of udev netlink socket, unable to determine if we are in host netns: %m");
181 if (fstat(netns
, &a
) < 0) {
182 r
= log_debug_errno(errno
, "sd-device-monitor: Failed to stat netns of udev netlink socket: %m");
186 if (stat("/proc/1/ns/net", &b
) < 0) {
187 if (ERRNO_IS_PRIVILEGE(errno
))
188 /* If we can't access PID1's netns info due to permissions, it's fine, this is a
189 * safety check only after all. */
190 log_debug_errno(errno
, "sd-device-monitor: No permission to stat PID1's netns, unable to determine if we are in host netns: %m");
192 log_debug_errno(errno
, "sd-device-monitor: Failed to stat PID1's netns: %m");
194 } else if (a
.st_dev
!= b
.st_dev
|| a
.st_ino
!= b
.st_ino
)
195 log_debug("sd-device-monitor: Netlink socket we listen on is not from host netns, we won't see device events.");
203 /* Let's unset the socket fd in the monitor object before we destroy it so that the fd passed in is
204 * not closed on failure. */
211 _public_
int sd_device_monitor_new(sd_device_monitor
**ret
) {
212 return device_monitor_new_full(ret
, MONITOR_GROUP_UDEV
, -1);
215 _public_
int sd_device_monitor_stop(sd_device_monitor
*m
) {
216 assert_return(m
, -EINVAL
);
218 m
->event_source
= sd_event_source_unref(m
->event_source
);
219 (void) device_monitor_disconnect(m
);
224 static int device_monitor_event_handler(sd_event_source
*s
, int fd
, uint32_t revents
, void *userdata
) {
225 _cleanup_(sd_device_unrefp
) sd_device
*device
= NULL
;
226 sd_device_monitor
*m
= userdata
;
230 if (device_monitor_receive_device(m
, &device
) <= 0)
234 return m
->callback(m
, device
, m
->userdata
);
239 _public_
int sd_device_monitor_start(sd_device_monitor
*m
, sd_device_monitor_handler_t callback
, void *userdata
) {
242 assert_return(m
, -EINVAL
);
245 r
= sd_device_monitor_attach_event(m
, NULL
);
250 r
= device_monitor_enable_receiving(m
);
254 m
->callback
= callback
;
255 m
->userdata
= userdata
;
257 r
= sd_event_add_io(m
->event
, &m
->event_source
, m
->sock
, EPOLLIN
, device_monitor_event_handler
, m
);
261 (void) sd_event_source_set_description(m
->event_source
, "sd-device-monitor");
266 _public_
int sd_device_monitor_detach_event(sd_device_monitor
*m
) {
267 assert_return(m
, -EINVAL
);
269 (void) sd_device_monitor_stop(m
);
270 m
->event
= sd_event_unref(m
->event
);
275 _public_
int sd_device_monitor_attach_event(sd_device_monitor
*m
, sd_event
*event
) {
278 assert_return(m
, -EINVAL
);
279 assert_return(!m
->event
, -EBUSY
);
282 m
->event
= sd_event_ref(event
);
284 r
= sd_event_default(&m
->event
);
292 _public_ sd_event
*sd_device_monitor_get_event(sd_device_monitor
*m
) {
293 assert_return(m
, NULL
);
298 _public_ sd_event_source
*sd_device_monitor_get_event_source(sd_device_monitor
*m
) {
299 assert_return(m
, NULL
);
301 return m
->event_source
;
304 int device_monitor_enable_receiving(sd_device_monitor
*m
) {
307 assert_return(m
, -EINVAL
);
309 r
= sd_device_monitor_filter_update(m
);
311 return log_debug_errno(r
, "sd-device-monitor: Failed to update filter: %m");
314 /* enable receiving of sender credentials */
315 r
= setsockopt_int(m
->sock
, SOL_SOCKET
, SO_PASSCRED
, true);
317 return log_debug_errno(r
, "sd-device-monitor: Failed to set socket option SO_PASSCRED: %m");
319 if (bind(m
->sock
, &m
->snl
.sa
, sizeof(struct sockaddr_nl
)) < 0)
320 return log_debug_errno(errno
, "sd-device-monitor: Failed to bind monitoring socket: %m");
324 r
= monitor_set_nl_address(m
);
326 return log_debug_errno(r
, "sd-device-monitor: Failed to set address: %m");
332 static sd_device_monitor
*device_monitor_free(sd_device_monitor
*m
) {
335 (void) sd_device_monitor_detach_event(m
);
337 hashmap_free_free_free(m
->subsystem_filter
);
338 set_free_free(m
->tag_filter
);
343 DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(sd_device_monitor
, sd_device_monitor
, device_monitor_free
);
345 static int passes_filter(sd_device_monitor
*m
, sd_device
*device
) {
346 const char *tag
, *subsystem
, *devtype
, *s
, *d
= NULL
;
349 assert_return(m
, -EINVAL
);
350 assert_return(device
, -EINVAL
);
352 if (hashmap_isempty(m
->subsystem_filter
))
355 r
= sd_device_get_subsystem(device
, &s
);
359 r
= sd_device_get_devtype(device
, &d
);
360 if (r
< 0 && r
!= -ENOENT
)
363 HASHMAP_FOREACH_KEY(devtype
, subsystem
, m
->subsystem_filter
) {
364 if (!streq(s
, subsystem
))
373 if (streq(d
, devtype
))
380 if (set_isempty(m
->tag_filter
))
383 SET_FOREACH(tag
, m
->tag_filter
)
384 if (sd_device_has_tag(device
, tag
) > 0)
390 int device_monitor_receive_device(sd_device_monitor
*m
, sd_device
**ret
) {
391 _cleanup_(sd_device_unrefp
) sd_device
*device
= NULL
;
393 monitor_netlink_header nlh
;
398 .iov_len
= sizeof(buf
)
400 CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct ucred
))) control
;
401 union sockaddr_union snl
;
402 struct msghdr smsg
= {
405 .msg_control
= &control
,
406 .msg_controllen
= sizeof(control
),
408 .msg_namelen
= sizeof(snl
),
410 struct cmsghdr
*cmsg
;
412 ssize_t buflen
, bufpos
;
413 bool is_initialized
= false;
418 buflen
= recvmsg(m
->sock
, &smsg
, 0);
421 log_debug_errno(errno
, "sd-device-monitor: Failed to receive message: %m");
425 if (buflen
< 32 || (smsg
.msg_flags
& MSG_TRUNC
))
426 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
),
427 "sd-device-monitor: Invalid message length.");
429 if (snl
.nl
.nl_groups
== MONITOR_GROUP_NONE
) {
430 /* unicast message, check if we trust the sender */
431 if (m
->snl_trusted_sender
.nl
.nl_pid
== 0 ||
432 snl
.nl
.nl_pid
!= m
->snl_trusted_sender
.nl
.nl_pid
)
433 return log_debug_errno(SYNTHETIC_ERRNO(EAGAIN
),
434 "sd-device-monitor: Unicast netlink message ignored.");
436 } else if (snl
.nl
.nl_groups
== MONITOR_GROUP_KERNEL
) {
437 if (snl
.nl
.nl_pid
> 0)
438 return log_debug_errno(SYNTHETIC_ERRNO(EAGAIN
),
439 "sd-device-monitor: Multicast kernel netlink message from PID %"PRIu32
" ignored.", snl
.nl
.nl_pid
);
442 cmsg
= CMSG_FIRSTHDR(&smsg
);
443 if (!cmsg
|| cmsg
->cmsg_type
!= SCM_CREDENTIALS
)
444 return log_debug_errno(SYNTHETIC_ERRNO(EAGAIN
),
445 "sd-device-monitor: No sender credentials received, message ignored.");
447 cred
= (struct ucred
*) CMSG_DATA(cmsg
);
449 return log_debug_errno(SYNTHETIC_ERRNO(EAGAIN
),
450 "sd-device-monitor: Sender uid="UID_FMT
", message ignored.", cred
->uid
);
452 if (streq(buf
.raw
, "libudev")) {
453 /* udev message needs proper version magic */
454 if (buf
.nlh
.magic
!= htobe32(UDEV_MONITOR_MAGIC
))
455 return log_debug_errno(SYNTHETIC_ERRNO(EAGAIN
),
456 "sd-device-monitor: Invalid message signature (%x != %x)",
457 buf
.nlh
.magic
, htobe32(UDEV_MONITOR_MAGIC
));
459 if (buf
.nlh
.properties_off
+32 > (size_t) buflen
)
460 return log_debug_errno(SYNTHETIC_ERRNO(EAGAIN
),
461 "sd-device-monitor: Invalid message length (%u > %zd)",
462 buf
.nlh
.properties_off
+32, buflen
);
464 bufpos
= buf
.nlh
.properties_off
;
466 /* devices received from udev are always initialized */
467 is_initialized
= true;
470 /* kernel message with header */
471 bufpos
= strlen(buf
.raw
) + 1;
472 if ((size_t) bufpos
< sizeof("a@/d") || bufpos
>= buflen
)
473 return log_debug_errno(SYNTHETIC_ERRNO(EAGAIN
),
474 "sd-device-monitor: Invalid message length");
476 /* check message header */
477 if (!strstr(buf
.raw
, "@/"))
478 return log_debug_errno(SYNTHETIC_ERRNO(EAGAIN
),
479 "sd-device-monitor: Invalid message header");
482 r
= device_new_from_nulstr(&device
, (uint8_t*) &buf
.raw
[bufpos
], buflen
- bufpos
);
484 return log_debug_errno(r
, "sd-device-monitor: Failed to create device from received message: %m");
487 device_set_is_initialized(device
);
489 /* Skip device, if it does not pass the current filter */
490 r
= passes_filter(m
, device
);
492 return log_device_debug_errno(device
, r
, "sd-device-monitor: Failed to check received device passing filter: %m");
494 log_device_debug(device
, "sd-device-monitor: Received device does not pass filter, ignoring");
496 *ret
= TAKE_PTR(device
);
501 static uint32_t string_hash32(const char *str
) {
502 return MurmurHash2(str
, strlen(str
), 0);
505 /* Get a bunch of bit numbers out of the hash, and set the bits in our bit field */
506 static uint64_t string_bloom64(const char *str
) {
508 uint32_t hash
= string_hash32(str
);
510 bits
|= 1LLU << (hash
& 63);
511 bits
|= 1LLU << ((hash
>> 6) & 63);
512 bits
|= 1LLU << ((hash
>> 12) & 63);
513 bits
|= 1LLU << ((hash
>> 18) & 63);
517 int device_monitor_send_device(
518 sd_device_monitor
*m
,
519 sd_device_monitor
*destination
,
522 monitor_netlink_header nlh
= {
524 .magic
= htobe32(UDEV_MONITOR_MAGIC
),
525 .header_size
= sizeof nlh
,
527 struct iovec iov
[2] = {
528 { .iov_base
= &nlh
, .iov_len
= sizeof nlh
},
530 struct msghdr smsg
= {
534 /* default destination for sending */
535 union sockaddr_union default_destination
= {
536 .nl
.nl_family
= AF_NETLINK
,
537 .nl
.nl_groups
= MONITOR_GROUP_UDEV
,
539 uint64_t tag_bloom_bits
;
540 const char *buf
, *val
;
548 r
= device_get_properties_nulstr(device
, (const uint8_t **) &buf
, &blen
);
550 return log_device_debug_errno(device
, r
, "sd-device-monitor: Failed to get device properties: %m");
552 log_device_debug_errno(device
, SYNTHETIC_ERRNO(EINVAL
),
553 "sd-device-monitor: Length of device property nulstr is too small to contain valid device information");
555 /* fill in versioned header */
556 r
= sd_device_get_subsystem(device
, &val
);
558 return log_device_debug_errno(device
, r
, "sd-device-monitor: Failed to get device subsystem: %m");
559 nlh
.filter_subsystem_hash
= htobe32(string_hash32(val
));
561 if (sd_device_get_devtype(device
, &val
) >= 0)
562 nlh
.filter_devtype_hash
= htobe32(string_hash32(val
));
564 /* add tag bloom filter */
566 FOREACH_DEVICE_TAG(device
, val
)
567 tag_bloom_bits
|= string_bloom64(val
);
569 if (tag_bloom_bits
> 0) {
570 nlh
.filter_tag_bloom_hi
= htobe32(tag_bloom_bits
>> 32);
571 nlh
.filter_tag_bloom_lo
= htobe32(tag_bloom_bits
& 0xffffffff);
574 /* add properties list */
575 nlh
.properties_off
= iov
[0].iov_len
;
576 nlh
.properties_len
= blen
;
577 iov
[1] = IOVEC_MAKE((char*) buf
, blen
);
580 * Use custom address for target, or the default one.
582 * If we send to a multicast group, we will get
583 * ECONNREFUSED, which is expected.
585 smsg
.msg_name
= destination
? &destination
->snl
: &default_destination
;
586 smsg
.msg_namelen
= sizeof(struct sockaddr_nl
);
587 count
= sendmsg(m
->sock
, &smsg
, 0);
589 if (!destination
&& errno
== ECONNREFUSED
) {
590 log_device_debug(device
, "sd-device-monitor: Passed to netlink monitor");
593 return log_device_debug_errno(device
, errno
, "sd-device-monitor: Failed to send device to netlink monitor: %m");
596 log_device_debug(device
, "sd-device-monitor: Passed %zi byte to netlink monitor", count
);
600 static void bpf_stmt(struct sock_filter
*ins
, unsigned *i
,
601 unsigned short code
, unsigned data
) {
602 ins
[(*i
)++] = (struct sock_filter
) {
608 static void bpf_jmp(struct sock_filter
*ins
, unsigned *i
,
609 unsigned short code
, unsigned data
,
610 unsigned short jt
, unsigned short jf
) {
611 ins
[(*i
)++] = (struct sock_filter
) {
619 _public_
int sd_device_monitor_filter_update(sd_device_monitor
*m
) {
620 struct sock_filter ins
[512] = {};
621 struct sock_fprog filter
;
622 const char *subsystem
, *devtype
, *tag
;
625 assert_return(m
, -EINVAL
);
627 if (m
->filter_uptodate
)
630 if (hashmap_isempty(m
->subsystem_filter
) &&
631 set_isempty(m
->tag_filter
)) {
632 m
->filter_uptodate
= true;
636 /* load magic in A */
637 bpf_stmt(ins
, &i
, BPF_LD
|BPF_W
|BPF_ABS
, offsetof(monitor_netlink_header
, magic
));
638 /* jump if magic matches */
639 bpf_jmp(ins
, &i
, BPF_JMP
|BPF_JEQ
|BPF_K
, UDEV_MONITOR_MAGIC
, 1, 0);
640 /* wrong magic, pass packet */
641 bpf_stmt(ins
, &i
, BPF_RET
|BPF_K
, 0xffffffff);
643 if (!set_isempty(m
->tag_filter
)) {
644 int tag_matches
= set_size(m
->tag_filter
);
646 /* add all tags matches */
647 SET_FOREACH(tag
, m
->tag_filter
) {
648 uint64_t tag_bloom_bits
= string_bloom64(tag
);
649 uint32_t tag_bloom_hi
= tag_bloom_bits
>> 32;
650 uint32_t tag_bloom_lo
= tag_bloom_bits
& 0xffffffff;
652 /* load device bloom bits in A */
653 bpf_stmt(ins
, &i
, BPF_LD
|BPF_W
|BPF_ABS
, offsetof(monitor_netlink_header
, filter_tag_bloom_hi
));
654 /* clear bits (tag bits & bloom bits) */
655 bpf_stmt(ins
, &i
, BPF_ALU
|BPF_AND
|BPF_K
, tag_bloom_hi
);
656 /* jump to next tag if it does not match */
657 bpf_jmp(ins
, &i
, BPF_JMP
|BPF_JEQ
|BPF_K
, tag_bloom_hi
, 0, 3);
659 /* load device bloom bits in A */
660 bpf_stmt(ins
, &i
, BPF_LD
|BPF_W
|BPF_ABS
, offsetof(monitor_netlink_header
, filter_tag_bloom_lo
));
661 /* clear bits (tag bits & bloom bits) */
662 bpf_stmt(ins
, &i
, BPF_ALU
|BPF_AND
|BPF_K
, tag_bloom_lo
);
663 /* jump behind end of tag match block if tag matches */
665 bpf_jmp(ins
, &i
, BPF_JMP
|BPF_JEQ
|BPF_K
, tag_bloom_lo
, 1 + (tag_matches
* 6), 0);
668 /* nothing matched, drop packet */
669 bpf_stmt(ins
, &i
, BPF_RET
|BPF_K
, 0);
672 /* add all subsystem matches */
673 if (!hashmap_isempty(m
->subsystem_filter
)) {
674 HASHMAP_FOREACH_KEY(devtype
, subsystem
, m
->subsystem_filter
) {
675 uint32_t hash
= string_hash32(subsystem
);
677 /* load device subsystem value in A */
678 bpf_stmt(ins
, &i
, BPF_LD
|BPF_W
|BPF_ABS
, offsetof(monitor_netlink_header
, filter_subsystem_hash
));
680 /* jump if subsystem does not match */
681 bpf_jmp(ins
, &i
, BPF_JMP
|BPF_JEQ
|BPF_K
, hash
, 0, 1);
683 /* jump if subsystem does not match */
684 bpf_jmp(ins
, &i
, BPF_JMP
|BPF_JEQ
|BPF_K
, hash
, 0, 3);
685 /* load device devtype value in A */
686 bpf_stmt(ins
, &i
, BPF_LD
|BPF_W
|BPF_ABS
, offsetof(monitor_netlink_header
, filter_devtype_hash
));
687 /* jump if value does not match */
688 hash
= string_hash32(devtype
);
689 bpf_jmp(ins
, &i
, BPF_JMP
|BPF_JEQ
|BPF_K
, hash
, 0, 1);
692 /* matched, pass packet */
693 bpf_stmt(ins
, &i
, BPF_RET
|BPF_K
, 0xffffffff);
695 if (i
+1 >= ELEMENTSOF(ins
))
699 /* nothing matched, drop packet */
700 bpf_stmt(ins
, &i
, BPF_RET
|BPF_K
, 0);
703 /* matched, pass packet */
704 bpf_stmt(ins
, &i
, BPF_RET
|BPF_K
, 0xffffffff);
707 filter
= (struct sock_fprog
) {
711 if (setsockopt(m
->sock
, SOL_SOCKET
, SO_ATTACH_FILTER
, &filter
, sizeof(filter
)) < 0)
714 m
->filter_uptodate
= true;
718 _public_
int sd_device_monitor_filter_add_match_subsystem_devtype(sd_device_monitor
*m
, const char *subsystem
, const char *devtype
) {
719 _cleanup_free_
char *s
= NULL
, *d
= NULL
;
722 assert_return(m
, -EINVAL
);
723 assert_return(subsystem
, -EINVAL
);
725 s
= strdup(subsystem
);
735 r
= hashmap_ensure_put(&m
->subsystem_filter
, NULL
, s
, d
);
742 m
->filter_uptodate
= false;
747 _public_
int sd_device_monitor_filter_add_match_tag(sd_device_monitor
*m
, const char *tag
) {
748 assert_return(m
, -EINVAL
);
749 assert_return(tag
, -EINVAL
);
751 int r
= set_put_strdup(&m
->tag_filter
, tag
);
753 m
->filter_uptodate
= false;
757 _public_
int sd_device_monitor_filter_remove(sd_device_monitor
*m
) {
758 static const struct sock_fprog filter
= { 0, NULL
};
760 assert_return(m
, -EINVAL
);
762 m
->subsystem_filter
= hashmap_free_free_free(m
->subsystem_filter
);
763 m
->tag_filter
= set_free_free(m
->tag_filter
);
765 if (setsockopt(m
->sock
, SOL_SOCKET
, SO_DETACH_FILTER
, &filter
, sizeof(filter
)) < 0)
768 m
->filter_uptodate
= true;