mirror of
https://github.com/systemd/systemd
synced 2026-03-31 12:14:57 +02:00
Compare commits
7 Commits
a2ca8c54cc
...
231c7645ca
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
231c7645ca | ||
|
|
952d873f56 | ||
|
|
a4a1385e07 | ||
|
|
888f57c11c | ||
|
|
ed08ed4a45 | ||
|
|
26a8be48bc | ||
|
|
dc317a9aed |
@ -1023,3 +1023,18 @@ int sd_netlink_add_match(
|
|||||||
return netlink_add_match_internal(rtnl, ret_slot, groups, n_groups, type, 0, callback,
|
return netlink_add_match_internal(rtnl, ret_slot, groups, n_groups, type, 0, callback,
|
||||||
destroy_callback, userdata, description);
|
destroy_callback, userdata, description);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int sd_netlink_attach_filter(sd_netlink *nl, size_t len, struct sock_filter *filter) {
|
||||||
|
assert_return(nl, -EINVAL);
|
||||||
|
assert_return(len == 0 || filter, -EINVAL);
|
||||||
|
|
||||||
|
if (setsockopt(nl->fd, SOL_SOCKET,
|
||||||
|
len == 0 ? SO_DETACH_FILTER : SO_ATTACH_FILTER,
|
||||||
|
&(struct sock_fprog) {
|
||||||
|
.len = len,
|
||||||
|
.filter = filter,
|
||||||
|
}, sizeof(struct sock_fprog)) < 0)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|||||||
@ -263,6 +263,40 @@ static int manager_connect_genl(Manager *m) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int manager_setup_rtnl_filter(Manager *manager) {
|
||||||
|
struct sock_filter filter[] = {
|
||||||
|
/* Check the packet length. */
|
||||||
|
BPF_STMT(BPF_LD + BPF_W + BPF_LEN, 0), /* A <- packet length */
|
||||||
|
BPF_JUMP(BPF_JMP + BPF_JGE + BPF_K, sizeof(struct nlmsghdr), 1, 0), /* A (packet length) >= sizeof(struct nlmsghdr) ? */
|
||||||
|
BPF_STMT(BPF_RET + BPF_K, 0), /* reject */
|
||||||
|
/* Always accept multipart message. */
|
||||||
|
BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(struct nlmsghdr, nlmsg_flags)), /* A <- message flags */
|
||||||
|
BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, htobe16(NLM_F_MULTI), 0, 1), /* message flags has NLM_F_MULTI ? */
|
||||||
|
BPF_STMT(BPF_RET + BPF_K, UINT32_MAX), /* accept */
|
||||||
|
/* Accept all message types except for RTM_NEWNEIGH or RTM_DELNEIGH. */
|
||||||
|
BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(struct nlmsghdr, nlmsg_type)), /* A <- message type */
|
||||||
|
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, htobe16(RTM_NEWNEIGH), 2, 0), /* message type == RTM_NEWNEIGH ? */
|
||||||
|
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, htobe16(RTM_DELNEIGH), 1, 0), /* message type == RTM_DELNEIGH ? */
|
||||||
|
BPF_STMT(BPF_RET + BPF_K, UINT32_MAX), /* accept */
|
||||||
|
/* Check the packet length. */
|
||||||
|
BPF_STMT(BPF_LD + BPF_W + BPF_LEN, 0), /* A <- packet length */
|
||||||
|
BPF_JUMP(BPF_JMP + BPF_JGE + BPF_K, sizeof(struct nlmsghdr) + sizeof(struct ndmsg), 1, 0),
|
||||||
|
/* packet length >= sizeof(struct nlmsghdr) + sizeof(struct ndmsg) ? */
|
||||||
|
BPF_STMT(BPF_RET + BPF_K, 0), /* reject */
|
||||||
|
/* Reject the message when the neighbor state does not have NUD_PERMANENT flag. */
|
||||||
|
BPF_STMT(BPF_LD + BPF_H + BPF_ABS, sizeof(struct nlmsghdr) + offsetof(struct ndmsg, ndm_state)),
|
||||||
|
/* A <- neighbor state */
|
||||||
|
BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, htobe16(NUD_PERMANENT), 1, 0), /* neighbor state has NUD_PERMANENT ? */
|
||||||
|
BPF_STMT(BPF_RET + BPF_K, 0), /* reject */
|
||||||
|
BPF_STMT(BPF_RET + BPF_K, UINT32_MAX), /* accept */
|
||||||
|
};
|
||||||
|
|
||||||
|
assert(manager);
|
||||||
|
assert(manager->rtnl);
|
||||||
|
|
||||||
|
return sd_netlink_attach_filter(manager->rtnl, ELEMENTSOF(filter), filter);
|
||||||
|
}
|
||||||
|
|
||||||
static int manager_connect_rtnl(Manager *m) {
|
static int manager_connect_rtnl(Manager *m) {
|
||||||
int fd, r;
|
int fd, r;
|
||||||
|
|
||||||
@ -337,7 +371,7 @@ static int manager_connect_rtnl(Manager *m) {
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
return 0;
|
return manager_setup_rtnl_filter(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int manager_dirty_handler(sd_event_source *s, void *userdata) {
|
static int manager_dirty_handler(sd_event_source *s, void *userdata) {
|
||||||
|
|||||||
@ -21,6 +21,7 @@
|
|||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <net/ethernet.h>
|
#include <net/ethernet.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
#include <linux/filter.h>
|
||||||
#include <linux/neighbour.h>
|
#include <linux/neighbour.h>
|
||||||
#include <linux/rtnetlink.h>
|
#include <linux/rtnetlink.h>
|
||||||
|
|
||||||
@ -68,6 +69,7 @@ int sd_netlink_add_match(sd_netlink *nl, sd_netlink_slot **ret_slot, uint16_t ma
|
|||||||
|
|
||||||
int sd_netlink_attach_event(sd_netlink *nl, sd_event *e, int64_t priority);
|
int sd_netlink_attach_event(sd_netlink *nl, sd_event *e, int64_t priority);
|
||||||
int sd_netlink_detach_event(sd_netlink *nl);
|
int sd_netlink_detach_event(sd_netlink *nl);
|
||||||
|
int sd_netlink_attach_filter(sd_netlink *nl, size_t len, struct sock_filter *filter);
|
||||||
|
|
||||||
/* message */
|
/* message */
|
||||||
int sd_netlink_message_append_string(sd_netlink_message *m, unsigned short type, const char *data);
|
int sd_netlink_message_append_string(sd_netlink_message *m, unsigned short type, const char *data);
|
||||||
|
|||||||
@ -21,8 +21,9 @@ networkd_ci_path='/run/networkd-ci'
|
|||||||
network_sysctl_ipv6_path='/proc/sys/net/ipv6/conf'
|
network_sysctl_ipv6_path='/proc/sys/net/ipv6/conf'
|
||||||
network_sysctl_ipv4_path='/proc/sys/net/ipv4/conf'
|
network_sysctl_ipv4_path='/proc/sys/net/ipv4/conf'
|
||||||
|
|
||||||
dnsmasq_pid_file='/run/networkd-ci/test-test-dnsmasq.pid'
|
dnsmasq_pid_file='/run/networkd-ci/test-dnsmasq.pid'
|
||||||
dnsmasq_log_file='/run/networkd-ci/test-dnsmasq-log-file'
|
dnsmasq_log_file='/run/networkd-ci/test-dnsmasq.log'
|
||||||
|
dnsmasq_lease_file='/run/networkd-ci/test-dnsmasq.lease'
|
||||||
|
|
||||||
systemd_lib_paths=['/usr/lib/systemd', '/lib/systemd']
|
systemd_lib_paths=['/usr/lib/systemd', '/lib/systemd']
|
||||||
which_paths=':'.join(systemd_lib_paths + os.getenv('PATH', os.defpath).lstrip(':').split(':'))
|
which_paths=':'.join(systemd_lib_paths + os.getenv('PATH', os.defpath).lstrip(':').split(':'))
|
||||||
@ -474,10 +475,10 @@ def remove_networkd_conf_dropin(dropins):
|
|||||||
os.remove(os.path.join(networkd_conf_dropin_path, dropin))
|
os.remove(os.path.join(networkd_conf_dropin_path, dropin))
|
||||||
|
|
||||||
def start_dnsmasq(additional_options='', ipv4_range='192.168.5.10,192.168.5.200', ipv6_range='2600::10,2600::20', lease_time='1h'):
|
def start_dnsmasq(additional_options='', ipv4_range='192.168.5.10,192.168.5.200', ipv6_range='2600::10,2600::20', lease_time='1h'):
|
||||||
dnsmasq_command = f'dnsmasq -8 /var/run/networkd-ci/test-dnsmasq-log-file --log-queries=extra --log-dhcp --pid-file=/var/run/networkd-ci/test-test-dnsmasq.pid --conf-file=/dev/null --interface=veth-peer --enable-ra --dhcp-range={ipv6_range},{lease_time} --dhcp-range={ipv4_range},{lease_time} -R --dhcp-leasefile=/var/run/networkd-ci/lease --dhcp-option=26,1492 --dhcp-option=option:router,192.168.5.1 --port=0 ' + additional_options
|
dnsmasq_command = f'dnsmasq -8 {dnsmasq_log_file} --log-queries=extra --log-dhcp --pid-file={dnsmasq_pid_file} --conf-file=/dev/null --interface=veth-peer --enable-ra --dhcp-range={ipv6_range},{lease_time} --dhcp-range={ipv4_range},{lease_time} -R --dhcp-leasefile={dnsmasq_lease_file} --dhcp-option=26,1492 --dhcp-option=option:router,192.168.5.1 --port=0 ' + additional_options
|
||||||
check_output(dnsmasq_command)
|
check_output(dnsmasq_command)
|
||||||
|
|
||||||
def stop_dnsmasq(pid_file):
|
def stop_by_pid_file(pid_file):
|
||||||
if os.path.exists(pid_file):
|
if os.path.exists(pid_file):
|
||||||
with open(pid_file, 'r') as f:
|
with open(pid_file, 'r') as f:
|
||||||
pid = f.read().rstrip(' \t\r\n\0')
|
pid = f.read().rstrip(' \t\r\n\0')
|
||||||
@ -485,6 +486,9 @@ def stop_dnsmasq(pid_file):
|
|||||||
|
|
||||||
os.remove(pid_file)
|
os.remove(pid_file)
|
||||||
|
|
||||||
|
def stop_dnsmasq():
|
||||||
|
stop_by_pid_file(dnsmasq_pid_file)
|
||||||
|
|
||||||
def search_words_in_dnsmasq_log(words, show_all=False):
|
def search_words_in_dnsmasq_log(words, show_all=False):
|
||||||
if os.path.exists(dnsmasq_log_file):
|
if os.path.exists(dnsmasq_log_file):
|
||||||
with open (dnsmasq_log_file) as in_file:
|
with open (dnsmasq_log_file) as in_file:
|
||||||
@ -498,11 +502,11 @@ def search_words_in_dnsmasq_log(words, show_all=False):
|
|||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def remove_lease_file():
|
def remove_dnsmasq_lease_file():
|
||||||
if os.path.exists(os.path.join(networkd_ci_path, 'lease')):
|
if os.path.exists(dnsmasq_lease_file):
|
||||||
os.remove(os.path.join(networkd_ci_path, 'lease'))
|
os.remove(dnsmasq_lease_file)
|
||||||
|
|
||||||
def remove_log_file():
|
def remove_dnsmasq_log_file():
|
||||||
if os.path.exists(dnsmasq_log_file):
|
if os.path.exists(dnsmasq_log_file):
|
||||||
os.remove(dnsmasq_log_file)
|
os.remove(dnsmasq_log_file)
|
||||||
|
|
||||||
@ -4034,14 +4038,16 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
|
|||||||
'static.network']
|
'static.network']
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
stop_dnsmasq(dnsmasq_pid_file)
|
stop_dnsmasq()
|
||||||
|
remove_dnsmasq_lease_file()
|
||||||
|
remove_dnsmasq_log_file()
|
||||||
remove_links(self.links)
|
remove_links(self.links)
|
||||||
stop_networkd(show_logs=False)
|
stop_networkd(show_logs=False)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
stop_dnsmasq(dnsmasq_pid_file)
|
stop_dnsmasq()
|
||||||
remove_lease_file()
|
remove_dnsmasq_lease_file()
|
||||||
remove_log_file()
|
remove_dnsmasq_log_file()
|
||||||
remove_links(self.links)
|
remove_links(self.links)
|
||||||
remove_unit_from_networkd_path(self.units)
|
remove_unit_from_networkd_path(self.units)
|
||||||
stop_networkd(show_logs=True)
|
stop_networkd(show_logs=True)
|
||||||
@ -4092,7 +4098,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
|
|||||||
self.assertRegex(output, r'192.168.5.6 proto dhcp scope link src 192.168.5.181 metric 1024')
|
self.assertRegex(output, r'192.168.5.6 proto dhcp scope link src 192.168.5.181 metric 1024')
|
||||||
self.assertRegex(output, r'192.168.5.7 proto dhcp scope link src 192.168.5.181 metric 1024')
|
self.assertRegex(output, r'192.168.5.7 proto dhcp scope link src 192.168.5.181 metric 1024')
|
||||||
|
|
||||||
stop_dnsmasq(dnsmasq_pid_file)
|
stop_dnsmasq()
|
||||||
start_dnsmasq(additional_options='--dhcp-option=option:dns-server,192.168.5.1,192.168.5.7,192.168.5.8', lease_time='2m')
|
start_dnsmasq(additional_options='--dhcp-option=option:dns-server,192.168.5.1,192.168.5.7,192.168.5.8', lease_time='2m')
|
||||||
|
|
||||||
# Sleep for 120 sec as the dnsmasq minimum lease time can only be set to 120
|
# Sleep for 120 sec as the dnsmasq minimum lease time can only be set to 120
|
||||||
@ -4330,7 +4336,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
|
|||||||
self.assertRegex(output, r'192.168.6.0/24 proto static')
|
self.assertRegex(output, r'192.168.6.0/24 proto static')
|
||||||
self.assertRegex(output, r'192.168.7.0/24 proto static')
|
self.assertRegex(output, r'192.168.7.0/24 proto static')
|
||||||
|
|
||||||
stop_dnsmasq(dnsmasq_pid_file)
|
stop_dnsmasq()
|
||||||
start_dnsmasq(ipv4_range='192.168.5.210,192.168.5.220', lease_time='2m')
|
start_dnsmasq(ipv4_range='192.168.5.210,192.168.5.220', lease_time='2m')
|
||||||
|
|
||||||
# Sleep for 120 sec as the dnsmasq minimum lease time can only be set to 120
|
# Sleep for 120 sec as the dnsmasq minimum lease time can only be set to 120
|
||||||
@ -4363,7 +4369,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
|
|||||||
self.assertRegex(output, r'2600::/64 proto ra metric 1024')
|
self.assertRegex(output, r'2600::/64 proto ra metric 1024')
|
||||||
self.assertRegex(output, r'2600:0:0:1::/64 proto static metric 1024 pref medium')
|
self.assertRegex(output, r'2600:0:0:1::/64 proto static metric 1024 pref medium')
|
||||||
|
|
||||||
stop_dnsmasq(dnsmasq_pid_file)
|
stop_dnsmasq()
|
||||||
start_dnsmasq(ipv6_range='2600::30,2600::40', lease_time='2m')
|
start_dnsmasq(ipv6_range='2600::30,2600::40', lease_time='2m')
|
||||||
|
|
||||||
# Sleep for 120 sec as the dnsmasq minimum lease time can only be set to 120
|
# Sleep for 120 sec as the dnsmasq minimum lease time can only be set to 120
|
||||||
@ -4393,7 +4399,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
|
|||||||
self.assertRegex(output, r'192.168.5.*')
|
self.assertRegex(output, r'192.168.5.*')
|
||||||
|
|
||||||
# Stopping dnsmasq as networkd won't be allowed to renew the DHCP lease.
|
# Stopping dnsmasq as networkd won't be allowed to renew the DHCP lease.
|
||||||
stop_dnsmasq(dnsmasq_pid_file)
|
stop_dnsmasq()
|
||||||
|
|
||||||
# Sleep for 120 sec as the dnsmasq minimum lease time can only be set to 120
|
# Sleep for 120 sec as the dnsmasq minimum lease time can only be set to 120
|
||||||
print('Wait for the dynamic address to be expired')
|
print('Wait for the dynamic address to be expired')
|
||||||
@ -4443,7 +4449,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
|
|||||||
print(output)
|
print(output)
|
||||||
self.assertRegex(output, r'192.168.5.*')
|
self.assertRegex(output, r'192.168.5.*')
|
||||||
|
|
||||||
stop_dnsmasq(dnsmasq_pid_file)
|
stop_dnsmasq()
|
||||||
check_output('systemctl stop systemd-networkd.socket')
|
check_output('systemctl stop systemd-networkd.socket')
|
||||||
check_output('systemctl stop systemd-networkd.service')
|
check_output('systemctl stop systemd-networkd.service')
|
||||||
|
|
||||||
@ -4686,7 +4692,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
|
|||||||
self.assertRegex(output, f'default via 192.168.5.1 proto dhcp src {address1} metric 1024')
|
self.assertRegex(output, f'default via 192.168.5.1 proto dhcp src {address1} metric 1024')
|
||||||
self.assertRegex(output, f'192.168.5.1 proto dhcp scope link src {address1} metric 1024')
|
self.assertRegex(output, f'192.168.5.1 proto dhcp scope link src {address1} metric 1024')
|
||||||
|
|
||||||
stop_dnsmasq(dnsmasq_pid_file)
|
stop_dnsmasq()
|
||||||
start_dnsmasq(ipv4_range='192.168.5.200,192.168.5.250', lease_time='2m')
|
start_dnsmasq(ipv4_range='192.168.5.200,192.168.5.250', lease_time='2m')
|
||||||
|
|
||||||
print('Wait for the dynamic address to be expired')
|
print('Wait for the dynamic address to be expired')
|
||||||
@ -4839,7 +4845,6 @@ class NetworkdIPv6PrefixTests(unittest.TestCase, Utilities):
|
|||||||
stop_networkd(show_logs=False)
|
stop_networkd(show_logs=False)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
remove_log_file()
|
|
||||||
remove_links(self.links)
|
remove_links(self.links)
|
||||||
remove_unit_from_networkd_path(self.units)
|
remove_unit_from_networkd_path(self.units)
|
||||||
stop_networkd(show_logs=True)
|
stop_networkd(show_logs=True)
|
||||||
@ -4928,7 +4933,6 @@ class NetworkdMTUTests(unittest.TestCase, Utilities):
|
|||||||
stop_networkd(show_logs=False)
|
stop_networkd(show_logs=False)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
remove_log_file()
|
|
||||||
remove_links(self.links)
|
remove_links(self.links)
|
||||||
remove_unit_from_networkd_path(self.units)
|
remove_unit_from_networkd_path(self.units)
|
||||||
stop_networkd(show_logs=True)
|
stop_networkd(show_logs=True)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user