networkd: enforce a limit on the number of statically assigned addresses/routes/fdb entries

We should put a limit on everything, hence also on these resources.
This commit is contained in:
Lennart Poettering 2016-06-03 19:14:12 +02:00
parent f3e4363593
commit 8c34b96307
4 changed files with 47 additions and 14 deletions

View File

@ -32,6 +32,8 @@
#include "utf8.h"
#include "util.h"
#define STATIC_ADDRESSES_PER_NETWORK_MAX 1024U
int address_new(Address **ret) {
_cleanup_address_free_ Address *address = NULL;
@ -54,6 +56,9 @@ int address_new_static(Network *network, unsigned section, Address **ret) {
_cleanup_address_free_ Address *address = NULL;
int r;
assert(network);
assert(ret);
if (section) {
address = hashmap_get(network->addresses_by_section, UINT_TO_PTR(section));
if (address) {
@ -64,18 +69,21 @@ int address_new_static(Network *network, unsigned section, Address **ret) {
}
}
if (network->n_static_addresses >= STATIC_ADDRESSES_PER_NETWORK_MAX)
return -E2BIG;
r = address_new(&address);
if (r < 0)
return r;
if (section) {
address->section = section;
hashmap_put(network->addresses_by_section,
UINT_TO_PTR(address->section), address);
hashmap_put(network->addresses_by_section, UINT_TO_PTR(address->section), address);
}
address->network = network;
LIST_APPEND(addresses, network->static_addresses, address);
network->n_static_addresses++;
*ret = address;
address = NULL;
@ -89,10 +97,11 @@ void address_free(Address *address) {
if (address->network) {
LIST_REMOVE(addresses, address->network->static_addresses, address);
assert(address->network->n_static_addresses > 0);
address->network->n_static_addresses--;
if (address->section)
hashmap_remove(address->network->addresses_by_section,
UINT_TO_PTR(address->section));
hashmap_remove(address->network->addresses_by_section, UINT_TO_PTR(address->section));
}
if (address->link) {

View File

@ -27,14 +27,19 @@
#include "networkd.h"
#include "util.h"
#define STATIC_FDB_ENTRIES_PER_NETWORK_MAX 1024U
/* create a new FDB entry or get an existing one. */
int fdb_entry_new_static(Network *const network,
const unsigned section,
FdbEntry **ret) {
int fdb_entry_new_static(
Network *network,
const unsigned section,
FdbEntry **ret) {
_cleanup_fdbentry_free_ FdbEntry *fdb_entry = NULL;
struct ether_addr *mac_addr = NULL;
assert(network);
assert(ret);
/* search entry in hashmap first. */
if (section) {
@ -47,6 +52,9 @@ int fdb_entry_new_static(Network *const network,
}
}
if (network->n_static_fdb_entries >= STATIC_FDB_ENTRIES_PER_NETWORK_MAX)
return -E2BIG;
/* allocate space for MAC address. */
mac_addr = new0(struct ether_addr, 1);
if (!mac_addr)
@ -54,7 +62,6 @@ int fdb_entry_new_static(Network *const network,
/* allocate space for and FDB entry. */
fdb_entry = new0(FdbEntry, 1);
if (!fdb_entry) {
/* free previously allocated space for mac_addr. */
free(mac_addr);
@ -66,6 +73,7 @@ int fdb_entry_new_static(Network *const network,
fdb_entry->mac_addr = mac_addr;
LIST_PREPEND(static_fdb_entries, network->static_fdb_entries, fdb_entry);
network->n_static_fdb_entries++;
if (section) {
fdb_entry->section = section;
@ -145,12 +153,13 @@ void fdb_entry_free(FdbEntry *fdb_entry) {
return;
if (fdb_entry->network) {
LIST_REMOVE(static_fdb_entries, fdb_entry->network->static_fdb_entries,
fdb_entry);
LIST_REMOVE(static_fdb_entries, fdb_entry->network->static_fdb_entries, fdb_entry);
assert(fdb_entry->network->n_static_fdb_entries > 0);
fdb_entry->network->n_static_fdb_entries--;
if (fdb_entry->section)
hashmap_remove(fdb_entry->network->fdb_entries_by_section,
UINT_TO_PTR(fdb_entry->section));
hashmap_remove(fdb_entry->network->fdb_entries_by_section, UINT_TO_PTR(fdb_entry->section));
}
free(fdb_entry->mac_addr);

View File

@ -169,6 +169,10 @@ struct Network {
LIST_HEAD(Route, static_routes);
LIST_HEAD(FdbEntry, static_fdb_entries);
unsigned n_static_addresses;
unsigned n_static_routes;
unsigned n_static_fdb_entries;
Hashmap *addresses_by_section;
Hashmap *routes_by_section;
Hashmap *fdb_entries_by_section;

View File

@ -28,6 +28,8 @@
#include "string-util.h"
#include "util.h"
#define STATIC_ROUTES_PER_NETWORK_MAX 1024U
int route_new(Route **ret) {
_cleanup_route_free_ Route *route = NULL;
@ -51,6 +53,9 @@ int route_new_static(Network *network, unsigned section, Route **ret) {
_cleanup_route_free_ Route *route = NULL;
int r;
assert(network);
assert(ret);
if (section) {
route = hashmap_get(network->routes_by_section, UINT_TO_PTR(section));
if (route) {
@ -61,6 +66,9 @@ int route_new_static(Network *network, unsigned section, Route **ret) {
}
}
if (network->n_static_routes >= STATIC_ROUTES_PER_NETWORK_MAX)
return -E2BIG;
r = route_new(&route);
if (r < 0)
return r;
@ -77,6 +85,7 @@ int route_new_static(Network *network, unsigned section, Route **ret) {
route->network = network;
LIST_PREPEND(routes, network->static_routes, route);
network->n_static_routes++;
*ret = route;
route = NULL;
@ -91,9 +100,11 @@ void route_free(Route *route) {
if (route->network) {
LIST_REMOVE(routes, route->network->static_routes, route);
assert(route->network->n_static_routes > 0);
route->network->n_static_routes--;
if (route->section)
hashmap_remove(route->network->routes_by_section,
UINT_TO_PTR(route->section));
hashmap_remove(route->network->routes_by_section, UINT_TO_PTR(route->section));
}
if (route->link) {