mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-10-28 03:25:27 +03:00
Merge pull request #1459 from ssahani/bridge1
networkd: add bridge properties
This commit is contained in:
commit
dc545f8331
@ -321,6 +321,7 @@ AC_CHECK_DECLS([IFLA_INET6_ADDR_GEN_MODE,
|
||||
IFLA_GRE_ENCAP_DPORT,
|
||||
IFLA_BRIDGE_VLAN_INFO,
|
||||
IFLA_BRPORT_LEARNING_SYNC,
|
||||
IFLA_BR_PRIORITY,
|
||||
NDA_IFINDEX,
|
||||
IFA_FLAGS],
|
||||
[], [], [[
|
||||
|
@ -277,6 +277,43 @@
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>[Bridge] Section Options</title>
|
||||
|
||||
<para>The <literal>[Bridge]</literal> section only applies for
|
||||
netdevs of kind <literal>bridge</literal>, and accepts the
|
||||
following key:</para>
|
||||
|
||||
<variablelist class='network-directives'>
|
||||
<varlistentry>
|
||||
<term><varname>HelloTimeSec=</varname></term>
|
||||
<listitem>
|
||||
<para>HelloTimeSec specifies the number of seconds a hello packet is
|
||||
sent out by the root bridge and the designated bridges. Hello packets are
|
||||
used to communicate information about the topology throughout the entire
|
||||
bridged local area network.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>MaxAgeSec=</varname></term>
|
||||
<listitem>
|
||||
<para>MaxAgeSec specifies the number of seconds of maximum message age.
|
||||
If the last seen (received) hello packet is more than this number of
|
||||
seconds old, the bridge in question will start the takeover procedure
|
||||
in attempt to become the Root Bridge itself.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>ForwardDelaySec=</varname></term>
|
||||
<listitem>
|
||||
<para>ForwardDelaySec specifies the number of seconds spent in each
|
||||
of the Listening and Learning states before the Forwarding state is entered.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>[VLAN] Section Options</title>
|
||||
|
||||
|
@ -842,6 +842,19 @@ static inline int setns(int fd, int nstype) {
|
||||
#define IFLA_BRIDGE_MAX (__IFLA_BRIDGE_MAX - 1)
|
||||
#endif
|
||||
|
||||
#if !HAVE_DECL_IFLA_BR_PRIORITY
|
||||
#define IFLA_BR_UNSPEC 0
|
||||
#define IFLA_BR_FORWARD_DELAY 1
|
||||
#define IFLA_BR_HELLO_TIME 2
|
||||
#define IFLA_BR_MAX_AGE 3
|
||||
#define IFLA_BR_AGEING_TIME 4
|
||||
#define IFLA_BR_STP_STATE 5
|
||||
#define IFLA_BR_PRIORITY 6
|
||||
#define __IFLA_BR_MAX 7
|
||||
|
||||
#define IFLA_BR_MAX (__IFLA_BR_MAX - 1)
|
||||
#endif
|
||||
|
||||
#if !HAVE_DECL_IFLA_BRPORT_LEARNING_SYNC
|
||||
#define IFLA_BRPORT_UNSPEC 0
|
||||
#define IFLA_BRPORT_STATE 1
|
||||
|
@ -149,6 +149,15 @@ int sd_netlink_message_get_type(sd_netlink_message *m, uint16_t *type) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_netlink_message_set_flags(sd_netlink_message *m, uint16_t flags) {
|
||||
assert_return(m, -EINVAL);
|
||||
assert_return(flags, -EINVAL);
|
||||
|
||||
m->hdr->nlmsg_flags = flags;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_netlink_message_is_broadcast(sd_netlink_message *m) {
|
||||
assert_return(m, -EINVAL);
|
||||
|
||||
|
@ -97,7 +97,7 @@ static const NLType rtnl_link_info_data_macvlan_types[IFLA_MACVLAN_MAX + 1] = {
|
||||
[IFLA_MACVLAN_FLAGS] = { .type = NETLINK_TYPE_U16 },
|
||||
};
|
||||
|
||||
static const NLType rtnl_link_info_data_bridge_types[IFLA_BRIDGE_MAX + 1] = {
|
||||
static const NLType rtnl_link_bridge_management_types[IFLA_BRIDGE_MAX + 1] = {
|
||||
[IFLA_BRIDGE_FLAGS] = { .type = NETLINK_TYPE_U16 },
|
||||
[IFLA_BRIDGE_MODE] = { .type = NETLINK_TYPE_U16 },
|
||||
/*
|
||||
@ -106,6 +106,15 @@ static const NLType rtnl_link_info_data_bridge_types[IFLA_BRIDGE_MAX + 1] = {
|
||||
*/
|
||||
};
|
||||
|
||||
static const NLType rtnl_link_info_data_bridge_types[IFLA_BR_MAX + 1] = {
|
||||
[IFLA_BR_FORWARD_DELAY] = { .type = NETLINK_TYPE_U32 },
|
||||
[IFLA_BR_HELLO_TIME] = { .type = NETLINK_TYPE_U32 },
|
||||
[IFLA_BR_MAX_AGE] = { .type = NETLINK_TYPE_U32 },
|
||||
[IFLA_BR_AGEING_TIME] = { .type = NETLINK_TYPE_U32 },
|
||||
[IFLA_BR_STP_STATE] = { .type = NETLINK_TYPE_U32 },
|
||||
[IFLA_BR_PRIORITY] = { .type = NETLINK_TYPE_U16 },
|
||||
};
|
||||
|
||||
static const NLType rtnl_link_info_data_vlan_types[IFLA_VLAN_MAX + 1] = {
|
||||
[IFLA_VLAN_ID] = { .type = NETLINK_TYPE_U16 },
|
||||
/*
|
||||
|
@ -20,12 +20,96 @@
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include <net/if.h>
|
||||
|
||||
#include "networkd-netdev-bridge.h"
|
||||
#include "missing.h"
|
||||
#include "netlink-util.h"
|
||||
|
||||
/* callback for brige netdev's parameter set */
|
||||
static int netdev_bridge_set_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
|
||||
_cleanup_netdev_unref_ NetDev *netdev = userdata;
|
||||
int r;
|
||||
|
||||
assert(netdev);
|
||||
assert(m);
|
||||
|
||||
r = sd_netlink_message_get_errno(m);
|
||||
if (r < 0) {
|
||||
log_netdev_warning_errno(netdev, r, "Bridge parameters could not be set: %m");
|
||||
return 1;
|
||||
}
|
||||
|
||||
log_netdev_debug(netdev, "Bridge parametres set success");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int netdev_bridge_post_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
|
||||
_cleanup_netlink_message_unref_ sd_netlink_message *req = NULL;
|
||||
Bridge *b;
|
||||
int r;
|
||||
|
||||
assert(netdev);
|
||||
|
||||
b = BRIDGE(netdev);
|
||||
|
||||
assert(b);
|
||||
|
||||
r = sd_rtnl_message_new_link(netdev->manager->rtnl, &req, RTM_NEWLINK, netdev->ifindex);
|
||||
if (r < 0)
|
||||
return log_netdev_error_errno(netdev, r, "Could not allocate RTM_SETLINK message: %m");
|
||||
|
||||
r = sd_netlink_message_set_flags(req, NLM_F_REQUEST | NLM_F_ACK);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not set netlink flags: %m");
|
||||
|
||||
r = sd_netlink_message_open_container(req, IFLA_LINKINFO);
|
||||
if (r < 0)
|
||||
return log_netdev_error_errno(netdev, r, "Could not append IFLA_PROTINFO attribute: %m");
|
||||
|
||||
r = sd_netlink_message_open_container_union(req, IFLA_INFO_DATA, netdev_kind_to_string(netdev->kind));
|
||||
if (r < 0)
|
||||
return log_netdev_error_errno(netdev, r, "Could not append IFLA_INFO_DATA attribute: %m");
|
||||
|
||||
if (b->forward_delay > 0) {
|
||||
r = sd_netlink_message_append_u32(req, IFLA_BR_FORWARD_DELAY, b->forward_delay / USEC_PER_SEC);
|
||||
if (r < 0)
|
||||
return log_netdev_error_errno(netdev, r, "Could not append IFLA_BR_FORWARD_DELAY attribute: %m");
|
||||
}
|
||||
|
||||
if (b->hello_time > 0) {
|
||||
r = sd_netlink_message_append_u32(req, IFLA_BR_HELLO_TIME, b->hello_time / USEC_PER_SEC );
|
||||
if (r < 0)
|
||||
return log_netdev_error_errno(netdev, r, "Could not append IFLA_BR_HELLO_TIME attribute: %m");
|
||||
}
|
||||
|
||||
if (b->max_age > 0) {
|
||||
r = sd_netlink_message_append_u32(req, IFLA_BR_MAX_AGE, b->max_age / USEC_PER_SEC);
|
||||
if (r < 0)
|
||||
return log_netdev_error_errno(netdev, r, "Could not append IFLA_BR_MAX_AGE attribute: %m");
|
||||
}
|
||||
|
||||
r = sd_netlink_message_close_container(req);
|
||||
if (r < 0)
|
||||
return log_netdev_error_errno(netdev, r, "Could not append IFLA_LINKINFO attribute: %m");
|
||||
|
||||
r = sd_netlink_message_close_container(req);
|
||||
if (r < 0)
|
||||
return log_netdev_error_errno(netdev, r, "Could not append IFLA_INFO_DATA attribute: %m");
|
||||
|
||||
r = sd_netlink_call_async(netdev->manager->rtnl, req, netdev_bridge_set_handler, netdev, 0, NULL);
|
||||
if (r < 0)
|
||||
return log_netdev_error_errno(netdev, r, "Could not send rtnetlink message: %m");
|
||||
|
||||
netdev_ref(netdev);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
const NetDevVTable bridge_vtable = {
|
||||
.object_size = sizeof(Bridge),
|
||||
.sections = "Match\0NetDev\0",
|
||||
.sections = "Match\0NetDev\0Bridge\0",
|
||||
.post_create = netdev_bridge_post_create,
|
||||
.create_type = NETDEV_CREATE_MASTER,
|
||||
};
|
||||
|
@ -27,6 +27,10 @@ typedef struct Bridge Bridge;
|
||||
|
||||
struct Bridge {
|
||||
NetDev meta;
|
||||
|
||||
usec_t forward_delay;
|
||||
usec_t hello_time;
|
||||
usec_t max_age;
|
||||
};
|
||||
|
||||
extern const NetDevVTable bridge_vtable;
|
||||
|
@ -86,3 +86,6 @@ Bond.UpDelaySec, config_parse_sec, 0,
|
||||
Bond.DownDelaySec, config_parse_sec, 0, offsetof(Bond, downdelay)
|
||||
Bond.ARPIntervalSec, config_parse_sec, 0, offsetof(Bond, arp_interval)
|
||||
Bond.LearnPacketIntervalSec, config_parse_sec, 0, offsetof(Bond, lp_interval)
|
||||
Bridge.HelloTimeSec, config_parse_sec, 0, offsetof(Bridge, hello_time)
|
||||
Bridge.MaxAgeSec, config_parse_sec, 0, offsetof(Bridge, max_age)
|
||||
Bridge.ForwardDelaySec, config_parse_sec, 0, offsetof(Bridge, forward_delay)
|
||||
|
@ -245,6 +245,9 @@ static int netdev_enter_ready(NetDev *netdev) {
|
||||
free(callback);
|
||||
}
|
||||
|
||||
if (NETDEV_VTABLE(netdev)->post_create)
|
||||
NETDEV_VTABLE(netdev)->post_create(netdev, NULL, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -141,6 +141,9 @@ struct NetDevVTable {
|
||||
/* create netdev, if not done via rtnl */
|
||||
int (*create)(NetDev *netdev);
|
||||
|
||||
/* perform additional configuration after netdev has been createad */
|
||||
int (*post_create)(NetDev *netdev, Link *link, sd_netlink_message *message);
|
||||
|
||||
/* verify that compulsory configuration options were specified */
|
||||
int (*config_verify)(NetDev *netdev, const char *filename);
|
||||
};
|
||||
|
@ -104,6 +104,7 @@ int sd_netlink_message_request_dump(sd_netlink_message *m, int dump);
|
||||
int sd_netlink_message_is_error(sd_netlink_message *m);
|
||||
int sd_netlink_message_get_errno(sd_netlink_message *m);
|
||||
int sd_netlink_message_get_type(sd_netlink_message *m, uint16_t *type);
|
||||
int sd_netlink_message_set_flags(sd_netlink_message *m, uint16_t flags);
|
||||
int sd_netlink_message_is_broadcast(sd_netlink_message *m);
|
||||
|
||||
/* rtnl */
|
||||
|
Loading…
Reference in New Issue
Block a user