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

          Line data    Source code
       1             : /* SPDX-License-Identifier: LGPL-2.1+ */
       2             : 
       3             : #include <net/if.h>
       4             : 
       5             : #include "missing.h"
       6             : #include "netlink-util.h"
       7             : #include "netdev/bridge.h"
       8             : #include "network-internal.h"
       9             : #include "networkd-manager.h"
      10             : #include "string-table.h"
      11             : #include "vlan-util.h"
      12             : 
      13             : static const char* const multicast_router_table[_MULTICAST_ROUTER_MAX] = {
      14             :         [MULTICAST_ROUTER_NONE] = "no",
      15             :         [MULTICAST_ROUTER_TEMPORARY_QUERY] = "query",
      16             :         [MULTICAST_ROUTER_PERMANENT] = "permanent",
      17             :         [MULTICAST_ROUTER_TEMPORARY] = "temporary",
      18             : };
      19             : 
      20           0 : DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(multicast_router, MulticastRouter, _MULTICAST_ROUTER_INVALID);
      21           0 : DEFINE_CONFIG_PARSE_ENUM(config_parse_multicast_router, multicast_router, MulticastRouter,
      22             :                          "Failed to parse bridge multicast router setting");
      23             : 
      24             : /* callback for bridge netdev's parameter set */
      25           0 : static int netdev_bridge_set_handler(sd_netlink *rtnl, sd_netlink_message *m, NetDev *netdev) {
      26             :         int r;
      27             : 
      28           0 :         assert(netdev);
      29           0 :         assert(m);
      30             : 
      31           0 :         r = sd_netlink_message_get_errno(m);
      32           0 :         if (r < 0) {
      33           0 :                 log_netdev_warning_errno(netdev, r, "Bridge parameters could not be set: %m");
      34           0 :                 return 1;
      35             :         }
      36             : 
      37           0 :         log_netdev_debug(netdev, "Bridge parameters set success");
      38             : 
      39           0 :         return 1;
      40             : }
      41             : 
      42           0 : static int netdev_bridge_post_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
      43           0 :         _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
      44             :         Bridge *b;
      45             :         int r;
      46             : 
      47           0 :         assert(netdev);
      48             : 
      49           0 :         b = BRIDGE(netdev);
      50             : 
      51           0 :         assert(b);
      52             : 
      53           0 :         r = sd_rtnl_message_new_link(netdev->manager->rtnl, &req, RTM_NEWLINK, netdev->ifindex);
      54           0 :         if (r < 0)
      55           0 :                 return log_netdev_error_errno(netdev, r, "Could not allocate RTM_SETLINK message: %m");
      56             : 
      57           0 :         r = sd_netlink_message_set_flags(req, NLM_F_REQUEST | NLM_F_ACK);
      58           0 :         if (r < 0)
      59           0 :                 return log_link_error_errno(link, r, "Could not set netlink flags: %m");
      60             : 
      61           0 :         r = sd_netlink_message_open_container(req, IFLA_LINKINFO);
      62           0 :         if (r < 0)
      63           0 :                 return log_netdev_error_errno(netdev, r, "Could not append IFLA_LINKINFO attribute: %m");
      64             : 
      65           0 :         r = sd_netlink_message_open_container_union(req, IFLA_INFO_DATA, netdev_kind_to_string(netdev->kind));
      66           0 :         if (r < 0)
      67           0 :                 return log_netdev_error_errno(netdev, r, "Could not append IFLA_INFO_DATA attribute: %m");
      68             : 
      69             :         /* convert to jiffes */
      70           0 :         if (b->forward_delay != USEC_INFINITY) {
      71           0 :                 r = sd_netlink_message_append_u32(req, IFLA_BR_FORWARD_DELAY, usec_to_jiffies(b->forward_delay));
      72           0 :                 if (r < 0)
      73           0 :                         return log_netdev_error_errno(netdev, r, "Could not append IFLA_BR_FORWARD_DELAY attribute: %m");
      74             :         }
      75             : 
      76           0 :         if (b->hello_time > 0) {
      77           0 :                 r = sd_netlink_message_append_u32(req, IFLA_BR_HELLO_TIME, usec_to_jiffies(b->hello_time));
      78           0 :                 if (r < 0)
      79           0 :                         return log_netdev_error_errno(netdev, r, "Could not append IFLA_BR_HELLO_TIME attribute: %m");
      80             :         }
      81             : 
      82           0 :         if (b->max_age > 0) {
      83           0 :                 r = sd_netlink_message_append_u32(req, IFLA_BR_MAX_AGE, usec_to_jiffies(b->max_age));
      84           0 :                 if (r < 0)
      85           0 :                         return log_netdev_error_errno(netdev, r, "Could not append IFLA_BR_MAX_AGE attribute: %m");
      86             :         }
      87             : 
      88           0 :         if (b->ageing_time != USEC_INFINITY) {
      89           0 :                 r = sd_netlink_message_append_u32(req, IFLA_BR_AGEING_TIME, usec_to_jiffies(b->ageing_time));
      90           0 :                 if (r < 0)
      91           0 :                         return log_netdev_error_errno(netdev, r, "Could not append IFLA_BR_AGEING_TIME attribute: %m");
      92             :         }
      93             : 
      94           0 :         if (b->priority > 0) {
      95           0 :                 r = sd_netlink_message_append_u16(req, IFLA_BR_PRIORITY, b->priority);
      96           0 :                 if (r < 0)
      97           0 :                         return log_netdev_error_errno(netdev, r, "Could not append IFLA_BR_PRIORITY attribute: %m");
      98             :         }
      99             : 
     100           0 :         if (b->group_fwd_mask > 0) {
     101           0 :                 r = sd_netlink_message_append_u16(req, IFLA_BR_GROUP_FWD_MASK, b->group_fwd_mask);
     102           0 :                 if (r < 0)
     103           0 :                         return log_netdev_error_errno(netdev, r, "Could not append IFLA_BR_GROUP_FWD_MASK attribute: %m");
     104             :         }
     105             : 
     106           0 :         if (b->default_pvid != VLANID_INVALID) {
     107           0 :                 r = sd_netlink_message_append_u16(req, IFLA_BR_VLAN_DEFAULT_PVID, b->default_pvid);
     108           0 :                 if (r < 0)
     109           0 :                         return log_netdev_error_errno(netdev, r, "Could not append IFLA_BR_VLAN_DEFAULT_PVID attribute: %m");
     110             :         }
     111             : 
     112           0 :         if (b->mcast_querier >= 0) {
     113           0 :                 r = sd_netlink_message_append_u8(req, IFLA_BR_MCAST_QUERIER, b->mcast_querier);
     114           0 :                 if (r < 0)
     115           0 :                         return log_netdev_error_errno(netdev, r, "Could not append IFLA_BR_MCAST_QUERIER attribute: %m");
     116             :         }
     117             : 
     118           0 :         if (b->mcast_snooping >= 0) {
     119           0 :                 r = sd_netlink_message_append_u8(req, IFLA_BR_MCAST_SNOOPING, b->mcast_snooping);
     120           0 :                 if (r < 0)
     121           0 :                         return log_netdev_error_errno(netdev, r, "Could not append IFLA_BR_MCAST_SNOOPING attribute: %m");
     122             :         }
     123             : 
     124           0 :         if (b->vlan_filtering >= 0) {
     125           0 :                 r = sd_netlink_message_append_u8(req, IFLA_BR_VLAN_FILTERING, b->vlan_filtering);
     126           0 :                 if (r < 0)
     127           0 :                         return log_netdev_error_errno(netdev, r, "Could not append IFLA_BR_VLAN_FILTERING attribute: %m");
     128             :         }
     129             : 
     130           0 :         if (b->stp >= 0) {
     131           0 :                 r = sd_netlink_message_append_u32(req, IFLA_BR_STP_STATE, b->stp);
     132           0 :                 if (r < 0)
     133           0 :                         return log_netdev_error_errno(netdev, r, "Could not append IFLA_BR_STP_STATE attribute: %m");
     134             :         }
     135             : 
     136           0 :         if (b->igmp_version > 0) {
     137           0 :                 r = sd_netlink_message_append_u8(req, IFLA_BR_MCAST_IGMP_VERSION, b->igmp_version);
     138           0 :                 if (r < 0)
     139           0 :                         return log_netdev_error_errno(netdev, r, "Could not append IFLA_BR_MCAST_IGMP_VERSION attribute: %m");
     140             :         }
     141             : 
     142           0 :         r = sd_netlink_message_close_container(req);
     143           0 :         if (r < 0)
     144           0 :                 return log_netdev_error_errno(netdev, r, "Could not append IFLA_LINKINFO attribute: %m");
     145             : 
     146           0 :         r = sd_netlink_message_close_container(req);
     147           0 :         if (r < 0)
     148           0 :                 return log_netdev_error_errno(netdev, r, "Could not append IFLA_INFO_DATA attribute: %m");
     149             : 
     150           0 :         r = netlink_call_async(netdev->manager->rtnl, NULL, req, netdev_bridge_set_handler,
     151             :                                netdev_destroy_callback, netdev);
     152           0 :         if (r < 0)
     153           0 :                 return log_netdev_error_errno(netdev, r, "Could not send rtnetlink message: %m");
     154             : 
     155           0 :         netdev_ref(netdev);
     156             : 
     157           0 :         return r;
     158             : }
     159             : 
     160           0 : static int link_set_bridge_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
     161             :         int r;
     162             : 
     163           0 :         assert(m);
     164           0 :         assert(link);
     165           0 :         assert(link->ifname);
     166             : 
     167           0 :         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
     168           0 :                 return 1;
     169             : 
     170           0 :         r = sd_netlink_message_get_errno(m);
     171           0 :         if (r < 0) {
     172           0 :                 log_link_warning_errno(link, r, "Could not set bridge interface: %m");
     173           0 :                 return 1;
     174             :         }
     175             : 
     176           0 :         return 1;
     177             : }
     178             : 
     179           0 : int link_set_bridge(Link *link) {
     180           0 :         _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
     181             :         int r;
     182             : 
     183           0 :         assert(link);
     184           0 :         assert(link->network);
     185             : 
     186           0 :         r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex);
     187           0 :         if (r < 0)
     188           0 :                 return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
     189             : 
     190           0 :         r = sd_rtnl_message_link_set_family(req, PF_BRIDGE);
     191           0 :         if (r < 0)
     192           0 :                 return log_link_error_errno(link, r, "Could not set message family: %m");
     193             : 
     194           0 :         r = sd_netlink_message_open_container(req, IFLA_PROTINFO);
     195           0 :         if (r < 0)
     196           0 :                 return log_link_error_errno(link, r, "Could not append IFLA_PROTINFO attribute: %m");
     197             : 
     198           0 :         if (link->network->use_bpdu >= 0) {
     199           0 :                 r = sd_netlink_message_append_u8(req, IFLA_BRPORT_GUARD, link->network->use_bpdu);
     200           0 :                 if (r < 0)
     201           0 :                         return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_GUARD attribute: %m");
     202             :         }
     203             : 
     204           0 :         if (link->network->hairpin >= 0) {
     205           0 :                 r = sd_netlink_message_append_u8(req, IFLA_BRPORT_MODE, link->network->hairpin);
     206           0 :                 if (r < 0)
     207           0 :                         return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_MODE attribute: %m");
     208             :         }
     209             : 
     210           0 :         if (link->network->fast_leave >= 0) {
     211           0 :                 r = sd_netlink_message_append_u8(req, IFLA_BRPORT_FAST_LEAVE, link->network->fast_leave);
     212           0 :                 if (r < 0)
     213           0 :                         return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_FAST_LEAVE attribute: %m");
     214             :         }
     215             : 
     216           0 :         if (link->network->allow_port_to_be_root >=  0) {
     217           0 :                 r = sd_netlink_message_append_u8(req, IFLA_BRPORT_PROTECT, link->network->allow_port_to_be_root);
     218           0 :                 if (r < 0)
     219           0 :                         return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_PROTECT attribute: %m");
     220             :         }
     221             : 
     222           0 :         if (link->network->unicast_flood >= 0) {
     223           0 :                 r = sd_netlink_message_append_u8(req, IFLA_BRPORT_UNICAST_FLOOD, link->network->unicast_flood);
     224           0 :                 if (r < 0)
     225           0 :                         return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_UNICAST_FLOOD attribute: %m");
     226             :         }
     227             : 
     228           0 :         if (link->network->multicast_flood >= 0) {
     229           0 :                 r = sd_netlink_message_append_u8(req, IFLA_BRPORT_MCAST_FLOOD, link->network->multicast_flood);
     230           0 :                 if (r < 0)
     231           0 :                         return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_MCAST_FLOOD attribute: %m");
     232             :         }
     233             : 
     234           0 :         if (link->network->multicast_to_unicast >= 0) {
     235           0 :                 r = sd_netlink_message_append_u8(req, IFLA_BRPORT_MCAST_TO_UCAST, link->network->multicast_to_unicast);
     236           0 :                 if (r < 0)
     237           0 :                         return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_MCAST_TO_UCAST attribute: %m");
     238             :         }
     239             : 
     240           0 :         if (link->network->neighbor_suppression >= 0) {
     241           0 :                 r = sd_netlink_message_append_u8(req, IFLA_BRPORT_NEIGH_SUPPRESS, link->network->neighbor_suppression);
     242           0 :                 if (r < 0)
     243           0 :                         return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_NEIGH_SUPPRESS attribute: %m");
     244             :         }
     245             : 
     246           0 :         if (link->network->learning >= 0) {
     247           0 :                 r = sd_netlink_message_append_u8(req, IFLA_BRPORT_LEARNING, link->network->learning);
     248           0 :                 if (r < 0)
     249           0 :                         return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_LEARNING attribute: %m");
     250             :         }
     251             : 
     252           0 :         if (link->network->bridge_proxy_arp >= 0) {
     253           0 :                 r = sd_netlink_message_append_u8(req, IFLA_BRPORT_PROXYARP, link->network->bridge_proxy_arp);
     254           0 :                 if (r < 0)
     255           0 :                         return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_PROXYARP attribute: %m");
     256             :         }
     257             : 
     258           0 :         if (link->network->bridge_proxy_arp_wifi >= 0) {
     259           0 :                 r = sd_netlink_message_append_u8(req, IFLA_BRPORT_PROXYARP_WIFI, link->network->bridge_proxy_arp_wifi);
     260           0 :                 if (r < 0)
     261           0 :                         return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_PROXYARP_WIFI attribute: %m");
     262             :         }
     263             : 
     264           0 :         if (link->network->cost != 0) {
     265           0 :                 r = sd_netlink_message_append_u32(req, IFLA_BRPORT_COST, link->network->cost);
     266           0 :                 if (r < 0)
     267           0 :                         return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_COST attribute: %m");
     268             :         }
     269             : 
     270           0 :         if (link->network->priority != LINK_BRIDGE_PORT_PRIORITY_INVALID) {
     271           0 :                 r = sd_netlink_message_append_u16(req, IFLA_BRPORT_PRIORITY, link->network->priority);
     272           0 :                 if (r < 0)
     273           0 :                         return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_PRIORITY attribute: %m");
     274             :         }
     275             : 
     276           0 :         if (link->network->multicast_router != _MULTICAST_ROUTER_INVALID) {
     277           0 :                 r = sd_netlink_message_append_u8(req, IFLA_BRPORT_MULTICAST_ROUTER, link->network->multicast_router);
     278           0 :                 if (r < 0)
     279           0 :                         return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_MULTICAST_ROUTER attribute: %m");
     280             :         }
     281             : 
     282           0 :         r = sd_netlink_message_close_container(req);
     283           0 :         if (r < 0)
     284           0 :                 return log_link_error_errno(link, r, "Could not append IFLA_LINKINFO attribute: %m");
     285             : 
     286           0 :         r = netlink_call_async(link->manager->rtnl, NULL, req, link_set_bridge_handler,
     287             :                                link_netlink_destroy_callback, link);
     288           0 :         if (r < 0)
     289           0 :                 return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
     290             : 
     291           0 :         link_ref(link);
     292             : 
     293           0 :         return r;
     294             : }
     295             : 
     296           0 : int config_parse_bridge_igmp_version(
     297             :                 const char *unit,
     298             :                 const char *filename,
     299             :                 unsigned line,
     300             :                 const char *section,
     301             :                 unsigned section_line,
     302             :                 const char *lvalue,
     303             :                 int ltype,
     304             :                 const char *rvalue,
     305             :                 void *data,
     306             :                 void *userdata) {
     307             : 
     308           0 :         Bridge *b = userdata;
     309             :         uint8_t u;
     310             :         int r;
     311             : 
     312           0 :         assert(filename);
     313           0 :         assert(lvalue);
     314           0 :         assert(rvalue);
     315           0 :         assert(data);
     316             : 
     317           0 :         if (isempty(rvalue)) {
     318           0 :                 b->igmp_version = 0; /* 0 means unset. */
     319           0 :                 return 0;
     320             :         }
     321             : 
     322           0 :         r = safe_atou8(rvalue, &u);
     323           0 :         if (r < 0) {
     324           0 :                 log_syntax(unit, LOG_ERR, filename, line, r,
     325             :                            "Failed to parse bridge's multicast IGMP version number '%s', ignoring assignment: %m",
     326             :                            rvalue);
     327           0 :                 return 0;
     328             :         }
     329           0 :         if (!IN_SET(u, 2, 3)) {
     330           0 :                 log_syntax(unit, LOG_ERR, filename, line, 0,
     331             :                            "Invalid bridge's multicast IGMP version number '%s', ignoring assignment.", rvalue);
     332           0 :                 return 0;
     333             :         }
     334             : 
     335           0 :         b->igmp_version = u;
     336             : 
     337           0 :         return 0;
     338             : }
     339             : 
     340           0 : static void bridge_init(NetDev *n) {
     341             :         Bridge *b;
     342             : 
     343           0 :         b = BRIDGE(n);
     344             : 
     345           0 :         assert(b);
     346             : 
     347           0 :         b->mcast_querier = -1;
     348           0 :         b->mcast_snooping = -1;
     349           0 :         b->vlan_filtering = -1;
     350           0 :         b->stp = -1;
     351           0 :         b->default_pvid = VLANID_INVALID;
     352           0 :         b->forward_delay = USEC_INFINITY;
     353           0 :         b->ageing_time = USEC_INFINITY;
     354           0 : }
     355             : 
     356             : const NetDevVTable bridge_vtable = {
     357             :         .object_size = sizeof(Bridge),
     358             :         .init = bridge_init,
     359             :         .sections = "Match\0NetDev\0Bridge\0",
     360             :         .post_create = netdev_bridge_post_create,
     361             :         .create_type = NETDEV_CREATE_MASTER,
     362             : };

Generated by: LCOV version 1.14