]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
networkd: enforce a limit on the number of statically assigned addresses/routes/fdb...
authorLennart Poettering <lennart@poettering.net>
Fri, 3 Jun 2016 17:14:12 +0000 (19:14 +0200)
committerLennart Poettering <lennart@poettering.net>
Fri, 3 Jun 2016 17:14:12 +0000 (19:14 +0200)
We should put a limit on everything, hence also on these resources.

src/network/networkd-address.c
src/network/networkd-fdb.c
src/network/networkd-network.h
src/network/networkd-route.c

index 367c340e08f9da5c140f0468abb9030c2ae3e514..4cdb500bd67a3dd62cd92a466aa685e14c261eac 100644 (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) {
index 241f4862117d4e4f4064eda5ab9ee466037feb2f..4d51fa41e27e7be971e84655e952340556b3a4ae 100644 (file)
 #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);
index 91099161ce021d30c00c0e29bec7c430f46d3ba6..248a427e8db1cae5e120228619638a794b6b9a0e 100644 (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;
index f001de772aef4783422f6eaec564fb63f06326bb..1b480385c68a5711cf40a3febb8b9aca0bd6f730 100644 (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) {