LCOV - code coverage report
Current view: top level - network - networkd-address-label.c (source / functions) Hit Total Coverage
Test: main_coverage.info Lines: 0 122 0.0 %
Date: 2019-08-22 15:41:25 Functions: 0 6 0.0 %

          Line data    Source code
       1             : /* SPDX-License-Identifier: LGPL-2.1+ */
       2             : 
       3             : #include <net/if.h>
       4             : #include <linux/if_addrlabel.h>
       5             : 
       6             : #include "alloc-util.h"
       7             : #include "conf-parser.h"
       8             : #include "networkd-address-label.h"
       9             : #include "netlink-util.h"
      10             : #include "networkd-manager.h"
      11             : #include "parse-util.h"
      12             : #include "socket-util.h"
      13             : 
      14           0 : void address_label_free(AddressLabel *label) {
      15           0 :         if (!label)
      16           0 :                 return;
      17             : 
      18           0 :         if (label->network) {
      19           0 :                 LIST_REMOVE(labels, label->network->address_labels, label);
      20           0 :                 assert(label->network->n_address_labels > 0);
      21           0 :                 label->network->n_address_labels--;
      22             : 
      23           0 :                 if (label->section) {
      24           0 :                         hashmap_remove(label->network->address_labels_by_section, label->section);
      25           0 :                         network_config_section_free(label->section);
      26             :                 }
      27             :         }
      28             : 
      29           0 :         free(label);
      30             : }
      31             : 
      32           0 : static int address_label_new_static(Network *network, const char *filename, unsigned section_line, AddressLabel **ret) {
      33           0 :         _cleanup_(network_config_section_freep) NetworkConfigSection *n = NULL;
      34           0 :         _cleanup_(address_label_freep) AddressLabel *label = NULL;
      35             :         int r;
      36             : 
      37           0 :         assert(network);
      38           0 :         assert(ret);
      39           0 :         assert(!!filename == (section_line > 0));
      40             : 
      41           0 :         if (filename) {
      42           0 :                 r = network_config_section_new(filename, section_line, &n);
      43           0 :                 if (r < 0)
      44           0 :                         return r;
      45             : 
      46           0 :                 label = hashmap_get(network->address_labels_by_section, n);
      47           0 :                 if (label) {
      48           0 :                         *ret = TAKE_PTR(label);
      49             : 
      50           0 :                         return 0;
      51             :                 }
      52             :         }
      53             : 
      54           0 :         label = new(AddressLabel, 1);
      55           0 :         if (!label)
      56           0 :                 return -ENOMEM;
      57             : 
      58           0 :         *label = (AddressLabel) {
      59             :                 .network = network,
      60             :         };
      61             : 
      62           0 :         LIST_APPEND(labels, network->address_labels, label);
      63           0 :         network->n_address_labels++;
      64             : 
      65           0 :         if (filename) {
      66           0 :                 label->section = TAKE_PTR(n);
      67             : 
      68           0 :                 r = hashmap_ensure_allocated(&network->address_labels_by_section, &network_config_hash_ops);
      69           0 :                 if (r < 0)
      70           0 :                         return r;
      71             : 
      72           0 :                 r = hashmap_put(network->address_labels_by_section, label->section, label);
      73           0 :                 if (r < 0)
      74           0 :                         return r;
      75             :         }
      76             : 
      77           0 :         *ret = TAKE_PTR(label);
      78             : 
      79           0 :         return 0;
      80             : }
      81             : 
      82           0 : static int address_label_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
      83             :         int r;
      84             : 
      85           0 :         assert(rtnl);
      86           0 :         assert(m);
      87           0 :         assert(link);
      88           0 :         assert(link->ifname);
      89           0 :         assert(link->address_label_messages > 0);
      90             : 
      91           0 :         link->address_label_messages--;
      92             : 
      93           0 :         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
      94           0 :                 return 1;
      95             : 
      96           0 :         r = sd_netlink_message_get_errno(m);
      97           0 :         if (r < 0 && r != -EEXIST) {
      98           0 :                 log_link_warning_errno(link, r, "could not set address label: %m");
      99           0 :                 link_enter_failed(link);
     100           0 :                 return 1;
     101           0 :         } else if (r >= 0)
     102           0 :                 (void) manager_rtnl_process_address(rtnl, m, link->manager);
     103             : 
     104           0 :         if (link->address_label_messages == 0)
     105           0 :                 log_link_debug(link, "Addresses label set");
     106             : 
     107           0 :         return 1;
     108             : }
     109             : 
     110           0 : int address_label_configure(
     111             :                 AddressLabel *label,
     112             :                 Link *link,
     113             :                 link_netlink_message_handler_t callback,
     114             :                 bool update) {
     115             : 
     116           0 :         _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
     117             :         int r;
     118             : 
     119           0 :         assert(label);
     120           0 :         assert(link);
     121           0 :         assert(link->ifindex > 0);
     122           0 :         assert(link->manager);
     123           0 :         assert(link->manager->rtnl);
     124             : 
     125           0 :         r = sd_rtnl_message_new_addrlabel(link->manager->rtnl, &req, RTM_NEWADDRLABEL,
     126             :                                           link->ifindex, AF_INET6);
     127           0 :         if (r < 0)
     128           0 :                 return log_error_errno(r, "Could not allocate RTM_NEWADDR message: %m");
     129             : 
     130           0 :         r = sd_rtnl_message_addrlabel_set_prefixlen(req, label->prefixlen);
     131           0 :         if (r < 0)
     132           0 :                 return log_error_errno(r, "Could not set prefixlen: %m");
     133             : 
     134           0 :         r = sd_netlink_message_append_u32(req, IFAL_LABEL, label->label);
     135           0 :         if (r < 0)
     136           0 :                 return log_error_errno(r, "Could not append IFAL_LABEL attribute: %m");
     137             : 
     138           0 :         r = sd_netlink_message_append_in6_addr(req, IFA_ADDRESS, &label->in_addr.in6);
     139           0 :         if (r < 0)
     140           0 :                 return log_error_errno(r, "Could not append IFA_ADDRESS attribute: %m");
     141             : 
     142           0 :         r = netlink_call_async(link->manager->rtnl, NULL, req,
     143             :                                callback ?: address_label_handler,
     144             :                                link_netlink_destroy_callback, link);
     145           0 :         if (r < 0)
     146           0 :                 return log_error_errno(r, "Could not send rtnetlink message: %m");
     147             : 
     148           0 :         link_ref(link);
     149             : 
     150           0 :         return 0;
     151             : }
     152             : 
     153           0 : int config_parse_address_label_prefix(const char *unit,
     154             :                                       const char *filename,
     155             :                                       unsigned line,
     156             :                                       const char *section,
     157             :                                       unsigned section_line,
     158             :                                       const char *lvalue,
     159             :                                       int ltype,
     160             :                                       const char *rvalue,
     161             :                                       void *data,
     162             :                                       void *userdata) {
     163             : 
     164           0 :         _cleanup_(address_label_free_or_set_invalidp) AddressLabel *n = NULL;
     165           0 :         Network *network = userdata;
     166             :         int r;
     167             : 
     168           0 :         assert(filename);
     169           0 :         assert(section);
     170           0 :         assert(lvalue);
     171           0 :         assert(rvalue);
     172           0 :         assert(data);
     173             : 
     174           0 :         r = address_label_new_static(network, filename, section_line, &n);
     175           0 :         if (r < 0)
     176           0 :                 return r;
     177             : 
     178           0 :         r = in_addr_prefix_from_string(rvalue, AF_INET6, &n->in_addr, &n->prefixlen);
     179           0 :         if (r < 0) {
     180           0 :                 log_syntax(unit, LOG_ERR, filename, line, r, "Address label is invalid, ignoring assignment: %s", rvalue);
     181           0 :                 return 0;
     182             :         }
     183             : 
     184           0 :         n = NULL;
     185             : 
     186           0 :         return 0;
     187             : }
     188             : 
     189           0 : int config_parse_address_label(
     190             :                 const char *unit,
     191             :                 const char *filename,
     192             :                 unsigned line,
     193             :                 const char *section,
     194             :                 unsigned section_line,
     195             :                 const char *lvalue,
     196             :                 int ltype,
     197             :                 const char *rvalue,
     198             :                 void *data,
     199             :                 void *userdata) {
     200             : 
     201           0 :         _cleanup_(address_label_free_or_set_invalidp) AddressLabel *n = NULL;
     202           0 :         Network *network = userdata;
     203             :         uint32_t k;
     204             :         int r;
     205             : 
     206           0 :         assert(filename);
     207           0 :         assert(section);
     208           0 :         assert(lvalue);
     209           0 :         assert(rvalue);
     210           0 :         assert(data);
     211             : 
     212           0 :         r = address_label_new_static(network, filename, section_line, &n);
     213           0 :         if (r < 0)
     214           0 :                 return r;
     215             : 
     216           0 :         r = safe_atou32(rvalue, &k);
     217           0 :         if (r < 0) {
     218           0 :                 log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse address label, ignoring: %s", rvalue);
     219           0 :                 return 0;
     220             :         }
     221             : 
     222           0 :         if (k == 0xffffffffUL) {
     223           0 :                 log_syntax(unit, LOG_ERR, filename, line, r, "Address label is invalid, ignoring: %s", rvalue);
     224           0 :                 return 0;
     225             :         }
     226             : 
     227           0 :         n->label = k;
     228           0 :         n = NULL;
     229             : 
     230           0 :         return 0;
     231             : }

Generated by: LCOV version 1.14