Merge pull request #1459 from ssahani/bridge1

networkd: add bridge properties
This commit is contained in:
Tom Gundersen 2015-10-05 22:44:38 +02:00
commit dc545f8331
11 changed files with 169 additions and 2 deletions

View file

@ -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],
[], [], [[

View file

@ -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>

View file

@ -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

View file

@ -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);

View file

@ -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 },
/*

View file

@ -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,
};

View file

@ -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;

View file

@ -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)

View file

@ -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;
}

View file

@ -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);
};

View file

@ -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 */