| File: | build-scan/../src/network/networkd-routing-policy-rule.c |
| Warning: | line 955, column 40 Potential leak of memory pointed to by 'rule' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* SPDX-License-Identifier: LGPL-2.1+ */ | |||
| 2 | ||||
| 3 | #include <net/if.h> | |||
| 4 | #include <linux1/fib_rules.h> | |||
| 5 | ||||
| 6 | #include "alloc-util.h" | |||
| 7 | #include "conf-parser.h" | |||
| 8 | #include "fileio.h" | |||
| 9 | #include "networkd-routing-policy-rule.h" | |||
| 10 | #include "netlink-util.h" | |||
| 11 | #include "networkd-manager.h" | |||
| 12 | #include "parse-util.h" | |||
| 13 | #include "socket-util.h" | |||
| 14 | #include "string-util.h" | |||
| 15 | ||||
| 16 | int routing_policy_rule_new(RoutingPolicyRule **ret) { | |||
| 17 | RoutingPolicyRule *rule; | |||
| 18 | ||||
| 19 | rule = new0(RoutingPolicyRule, 1)((RoutingPolicyRule*) calloc((1), sizeof(RoutingPolicyRule))); | |||
| 20 | if (!rule) | |||
| 21 | return -ENOMEM12; | |||
| 22 | ||||
| 23 | rule->family = AF_INET2; | |||
| 24 | rule->table = RT_TABLE_MAIN; | |||
| 25 | ||||
| 26 | *ret = rule; | |||
| 27 | return 0; | |||
| 28 | } | |||
| 29 | ||||
| 30 | void routing_policy_rule_free(RoutingPolicyRule *rule) { | |||
| 31 | ||||
| 32 | if (!rule) | |||
| 33 | return; | |||
| 34 | ||||
| 35 | if (rule->network) { | |||
| 36 | LIST_REMOVE(rules, rule->network->rules, rule)do { typeof(*(rule->network->rules)) **_head = &(rule ->network->rules), *_item = (rule); do { if ((__builtin_expect (!!(!(_item)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("_item"), "../src/network/networkd-routing-policy-rule.c", 36 , __PRETTY_FUNCTION__); } while (0); if (_item->rules_next ) _item->rules_next->rules_prev = _item->rules_prev; if (_item->rules_prev) _item->rules_prev->rules_next = _item->rules_next; else { do { if ((__builtin_expect(!! (!(*_head == _item)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD , ("*_head == _item"), "../src/network/networkd-routing-policy-rule.c" , 36, __PRETTY_FUNCTION__); } while (0); *_head = _item->rules_next ; } _item->rules_next = _item->rules_prev = ((void*)0); } while (0); | |||
| 37 | assert(rule->network->n_rules > 0)do { if ((__builtin_expect(!!(!(rule->network->n_rules > 0)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("rule->network->n_rules > 0" ), "../src/network/networkd-routing-policy-rule.c", 37, __PRETTY_FUNCTION__ ); } while (0); | |||
| 38 | rule->network->n_rules--; | |||
| 39 | ||||
| 40 | if (rule->section) { | |||
| 41 | hashmap_remove(rule->network->rules_by_section, rule->section); | |||
| 42 | network_config_section_free(rule->section); | |||
| 43 | } | |||
| 44 | ||||
| 45 | } | |||
| 46 | ||||
| 47 | if (rule->manager) { | |||
| 48 | set_remove(rule->manager->rules, rule); | |||
| 49 | set_remove(rule->manager->rules_foreign, rule); | |||
| 50 | } | |||
| 51 | ||||
| 52 | free(rule->iif); | |||
| 53 | free(rule->oif); | |||
| 54 | free(rule); | |||
| 55 | } | |||
| 56 | ||||
| 57 | static void routing_policy_rule_hash_func(const void *b, struct siphash *state) { | |||
| 58 | const RoutingPolicyRule *rule = b; | |||
| 59 | ||||
| 60 | assert(rule)do { if ((__builtin_expect(!!(!(rule)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("rule"), "../src/network/networkd-routing-policy-rule.c" , 60, __PRETTY_FUNCTION__); } while (0); | |||
| 61 | ||||
| 62 | siphash24_compress(&rule->family, sizeof(rule->family), state); | |||
| 63 | ||||
| 64 | switch (rule->family) { | |||
| 65 | case AF_INET2: | |||
| 66 | case AF_INET610: | |||
| 67 | ||||
| 68 | siphash24_compress(&rule->from, FAMILY_ADDRESS_SIZE(rule->family), state); | |||
| 69 | siphash24_compress(&rule->from_prefixlen, sizeof(rule->from_prefixlen), state); | |||
| 70 | ||||
| 71 | siphash24_compress(&rule->to, FAMILY_ADDRESS_SIZE(rule->family), state); | |||
| 72 | siphash24_compress(&rule->to_prefixlen, sizeof(rule->to_prefixlen), state); | |||
| 73 | ||||
| 74 | siphash24_compress(&rule->tos, sizeof(rule->tos), state); | |||
| 75 | siphash24_compress(&rule->fwmark, sizeof(rule->fwmark), state); | |||
| 76 | siphash24_compress(&rule->table, sizeof(rule->table), state); | |||
| 77 | ||||
| 78 | if (rule->iif) | |||
| 79 | siphash24_compress(&rule->iif, strlen(rule->iif), state); | |||
| 80 | ||||
| 81 | if (rule->oif) | |||
| 82 | siphash24_compress(&rule->oif, strlen(rule->oif), state); | |||
| 83 | ||||
| 84 | break; | |||
| 85 | default: | |||
| 86 | /* treat any other address family as AF_UNSPEC */ | |||
| 87 | break; | |||
| 88 | } | |||
| 89 | } | |||
| 90 | ||||
| 91 | static int routing_policy_rule_compare_func(const void *_a, const void *_b) { | |||
| 92 | const RoutingPolicyRule *a = _a, *b = _b; | |||
| 93 | int r; | |||
| 94 | ||||
| 95 | if (a->family < b->family) | |||
| 96 | return -1; | |||
| 97 | if (a->family > b->family) | |||
| 98 | return 1; | |||
| 99 | ||||
| 100 | switch (a->family) { | |||
| 101 | case AF_INET2: | |||
| 102 | case AF_INET610: | |||
| 103 | if (a->from_prefixlen < b->from_prefixlen) | |||
| 104 | return -1; | |||
| 105 | if (a->from_prefixlen > b->from_prefixlen) | |||
| 106 | return 1; | |||
| 107 | ||||
| 108 | if (a->to_prefixlen < b->to_prefixlen) | |||
| 109 | return -1; | |||
| 110 | if (a->to_prefixlen > b->to_prefixlen) | |||
| 111 | return 1; | |||
| 112 | ||||
| 113 | if (a->tos < b->tos) | |||
| 114 | return -1; | |||
| 115 | if (a->tos > b->tos) | |||
| 116 | return 1; | |||
| 117 | ||||
| 118 | if (a->fwmask < b->fwmark) | |||
| 119 | return -1; | |||
| 120 | if (a->fwmask > b->fwmark) | |||
| 121 | return 1; | |||
| 122 | ||||
| 123 | if (a->table < b->table) | |||
| 124 | return -1; | |||
| 125 | if (a->table > b->table) | |||
| 126 | return 1; | |||
| 127 | ||||
| 128 | r = strcmp_ptr(a->iif, b->iif); | |||
| 129 | if (!r) | |||
| 130 | return r; | |||
| 131 | ||||
| 132 | r = strcmp_ptr(a->oif, b->oif); | |||
| 133 | if (!r) | |||
| 134 | return r; | |||
| 135 | ||||
| 136 | r = memcmp(&a->from, &b->from, FAMILY_ADDRESS_SIZE(a->family)); | |||
| 137 | if (r != 0) | |||
| 138 | return r; | |||
| 139 | ||||
| 140 | return memcmp(&a->to, &b->to, FAMILY_ADDRESS_SIZE(a->family)); | |||
| 141 | ||||
| 142 | default: | |||
| 143 | /* treat any other address family as AF_UNSPEC */ | |||
| 144 | return 0; | |||
| 145 | } | |||
| 146 | } | |||
| 147 | ||||
| 148 | const struct hash_ops routing_policy_rule_hash_ops = { | |||
| 149 | .hash = routing_policy_rule_hash_func, | |||
| 150 | .compare = routing_policy_rule_compare_func | |||
| 151 | }; | |||
| 152 | ||||
| 153 | int routing_policy_rule_get(Manager *m, | |||
| 154 | int family, | |||
| 155 | const union in_addr_union *from, | |||
| 156 | uint8_t from_prefixlen, | |||
| 157 | const union in_addr_union *to, | |||
| 158 | uint8_t to_prefixlen, | |||
| 159 | uint8_t tos, | |||
| 160 | uint32_t fwmark, | |||
| 161 | uint32_t table, | |||
| 162 | char *iif, | |||
| 163 | char *oif, | |||
| 164 | RoutingPolicyRule **ret) { | |||
| 165 | ||||
| 166 | RoutingPolicyRule rule, *existing; | |||
| 167 | ||||
| 168 | assert_return(m, -1)do { if (!(((__builtin_expect(!!(m),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_SYSTEMD, ("m"), "../src/network/networkd-routing-policy-rule.c" , 168, __PRETTY_FUNCTION__), 0))) return (-1); } while (0); | |||
| 169 | ||||
| 170 | rule = (RoutingPolicyRule) { | |||
| 171 | .family = family, | |||
| 172 | .from = *from, | |||
| 173 | .from_prefixlen = from_prefixlen, | |||
| 174 | .to = *to, | |||
| 175 | .to_prefixlen = to_prefixlen, | |||
| 176 | .tos = tos, | |||
| 177 | .fwmark = fwmark, | |||
| 178 | .table = table, | |||
| 179 | .iif = iif, | |||
| 180 | .oif = oif | |||
| 181 | }; | |||
| 182 | ||||
| 183 | if (m->rules) { | |||
| 184 | existing = set_get(m->rules, &rule); | |||
| 185 | if (existing) { | |||
| 186 | if (ret) | |||
| 187 | *ret = existing; | |||
| 188 | return 1; | |||
| 189 | } | |||
| 190 | } | |||
| 191 | ||||
| 192 | if (m->rules_foreign) { | |||
| 193 | existing = set_get(m->rules_foreign, &rule); | |||
| 194 | if (existing) { | |||
| 195 | if (ret) | |||
| 196 | *ret = existing; | |||
| 197 | return 1; | |||
| 198 | } | |||
| 199 | } | |||
| 200 | ||||
| 201 | return -ENOENT2; | |||
| 202 | } | |||
| 203 | ||||
| 204 | int routing_policy_rule_make_local(Manager *m, RoutingPolicyRule *rule) { | |||
| 205 | int r; | |||
| 206 | ||||
| 207 | assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("m"), "../src/network/networkd-routing-policy-rule.c" , 207, __PRETTY_FUNCTION__); } while (0); | |||
| 208 | ||||
| 209 | if (set_contains(m->rules_foreign, rule)) { | |||
| 210 | set_remove(m->rules_foreign, rule); | |||
| 211 | ||||
| 212 | r = set_ensure_allocated(&m->rules, &routing_policy_rule_hash_ops)internal_set_ensure_allocated(&m->rules, &routing_policy_rule_hash_ops ); | |||
| 213 | if (r < 0) | |||
| 214 | return r; | |||
| 215 | ||||
| 216 | return set_put(m->rules, rule); | |||
| 217 | } | |||
| 218 | ||||
| 219 | return -ENOENT2; | |||
| 220 | } | |||
| 221 | ||||
| 222 | static int routing_policy_rule_add_internal(Manager *m, | |||
| 223 | Set **rules, | |||
| 224 | int family, | |||
| 225 | const union in_addr_union *from, | |||
| 226 | uint8_t from_prefixlen, | |||
| 227 | const union in_addr_union *to, | |||
| 228 | uint8_t to_prefixlen, | |||
| 229 | uint8_t tos, | |||
| 230 | uint32_t fwmark, | |||
| 231 | uint32_t table, | |||
| 232 | char *iif, | |||
| 233 | char *oif, | |||
| 234 | RoutingPolicyRule **ret) { | |||
| 235 | ||||
| 236 | _cleanup_(routing_policy_rule_freep)__attribute__((cleanup(routing_policy_rule_freep))) RoutingPolicyRule *rule = NULL((void*)0); | |||
| 237 | int r; | |||
| 238 | ||||
| 239 | assert_return(rules, -EINVAL)do { if (!(((__builtin_expect(!!(rules),1))) ? (1) : (log_assert_failed_return_realm (LOG_REALM_SYSTEMD, ("rules"), "../src/network/networkd-routing-policy-rule.c" , 239, __PRETTY_FUNCTION__), 0))) return (-22); } while (0); | |||
| 240 | ||||
| 241 | r = routing_policy_rule_new(&rule); | |||
| 242 | if (r < 0) | |||
| 243 | return r; | |||
| 244 | ||||
| 245 | rule->manager = m; | |||
| 246 | rule->family = family; | |||
| 247 | rule->from = *from; | |||
| 248 | rule->from_prefixlen = from_prefixlen; | |||
| 249 | rule->to = *to; | |||
| 250 | rule->to_prefixlen = to_prefixlen; | |||
| 251 | rule->tos = tos; | |||
| 252 | rule->fwmark = fwmark; | |||
| 253 | rule->table = table; | |||
| 254 | rule->iif = iif; | |||
| 255 | rule->oif = oif; | |||
| 256 | ||||
| 257 | r = set_ensure_allocated(rules, &routing_policy_rule_hash_ops)internal_set_ensure_allocated(rules, &routing_policy_rule_hash_ops ); | |||
| 258 | if (r < 0) | |||
| 259 | return r; | |||
| 260 | ||||
| 261 | r = set_put(*rules, rule); | |||
| 262 | if (r < 0) | |||
| 263 | return r; | |||
| 264 | ||||
| 265 | if (ret) | |||
| 266 | *ret = rule; | |||
| 267 | ||||
| 268 | rule = NULL((void*)0); | |||
| 269 | ||||
| 270 | return 0; | |||
| 271 | } | |||
| 272 | ||||
| 273 | int routing_policy_rule_add(Manager *m, | |||
| 274 | int family, | |||
| 275 | const union in_addr_union *from, | |||
| 276 | uint8_t from_prefixlen, | |||
| 277 | const union in_addr_union *to, | |||
| 278 | uint8_t to_prefixlen, | |||
| 279 | uint8_t tos, | |||
| 280 | uint32_t fwmark, | |||
| 281 | uint32_t table, | |||
| 282 | char *iif, | |||
| 283 | char *oif, | |||
| 284 | RoutingPolicyRule **ret) { | |||
| 285 | ||||
| 286 | return routing_policy_rule_add_internal(m, &m->rules, family, from, from_prefixlen, to, to_prefixlen, tos, fwmark, table, iif, oif, ret); | |||
| 287 | } | |||
| 288 | ||||
| 289 | int routing_policy_rule_add_foreign(Manager *m, | |||
| 290 | int family, | |||
| 291 | const union in_addr_union *from, | |||
| 292 | uint8_t from_prefixlen, | |||
| 293 | const union in_addr_union *to, | |||
| 294 | uint8_t to_prefixlen, | |||
| 295 | uint8_t tos, | |||
| 296 | uint32_t fwmark, | |||
| 297 | uint32_t table, | |||
| 298 | char *iif, | |||
| 299 | char *oif, | |||
| 300 | RoutingPolicyRule **ret) { | |||
| 301 | return routing_policy_rule_add_internal(m, &m->rules_foreign, family, from, from_prefixlen, to, to_prefixlen, tos, fwmark, table, iif, oif, ret); | |||
| 302 | } | |||
| 303 | ||||
| 304 | static int routing_policy_rule_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) { | |||
| 305 | _cleanup_(link_unrefp)__attribute__((cleanup(link_unrefp))) Link *link = userdata; | |||
| 306 | int r; | |||
| 307 | ||||
| 308 | assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("m"), "../src/network/networkd-routing-policy-rule.c" , 308, __PRETTY_FUNCTION__); } while (0); | |||
| 309 | assert(link)do { if ((__builtin_expect(!!(!(link)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("link"), "../src/network/networkd-routing-policy-rule.c" , 309, __PRETTY_FUNCTION__); } while (0); | |||
| 310 | assert(link->ifname)do { if ((__builtin_expect(!!(!(link->ifname)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("link->ifname"), "../src/network/networkd-routing-policy-rule.c" , 310, __PRETTY_FUNCTION__); } while (0); | |||
| 311 | ||||
| 312 | link->routing_policy_rule_remove_messages--; | |||
| 313 | ||||
| 314 | if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended [20 - sizeof((int[]){LINK_STATE_FAILED, LINK_STATE_LINGER})/sizeof (int)]; switch(link->state) { case LINK_STATE_FAILED: case LINK_STATE_LINGER: _found = 1; break; default: break; } _found ; })) | |||
| 315 | return 1; | |||
| 316 | ||||
| 317 | r = sd_netlink_message_get_errno(m); | |||
| 318 | if (r < 0) | |||
| 319 | log_link_warning_errno(link, r, "Could not drop routing policy rule: %m")({ const Link *_l = (link); _l ? log_object_internal(4, r, "../src/network/networkd-routing-policy-rule.c" , 319, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((void *)0), "Could not drop routing policy rule: %m") : log_internal_realm (((LOG_REALM_SYSTEMD) << 10 | ((4))), r, "../src/network/networkd-routing-policy-rule.c" , 319, __func__, "Could not drop routing policy rule: %m"); } ); | |||
| 320 | ||||
| 321 | return 1; | |||
| 322 | } | |||
| 323 | ||||
| 324 | int routing_policy_rule_remove(RoutingPolicyRule *routing_policy_rule, Link *link, sd_netlink_message_handler_t callback) { | |||
| 325 | _cleanup_(sd_netlink_message_unrefp)__attribute__((cleanup(sd_netlink_message_unrefp))) sd_netlink_message *m = NULL((void*)0); | |||
| 326 | int r; | |||
| 327 | ||||
| 328 | assert(routing_policy_rule)do { if ((__builtin_expect(!!(!(routing_policy_rule)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("routing_policy_rule"), "../src/network/networkd-routing-policy-rule.c" , 328, __PRETTY_FUNCTION__); } while (0); | |||
| 329 | assert(link)do { if ((__builtin_expect(!!(!(link)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("link"), "../src/network/networkd-routing-policy-rule.c" , 329, __PRETTY_FUNCTION__); } while (0); | |||
| 330 | assert(link->manager)do { if ((__builtin_expect(!!(!(link->manager)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("link->manager"), "../src/network/networkd-routing-policy-rule.c" , 330, __PRETTY_FUNCTION__); } while (0); | |||
| 331 | assert(link->manager->rtnl)do { if ((__builtin_expect(!!(!(link->manager->rtnl)),0 ))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("link->manager->rtnl" ), "../src/network/networkd-routing-policy-rule.c", 331, __PRETTY_FUNCTION__ ); } while (0); | |||
| 332 | assert(link->ifindex > 0)do { if ((__builtin_expect(!!(!(link->ifindex > 0)),0)) ) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("link->ifindex > 0" ), "../src/network/networkd-routing-policy-rule.c", 332, __PRETTY_FUNCTION__ ); } while (0); | |||
| 333 | assert(IN_SET(routing_policy_rule->family, AF_INET, AF_INET6))do { if ((__builtin_expect(!!(!(({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended[20 - sizeof((int[]){2, 10})/sizeof(int)]; switch(routing_policy_rule ->family) { case 2: case 10: _found = 1; break; default: break ; } _found; }))),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD , ("IN_SET(routing_policy_rule->family, AF_INET, AF_INET6)" ), "../src/network/networkd-routing-policy-rule.c", 333, __PRETTY_FUNCTION__ ); } while (0); | |||
| 334 | ||||
| 335 | r = sd_rtnl_message_new_routing_policy_rule(link->manager->rtnl, &m, RTM_DELRULERTM_DELRULE, routing_policy_rule->family); | |||
| 336 | if (r < 0) | |||
| 337 | return log_error_errno(r, "Could not allocate RTM_DELRULE message: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/network/networkd-routing-policy-rule.c", 337, __func__ , "Could not allocate RTM_DELRULE message: %m") : -abs(_e); } ); | |||
| 338 | ||||
| 339 | if (!in_addr_is_null(routing_policy_rule->family, &routing_policy_rule->from)) { | |||
| 340 | if (routing_policy_rule->family == AF_INET2) | |||
| 341 | r = sd_netlink_message_append_in_addr(m, FRA_SRC, &routing_policy_rule->from.in); | |||
| 342 | else | |||
| 343 | r = sd_netlink_message_append_in6_addr(m, FRA_SRC, &routing_policy_rule->from.in6); | |||
| 344 | ||||
| 345 | if (r < 0) | |||
| 346 | return log_error_errno(r, "Could not append FRA_SRC attribute: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/network/networkd-routing-policy-rule.c", 346, __func__ , "Could not append FRA_SRC attribute: %m") : -abs(_e); }); | |||
| 347 | ||||
| 348 | r = sd_rtnl_message_routing_policy_rule_set_rtm_src_prefixlen(m, routing_policy_rule->from_prefixlen); | |||
| 349 | if (r < 0) | |||
| 350 | return log_error_errno(r, "Could not set source prefix length: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/network/networkd-routing-policy-rule.c", 350, __func__ , "Could not set source prefix length: %m") : -abs(_e); }); | |||
| 351 | } | |||
| 352 | ||||
| 353 | if (!in_addr_is_null(routing_policy_rule->family, &routing_policy_rule->to)) { | |||
| 354 | if (routing_policy_rule->family == AF_INET2) | |||
| 355 | r = sd_netlink_message_append_in_addr(m, FRA_DST, &routing_policy_rule->to.in); | |||
| 356 | else | |||
| 357 | r = sd_netlink_message_append_in6_addr(m, FRA_DST, &routing_policy_rule->to.in6); | |||
| 358 | ||||
| 359 | if (r < 0) | |||
| 360 | return log_error_errno(r, "Could not append FRA_DST attribute: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/network/networkd-routing-policy-rule.c", 360, __func__ , "Could not append FRA_DST attribute: %m") : -abs(_e); }); | |||
| 361 | ||||
| 362 | r = sd_rtnl_message_routing_policy_rule_set_rtm_dst_prefixlen(m, routing_policy_rule->to_prefixlen); | |||
| 363 | if (r < 0) | |||
| 364 | return log_error_errno(r, "Could not set destination prefix length: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/network/networkd-routing-policy-rule.c", 364, __func__ , "Could not set destination prefix length: %m") : -abs(_e); } ); | |||
| 365 | } | |||
| 366 | ||||
| 367 | r = sd_netlink_call_async(link->manager->rtnl, m, callback, link, 0, NULL((void*)0)); | |||
| 368 | if (r < 0) | |||
| 369 | return log_error_errno(r, "Could not send rtnetlink message: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/network/networkd-routing-policy-rule.c", 369, __func__ , "Could not send rtnetlink message: %m") : -abs(_e); }); | |||
| 370 | ||||
| 371 | link_ref(link); | |||
| 372 | ||||
| 373 | return 0; | |||
| 374 | } | |||
| 375 | ||||
| 376 | static int routing_policy_rule_new_static(Network *network, const char *filename, unsigned section_line, RoutingPolicyRule **ret) { | |||
| 377 | _cleanup_(routing_policy_rule_freep)__attribute__((cleanup(routing_policy_rule_freep))) RoutingPolicyRule *rule = NULL((void*)0); | |||
| 378 | _cleanup_(network_config_section_freep)__attribute__((cleanup(network_config_section_freep))) NetworkConfigSection *n = NULL((void*)0); | |||
| 379 | int r; | |||
| 380 | ||||
| 381 | assert(network)do { if ((__builtin_expect(!!(!(network)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("network"), "../src/network/networkd-routing-policy-rule.c" , 381, __PRETTY_FUNCTION__); } while (0); | |||
| 382 | assert(ret)do { if ((__builtin_expect(!!(!(ret)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("ret"), "../src/network/networkd-routing-policy-rule.c" , 382, __PRETTY_FUNCTION__); } while (0); | |||
| 383 | assert(!!filename == (section_line > 0))do { if ((__builtin_expect(!!(!(!!filename == (section_line > 0))),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("!!filename == (section_line > 0)" ), "../src/network/networkd-routing-policy-rule.c", 383, __PRETTY_FUNCTION__ ); } while (0); | |||
| 384 | ||||
| 385 | r = network_config_section_new(filename, section_line, &n); | |||
| 386 | if (r < 0) | |||
| 387 | return r; | |||
| 388 | ||||
| 389 | rule = hashmap_get(network->rules_by_section, n); | |||
| 390 | if (rule) { | |||
| 391 | *ret = TAKE_PTR(rule)({ typeof(rule) _ptr_ = (rule); (rule) = ((void*)0); _ptr_; } ); | |||
| 392 | ||||
| 393 | return 0; | |||
| 394 | } | |||
| 395 | ||||
| 396 | r = routing_policy_rule_new(&rule); | |||
| 397 | if (r < 0) | |||
| 398 | return r; | |||
| 399 | ||||
| 400 | rule->section = n; | |||
| 401 | rule->network = network; | |||
| 402 | n = NULL((void*)0); | |||
| 403 | ||||
| 404 | r = hashmap_put(network->rules_by_section, rule->section, rule); | |||
| 405 | if (r < 0) | |||
| 406 | return r; | |||
| 407 | ||||
| 408 | LIST_APPEND(rules, network->rules, rule)do { typeof(*(network->rules)) *_tail; do { typeof(*(network ->rules)) *_item = (network->rules); if (!_item) (_tail ) = ((void*)0); else { while (_item->rules_next) _item = _item ->rules_next; (_tail) = _item; } } while (0); do { typeof( *(network->rules)) **_head = &(network->rules), *_a = (_tail), *_b = (rule); do { if ((__builtin_expect(!!(!(_b) ),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("_b"), "../src/network/networkd-routing-policy-rule.c" , 408, __PRETTY_FUNCTION__); } while (0); if (!_a) { if ((_b-> rules_next = *_head)) _b->rules_next->rules_prev = _b; _b ->rules_prev = ((void*)0); *_head = _b; } else { if ((_b-> rules_next = _a->rules_next)) _b->rules_next->rules_prev = _b; _b->rules_prev = _a; _a->rules_next = _b; } } while (0); } while (0); | |||
| 409 | network->n_rules++; | |||
| 410 | ||||
| 411 | *ret = TAKE_PTR(rule)({ typeof(rule) _ptr_ = (rule); (rule) = ((void*)0); _ptr_; } ); | |||
| 412 | ||||
| 413 | return 0; | |||
| 414 | } | |||
| 415 | ||||
| 416 | int link_routing_policy_rule_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) { | |||
| 417 | _cleanup_(link_unrefp)__attribute__((cleanup(link_unrefp))) Link *link = userdata; | |||
| 418 | int r; | |||
| 419 | ||||
| 420 | assert(rtnl)do { if ((__builtin_expect(!!(!(rtnl)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("rtnl"), "../src/network/networkd-routing-policy-rule.c" , 420, __PRETTY_FUNCTION__); } while (0); | |||
| 421 | assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("m"), "../src/network/networkd-routing-policy-rule.c" , 421, __PRETTY_FUNCTION__); } while (0); | |||
| 422 | assert(link)do { if ((__builtin_expect(!!(!(link)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("link"), "../src/network/networkd-routing-policy-rule.c" , 422, __PRETTY_FUNCTION__); } while (0); | |||
| 423 | assert(link->ifname)do { if ((__builtin_expect(!!(!(link->ifname)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("link->ifname"), "../src/network/networkd-routing-policy-rule.c" , 423, __PRETTY_FUNCTION__); } while (0); | |||
| 424 | assert(link->routing_policy_rule_messages > 0)do { if ((__builtin_expect(!!(!(link->routing_policy_rule_messages > 0)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("link->routing_policy_rule_messages > 0" ), "../src/network/networkd-routing-policy-rule.c", 424, __PRETTY_FUNCTION__ ); } while (0); | |||
| 425 | ||||
| 426 | link->routing_policy_rule_messages--; | |||
| 427 | ||||
| 428 | if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended [20 - sizeof((int[]){LINK_STATE_FAILED, LINK_STATE_LINGER})/sizeof (int)]; switch(link->state) { case LINK_STATE_FAILED: case LINK_STATE_LINGER: _found = 1; break; default: break; } _found ; })) | |||
| 429 | return 1; | |||
| 430 | ||||
| 431 | r = sd_netlink_message_get_errno(m); | |||
| 432 | if (r < 0 && r != -EEXIST17) | |||
| 433 | log_link_warning_errno(link, r, "Could not add routing policy rule: %m")({ const Link *_l = (link); _l ? log_object_internal(4, r, "../src/network/networkd-routing-policy-rule.c" , 433, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((void *)0), "Could not add routing policy rule: %m") : log_internal_realm (((LOG_REALM_SYSTEMD) << 10 | ((4))), r, "../src/network/networkd-routing-policy-rule.c" , 433, __func__, "Could not add routing policy rule: %m"); }); | |||
| 434 | ||||
| 435 | if (link->routing_policy_rule_messages == 0) { | |||
| 436 | log_link_debug(link, "Routing policy rule configured")({ const Link *_l = (link); _l ? log_object_internal(7, 0, "../src/network/networkd-routing-policy-rule.c" , 436, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((void *)0), "Routing policy rule configured") : log_internal_realm( ((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/network/networkd-routing-policy-rule.c" , 436, __func__, "Routing policy rule configured"); }); | |||
| 437 | link->routing_policy_rules_configured = true1; | |||
| 438 | link_check_ready(link); | |||
| 439 | } | |||
| 440 | ||||
| 441 | return 1; | |||
| 442 | } | |||
| 443 | ||||
| 444 | int routing_policy_rule_configure(RoutingPolicyRule *rule, Link *link, sd_netlink_message_handler_t callback, bool_Bool update) { | |||
| 445 | _cleanup_(sd_netlink_message_unrefp)__attribute__((cleanup(sd_netlink_message_unrefp))) sd_netlink_message *m = NULL((void*)0); | |||
| 446 | int r; | |||
| 447 | ||||
| 448 | assert(rule)do { if ((__builtin_expect(!!(!(rule)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("rule"), "../src/network/networkd-routing-policy-rule.c" , 448, __PRETTY_FUNCTION__); } while (0); | |||
| 449 | assert(link)do { if ((__builtin_expect(!!(!(link)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("link"), "../src/network/networkd-routing-policy-rule.c" , 449, __PRETTY_FUNCTION__); } while (0); | |||
| 450 | assert(link->ifindex > 0)do { if ((__builtin_expect(!!(!(link->ifindex > 0)),0)) ) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("link->ifindex > 0" ), "../src/network/networkd-routing-policy-rule.c", 450, __PRETTY_FUNCTION__ ); } while (0); | |||
| 451 | assert(link->manager)do { if ((__builtin_expect(!!(!(link->manager)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("link->manager"), "../src/network/networkd-routing-policy-rule.c" , 451, __PRETTY_FUNCTION__); } while (0); | |||
| 452 | assert(link->manager->rtnl)do { if ((__builtin_expect(!!(!(link->manager->rtnl)),0 ))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("link->manager->rtnl" ), "../src/network/networkd-routing-policy-rule.c", 452, __PRETTY_FUNCTION__ ); } while (0); | |||
| 453 | ||||
| 454 | r = sd_rtnl_message_new_routing_policy_rule(link->manager->rtnl, &m, RTM_NEWRULERTM_NEWRULE, rule->family); | |||
| 455 | if (r < 0) | |||
| 456 | return log_error_errno(r, "Could not allocate RTM_NEWRULE message: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/network/networkd-routing-policy-rule.c", 456, __func__ , "Could not allocate RTM_NEWRULE message: %m") : -abs(_e); } ); | |||
| 457 | ||||
| 458 | if (!in_addr_is_null(rule->family, &rule->from)) { | |||
| 459 | if (rule->family == AF_INET2) | |||
| 460 | r = sd_netlink_message_append_in_addr(m, FRA_SRC, &rule->from.in); | |||
| 461 | else | |||
| 462 | r = sd_netlink_message_append_in6_addr(m, FRA_SRC, &rule->from.in6); | |||
| 463 | ||||
| 464 | if (r < 0) | |||
| 465 | return log_error_errno(r, "Could not append FRA_SRC attribute: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/network/networkd-routing-policy-rule.c", 465, __func__ , "Could not append FRA_SRC attribute: %m") : -abs(_e); }); | |||
| 466 | ||||
| 467 | r = sd_rtnl_message_routing_policy_rule_set_rtm_src_prefixlen(m, rule->from_prefixlen); | |||
| 468 | if (r < 0) | |||
| 469 | return log_error_errno(r, "Could not set source prefix length: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/network/networkd-routing-policy-rule.c", 469, __func__ , "Could not set source prefix length: %m") : -abs(_e); }); | |||
| 470 | } | |||
| 471 | ||||
| 472 | if (!in_addr_is_null(rule->family, &rule->to)) { | |||
| 473 | if (rule->family == AF_INET2) | |||
| 474 | r = sd_netlink_message_append_in_addr(m, FRA_DST, &rule->to.in); | |||
| 475 | else | |||
| 476 | r = sd_netlink_message_append_in6_addr(m, FRA_DST, &rule->to.in6); | |||
| 477 | ||||
| 478 | if (r < 0) | |||
| 479 | return log_error_errno(r, "Could not append FRA_DST attribute: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/network/networkd-routing-policy-rule.c", 479, __func__ , "Could not append FRA_DST attribute: %m") : -abs(_e); }); | |||
| 480 | ||||
| 481 | r = sd_rtnl_message_routing_policy_rule_set_rtm_dst_prefixlen(m, rule->to_prefixlen); | |||
| 482 | if (r < 0) | |||
| 483 | return log_error_errno(r, "Could not set destination prefix length: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/network/networkd-routing-policy-rule.c", 483, __func__ , "Could not set destination prefix length: %m") : -abs(_e); } ); | |||
| 484 | } | |||
| 485 | ||||
| 486 | r = sd_netlink_message_append_u32(m, FRA_PRIORITY, rule->priority); | |||
| 487 | if (r < 0) | |||
| 488 | return log_error_errno(r, "Could not append FRA_PRIORITY attribute: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/network/networkd-routing-policy-rule.c", 488, __func__ , "Could not append FRA_PRIORITY attribute: %m") : -abs(_e); } ); | |||
| 489 | ||||
| 490 | if (rule->tos > 0) { | |||
| 491 | r = sd_rtnl_message_routing_policy_rule_set_tos(m, rule->tos); | |||
| 492 | if (r < 0) | |||
| 493 | return log_error_errno(r, "Could not set ip rule tos: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/network/networkd-routing-policy-rule.c", 493, __func__ , "Could not set ip rule tos: %m") : -abs(_e); }); | |||
| 494 | } | |||
| 495 | ||||
| 496 | if (rule->table < 256) { | |||
| 497 | r = sd_rtnl_message_routing_policy_rule_set_table(m, rule->table); | |||
| 498 | if (r < 0) | |||
| 499 | return log_error_errno(r, "Could not set ip rule table: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/network/networkd-routing-policy-rule.c", 499, __func__ , "Could not set ip rule table: %m") : -abs(_e); }); | |||
| 500 | } else { | |||
| 501 | r = sd_rtnl_message_routing_policy_rule_set_table(m, RT_TABLE_UNSPEC); | |||
| 502 | if (r < 0) | |||
| 503 | return log_error_errno(r, "Could not set ip rule table: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/network/networkd-routing-policy-rule.c", 503, __func__ , "Could not set ip rule table: %m") : -abs(_e); }); | |||
| 504 | ||||
| 505 | r = sd_netlink_message_append_u32(m, FRA_TABLE, rule->table); | |||
| 506 | if (r < 0) | |||
| 507 | return log_error_errno(r, "Could not append FRA_TABLE attribute: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/network/networkd-routing-policy-rule.c", 507, __func__ , "Could not append FRA_TABLE attribute: %m") : -abs(_e); }); | |||
| 508 | } | |||
| 509 | ||||
| 510 | if (rule->fwmark > 0) { | |||
| 511 | r = sd_netlink_message_append_u32(m, FRA_FWMARK, rule->fwmark); | |||
| 512 | if (r < 0) | |||
| 513 | return log_error_errno(r, "Could not append FRA_FWMARK attribute: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/network/networkd-routing-policy-rule.c", 513, __func__ , "Could not append FRA_FWMARK attribute: %m") : -abs(_e); }); | |||
| 514 | } | |||
| 515 | ||||
| 516 | if (rule->fwmask > 0) { | |||
| 517 | r = sd_netlink_message_append_u32(m, FRA_FWMASK, rule->fwmask); | |||
| 518 | if (r < 0) | |||
| 519 | return log_error_errno(r, "Could not append FRA_FWMASK attribute: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/network/networkd-routing-policy-rule.c", 519, __func__ , "Could not append FRA_FWMASK attribute: %m") : -abs(_e); }); | |||
| 520 | } | |||
| 521 | ||||
| 522 | if (rule->iif) { | |||
| 523 | r = sd_netlink_message_append_string(m, FRA_IFNAMEFRA_IIFNAME, rule->iif); | |||
| 524 | if (r < 0) | |||
| 525 | return log_error_errno(r, "Could not append FRA_IFNAME attribute: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/network/networkd-routing-policy-rule.c", 525, __func__ , "Could not append FRA_IFNAME attribute: %m") : -abs(_e); }); | |||
| 526 | } | |||
| 527 | ||||
| 528 | if (rule->oif) { | |||
| 529 | r = sd_netlink_message_append_string(m, FRA_OIFNAME, rule->oif); | |||
| 530 | if (r < 0) | |||
| 531 | return log_error_errno(r, "Could not append FRA_OIFNAME attribute: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/network/networkd-routing-policy-rule.c", 531, __func__ , "Could not append FRA_OIFNAME attribute: %m") : -abs(_e); } ); | |||
| 532 | } | |||
| 533 | ||||
| 534 | rule->link = link; | |||
| 535 | ||||
| 536 | r = sd_netlink_call_async(link->manager->rtnl, m, callback, link, 0, NULL((void*)0)); | |||
| 537 | if (r < 0) | |||
| 538 | return log_error_errno(r, "Could not send rtnetlink message: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/network/networkd-routing-policy-rule.c", 538, __func__ , "Could not send rtnetlink message: %m") : -abs(_e); }); | |||
| 539 | ||||
| 540 | link_ref(link); | |||
| 541 | ||||
| 542 | r = routing_policy_rule_add(link->manager, rule->family, &rule->from, rule->from_prefixlen, &rule->to, | |||
| 543 | rule->to_prefixlen, rule->tos, rule->fwmark, rule->table, rule->iif, rule->oif, NULL((void*)0)); | |||
| 544 | if (r < 0) | |||
| 545 | return log_error_errno(r, "Could not add rule : %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/network/networkd-routing-policy-rule.c", 545, __func__ , "Could not add rule : %m") : -abs(_e); }); | |||
| 546 | ||||
| 547 | return 0; | |||
| 548 | } | |||
| 549 | ||||
| 550 | static int parse_fwmark_fwmask(const char *s, uint32_t *fwmark, uint32_t *fwmask) { | |||
| 551 | _cleanup_free___attribute__((cleanup(freep))) char *f = NULL((void*)0); | |||
| 552 | char *p; | |||
| 553 | int r; | |||
| 554 | ||||
| 555 | assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("s"), "../src/network/networkd-routing-policy-rule.c" , 555, __PRETTY_FUNCTION__); } while (0); | |||
| 556 | ||||
| 557 | f = strdup(s); | |||
| 558 | if (!f) | |||
| 559 | return -ENOMEM12; | |||
| 560 | ||||
| 561 | p = strchr(f, '/'); | |||
| 562 | if (p) | |||
| 563 | *p++ = '\0'; | |||
| 564 | ||||
| 565 | r = safe_atou32(f, fwmark); | |||
| 566 | if (r < 0) | |||
| 567 | return log_error_errno(r, "Failed to parse RPDB rule firewall mark, ignoring: %s", f)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/network/networkd-routing-policy-rule.c", 567, __func__ , "Failed to parse RPDB rule firewall mark, ignoring: %s", f) : -abs(_e); }); | |||
| 568 | ||||
| 569 | if (p) { | |||
| 570 | r = safe_atou32(p, fwmask); | |||
| 571 | if (r < 0) | |||
| 572 | return log_error_errno(r, "Failed to parse RPDB rule mask, ignoring: %s", f)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/network/networkd-routing-policy-rule.c", 572, __func__ , "Failed to parse RPDB rule mask, ignoring: %s", f) : -abs(_e ); }); | |||
| 573 | } | |||
| 574 | ||||
| 575 | return 0; | |||
| 576 | } | |||
| 577 | ||||
| 578 | int config_parse_routing_policy_rule_tos( | |||
| 579 | const char *unit, | |||
| 580 | const char *filename, | |||
| 581 | unsigned line, | |||
| 582 | const char *section, | |||
| 583 | unsigned section_line, | |||
| 584 | const char *lvalue, | |||
| 585 | int ltype, | |||
| 586 | const char *rvalue, | |||
| 587 | void *data, | |||
| 588 | void *userdata) { | |||
| 589 | ||||
| 590 | _cleanup_(routing_policy_rule_freep)__attribute__((cleanup(routing_policy_rule_freep))) RoutingPolicyRule *n = NULL((void*)0); | |||
| 591 | Network *network = userdata; | |||
| 592 | int r; | |||
| 593 | ||||
| 594 | assert(filename)do { if ((__builtin_expect(!!(!(filename)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("filename"), "../src/network/networkd-routing-policy-rule.c" , 594, __PRETTY_FUNCTION__); } while (0); | |||
| 595 | assert(section)do { if ((__builtin_expect(!!(!(section)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("section"), "../src/network/networkd-routing-policy-rule.c" , 595, __PRETTY_FUNCTION__); } while (0); | |||
| 596 | assert(lvalue)do { if ((__builtin_expect(!!(!(lvalue)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("lvalue"), "../src/network/networkd-routing-policy-rule.c" , 596, __PRETTY_FUNCTION__); } while (0); | |||
| 597 | assert(rvalue)do { if ((__builtin_expect(!!(!(rvalue)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("rvalue"), "../src/network/networkd-routing-policy-rule.c" , 597, __PRETTY_FUNCTION__); } while (0); | |||
| 598 | assert(data)do { if ((__builtin_expect(!!(!(data)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("data"), "../src/network/networkd-routing-policy-rule.c" , 598, __PRETTY_FUNCTION__); } while (0); | |||
| 599 | ||||
| 600 | r = routing_policy_rule_new_static(network, filename, section_line, &n); | |||
| 601 | if (r < 0) | |||
| 602 | return r; | |||
| 603 | ||||
| 604 | r = safe_atou8(rvalue, &n->tos); | |||
| 605 | if (r < 0) { | |||
| 606 | log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse RPDB rule tos, ignoring: %s", rvalue)({ int _level = (3), _e = (r); (log_get_max_level_realm(LOG_REALM_SYSTEMD ) >= ((_level) & 0x07)) ? log_syntax_internal(unit, _level , filename, line, _e, "../src/network/networkd-routing-policy-rule.c" , 606, __func__, "Failed to parse RPDB rule tos, ignoring: %s" , rvalue) : -abs(_e); }); | |||
| 607 | return 0; | |||
| 608 | } | |||
| 609 | ||||
| 610 | n = NULL((void*)0); | |||
| 611 | ||||
| 612 | return 0; | |||
| 613 | } | |||
| 614 | ||||
| 615 | int config_parse_routing_policy_rule_priority( | |||
| 616 | const char *unit, | |||
| 617 | const char *filename, | |||
| 618 | unsigned line, | |||
| 619 | const char *section, | |||
| 620 | unsigned section_line, | |||
| 621 | const char *lvalue, | |||
| 622 | int ltype, | |||
| 623 | const char *rvalue, | |||
| 624 | void *data, | |||
| 625 | void *userdata) { | |||
| 626 | ||||
| 627 | _cleanup_(routing_policy_rule_freep)__attribute__((cleanup(routing_policy_rule_freep))) RoutingPolicyRule *n = NULL((void*)0); | |||
| 628 | Network *network = userdata; | |||
| 629 | int r; | |||
| 630 | ||||
| 631 | assert(filename)do { if ((__builtin_expect(!!(!(filename)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("filename"), "../src/network/networkd-routing-policy-rule.c" , 631, __PRETTY_FUNCTION__); } while (0); | |||
| 632 | assert(section)do { if ((__builtin_expect(!!(!(section)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("section"), "../src/network/networkd-routing-policy-rule.c" , 632, __PRETTY_FUNCTION__); } while (0); | |||
| 633 | assert(lvalue)do { if ((__builtin_expect(!!(!(lvalue)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("lvalue"), "../src/network/networkd-routing-policy-rule.c" , 633, __PRETTY_FUNCTION__); } while (0); | |||
| 634 | assert(rvalue)do { if ((__builtin_expect(!!(!(rvalue)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("rvalue"), "../src/network/networkd-routing-policy-rule.c" , 634, __PRETTY_FUNCTION__); } while (0); | |||
| 635 | assert(data)do { if ((__builtin_expect(!!(!(data)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("data"), "../src/network/networkd-routing-policy-rule.c" , 635, __PRETTY_FUNCTION__); } while (0); | |||
| 636 | ||||
| 637 | r = routing_policy_rule_new_static(network, filename, section_line, &n); | |||
| 638 | if (r < 0) | |||
| 639 | return r; | |||
| 640 | ||||
| 641 | r = safe_atou32(rvalue, &n->priority); | |||
| 642 | if (r < 0) { | |||
| 643 | log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse RPDB rule priority, ignoring: %s", rvalue)({ int _level = (3), _e = (r); (log_get_max_level_realm(LOG_REALM_SYSTEMD ) >= ((_level) & 0x07)) ? log_syntax_internal(unit, _level , filename, line, _e, "../src/network/networkd-routing-policy-rule.c" , 643, __func__, "Failed to parse RPDB rule priority, ignoring: %s" , rvalue) : -abs(_e); }); | |||
| 644 | return 0; | |||
| 645 | } | |||
| 646 | ||||
| 647 | n = NULL((void*)0); | |||
| 648 | ||||
| 649 | return 0; | |||
| 650 | } | |||
| 651 | ||||
| 652 | int config_parse_routing_policy_rule_table( | |||
| 653 | const char *unit, | |||
| 654 | const char *filename, | |||
| 655 | unsigned line, | |||
| 656 | const char *section, | |||
| 657 | unsigned section_line, | |||
| 658 | const char *lvalue, | |||
| 659 | int ltype, | |||
| 660 | const char *rvalue, | |||
| 661 | void *data, | |||
| 662 | void *userdata) { | |||
| 663 | ||||
| 664 | _cleanup_(routing_policy_rule_freep)__attribute__((cleanup(routing_policy_rule_freep))) RoutingPolicyRule *n = NULL((void*)0); | |||
| 665 | Network *network = userdata; | |||
| 666 | int r; | |||
| 667 | ||||
| 668 | assert(filename)do { if ((__builtin_expect(!!(!(filename)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("filename"), "../src/network/networkd-routing-policy-rule.c" , 668, __PRETTY_FUNCTION__); } while (0); | |||
| 669 | assert(section)do { if ((__builtin_expect(!!(!(section)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("section"), "../src/network/networkd-routing-policy-rule.c" , 669, __PRETTY_FUNCTION__); } while (0); | |||
| 670 | assert(lvalue)do { if ((__builtin_expect(!!(!(lvalue)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("lvalue"), "../src/network/networkd-routing-policy-rule.c" , 670, __PRETTY_FUNCTION__); } while (0); | |||
| 671 | assert(rvalue)do { if ((__builtin_expect(!!(!(rvalue)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("rvalue"), "../src/network/networkd-routing-policy-rule.c" , 671, __PRETTY_FUNCTION__); } while (0); | |||
| 672 | assert(data)do { if ((__builtin_expect(!!(!(data)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("data"), "../src/network/networkd-routing-policy-rule.c" , 672, __PRETTY_FUNCTION__); } while (0); | |||
| 673 | ||||
| 674 | r = routing_policy_rule_new_static(network, filename, section_line, &n); | |||
| 675 | if (r < 0) | |||
| 676 | return r; | |||
| 677 | ||||
| 678 | r = safe_atou32(rvalue, &n->table); | |||
| 679 | if (r < 0) { | |||
| 680 | log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse RPDB rule table, ignoring: %s", rvalue)({ int _level = (3), _e = (r); (log_get_max_level_realm(LOG_REALM_SYSTEMD ) >= ((_level) & 0x07)) ? log_syntax_internal(unit, _level , filename, line, _e, "../src/network/networkd-routing-policy-rule.c" , 680, __func__, "Failed to parse RPDB rule table, ignoring: %s" , rvalue) : -abs(_e); }); | |||
| 681 | return 0; | |||
| 682 | } | |||
| 683 | ||||
| 684 | n = NULL((void*)0); | |||
| 685 | ||||
| 686 | return 0; | |||
| 687 | } | |||
| 688 | ||||
| 689 | int config_parse_routing_policy_rule_fwmark_mask( | |||
| 690 | const char *unit, | |||
| 691 | const char *filename, | |||
| 692 | unsigned line, | |||
| 693 | const char *section, | |||
| 694 | unsigned section_line, | |||
| 695 | const char *lvalue, | |||
| 696 | int ltype, | |||
| 697 | const char *rvalue, | |||
| 698 | void *data, | |||
| 699 | void *userdata) { | |||
| 700 | ||||
| 701 | _cleanup_(routing_policy_rule_freep)__attribute__((cleanup(routing_policy_rule_freep))) RoutingPolicyRule *n = NULL((void*)0); | |||
| 702 | Network *network = userdata; | |||
| 703 | int r; | |||
| 704 | ||||
| 705 | assert(filename)do { if ((__builtin_expect(!!(!(filename)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("filename"), "../src/network/networkd-routing-policy-rule.c" , 705, __PRETTY_FUNCTION__); } while (0); | |||
| 706 | assert(section)do { if ((__builtin_expect(!!(!(section)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("section"), "../src/network/networkd-routing-policy-rule.c" , 706, __PRETTY_FUNCTION__); } while (0); | |||
| 707 | assert(lvalue)do { if ((__builtin_expect(!!(!(lvalue)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("lvalue"), "../src/network/networkd-routing-policy-rule.c" , 707, __PRETTY_FUNCTION__); } while (0); | |||
| 708 | assert(rvalue)do { if ((__builtin_expect(!!(!(rvalue)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("rvalue"), "../src/network/networkd-routing-policy-rule.c" , 708, __PRETTY_FUNCTION__); } while (0); | |||
| 709 | assert(data)do { if ((__builtin_expect(!!(!(data)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("data"), "../src/network/networkd-routing-policy-rule.c" , 709, __PRETTY_FUNCTION__); } while (0); | |||
| 710 | ||||
| 711 | r = routing_policy_rule_new_static(network, filename, section_line, &n); | |||
| 712 | if (r < 0) | |||
| 713 | return r; | |||
| 714 | ||||
| 715 | r = parse_fwmark_fwmask(rvalue, &n->fwmark, &n->fwmask); | |||
| 716 | if (r < 0) { | |||
| 717 | log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse RPDB rule firewall mark or mask, ignoring: %s", rvalue)({ int _level = (3), _e = (r); (log_get_max_level_realm(LOG_REALM_SYSTEMD ) >= ((_level) & 0x07)) ? log_syntax_internal(unit, _level , filename, line, _e, "../src/network/networkd-routing-policy-rule.c" , 717, __func__, "Failed to parse RPDB rule firewall mark or mask, ignoring: %s" , rvalue) : -abs(_e); }); | |||
| 718 | return 0; | |||
| 719 | } | |||
| 720 | ||||
| 721 | n = NULL((void*)0); | |||
| 722 | ||||
| 723 | return 0; | |||
| 724 | } | |||
| 725 | ||||
| 726 | int config_parse_routing_policy_rule_prefix( | |||
| 727 | const char *unit, | |||
| 728 | const char *filename, | |||
| 729 | unsigned line, | |||
| 730 | const char *section, | |||
| 731 | unsigned section_line, | |||
| 732 | const char *lvalue, | |||
| 733 | int ltype, | |||
| 734 | const char *rvalue, | |||
| 735 | void *data, | |||
| 736 | void *userdata) { | |||
| 737 | ||||
| 738 | _cleanup_(routing_policy_rule_freep)__attribute__((cleanup(routing_policy_rule_freep))) RoutingPolicyRule *n = NULL((void*)0); | |||
| 739 | Network *network = userdata; | |||
| 740 | union in_addr_union buffer; | |||
| 741 | uint8_t prefixlen; | |||
| 742 | int r; | |||
| 743 | ||||
| 744 | assert(filename)do { if ((__builtin_expect(!!(!(filename)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("filename"), "../src/network/networkd-routing-policy-rule.c" , 744, __PRETTY_FUNCTION__); } while (0); | |||
| 745 | assert(section)do { if ((__builtin_expect(!!(!(section)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("section"), "../src/network/networkd-routing-policy-rule.c" , 745, __PRETTY_FUNCTION__); } while (0); | |||
| 746 | assert(lvalue)do { if ((__builtin_expect(!!(!(lvalue)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("lvalue"), "../src/network/networkd-routing-policy-rule.c" , 746, __PRETTY_FUNCTION__); } while (0); | |||
| 747 | assert(rvalue)do { if ((__builtin_expect(!!(!(rvalue)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("rvalue"), "../src/network/networkd-routing-policy-rule.c" , 747, __PRETTY_FUNCTION__); } while (0); | |||
| 748 | assert(data)do { if ((__builtin_expect(!!(!(data)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("data"), "../src/network/networkd-routing-policy-rule.c" , 748, __PRETTY_FUNCTION__); } while (0); | |||
| 749 | ||||
| 750 | r = routing_policy_rule_new_static(network, filename, section_line, &n); | |||
| 751 | if (r < 0) | |||
| 752 | return r; | |||
| 753 | ||||
| 754 | r = in_addr_prefix_from_string(rvalue, AF_INET2, &buffer, &prefixlen); | |||
| 755 | if (r < 0) { | |||
| 756 | r = in_addr_prefix_from_string(rvalue, AF_INET610, &buffer, &prefixlen); | |||
| 757 | if (r < 0) { | |||
| 758 | log_syntax(unit, LOG_ERR, filename, line, r, "RPDB rule prefix is invalid, ignoring assignment: %s", rvalue)({ int _level = (3), _e = (r); (log_get_max_level_realm(LOG_REALM_SYSTEMD ) >= ((_level) & 0x07)) ? log_syntax_internal(unit, _level , filename, line, _e, "../src/network/networkd-routing-policy-rule.c" , 758, __func__, "RPDB rule prefix is invalid, ignoring assignment: %s" , rvalue) : -abs(_e); }); | |||
| 759 | return 0; | |||
| 760 | } | |||
| 761 | ||||
| 762 | n->family = AF_INET610; | |||
| 763 | } else | |||
| 764 | n->family = AF_INET2; | |||
| 765 | ||||
| 766 | if (streq(lvalue, "To")(strcmp((lvalue),("To")) == 0)) { | |||
| 767 | n->to = buffer; | |||
| 768 | n->to_prefixlen = prefixlen; | |||
| 769 | } else { | |||
| 770 | n->from = buffer; | |||
| 771 | n->from_prefixlen = prefixlen; | |||
| 772 | } | |||
| 773 | ||||
| 774 | n = NULL((void*)0); | |||
| 775 | ||||
| 776 | return 0; | |||
| 777 | } | |||
| 778 | ||||
| 779 | int config_parse_routing_policy_rule_device( | |||
| 780 | const char *unit, | |||
| 781 | const char *filename, | |||
| 782 | unsigned line, | |||
| 783 | const char *section, | |||
| 784 | unsigned section_line, | |||
| 785 | const char *lvalue, | |||
| 786 | int ltype, | |||
| 787 | const char *rvalue, | |||
| 788 | void *data, | |||
| 789 | void *userdata) { | |||
| 790 | ||||
| 791 | _cleanup_(routing_policy_rule_freep)__attribute__((cleanup(routing_policy_rule_freep))) RoutingPolicyRule *n = NULL((void*)0); | |||
| 792 | Network *network = userdata; | |||
| 793 | int r; | |||
| 794 | ||||
| 795 | assert(filename)do { if ((__builtin_expect(!!(!(filename)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("filename"), "../src/network/networkd-routing-policy-rule.c" , 795, __PRETTY_FUNCTION__); } while (0); | |||
| 796 | assert(section)do { if ((__builtin_expect(!!(!(section)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("section"), "../src/network/networkd-routing-policy-rule.c" , 796, __PRETTY_FUNCTION__); } while (0); | |||
| 797 | assert(lvalue)do { if ((__builtin_expect(!!(!(lvalue)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("lvalue"), "../src/network/networkd-routing-policy-rule.c" , 797, __PRETTY_FUNCTION__); } while (0); | |||
| 798 | assert(rvalue)do { if ((__builtin_expect(!!(!(rvalue)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("rvalue"), "../src/network/networkd-routing-policy-rule.c" , 798, __PRETTY_FUNCTION__); } while (0); | |||
| 799 | assert(data)do { if ((__builtin_expect(!!(!(data)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("data"), "../src/network/networkd-routing-policy-rule.c" , 799, __PRETTY_FUNCTION__); } while (0); | |||
| 800 | ||||
| 801 | r = routing_policy_rule_new_static(network, filename, section_line, &n); | |||
| 802 | if (r < 0) | |||
| 803 | return r; | |||
| 804 | ||||
| 805 | if (!ifname_valid(rvalue)) { | |||
| 806 | log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse '%s' interface name, ignoring: %s", lvalue, rvalue)({ int _level = (3), _e = (r); (log_get_max_level_realm(LOG_REALM_SYSTEMD ) >= ((_level) & 0x07)) ? log_syntax_internal(unit, _level , filename, line, _e, "../src/network/networkd-routing-policy-rule.c" , 806, __func__, "Failed to parse '%s' interface name, ignoring: %s" , lvalue, rvalue) : -abs(_e); }); | |||
| 807 | return 0; | |||
| 808 | } | |||
| 809 | ||||
| 810 | if (streq(lvalue, "IncomingInterface")(strcmp((lvalue),("IncomingInterface")) == 0)) { | |||
| 811 | r = free_and_strdup(&n->iif, rvalue); | |||
| 812 | if (r < 0) | |||
| 813 | return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/network/networkd-routing-policy-rule.c" , 813, __func__); | |||
| 814 | } else { | |||
| 815 | r = free_and_strdup(&n->oif, rvalue); | |||
| 816 | if (r < 0) | |||
| 817 | return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/network/networkd-routing-policy-rule.c" , 817, __func__); | |||
| 818 | } | |||
| 819 | ||||
| 820 | n = NULL((void*)0); | |||
| 821 | ||||
| 822 | return 0; | |||
| 823 | } | |||
| 824 | ||||
| 825 | static int routing_policy_rule_read_full_file(const char *state_file, char **ret) { | |||
| 826 | _cleanup_free___attribute__((cleanup(freep))) char *s = NULL((void*)0); | |||
| 827 | size_t size; | |||
| 828 | int r; | |||
| 829 | ||||
| 830 | assert(state_file)do { if ((__builtin_expect(!!(!(state_file)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("state_file"), "../src/network/networkd-routing-policy-rule.c" , 830, __PRETTY_FUNCTION__); } while (0); | |||
| 831 | ||||
| 832 | r = read_full_file(state_file, &s, &size); | |||
| 833 | if (r == -ENOENT2) | |||
| 834 | return -ENODATA61; | |||
| 835 | if (r < 0) | |||
| 836 | return r; | |||
| 837 | if (size <= 0) | |||
| 838 | return -ENODATA61; | |||
| 839 | ||||
| 840 | *ret = TAKE_PTR(s)({ typeof(s) _ptr_ = (s); (s) = ((void*)0); _ptr_; }); | |||
| 841 | ||||
| 842 | return size; | |||
| 843 | } | |||
| 844 | ||||
| 845 | int routing_policy_serialize_rules(Set *rules, FILE *f) { | |||
| 846 | RoutingPolicyRule *rule = NULL((void*)0); | |||
| 847 | Iterator i; | |||
| 848 | int r; | |||
| 849 | ||||
| 850 | assert(f)do { if ((__builtin_expect(!!(!(f)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("f"), "../src/network/networkd-routing-policy-rule.c" , 850, __PRETTY_FUNCTION__); } while (0); | |||
| 851 | ||||
| 852 | SET_FOREACH(rule, rules, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), . next_key = ((void*)0) }); set_iterate((rules), &(i), (void **)&(rule)); ) { | |||
| 853 | _cleanup_free___attribute__((cleanup(freep))) char *from_str = NULL((void*)0), *to_str = NULL((void*)0); | |||
| 854 | bool_Bool space = false0; | |||
| 855 | ||||
| 856 | fputs("RULE=", f); | |||
| 857 | ||||
| 858 | if (!in_addr_is_null(rule->family, &rule->from)) { | |||
| 859 | r = in_addr_to_string(rule->family, &rule->from, &from_str); | |||
| 860 | if (r < 0) | |||
| 861 | return r; | |||
| 862 | ||||
| 863 | fprintf(f, "from=%s/%hhu", | |||
| 864 | from_str, rule->from_prefixlen); | |||
| 865 | space = true1; | |||
| 866 | } | |||
| 867 | ||||
| 868 | if (!in_addr_is_null(rule->family, &rule->to)) { | |||
| 869 | r = in_addr_to_string(rule->family, &rule->to, &to_str); | |||
| 870 | if (r < 0) | |||
| 871 | return r; | |||
| 872 | ||||
| 873 | fprintf(f, "%sto=%s/%hhu", | |||
| 874 | space ? " " : "", | |||
| 875 | to_str, rule->to_prefixlen); | |||
| 876 | space = true1; | |||
| 877 | } | |||
| 878 | ||||
| 879 | if (rule->tos != 0) { | |||
| 880 | fprintf(f, "%stos=%hhu", | |||
| 881 | space ? " " : "", | |||
| 882 | rule->tos); | |||
| 883 | space = true1; | |||
| 884 | } | |||
| 885 | ||||
| 886 | if (rule->fwmark != 0) { | |||
| 887 | fprintf(f, "%sfwmark=%"PRIu32"u""/%"PRIu32"u", | |||
| 888 | space ? " " : "", | |||
| 889 | rule->fwmark, rule->fwmask); | |||
| 890 | space = true1; | |||
| 891 | } | |||
| 892 | ||||
| 893 | if (rule->iif) { | |||
| 894 | fprintf(f, "%siif=%s", | |||
| 895 | space ? " " : "", | |||
| 896 | rule->iif); | |||
| 897 | space = true1; | |||
| 898 | } | |||
| 899 | ||||
| 900 | if (rule->oif) { | |||
| 901 | fprintf(f, "%soif=%s", | |||
| 902 | space ? " " : "", | |||
| 903 | rule->oif); | |||
| 904 | space = true1; | |||
| 905 | } | |||
| 906 | ||||
| 907 | fprintf(f, "%stable=%"PRIu32"u" "\n", | |||
| 908 | space ? " " : "", | |||
| 909 | rule->table); | |||
| 910 | } | |||
| 911 | ||||
| 912 | return 0; | |||
| 913 | } | |||
| 914 | ||||
| 915 | int routing_policy_load_rules(const char *state_file, Set **rules) { | |||
| 916 | _cleanup_strv_free___attribute__((cleanup(strv_freep))) char **l = NULL((void*)0); | |||
| 917 | _cleanup_free___attribute__((cleanup(freep))) char *data = NULL((void*)0); | |||
| 918 | const char *p; | |||
| 919 | char **i; | |||
| 920 | int r; | |||
| 921 | ||||
| 922 | assert(state_file)do { if ((__builtin_expect(!!(!(state_file)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("state_file"), "../src/network/networkd-routing-policy-rule.c" , 922, __PRETTY_FUNCTION__); } while (0); | |||
| ||||
| 923 | assert(rules)do { if ((__builtin_expect(!!(!(rules)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("rules"), "../src/network/networkd-routing-policy-rule.c" , 923, __PRETTY_FUNCTION__); } while (0); | |||
| 924 | ||||
| 925 | r = routing_policy_rule_read_full_file(state_file, &data); | |||
| 926 | if (r
| |||
| 927 | return r; | |||
| 928 | ||||
| 929 | l = strv_split_newlines(data); | |||
| 930 | if (!l) | |||
| 931 | return -ENOMEM12; | |||
| 932 | ||||
| 933 | r = set_ensure_allocated(rules, &routing_policy_rule_hash_ops)internal_set_ensure_allocated(rules, &routing_policy_rule_hash_ops ); | |||
| 934 | if (r < 0) | |||
| 935 | return r; | |||
| 936 | ||||
| 937 | STRV_FOREACH(i, l)for ((i) = (l); (i) && *(i); (i)++) { | |||
| 938 | _cleanup_(routing_policy_rule_freep)__attribute__((cleanup(routing_policy_rule_freep))) RoutingPolicyRule *rule = NULL((void*)0); | |||
| 939 | ||||
| 940 | p = startswith(*i, "RULE="); | |||
| 941 | if (!p
| |||
| 942 | continue; | |||
| 943 | ||||
| 944 | r = routing_policy_rule_new(&rule); | |||
| 945 | if (r
| |||
| 946 | return r; | |||
| 947 | ||||
| 948 | for (;;) { | |||
| 949 | _cleanup_free___attribute__((cleanup(freep))) char *word = NULL((void*)0), *a = NULL((void*)0), *b = NULL((void*)0); | |||
| 950 | union in_addr_union buffer; | |||
| 951 | uint8_t prefixlen; | |||
| 952 | ||||
| 953 | r = extract_first_word(&p, &word, NULL((void*)0), 0); | |||
| 954 | if (r < 0) | |||
| 955 | return r; | |||
| ||||
| 956 | if (r == 0) | |||
| 957 | break; | |||
| 958 | ||||
| 959 | r = split_pair(word, "=", &a, &b); | |||
| 960 | if (r < 0) | |||
| 961 | continue; | |||
| 962 | ||||
| 963 | if (STR_IN_SET(a, "from", "to")(!!strv_find((((char**) ((const char*[]) { "from", "to", ((void *)0) }))), (a)))) { | |||
| 964 | ||||
| 965 | r = in_addr_prefix_from_string(b, AF_INET2, &buffer, &prefixlen); | |||
| 966 | if (r < 0) { | |||
| 967 | r = in_addr_prefix_from_string(b, AF_INET610, &buffer, &prefixlen); | |||
| 968 | if (r < 0) { | |||
| 969 | log_error_errno(r, "RPDB rule prefix is invalid, ignoring assignment: %s", b)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/network/networkd-routing-policy-rule.c", 969, __func__ , "RPDB rule prefix is invalid, ignoring assignment: %s", b) : -abs(_e); }); | |||
| 970 | continue; | |||
| 971 | } | |||
| 972 | ||||
| 973 | rule->family = AF_INET610; | |||
| 974 | } else | |||
| 975 | rule->family = AF_INET2; | |||
| 976 | ||||
| 977 | if (streq(a, "to")(strcmp((a),("to")) == 0)) { | |||
| 978 | rule->to = buffer; | |||
| 979 | rule->to_prefixlen = prefixlen; | |||
| 980 | } else { | |||
| 981 | rule->from = buffer; | |||
| 982 | rule->from_prefixlen = prefixlen; | |||
| 983 | } | |||
| 984 | } else if (streq(a, "tos")(strcmp((a),("tos")) == 0)) { | |||
| 985 | r = safe_atou8(b, &rule->tos); | |||
| 986 | if (r < 0) { | |||
| 987 | log_error_errno(r, "Failed to parse RPDB rule tos, ignoring: %s", b)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/network/networkd-routing-policy-rule.c", 987, __func__ , "Failed to parse RPDB rule tos, ignoring: %s", b) : -abs(_e ); }); | |||
| 988 | continue; | |||
| 989 | } | |||
| 990 | } else if (streq(a, "table")(strcmp((a),("table")) == 0)) { | |||
| 991 | r = safe_atou32(b, &rule->table); | |||
| 992 | if (r < 0) { | |||
| 993 | log_error_errno(r, "Failed to parse RPDB rule table, ignoring: %s", b)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/network/networkd-routing-policy-rule.c", 993, __func__ , "Failed to parse RPDB rule table, ignoring: %s", b) : -abs( _e); }); | |||
| 994 | continue; | |||
| 995 | } | |||
| 996 | } else if (streq(a, "fwmark")(strcmp((a),("fwmark")) == 0)) { | |||
| 997 | ||||
| 998 | r = parse_fwmark_fwmask(b, &rule->fwmark, &rule->fwmask); | |||
| 999 | if (r < 0) { | |||
| 1000 | log_error_errno(r, "Failed to parse RPDB rule firewall mark or mask, ignoring: %s", a)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/network/networkd-routing-policy-rule.c", 1000, __func__ , "Failed to parse RPDB rule firewall mark or mask, ignoring: %s" , a) : -abs(_e); }); | |||
| 1001 | continue; | |||
| 1002 | } | |||
| 1003 | } else if (streq(a, "iif")(strcmp((a),("iif")) == 0)) { | |||
| 1004 | ||||
| 1005 | if (free_and_strdup(&rule->iif, b) < 0) | |||
| 1006 | return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/network/networkd-routing-policy-rule.c" , 1006, __func__); | |||
| 1007 | ||||
| 1008 | } else if (streq(a, "oif")(strcmp((a),("oif")) == 0)) { | |||
| 1009 | ||||
| 1010 | if (free_and_strdup(&rule->oif, b) < 0) | |||
| 1011 | return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/network/networkd-routing-policy-rule.c" , 1011, __func__); | |||
| 1012 | } | |||
| 1013 | } | |||
| 1014 | ||||
| 1015 | r = set_put(*rules, rule); | |||
| 1016 | if (r < 0) { | |||
| 1017 | log_warning_errno(r, "Failed to add RPDB rule to saved DB, ignoring: %s", p)({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/network/networkd-routing-policy-rule.c", 1017, __func__ , "Failed to add RPDB rule to saved DB, ignoring: %s", p) : - abs(_e); }); | |||
| 1018 | continue; | |||
| 1019 | } | |||
| 1020 | ||||
| 1021 | rule = NULL((void*)0); | |||
| 1022 | } | |||
| 1023 | ||||
| 1024 | return 0; | |||
| 1025 | } | |||
| 1026 | ||||
| 1027 | void routing_policy_rule_purge(Manager *m, Link *link) { | |||
| 1028 | RoutingPolicyRule *rule, *existing; | |||
| 1029 | Iterator i; | |||
| 1030 | int r; | |||
| 1031 | ||||
| 1032 | assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("m"), "../src/network/networkd-routing-policy-rule.c" , 1032, __PRETTY_FUNCTION__); } while (0); | |||
| 1033 | assert(link)do { if ((__builtin_expect(!!(!(link)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("link"), "../src/network/networkd-routing-policy-rule.c" , 1033, __PRETTY_FUNCTION__); } while (0); | |||
| 1034 | ||||
| 1035 | SET_FOREACH(rule, m->rules_saved, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), . next_key = ((void*)0) }); set_iterate((m->rules_saved), & (i), (void**)&(rule)); ) { | |||
| 1036 | existing = set_get(m->rules_foreign, rule); | |||
| 1037 | if (existing) { | |||
| 1038 | ||||
| 1039 | r = routing_policy_rule_remove(rule, link, routing_policy_rule_remove_handler); | |||
| 1040 | if (r < 0) { | |||
| 1041 | log_warning_errno(r, "Could not remove routing policy rules: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/network/networkd-routing-policy-rule.c", 1041, __func__ , "Could not remove routing policy rules: %m") : -abs(_e); }); | |||
| 1042 | continue; | |||
| 1043 | } | |||
| 1044 | ||||
| 1045 | link->routing_policy_rule_remove_messages++; | |||
| 1046 | } | |||
| 1047 | } | |||
| 1048 | } |