]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
networkd: add bridge properties
authorSusant Sahani <ssahani@gmail.com>
Mon, 5 Oct 2015 04:08:00 +0000 (09:38 +0530)
committerSusant Sahani <ssahani@gmail.com>
Mon, 5 Oct 2015 04:13:29 +0000 (09:43 +0530)
ForwardDelaySec:   forward delay
HelloTimeSec:      hello time
MaxAgeSec:         maximum message age

for more information see
http://www.tldp.org/HOWTO/BRIDGE-STP-HOWTO/set-up-the-bridge.html

In kernel
br_dev_newlink: does not have the this functionality to set while
creation.
br_changelink: after creation we can change the parameters.

we need to first create then set it the parameters.

Introduce new callback post_create .This should
set the properties after the creation.

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

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