]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/basic/socket-label.c
Merge pull request #17185 from yuwata/ethtool-update
[thirdparty/systemd.git] / src / basic / socket-label.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
cc527a47 2
cc527a47 3#include <errno.h>
11c3a366
TA
4#include <netinet/in.h>
5#include <stdbool.h>
cc527a47 6#include <stddef.h>
3ffd4af2 7#include <string.h>
11c3a366 8#include <sys/un.h>
3ffd4af2 9#include <unistd.h>
cc527a47 10
b5efdb8a 11#include "alloc-util.h"
3ffd4af2 12#include "fd-util.h"
294d46f1 13#include "fs-util.h"
93cc7779 14#include "log.h"
cc527a47 15#include "macro.h"
f5947a5e 16#include "missing_socket.h"
3ffd4af2 17#include "mkdir.h"
d7b8eec7
LP
18#include "selinux-util.h"
19#include "socket-util.h"
825546ef 20#include "umask-util.h"
cc527a47
KS
21
22int socket_address_listen(
23 const SocketAddress *a,
175a3d25 24 int flags,
cc527a47
KS
25 int backlog,
26 SocketAddressBindIPv6Only only,
27 const char *bind_to_device,
54255c64 28 bool reuse_port,
cc527a47
KS
29 bool free_bind,
30 bool transparent,
31 mode_t directory_mode,
32 mode_t socket_mode,
175a3d25
LP
33 const char *label) {
34
35 _cleanup_close_ int fd = -1;
294d46f1 36 const char *p;
6d5e65f6 37 int r;
cc527a47 38
cc527a47 39 assert(a);
cc527a47 40
15dca371 41 r = socket_address_verify(a, true);
175a3d25 42 if (r < 0)
cc527a47
KS
43 return r;
44
45 if (socket_address_family(a) == AF_INET6 && !socket_ipv6_is_supported())
46 return -EAFNOSUPPORT;
47
175a3d25 48 if (label) {
ecabcf8b 49 r = mac_selinux_create_socket_prepare(label);
175a3d25
LP
50 if (r < 0)
51 return r;
52 }
cc527a47 53
175a3d25 54 fd = socket(socket_address_family(a), a->type | flags, a->protocol);
cc527a47
KS
55 r = fd < 0 ? -errno : 0;
56
175a3d25 57 if (label)
ecabcf8b 58 mac_selinux_create_socket_clear();
cc527a47
KS
59
60 if (r < 0)
61 return r;
62
63 if (socket_address_family(a) == AF_INET6 && only != SOCKET_ADDRESS_DEFAULT) {
2ff48e98
LP
64 r = setsockopt_int(fd, IPPROTO_IPV6, IPV6_V6ONLY, only == SOCKET_ADDRESS_IPV6_ONLY);
65 if (r < 0)
66 return r;
cc527a47
KS
67 }
68
5ed272cf 69 if (IN_SET(socket_address_family(a), AF_INET, AF_INET6)) {
953a02d1
LP
70 if (bind_to_device) {
71 r = socket_bind_to_ifname(fd, bind_to_device);
72 if (r < 0)
73 return r;
74 }
cc527a47 75
54255c64 76 if (reuse_port) {
2ff48e98
LP
77 r = setsockopt_int(fd, SOL_SOCKET, SO_REUSEPORT, true);
78 if (r < 0)
79 log_warning_errno(r, "SO_REUSEPORT failed: %m");
54255c64
CT
80 }
81
cc527a47 82 if (free_bind) {
5d0fe423 83 r = socket_set_freebind(fd, socket_address_family(a), true);
2ff48e98 84 if (r < 0)
5d0fe423 85 log_warning_errno(r, "IP_FREEBIND/IPV6_FREEBIND failed: %m");
cc527a47
KS
86 }
87
88 if (transparent) {
5d0fe423 89 r = socket_set_transparent(fd, socket_address_family(a), true);
2ff48e98 90 if (r < 0)
5d0fe423 91 log_warning_errno(r, "IP_TRANSPARENT/IPV6_TRANSPARENT failed: %m");
cc527a47
KS
92 }
93 }
94
2ff48e98
LP
95 r = setsockopt_int(fd, SOL_SOCKET, SO_REUSEADDR, true);
96 if (r < 0)
97 return r;
cc527a47 98
294d46f1
LP
99 p = socket_address_get_path(a);
100 if (p) {
cc527a47 101 /* Create parents */
294d46f1 102 (void) mkdir_parents_label(p, directory_mode);
cc527a47 103
175a3d25 104 /* Enforce the right access mode for the socket */
825546ef
ZJS
105 RUN_WITH_UMASK(~socket_mode) {
106 r = mac_selinux_bind(fd, &a->sockaddr.sa, a->size);
107 if (r == -EADDRINUSE) {
108 /* Unlink and try again */
706d7c27
LP
109
110 if (unlink(p) < 0)
111 return r; /* didn't work, return original error */
112
113 r = mac_selinux_bind(fd, &a->sockaddr.sa, a->size);
114 }
115 if (r < 0)
825546ef 116 return r;
cc527a47 117 }
825546ef
ZJS
118 } else {
119 if (bind(fd, &a->sockaddr.sa, a->size) < 0)
120 return -errno;
121 }
cc527a47
KS
122
123 if (socket_address_can_accept(a))
124 if (listen(fd, backlog) < 0)
175a3d25 125 return -errno;
cc527a47 126
5b5e6dea
LP
127 /* Let's trigger an inotify event on the socket node, so that anyone waiting for this socket to be connectable
128 * gets notified */
129 if (p)
130 (void) touch(p);
131
d7a0f1f4 132 return TAKE_FD(fd);
cc527a47 133}