diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2019-06-19 13:04:24 +0900 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2019-06-19 21:10:07 +0900 |
commit | b80a511b1b073187c2cbd14b716ad38ea8b2a88a (patch) | |
tree | 809fe51984a5277648fec0418555b09006c71683 | |
parent | f3f0d873e2046877a72809bac922cef2eb85dd65 (diff) | |
download | systemd-b80a511b1b073187c2cbd14b716ad38ea8b2a88a.tar.gz |
network: add missing entries in routing_policy_rule_{hash,compare}_func()
This also makes routing_policy_rule_get() or friends take
a RoutingPolicyRule object as an input.
-rw-r--r-- | src/network/networkd-link.c | 4 | ||||
-rw-r--r-- | src/network/networkd-manager.c | 80 | ||||
-rw-r--r-- | src/network/networkd-routing-policy-rule.c | 151 | ||||
-rw-r--r-- | src/network/networkd-routing-policy-rule.h | 11 |
4 files changed, 105 insertions, 141 deletions
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 98848313bd..4d843651c9 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -839,9 +839,7 @@ static int link_request_set_routing_policy_rule(Link *link) { link->routing_policy_rules_configured = false; LIST_FOREACH(rules, rule, link->network->rules) { - r = routing_policy_rule_get(link->manager, rule->family, &rule->from, rule->from_prefixlen, &rule->to, - rule->to_prefixlen, rule->tos, rule->fwmark, rule->table, rule->iif, rule->oif, - rule->protocol, &rule->sport, &rule->dport, &rrule); + r = routing_policy_rule_get(link->manager, rule, &rrule); if (r >= 0) { if (r == 0) (void) routing_policy_rule_make_local(link->manager, rrule); diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c index 92e3b0a0f1..0b7d9210da 100644 --- a/src/network/networkd-manager.c +++ b/src/network/networkd-manager.c @@ -725,15 +725,12 @@ 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, protocol = 0; - struct fib_rule_port_range sport = {}, dport = {}; - union in_addr_union to = IN_ADDR_NULL, from = IN_ADDR_NULL; + _cleanup_(routing_policy_rule_freep) RoutingPolicyRule *tmp = NULL; RoutingPolicyRule *rule = NULL; - uint32_t fwmark = 0, table = 0; const char *iif = NULL, *oif = NULL; Manager *m = userdata; + unsigned flags; uint16_t type; - int family; int r; assert(rtnl); @@ -757,35 +754,41 @@ int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, voi return 0; } - r = sd_rtnl_message_get_family(message, &family); + r = routing_policy_rule_new(&tmp); + if (r < 0) { + log_oom(); + return 0; + } + + r = sd_rtnl_message_get_family(message, &tmp->family); if (r < 0) { log_warning_errno(r, "rtnl: could not get rule family, ignoring: %m"); return 0; - } else if (!IN_SET(family, AF_INET, AF_INET6)) { - log_debug("rtnl: received address with invalid family %u, ignoring", family); + } else if (!IN_SET(tmp->family, AF_INET, AF_INET6)) { + log_debug("rtnl: received address with invalid family %u, ignoring", tmp->family); return 0; } - switch (family) { + switch (tmp->family) { case AF_INET: - r = sd_netlink_message_read_in_addr(message, FRA_SRC, &from.in); + r = sd_netlink_message_read_in_addr(message, FRA_SRC, &tmp->from.in); if (r < 0 && r != -ENODATA) { log_warning_errno(r, "rtnl: could not get FRA_SRC attribute, ignoring: %m"); return 0; } else if (r >= 0) { - r = sd_rtnl_message_routing_policy_rule_get_rtm_src_prefixlen(message, &from_prefixlen); + r = sd_rtnl_message_routing_policy_rule_get_rtm_src_prefixlen(message, &tmp->from_prefixlen); if (r < 0) { log_warning_errno(r, "rtnl: failed to retrieve rule from prefix length, ignoring: %m"); return 0; } } - r = sd_netlink_message_read_in_addr(message, FRA_DST, &to.in); + r = sd_netlink_message_read_in_addr(message, FRA_DST, &tmp->to.in); if (r < 0 && r != -ENODATA) { log_warning_errno(r, "rtnl: could not get FRA_DST attribute, ignoring: %m"); return 0; } else if (r >= 0) { - r = sd_rtnl_message_routing_policy_rule_get_rtm_dst_prefixlen(message, &to_prefixlen); + r = sd_rtnl_message_routing_policy_rule_get_rtm_dst_prefixlen(message, &tmp->to_prefixlen); if (r < 0) { log_warning_errno(r, "rtnl: failed to retrieve rule to prefix length, ignoring: %m"); return 0; @@ -795,24 +798,24 @@ int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, voi break; case AF_INET6: - r = sd_netlink_message_read_in6_addr(message, FRA_SRC, &from.in6); + r = sd_netlink_message_read_in6_addr(message, FRA_SRC, &tmp->from.in6); if (r < 0 && r != -ENODATA) { log_warning_errno(r, "rtnl: could not get FRA_SRC attribute, ignoring: %m"); return 0; } else if (r >= 0) { - r = sd_rtnl_message_routing_policy_rule_get_rtm_src_prefixlen(message, &from_prefixlen); + r = sd_rtnl_message_routing_policy_rule_get_rtm_src_prefixlen(message, &tmp->from_prefixlen); if (r < 0) { log_warning_errno(r, "rtnl: failed to retrieve rule from prefix length, ignoring: %m"); return 0; } } - r = sd_netlink_message_read_in6_addr(message, FRA_DST, &to.in6); + r = sd_netlink_message_read_in6_addr(message, FRA_DST, &tmp->to.in6); if (r < 0 && r != -ENODATA) { log_warning_errno(r, "rtnl: could not get FRA_DST attribute, ignoring: %m"); return 0; } else if (r >= 0) { - r = sd_rtnl_message_routing_policy_rule_get_rtm_dst_prefixlen(message, &to_prefixlen); + r = sd_rtnl_message_routing_policy_rule_get_rtm_dst_prefixlen(message, &tmp->to_prefixlen); if (r < 0) { log_warning_errno(r, "rtnl: failed to retrieve rule to prefix length, ignoring: %m"); return 0; @@ -825,22 +828,41 @@ int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, voi assert_not_reached("Received unsupported address family"); } - if (from_prefixlen == 0 && to_prefixlen == 0) + if (tmp->from_prefixlen == 0 && tmp->to_prefixlen == 0) return 0; - r = sd_netlink_message_read_u32(message, FRA_FWMARK, &fwmark); + r = sd_rtnl_message_routing_policy_rule_get_flags(message, &flags); + if (r < 0) { + log_warning_errno(r, "rtnl: could not get flag, ignoring: %m"); + return 0; + } + tmp->invert_rule = flags & FIB_RULE_INVERT; + + r = sd_netlink_message_read_u32(message, FRA_FWMARK, &tmp->fwmark); if (r < 0 && r != -ENODATA) { log_warning_errno(r, "rtnl: could not get FRA_FWMARK attribute, ignoring: %m"); return 0; } - r = sd_netlink_message_read_u32(message, FRA_TABLE, &table); + r = sd_netlink_message_read_u32(message, FRA_FWMASK, &tmp->fwmask); + if (r < 0 && r != -ENODATA) { + log_warning_errno(r, "rtnl: could not get FRA_FWMASK attribute, ignoring: %m"); + return 0; + } + + r = sd_netlink_message_read_u32(message, FRA_PRIORITY, &tmp->priority); + if (r < 0 && r != -ENODATA) { + log_warning_errno(r, "rtnl: could not get FRA_PRIORITY attribute, ignoring: %m"); + return 0; + } + + r = sd_netlink_message_read_u32(message, FRA_TABLE, &tmp->table); if (r < 0 && r != -ENODATA) { log_warning_errno(r, "rtnl: could not get FRA_TABLE attribute, ignoring: %m"); return 0; } - r = sd_rtnl_message_routing_policy_rule_get_tos(message, &tos); + r = sd_rtnl_message_routing_policy_rule_get_tos(message, &tmp->tos); if (r < 0 && r != -ENODATA) { log_warning_errno(r, "rtnl: could not get ip rule TOS, ignoring: %m"); return 0; @@ -851,37 +873,43 @@ int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, voi log_warning_errno(r, "rtnl: could not get FRA_IIFNAME attribute, ignoring: %m"); return 0; } + r = free_and_strdup(&tmp->iif, iif); + if (r < 0) + return log_oom(); r = sd_netlink_message_read_string(message, FRA_OIFNAME, &oif); if (r < 0 && r != -ENODATA) { log_warning_errno(r, "rtnl: could not get FRA_OIFNAME attribute, ignoring: %m"); return 0; } + r = free_and_strdup(&tmp->oif, oif); + if (r < 0) + return log_oom(); - r = sd_netlink_message_read_u8(message, FRA_IP_PROTO, &protocol); + r = sd_netlink_message_read_u8(message, FRA_IP_PROTO, &tmp->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); + r = sd_netlink_message_read(message, FRA_SPORT_RANGE, sizeof(tmp->sport), &tmp->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); + r = sd_netlink_message_read(message, FRA_DPORT_RANGE, sizeof(tmp->dport), &tmp->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); + (void) routing_policy_rule_get(m, tmp, &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, protocol, &sport, &dport, &rule); + r = routing_policy_rule_add_foreign(m, tmp, &rule); if (r < 0) { log_warning_errno(r, "Could not add rule, ignoring: %m"); return 0; diff --git a/src/network/networkd-routing-policy-rule.c b/src/network/networkd-routing-policy-rule.c index 420062c647..4715850a9b 100644 --- a/src/network/networkd-routing-policy-rule.c +++ b/src/network/networkd-routing-policy-rule.c @@ -73,8 +73,12 @@ static void routing_policy_rule_hash_func(const RoutingPolicyRule *rule, struct siphash24_compress(&rule->to, FAMILY_ADDRESS_SIZE(rule->family), state); siphash24_compress(&rule->to_prefixlen, sizeof(rule->to_prefixlen), state); + siphash24_compress_boolean(rule->invert_rule, state); + siphash24_compress(&rule->tos, sizeof(rule->tos), state); siphash24_compress(&rule->fwmark, sizeof(rule->fwmark), state); + siphash24_compress(&rule->fwmask, sizeof(rule->fwmask), state); + siphash24_compress(&rule->priority, sizeof(rule->priority), state); siphash24_compress(&rule->table, sizeof(rule->table), state); siphash24_compress(&rule->protocol, sizeof(rule->protocol), state); @@ -112,14 +116,26 @@ static int routing_policy_rule_compare_func(const RoutingPolicyRule *a, const Ro if (r != 0) return r; + r = CMP(a->invert_rule, b->invert_rule); + if (r != 0) + return r; + r = CMP(a->tos, b->tos); if (r != 0) return r; + r = CMP(a->fwmark, b->fwmark); + if (r != 0) + return r; + r = CMP(a->fwmask, b->fwmask); if (r != 0) return r; + r = CMP(a->priority, b->priority); + if (r != 0) + return r; + r = CMP(a->table, b->table); if (r != 0) return r; @@ -158,50 +174,20 @@ static int routing_policy_rule_compare_func(const RoutingPolicyRule *a, const Ro DEFINE_PRIVATE_HASH_OPS(routing_policy_rule_hash_ops, RoutingPolicyRule, routing_policy_rule_hash_func, routing_policy_rule_compare_func); -int routing_policy_rule_get(Manager *m, - int family, - const union in_addr_union *from, - uint8_t from_prefixlen, - const union in_addr_union *to, - uint8_t to_prefixlen, - uint8_t tos, - uint32_t fwmark, - uint32_t table, - const char *iif, - const char *oif, - uint8_t protocol, - struct fib_rule_port_range *sport, - struct fib_rule_port_range *dport, - RoutingPolicyRule **ret) { - - RoutingPolicyRule rule, *existing; +int routing_policy_rule_get(Manager *m, RoutingPolicyRule *rule, RoutingPolicyRule **ret) { - assert(m); + RoutingPolicyRule *existing; - rule = (RoutingPolicyRule) { - .family = family, - .from = *from, - .from_prefixlen = from_prefixlen, - .to = *to, - .to_prefixlen = to_prefixlen, - .tos = tos, - .fwmark = fwmark, - .table = table, - .iif = (char*) iif, - .oif = (char*) oif, - .protocol = protocol, - .sport = *sport, - .dport = *dport, - }; + assert(m); - existing = set_get(m->rules, &rule); + existing = set_get(m->rules, rule); if (existing) { if (ret) *ret = existing; return 1; } - existing = set_get(m->rules_foreign, &rule); + existing = set_get(m->rules_foreign, rule); if (existing) { if (ret) *ret = existing; @@ -229,37 +215,23 @@ int routing_policy_rule_make_local(Manager *m, RoutingPolicyRule *rule) { return -ENOENT; } -static int routing_policy_rule_add_internal(Manager *m, - Set **rules, - int family, - const union in_addr_union *from, - uint8_t from_prefixlen, - const union in_addr_union *to, - uint8_t to_prefixlen, - uint8_t tos, - uint32_t fwmark, - uint32_t table, - const char *_iif, - const char *_oif, - uint8_t protocol, - const struct fib_rule_port_range *sport, - const struct fib_rule_port_range *dport, - RoutingPolicyRule **ret) { - +static int routing_policy_rule_add_internal(Manager *m, Set **rules, RoutingPolicyRule *in, RoutingPolicyRule **ret) { _cleanup_(routing_policy_rule_freep) RoutingPolicyRule *rule = NULL; _cleanup_free_ char *iif = NULL, *oif = NULL; int r; - assert_return(rules, -EINVAL); + assert(m); + assert(rules); + assert(in); - if (_iif) { - iif = strdup(_iif); + if (in->iif) { + iif = strdup(in->iif); if (!iif) return -ENOMEM; } - if (_oif) { - oif = strdup(_oif); + if (in->oif) { + oif = strdup(in->oif); if (!oif) return -ENOMEM; } @@ -269,19 +241,22 @@ static int routing_policy_rule_add_internal(Manager *m, return r; rule->manager = m; - rule->family = family; - rule->from = *from; - rule->from_prefixlen = from_prefixlen; - rule->to = *to; - rule->to_prefixlen = to_prefixlen; - rule->tos = tos; - rule->fwmark = fwmark; - rule->table = table; + rule->family = in->family; + rule->from = in->from; + rule->from_prefixlen = in->from_prefixlen; + rule->to = in->to; + rule->to_prefixlen = in->to_prefixlen; + rule->invert_rule = in->invert_rule; + rule->tos = in->tos; + rule->fwmark = in->fwmark; + rule->fwmask = in->fwmask; + rule->priority = in->priority; + rule->table = in->table; rule->iif = TAKE_PTR(iif); rule->oif = TAKE_PTR(oif); - rule->protocol = protocol; - rule->sport = *sport; - rule->dport = *dport; + rule->protocol = in->protocol; + rule->sport = in->sport; + rule->dport = in->dport; r = set_ensure_allocated(rules, &routing_policy_rule_hash_ops); if (r < 0) @@ -298,41 +273,12 @@ static int routing_policy_rule_add_internal(Manager *m, return 0; } -int routing_policy_rule_add(Manager *m, - int family, - const union in_addr_union *from, - uint8_t from_prefixlen, - const union in_addr_union *to, - uint8_t to_prefixlen, - uint8_t tos, - uint32_t fwmark, - uint32_t table, - const char *iif, - const char *oif, - uint8_t protocol, - const struct fib_rule_port_range *sport, - const struct fib_rule_port_range *dport, - RoutingPolicyRule **ret) { - - return routing_policy_rule_add_internal(m, &m->rules, family, from, from_prefixlen, to, to_prefixlen, tos, fwmark, table, iif, oif, protocol, sport, dport, ret); +static int routing_policy_rule_add(Manager *m, RoutingPolicyRule *rule, RoutingPolicyRule **ret) { + return routing_policy_rule_add_internal(m, &m->rules, rule, ret); } -int routing_policy_rule_add_foreign(Manager *m, - int family, - const union in_addr_union *from, - uint8_t from_prefixlen, - const union in_addr_union *to, - uint8_t to_prefixlen, - uint8_t tos, - uint32_t fwmark, - uint32_t table, - const char *iif, - const char *oif, - uint8_t protocol, - const struct fib_rule_port_range *sport, - const struct fib_rule_port_range *dport, - RoutingPolicyRule **ret) { - return routing_policy_rule_add_internal(m, &m->rules_foreign, family, from, from_prefixlen, to, to_prefixlen, tos, fwmark, table, iif, oif, protocol, sport, dport, ret); +int routing_policy_rule_add_foreign(Manager *m, RoutingPolicyRule *rule, RoutingPolicyRule **ret) { + return routing_policy_rule_add_internal(m, &m->rules_foreign, rule, ret); } static int routing_policy_rule_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { @@ -593,8 +539,7 @@ int routing_policy_rule_configure(RoutingPolicyRule *rule, Link *link, link_netl link_ref(link); - r = routing_policy_rule_add(link->manager, rule->family, &rule->from, rule->from_prefixlen, &rule->to, - rule->to_prefixlen, rule->tos, rule->fwmark, rule->table, rule->iif, rule->oif, rule->protocol, &rule->sport, &rule->dport, NULL); + r = routing_policy_rule_add(link->manager, rule, NULL); if (r < 0) return log_error_errno(r, "Could not add rule: %m"); diff --git a/src/network/networkd-routing-policy-rule.h b/src/network/networkd-routing-policy-rule.h index 0b3204ad9c..512af3dfdd 100644 --- a/src/network/networkd-routing-policy-rule.h +++ b/src/network/networkd-routing-policy-rule.h @@ -60,15 +60,8 @@ DEFINE_NETWORK_SECTION_FUNCTIONS(RoutingPolicyRule, routing_policy_rule_free); int routing_policy_rule_configure(RoutingPolicyRule *address, Link *link, link_netlink_message_handler_t callback); int routing_policy_rule_remove(RoutingPolicyRule *routing_policy_rule, Link *link, link_netlink_message_handler_t callback); -int routing_policy_rule_add(Manager *m, int family, const union in_addr_union *from, uint8_t from_prefixlen, const union in_addr_union *to, uint8_t to_prefixlen, - uint8_t tos, uint32_t fwmark, uint32_t table, const char *iif, const char *oif, uint8_t protocol, const struct fib_rule_port_range *sport, - const struct fib_rule_port_range *dport, RoutingPolicyRule **ret); -int routing_policy_rule_add_foreign(Manager *m, int family, const union in_addr_union *from, uint8_t from_prefixlen, const union in_addr_union *to, uint8_t to_prefixlen, - uint8_t tos, uint32_t fwmark, uint32_t table, const char *iif, const char *oif, uint8_t protocol, const struct fib_rule_port_range *sport, - const struct fib_rule_port_range *dport, RoutingPolicyRule **ret); -int routing_policy_rule_get(Manager *m, int family, const union in_addr_union *from, uint8_t from_prefixlen, const union in_addr_union *to, uint8_t to_prefixlen, uint8_t tos, - uint32_t fwmark, uint32_t table, const char *iif, const char *oif, uint8_t protocol, struct fib_rule_port_range *sport, - struct fib_rule_port_range *dport, RoutingPolicyRule **ret); +int routing_policy_rule_add_foreign(Manager *m, RoutingPolicyRule *rule, RoutingPolicyRule **ret); +int routing_policy_rule_get(Manager *m, RoutingPolicyRule *rule, RoutingPolicyRule **ret); int routing_policy_rule_make_local(Manager *m, RoutingPolicyRule *rule); int routing_policy_serialize_rules(Set *rules, FILE *f); int routing_policy_load_rules(const char *state_file, Set **rules); |