1
0
mirror of https://github.com/systemd/systemd synced 2025-10-02 10:14:46 +02:00

Compare commits

..

6 Commits

Author SHA1 Message Date
Frantisek Sumsal
e4c9246fb3 Translated using Weblate (Serbian)
Currently translated at 66.6% (126 of 189 strings)

Co-authored-by: Frantisek Sumsal <frantisek@sumsal.cz>
Translate-URL: https://translate.fedoraproject.org/projects/systemd/master/sr/
Translation: systemd/main
2021-02-24 09:11:18 +09:00
Yu Watanabe
ebc98027fc
Merge pull request #18589 from yuwata/network-nexthop-drop-unnecessary-nexthops
network: drop unnecessary nexthops
2021-02-24 09:07:57 +09:00
Yu Watanabe
9947c7bad1 test-network: add tests for dropping unnecessary nexthops 2021-02-23 22:48:12 +09:00
Yu Watanabe
25b82b6e0e network: nexthop: drop unnecessary nexthops
Similar to addresses or routes, this makes networkd drops unnecessary
nexthops on configuring links or when a link is dropped.
2021-02-23 22:47:11 +09:00
Yu Watanabe
0e9d129c16 network: nexthop: read protocol in received netlink message
Preparation of later commits.
2021-02-23 22:47:11 +09:00
Yu Watanabe
e64e052e17 sd-netlink: introduce sd_rtnl_message_nexthop_get_protocol() 2021-02-23 22:47:11 +09:00
8 changed files with 269 additions and 26 deletions

View File

@ -2,23 +2,23 @@
# #
# SOME DESCRIPTIVE TITLE. # SOME DESCRIPTIVE TITLE.
# This file is distributed under the same license as the PACKAGE package. # This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. # Frantisek Sumsal <frantisek@sumsal.cz>, 2021.
#
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-01-08 17:48+0100\n" "POT-Creation-Date: 2021-01-08 17:48+0100\n"
"PO-Revision-Date: 2018-02-18 22:03+0100\n" "PO-Revision-Date: 2021-02-23 22:40+0000\n"
"Last-Translator: Марко М. Костић <marko.m.kostic@gmail.com>\n" "Last-Translator: Frantisek Sumsal <frantisek@sumsal.cz>\n"
"Language-Team: \n" "Language-Team: Serbian <https://translate.fedoraproject.org/projects/systemd/"
"master/sr/>\n"
"Language: sr\n" "Language: sr\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 2.0.3\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" "X-Generator: Weblate 4.4.2\n"
#: src/core/org.freedesktop.systemd1.policy.in:22 #: src/core/org.freedesktop.systemd1.policy.in:22
msgid "Send passphrase back to system" msgid "Send passphrase back to system"
@ -334,22 +334,17 @@ msgstr ""
"систему да уради било шта приликом заклапања екрана." "систему да уради било шта приликом заклапања екрана."
#: src/login/org.freedesktop.login1.policy:117 #: src/login/org.freedesktop.login1.policy:117
#, fuzzy
#| msgid "Allow applications to inhibit system handling of the power key"
msgid "Allow applications to inhibit system handling of the reboot key" msgid "Allow applications to inhibit system handling of the reboot key"
msgstr "Дозволи програмима да спрече систему управљање дугметом за напајање" msgstr ""
"Дозволи програмима да спрече систему управљање дугметом за поновно покретање"
#: src/login/org.freedesktop.login1.policy:118 #: src/login/org.freedesktop.login1.policy:118
#, fuzzy
#| msgid ""
#| "Authentication is required for an application to inhibit system handling "
#| "of the power key."
msgid "" msgid ""
"Authentication is required for an application to inhibit system handling of " "Authentication is required for an application to inhibit system handling of "
"the reboot key." "the reboot key."
msgstr "" msgstr ""
"Потребно је да се идентификујете да бисте дозволили програму да спречи " "Потребно је да се идентификујете да бисте дозволили програму да спречи "
"систему управљање дугметом за напајање." "систему управљање дугметом за поновно покретање."
#: src/login/org.freedesktop.login1.policy:128 #: src/login/org.freedesktop.login1.policy:128
msgid "Allow non-logged-in user to run programs" msgid "Allow non-logged-in user to run programs"
@ -478,16 +473,12 @@ msgid "Halt the system while an application is inhibiting this"
msgstr "Заустави систем иако програм тражи да се спречи заустављање" msgstr "Заустави систем иако програм тражи да се спречи заустављање"
#: src/login/org.freedesktop.login1.policy:258 #: src/login/org.freedesktop.login1.policy:258
#, fuzzy
#| msgid ""
#| "Authentication is required to hibernate the system while an application "
#| "is inhibiting this."
msgid "" msgid ""
"Authentication is required to halt the system while an application is " "Authentication is required to halt the system while an application is "
"inhibiting this." "inhibiting this."
msgstr "" msgstr ""
"Потребно је да се идентификујете да бисте успавали систем иако је програм " "Потребно је да се идентификујете да бисте обуставили систем иако је програм "
"затражио да се спречи успављивање система." "затражио да се спречи обустављање система."
#: src/login/org.freedesktop.login1.policy:268 #: src/login/org.freedesktop.login1.policy:268
msgid "Suspend the system" msgid "Suspend the system"
@ -578,11 +569,10 @@ msgid "Set the reboot \"reason\" in the kernel"
msgstr "" msgstr ""
#: src/login/org.freedesktop.login1.policy:353 #: src/login/org.freedesktop.login1.policy:353
#, fuzzy
#| msgid "Authentication is required to set the system timezone."
msgid "Authentication is required to set the reboot \"reason\" in the kernel." msgid "Authentication is required to set the reboot \"reason\" in the kernel."
msgstr "" msgstr ""
"Потребно је да се идентификујете да бисте поставили системску временску зону." "Потребно је да се идентификујете да бисте поставили \"разлог\" за поновно "
"поретање унутар језгра."
#: src/login/org.freedesktop.login1.policy:363 #: src/login/org.freedesktop.login1.policy:363
#, fuzzy #, fuzzy

View File

@ -329,6 +329,8 @@ int sd_rtnl_message_nexthop_get_family(const sd_netlink_message *m, uint8_t *fam
assert_return(m, -EINVAL); assert_return(m, -EINVAL);
assert_return(m->hdr, -EINVAL); assert_return(m->hdr, -EINVAL);
assert_return(rtnl_message_type_is_nexthop(m->hdr->nlmsg_type), -EINVAL);
assert_return(family, -EINVAL);
nhm = NLMSG_DATA(m->hdr); nhm = NLMSG_DATA(m->hdr);
*family = nhm->nh_family; *family = nhm->nh_family;
@ -336,6 +338,20 @@ int sd_rtnl_message_nexthop_get_family(const sd_netlink_message *m, uint8_t *fam
return 0; return 0;
} }
int sd_rtnl_message_nexthop_get_protocol(const sd_netlink_message *m, uint8_t *protocol) {
struct nhmsg *nhm;
assert_return(m, -EINVAL);
assert_return(m->hdr, -EINVAL);
assert_return(rtnl_message_type_is_nexthop(m->hdr->nlmsg_type), -EINVAL);
assert_return(protocol, -EINVAL);
nhm = NLMSG_DATA(m->hdr);
*protocol = nhm->nh_protocol;
return 0;
}
int sd_rtnl_message_neigh_set_flags(sd_netlink_message *m, uint8_t flags) { int sd_rtnl_message_neigh_set_flags(sd_netlink_message *m, uint8_t flags) {
struct ndmsg *ndm; struct ndmsg *ndm;

View File

@ -1980,6 +1980,10 @@ static int link_drop_foreign_config(Link *link) {
if (k < 0 && r >= 0) if (k < 0 && r >= 0)
r = k; r = k;
k = link_drop_foreign_nexthops(link);
if (k < 0 && r >= 0)
r = k;
k = manager_drop_foreign_routing_policy_rules(link->manager); k = manager_drop_foreign_routing_policy_rules(link->manager);
if (k < 0 && r >= 0) if (k < 0 && r >= 0)
r = k; r = k;
@ -2003,6 +2007,10 @@ static int link_drop_config(Link *link) {
if (k < 0 && r >= 0) if (k < 0 && r >= 0)
r = k; r = k;
k = link_drop_nexthops(link);
if (k < 0 && r >= 0)
r = k;
k = manager_drop_routing_policy_rules(link->manager, link); k = manager_drop_routing_policy_rules(link->manager, link);
if (k < 0 && r >= 0) if (k < 0 && r >= 0)
r = k; r = k;

View File

@ -102,6 +102,7 @@ static int nexthop_new_static(Network *network, const char *filename, unsigned s
static void nexthop_hash_func(const NextHop *nexthop, struct siphash *state) { static void nexthop_hash_func(const NextHop *nexthop, struct siphash *state) {
assert(nexthop); assert(nexthop);
siphash24_compress(&nexthop->protocol, sizeof(nexthop->protocol), state);
siphash24_compress(&nexthop->id, sizeof(nexthop->id), state); siphash24_compress(&nexthop->id, sizeof(nexthop->id), state);
siphash24_compress(&nexthop->blackhole, sizeof(nexthop->blackhole), state); siphash24_compress(&nexthop->blackhole, sizeof(nexthop->blackhole), state);
siphash24_compress(&nexthop->family, sizeof(nexthop->family), state); siphash24_compress(&nexthop->family, sizeof(nexthop->family), state);
@ -121,6 +122,10 @@ static void nexthop_hash_func(const NextHop *nexthop, struct siphash *state) {
static int nexthop_compare_func(const NextHop *a, const NextHop *b) { static int nexthop_compare_func(const NextHop *a, const NextHop *b) {
int r; int r;
r = CMP(a->protocol, b->protocol);
if (r != 0)
return r;
r = CMP(a->id, b->id); r = CMP(a->id, b->id);
if (r != 0) if (r != 0)
return r; return r;
@ -146,12 +151,23 @@ DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(
nexthop_compare_func, nexthop_compare_func,
nexthop_free); nexthop_free);
static bool nexthop_equal(const NextHop *a, const NextHop *b) {
if (a == b)
return true;
if (!a || !b)
return false;
return nexthop_compare_func(a, b) == 0;
}
static void nexthop_copy(NextHop *dest, const NextHop *src) { static void nexthop_copy(NextHop *dest, const NextHop *src) {
assert(dest); assert(dest);
assert(src); assert(src);
/* This only copies entries used in the above hash and compare functions. */ /* This only copies entries used in the above hash and compare functions. */
dest->protocol = src->protocol;
dest->id = src->id; dest->id = src->id;
dest->blackhole = src->blackhole; dest->blackhole = src->blackhole;
dest->family = src->family; dest->family = src->family;
@ -339,6 +355,56 @@ static void log_nexthop_debug(const NextHop *nexthop, uint32_t id, const char *s
} }
} }
static int nexthop_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
int r;
assert(m);
/* Note that link may be NULL. */
if (link && IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
return 1;
r = sd_netlink_message_get_errno(m);
if (r < 0 && r != -ENOENT)
log_link_message_warning_errno(link, m, r, "Could not drop nexthop, ignoring");
return 1;
}
static int nexthop_remove(const NextHop *nexthop, Manager *manager, Link *link) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
int r;
assert(nexthop);
assert(manager);
/* link may be NULL. */
if (nexthop->id == 0) {
log_link_debug(link, "Cannot remove nexthop without valid ID, ignoring.");
return 0;
}
log_nexthop_debug(nexthop, nexthop->id, "Removing", link);
r = sd_rtnl_message_new_nexthop(manager->rtnl, &req, RTM_DELNEXTHOP, AF_UNSPEC, RTPROT_UNSPEC);
if (r < 0)
return log_link_error_errno(link, r, "Could not create RTM_DELNEXTHOP message: %m");
r = sd_netlink_message_append_u32(req, NHA_ID, nexthop->id);
if (r < 0)
return log_link_error_errno(link, r, "Could not append NHA_ID attribute: %m");
r = netlink_call_async(manager->rtnl, NULL, req, nexthop_remove_handler,
link_netlink_destroy_callback, link);
if (r < 0)
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
link_ref(link); /* link may be NULL, link_ref() is OK with that */
return 0;
}
static int nexthop_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { static int nexthop_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
int r; int r;
@ -472,6 +538,124 @@ int link_set_nexthops(Link *link) {
return 0; return 0;
} }
static bool link_has_nexthop(const Link *link, const NextHop *nexthop) {
NextHop *net_nexthop;
assert(link);
assert(nexthop);
if (!link->network)
return false;
HASHMAP_FOREACH(net_nexthop, link->network->nexthops_by_section)
if (nexthop_equal(net_nexthop, nexthop))
return true;
return false;
}
static bool links_have_nexthop(const Manager *manager, const NextHop *nexthop, const Link *except) {
Link *link;
assert(manager);
HASHMAP_FOREACH(link, manager->links) {
if (link == except)
continue;
if (link_has_nexthop(link, nexthop))
return true;
}
return false;
}
static int manager_drop_nexthops_internal(Manager *manager, bool foreign, const Link *except) {
NextHop *nexthop;
Set *nexthops;
int k, r = 0;
assert(manager);
nexthops = foreign ? manager->nexthops_foreign : manager->nexthops;
SET_FOREACH(nexthop, nexthops) {
/* do not touch nexthop created by the kernel */
if (nexthop->protocol == RTPROT_KERNEL)
continue;
/* The nexthop will be configured later, or already configured by a link. */
if (links_have_nexthop(manager, nexthop, except))
continue;
/* The existing links do not have the nexthop. Let's drop this now. It may be
* re-configured later. */
k = nexthop_remove(nexthop, manager, NULL);
if (k < 0 && r >= 0)
r = k;
}
return r;
}
static int manager_drop_foreign_nexthops(Manager *manager) {
return manager_drop_nexthops_internal(manager, true, NULL);
}
static int manager_drop_nexthops(Manager *manager, const Link *except) {
return manager_drop_nexthops_internal(manager, false, except);
}
int link_drop_foreign_nexthops(Link *link) {
NextHop *nexthop;
int k, r = 0;
assert(link);
assert(link->manager);
SET_FOREACH(nexthop, link->nexthops_foreign) {
/* do not touch nexthop created by the kernel */
if (nexthop->protocol == RTPROT_KERNEL)
continue;
if (link_has_nexthop(link, nexthop))
k = nexthop_add(link, nexthop, NULL);
else
k = nexthop_remove(nexthop, link->manager, link);
if (k < 0 && r >= 0)
r = k;
}
k = manager_drop_foreign_nexthops(link->manager);
if (k < 0 && r >= 0)
r = k;
return r;
}
int link_drop_nexthops(Link *link) {
NextHop *nexthop;
int k, r = 0;
assert(link);
assert(link->manager);
SET_FOREACH(nexthop, link->nexthops) {
/* do not touch nexthop created by the kernel */
if (nexthop->protocol == RTPROT_KERNEL)
continue;
k = nexthop_remove(nexthop, link->manager, link);
if (k < 0 && r >= 0)
r = k;
}
k = manager_drop_nexthops(link->manager, link);
if (k < 0 && r >= 0)
r = k;
return r;
}
int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message, Manager *m) { int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message, Manager *m) {
_cleanup_(nexthop_freep) NextHop *tmp = NULL; _cleanup_(nexthop_freep) NextHop *tmp = NULL;
NextHop *nexthop = NULL; NextHop *nexthop = NULL;
@ -530,6 +714,12 @@ int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message,
} else if (!IN_SET(tmp->family, AF_INET, AF_INET6)) } else if (!IN_SET(tmp->family, AF_INET, AF_INET6))
return log_link_debug(link, "rtnl: received nexthop message with invalid family %d, ignoring.", tmp->family); return log_link_debug(link, "rtnl: received nexthop message with invalid family %d, ignoring.", tmp->family);
r = sd_rtnl_message_nexthop_get_protocol(message, &tmp->protocol);
if (r < 0) {
log_link_warning_errno(link, r, "rtnl: could not get nexthop protocol, ignoring: %m");
return 0;
}
r = netlink_message_read_in_addr_union(message, NHA_GATEWAY, tmp->family, &tmp->gw); r = netlink_message_read_in_addr_union(message, NHA_GATEWAY, tmp->family, &tmp->gw);
if (r < 0 && r != -ENODATA) { if (r < 0 && r != -ENODATA) {
log_link_warning_errno(link, r, "rtnl: could not get NHA_GATEWAY attribute, ignoring: %m"); log_link_warning_errno(link, r, "rtnl: could not get NHA_GATEWAY attribute, ignoring: %m");

View File

@ -23,7 +23,7 @@ typedef struct NextHop {
Manager *manager; Manager *manager;
Link *link; Link *link;
unsigned char protocol; uint8_t protocol;
uint32_t id; uint32_t id;
bool blackhole; bool blackhole;
@ -37,6 +37,8 @@ NextHop *nexthop_free(NextHop *nexthop);
void network_drop_invalid_nexthops(Network *network); void network_drop_invalid_nexthops(Network *network);
int link_set_nexthops(Link *link); int link_set_nexthops(Link *link);
int link_drop_nexthops(Link *link);
int link_drop_foreign_nexthops(Link *link);
int manager_get_nexthop_by_id(Manager *manager, uint32_t id, NextHop **ret); int manager_get_nexthop_by_id(Manager *manager, uint32_t id, NextHop **ret);
int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message, Manager *m); int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message, Manager *m);

View File

@ -184,6 +184,7 @@ int sd_rtnl_message_route_get_type(const sd_netlink_message *m, unsigned char *t
int sd_rtnl_message_new_nexthop(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t nhmsg_type, int nh_family, unsigned char nh_protocol); int sd_rtnl_message_new_nexthop(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t nhmsg_type, int nh_family, unsigned char nh_protocol);
int sd_rtnl_message_nexthop_set_flags(sd_netlink_message *m, uint8_t flags); int sd_rtnl_message_nexthop_set_flags(sd_netlink_message *m, uint8_t flags);
int sd_rtnl_message_nexthop_get_family(const sd_netlink_message *m, uint8_t *family); int sd_rtnl_message_nexthop_get_family(const sd_netlink_message *m, uint8_t *family);
int sd_rtnl_message_nexthop_get_protocol(const sd_netlink_message *m, uint8_t *protocol);
int sd_rtnl_message_new_neigh(sd_netlink *nl, sd_netlink_message **ret, uint16_t msg_type, int index, int nda_family); int sd_rtnl_message_new_neigh(sd_netlink *nl, sd_netlink_message **ret, uint16_t msg_type, int index, int nda_family);
int sd_rtnl_message_neigh_set_flags(sd_netlink_message *m, uint8_t flags); int sd_rtnl_message_neigh_set_flags(sd_netlink_message *m, uint8_t flags);

View File

@ -0,0 +1,8 @@
[Match]
Name=veth99
[Network]
IPv6AcceptRA=no
Address=2001:1234:5:8f63::1/120
Address=192.168.5.10/24
Gateway=192.168.5.1

View File

@ -1801,6 +1801,7 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
'25-neighbor-ipv6.network', '25-neighbor-ipv6.network',
'25-neighbor-ip-dummy.network', '25-neighbor-ip-dummy.network',
'25-neighbor-ip.network', '25-neighbor-ip.network',
'25-nexthop-nothing.network',
'25-nexthop.network', '25-nexthop.network',
'25-qdisc-cake.network', '25-qdisc-cake.network',
'25-qdisc-clsact-and-htb.network', '25-qdisc-clsact-and-htb.network',
@ -2868,6 +2869,33 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
print(output) print(output)
self.assertEqual('blackhole 2001:1234:5:8f62::2 nhid 7 dev lo proto static metric 1024 pref medium', output) self.assertEqual('blackhole 2001:1234:5:8f62::2 nhid 7 dev lo proto static metric 1024 pref medium', output)
remove_unit_from_networkd_path(['25-nexthop.network'])
copy_unit_to_networkd_unit_path('25-nexthop-nothing.network')
rc = call(*networkctl_cmd, 'reload', env=env)
self.assertEqual(rc, 0)
time.sleep(1)
output = check_output('ip nexthop list dev veth99')
print(output)
self.assertEqual(output, '')
output = check_output('ip nexthop list dev lo')
print(output)
self.assertEqual(output, '')
remove_unit_from_networkd_path(['25-nexthop-nothing.network'])
copy_unit_to_networkd_unit_path('25-nexthop.network')
rc = call(*networkctl_cmd, 'reload', env=env)
self.assertEqual(rc, 0)
time.sleep(1)
rc = call('ip link del veth99')
self.assertEqual(rc, 0)
time.sleep(2)
output = check_output('ip nexthop list dev lo')
print(output)
self.assertEqual(output, '')
def test_qdisc(self): def test_qdisc(self):
copy_unit_to_networkd_unit_path('25-qdisc-clsact-and-htb.network', '12-dummy.netdev', copy_unit_to_networkd_unit_path('25-qdisc-clsact-and-htb.network', '12-dummy.netdev',
'25-qdisc-ingress-netem-compat.network', '11-dummy.netdev') '25-qdisc-ingress-netem-compat.network', '11-dummy.netdev')