]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/network/networkd-manager.c
Merge pull request #10920 from yuwata/hashmap-destructor
[thirdparty/systemd.git] / src / network / networkd-manager.c
index fce8f4610c97444002808c175834e9f4967fa711..81c81f18af0253eceae2b8d2496d2e91066fc806 100644 (file)
@@ -23,6 +23,7 @@
 #include "path-util.h"
 #include "set.h"
 #include "strv.h"
+#include "tmpfile-util.h"
 #include "virt.h"
 
 /* use 8 MB for receive socket kernel queue. */
@@ -697,7 +698,8 @@ static int manager_rtnl_process_link(sd_netlink *rtnl, sd_netlink_message *messa
 }
 
 int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, void *userdata) {
-        uint8_t tos = 0, to_prefixlen = 0, from_prefixlen = 0;
+        uint8_t tos = 0, to_prefixlen = 0, from_prefixlen = 0, protocol = 0;
+        struct fib_rule_port_range sport = {}, dport = {};
         union in_addr_union to = {}, from = {};
         RoutingPolicyRule *rule = NULL;
         uint32_t fwmark = 0, table = 0;
@@ -829,12 +831,30 @@ int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, voi
                 return 0;
         }
 
-        (void) routing_policy_rule_get(m, family, &from, from_prefixlen, &to, to_prefixlen, tos, fwmark, table, iif, oif, &rule);
+        r = sd_netlink_message_read_u8(message, FRA_IP_PROTO, &protocol);
+        if (r < 0 && r != -ENODATA) {
+                log_warning_errno(r, "rtnl: could not get FRA_IP_PROTO attribute, ignoring: %m");
+                return 0;
+        }
+
+        r = sd_netlink_message_read(message, FRA_SPORT_RANGE, sizeof(sport), (void *) &sport);
+        if (r < 0 && r != -ENODATA) {
+                log_warning_errno(r, "rtnl: could not get FRA_SPORT_RANGE attribute, ignoring: %m");
+                return 0;
+        }
+
+        r = sd_netlink_message_read(message, FRA_DPORT_RANGE, sizeof(dport), (void *) &dport);
+        if (r < 0 && r != -ENODATA) {
+                log_warning_errno(r, "rtnl: could not get FRA_DPORT_RANGE attribute, ignoring: %m");
+                return 0;
+        }
+
+        (void) routing_policy_rule_get(m, family, &from, from_prefixlen, &to, to_prefixlen, tos, fwmark, table, iif, oif, protocol, &sport, &dport, &rule);
 
         switch (type) {
         case RTM_NEWRULE:
                 if (!rule) {
-                        r = routing_policy_rule_add_foreign(m, family, &from, from_prefixlen, &to, to_prefixlen, tos, fwmark, table, iif, oif, &rule);
+                        r = routing_policy_rule_add_foreign(m, family, &from, from_prefixlen, &to, to_prefixlen, tos, fwmark, table, iif, oif, protocol, &sport, &dport, &rule);
                         if (r < 0) {
                                 log_warning_errno(r, "Could not add rule, ignoring: %m");
                                 return 0;
@@ -1218,8 +1238,7 @@ Link *manager_dhcp6_prefix_get(Manager *m, struct in6_addr *addr) {
         return hashmap_get(m->dhcp6_prefixes, addr);
 }
 
-static int dhcp6_route_add_handler(sd_netlink *nl, sd_netlink_message *m, void *userdata) {
-        Link *link = userdata;
+static int dhcp6_route_add_handler(sd_netlink *nl, sd_netlink_message *m, Link *link) {
         int r;
 
         assert(link);
@@ -1231,24 +1250,17 @@ static int dhcp6_route_add_handler(sd_netlink *nl, sd_netlink_message *m, void *
         return 0;
 }
 
-static void dhcp6_prefixes_hash_func(const void *p, struct siphash *state) {
-        const struct in6_addr *addr = p;
-
-        assert(p);
+static void dhcp6_prefixes_hash_func(const struct in6_addr *addr, struct siphash *state) {
+        assert(addr);
 
         siphash24_compress(addr, sizeof(*addr), state);
 }
 
-static int dhcp6_prefixes_compare_func(const void *_a, const void *_b) {
-        const struct in6_addr *a = _a, *b = _b;
-
+static int dhcp6_prefixes_compare_func(const struct in6_addr *a, const struct in6_addr *b) {
         return memcmp(a, b, sizeof(*a));
 }
 
-static const struct hash_ops dhcp6_prefixes_hash_ops = {
-        .hash = dhcp6_prefixes_hash_func,
-        .compare = dhcp6_prefixes_compare_func,
-};
+DEFINE_PRIVATE_HASH_OPS(dhcp6_prefixes_hash_ops, struct in6_addr, dhcp6_prefixes_hash_func, dhcp6_prefixes_compare_func);
 
 int manager_dhcp6_prefix_add(Manager *m, struct in6_addr *addr, Link *link) {
         _cleanup_free_ char *buf = NULL;
@@ -1277,8 +1289,7 @@ int manager_dhcp6_prefix_add(Manager *m, struct in6_addr *addr, Link *link) {
         return hashmap_put(m->dhcp6_prefixes, addr, link);
 }
 
-static int dhcp6_route_remove_handler(sd_netlink *nl, sd_netlink_message *m, void *userdata) {
-        Link *link = userdata;
+static int dhcp6_route_remove_handler(sd_netlink *nl, sd_netlink_message *m, Link *link) {
         int r;
 
         assert(link);
@@ -1417,13 +1428,9 @@ void manager_free(Manager *m) {
                 manager_dhcp6_prefix_remove_all(m, link);
         hashmap_free(m->dhcp6_prefixes);
 
-        while ((link = hashmap_first(m->links))) {
+        while ((link = hashmap_steal_first(m->links))) {
                 if (link->dhcp6_client)
-                        (void) dhcp6_lease_pd_prefix_lost(link->dhcp6_client,
-                                                          link);
-
-                hashmap_remove(m->links, INT_TO_PTR(link->ifindex));
-
+                        (void) dhcp6_lease_pd_prefix_lost(link->dhcp6_client, link);
                 link_unref(link);
         }