]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #1459 from ssahani/bridge1
authorTom Gundersen <teg@jklm.no>
Mon, 5 Oct 2015 20:44:38 +0000 (22:44 +0200)
committerTom Gundersen <teg@jklm.no>
Mon, 5 Oct 2015 20:44:38 +0000 (22:44 +0200)
networkd: add bridge properties

configure.ac
man/systemd.netdev.xml
src/basic/missing.h
src/libsystemd/sd-netlink/netlink-message.c
src/libsystemd/sd-netlink/netlink-types.c
src/network/networkd-netdev-bridge.c
src/network/networkd-netdev-bridge.h
src/network/networkd-netdev-gperf.gperf
src/network/networkd-netdev.c
src/network/networkd-netdev.h
src/systemd/sd-netlink.h

index d75a02623bc63f43a7795ab5d1a524b7aa5e379b..aabb5e4fe48680889565355d43f87584316b6baf 100644 (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],
 [], [], [[
index 05bbad7f65500911f53df851b5ac569d6a121e41..67c12a7173df0ca9c10802498e7dfd1833f9f2a2 100644 (file)
       </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>
 
index 9811b6b23e4e7b6fe930a4f6722412614158252a..1e3af283bb3496e5b819cf5f12f235ed550aa6ab 100644 (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
index 0d8e37b856c1e9f2e10d4e26494412c1e4d39dda..cf693de5fbf3cb68779df2652fcb5fbe9148d6b5 100644 (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);
 
index 21283291919fbbb5f3cefb6d6fba00fb3f084a1f..4a5340e659248dac68e85f595aa7c4cccb98f701 100644 (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 },
 /*
index fd6af7e99b7f39a854bcfbd58a25f94add67270c..2eeb86a683b0ea0d787c3cfa9451a67a008e71b2 100644 (file)
     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,
 };
index a7d02b1c91c61b24fb37f5c9b6dcfadbce6d370b..d3bd15e0d6d128db13b1198dd69ac39c02239902 100644 (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;
index e0bd0e024aa3d1ce53c3cc2c24ea3749e483d8c5..4aac2398503b4962a41c25a19f229fc3aa62a49f 100644 (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)
index ff1edf2c39c575bfc857e9be085517d89d87ec09..3d4865a780b98f435c33125ff98277a55e39fc8f 100644 (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;
 }
 
index 1f8510c4f717d56c335b85cb8c7c2bc691c9cae5..3b9ab27b675186ef759aa7551cac78ff70249643 100644 (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);
 };
index cb462bf48f0432f0a4ea08a03add9bbcf1418dac..e09b8c8e2d51d1aa65e76958f37b827f2801c9fc 100644 (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 */