Add ip protocol token to SocketBind{Allow|Deny}= property parser.
Use parse_socket_bind_item helper.
Replace int32_t with int in cgroup item for socket-bind as it was
requested in [0].
Update tests.
[0] https://github.com/systemd/systemd/pull/19942#discussion_r652150024
#include "fileio.h"
#include "fs-util.h"
#include "io-util.h"
+#include "ip-protocol-list.h"
#include "limits-util.h"
#include "nulstr-util.h"
#include "parse-util.h"
}
void cgroup_context_dump_socket_bind_item(const CGroupSocketBindItem *item, FILE *f) {
- const char *family, *colon;
+ const char *family, *colon1, *protocol = "", *colon2 = "";
family = strempty(af_to_ipv4_ipv6(item->address_family));
- colon = isempty(family) ? "" : ":";
+ colon1 = isempty(family) ? "" : ":";
+
+ if (item->ip_protocol != 0) {
+ protocol = ip_protocol_to_tcp_udp(item->ip_protocol);
+ colon2 = ":";
+ }
if (item->nr_ports == 0)
- fprintf(f, " %s%sany", family, colon);
+ fprintf(f, " %s%s%s%sany", family, colon1, protocol, colon2);
else if (item->nr_ports == 1)
- fprintf(f, " %s%s%" PRIu16, family, colon, item->port_min);
+ fprintf(f, " %s%s%s%s%" PRIu16, family, colon1, protocol, colon2, item->port_min);
else {
uint16_t port_max = item->port_min + item->nr_ports - 1;
- fprintf(f, " %s%s%" PRIu16 "-%" PRIu16, family, colon, item->port_min, port_max);
+ fprintf(f, " %s%s%s%s%" PRIu16 "-%" PRIu16, family, colon1, protocol, colon2,
+ item->port_min, port_max);
}
}
struct CGroupSocketBindItem {
LIST_FIELDS(CGroupSocketBindItem, socket_bind_items);
- int32_t address_family;
- int32_t ip_protocol;
+ int address_family;
+ int ip_protocol;
uint16_t nr_ports;
uint16_t port_min;
};
#include "log.h"
#include "mountpoint-util.h"
#include "nulstr-util.h"
+#include "parse-socket-bind-item.h"
#include "parse-util.h"
#include "path-util.h"
#include "percent-util.h"
void *data,
void *userdata) {
_cleanup_free_ CGroupSocketBindItem *item = NULL;
- const char *user_port;
- uint16_t nr_ports = 0, port_min = 0;
CGroupSocketBindItem **head = data;
- _cleanup_free_ char *word = NULL;
- int af, r;
+ uint16_t nr_ports, port_min;
+ int af, ip_protocol, r;
if (isempty(rvalue)) {
cgroup_context_remove_socket_bind(head);
return 0;
}
- r = extract_first_word(&rvalue, &word, ":", 0);
+ r = parse_socket_bind_item(rvalue, &af, &ip_protocol, &nr_ports, &port_min);
if (r == -ENOMEM)
return log_oom();
- if (r <= 0) {
+ if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Unable to parse %s= assignment, ignoring: %s", lvalue, rvalue);
return 0;
}
- if (rvalue) {
- af = af_from_ipv4_ipv6(word);
- if (af == AF_UNSPEC) {
- log_syntax(unit, LOG_WARNING, filename, line, 0,
- "Only \"ipv4\" and \"ipv6\" protocols are supported, ignoring.");
- return 0;
- }
-
- user_port = rvalue;
- } else {
- af = AF_UNSPEC;
- user_port = word;
- }
-
- if (!streq(user_port, "any")) {
- uint16_t port_max;
-
- r = parse_ip_port_range(user_port, &port_min, &port_max);
- if (r == -ENOMEM)
- return log_oom();
- if (r < 0) {
- log_syntax(unit, LOG_WARNING, filename, line, r,
- "Invalid port or port range, ignoring: %m");
- return 0;
- }
-
- nr_ports = 1 + port_max - port_min;
- }
-
item = new(CGroupSocketBindItem, 1);
if (!item)
return log_oom();
*item = (CGroupSocketBindItem) {
.address_family = af,
- /* No ip protocol specified for now. */
- .ip_protocol = 0,
+ .ip_protocol = ip_protocol,
.nr_ports = nr_ports,
.port_min = port_min,
};
assert_se(test_socket_bind(m, "socket_bind_test.service", netcat_path, "6666", STRV_MAKE("6667", "6668", ""), STRV_MAKE("any")) >= 0);
assert_se(test_socket_bind(m, "socket_bind_test.service", netcat_path, "7777", STRV_MAKE_EMPTY, STRV_MAKE_EMPTY) >= 0);
assert_se(test_socket_bind(m, "socket_bind_test.service", netcat_path, "8888", STRV_MAKE("any"), STRV_MAKE("any")) >= 0);
+ assert_se(test_socket_bind(m, "socket_bind_test.service", netcat_path, "8888", STRV_MAKE("ipv6:tcp:8888-8889"), STRV_MAKE("any")) >= 0);
+ assert_se(test_socket_bind(m, "socket_bind_test.service", netcat_path, "10000", STRV_MAKE("ipv6:udp:9999-10000"), STRV_MAKE("any")) >= 0);
+ assert_se(test_socket_bind(m, "socket_bind_test.service", netcat_path, "6666", STRV_MAKE("ipv4:tcp:6666"), STRV_MAKE("any")) >= 0);
+ assert_se(test_socket_bind(m, "socket_bind_test.service", netcat_path, "6666", STRV_MAKE("ipv4:udp:6666"), STRV_MAKE("any")) >= 0);
+ assert_se(test_socket_bind(m, "socket_bind_test.service", netcat_path, "6666", STRV_MAKE("tcp:6666"), STRV_MAKE("any")) >= 0);
return 0;
}