mirror of
https://github.com/systemd/systemd.git
synced 2024-11-01 17:51:22 +03:00
networkd: also enforce limit on total number of address/routes
This covers the address/routers acquire dynamically.
This commit is contained in:
parent
a60a720c7e
commit
1b56607157
@ -32,6 +32,7 @@
|
|||||||
#include "utf8.h"
|
#include "utf8.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
#define ADDRESSES_PER_LINK_MAX 2048U
|
||||||
#define STATIC_ADDRESSES_PER_NETWORK_MAX 1024U
|
#define STATIC_ADDRESSES_PER_NETWORK_MAX 1024U
|
||||||
|
|
||||||
int address_new(Address **ret) {
|
int address_new(Address **ret) {
|
||||||
@ -392,31 +393,38 @@ int address_drop(Address *address) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int address_get(Link *link, int family, const union in_addr_union *in_addr, unsigned char prefixlen, Address **ret) {
|
int address_get(Link *link,
|
||||||
Address address = {}, *existing;
|
int family,
|
||||||
|
const union in_addr_union *in_addr,
|
||||||
|
unsigned char prefixlen,
|
||||||
|
Address **ret) {
|
||||||
|
|
||||||
|
Address address, *existing;
|
||||||
|
|
||||||
assert(link);
|
assert(link);
|
||||||
assert(in_addr);
|
assert(in_addr);
|
||||||
assert(ret);
|
|
||||||
|
|
||||||
address.family = family;
|
address = (Address) {
|
||||||
address.in_addr = *in_addr;
|
.family = family,
|
||||||
address.prefixlen = prefixlen;
|
.in_addr = *in_addr,
|
||||||
|
.prefixlen = prefixlen,
|
||||||
|
};
|
||||||
|
|
||||||
existing = set_get(link->addresses, &address);
|
existing = set_get(link->addresses, &address);
|
||||||
if (existing) {
|
if (existing) {
|
||||||
*ret = existing;
|
if (ret)
|
||||||
|
*ret = existing;
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
|
||||||
existing = set_get(link->addresses_foreign, &address);
|
|
||||||
if (!existing)
|
|
||||||
return -ENOENT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*ret = existing;
|
existing = set_get(link->addresses_foreign, &address);
|
||||||
|
if (existing) {
|
||||||
|
if (ret)
|
||||||
|
*ret = existing;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
int address_remove(
|
int address_remove(
|
||||||
@ -518,7 +526,12 @@ static int address_acquire(Link *link, Address *original, Address **ret) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int address_configure(Address *address, Link *link, sd_netlink_message_handler_t callback, bool update) {
|
int address_configure(
|
||||||
|
Address *address,
|
||||||
|
Link *link,
|
||||||
|
sd_netlink_message_handler_t callback,
|
||||||
|
bool update) {
|
||||||
|
|
||||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
|
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
@ -529,6 +542,11 @@ int address_configure(Address *address, Link *link, sd_netlink_message_handler_t
|
|||||||
assert(link->manager);
|
assert(link->manager);
|
||||||
assert(link->manager->rtnl);
|
assert(link->manager->rtnl);
|
||||||
|
|
||||||
|
/* If this is a new address, then refuse adding more than the limit */
|
||||||
|
if (address_get(link, address->family, &address->in_addr, address->prefixlen, NULL) <= 0 &&
|
||||||
|
set_size(link->addresses) >= ADDRESSES_PER_LINK_MAX)
|
||||||
|
return -E2BIG;
|
||||||
|
|
||||||
r = address_acquire(link, address, &address);
|
r = address_acquire(link, address, &address);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include "string-util.h"
|
#include "string-util.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
#define ROUTES_PER_LINK_MAX 2048U
|
||||||
#define STATIC_ROUTES_PER_NETWORK_MAX 1024U
|
#define STATIC_ROUTES_PER_NETWORK_MAX 1024U
|
||||||
|
|
||||||
int route_new(Route **ret) {
|
int route_new(Route **ret) {
|
||||||
@ -187,39 +188,42 @@ static const struct hash_ops route_hash_ops = {
|
|||||||
|
|
||||||
int route_get(Link *link,
|
int route_get(Link *link,
|
||||||
int family,
|
int family,
|
||||||
union in_addr_union *dst,
|
const union in_addr_union *dst,
|
||||||
unsigned char dst_prefixlen,
|
unsigned char dst_prefixlen,
|
||||||
unsigned char tos,
|
unsigned char tos,
|
||||||
uint32_t priority,
|
uint32_t priority,
|
||||||
unsigned char table,
|
unsigned char table,
|
||||||
Route **ret) {
|
Route **ret) {
|
||||||
Route route = {
|
|
||||||
|
Route route, *existing;
|
||||||
|
|
||||||
|
assert(link);
|
||||||
|
assert(dst);
|
||||||
|
|
||||||
|
route = (Route) {
|
||||||
.family = family,
|
.family = family,
|
||||||
|
.dst = *dst,
|
||||||
.dst_prefixlen = dst_prefixlen,
|
.dst_prefixlen = dst_prefixlen,
|
||||||
.tos = tos,
|
.tos = tos,
|
||||||
.priority = priority,
|
.priority = priority,
|
||||||
.table = table,
|
.table = table,
|
||||||
}, *existing;
|
};
|
||||||
|
|
||||||
assert(link);
|
|
||||||
assert(dst);
|
|
||||||
assert(ret);
|
|
||||||
|
|
||||||
route.dst = *dst;
|
|
||||||
|
|
||||||
existing = set_get(link->routes, &route);
|
existing = set_get(link->routes, &route);
|
||||||
if (existing) {
|
if (existing) {
|
||||||
*ret = existing;
|
if (ret)
|
||||||
|
*ret = existing;
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
|
||||||
existing = set_get(link->routes_foreign, &route);
|
|
||||||
if (!existing)
|
|
||||||
return -ENOENT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*ret = existing;
|
existing = set_get(link->routes_foreign, &route);
|
||||||
|
if (existing) {
|
||||||
|
if (ret)
|
||||||
|
*ret = existing;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int route_add_internal(Link *link, Set **routes,
|
static int route_add_internal(Link *link, Set **routes,
|
||||||
@ -460,8 +464,11 @@ int route_expire_handler(sd_event_source *s, uint64_t usec, void *userdata) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int route_configure(Route *route, Link *link,
|
int route_configure(
|
||||||
sd_netlink_message_handler_t callback) {
|
Route *route,
|
||||||
|
Link *link,
|
||||||
|
sd_netlink_message_handler_t callback) {
|
||||||
|
|
||||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
|
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
|
||||||
_cleanup_(sd_event_source_unrefp) sd_event_source *expire = NULL;
|
_cleanup_(sd_event_source_unrefp) sd_event_source *expire = NULL;
|
||||||
usec_t lifetime;
|
usec_t lifetime;
|
||||||
@ -473,6 +480,10 @@ int route_configure(Route *route, Link *link,
|
|||||||
assert(link->ifindex > 0);
|
assert(link->ifindex > 0);
|
||||||
assert(route->family == AF_INET || route->family == AF_INET6);
|
assert(route->family == AF_INET || route->family == AF_INET6);
|
||||||
|
|
||||||
|
if (route_get(link, route->family, &route->dst, route->dst_prefixlen, route->tos, route->priority, route->table, NULL) <= 0 &&
|
||||||
|
set_size(route->link->routes) >= ROUTES_PER_LINK_MAX)
|
||||||
|
return -E2BIG;
|
||||||
|
|
||||||
r = sd_rtnl_message_new_route(link->manager->rtnl, &req,
|
r = sd_rtnl_message_new_route(link->manager->rtnl, &req,
|
||||||
RTM_NEWROUTE, route->family,
|
RTM_NEWROUTE, route->family,
|
||||||
route->protocol);
|
route->protocol);
|
||||||
|
@ -57,7 +57,7 @@ void route_free(Route *route);
|
|||||||
int route_configure(Route *route, Link *link, sd_netlink_message_handler_t callback);
|
int route_configure(Route *route, Link *link, sd_netlink_message_handler_t callback);
|
||||||
int route_remove(Route *route, Link *link, sd_netlink_message_handler_t callback);
|
int route_remove(Route *route, Link *link, sd_netlink_message_handler_t callback);
|
||||||
|
|
||||||
int route_get(Link *link, int family, union in_addr_union *dst, unsigned char dst_prefixlen, unsigned char tos, uint32_t priority, unsigned char table, Route **ret);
|
int route_get(Link *link, int family, const union in_addr_union *dst, unsigned char dst_prefixlen, unsigned char tos, uint32_t priority, unsigned char table, Route **ret);
|
||||||
int route_add(Link *link, int family, union in_addr_union *dst, unsigned char dst_prefixlen, unsigned char tos, uint32_t priority, unsigned char table, Route **ret);
|
int route_add(Link *link, int family, union in_addr_union *dst, unsigned char dst_prefixlen, unsigned char tos, uint32_t priority, unsigned char table, Route **ret);
|
||||||
int route_add_foreign(Link *link, int family, union in_addr_union *dst, unsigned char dst_prefixlen, unsigned char tos, uint32_t priority, unsigned char table, Route **ret);
|
int route_add_foreign(Link *link, int family, union in_addr_union *dst, unsigned char dst_prefixlen, unsigned char tos, uint32_t priority, unsigned char table, Route **ret);
|
||||||
int route_update(Route *route, union in_addr_union *src, unsigned char src_prefixlen, union in_addr_union *gw, union in_addr_union *prefsrc, unsigned char scope, unsigned char protocol);
|
int route_update(Route *route, union in_addr_union *src, unsigned char src_prefixlen, union in_addr_union *gw, union in_addr_union *prefsrc, unsigned char scope, unsigned char protocol);
|
||||||
|
Loading…
Reference in New Issue
Block a user