LCOV - code coverage report
Current view: top level - network - networkd-address-pool.c (source / functions) Hit Total Coverage
Test: systemd_full.info Lines: 23 66 34.8 %
Date: 2019-08-23 13:36:53 Functions: 3 5 60.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 18 76 23.7 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: LGPL-2.1+ */
       2                 :            : 
       3                 :            : #include "alloc-util.h"
       4                 :            : #include "networkd-address-pool.h"
       5                 :            : #include "networkd-manager.h"
       6                 :            : #include "set.h"
       7                 :            : #include "string-util.h"
       8                 :            : 
       9                 :            : #define RANDOM_PREFIX_TRIAL_MAX  1024
      10                 :            : 
      11                 :         16 : static int address_pool_new(
      12                 :            :                 Manager *m,
      13                 :            :                 AddressPool **ret,
      14                 :            :                 int family,
      15                 :            :                 const union in_addr_union *u,
      16                 :            :                 unsigned prefixlen) {
      17                 :            : 
      18                 :            :         AddressPool *p;
      19                 :            : 
      20         [ -  + ]:         16 :         assert(m);
      21         [ -  + ]:         16 :         assert(ret);
      22         [ -  + ]:         16 :         assert(u);
      23                 :            : 
      24                 :         16 :         p = new(AddressPool, 1);
      25         [ -  + ]:         16 :         if (!p)
      26                 :          0 :                 return -ENOMEM;
      27                 :            : 
      28                 :         16 :         *p = (AddressPool) {
      29                 :            :                 .manager = m,
      30                 :            :                 .family = family,
      31                 :            :                 .prefixlen = prefixlen,
      32                 :         16 :                 .in_addr = *u,
      33                 :            :         };
      34                 :            : 
      35   [ -  +  +  + ]:         16 :         LIST_PREPEND(address_pools, m->address_pools, p);
      36                 :            : 
      37                 :         16 :         *ret = p;
      38                 :         16 :         return 0;
      39                 :            : }
      40                 :            : 
      41                 :         16 : int address_pool_new_from_string(
      42                 :            :                 Manager *m,
      43                 :            :                 AddressPool **ret,
      44                 :            :                 int family,
      45                 :            :                 const char *p,
      46                 :            :                 unsigned prefixlen) {
      47                 :            : 
      48                 :            :         union in_addr_union u;
      49                 :            :         int r;
      50                 :            : 
      51         [ -  + ]:         16 :         assert(m);
      52         [ -  + ]:         16 :         assert(ret);
      53         [ -  + ]:         16 :         assert(p);
      54                 :            : 
      55                 :         16 :         r = in_addr_from_string(family, p, &u);
      56         [ -  + ]:         16 :         if (r < 0)
      57                 :          0 :                 return r;
      58                 :            : 
      59                 :         16 :         return address_pool_new(m, ret, family, &u, prefixlen);
      60                 :            : }
      61                 :            : 
      62                 :         16 : void address_pool_free(AddressPool *p) {
      63                 :            : 
      64         [ -  + ]:         16 :         if (!p)
      65                 :          0 :                 return;
      66                 :            : 
      67         [ +  - ]:         16 :         if (p->manager)
      68   [ -  +  +  +  :         16 :                 LIST_REMOVE(address_pools, p->manager->address_pools, p);
             -  +  -  + ]
      69                 :            : 
      70                 :         16 :         free(p);
      71                 :            : }
      72                 :            : 
      73                 :          0 : static bool address_pool_prefix_is_taken(
      74                 :            :                 AddressPool *p,
      75                 :            :                 const union in_addr_union *u,
      76                 :            :                 unsigned prefixlen) {
      77                 :            : 
      78                 :            :         Iterator i;
      79                 :            :         Link *l;
      80                 :            :         Network *n;
      81                 :            : 
      82         [ #  # ]:          0 :         assert(p);
      83         [ #  # ]:          0 :         assert(u);
      84                 :            : 
      85         [ #  # ]:          0 :         HASHMAP_FOREACH(l, p->manager->links, i) {
      86                 :            :                 Address *a;
      87                 :            :                 Iterator j;
      88                 :            : 
      89                 :            :                 /* Don't clash with assigned addresses */
      90         [ #  # ]:          0 :                 SET_FOREACH(a, l->addresses, j) {
      91         [ #  # ]:          0 :                         if (a->family != p->family)
      92                 :          0 :                                 continue;
      93                 :            : 
      94         [ #  # ]:          0 :                         if (in_addr_prefix_intersect(p->family, u, prefixlen, &a->in_addr, a->prefixlen))
      95                 :          0 :                                 return true;
      96                 :            :                 }
      97                 :            : 
      98                 :            :                 /* Don't clash with addresses already pulled from the pool, but not assigned yet */
      99         [ #  # ]:          0 :                 LIST_FOREACH(addresses, a, l->pool_addresses) {
     100         [ #  # ]:          0 :                         if (a->family != p->family)
     101                 :          0 :                                 continue;
     102                 :            : 
     103         [ #  # ]:          0 :                         if (in_addr_prefix_intersect(p->family, u, prefixlen, &a->in_addr, a->prefixlen))
     104                 :          0 :                                 return true;
     105                 :            :                 }
     106                 :            :         }
     107                 :            : 
     108                 :            :         /* And don't clash with configured but un-assigned addresses either */
     109         [ #  # ]:          0 :         ORDERED_HASHMAP_FOREACH(n, p->manager->networks, i) {
     110                 :            :                 Address *a;
     111                 :            : 
     112         [ #  # ]:          0 :                 LIST_FOREACH(addresses, a, n->static_addresses) {
     113         [ #  # ]:          0 :                         if (a->family != p->family)
     114                 :          0 :                                 continue;
     115                 :            : 
     116         [ #  # ]:          0 :                         if (in_addr_prefix_intersect(p->family, u, prefixlen, &a->in_addr, a->prefixlen))
     117                 :          0 :                                 return true;
     118                 :            :                 }
     119                 :            :         }
     120                 :            : 
     121                 :          0 :         return false;
     122                 :            : }
     123                 :            : 
     124                 :          0 : int address_pool_acquire(AddressPool *p, unsigned prefixlen, union in_addr_union *found) {
     125                 :            :         union in_addr_union u;
     126                 :            :         unsigned i;
     127                 :            :         int r;
     128                 :            : 
     129         [ #  # ]:          0 :         assert(p);
     130         [ #  # ]:          0 :         assert(prefixlen > 0);
     131         [ #  # ]:          0 :         assert(found);
     132                 :            : 
     133         [ #  # ]:          0 :         if (p->prefixlen >= prefixlen)
     134                 :          0 :                 return 0;
     135                 :            : 
     136                 :          0 :         u = p->in_addr;
     137                 :            : 
     138         [ #  # ]:          0 :         for (i = 0; i < RANDOM_PREFIX_TRIAL_MAX; i++) {
     139                 :          0 :                 r = in_addr_random_prefix(p->family, &u, p->prefixlen, prefixlen);
     140         [ #  # ]:          0 :                 if (r <= 0)
     141                 :          0 :                         return r;
     142                 :            : 
     143         [ #  # ]:          0 :                 if (!address_pool_prefix_is_taken(p, &u, prefixlen)) {
     144         [ #  # ]:          0 :                         if (DEBUG_LOGGING) {
     145                 :          0 :                                 _cleanup_free_ char *s = NULL;
     146                 :            : 
     147                 :          0 :                                 (void) in_addr_to_string(p->family, &u, &s);
     148         [ #  # ]:          0 :                                 log_debug("Found range %s/%u", strna(s), prefixlen);
     149                 :            :                         }
     150                 :            : 
     151                 :          0 :                         *found = u;
     152                 :          0 :                         return 1;
     153                 :            :                 }
     154                 :            :         }
     155                 :            : 
     156                 :          0 :         return 0;
     157                 :            : }

Generated by: LCOV version 1.14