diff options
Diffstat (limited to 'src/network/networkd-address.c')
-rw-r--r-- | src/network/networkd-address.c | 103 |
1 files changed, 58 insertions, 45 deletions
diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c index 0414ced48a..48715972b6 100644 --- a/src/network/networkd-address.c +++ b/src/network/networkd-address.c @@ -198,6 +198,33 @@ bool address_equal(Address *a1, Address *a2) { return address_compare_func(a1, a2) == 0; } +static int address_establish(Address *address, Link *link) { + bool masq; + int r; + + assert(address); + assert(link); + + masq = link->network && + link->network->ip_masquerade && + address->family == AF_INET && + address->scope < RT_SCOPE_LINK; + + /* Add firewall entry if this is requested */ + if (address->ip_masquerade_done != masq) { + union in_addr_union masked = address->in_addr; + in_addr_mask(address->family, &masked, address->prefixlen); + + r = fw_add_masquerade(masq, AF_INET, 0, &masked, address->prefixlen, NULL, NULL, 0); + if (r < 0) + log_link_warning_errno(link, r, "Could not enable IP masquerading: %m"); + + address->ip_masquerade_done = masq; + } + + return 0; +} + int address_add(Link *link, int family, const union in_addr_union *in_addr, unsigned char prefixlen, Address **ret) { _cleanup_address_free_ Address *address = NULL; int r; @@ -224,81 +251,67 @@ int address_add(Link *link, int family, const union in_addr_union *in_addr, unsi address->link = link; + r = address_establish(address, link); + if (r < 0) + return r; + *ret = address; address = NULL; return 0; } -int address_get(Link *link, int family, const union in_addr_union *in_addr, unsigned char prefixlen, Address **ret) { - Address address = {}, *existing; - - assert(link); - assert(in_addr); - assert(ret); - - address.family = family; - address.in_addr = *in_addr; - address.prefixlen = prefixlen; - - existing = set_get(link->addresses, &address); - if (!existing) - return -ENOENT; - - *ret = existing; - - return 0; -} - -int address_establish(Address *address, Link *link) { - bool masq; +static int address_release(Address *address, Link *link) { int r; assert(address); assert(link); - masq = link->network && - link->network->ip_masquerade && - address->family == AF_INET && - address->scope < RT_SCOPE_LINK; - - /* Add firewall entry if this is requested */ - if (address->ip_masquerade_done != masq) { + /* Remove masquerading firewall entry if it was added */ + if (address->ip_masquerade_done) { union in_addr_union masked = address->in_addr; in_addr_mask(address->family, &masked, address->prefixlen); - r = fw_add_masquerade(masq, AF_INET, 0, &masked, address->prefixlen, NULL, NULL, 0); + r = fw_add_masquerade(false, AF_INET, 0, &masked, address->prefixlen, NULL, NULL, 0); if (r < 0) - log_link_warning_errno(link, r, "Could not enable IP masquerading: %m"); + log_link_warning_errno(link, r, "Failed to disable IP masquerading: %m"); - address->ip_masquerade_done = masq; + address->ip_masquerade_done = false; } return 0; } -int address_release(Address *address, Link *link) { - int r; - +int address_drop(Address *address) { assert(address); + + address_release(address, address->link); + address_free(address); + + return 0; +} + +int address_get(Link *link, int family, const union in_addr_union *in_addr, unsigned char prefixlen, Address **ret) { + Address address = {}, *existing; + assert(link); + assert(in_addr); + assert(ret); - /* Remove masquerading firewall entry if it was added */ - if (address->ip_masquerade_done) { - union in_addr_union masked = address->in_addr; - in_addr_mask(address->family, &masked, address->prefixlen); + address.family = family; + address.in_addr = *in_addr; + address.prefixlen = prefixlen; - r = fw_add_masquerade(false, AF_INET, 0, &masked, address->prefixlen, NULL, NULL, 0); - if (r < 0) - log_link_warning_errno(link, r, "Failed to disable IP masquerading: %m"); + existing = set_get(link->addresses, &address); + if (!existing) + return -ENOENT; - address->ip_masquerade_done = false; - } + *ret = existing; return 0; } -int address_drop(Address *address, Link *link, +int address_remove(Address *address, Link *link, sd_netlink_message_handler_t callback) { _cleanup_netlink_message_unref_ sd_netlink_message *req = NULL; int r; |