LCOV - code coverage report
Current view: top level - network/netdev - bond.c (source / functions) Hit Total Coverage
Test: main_coverage.info Lines: 8 275 2.9 %
Date: 2019-08-22 15:41:25 Functions: 16 33 48.5 %

          Line data    Source code
       1             : /* SPDX-License-Identifier: LGPL-2.1+ */
       2             : 
       3             : #include "sd-netlink.h"
       4             : 
       5             : #include "alloc-util.h"
       6             : #include "bond.h"
       7             : #include "conf-parser.h"
       8             : #include "ether-addr-util.h"
       9             : #include "extract-word.h"
      10             : #include "netlink-util.h"
      11             : #include "networkd-manager.h"
      12             : #include "string-table.h"
      13             : #include "string-util.h"
      14             : 
      15             : /*
      16             :  * Number of seconds between instances where the bonding
      17             :  * driver sends learning packets to each slaves peer switch
      18             :  */
      19             : #define LEARNING_PACKETS_INTERVAL_MIN_SEC       (1 * USEC_PER_SEC)
      20             : #define LEARNING_PACKETS_INTERVAL_MAX_SEC       (0x7fffffff * USEC_PER_SEC)
      21             : 
      22             : /* Number of IGMP membership reports to be issued after
      23             :  * a failover event.
      24             :  */
      25             : #define RESEND_IGMP_MIN           0
      26             : #define RESEND_IGMP_MAX           255
      27             : #define RESEND_IGMP_DEFAULT       1
      28             : 
      29             : /*
      30             :  * Number of packets to transmit through a slave before
      31             :  * moving to the next one.
      32             :  */
      33             : #define PACKETS_PER_SLAVE_MIN     0
      34             : #define PACKETS_PER_SLAVE_MAX     65535
      35             : #define PACKETS_PER_SLAVE_DEFAULT 1
      36             : 
      37             : /*
      38             :  * Number of peer notifications (gratuitous ARPs and
      39             :  * unsolicited IPv6 Neighbor Advertisements) to be issued after a
      40             :  * failover event.
      41             :  */
      42             : #define GRATUITOUS_ARP_MIN        0
      43             : #define GRATUITOUS_ARP_MAX        255
      44             : #define GRATUITOUS_ARP_DEFAULT    1
      45             : 
      46             : static const char* const bond_mode_table[_NETDEV_BOND_MODE_MAX] = {
      47             :         [NETDEV_BOND_MODE_BALANCE_RR] = "balance-rr",
      48             :         [NETDEV_BOND_MODE_ACTIVE_BACKUP] = "active-backup",
      49             :         [NETDEV_BOND_MODE_BALANCE_XOR] = "balance-xor",
      50             :         [NETDEV_BOND_MODE_BROADCAST] = "broadcast",
      51             :         [NETDEV_BOND_MODE_802_3AD] = "802.3ad",
      52             :         [NETDEV_BOND_MODE_BALANCE_TLB] = "balance-tlb",
      53             :         [NETDEV_BOND_MODE_BALANCE_ALB] = "balance-alb",
      54             : };
      55             : 
      56          18 : DEFINE_STRING_TABLE_LOOKUP(bond_mode, BondMode);
      57           0 : DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_mode, bond_mode, BondMode, "Failed to parse bond mode");
      58             : 
      59             : static const char* const bond_xmit_hash_policy_table[_NETDEV_BOND_XMIT_HASH_POLICY_MAX] = {
      60             :         [NETDEV_BOND_XMIT_HASH_POLICY_LAYER2] = "layer2",
      61             :         [NETDEV_BOND_XMIT_HASH_POLICY_LAYER34] = "layer3+4",
      62             :         [NETDEV_BOND_XMIT_HASH_POLICY_LAYER23] = "layer2+3",
      63             :         [NETDEV_BOND_XMIT_HASH_POLICY_ENCAP23] = "encap2+3",
      64             :         [NETDEV_BOND_XMIT_HASH_POLICY_ENCAP34] = "encap3+4",
      65             : };
      66             : 
      67          14 : DEFINE_STRING_TABLE_LOOKUP(bond_xmit_hash_policy, BondXmitHashPolicy);
      68           0 : DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_xmit_hash_policy,
      69             :                          bond_xmit_hash_policy,
      70             :                          BondXmitHashPolicy,
      71             :                          "Failed to parse bond transmit hash policy")
      72             : 
      73             : static const char* const bond_lacp_rate_table[_NETDEV_BOND_LACP_RATE_MAX] = {
      74             :         [NETDEV_BOND_LACP_RATE_SLOW] = "slow",
      75             :         [NETDEV_BOND_LACP_RATE_FAST] = "fast",
      76             : };
      77             : 
      78           8 : DEFINE_STRING_TABLE_LOOKUP(bond_lacp_rate, BondLacpRate);
      79           0 : DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_lacp_rate, bond_lacp_rate, BondLacpRate, "Failed to parse bond lacp rate")
      80             : 
      81             : static const char* const bond_ad_select_table[_NETDEV_BOND_AD_SELECT_MAX] = {
      82             :         [NETDEV_BOND_AD_SELECT_STABLE] = "stable",
      83             :         [NETDEV_BOND_AD_SELECT_BANDWIDTH] = "bandwidth",
      84             :         [NETDEV_BOND_AD_SELECT_COUNT] = "count",
      85             : };
      86             : 
      87          10 : DEFINE_STRING_TABLE_LOOKUP(bond_ad_select, BondAdSelect);
      88           0 : DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_ad_select, bond_ad_select, BondAdSelect, "Failed to parse bond AD select");
      89             : 
      90             : static const char* const bond_fail_over_mac_table[_NETDEV_BOND_FAIL_OVER_MAC_MAX] = {
      91             :         [NETDEV_BOND_FAIL_OVER_MAC_NONE] = "none",
      92             :         [NETDEV_BOND_FAIL_OVER_MAC_ACTIVE] = "active",
      93             :         [NETDEV_BOND_FAIL_OVER_MAC_FOLLOW] = "follow",
      94             : };
      95             : 
      96          10 : DEFINE_STRING_TABLE_LOOKUP(bond_fail_over_mac, BondFailOverMac);
      97           0 : DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_fail_over_mac, bond_fail_over_mac, BondFailOverMac, "Failed to parse bond fail over MAC");
      98             : 
      99             : static const char *const bond_arp_validate_table[_NETDEV_BOND_ARP_VALIDATE_MAX] = {
     100             :         [NETDEV_BOND_ARP_VALIDATE_NONE] = "none",
     101             :         [NETDEV_BOND_ARP_VALIDATE_ACTIVE]= "active",
     102             :         [NETDEV_BOND_ARP_VALIDATE_BACKUP]= "backup",
     103             :         [NETDEV_BOND_ARP_VALIDATE_ALL]= "all",
     104             : };
     105             : 
     106          12 : DEFINE_STRING_TABLE_LOOKUP(bond_arp_validate, BondArpValidate);
     107           0 : DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_arp_validate, bond_arp_validate, BondArpValidate, "Failed to parse bond arp validate");
     108             : 
     109             : static const char *const bond_arp_all_targets_table[_NETDEV_BOND_ARP_ALL_TARGETS_MAX] = {
     110             :         [NETDEV_BOND_ARP_ALL_TARGETS_ANY] = "any",
     111             :         [NETDEV_BOND_ARP_ALL_TARGETS_ALL] = "all",
     112             : };
     113             : 
     114           8 : DEFINE_STRING_TABLE_LOOKUP(bond_arp_all_targets, BondArpAllTargets);
     115           0 : DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_arp_all_targets, bond_arp_all_targets, BondArpAllTargets, "Failed to parse bond Arp all targets");
     116             : 
     117             : static const char *const bond_primary_reselect_table[_NETDEV_BOND_PRIMARY_RESELECT_MAX] = {
     118             :         [NETDEV_BOND_PRIMARY_RESELECT_ALWAYS] = "always",
     119             :         [NETDEV_BOND_PRIMARY_RESELECT_BETTER]= "better",
     120             :         [NETDEV_BOND_PRIMARY_RESELECT_FAILURE]= "failure",
     121             : };
     122             : 
     123          10 : DEFINE_STRING_TABLE_LOOKUP(bond_primary_reselect, BondPrimaryReselect);
     124           0 : DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_primary_reselect, bond_primary_reselect, BondPrimaryReselect, "Failed to parse bond primary reselect");
     125             : 
     126           0 : static int netdev_bond_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
     127             :         Bond *b;
     128             :         int r;
     129             : 
     130           0 :         assert(netdev);
     131           0 :         assert(!link);
     132           0 :         assert(m);
     133             : 
     134           0 :         b = BOND(netdev);
     135             : 
     136           0 :         assert(b);
     137             : 
     138           0 :         if (b->mode != _NETDEV_BOND_MODE_INVALID) {
     139           0 :                 r = sd_netlink_message_append_u8(m, IFLA_BOND_MODE, b->mode);
     140           0 :                 if (r < 0)
     141           0 :                         return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_MODE attribute: %m");
     142             :         }
     143             : 
     144           0 :         if (b->xmit_hash_policy != _NETDEV_BOND_XMIT_HASH_POLICY_INVALID) {
     145           0 :                 r = sd_netlink_message_append_u8(m, IFLA_BOND_XMIT_HASH_POLICY, b->xmit_hash_policy);
     146           0 :                 if (r < 0)
     147           0 :                         return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_XMIT_HASH_POLICY attribute: %m");
     148             :         }
     149             : 
     150           0 :         if (b->lacp_rate != _NETDEV_BOND_LACP_RATE_INVALID &&
     151           0 :             b->mode == NETDEV_BOND_MODE_802_3AD) {
     152           0 :                 r = sd_netlink_message_append_u8(m, IFLA_BOND_AD_LACP_RATE, b->lacp_rate);
     153           0 :                 if (r < 0)
     154           0 :                         return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_AD_LACP_RATE attribute: %m");
     155             :         }
     156             : 
     157           0 :         if (b->miimon != 0) {
     158           0 :                 r = sd_netlink_message_append_u32(m, IFLA_BOND_MIIMON, b->miimon / USEC_PER_MSEC);
     159           0 :                 if (r < 0)
     160           0 :                         log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_BOND_MIIMON attribute: %m");
     161             :         }
     162             : 
     163           0 :         if (b->downdelay != 0) {
     164           0 :                 r = sd_netlink_message_append_u32(m, IFLA_BOND_DOWNDELAY, b->downdelay / USEC_PER_MSEC);
     165           0 :                 if (r < 0)
     166           0 :                         return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_DOWNDELAY attribute: %m");
     167             :         }
     168             : 
     169           0 :         if (b->updelay != 0) {
     170           0 :                 r = sd_netlink_message_append_u32(m, IFLA_BOND_UPDELAY, b->updelay / USEC_PER_MSEC);
     171           0 :                 if (r < 0)
     172           0 :                         return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_UPDELAY attribute: %m");
     173             :         }
     174             : 
     175           0 :         if (b->arp_interval != 0) {
     176           0 :                 r = sd_netlink_message_append_u32(m, IFLA_BOND_ARP_INTERVAL, b->arp_interval / USEC_PER_MSEC);
     177           0 :                 if (r < 0)
     178           0 :                         return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_ARP_INTERVAL attribute: %m");
     179             : 
     180           0 :                 if (b->lp_interval >= LEARNING_PACKETS_INTERVAL_MIN_SEC &&
     181           0 :                     b->lp_interval <= LEARNING_PACKETS_INTERVAL_MAX_SEC) {
     182           0 :                         r = sd_netlink_message_append_u32(m, IFLA_BOND_LP_INTERVAL, b->lp_interval / USEC_PER_SEC);
     183           0 :                         if (r < 0)
     184           0 :                                 return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_LP_INTERVAL attribute: %m");
     185             :                 }
     186             :         }
     187             : 
     188           0 :         if (b->ad_select != _NETDEV_BOND_AD_SELECT_INVALID &&
     189           0 :             b->mode == NETDEV_BOND_MODE_802_3AD) {
     190           0 :                 r = sd_netlink_message_append_u8(m, IFLA_BOND_AD_SELECT, b->ad_select);
     191           0 :                 if (r < 0)
     192           0 :                         return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_AD_SELECT attribute: %m");
     193             :         }
     194             : 
     195           0 :         if (b->fail_over_mac != _NETDEV_BOND_FAIL_OVER_MAC_INVALID &&
     196           0 :             b->mode == NETDEV_BOND_MODE_ACTIVE_BACKUP) {
     197           0 :                 r = sd_netlink_message_append_u8(m, IFLA_BOND_FAIL_OVER_MAC, b->fail_over_mac);
     198           0 :                 if (r < 0)
     199           0 :                         return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_FAIL_OVER_MAC attribute: %m");
     200             :         }
     201             : 
     202           0 :         if (b->arp_validate != _NETDEV_BOND_ARP_VALIDATE_INVALID) {
     203           0 :                 r = sd_netlink_message_append_u32(m, IFLA_BOND_ARP_VALIDATE, b->arp_validate);
     204           0 :                 if (r < 0)
     205           0 :                         return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_ARP_VALIDATE attribute: %m");
     206             :         }
     207             : 
     208           0 :         if (b->arp_all_targets != _NETDEV_BOND_ARP_ALL_TARGETS_INVALID) {
     209           0 :                 r = sd_netlink_message_append_u32(m, IFLA_BOND_ARP_ALL_TARGETS, b->arp_all_targets);
     210           0 :                 if (r < 0)
     211           0 :                         return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_ARP_ALL_TARGETS attribute: %m");
     212             :         }
     213             : 
     214           0 :         if (b->primary_reselect != _NETDEV_BOND_PRIMARY_RESELECT_INVALID) {
     215           0 :                 r = sd_netlink_message_append_u8(m, IFLA_BOND_PRIMARY_RESELECT, b->primary_reselect);
     216           0 :                 if (r < 0)
     217           0 :                         return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_PRIMARY_RESELECT attribute: %m");
     218             :         }
     219             : 
     220           0 :         if (b->resend_igmp <= RESEND_IGMP_MAX) {
     221           0 :                 r = sd_netlink_message_append_u32(m, IFLA_BOND_RESEND_IGMP, b->resend_igmp);
     222           0 :                 if (r < 0)
     223           0 :                         return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_RESEND_IGMP attribute: %m");
     224             :         }
     225             : 
     226           0 :         if (b->packets_per_slave <= PACKETS_PER_SLAVE_MAX &&
     227           0 :             b->mode == NETDEV_BOND_MODE_BALANCE_RR) {
     228           0 :                 r = sd_netlink_message_append_u32(m, IFLA_BOND_PACKETS_PER_SLAVE, b->packets_per_slave);
     229           0 :                 if (r < 0)
     230           0 :                         return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_PACKETS_PER_SLAVE attribute: %m");
     231             :         }
     232             : 
     233           0 :         if (b->num_grat_arp <= GRATUITOUS_ARP_MAX) {
     234           0 :                 r = sd_netlink_message_append_u8(m, IFLA_BOND_NUM_PEER_NOTIF, b->num_grat_arp);
     235           0 :                 if (r < 0)
     236           0 :                         return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_NUM_PEER_NOTIF attribute: %m");
     237             :         }
     238             : 
     239           0 :         if (b->min_links != 0) {
     240           0 :                 r = sd_netlink_message_append_u32(m, IFLA_BOND_MIN_LINKS, b->min_links);
     241           0 :                 if (r < 0)
     242           0 :                         return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_MIN_LINKS attribute: %m");
     243             :         }
     244             : 
     245           0 :         if (b->ad_actor_sys_prio != 0) {
     246           0 :                 r = sd_netlink_message_append_u16(m, IFLA_BOND_AD_ACTOR_SYS_PRIO, b->ad_actor_sys_prio);
     247           0 :                 if (r < 0)
     248           0 :                         return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_AD_ACTOR_SYS_PRIO attribute: %m");
     249             :         }
     250             : 
     251           0 :         if (b->ad_user_port_key != 0) {
     252           0 :                 r = sd_netlink_message_append_u16(m, IFLA_BOND_AD_USER_PORT_KEY, b->ad_user_port_key);
     253           0 :                 if (r < 0)
     254           0 :                         return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_AD_USER_PORT_KEY attribute: %m");
     255             :         }
     256             : 
     257           0 :         if (!ether_addr_is_null(&b->ad_actor_system)) {
     258           0 :                 r = sd_netlink_message_append_ether_addr(m, IFLA_BOND_AD_ACTOR_SYSTEM, &b->ad_actor_system);
     259           0 :                 if (r < 0)
     260           0 :                         return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_AD_ACTOR_SYSTEM attribute: %m");
     261             :         }
     262             : 
     263           0 :         r = sd_netlink_message_append_u8(m, IFLA_BOND_ALL_SLAVES_ACTIVE, b->all_slaves_active);
     264           0 :         if (r < 0)
     265           0 :                 return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_ALL_SLAVES_ACTIVE attribute: %m");
     266             : 
     267           0 :         if (b->tlb_dynamic_lb >= 0) {
     268           0 :                 r = sd_netlink_message_append_u8(m, IFLA_BOND_TLB_DYNAMIC_LB, b->tlb_dynamic_lb);
     269           0 :                 if (r < 0)
     270           0 :                         return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_TLB_DYNAMIC_LB attribute: %m");
     271             :         }
     272             : 
     273           0 :         if (b->arp_interval > 0 && !ordered_set_isempty(b->arp_ip_targets)) {
     274             :                 Iterator i;
     275             :                 void *val;
     276           0 :                 int n = 0;
     277             : 
     278           0 :                 r = sd_netlink_message_open_container(m, IFLA_BOND_ARP_IP_TARGET);
     279           0 :                 if (r < 0)
     280           0 :                         return log_netdev_error_errno(netdev, r, "Could not open contaniner IFLA_BOND_ARP_IP_TARGET : %m");
     281             : 
     282           0 :                 ORDERED_SET_FOREACH(val, b->arp_ip_targets, i) {
     283           0 :                         r = sd_netlink_message_append_u32(m, n++, PTR_TO_UINT32(val));
     284           0 :                         if (r < 0)
     285           0 :                                 return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_ARP_ALL_TARGETS attribute: %m");
     286             :                 }
     287             : 
     288           0 :                 r = sd_netlink_message_close_container(m);
     289           0 :                 if (r < 0)
     290           0 :                         return log_netdev_error_errno(netdev, r, "Could not close contaniner IFLA_BOND_ARP_IP_TARGET : %m");
     291             :         }
     292             : 
     293           0 :         return 0;
     294             : }
     295             : 
     296           0 : static int link_set_bond_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
     297             :         int r;
     298             : 
     299           0 :         assert(m);
     300           0 :         assert(link);
     301           0 :         assert(link->ifname);
     302             : 
     303           0 :         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
     304           0 :                 return 1;
     305             : 
     306           0 :         r = sd_netlink_message_get_errno(m);
     307           0 :         if (r < 0) {
     308           0 :                 log_link_warning_errno(link, r, "Could not set bonding interface: %m");
     309           0 :                 return 1;
     310             :         }
     311             : 
     312           0 :         return 1;
     313             : }
     314             : 
     315           0 : int link_set_bond(Link *link) {
     316           0 :         _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
     317             :         int r;
     318             : 
     319           0 :         assert(link);
     320           0 :         assert(link->network);
     321             : 
     322           0 :         r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_NEWLINK, link->network->bond->ifindex);
     323           0 :         if (r < 0)
     324           0 :                 return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
     325             : 
     326           0 :         r = sd_netlink_message_set_flags(req, NLM_F_REQUEST | NLM_F_ACK);
     327           0 :         if (r < 0)
     328           0 :                 return log_link_error_errno(link, r, "Could not set netlink flags: %m");
     329             : 
     330           0 :         r = sd_netlink_message_open_container(req, IFLA_LINKINFO);
     331           0 :         if (r < 0)
     332           0 :                 return log_link_error_errno(link, r, "Could not append IFLA_PROTINFO attribute: %m");
     333             : 
     334           0 :         r = sd_netlink_message_open_container_union(req, IFLA_INFO_DATA, "bond");
     335           0 :         if (r < 0)
     336           0 :                 return log_link_error_errno(link, r, "Could not append IFLA_INFO_DATA attribute: %m");
     337             : 
     338           0 :         if (link->network->active_slave) {
     339           0 :                 r = sd_netlink_message_append_u32(req, IFLA_BOND_ACTIVE_SLAVE, link->ifindex);
     340           0 :                 if (r < 0)
     341           0 :                         return log_link_error_errno(link, r, "Could not append IFLA_BOND_ACTIVE_SLAVE attribute: %m");
     342             :         }
     343             : 
     344           0 :         if (link->network->primary_slave) {
     345           0 :                 r = sd_netlink_message_append_u32(req, IFLA_BOND_PRIMARY, link->ifindex);
     346           0 :                 if (r < 0)
     347           0 :                         return log_link_error_errno(link, r, "Could not append IFLA_BOND_PRIMARY attribute: %m");
     348             :         }
     349             : 
     350           0 :         r = sd_netlink_message_close_container(req);
     351           0 :         if (r < 0)
     352           0 :                 return log_link_error_errno(link, r, "Could not append IFLA_LINKINFO attribute: %m");
     353             : 
     354           0 :         r = sd_netlink_message_close_container(req);
     355           0 :         if (r < 0)
     356           0 :                 return log_link_error_errno(link, r, "Could not append IFLA_INFO_DATA attribute: %m");
     357             : 
     358           0 :         r = netlink_call_async(link->manager->rtnl, NULL, req, link_set_bond_handler,
     359             :                                link_netlink_destroy_callback, link);
     360           0 :         if (r < 0)
     361           0 :                 return log_link_error_errno(link, r,  "Could not send rtnetlink message: %m");
     362             : 
     363           0 :         link_ref(link);
     364             : 
     365           0 :         return r;
     366             : }
     367             : 
     368           0 : int config_parse_arp_ip_target_address(
     369             :                 const char *unit,
     370             :                 const char *filename,
     371             :                 unsigned line,
     372             :                 const char *section,
     373             :                 unsigned section_line,
     374             :                 const char *lvalue,
     375             :                 int ltype,
     376             :                 const char *rvalue,
     377             :                 void *data,
     378             :                 void *userdata) {
     379             : 
     380           0 :         Bond *b = userdata;
     381             :         int r;
     382             : 
     383           0 :         assert(filename);
     384           0 :         assert(lvalue);
     385           0 :         assert(rvalue);
     386           0 :         assert(data);
     387             : 
     388           0 :         if (isempty(rvalue)) {
     389           0 :                 b->arp_ip_targets = ordered_set_free(b->arp_ip_targets);
     390           0 :                 return 0;
     391             :         }
     392             : 
     393           0 :         for (;;) {
     394           0 :                 _cleanup_free_ char *n = NULL;
     395             :                 union in_addr_union ip;
     396             : 
     397           0 :                 r = extract_first_word(&rvalue, &n, NULL, 0);
     398           0 :                 if (r < 0) {
     399           0 :                         log_syntax(unit, LOG_ERR, filename, line, r,
     400             :                                    "Failed to parse Bond ARP ip target address, ignoring assignment: %s",
     401             :                                    rvalue);
     402           0 :                         return 0;
     403             :                 }
     404           0 :                 if (r == 0)
     405           0 :                         return 0;
     406             : 
     407           0 :                 r = in_addr_from_string(AF_INET, n, &ip);
     408           0 :                 if (r < 0) {
     409           0 :                         log_syntax(unit, LOG_ERR, filename, line, r,
     410             :                                    "Bond ARP ip target address is invalid, ignoring assignment: %s", n);
     411           0 :                         continue;
     412             :                 }
     413             : 
     414           0 :                 r = ordered_set_ensure_allocated(&b->arp_ip_targets, NULL);
     415           0 :                 if (r < 0)
     416           0 :                         return log_oom();
     417             : 
     418           0 :                 if (ordered_set_size(b->arp_ip_targets) >= NETDEV_BOND_ARP_TARGETS_MAX) {
     419           0 :                         log_syntax(unit, LOG_WARNING, filename, line, 0,
     420             :                                    "Too many ARP ip targets are specified. The maximum number is %d. Ignoring assignment: %s",
     421             :                                    NETDEV_BOND_ARP_TARGETS_MAX, n);
     422           0 :                         continue;
     423             :                 }
     424             : 
     425           0 :                 r = ordered_set_put(b->arp_ip_targets, UINT32_TO_PTR(ip.in.s_addr));
     426           0 :                 if (r == -EEXIST)
     427           0 :                         log_syntax(unit, LOG_WARNING, filename, line, r,
     428             :                                    "Bond ARP ip target address is duplicated, ignoring assignment: %s", n);
     429           0 :                 if (r < 0)
     430           0 :                         log_syntax(unit, LOG_ERR, filename, line, r,
     431             :                                    "Failed to store bond ARP ip target address '%s', ignoring assignment: %m", n);
     432             :         }
     433             : }
     434             : 
     435           0 : int config_parse_ad_actor_sys_prio(
     436             :                 const char *unit,
     437             :                 const char *filename,
     438             :                 unsigned line,
     439             :                 const char *section,
     440             :                 unsigned section_line,
     441             :                 const char *lvalue,
     442             :                 int ltype,
     443             :                 const char *rvalue,
     444             :                 void *data,
     445             :                 void *userdata) {
     446           0 :         Bond *b = userdata;
     447             :         uint16_t v;
     448             :         int r;
     449             : 
     450           0 :         assert(filename);
     451           0 :         assert(lvalue);
     452           0 :         assert(rvalue);
     453           0 :         assert(data);
     454             : 
     455           0 :         r = safe_atou16(rvalue, &v);
     456           0 :         if (r < 0) {
     457           0 :                 log_syntax(unit, LOG_ERR, filename, line, r,
     458             :                            "Failed to parse actor system priority '%s', ignoring: %m", rvalue);
     459           0 :                 return 0;
     460             :         }
     461             : 
     462           0 :         if (v == 0) {
     463           0 :                 log_syntax(unit, LOG_ERR, filename, line, 0,
     464             :                            "Failed to parse actor system priority '%s'. Range is [1,65535], ignoring.",
     465             :                            rvalue);
     466           0 :                 return 0;
     467             :         }
     468             : 
     469           0 :         b->ad_actor_sys_prio = v;
     470             : 
     471           0 :         return 0;
     472             : }
     473             : 
     474           0 : int config_parse_ad_user_port_key(
     475             :                 const char *unit,
     476             :                 const char *filename,
     477             :                 unsigned line,
     478             :                 const char *section,
     479             :                 unsigned section_line,
     480             :                 const char *lvalue,
     481             :                 int ltype,
     482             :                 const char *rvalue,
     483             :                 void *data,
     484             :                 void *userdata) {
     485           0 :         Bond *b = userdata;
     486             :         uint16_t v;
     487             :         int r;
     488             : 
     489           0 :         assert(filename);
     490           0 :         assert(lvalue);
     491           0 :         assert(rvalue);
     492           0 :         assert(data);
     493             : 
     494           0 :         r = safe_atou16(rvalue, &v);
     495           0 :         if (r < 0) {
     496           0 :                 log_syntax(unit, LOG_ERR, filename, line, r,
     497             :                            "Failed to parse user port key '%s', ignoring: %m", rvalue);
     498           0 :                 return 0;
     499             :         }
     500             : 
     501           0 :         if (v > 1023) {
     502           0 :                 log_syntax(unit, LOG_ERR, filename, line, 0,
     503             :                            "Failed to parse user port key '%s'. Range is [0…1023], ignoring.", rvalue);
     504           0 :                 return 0;
     505             :         }
     506             : 
     507           0 :         b->ad_user_port_key = v;
     508             : 
     509           0 :         return 0;
     510             : }
     511             : 
     512           0 : int config_parse_ad_actor_system(
     513             :                 const char *unit,
     514             :                 const char *filename,
     515             :                 unsigned line,
     516             :                 const char *section,
     517             :                 unsigned section_line,
     518             :                 const char *lvalue,
     519             :                 int ltype,
     520             :                 const char *rvalue,
     521             :                 void *data,
     522             :                 void *userdata) {
     523           0 :         Bond *b = userdata;
     524             :         struct ether_addr n;
     525             :         int r;
     526             : 
     527           0 :         assert(filename);
     528           0 :         assert(lvalue);
     529           0 :         assert(rvalue);
     530           0 :         assert(data);
     531             : 
     532           0 :         r = ether_addr_from_string(rvalue, &n);
     533           0 :         if (r < 0) {
     534           0 :                 log_syntax(unit, LOG_ERR, filename, line, r,
     535             :                            "Not a valid MAC address %s. Ignoring assignment: %m",
     536             :                            rvalue);
     537           0 :                 return 0;
     538             :         }
     539           0 :         if (ether_addr_is_null(&n) || (n.ether_addr_octet[0] & 0x01)) {
     540           0 :                 log_syntax(unit, LOG_ERR, filename, line, 0,
     541             :                            "Not a valid MAC address %s, can not be null or multicast. Ignoring assignment.",
     542             :                            rvalue);
     543           0 :                 return 0;
     544             :         }
     545             : 
     546           0 :         b->ad_actor_system = n;
     547             : 
     548           0 :         return 0;
     549             : }
     550             : 
     551           0 : static void bond_done(NetDev *netdev) {
     552             :         Bond *b;
     553             : 
     554           0 :         assert(netdev);
     555           0 :         b = BOND(netdev);
     556           0 :         assert(b);
     557             : 
     558           0 :         ordered_set_free(b->arp_ip_targets);
     559           0 : }
     560             : 
     561           0 : static void bond_init(NetDev *netdev) {
     562             :         Bond *b;
     563             : 
     564           0 :         assert(netdev);
     565             : 
     566           0 :         b = BOND(netdev);
     567             : 
     568           0 :         assert(b);
     569             : 
     570           0 :         b->mode = _NETDEV_BOND_MODE_INVALID;
     571           0 :         b->xmit_hash_policy = _NETDEV_BOND_XMIT_HASH_POLICY_INVALID;
     572           0 :         b->lacp_rate = _NETDEV_BOND_LACP_RATE_INVALID;
     573           0 :         b->ad_select = _NETDEV_BOND_AD_SELECT_INVALID;
     574           0 :         b->fail_over_mac = _NETDEV_BOND_FAIL_OVER_MAC_INVALID;
     575           0 :         b->arp_validate = _NETDEV_BOND_ARP_VALIDATE_INVALID;
     576           0 :         b->arp_all_targets = _NETDEV_BOND_ARP_ALL_TARGETS_INVALID;
     577           0 :         b->primary_reselect = _NETDEV_BOND_PRIMARY_RESELECT_INVALID;
     578             : 
     579           0 :         b->all_slaves_active = false;
     580           0 :         b->tlb_dynamic_lb = -1;
     581             : 
     582           0 :         b->resend_igmp = RESEND_IGMP_DEFAULT;
     583           0 :         b->packets_per_slave = PACKETS_PER_SLAVE_DEFAULT;
     584           0 :         b->num_grat_arp = GRATUITOUS_ARP_DEFAULT;
     585           0 :         b->lp_interval = LEARNING_PACKETS_INTERVAL_MIN_SEC;
     586           0 : }
     587             : 
     588             : const NetDevVTable bond_vtable = {
     589             :         .object_size = sizeof(Bond),
     590             :         .init = bond_init,
     591             :         .done = bond_done,
     592             :         .sections = "Match\0NetDev\0Bond\0",
     593             :         .fill_message_create = netdev_bond_fill_message_create,
     594             :         .create_type = NETDEV_CREATE_MASTER,
     595             :         .generate_mac = true,
     596             : };

Generated by: LCOV version 1.14