1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2014 Tom Gundersen <teg@jklm.no>
6 Copyright 2014 Susant Sahani
12 #include "netlink-util.h"
13 #include "netdev/bridge.h"
14 #include "networkd-manager.h"
15 #include "vlan-util.h"
17 /* callback for brige netdev's parameter set */
18 static int netdev_bridge_set_handler(sd_netlink
*rtnl
, sd_netlink_message
*m
, void *userdata
) {
19 _cleanup_netdev_unref_ NetDev
*netdev
= userdata
;
25 r
= sd_netlink_message_get_errno(m
);
27 log_netdev_warning_errno(netdev
, r
, "Bridge parameters could not be set: %m");
31 log_netdev_debug(netdev
, "Bridge parameters set success");
36 static int netdev_bridge_post_create(NetDev
*netdev
, Link
*link
, sd_netlink_message
*m
) {
37 _cleanup_(sd_netlink_message_unrefp
) sd_netlink_message
*req
= NULL
;
47 r
= sd_rtnl_message_new_link(netdev
->manager
->rtnl
, &req
, RTM_NEWLINK
, netdev
->ifindex
);
49 return log_netdev_error_errno(netdev
, r
, "Could not allocate RTM_SETLINK message: %m");
51 r
= sd_netlink_message_set_flags(req
, NLM_F_REQUEST
| NLM_F_ACK
);
53 return log_link_error_errno(link
, r
, "Could not set netlink flags: %m");
55 r
= sd_netlink_message_open_container(req
, IFLA_LINKINFO
);
57 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_PROTINFO attribute: %m");
59 r
= sd_netlink_message_open_container_union(req
, IFLA_INFO_DATA
, netdev_kind_to_string(netdev
->kind
));
61 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_INFO_DATA attribute: %m");
63 /* convert to jiffes */
64 if (b
->forward_delay
!= USEC_INFINITY
) {
65 r
= sd_netlink_message_append_u32(req
, IFLA_BR_FORWARD_DELAY
, usec_to_jiffies(b
->forward_delay
));
67 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_BR_FORWARD_DELAY attribute: %m");
70 if (b
->hello_time
> 0) {
71 r
= sd_netlink_message_append_u32(req
, IFLA_BR_HELLO_TIME
, usec_to_jiffies(b
->hello_time
));
73 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_BR_HELLO_TIME attribute: %m");
77 r
= sd_netlink_message_append_u32(req
, IFLA_BR_MAX_AGE
, usec_to_jiffies(b
->max_age
));
79 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_BR_MAX_AGE attribute: %m");
82 if (b
->ageing_time
!= USEC_INFINITY
) {
83 r
= sd_netlink_message_append_u32(req
, IFLA_BR_AGEING_TIME
, usec_to_jiffies(b
->ageing_time
));
85 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_BR_AGEING_TIME attribute: %m");
88 if (b
->priority
> 0) {
89 r
= sd_netlink_message_append_u16(req
, IFLA_BR_PRIORITY
, b
->priority
);
91 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_BR_PRIORITY attribute: %m");
94 if (b
->group_fwd_mask
> 0) {
95 r
= sd_netlink_message_append_u16(req
, IFLA_BR_GROUP_FWD_MASK
, b
->group_fwd_mask
);
97 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_BR_GROUP_FWD_MASK attribute: %m");
100 if (b
->default_pvid
!= VLANID_INVALID
) {
101 r
= sd_netlink_message_append_u16(req
, IFLA_BR_VLAN_DEFAULT_PVID
, b
->default_pvid
);
103 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_BR_VLAN_DEFAULT_PVID attribute: %m");
106 if (b
->mcast_querier
>= 0) {
107 r
= sd_netlink_message_append_u8(req
, IFLA_BR_MCAST_QUERIER
, b
->mcast_querier
);
109 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_BR_MCAST_QUERIER attribute: %m");
112 if (b
->mcast_snooping
>= 0) {
113 r
= sd_netlink_message_append_u8(req
, IFLA_BR_MCAST_SNOOPING
, b
->mcast_snooping
);
115 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_BR_MCAST_SNOOPING attribute: %m");
118 if (b
->vlan_filtering
>= 0) {
119 r
= sd_netlink_message_append_u8(req
, IFLA_BR_VLAN_FILTERING
, b
->vlan_filtering
);
121 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_BR_VLAN_FILTERING attribute: %m");
125 r
= sd_netlink_message_append_u32(req
, IFLA_BR_STP_STATE
, b
->stp
);
127 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_BR_STP_STATE attribute: %m");
130 r
= sd_netlink_message_close_container(req
);
132 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_LINKINFO attribute: %m");
134 r
= sd_netlink_message_close_container(req
);
136 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_INFO_DATA attribute: %m");
138 r
= sd_netlink_call_async(netdev
->manager
->rtnl
, req
, netdev_bridge_set_handler
, netdev
, 0, NULL
);
140 return log_netdev_error_errno(netdev
, r
, "Could not send rtnetlink message: %m");
147 static void bridge_init(NetDev
*n
) {
154 b
->mcast_querier
= -1;
155 b
->mcast_snooping
= -1;
156 b
->vlan_filtering
= -1;
158 b
->default_pvid
= VLANID_INVALID
;
159 b
->forward_delay
= USEC_INFINITY
;
160 b
->ageing_time
= USEC_INFINITY
;
163 const NetDevVTable bridge_vtable
= {
164 .object_size
= sizeof(Bridge
),
166 .sections
= "Match\0NetDev\0Bridge\0",
167 .post_create
= netdev_bridge_post_create
,
168 .create_type
= NETDEV_CREATE_MASTER
,