summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/basic/calendarspec.c8
-rw-r--r--src/libsystemd-network/dhcp-internal.h4
-rw-r--r--src/libsystemd-network/dhcp-network.c14
-rw-r--r--src/libsystemd-network/network-internal.c33
-rw-r--r--src/libsystemd-network/sd-dhcp-client.c2
-rw-r--r--src/libsystemd-network/sd-dhcp-server.c2
-rw-r--r--src/libsystemd-network/test-dhcp-client.c2
-rw-r--r--src/test/test-calendarspec.c3
8 files changed, 48 insertions, 20 deletions
diff --git a/src/basic/calendarspec.c b/src/basic/calendarspec.c
index 8b57de4744..514587d237 100644
--- a/src/basic/calendarspec.c
+++ b/src/basic/calendarspec.c
@@ -752,12 +752,8 @@ static int parse_calendar_time(const char **p, CalendarSpec *c) {
goto fail;
/* Already at the end? Then it's hours and minutes, and seconds are 0 */
- if (*t == 0) {
- if (m != NULL)
- goto null_second;
-
- goto finish;
- }
+ if (*t == 0)
+ goto null_second;
if (*t != ':') {
r = -EINVAL;
diff --git a/src/libsystemd-network/dhcp-internal.h b/src/libsystemd-network/dhcp-internal.h
index 5aa8aca426..3fdf02da3e 100644
--- a/src/libsystemd-network/dhcp-internal.h
+++ b/src/libsystemd-network/dhcp-internal.h
@@ -30,11 +30,11 @@
#include "dhcp-protocol.h"
#include "socket-util.h"
-int dhcp_network_bind_raw_socket(int index, union sockaddr_union *link,
+int dhcp_network_bind_raw_socket(int ifindex, union sockaddr_union *link,
uint32_t xid, const uint8_t *mac_addr,
size_t mac_addr_len, uint16_t arp_type,
uint16_t port);
-int dhcp_network_bind_udp_socket(be32_t address, uint16_t port);
+int dhcp_network_bind_udp_socket(int ifindex, be32_t address, uint16_t port);
int dhcp_network_send_raw_socket(int s, const union sockaddr_union *link,
const void *packet, size_t len);
int dhcp_network_send_udp_socket(int s, be32_t address, uint16_t port,
diff --git a/src/libsystemd-network/dhcp-network.c b/src/libsystemd-network/dhcp-network.c
index 3c85bb0b54..65405dcce0 100644
--- a/src/libsystemd-network/dhcp-network.c
+++ b/src/libsystemd-network/dhcp-network.c
@@ -19,6 +19,7 @@
#include <errno.h>
#include <net/ethernet.h>
+#include <net/if.h>
#include <net/if_arp.h>
#include <stdio.h>
#include <string.h>
@@ -156,13 +157,14 @@ int dhcp_network_bind_raw_socket(int ifindex, union sockaddr_union *link,
bcast_addr, &eth_mac, arp_type, dhcp_hlen, port);
}
-int dhcp_network_bind_udp_socket(be32_t address, uint16_t port) {
+int dhcp_network_bind_udp_socket(int ifindex, be32_t address, uint16_t port) {
union sockaddr_union src = {
.in.sin_family = AF_INET,
.in.sin_port = htobe16(port),
.in.sin_addr.s_addr = address,
};
_cleanup_close_ int s = -1;
+ char ifname[IF_NAMESIZE] = "";
int r, on = 1, tos = IPTOS_CLASS_CS6;
s = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
@@ -177,6 +179,15 @@ int dhcp_network_bind_udp_socket(be32_t address, uint16_t port) {
if (r < 0)
return -errno;
+ if (ifindex > 0) {
+ if (if_indextoname(ifindex, ifname) == 0)
+ return -errno;
+
+ r = setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, ifname, strlen(ifname));
+ if (r < 0)
+ return -errno;
+ }
+
if (address == INADDR_ANY) {
r = setsockopt(s, IPPROTO_IP, IP_PKTINFO, &on, sizeof(on));
if (r < 0)
@@ -185,6 +196,7 @@ int dhcp_network_bind_udp_socket(be32_t address, uint16_t port) {
r = setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
if (r < 0)
return -errno;
+
} else {
r = setsockopt(s, IPPROTO_IP, IP_FREEBIND, &on, sizeof(on));
if (r < 0)
diff --git a/src/libsystemd-network/network-internal.c b/src/libsystemd-network/network-internal.c
index 9d78b953fc..0827995bb0 100644
--- a/src/libsystemd-network/network-internal.c
+++ b/src/libsystemd-network/network-internal.c
@@ -86,6 +86,27 @@ int net_get_unique_predictable_data(struct udev_device *device, uint64_t *result
return 0;
}
+static bool net_condition_test_strv(char * const *raw_patterns, char *string) {
+ if (strv_isempty(raw_patterns))
+ return true;
+
+ /* If the patterns begin with "!", edit it out and negate the test. */
+ if (raw_patterns[0][0] == '!') {
+ char **patterns;
+ unsigned i, length;
+
+ length = strv_length(raw_patterns) + 1; /* Include the NULL. */
+ patterns = newa(char*, length);
+ patterns[0] = raw_patterns[0] + 1; /* Skip the "!". */
+ for (i = 1; i < length; i++)
+ patterns[i] = raw_patterns[i];
+
+ return !string || !strv_fnmatch(patterns, string, 0);
+ }
+
+ return string && strv_fnmatch(raw_patterns, string, 0);
+}
+
bool net_match_config(const struct ether_addr *match_mac,
char * const *match_paths,
char * const *match_drivers,
@@ -117,20 +138,16 @@ bool net_match_config(const struct ether_addr *match_mac,
if (match_mac && (!dev_mac || memcmp(match_mac, dev_mac, ETH_ALEN)))
return false;
- if (!strv_isempty(match_paths) &&
- (!dev_path || !strv_fnmatch(match_paths, dev_path, 0)))
+ if (!net_condition_test_strv(match_paths, dev_path))
return false;
- if (!strv_isempty(match_drivers) &&
- (!dev_driver || !strv_fnmatch(match_drivers, dev_driver, 0)))
+ if (!net_condition_test_strv(match_drivers, dev_driver))
return false;
- if (!strv_isempty(match_types) &&
- (!dev_type || !strv_fnmatch_or_empty(match_types, dev_type, 0)))
+ if (!net_condition_test_strv(match_types, dev_type))
return false;
- if (!strv_isempty(match_names) &&
- (!dev_name || !strv_fnmatch_or_empty(match_names, dev_name, 0)))
+ if (!net_condition_test_strv(match_names, dev_name))
return false;
return true;
diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c
index 1423264806..b4bf75a3dc 100644
--- a/src/libsystemd-network/sd-dhcp-client.c
+++ b/src/libsystemd-network/sd-dhcp-client.c
@@ -1546,7 +1546,7 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, i
goto error;
}
- r = dhcp_network_bind_udp_socket(client->lease->address, client->port);
+ r = dhcp_network_bind_udp_socket(client->ifindex, client->lease->address, client->port);
if (r < 0) {
log_dhcp_client(client, "could not bind UDP socket");
goto error;
diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c
index f16314a37f..0e57ab6b69 100644
--- a/src/libsystemd-network/sd-dhcp-server.c
+++ b/src/libsystemd-network/sd-dhcp-server.c
@@ -1022,7 +1022,7 @@ int sd_dhcp_server_start(sd_dhcp_server *server) {
}
server->fd_raw = r;
- r = dhcp_network_bind_udp_socket(INADDR_ANY, DHCP_PORT_SERVER);
+ r = dhcp_network_bind_udp_socket(server->ifindex, INADDR_ANY, DHCP_PORT_SERVER);
if (r < 0) {
sd_dhcp_server_stop(server);
return r;
diff --git a/src/libsystemd-network/test-dhcp-client.c b/src/libsystemd-network/test-dhcp-client.c
index c10ca74b86..f5f1284e6d 100644
--- a/src/libsystemd-network/test-dhcp-client.c
+++ b/src/libsystemd-network/test-dhcp-client.c
@@ -203,7 +203,7 @@ int dhcp_network_bind_raw_socket(
return test_fd[0];
}
-int dhcp_network_bind_udp_socket(be32_t address, uint16_t port) {
+int dhcp_network_bind_udp_socket(int ifindex, be32_t address, uint16_t port) {
int fd;
fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC, 0);
diff --git a/src/test/test-calendarspec.c b/src/test/test-calendarspec.c
index b3d1160ea7..b8320b081b 100644
--- a/src/test/test-calendarspec.c
+++ b/src/test/test-calendarspec.c
@@ -186,6 +186,9 @@ int main(int argc, char* argv[]) {
test_one("Monday *-*-*", "Mon *-*-* 00:00:00");
test_one("*-*-*", "*-*-* 00:00:00");
test_one("*:*:*", "*-*-* *:*:*");
+ test_one("*:*", "*-*-* *:*:00");
+ test_one("12:*", "*-*-* 12:*:00");
+ test_one("*:30", "*-*-* *:30:00");
test_next("2016-03-27 03:17:00", "", 12345, 1459048620000000);
test_next("2016-03-27 03:17:00", "CET", 12345, 1459041420000000);