LCOV - code coverage report
Current view: top level - ovn/lib - ovn-util.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 87 101 86.1 %
Date: 2016-09-14 01:02:56 Functions: 9 9 100.0 %
Branches: 20 38 52.6 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Licensed under the Apache License, Version 2.0 (the "License");
       3                 :            :  * you may not use this file except in compliance with the License.
       4                 :            :  * You may obtain a copy of the License at:
       5                 :            :  *
       6                 :            :  *     http://www.apache.org/licenses/LICENSE-2.0
       7                 :            :  *
       8                 :            :  * Unless required by applicable law or agreed to in writing, software
       9                 :            :  * distributed under the License is distributed on an "AS IS" BASIS,
      10                 :            :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      11                 :            :  * See the License for the specific language governing permissions and
      12                 :            :  * limitations under the License.
      13                 :            :  */
      14                 :            : 
      15                 :            : #include <config.h>
      16                 :            : #include "ovn-util.h"
      17                 :            : #include "dirs.h"
      18                 :            : #include "openvswitch/vlog.h"
      19                 :            : #include "ovn/lib/ovn-nb-idl.h"
      20                 :            : 
      21                 :       2342 : VLOG_DEFINE_THIS_MODULE(ovn_util);
      22                 :            : 
      23                 :            : static void
      24                 :      39990 : add_ipv4_netaddr(struct lport_addresses *laddrs, ovs_be32 addr,
      25                 :            :                  unsigned int plen)
      26                 :            : {
      27                 :      39990 :     laddrs->n_ipv4_addrs++;
      28                 :      39990 :     laddrs->ipv4_addrs = xrealloc(laddrs->ipv4_addrs,
      29                 :      39990 :         laddrs->n_ipv4_addrs * sizeof *laddrs->ipv4_addrs);
      30                 :            : 
      31                 :      39990 :     struct ipv4_netaddr *na = &laddrs->ipv4_addrs[laddrs->n_ipv4_addrs - 1];
      32                 :            : 
      33                 :      39990 :     na->addr = addr;
      34                 :      39990 :     na->mask = be32_prefix_mask(plen);
      35                 :      39990 :     na->network = addr & na->mask;
      36                 :      39990 :     na->plen = plen;
      37                 :            : 
      38                 :      39990 :     ovs_be32 bcast = addr | ~na->mask;
      39                 :      39990 :     inet_ntop(AF_INET, &addr, na->addr_s, sizeof na->addr_s);
      40                 :      39990 :     inet_ntop(AF_INET, &na->network, na->network_s, sizeof na->network_s);
      41                 :      39990 :     inet_ntop(AF_INET, &bcast, na->bcast_s, sizeof na->bcast_s);
      42                 :      39990 : }
      43                 :            : 
      44                 :            : static void
      45                 :      11151 : add_ipv6_netaddr(struct lport_addresses *laddrs, struct in6_addr addr,
      46                 :            :                  unsigned int plen)
      47                 :            : {
      48                 :      11151 :     laddrs->n_ipv6_addrs++;
      49                 :      11151 :     laddrs->ipv6_addrs = xrealloc(laddrs->ipv6_addrs,
      50                 :      11151 :         laddrs->n_ipv6_addrs * sizeof *laddrs->ipv6_addrs);
      51                 :            : 
      52                 :      11151 :     struct ipv6_netaddr *na = &laddrs->ipv6_addrs[laddrs->n_ipv6_addrs - 1];
      53                 :            : 
      54                 :      11151 :     memcpy(&na->addr, &addr, sizeof na->addr);
      55                 :      11151 :     na->mask = ipv6_create_mask(plen);
      56                 :      11151 :     na->network = ipv6_addr_bitand(&addr, &na->mask);
      57                 :      11151 :     na->plen = plen;
      58                 :      11151 :     in6_addr_solicited_node(&na->sn_addr, &addr);
      59                 :            : 
      60                 :      11151 :     inet_ntop(AF_INET6, &addr, na->addr_s, sizeof na->addr_s);
      61                 :      11151 :     inet_ntop(AF_INET6, &na->sn_addr, na->sn_addr_s, sizeof na->sn_addr_s);
      62                 :      11151 :     inet_ntop(AF_INET6, &na->network, na->network_s, sizeof na->network_s);
      63                 :      11151 : }
      64                 :            : 
      65                 :            : /* Extracts the mac, IPv4 and IPv6 addresses from * 'address' which
      66                 :            :  * should be of the format 'MAC [IP1 IP2 ..]" where IPn should be a
      67                 :            :  * valid IPv4 or IPv6 address and stores them in the 'ipv4_addrs' and
      68                 :            :  * 'ipv6_addrs' fields of 'laddrs'.
      69                 :            :  *
      70                 :            :  * Return true if at least 'MAC' is found in 'address', false otherwise.
      71                 :            :  *
      72                 :            :  * The caller must call destroy_lport_addresses(). */
      73                 :            : bool
      74                 :      41697 : extract_lsp_addresses(const char *address, struct lport_addresses *laddrs)
      75                 :            : {
      76                 :      41697 :     memset(laddrs, 0, sizeof *laddrs);
      77                 :            : 
      78                 :      41697 :     const char *buf = address;
      79                 :      41697 :     int buf_index = 0;
      80                 :      41697 :     const char *buf_end = buf + strlen(address);
      81         [ -  + ]:      41697 :     if (!ovs_scan_len(buf, &buf_index, ETH_ADDR_SCAN_FMT,
      82                 :            :                       ETH_ADDR_SCAN_ARGS(laddrs->ea))) {
      83                 :          0 :         laddrs->ea = eth_addr_zero;
      84                 :          0 :         return false;
      85                 :            :     }
      86                 :            : 
      87                 :     250182 :     snprintf(laddrs->ea_s, sizeof laddrs->ea_s, ETH_ADDR_FMT,
      88                 :     250182 :              ETH_ADDR_ARGS(laddrs->ea));
      89                 :            : 
      90                 :            :     ovs_be32 ip4;
      91                 :            :     struct in6_addr ip6;
      92                 :            :     unsigned int plen;
      93                 :            :     char *error;
      94                 :            : 
      95                 :            :     /* Loop through the buffer and extract the IPv4/IPv6 addresses
      96                 :            :      * and store in the 'laddrs'. Break the loop if invalid data is found.
      97                 :            :      */
      98                 :      41697 :     buf += buf_index;
      99         [ +  + ]:      72916 :     while (buf < buf_end) {
     100                 :      31251 :         buf_index = 0;
     101                 :      31251 :         error = ip_parse_cidr_len(buf, &buf_index, &ip4, &plen);
     102         [ +  + ]:      31251 :         if (!error) {
     103                 :      30012 :             add_ipv4_netaddr(laddrs, ip4, plen);
     104                 :      30012 :             buf += buf_index;
     105                 :      30012 :             continue;
     106                 :            :         }
     107                 :       1239 :         free(error);
     108                 :       1239 :         error = ipv6_parse_cidr_len(buf, &buf_index, &ip6, &plen);
     109         [ +  + ]:       1239 :         if (!error) {
     110                 :       1207 :             add_ipv6_netaddr(laddrs, ip6, plen);
     111                 :            :         } else {
     112                 :            :             static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
     113         [ +  - ]:         32 :             VLOG_INFO_RL(&rl, "invalid syntax '%s' in address", address);
     114                 :         32 :             free(error);
     115                 :         32 :             break;
     116                 :            :         }
     117                 :       1207 :         buf += buf_index;
     118                 :            :     }
     119                 :            : 
     120                 :      41697 :     return true;
     121                 :            : }
     122                 :            : 
     123                 :            : /* Extracts the mac, IPv4 and IPv6 addresses from the
     124                 :            :  * "nbrec_logical_router_port" parameter 'lrp'.  Stores the IPv4 and
     125                 :            :  * IPv6 addresses in the 'ipv4_addrs' and 'ipv6_addrs' fields of
     126                 :            :  * 'laddrs', respectively.  In addition, a link local IPv6 address
     127                 :            :  * based on the 'mac' member of 'lrp' is added to the 'ipv6_addrs'
     128                 :            :  * field.
     129                 :            :  *
     130                 :            :  * Return true if a valid 'mac' address is found in 'lrp', false otherwise.
     131                 :            :  *
     132                 :            :  * The caller must call destroy_lport_addresses(). */
     133                 :            : bool
     134                 :       9944 : extract_lrp_networks(const struct nbrec_logical_router_port *lrp,
     135                 :            :                      struct lport_addresses *laddrs)
     136                 :            : {
     137                 :       9944 :     memset(laddrs, 0, sizeof *laddrs);
     138                 :            : 
     139         [ -  + ]:       9944 :     if (!eth_addr_from_string(lrp->mac, &laddrs->ea)) {
     140                 :          0 :         laddrs->ea = eth_addr_zero;
     141                 :          0 :         return false;
     142                 :            :     }
     143                 :      59664 :     snprintf(laddrs->ea_s, sizeof laddrs->ea_s, ETH_ADDR_FMT,
     144                 :      59664 :              ETH_ADDR_ARGS(laddrs->ea));
     145                 :            : 
     146         [ +  + ]:      19922 :     for (int i = 0; i < lrp->n_networks; i++) {
     147                 :            :         ovs_be32 ip4;
     148                 :            :         struct in6_addr ip6;
     149                 :            :         unsigned int plen;
     150                 :            :         char *error;
     151                 :            : 
     152                 :       9978 :         error = ip_parse_cidr(lrp->networks[i], &ip4, &plen);
     153         [ +  - ]:       9978 :         if (!error) {
     154 [ +  - ][ -  + ]:       9978 :             if (!ip4 || plen == 32) {
     155                 :            :                 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1);
     156         [ #  # ]:          0 :                 VLOG_WARN_RL(&rl, "bad 'networks' %s", lrp->networks[i]);
     157                 :       9978 :                 continue;
     158                 :            :             }
     159                 :            : 
     160                 :       9978 :             add_ipv4_netaddr(laddrs, ip4, plen);
     161                 :       9978 :             continue;
     162                 :            :         }
     163                 :          0 :         free(error);
     164                 :            : 
     165                 :          0 :         error = ipv6_parse_cidr(lrp->networks[i], &ip6, &plen);
     166         [ #  # ]:          0 :         if (!error) {
     167         [ #  # ]:          0 :             if (plen == 128) {
     168                 :            :                 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1);
     169         [ #  # ]:          0 :                 VLOG_WARN_RL(&rl, "bad 'networks' %s", lrp->networks[i]);
     170                 :          0 :                 continue;
     171                 :            :             }
     172                 :          0 :             add_ipv6_netaddr(laddrs, ip6, plen);
     173                 :            :         } else {
     174                 :            :             static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
     175         [ #  # ]:          0 :             VLOG_INFO_RL(&rl, "invalid syntax '%s' in networks",
     176                 :            :                          lrp->networks[i]);
     177                 :          0 :             free(error);
     178                 :            :         }
     179                 :            :     }
     180                 :            : 
     181                 :            :     /* Always add the IPv6 link local address. */
     182                 :            :     struct in6_addr lla;
     183                 :       9944 :     in6_generate_lla(laddrs->ea, &lla);
     184                 :       9944 :     add_ipv6_netaddr(laddrs, lla, 64);
     185                 :            : 
     186                 :       9944 :     return true;
     187                 :            : }
     188                 :            : 
     189                 :            : void
     190                 :      71802 : destroy_lport_addresses(struct lport_addresses *laddrs)
     191                 :            : {
     192                 :      71802 :     free(laddrs->ipv4_addrs);
     193                 :      71802 :     free(laddrs->ipv6_addrs);
     194                 :      71802 : }
     195                 :            : 
     196                 :            : /* Allocates a key for NAT conntrack zone allocation for a provided
     197                 :            :  * 'key' record and a 'type'.
     198                 :            :  *
     199                 :            :  * It is the caller's responsibility to free the allocated memory. */
     200                 :            : char *
     201                 :      73338 : alloc_nat_zone_key(const struct uuid *key, const char *type)
     202                 :            : {
     203                 :      73338 :     return xasprintf(UUID_FMT"_%s", UUID_ARGS(key), type);
     204                 :            : }
     205                 :            : 
     206                 :            : const char *
     207                 :        899 : default_nb_db(void)
     208                 :            : {
     209                 :            :     static char *def;
     210         [ +  - ]:        899 :     if (!def) {
     211                 :        899 :         def = getenv("OVN_NB_DB");
     212         [ +  + ]:        899 :         if (!def) {
     213                 :        229 :             def = xasprintf("unix:%s/ovnnb_db.sock", ovs_rundir());
     214                 :            :         }
     215                 :            :     }
     216                 :        899 :     return def;
     217                 :            : }
     218                 :            : 
     219                 :            : const char *
     220                 :        188 : default_sb_db(void)
     221                 :            : {
     222                 :            :     static char *def;
     223         [ +  - ]:        188 :     if (!def) {
     224                 :        188 :         def = getenv("OVN_SB_DB");
     225         [ +  + ]:        188 :         if (!def) {
     226                 :         64 :             def = xasprintf("unix:%s/ovnsb_db.sock", ovs_rundir());
     227                 :            :         }
     228                 :            :     }
     229                 :        188 :     return def;
     230                 :            : }

Generated by: LCOV version 1.12