All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH openbmc] Dbus API for systemd/networkd for network configuration.
@ 2016-01-20 15:10 OpenBMC Patches
  2016-01-20 15:10 ` OpenBMC Patches
  0 siblings, 1 reply; 4+ messages in thread
From: OpenBMC Patches @ 2016-01-20 15:10 UTC (permalink / raw)
  To: openbmc

Added interfaces
  org.freedesktop.network1.Network &
  org.freedesktop.network1.Link 
on bus connection org.freedesktop.network1.

networkd-link-bus.c:            SD_BUS_METHOD("GetAddress", "s", "s", method_get_address, SD_BUS_VTABLE_UNPRIVILEGED),
networkd-network-bus.c:         SD_BUS_METHOD("AddAddress", "sssyyys", "x", method_add_address, SD_BUS_VTABLE_UNPRIVILEGED),
networkd-network-bus.c:         SD_BUS_METHOD("DelAddress", "sssyyys", "x", method_del_address, SD_BUS_VTABLE_UNPRIVILEGED),
networkd-network-bus.c:         SD_BUS_METHOD("GetAddress", "s", "a(iyyus)s", method_get_address, SD_BUS_VTABLE_UNPRIVILEGED),


https://github.com/openbmc/openbmc/pull/139

Hariharasubramanian R (1):
  Dbus API for systemd/networkd for network configuration.

 .../0100-systemd_networkd_dbus_setaddress.patch    | 845 +++++++++++++++++++++
 .../meta/recipes-core/systemd/systemd_225.bb       |   1 +
 2 files changed, 846 insertions(+)
 create mode 100644 yocto-poky/meta/recipes-core/systemd/systemd/0100-systemd_networkd_dbus_setaddress.patch

-- 
2.6.4

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH openbmc] Dbus API for systemd/networkd for network configuration.
  2016-01-20 15:10 [PATCH openbmc] Dbus API for systemd/networkd for network configuration OpenBMC Patches
@ 2016-01-20 15:10 ` OpenBMC Patches
  2016-01-21  5:23   ` Cyril Bur
  0 siblings, 1 reply; 4+ messages in thread
From: OpenBMC Patches @ 2016-01-20 15:10 UTC (permalink / raw)
  To: openbmc

From: Hariharasubramanian R <hramasub@in.ibm.com>

---
 .../0100-systemd_networkd_dbus_setaddress.patch    | 845 +++++++++++++++++++++
 .../meta/recipes-core/systemd/systemd_225.bb       |   1 +
 2 files changed, 846 insertions(+)
 create mode 100644 yocto-poky/meta/recipes-core/systemd/systemd/0100-systemd_networkd_dbus_setaddress.patch

diff --git a/yocto-poky/meta/recipes-core/systemd/systemd/0100-systemd_networkd_dbus_setaddress.patch b/yocto-poky/meta/recipes-core/systemd/systemd/0100-systemd_networkd_dbus_setaddress.patch
new file mode 100644
index 0000000..6727c1e
--- /dev/null
+++ b/yocto-poky/meta/recipes-core/systemd/systemd/0100-systemd_networkd_dbus_setaddress.patch
@@ -0,0 +1,845 @@
+From 35efeac7a1b1f6b737348f649d58d1c7eb5ecb8d Mon Sep 17 00:00:00 2001
+From: Hariharasubramanian R <hramasub@in.ibm.com>
+Date: Tue, 19 Jan 2016 05:04:40 -0600
+Subject: [PATCH] Test
+
+---
+ src/network/networkd-link-bus.c           |  93 +++++
+ src/network/networkd-network-bus.c        | 556 ++++++++++++++++++++++++++++++
+ src/network/networkd-network.c            |  81 +++++
+ src/network/org.freedesktop.network1.conf |  17 +
+ 4 files changed, 747 insertions(+)
+
+diff --git a/src/network/networkd-link-bus.c b/src/network/networkd-link-bus.c
+index 1a1524d..103d513 100644
+--- a/src/network/networkd-link-bus.c
++++ b/src/network/networkd-link-bus.c
+@@ -25,15 +25,41 @@
+ #include "networkd.h"
+ #include "networkd-link.h"
+ 
++#define SYSTEMD_NETWORKD_DBUS 1
++
++#ifdef SYSTEMD_NETWORKD_DBUS
++/*
++#include "hostname-util.h"
++#include "network-internal.h"
++#include "networkd-link.h"
++#include "bus-util.h"
++*/
++#include "sd-network.h"
++#include "sd-netlink.h"
++#include "socket-util.h"
++#include "ether-addr-util.h"
++/*
++#include "local-addresses.h"
++*/
++#endif
++
+ static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_operational_state, link_operstate, LinkOperationalState);
+ static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_administrative_state, link_state, LinkState);
+ 
++#ifdef SYSTEMD_NETWORKD_DBUS
++static int method_get_address (sd_bus_message *m, void* userdata, sd_bus_error *error);
++#endif
++
+ const sd_bus_vtable link_vtable[] = {
+         SD_BUS_VTABLE_START(0),
+ 
+         SD_BUS_PROPERTY("OperationalState", "s", property_get_operational_state, offsetof(Link, operstate), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
+         SD_BUS_PROPERTY("AdministrativeState", "s", property_get_administrative_state, offsetof(Link, state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
+ 
++#ifdef SYSTEMD_NETWORKD_DBUS
++	    /* device name */
++    	SD_BUS_METHOD("GetAddress", "s", "s", method_get_address, SD_BUS_VTABLE_UNPRIVILEGED),
++#endif
+         SD_BUS_VTABLE_END
+ };
+ 
+@@ -136,3 +162,70 @@ int link_send_changed(Link *link, const char *property, ...) {
+                         "org.freedesktop.network1.Link",
+                         l);
+ }
++
++static int method_get_address (sd_bus_message *m, void* userdata, sd_bus_error *error)
++{
++    _cleanup_netlink_unref_ sd_netlink                  *rtnl   = NULL;
++    _cleanup_netlink_message_unref_ sd_netlink_message  *req    = NULL;
++    _cleanup_netlink_message_unref_ sd_netlink_message  *reply  = NULL;
++    _cleanup_bus_message_unref_ sd_bus_message          *resp   = NULL;
++    Manager                                             *mgr    = userdata;
++
++    struct udev*        udev               = NULL;
++    struct udev_device* udev_eth           = NULL;
++    const char*         device             = NULL;
++    char                devpath [32]       = "/sys/class/net/"; 
++
++    int                 r;
++    unsigned char       ifindex;
++    bool                have_mac;
++    struct ether_addr   e;
++    char                ea[ETHER_ADDR_TO_STRING_MAX];
++
++    assert(m);
++    assert(mgr);
++
++    r = sd_bus_message_read (m, "s", &device);
++    if (r < 0)
++        return r;
++
++    if (isempty (device))
++        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid Device Name.");
++
++    udev = udev_new();
++    udev_eth = udev_device_new_from_syspath(udev, strcat (devpath, device));
++    if (!udev_eth)
++        return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Could not find udev device");
++
++    ifindex = udev_device_get_ifindex(udev_eth);
++
++    r = sd_netlink_open(&rtnl);
++    if (r < 0)
++            return log_error_errno(r, "Failed to connect to netlink:"); /* fixme */
++
++    r = sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, ifindex);
++    if (r < 0)
++            return r;
++
++    r = sd_netlink_call(rtnl, req, 0, &reply); /* fixme */
++    if (r < 0)
++            return r;
++
++    have_mac = sd_netlink_message_read_ether_addr(reply, IFLA_ADDRESS, &e) >= 0;
++    if (!have_mac)
++        return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Error reading IFLA address");
++
++    ether_addr_to_string(&e, ea);
++
++    r = sd_bus_message_new_method_return(m, &resp);
++    if (r < 0)
++        return sd_bus_error_setf(error, SD_BUS_ERROR_NO_MEMORY, "Error allocating reply messgage");
++
++    r = sd_bus_message_append(resp, "s", ea);
++    if (r < 0)
++        return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Error appending to reply messgage");
++
++    r = sd_bus_send(mgr->bus, resp, NULL);
++
++    return sd_bus_reply_method_return(m, "s", "Getting IFLA address ...");
++}
+diff --git a/src/network/networkd-network-bus.c b/src/network/networkd-network-bus.c
+index 5717a15..6f0d1e5 100644
+--- a/src/network/networkd-network-bus.c
++++ b/src/network/networkd-network-bus.c
+@@ -19,10 +19,34 @@
+   along with systemd; If not, see <http://www.gnu.org/licenses/>.
+ ***/
+ 
++#define SYSTEMD_NETWORKD_DBUS 1
++
++#ifdef SYSTEMD_NETWORKD_DBUS
++#include <netinet/ether.h>
++#include <linux/if.h>
++#endif
++
+ #include "strv.h"
+ 
+ #include "networkd.h"
+ 
++#ifdef SYSTEMD_NETWORKD_DBUS
++#include "hostname-util.h"
++#include "network-internal.h"
++#include "networkd-link.h"
++#include "bus-util.h"
++
++#include "sd-network.h"
++#include "sd-netlink.h"
++#include "local-addresses.h"
++#endif
++
++#ifdef SYSTEMD_NETWORKD_DBUS
++int network_address_added_handler (sd_netlink* rtnl, sd_netlink_message* m, void* userdata);
++int network_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message, void *userdata, Address* address); /* fixme */
++static int method_get_address (sd_bus_message *m, void* userdata, sd_bus_error *error); /* fixme */
++#endif
++
+ static int property_get_ether_addrs(
+                 sd_bus *bus,
+                 const char *path,
+@@ -56,6 +80,11 @@ static int property_get_ether_addrs(
+         return sd_bus_message_close_container(reply);
+ }
+ 
++#ifdef SYSTEMD_NETWORKD_DBUS
++static int method_add_address (sd_bus_message *m, void* userdata, sd_bus_error *error);
++static int method_del_address (sd_bus_message *m, void* userdata, sd_bus_error *error);
++#endif
++
+ const sd_bus_vtable network_vtable[] = {
+         SD_BUS_VTABLE_START(0),
+ 
+@@ -67,6 +96,13 @@ const sd_bus_vtable network_vtable[] = {
+         SD_BUS_PROPERTY("MatchType", "as", NULL, offsetof(Network, match_type), SD_BUS_VTABLE_PROPERTY_CONST),
+         SD_BUS_PROPERTY("MatchName", "as", NULL, offsetof(Network, match_name), SD_BUS_VTABLE_PROPERTY_CONST),
+ 
++#ifdef SYSTEMD_NETWORKD_DBUS
++	    /* device, IP, netmask, family, flags, scope, gateway */
++    	SD_BUS_METHOD("AddAddress", "sssyyys", "x", method_add_address, SD_BUS_VTABLE_UNPRIVILEGED),
++    	SD_BUS_METHOD("DelAddress", "sssyyys", "x", method_del_address, SD_BUS_VTABLE_UNPRIVILEGED),
++	    /* (family, prefixlen, flags, scope, IP)+ gateway */
++    	SD_BUS_METHOD("GetAddress", "s", "a(iyyus)s", method_get_address, SD_BUS_VTABLE_UNPRIVILEGED),
++#endif
+         SD_BUS_VTABLE_END
+ };
+ 
+@@ -152,3 +188,523 @@ int network_object_find(sd_bus *bus, const char *path, const char *interface, vo
+ 
+         return 1;
+ }
++
++#ifdef SYSTEMD_NETWORKD_DBUS
++
++static int method_add_address (sd_bus_message *m, void* userdata, sd_bus_error *error)
++{
++    _cleanup_bus_message_unref_ sd_bus_message*         resp    = NULL;
++    _cleanup_netlink_unref_ sd_netlink*                 rtnl    = NULL;
++    _cleanup_netlink_message_unref_ sd_netlink_message* req     = NULL;
++    _cleanup_netlink_message_unref_ sd_netlink_message* reply   = NULL;
++    _cleanup_address_free_ Address *addr                        = NULL;
++    _cleanup_route_free_ Route *rt                              = NULL;
++    Manager *mgr                                                = userdata;
++    Link*               link               = NULL;
++    struct udev*        udev               = NULL;
++    struct udev_device* udev_eth           = NULL;
++
++    const char*         device             = NULL;
++    const char*         ipaddr             = NULL;
++    const char*         netmask            = NULL;
++    const char*         gateway            = NULL;
++    char                devpath [32]       = "/sys/class/net/"; 
++
++    unsigned char       family;
++    unsigned char       prefixlen;
++    unsigned char       flags;
++    unsigned char       scope;
++    unsigned char       ifindex;
++
++    struct in_addr      nm;
++    struct in_addr      ip;
++    struct in_addr      gw;
++    int r;
++
++    assert(m);
++    assert(mgr);
++
++    r = sd_bus_message_read (m, "sssyyys", &device, &ipaddr, &netmask, &family, &flags, &scope, &gateway);
++    if (r < 0)
++        return r;
++
++    if (isempty (device))
++        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid Device Name.");
++
++    if (isempty (ipaddr))
++        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid IP Address.");
++
++    if (isempty (netmask))
++        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid IP Netmask.");
++
++    assert(family == AF_INET || family == AF_INET6);
++
++    udev = udev_new();
++    udev_eth = udev_device_new_from_syspath(udev, strcat (devpath, device));
++    if (!udev_eth)
++            return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Could not find udev device");
++
++    ifindex = udev_device_get_ifindex(udev_eth);
++
++    inet_aton (netmask, &nm);
++    inet_aton (ipaddr, &ip);
++    if (!isempty (gateway)) inet_aton (gateway, &gw);
++
++    prefixlen = in_addr_netmask_to_prefixlen(&nm);
++    assert(prefixlen > 0);
++
++    r = address_new_dynamic(&addr);
++    if (r < 0)
++        return sd_bus_error_setf(error, SD_BUS_ERROR_NO_MEMORY, "Error allocating new address");
++
++    r = sd_netlink_open(&rtnl);
++    if (r < 0)
++            return sd_bus_error_setf(error, SD_BUS_ERROR_IO_ERROR, "Failed to connect to netlink");
++
++    link = new0(Link, 1);
++    if (!link)
++            return -ENOMEM;
++
++    link->network = new0(Network, 1);
++    if (!link->network)
++            return sd_bus_error_setf(error, SD_BUS_ERROR_NO_MEMORY, "Could not alloc memory for Network");
++
++    link->n_ref                 = 1;
++    link->manager               = mgr;
++    link->manager->rtnl         = rtnl;
++    link->state                 = LINK_STATE_PENDING;
++    link->rtnl_extended_attrs   = true;
++    link->ifindex               = ifindex;
++    link->ifname                = strdup(device); /*FIXME:*/
++    if (!link->ifname)
++            return -ENOMEM;
++
++    addr->family                = family;
++    addr->in_addr.in.s_addr     = ip.s_addr;
++    addr->prefixlen             = prefixlen;
++    addr->broadcast.s_addr      = ip.s_addr | ~nm.s_addr;
++
++    if (!isempty (gateway))
++    {
++        r = route_new_dynamic(&rt, RTPROT_STATIC);
++        if (r < 0)
++            return r;
++
++        rt->protocol        = RTPROT_STATIC;
++        rt->network         = link->network;
++        rt->family          = family;
++        rt->scope           = RT_SCOPE_LINK;            /* FIXME: */
++        rt->dst_prefixlen   = 32;                       /* FIXME: AF_INET assumed */
++        rt->dst_addr.in     = gw;
++
++        LIST_PREPEND(routes, link->network->static_routes, rt);
++    }
++
++    /* send an nlmsg (RTM_NEWADDR) and append address to link address list */
++    r = address_update (addr, link, network_address_added_handler);
++    if (r < 0)
++        return r;
++
++    r = sd_bus_message_new_method_return(m, &resp);
++    if (r < 0)
++        return sd_bus_error_setf(error, SD_BUS_ERROR_NO_MEMORY, "Error allocating reply messgage");
++
++    r = sd_bus_message_append(resp, "x", 0);
++    if (r < 0)
++            return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Error appending to reply messgage");
++
++    r = sd_bus_send(mgr->bus, resp, NULL);
++    if (r < 0)
++            return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Error sending reply messgage");
++
++    return sd_bus_reply_method_return(m, "s", "Adding IP address...");
++}
++
++static int method_del_address (sd_bus_message *m, void* userdata, sd_bus_error *error)
++{
++    _cleanup_bus_message_unref_ sd_bus_message*         resp    = NULL;
++    _cleanup_netlink_unref_ sd_netlink*                 rtnl    = NULL;
++    _cleanup_netlink_message_unref_ sd_netlink_message* req     = NULL;
++    _cleanup_netlink_message_unref_ sd_netlink_message* reply   = NULL;
++    _cleanup_address_free_ Address *addr                        = NULL;
++    _cleanup_route_free_ Route *rt                              = NULL;
++    Manager *mgr                                                = userdata;
++    Link*               link               = NULL;
++    struct udev*        udev               = NULL;
++    struct udev_device* udev_eth           = NULL;
++
++    const char*         device             = NULL;
++    const char*         ipaddr             = NULL;
++    const char*         netmask            = NULL;
++    const char*         gateway            = NULL;
++    char                devpath [32]       = "/sys/class/net/"; 
++
++    unsigned char       family;
++    unsigned char       prefixlen;
++    unsigned char       flags;
++    unsigned char       scope;
++    unsigned char       ifindex;
++
++    struct in_addr      nm;
++    struct in_addr      ip;
++    struct in_addr      gw;
++    int r;
++
++    assert(m);
++    assert(mgr);
++
++    r = sd_bus_message_read (m, "sssyyys", &device, &ipaddr, &netmask, &family, &flags, &scope, &gateway);
++    if (r < 0)
++        return r;
++
++    if (isempty (device))
++        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid Device Name.");
++
++    if (isempty (ipaddr))
++        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid IP Address.");
++
++    if (isempty (netmask))
++        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid IP Netmask.");
++
++    assert(family == AF_INET || family == AF_INET6);
++
++    udev = udev_new();
++    udev_eth = udev_device_new_from_syspath(udev, strcat (devpath, device));
++    if (!udev_eth)
++            return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Could not find udev device");
++
++    ifindex = udev_device_get_ifindex(udev_eth);
++
++    inet_aton (netmask, &nm);
++    inet_aton (ipaddr, &ip);
++    if (!isempty (gateway)) inet_aton (gateway, &gw);
++
++    prefixlen = in_addr_netmask_to_prefixlen(&nm);
++    assert(prefixlen > 0);
++
++    r = address_new_dynamic(&addr);
++    if (r < 0)
++        return sd_bus_error_setf(error, SD_BUS_ERROR_NO_MEMORY, "Error allocating new address");
++
++    r = sd_netlink_open(&rtnl);
++    if (r < 0)
++            return sd_bus_error_setf(error, SD_BUS_ERROR_IO_ERROR, "Failed to connect to netlink");
++
++    link = new0(Link, 1);
++    if (!link)
++            return -ENOMEM;
++
++    link->network = new0(Network, 1);
++    if (!link->network)
++            return sd_bus_error_setf(error, SD_BUS_ERROR_NO_MEMORY, "Could not alloc memory for Network");
++
++    link->n_ref                 = 1;
++    link->manager               = mgr;
++    link->manager->rtnl         = rtnl;
++    link->state                 = LINK_STATE_PENDING;
++    link->rtnl_extended_attrs   = true;
++    link->ifindex               = ifindex;
++    link->ifname                = strdup(device);
++    if (!link->ifname)
++            return -ENOMEM;
++
++    addr->family                = family;
++    addr->in_addr.in.s_addr     = ip.s_addr;
++    addr->prefixlen             = prefixlen;
++    addr->broadcast.s_addr      = ip.s_addr | ~nm.s_addr;
++
++    if (!isempty (gateway))
++    {
++        r = route_new_dynamic(&rt, RTPROT_STATIC);
++        if (r < 0)
++            return r;
++
++        rt->network         = link->network;
++        rt->family          = family;
++        rt->scope           = RT_SCOPE_LINK;            /* FIXME: */
++        rt->dst_prefixlen   = 32;                       /* FIXME: AF_INET assumed */
++        rt->dst_addr.in     = gw;
++
++        /*LIST_PREPEND(routes, link->network->static_routes, rt);*/
++        /* Drop the Gateway */
++        route_drop (rt, link, link_route_drop_handler);
++    }
++
++    /* send an nlmsg to delete address from address list */
++    r = address_drop(addr, link, link_address_drop_handler);
++    if (r < 0)
++        return r;
++
++    r = sd_bus_message_new_method_return(m, &resp);
++    if (r < 0)
++        return sd_bus_error_setf(error, SD_BUS_ERROR_NO_MEMORY, "Error allocating reply messgage");
++
++    r = sd_bus_message_append(resp, "x", 0);
++    if (r < 0)
++            return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Error appending to reply messgage");
++
++    r = sd_bus_send(mgr->bus, resp, NULL);
++    if (r < 0)
++            return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Error sending reply messgage");
++
++    return sd_bus_reply_method_return(m, "s", "Deleted IP address...");
++}
++
++static int method_get_address (sd_bus_message *m, void* userdata, sd_bus_error *error)
++{
++    _cleanup_netlink_unref_ sd_netlink  *rtnl   = NULL;
++    _cleanup_address_free_ Address      *addr   = NULL;
++    _cleanup_route_free_ Route          *rt     = NULL;
++    Manager                             *mgr    = userdata;
++#if 0 /* fixme: */
++    Link*               link               = NULL;
++#endif
++    struct udev*        udev               = NULL;
++    struct udev_device* udev_eth           = NULL;
++
++    const char*         device             = NULL;
++#if 0 /* fixme: */
++    const char*         ipaddr             = NULL;
++    const char*         netmask            = NULL;
++    const char*         gateway            = NULL;
++#endif
++    char                devpath [32]       = "/sys/class/net/"; 
++
++#if 0 /* fixme: */
++    unsigned char       family;
++    unsigned char       prefixlen;
++    unsigned char       flags;
++    unsigned char       scope;
++#endif
++    unsigned char       ifindex;
++
++#if 0 /* fixme: */
++    struct in_addr      nm;
++    struct in_addr      ip;
++    struct in_addr      gw;
++#endif
++    int                 r;
++
++    sd_netlink_message* maddr;
++
++    _cleanup_netlink_message_unref_ sd_netlink_message  *req    = NULL;
++    _cleanup_netlink_message_unref_ sd_netlink_message  *reply    = NULL;
++    _cleanup_bus_message_unref_ sd_bus_message  *resp   = NULL;
++    _cleanup_address_free_ Address              *address = NULL;
++    _cleanup_free_ struct local_address         *local   = NULL;
++    _cleanup_free_ char                         *ipr     = NULL;
++    _cleanup_free_ char                         *gwr     = NULL;
++    int                 n;
++    int                 i;
++
++    assert(m);
++    assert(mgr);
++
++    r = sd_bus_message_read (m, "s", &device);
++    if (r < 0)
++        return r;
++
++    if (isempty (device))
++        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid Device Name.");
++
++    udev = udev_new();
++    udev_eth = udev_device_new_from_syspath(udev, strcat (devpath, device));
++    if (!udev_eth)
++        return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Could not find udev device");
++
++    ifindex = udev_device_get_ifindex(udev_eth);
++
++    r = sd_netlink_open(&rtnl);
++    if (r < 0)
++            return log_error_errno(r, "Failed to connect to netlink:"); /* fixme */
++
++    r = sd_rtnl_message_new_addr(rtnl, &req, RTM_GETADDR, 0, 0);
++    if (r < 0)
++            return r;
++
++    r = sd_netlink_message_request_dump(req, true);
++    if (r < 0)
++            return r;
++
++    r = sd_netlink_call(rtnl, req, 0, &reply); /* fixme */
++    if (r < 0)
++            return r;
++
++    r = sd_bus_message_new_method_return(m, &resp);
++    if (r < 0)
++        return sd_bus_error_setf(error, SD_BUS_ERROR_NO_MEMORY, "Error allocating reply messgage");
++
++    r = sd_bus_message_open_container(resp, 'a', "iyyus"); /*family,prefixlen,scope,flags,addr*/
++    if (r < 0)
++        return sd_bus_error_setf(error, SD_BUS_ERROR_NO_MEMORY, "Error opening a container for reply message");
++
++    for (maddr = reply; maddr; maddr = sd_netlink_message_next(maddr)) {
++            int k;
++
++            r = address_new_dynamic(&address);
++            if (r < 0)
++                    return r;
++
++            k = network_rtnl_process_address(rtnl, maddr, mgr, address);
++            if (k) {
++                r = sd_bus_message_append(resp, "i", address->family);
++                if (r < 0)
++                        return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Error appending to reply messgage");
++
++                r = sd_bus_message_append(resp, "y", address->prefixlen);
++                if (r < 0)
++                        return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Error appending to reply messgage");
++
++                r = sd_bus_message_append(resp, "y", address->scope);
++                if (r < 0)
++                        return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Error appending to reply messgage");
++
++                r = sd_bus_message_append(resp, "u", address->flags);
++                if (r < 0)
++                        return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Error appending to reply messgage");
++
++                r = in_addr_to_string(address->family, &address->in_addr, &ipr); /* fixme */
++                if (r < 0)
++                        return r;
++
++                r = sd_bus_message_append(resp, "s", ipr);
++                if (r < 0)
++                        return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Error appending to reply messgage");
++            }
++    }
++
++    r = sd_bus_message_close_container(resp);
++    if (r < 0)
++            return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Error closing reply container");
++
++    n = local_gateways(rtnl, ifindex, AF_UNSPEC, &local);
++    if (n < 0)
++            return n;
++
++    for (i = 0; i < n; i++) {
++
++            r = in_addr_to_string(local[i].family, &local[i].address, &gwr);
++            if (r < 0)
++                    return r;
++    }
++
++    r = sd_bus_message_append(resp, "s", gwr);
++    if (r < 0)
++            return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Error appending to reply messgage");
++
++    r = sd_bus_send(mgr->bus, resp, NULL);
++    if (r < 0)
++            return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Error sending reply messgage");
++
++    return sd_bus_reply_method_return(m, "s", "Getting IP configuration...");
++}
++
++
++int network_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message, void *userdata, Address* address) {
++        Manager*        m       = (Manager*) userdata; /* fixme */
++#if 0 /* fixme */
++        Link*           link    = NULL;
++#endif
++        uint16_t        type;
++        unsigned char   flags;
++#if 0 /* fixme */
++        Address*        existing;
++#endif
++        char            buf[INET6_ADDRSTRLEN]; 
++#if 0 /* fixme */
++        char            valid_buf[FORMAT_TIMESPAN_MAX];
++        const char*     valid_str = NULL;
++#endif
++        int             ifindex;
++        int             r; 
++        /*_cleanup_address_free_ Address *address = NULL;*/
++        sd_bus_error err    = SD_BUS_ERROR_NULL; /* fixme */
++        sd_bus_error* error = &err;             /* fixme */
++
++        assert(rtnl);
++        assert(message);
++        assert(m);
++        assert(address);
++
++        if (sd_netlink_message_is_error(message)) {
++                r = sd_netlink_message_get_errno(message);
++                if (r < 0)
++                        sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "rtnl: failed to receive address: ");
++
++                return 0;
++        }
++
++        r = sd_netlink_message_get_type(message, &type);
++        if (r < 0) {
++                sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "rtnl: could not get message type: ");
++                return 0;
++        } else if (type != RTM_NEWADDR && type != RTM_DELADDR) {
++                sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "rtnl: received unexpected message type when processing address");
++                return 0;
++        }
++
++        r = sd_rtnl_message_addr_get_ifindex(message, &ifindex);
++        if (r < 0) {
++                sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "rtnl: could not get ifindex from address: %m");
++                return 0;
++        } else if (ifindex <= 0) {
++                sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "rtnl: received address message with invalid ifindex: %d", ifindex);
++                return 0;
++        } 
++
++        r = sd_rtnl_message_addr_get_family(message, &address->family); /* int : i*/
++        if (r < 0 || !IN_SET(address->family, AF_INET, AF_INET6)) {
++                sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "rtnl: received address with invalid family, ignoring.");
++                return 0;
++        }
++
++        r = sd_rtnl_message_addr_get_prefixlen(message, &address->prefixlen); /* uchar : byte : y */
++        if (r < 0) {
++                sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "rtnl: received address with invalid prefixlen, ignoring: ");
++                return 0;
++        }
++
++        r = sd_rtnl_message_addr_get_scope(message, &address->scope); /* uchar : byte : y*/
++        if (r < 0) {
++                sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "rtnl: received address with invalid scope, ignoring: ");
++                return 0;
++        }
++
++        r = sd_rtnl_message_addr_get_flags(message, &flags); /* uint32 : u*/
++        if (r < 0) {
++                sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "rtnl: received address with invalid flags, ignoring: ");
++                return 0;
++        }
++        address->flags = flags;
++
++        switch (address->family) {
++        case AF_INET:
++                r = sd_netlink_message_read_in_addr(message, IFA_LOCAL, &address->in_addr.in); /* ulong : uint64 : t */
++                if (r < 0) {
++                        sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "rtnl: received address without valid address, ignoring: ");
++                        return 0;
++                }
++
++                break;
++
++        case AF_INET6:
++                r = sd_netlink_message_read_in6_addr(message, IFA_ADDRESS, &address->in_addr.in6); /* ulong : uint64 : t */
++                if (r < 0) {
++                        sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "rtnl: received address without valid address, ignoring: ");
++                        return 0;
++                }
++
++                break;
++
++        default:
++                assert_not_reached("invalid address family");
++        }
++
++        if (!inet_ntop(address->family, &address->in_addr, buf, INET6_ADDRSTRLEN)) { /* string : s */
++                sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Could not print address");
++                return 0;
++        }
++
++        return 1;
++}
++#endif
+diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
+index 6587ea9..2616c5b 100644
+--- a/src/network/networkd-network.c
++++ b/src/network/networkd-network.c
+@@ -32,6 +32,14 @@
+ #include "network-internal.h"
+ #include "dns-domain.h"
+ 
++#define SYSTEMD_NETWORKD_DBUS 1
++
++#ifdef SYSTEMD_NETWORKD_DBUS
++int network_address_added_handler (sd_netlink* rtnl, sd_netlink_message* m, void* userdata);
++int network_set_gateway (Link* link);
++static int route_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata);
++#endif
++
+ static int network_load_one(Manager *manager, const char *filename) {
+         _cleanup_network_free_ Network *network = NULL;
+         _cleanup_fclose_ FILE *file = NULL;
+@@ -850,3 +858,76 @@ int config_parse_hostname(const char *unit,
+ 
+         return 0;
+ }
++
++#ifdef SYSTEMD_NETWORKD_DBUS
++int network_address_added_handler (sd_netlink* rtnl, sd_netlink_message* m, void* userdata)
++{
++        _cleanup_link_unref_ Link *link = userdata;
++        int r;
++
++        assert(link);
++
++        r = sd_netlink_message_get_errno(m);
++        if (r < 0 && r != -EEXIST) {
++                log_debug("Error in set IP address!");
++                link_enter_failed(link);
++        } else if (r >= 0)
++                link_rtnl_process_address(rtnl, m, link->manager);
++
++	network_set_gateway (link);
++
++	return 1;
++}
++
++/* link_enter_set_routes */
++int network_set_gateway (Link* link)
++{
++        Route *rt;
++        int r;
++
++        assert(link);
++        assert(link->network);
++        assert(link->state == LINK_STATE_SETTING_ADDRESSES);
++
++        link->state = LINK_STATE_SETTING_ROUTES;
++
++        LIST_FOREACH(routes, rt, link->network->static_routes) {
++                r = route_configure(rt, link, &route_handler);
++                if (r < 0) {
++                        log_debug ("Could not set Gateway!");
++                        link_enter_failed(link);
++                        return r;
++                }
++
++                link->link_messages ++;
++        }
++
++        if (link->link_messages == 0) {
++                link->static_configured = true;
++
++                /*link_enter_configured (link);*/
++                log_link_info(link, "Configured");
++                link->state = LINK_STATE_CONFIGURED;
++                link_save(link);
++        } else
++                log_debug("Setting Gateway");
++
++        return 0;
++}
++
++static int route_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
++        _cleanup_link_unref_ Link *link = userdata;
++        int r;
++
++        assert(link);
++
++        r = sd_netlink_message_get_errno(m);
++        if (r < 0 && r != -EEXIST) {
++                log_debug ("Could not set route! ");
++                link_enter_failed(link);
++        }
++
++        return 1;
++}
++
++#endif
+diff --git a/src/network/org.freedesktop.network1.conf b/src/network/org.freedesktop.network1.conf
+index 52dad33..f424b88 100644
+--- a/src/network/org.freedesktop.network1.conf
++++ b/src/network/org.freedesktop.network1.conf
+@@ -36,6 +36,23 @@
+                        send_interface="org.freedesktop.DBus.Properties"
+                        send_member="GetAll"/>
+ 
++                <allow send_destination="org.freedesktop.network1"
++                       send_interface="org.freedesktop.network1.Network"
++                       send_member="AddAddress"/>
++
++                <allow send_destination="org.freedesktop.network1"
++                       send_interface="org.freedesktop.network1.Network"
++                       send_member="DelAddress"/>
++
++                <allow send_destination="org.freedesktop.network1"
++                       send_interface="org.freedesktop.network1.Network"
++                       send_member="GetAddress"/>
++
++                <allow send_destination="org.freedesktop.network1"
++                       send_interface="org.freedesktop.network1.Link"
++                       send_member="GetAddress"/>
++
++
+                 <allow receive_sender="org.freedesktop.network1"/>
+         </policy>
+ 
+-- 
+1.8.2.2
+
diff --git a/yocto-poky/meta/recipes-core/systemd/systemd_225.bb b/yocto-poky/meta/recipes-core/systemd/systemd_225.bb
index f7d4c7d..e3d55ec 100644
--- a/yocto-poky/meta/recipes-core/systemd/systemd_225.bb
+++ b/yocto-poky/meta/recipes-core/systemd/systemd_225.bb
@@ -41,6 +41,7 @@ SRC_URI = "git://github.com/systemd/systemd.git;protocol=git \
            file://0012-implment-systemd-sysv-install-for-OE.patch \
            file://0014-Revert-rules-remove-firmware-loading-rules.patch \
            file://0015-Revert-udev-remove-userspace-firmware-loading-suppor.patch \
+           file://0100-systemd_networkd_dbus_setaddress.patch \
            file://touchscreen.rules \
            file://00-create-volatile.conf \
            file://init \
-- 
2.6.4

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH openbmc] Dbus API for systemd/networkd for network configuration.
  2016-01-20 15:10 ` OpenBMC Patches
@ 2016-01-21  5:23   ` Cyril Bur
  2016-01-21  7:06     ` Hariharasubramanian Ramasubramanian
  0 siblings, 1 reply; 4+ messages in thread
From: Cyril Bur @ 2016-01-21  5:23 UTC (permalink / raw)
  To: OpenBMC Patches; +Cc: openbmc

On Wed, 20 Jan 2016 09:10:22 -0600
OpenBMC Patches <openbmc-patches@stwcx.xyz> wrote:

> From: Hariharasubramanian R <hramasub@in.ibm.com>
> 

Hi Hariharasubramanian,

Just to be sure I've got this right, we're patching systemd now? Does systemd
not already do this? I thought the one good thing with systemd is that it
provides all this kind of stuff out of the box?

> ---
>  .../0100-systemd_networkd_dbus_setaddress.patch    | 845 +++++++++++++++++++++
>  .../meta/recipes-core/systemd/systemd_225.bb       |   1 +
>  2 files changed, 846 insertions(+)
>  create mode 100644 yocto-poky/meta/recipes-core/systemd/systemd/0100-systemd_networkd_dbus_setaddress.patch
> 
> diff --git a/yocto-poky/meta/recipes-core/systemd/systemd/0100-systemd_networkd_dbus_setaddress.patch b/yocto-poky/meta/recipes-core/systemd/systemd/0100-systemd_networkd_dbus_setaddress.patch
> new file mode 100644
> index 0000000..6727c1e
> --- /dev/null
> +++ b/yocto-poky/meta/recipes-core/systemd/systemd/0100-systemd_networkd_dbus_setaddress.patch
> @@ -0,0 +1,845 @@
> +From 35efeac7a1b1f6b737348f649d58d1c7eb5ecb8d Mon Sep 17 00:00:00 2001
> +From: Hariharasubramanian R <hramasub@in.ibm.com>
> +Date: Tue, 19 Jan 2016 05:04:40 -0600
> +Subject: [PATCH] Test
> +
> +---
> + src/network/networkd-link-bus.c           |  93 +++++
> + src/network/networkd-network-bus.c        | 556 ++++++++++++++++++++++++++++++
> + src/network/networkd-network.c            |  81 +++++
> + src/network/org.freedesktop.network1.conf |  17 +
> + 4 files changed, 747 insertions(+)
> +
> +diff --git a/src/network/networkd-link-bus.c b/src/network/networkd-link-bus.c
> +index 1a1524d..103d513 100644
> +--- a/src/network/networkd-link-bus.c
> ++++ b/src/network/networkd-link-bus.c
> +@@ -25,15 +25,41 @@
> + #include "networkd.h"
> + #include "networkd-link.h"
> + 
> ++#define SYSTEMD_NETWORKD_DBUS 1
> ++
> ++#ifdef SYSTEMD_NETWORKD_DBUS
> ++/*
> ++#include "hostname-util.h"
> ++#include "network-internal.h"
> ++#include "networkd-link.h"
> ++#include "bus-util.h"
> ++*/
> ++#include "sd-network.h"
> ++#include "sd-netlink.h"
> ++#include "socket-util.h"
> ++#include "ether-addr-util.h"
> ++/*
> ++#include "local-addresses.h"
> ++*/
> ++#endif
> ++
> + static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_operational_state, link_operstate, LinkOperationalState);
> + static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_administrative_state, link_state, LinkState);
> + 
> ++#ifdef SYSTEMD_NETWORKD_DBUS
> ++static int method_get_address (sd_bus_message *m, void* userdata, sd_bus_error *error);
> ++#endif
> ++
> + const sd_bus_vtable link_vtable[] = {
> +         SD_BUS_VTABLE_START(0),
> + 
> +         SD_BUS_PROPERTY("OperationalState", "s", property_get_operational_state, offsetof(Link, operstate), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
> +         SD_BUS_PROPERTY("AdministrativeState", "s", property_get_administrative_state, offsetof(Link, state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
> + 
> ++#ifdef SYSTEMD_NETWORKD_DBUS
> ++	    /* device name */
> ++    	SD_BUS_METHOD("GetAddress", "s", "s", method_get_address, SD_BUS_VTABLE_UNPRIVILEGED),
> ++#endif
> +         SD_BUS_VTABLE_END
> + };
> + 
> +@@ -136,3 +162,70 @@ int link_send_changed(Link *link, const char *property, ...) {
> +                         "org.freedesktop.network1.Link",
> +                         l);
> + }
> ++
> ++static int method_get_address (sd_bus_message *m, void* userdata, sd_bus_error *error)
> ++{
> ++    _cleanup_netlink_unref_ sd_netlink                  *rtnl   = NULL;
> ++    _cleanup_netlink_message_unref_ sd_netlink_message  *req    = NULL;
> ++    _cleanup_netlink_message_unref_ sd_netlink_message  *reply  = NULL;
> ++    _cleanup_bus_message_unref_ sd_bus_message          *resp   = NULL;
> ++    Manager                                             *mgr    = userdata;
> ++
> ++    struct udev*        udev               = NULL;
> ++    struct udev_device* udev_eth           = NULL;
> ++    const char*         device             = NULL;
> ++    char                devpath [32]       = "/sys/class/net/"; 
> ++
> ++    int                 r;
> ++    unsigned char       ifindex;
> ++    bool                have_mac;
> ++    struct ether_addr   e;
> ++    char                ea[ETHER_ADDR_TO_STRING_MAX];
> ++
> ++    assert(m);
> ++    assert(mgr);
> ++
> ++    r = sd_bus_message_read (m, "s", &device);
> ++    if (r < 0)
> ++        return r;
> ++
> ++    if (isempty (device))
> ++        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid Device Name.");
> ++
> ++    udev = udev_new();
> ++    udev_eth = udev_device_new_from_syspath(udev, strcat (devpath, device));
> ++    if (!udev_eth)
> ++        return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Could not find udev device");
> ++
> ++    ifindex = udev_device_get_ifindex(udev_eth);
> ++
> ++    r = sd_netlink_open(&rtnl);
> ++    if (r < 0)
> ++            return log_error_errno(r, "Failed to connect to netlink:"); /* fixme */
> ++
> ++    r = sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, ifindex);
> ++    if (r < 0)
> ++            return r;
> ++
> ++    r = sd_netlink_call(rtnl, req, 0, &reply); /* fixme */
> ++    if (r < 0)
> ++            return r;
> ++
> ++    have_mac = sd_netlink_message_read_ether_addr(reply, IFLA_ADDRESS, &e) >= 0;
> ++    if (!have_mac)
> ++        return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Error reading IFLA address");
> ++
> ++    ether_addr_to_string(&e, ea);
> ++
> ++    r = sd_bus_message_new_method_return(m, &resp);
> ++    if (r < 0)
> ++        return sd_bus_error_setf(error, SD_BUS_ERROR_NO_MEMORY, "Error allocating reply messgage");
> ++
> ++    r = sd_bus_message_append(resp, "s", ea);
> ++    if (r < 0)
> ++        return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Error appending to reply messgage");
> ++
> ++    r = sd_bus_send(mgr->bus, resp, NULL);
> ++
> ++    return sd_bus_reply_method_return(m, "s", "Getting IFLA address ...");
> ++}
> +diff --git a/src/network/networkd-network-bus.c b/src/network/networkd-network-bus.c
> +index 5717a15..6f0d1e5 100644
> +--- a/src/network/networkd-network-bus.c
> ++++ b/src/network/networkd-network-bus.c
> +@@ -19,10 +19,34 @@
> +   along with systemd; If not, see <http://www.gnu.org/licenses/>.
> + ***/
> + 
> ++#define SYSTEMD_NETWORKD_DBUS 1
> ++
> ++#ifdef SYSTEMD_NETWORKD_DBUS
> ++#include <netinet/ether.h>
> ++#include <linux/if.h>
> ++#endif
> ++
> + #include "strv.h"
> + 
> + #include "networkd.h"
> + 
> ++#ifdef SYSTEMD_NETWORKD_DBUS
> ++#include "hostname-util.h"
> ++#include "network-internal.h"
> ++#include "networkd-link.h"
> ++#include "bus-util.h"
> ++
> ++#include "sd-network.h"
> ++#include "sd-netlink.h"
> ++#include "local-addresses.h"
> ++#endif
> ++
> ++#ifdef SYSTEMD_NETWORKD_DBUS
> ++int network_address_added_handler (sd_netlink* rtnl, sd_netlink_message* m, void* userdata);
> ++int network_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message, void *userdata, Address* address); /* fixme */
> ++static int method_get_address (sd_bus_message *m, void* userdata, sd_bus_error *error); /* fixme */
> ++#endif
> ++
> + static int property_get_ether_addrs(
> +                 sd_bus *bus,
> +                 const char *path,
> +@@ -56,6 +80,11 @@ static int property_get_ether_addrs(
> +         return sd_bus_message_close_container(reply);
> + }
> + 
> ++#ifdef SYSTEMD_NETWORKD_DBUS
> ++static int method_add_address (sd_bus_message *m, void* userdata, sd_bus_error *error);
> ++static int method_del_address (sd_bus_message *m, void* userdata, sd_bus_error *error);
> ++#endif
> ++
> + const sd_bus_vtable network_vtable[] = {
> +         SD_BUS_VTABLE_START(0),
> + 
> +@@ -67,6 +96,13 @@ const sd_bus_vtable network_vtable[] = {
> +         SD_BUS_PROPERTY("MatchType", "as", NULL, offsetof(Network, match_type), SD_BUS_VTABLE_PROPERTY_CONST),
> +         SD_BUS_PROPERTY("MatchName", "as", NULL, offsetof(Network, match_name), SD_BUS_VTABLE_PROPERTY_CONST),
> + 
> ++#ifdef SYSTEMD_NETWORKD_DBUS
> ++	    /* device, IP, netmask, family, flags, scope, gateway */
> ++    	SD_BUS_METHOD("AddAddress", "sssyyys", "x", method_add_address, SD_BUS_VTABLE_UNPRIVILEGED),
> ++    	SD_BUS_METHOD("DelAddress", "sssyyys", "x", method_del_address, SD_BUS_VTABLE_UNPRIVILEGED),
> ++	    /* (family, prefixlen, flags, scope, IP)+ gateway */
> ++    	SD_BUS_METHOD("GetAddress", "s", "a(iyyus)s", method_get_address, SD_BUS_VTABLE_UNPRIVILEGED),
> ++#endif
> +         SD_BUS_VTABLE_END
> + };
> + 
> +@@ -152,3 +188,523 @@ int network_object_find(sd_bus *bus, const char *path, const char *interface, vo
> + 
> +         return 1;
> + }
> ++
> ++#ifdef SYSTEMD_NETWORKD_DBUS
> ++
> ++static int method_add_address (sd_bus_message *m, void* userdata, sd_bus_error *error)
> ++{
> ++    _cleanup_bus_message_unref_ sd_bus_message*         resp    = NULL;
> ++    _cleanup_netlink_unref_ sd_netlink*                 rtnl    = NULL;
> ++    _cleanup_netlink_message_unref_ sd_netlink_message* req     = NULL;
> ++    _cleanup_netlink_message_unref_ sd_netlink_message* reply   = NULL;
> ++    _cleanup_address_free_ Address *addr                        = NULL;
> ++    _cleanup_route_free_ Route *rt                              = NULL;
> ++    Manager *mgr                                                = userdata;
> ++    Link*               link               = NULL;
> ++    struct udev*        udev               = NULL;
> ++    struct udev_device* udev_eth           = NULL;
> ++
> ++    const char*         device             = NULL;
> ++    const char*         ipaddr             = NULL;
> ++    const char*         netmask            = NULL;
> ++    const char*         gateway            = NULL;
> ++    char                devpath [32]       = "/sys/class/net/"; 
> ++
> ++    unsigned char       family;
> ++    unsigned char       prefixlen;
> ++    unsigned char       flags;
> ++    unsigned char       scope;
> ++    unsigned char       ifindex;
> ++
> ++    struct in_addr      nm;
> ++    struct in_addr      ip;
> ++    struct in_addr      gw;
> ++    int r;
> ++
> ++    assert(m);
> ++    assert(mgr);
> ++
> ++    r = sd_bus_message_read (m, "sssyyys", &device, &ipaddr, &netmask, &family, &flags, &scope, &gateway);
> ++    if (r < 0)
> ++        return r;
> ++
> ++    if (isempty (device))
> ++        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid Device Name.");
> ++
> ++    if (isempty (ipaddr))
> ++        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid IP Address.");
> ++
> ++    if (isempty (netmask))
> ++        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid IP Netmask.");
> ++
> ++    assert(family == AF_INET || family == AF_INET6);
> ++
> ++    udev = udev_new();
> ++    udev_eth = udev_device_new_from_syspath(udev, strcat (devpath, device));
> ++    if (!udev_eth)
> ++            return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Could not find udev device");
> ++
> ++    ifindex = udev_device_get_ifindex(udev_eth);
> ++
> ++    inet_aton (netmask, &nm);
> ++    inet_aton (ipaddr, &ip);
> ++    if (!isempty (gateway)) inet_aton (gateway, &gw);
> ++
> ++    prefixlen = in_addr_netmask_to_prefixlen(&nm);
> ++    assert(prefixlen > 0);
> ++
> ++    r = address_new_dynamic(&addr);
> ++    if (r < 0)
> ++        return sd_bus_error_setf(error, SD_BUS_ERROR_NO_MEMORY, "Error allocating new address");
> ++
> ++    r = sd_netlink_open(&rtnl);
> ++    if (r < 0)
> ++            return sd_bus_error_setf(error, SD_BUS_ERROR_IO_ERROR, "Failed to connect to netlink");
> ++
> ++    link = new0(Link, 1);
> ++    if (!link)
> ++            return -ENOMEM;
> ++
> ++    link->network = new0(Network, 1);
> ++    if (!link->network)
> ++            return sd_bus_error_setf(error, SD_BUS_ERROR_NO_MEMORY, "Could not alloc memory for Network");
> ++
> ++    link->n_ref                 = 1;
> ++    link->manager               = mgr;
> ++    link->manager->rtnl         = rtnl;
> ++    link->state                 = LINK_STATE_PENDING;
> ++    link->rtnl_extended_attrs   = true;
> ++    link->ifindex               = ifindex;
> ++    link->ifname                = strdup(device); /*FIXME:*/
> ++    if (!link->ifname)
> ++            return -ENOMEM;
> ++
> ++    addr->family                = family;
> ++    addr->in_addr.in.s_addr     = ip.s_addr;
> ++    addr->prefixlen             = prefixlen;
> ++    addr->broadcast.s_addr      = ip.s_addr | ~nm.s_addr;
> ++
> ++    if (!isempty (gateway))
> ++    {
> ++        r = route_new_dynamic(&rt, RTPROT_STATIC);
> ++        if (r < 0)
> ++            return r;
> ++
> ++        rt->protocol        = RTPROT_STATIC;
> ++        rt->network         = link->network;
> ++        rt->family          = family;
> ++        rt->scope           = RT_SCOPE_LINK;            /* FIXME: */
> ++        rt->dst_prefixlen   = 32;                       /* FIXME: AF_INET assumed */
> ++        rt->dst_addr.in     = gw;
> ++
> ++        LIST_PREPEND(routes, link->network->static_routes, rt);
> ++    }
> ++
> ++    /* send an nlmsg (RTM_NEWADDR) and append address to link address list */
> ++    r = address_update (addr, link, network_address_added_handler);
> ++    if (r < 0)
> ++        return r;
> ++
> ++    r = sd_bus_message_new_method_return(m, &resp);
> ++    if (r < 0)
> ++        return sd_bus_error_setf(error, SD_BUS_ERROR_NO_MEMORY, "Error allocating reply messgage");
> ++
> ++    r = sd_bus_message_append(resp, "x", 0);
> ++    if (r < 0)
> ++            return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Error appending to reply messgage");
> ++
> ++    r = sd_bus_send(mgr->bus, resp, NULL);
> ++    if (r < 0)
> ++            return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Error sending reply messgage");
> ++
> ++    return sd_bus_reply_method_return(m, "s", "Adding IP address...");
> ++}
> ++
> ++static int method_del_address (sd_bus_message *m, void* userdata, sd_bus_error *error)
> ++{
> ++    _cleanup_bus_message_unref_ sd_bus_message*         resp    = NULL;
> ++    _cleanup_netlink_unref_ sd_netlink*                 rtnl    = NULL;
> ++    _cleanup_netlink_message_unref_ sd_netlink_message* req     = NULL;
> ++    _cleanup_netlink_message_unref_ sd_netlink_message* reply   = NULL;
> ++    _cleanup_address_free_ Address *addr                        = NULL;
> ++    _cleanup_route_free_ Route *rt                              = NULL;
> ++    Manager *mgr                                                = userdata;
> ++    Link*               link               = NULL;
> ++    struct udev*        udev               = NULL;
> ++    struct udev_device* udev_eth           = NULL;
> ++
> ++    const char*         device             = NULL;
> ++    const char*         ipaddr             = NULL;
> ++    const char*         netmask            = NULL;
> ++    const char*         gateway            = NULL;
> ++    char                devpath [32]       = "/sys/class/net/"; 
> ++
> ++    unsigned char       family;
> ++    unsigned char       prefixlen;
> ++    unsigned char       flags;
> ++    unsigned char       scope;
> ++    unsigned char       ifindex;
> ++
> ++    struct in_addr      nm;
> ++    struct in_addr      ip;
> ++    struct in_addr      gw;
> ++    int r;
> ++
> ++    assert(m);
> ++    assert(mgr);
> ++
> ++    r = sd_bus_message_read (m, "sssyyys", &device, &ipaddr, &netmask, &family, &flags, &scope, &gateway);
> ++    if (r < 0)
> ++        return r;
> ++
> ++    if (isempty (device))
> ++        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid Device Name.");
> ++
> ++    if (isempty (ipaddr))
> ++        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid IP Address.");
> ++
> ++    if (isempty (netmask))
> ++        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid IP Netmask.");
> ++
> ++    assert(family == AF_INET || family == AF_INET6);
> ++
> ++    udev = udev_new();
> ++    udev_eth = udev_device_new_from_syspath(udev, strcat (devpath, device));
> ++    if (!udev_eth)
> ++            return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Could not find udev device");
> ++
> ++    ifindex = udev_device_get_ifindex(udev_eth);
> ++
> ++    inet_aton (netmask, &nm);
> ++    inet_aton (ipaddr, &ip);
> ++    if (!isempty (gateway)) inet_aton (gateway, &gw);
> ++
> ++    prefixlen = in_addr_netmask_to_prefixlen(&nm);
> ++    assert(prefixlen > 0);
> ++
> ++    r = address_new_dynamic(&addr);
> ++    if (r < 0)
> ++        return sd_bus_error_setf(error, SD_BUS_ERROR_NO_MEMORY, "Error allocating new address");
> ++
> ++    r = sd_netlink_open(&rtnl);
> ++    if (r < 0)
> ++            return sd_bus_error_setf(error, SD_BUS_ERROR_IO_ERROR, "Failed to connect to netlink");
> ++
> ++    link = new0(Link, 1);
> ++    if (!link)
> ++            return -ENOMEM;
> ++
> ++    link->network = new0(Network, 1);
> ++    if (!link->network)
> ++            return sd_bus_error_setf(error, SD_BUS_ERROR_NO_MEMORY, "Could not alloc memory for Network");
> ++
> ++    link->n_ref                 = 1;
> ++    link->manager               = mgr;
> ++    link->manager->rtnl         = rtnl;
> ++    link->state                 = LINK_STATE_PENDING;
> ++    link->rtnl_extended_attrs   = true;
> ++    link->ifindex               = ifindex;
> ++    link->ifname                = strdup(device);
> ++    if (!link->ifname)
> ++            return -ENOMEM;
> ++
> ++    addr->family                = family;
> ++    addr->in_addr.in.s_addr     = ip.s_addr;
> ++    addr->prefixlen             = prefixlen;
> ++    addr->broadcast.s_addr      = ip.s_addr | ~nm.s_addr;
> ++
> ++    if (!isempty (gateway))
> ++    {
> ++        r = route_new_dynamic(&rt, RTPROT_STATIC);
> ++        if (r < 0)
> ++            return r;
> ++
> ++        rt->network         = link->network;
> ++        rt->family          = family;
> ++        rt->scope           = RT_SCOPE_LINK;            /* FIXME: */
> ++        rt->dst_prefixlen   = 32;                       /* FIXME: AF_INET assumed */
> ++        rt->dst_addr.in     = gw;
> ++
> ++        /*LIST_PREPEND(routes, link->network->static_routes, rt);*/
> ++        /* Drop the Gateway */
> ++        route_drop (rt, link, link_route_drop_handler);
> ++    }
> ++
> ++    /* send an nlmsg to delete address from address list */
> ++    r = address_drop(addr, link, link_address_drop_handler);
> ++    if (r < 0)
> ++        return r;
> ++
> ++    r = sd_bus_message_new_method_return(m, &resp);
> ++    if (r < 0)
> ++        return sd_bus_error_setf(error, SD_BUS_ERROR_NO_MEMORY, "Error allocating reply messgage");
> ++
> ++    r = sd_bus_message_append(resp, "x", 0);
> ++    if (r < 0)
> ++            return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Error appending to reply messgage");
> ++
> ++    r = sd_bus_send(mgr->bus, resp, NULL);
> ++    if (r < 0)
> ++            return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Error sending reply messgage");
> ++
> ++    return sd_bus_reply_method_return(m, "s", "Deleted IP address...");
> ++}
> ++
> ++static int method_get_address (sd_bus_message *m, void* userdata, sd_bus_error *error)
> ++{
> ++    _cleanup_netlink_unref_ sd_netlink  *rtnl   = NULL;
> ++    _cleanup_address_free_ Address      *addr   = NULL;
> ++    _cleanup_route_free_ Route          *rt     = NULL;
> ++    Manager                             *mgr    = userdata;
> ++#if 0 /* fixme: */
> ++    Link*               link               = NULL;
> ++#endif
> ++    struct udev*        udev               = NULL;
> ++    struct udev_device* udev_eth           = NULL;
> ++
> ++    const char*         device             = NULL;
> ++#if 0 /* fixme: */
> ++    const char*         ipaddr             = NULL;
> ++    const char*         netmask            = NULL;
> ++    const char*         gateway            = NULL;
> ++#endif
> ++    char                devpath [32]       = "/sys/class/net/"; 
> ++
> ++#if 0 /* fixme: */
> ++    unsigned char       family;
> ++    unsigned char       prefixlen;
> ++    unsigned char       flags;
> ++    unsigned char       scope;
> ++#endif
> ++    unsigned char       ifindex;
> ++
> ++#if 0 /* fixme: */
> ++    struct in_addr      nm;
> ++    struct in_addr      ip;
> ++    struct in_addr      gw;
> ++#endif
> ++    int                 r;
> ++
> ++    sd_netlink_message* maddr;
> ++
> ++    _cleanup_netlink_message_unref_ sd_netlink_message  *req    = NULL;
> ++    _cleanup_netlink_message_unref_ sd_netlink_message  *reply    = NULL;
> ++    _cleanup_bus_message_unref_ sd_bus_message  *resp   = NULL;
> ++    _cleanup_address_free_ Address              *address = NULL;
> ++    _cleanup_free_ struct local_address         *local   = NULL;
> ++    _cleanup_free_ char                         *ipr     = NULL;
> ++    _cleanup_free_ char                         *gwr     = NULL;
> ++    int                 n;
> ++    int                 i;
> ++
> ++    assert(m);
> ++    assert(mgr);
> ++
> ++    r = sd_bus_message_read (m, "s", &device);
> ++    if (r < 0)
> ++        return r;
> ++
> ++    if (isempty (device))
> ++        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid Device Name.");
> ++
> ++    udev = udev_new();
> ++    udev_eth = udev_device_new_from_syspath(udev, strcat (devpath, device));
> ++    if (!udev_eth)
> ++        return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Could not find udev device");
> ++
> ++    ifindex = udev_device_get_ifindex(udev_eth);
> ++
> ++    r = sd_netlink_open(&rtnl);
> ++    if (r < 0)
> ++            return log_error_errno(r, "Failed to connect to netlink:"); /* fixme */
> ++
> ++    r = sd_rtnl_message_new_addr(rtnl, &req, RTM_GETADDR, 0, 0);
> ++    if (r < 0)
> ++            return r;
> ++
> ++    r = sd_netlink_message_request_dump(req, true);
> ++    if (r < 0)
> ++            return r;
> ++
> ++    r = sd_netlink_call(rtnl, req, 0, &reply); /* fixme */
> ++    if (r < 0)
> ++            return r;
> ++
> ++    r = sd_bus_message_new_method_return(m, &resp);
> ++    if (r < 0)
> ++        return sd_bus_error_setf(error, SD_BUS_ERROR_NO_MEMORY, "Error allocating reply messgage");
> ++
> ++    r = sd_bus_message_open_container(resp, 'a', "iyyus"); /*family,prefixlen,scope,flags,addr*/
> ++    if (r < 0)
> ++        return sd_bus_error_setf(error, SD_BUS_ERROR_NO_MEMORY, "Error opening a container for reply message");
> ++
> ++    for (maddr = reply; maddr; maddr = sd_netlink_message_next(maddr)) {
> ++            int k;
> ++
> ++            r = address_new_dynamic(&address);
> ++            if (r < 0)
> ++                    return r;
> ++
> ++            k = network_rtnl_process_address(rtnl, maddr, mgr, address);
> ++            if (k) {
> ++                r = sd_bus_message_append(resp, "i", address->family);
> ++                if (r < 0)
> ++                        return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Error appending to reply messgage");
> ++
> ++                r = sd_bus_message_append(resp, "y", address->prefixlen);
> ++                if (r < 0)
> ++                        return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Error appending to reply messgage");
> ++
> ++                r = sd_bus_message_append(resp, "y", address->scope);
> ++                if (r < 0)
> ++                        return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Error appending to reply messgage");
> ++
> ++                r = sd_bus_message_append(resp, "u", address->flags);
> ++                if (r < 0)
> ++                        return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Error appending to reply messgage");
> ++
> ++                r = in_addr_to_string(address->family, &address->in_addr, &ipr); /* fixme */
> ++                if (r < 0)
> ++                        return r;
> ++
> ++                r = sd_bus_message_append(resp, "s", ipr);
> ++                if (r < 0)
> ++                        return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Error appending to reply messgage");
> ++            }
> ++    }
> ++
> ++    r = sd_bus_message_close_container(resp);
> ++    if (r < 0)
> ++            return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Error closing reply container");
> ++
> ++    n = local_gateways(rtnl, ifindex, AF_UNSPEC, &local);
> ++    if (n < 0)
> ++            return n;
> ++
> ++    for (i = 0; i < n; i++) {
> ++
> ++            r = in_addr_to_string(local[i].family, &local[i].address, &gwr);
> ++            if (r < 0)
> ++                    return r;
> ++    }
> ++
> ++    r = sd_bus_message_append(resp, "s", gwr);
> ++    if (r < 0)
> ++            return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Error appending to reply messgage");
> ++
> ++    r = sd_bus_send(mgr->bus, resp, NULL);
> ++    if (r < 0)
> ++            return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Error sending reply messgage");
> ++
> ++    return sd_bus_reply_method_return(m, "s", "Getting IP configuration...");
> ++}
> ++
> ++
> ++int network_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message, void *userdata, Address* address) {
> ++        Manager*        m       = (Manager*) userdata; /* fixme */
> ++#if 0 /* fixme */
> ++        Link*           link    = NULL;
> ++#endif
> ++        uint16_t        type;
> ++        unsigned char   flags;
> ++#if 0 /* fixme */
> ++        Address*        existing;
> ++#endif
> ++        char            buf[INET6_ADDRSTRLEN]; 
> ++#if 0 /* fixme */
> ++        char            valid_buf[FORMAT_TIMESPAN_MAX];
> ++        const char*     valid_str = NULL;
> ++#endif
> ++        int             ifindex;
> ++        int             r; 
> ++        /*_cleanup_address_free_ Address *address = NULL;*/
> ++        sd_bus_error err    = SD_BUS_ERROR_NULL; /* fixme */
> ++        sd_bus_error* error = &err;             /* fixme */
> ++
> ++        assert(rtnl);
> ++        assert(message);
> ++        assert(m);
> ++        assert(address);
> ++
> ++        if (sd_netlink_message_is_error(message)) {
> ++                r = sd_netlink_message_get_errno(message);
> ++                if (r < 0)
> ++                        sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "rtnl: failed to receive address: ");
> ++
> ++                return 0;
> ++        }
> ++
> ++        r = sd_netlink_message_get_type(message, &type);
> ++        if (r < 0) {
> ++                sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "rtnl: could not get message type: ");
> ++                return 0;
> ++        } else if (type != RTM_NEWADDR && type != RTM_DELADDR) {
> ++                sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "rtnl: received unexpected message type when processing address");
> ++                return 0;
> ++        }
> ++
> ++        r = sd_rtnl_message_addr_get_ifindex(message, &ifindex);
> ++        if (r < 0) {
> ++                sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "rtnl: could not get ifindex from address: %m");
> ++                return 0;
> ++        } else if (ifindex <= 0) {
> ++                sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "rtnl: received address message with invalid ifindex: %d", ifindex);
> ++                return 0;
> ++        } 
> ++
> ++        r = sd_rtnl_message_addr_get_family(message, &address->family); /* int : i*/
> ++        if (r < 0 || !IN_SET(address->family, AF_INET, AF_INET6)) {
> ++                sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "rtnl: received address with invalid family, ignoring.");
> ++                return 0;
> ++        }
> ++
> ++        r = sd_rtnl_message_addr_get_prefixlen(message, &address->prefixlen); /* uchar : byte : y */
> ++        if (r < 0) {
> ++                sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "rtnl: received address with invalid prefixlen, ignoring: ");
> ++                return 0;
> ++        }
> ++
> ++        r = sd_rtnl_message_addr_get_scope(message, &address->scope); /* uchar : byte : y*/
> ++        if (r < 0) {
> ++                sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "rtnl: received address with invalid scope, ignoring: ");
> ++                return 0;
> ++        }
> ++
> ++        r = sd_rtnl_message_addr_get_flags(message, &flags); /* uint32 : u*/
> ++        if (r < 0) {
> ++                sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "rtnl: received address with invalid flags, ignoring: ");
> ++                return 0;
> ++        }
> ++        address->flags = flags;
> ++
> ++        switch (address->family) {
> ++        case AF_INET:
> ++                r = sd_netlink_message_read_in_addr(message, IFA_LOCAL, &address->in_addr.in); /* ulong : uint64 : t */
> ++                if (r < 0) {
> ++                        sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "rtnl: received address without valid address, ignoring: ");
> ++                        return 0;
> ++                }
> ++
> ++                break;
> ++
> ++        case AF_INET6:
> ++                r = sd_netlink_message_read_in6_addr(message, IFA_ADDRESS, &address->in_addr.in6); /* ulong : uint64 : t */
> ++                if (r < 0) {
> ++                        sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "rtnl: received address without valid address, ignoring: ");
> ++                        return 0;
> ++                }
> ++
> ++                break;
> ++
> ++        default:
> ++                assert_not_reached("invalid address family");
> ++        }
> ++
> ++        if (!inet_ntop(address->family, &address->in_addr, buf, INET6_ADDRSTRLEN)) { /* string : s */
> ++                sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Could not print address");
> ++                return 0;
> ++        }
> ++
> ++        return 1;
> ++}
> ++#endif
> +diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
> +index 6587ea9..2616c5b 100644
> +--- a/src/network/networkd-network.c
> ++++ b/src/network/networkd-network.c
> +@@ -32,6 +32,14 @@
> + #include "network-internal.h"
> + #include "dns-domain.h"
> + 
> ++#define SYSTEMD_NETWORKD_DBUS 1
> ++
> ++#ifdef SYSTEMD_NETWORKD_DBUS
> ++int network_address_added_handler (sd_netlink* rtnl, sd_netlink_message* m, void* userdata);
> ++int network_set_gateway (Link* link);
> ++static int route_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata);
> ++#endif
> ++
> + static int network_load_one(Manager *manager, const char *filename) {
> +         _cleanup_network_free_ Network *network = NULL;
> +         _cleanup_fclose_ FILE *file = NULL;
> +@@ -850,3 +858,76 @@ int config_parse_hostname(const char *unit,
> + 
> +         return 0;
> + }
> ++
> ++#ifdef SYSTEMD_NETWORKD_DBUS
> ++int network_address_added_handler (sd_netlink* rtnl, sd_netlink_message* m, void* userdata)
> ++{
> ++        _cleanup_link_unref_ Link *link = userdata;
> ++        int r;
> ++
> ++        assert(link);
> ++
> ++        r = sd_netlink_message_get_errno(m);
> ++        if (r < 0 && r != -EEXIST) {
> ++                log_debug("Error in set IP address!");
> ++                link_enter_failed(link);
> ++        } else if (r >= 0)
> ++                link_rtnl_process_address(rtnl, m, link->manager);
> ++
> ++	network_set_gateway (link);
> ++
> ++	return 1;
> ++}
> ++
> ++/* link_enter_set_routes */
> ++int network_set_gateway (Link* link)
> ++{
> ++        Route *rt;
> ++        int r;
> ++
> ++        assert(link);
> ++        assert(link->network);
> ++        assert(link->state == LINK_STATE_SETTING_ADDRESSES);
> ++
> ++        link->state = LINK_STATE_SETTING_ROUTES;
> ++
> ++        LIST_FOREACH(routes, rt, link->network->static_routes) {
> ++                r = route_configure(rt, link, &route_handler);
> ++                if (r < 0) {
> ++                        log_debug ("Could not set Gateway!");
> ++                        link_enter_failed(link);
> ++                        return r;
> ++                }
> ++
> ++                link->link_messages ++;
> ++        }
> ++
> ++        if (link->link_messages == 0) {
> ++                link->static_configured = true;
> ++
> ++                /*link_enter_configured (link);*/
> ++                log_link_info(link, "Configured");
> ++                link->state = LINK_STATE_CONFIGURED;
> ++                link_save(link);
> ++        } else
> ++                log_debug("Setting Gateway");
> ++
> ++        return 0;
> ++}
> ++
> ++static int route_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
> ++        _cleanup_link_unref_ Link *link = userdata;
> ++        int r;
> ++
> ++        assert(link);
> ++
> ++        r = sd_netlink_message_get_errno(m);
> ++        if (r < 0 && r != -EEXIST) {
> ++                log_debug ("Could not set route! ");
> ++                link_enter_failed(link);
> ++        }
> ++
> ++        return 1;
> ++}
> ++
> ++#endif
> +diff --git a/src/network/org.freedesktop.network1.conf b/src/network/org.freedesktop.network1.conf
> +index 52dad33..f424b88 100644
> +--- a/src/network/org.freedesktop.network1.conf
> ++++ b/src/network/org.freedesktop.network1.conf
> +@@ -36,6 +36,23 @@
> +                        send_interface="org.freedesktop.DBus.Properties"
> +                        send_member="GetAll"/>
> + 
> ++                <allow send_destination="org.freedesktop.network1"
> ++                       send_interface="org.freedesktop.network1.Network"
> ++                       send_member="AddAddress"/>
> ++
> ++                <allow send_destination="org.freedesktop.network1"
> ++                       send_interface="org.freedesktop.network1.Network"
> ++                       send_member="DelAddress"/>
> ++
> ++                <allow send_destination="org.freedesktop.network1"
> ++                       send_interface="org.freedesktop.network1.Network"
> ++                       send_member="GetAddress"/>
> ++
> ++                <allow send_destination="org.freedesktop.network1"
> ++                       send_interface="org.freedesktop.network1.Link"
> ++                       send_member="GetAddress"/>
> ++
> ++
> +                 <allow receive_sender="org.freedesktop.network1"/>
> +         </policy>
> + 
> +-- 
> +1.8.2.2
> +
> diff --git a/yocto-poky/meta/recipes-core/systemd/systemd_225.bb b/yocto-poky/meta/recipes-core/systemd/systemd_225.bb
> index f7d4c7d..e3d55ec 100644
> --- a/yocto-poky/meta/recipes-core/systemd/systemd_225.bb
> +++ b/yocto-poky/meta/recipes-core/systemd/systemd_225.bb
> @@ -41,6 +41,7 @@ SRC_URI = "git://github.com/systemd/systemd.git;protocol=git \
>             file://0012-implment-systemd-sysv-install-for-OE.patch \
>             file://0014-Revert-rules-remove-firmware-loading-rules.patch \
>             file://0015-Revert-udev-remove-userspace-firmware-loading-suppor.patch \
> +           file://0100-systemd_networkd_dbus_setaddress.patch \
>             file://touchscreen.rules \
>             file://00-create-volatile.conf \
>             file://init \

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH openbmc] Dbus API for systemd/networkd for network configuration.
  2016-01-21  5:23   ` Cyril Bur
@ 2016-01-21  7:06     ` Hariharasubramanian Ramasubramanian
  0 siblings, 0 replies; 4+ messages in thread
From: Hariharasubramanian Ramasubramanian @ 2016-01-21  7:06 UTC (permalink / raw)
  To: Cyril Bur; +Cc: OpenBMC Patches, openbmc


[-- Attachment #1.1: Type: text/plain, Size: 40446 bytes --]


Hi Cyril,

systemted-networkd did *not* support *dbus-api* to configure the network
interface. The way to configure network with networkd would be to edit a
corresponding *.link/*.network/*.service files.

This patch adds the dbus-api. If you introspected
the /org/freedesktop/network1/network/default object of the
org.freedesktop.network1 application, you would get the following. The
AddAddress, DelAddress and GetAddress are the new dbus methods enabled by
this patch.

--------
method return sender=:1.2 -> dest=:1.24 reply_serial=2
   string "<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object
Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
 <interface name="org.freedesktop.DBus.Peer">
  <method name="Ping"/>
  <method name="GetMachineId">
   <arg type="s" name="machine_uuid" direction="out"/>
  </method>
 </interface>
 <interface name="org.freedesktop.DBus.Introspectable">
  <method name="Introspect">
   <arg name="data" type="s" direction="out"/>
  </method>
 </interface>
 <interface name="org.freedesktop.DBus.Properties">
  <method name="Get">
   <arg name="interface" direction="in" type="s"/>
   <arg name="property" direction="in" type="s"/>
   <arg name="value" direction="out" type="v"/>
  </method>
  <method name="GetAll">
   <arg name="interface" direction="in" type="s"/>
   <arg name="properties" direction="out" type="a{sv}"/>
  </method>
  <method name="Set">
   <arg name="interface" direction="in" type="s"/>
   <arg name="property" direction="in" type="s"/>
   <arg name="value" direction="in" type="v"/>
  </method>
  <signal name="PropertiesChanged">
   <arg type="s" name="interface"/>
   <arg type="a{sv}" name="changed_properties"/>
   <arg type="as" name="invalidated_properties"/>
  </signal>
 </interface>
 <interface name="org.freedesktop.network1.Network">
  <property name="Description" type="s" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal"
value="const"/>
  </property>
  <property name="SourcePath" type="s" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal"
value="const"/>
  </property>
  <property name="MatchMAC" type="as" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal"
value="const"/>
  </property>
  <property name="MatchPath" type="as" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal"
value="const"/>
  </property>
  <property name="MatchDriver" type="as" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal"
value="const"/>
  </property>
  <property name="MatchType" type="as" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal"
value="const"/>
  </property>
  <property name="MatchName" type="as" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal"
value="const"/>
  </property>
  <method name="AddAddress">
   <arg type="s" direction="in"/>
   <arg type="s" direction="in"/>
   <arg type="s" direction="in"/>
   <arg type="y" direction="in"/>
   <arg type="y" direction="in"/>
   <arg type="y" direction="in"/>
   <arg type="s" direction="in"/>
   <arg type="x" direction="out"/>
  </method>
  <method name="DelAddress">
   <arg type="s" direction="in"/>
   <arg type="s" direction="in"/>
   <arg type="s" direction="in"/>
   <arg type="y" direction="in"/>
   <arg type="y" direction="in"/>
   <arg type="y" direction="in"/>
   <arg type="s" direction="in"/>
   <arg type="x" direction="out"/>
  </method>
  <method name="GetAddress">
   <arg type="s" direction="in"/>
   <arg type="a(iyyus)" direction="out"/>
   <arg type="s" direction="out"/>
  </method>
 </interface>
</node>
"
--------

regards,
rhari !

Hariharasubramanian R.
Power Firmware Development
IBM India Systems & Technology Lab, Bangalore, India
Phone:  +91 80 4025 6950



From:	Cyril Bur <cyrilbur@gmail.com>
To:	OpenBMC Patches <openbmc-patches@stwcx.xyz>
Cc:	openbmc@lists.ozlabs.org
Date:	01/21/2016 10:53 AM
Subject:	Re: [PATCH openbmc] Dbus API for systemd/networkd for network
            configuration.
Sent by:	"openbmc" <openbmc-bounces
            +hramasub=in.ibm.com@lists.ozlabs.org>



On Wed, 20 Jan 2016 09:10:22 -0600
OpenBMC Patches <openbmc-patches@stwcx.xyz> wrote:

> From: Hariharasubramanian R <hramasub@in.ibm.com>
>

Hi Hariharasubramanian,

Just to be sure I've got this right, we're patching systemd now? Does
systemd
not already do this? I thought the one good thing with systemd is that it
provides all this kind of stuff out of the box?

> ---
>  .../0100-systemd_networkd_dbus_setaddress.patch    | 845 +++++++++++++++
++++++
>  .../meta/recipes-core/systemd/systemd_225.bb       |   1 +
>  2 files changed, 846 insertions(+)
>  create mode 100644
yocto-poky/meta/recipes-core/systemd/systemd/0100-systemd_networkd_dbus_setaddress.patch

>
> diff --git
a/yocto-poky/meta/recipes-core/systemd/systemd/0100-systemd_networkd_dbus_setaddress.patch

b/yocto-poky/meta/recipes-core/systemd/systemd/0100-systemd_networkd_dbus_setaddress.patch

> new file mode 100644
> index 0000000..6727c1e
> --- /dev/null
> +++
b/yocto-poky/meta/recipes-core/systemd/systemd/0100-systemd_networkd_dbus_setaddress.patch

> @@ -0,0 +1,845 @@
> +From 35efeac7a1b1f6b737348f649d58d1c7eb5ecb8d Mon Sep 17 00:00:00 2001
> +From: Hariharasubramanian R <hramasub@in.ibm.com>
> +Date: Tue, 19 Jan 2016 05:04:40 -0600
> +Subject: [PATCH] Test
> +
> +---
> + src/network/networkd-link-bus.c           |  93 +++++
> + src/network/networkd-network-bus.c        | 556 +++++++++++++++++++++++
+++++++
> + src/network/networkd-network.c            |  81 +++++
> + src/network/org.freedesktop.network1.conf |  17 +
> + 4 files changed, 747 insertions(+)
> +
> +diff --git a/src/network/networkd-link-bus.c
b/src/network/networkd-link-bus.c
> +index 1a1524d..103d513 100644
> +--- a/src/network/networkd-link-bus.c
> ++++ b/src/network/networkd-link-bus.c
> +@@ -25,15 +25,41 @@
> + #include "networkd.h"
> + #include "networkd-link.h"
> +
> ++#define SYSTEMD_NETWORKD_DBUS 1
> ++
> ++#ifdef SYSTEMD_NETWORKD_DBUS
> ++/*
> ++#include "hostname-util.h"
> ++#include "network-internal.h"
> ++#include "networkd-link.h"
> ++#include "bus-util.h"
> ++*/
> ++#include "sd-network.h"
> ++#include "sd-netlink.h"
> ++#include "socket-util.h"
> ++#include "ether-addr-util.h"
> ++/*
> ++#include "local-addresses.h"
> ++*/
> ++#endif
> ++
> + static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_operational_state,
link_operstate, LinkOperationalState);
> + static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_administrative_state,
link_state, LinkState);
> +
> ++#ifdef SYSTEMD_NETWORKD_DBUS
> ++static int method_get_address (sd_bus_message *m, void* userdata,
sd_bus_error *error);
> ++#endif
> ++
> + const sd_bus_vtable link_vtable[] = {
> +         SD_BUS_VTABLE_START(0),
> +
> +         SD_BUS_PROPERTY("OperationalState", "s",
property_get_operational_state, offsetof(Link, operstate),
SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
> +         SD_BUS_PROPERTY("AdministrativeState", "s",
property_get_administrative_state, offsetof(Link, state),
SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
> +
> ++#ifdef SYSTEMD_NETWORKD_DBUS
> ++		     /* device name */
> ++    		 SD_BUS_METHOD("GetAddress", "s", "s",
method_get_address, SD_BUS_VTABLE_UNPRIVILEGED),
> ++#endif
> +         SD_BUS_VTABLE_END
> + };
> +
> +@@ -136,3 +162,70 @@ int link_send_changed(Link *link, const char
*property, ...) {
> +                         "org.freedesktop.network1.Link",
> +                         l);
> + }
> ++
> ++static int method_get_address (sd_bus_message *m, void* userdata,
sd_bus_error *error)
> ++{
> ++    _cleanup_netlink_unref_ sd_netlink                  *rtnl   = NULL;
> ++    _cleanup_netlink_message_unref_ sd_netlink_message  *req    = NULL;
> ++    _cleanup_netlink_message_unref_ sd_netlink_message  *reply  = NULL;
> ++    _cleanup_bus_message_unref_ sd_bus_message          *resp   = NULL;
> ++    Manager                                             *mgr    =
userdata;
> ++
> ++    struct udev*        udev               = NULL;
> ++    struct udev_device* udev_eth           = NULL;
> ++    const char*         device             = NULL;
> ++    char                devpath [32]       = "/sys/class/net/";
> ++
> ++    int                 r;
> ++    unsigned char       ifindex;
> ++    bool                have_mac;
> ++    struct ether_addr   e;
> ++    char                ea[ETHER_ADDR_TO_STRING_MAX];
> ++
> ++    assert(m);
> ++    assert(mgr);
> ++
> ++    r = sd_bus_message_read (m, "s", &device);
> ++    if (r < 0)
> ++        return r;
> ++
> ++    if (isempty (device))
> ++        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
"Invalid Device Name.");
> ++
> ++    udev = udev_new();
> ++    udev_eth = udev_device_new_from_syspath(udev, strcat (devpath,
device));
> ++    if (!udev_eth)
> ++        return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Could not
find udev device");
> ++
> ++    ifindex = udev_device_get_ifindex(udev_eth);
> ++
> ++    r = sd_netlink_open(&rtnl);
> ++    if (r < 0)
> ++            return log_error_errno(r, "Failed to connect to
netlink:"); /* fixme */
> ++
> ++    r = sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, ifindex);
> ++    if (r < 0)
> ++            return r;
> ++
> ++    r = sd_netlink_call(rtnl, req, 0, &reply); /* fixme */
> ++    if (r < 0)
> ++            return r;
> ++
> ++    have_mac = sd_netlink_message_read_ether_addr(reply, IFLA_ADDRESS,
&e) >= 0;
> ++    if (!have_mac)
> ++        return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Error
reading IFLA address");
> ++
> ++    ether_addr_to_string(&e, ea);
> ++
> ++    r = sd_bus_message_new_method_return(m, &resp);
> ++    if (r < 0)
> ++        return sd_bus_error_setf(error, SD_BUS_ERROR_NO_MEMORY, "Error
allocating reply messgage");
> ++
> ++    r = sd_bus_message_append(resp, "s", ea);
> ++    if (r < 0)
> ++        return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Error
appending to reply messgage");
> ++
> ++    r = sd_bus_send(mgr->bus, resp, NULL);
> ++
> ++    return sd_bus_reply_method_return(m, "s", "Getting IFLA
address ...");
> ++}
> +diff --git a/src/network/networkd-network-bus.c
b/src/network/networkd-network-bus.c
> +index 5717a15..6f0d1e5 100644
> +--- a/src/network/networkd-network-bus.c
> ++++ b/src/network/networkd-network-bus.c
> +@@ -19,10 +19,34 @@
> +   along with systemd; If not, see <http://www.gnu.org/licenses/>.
> + ***/
> +
> ++#define SYSTEMD_NETWORKD_DBUS 1
> ++
> ++#ifdef SYSTEMD_NETWORKD_DBUS
> ++#include <netinet/ether.h>
> ++#include <linux/if.h>
> ++#endif
> ++
> + #include "strv.h"
> +
> + #include "networkd.h"
> +
> ++#ifdef SYSTEMD_NETWORKD_DBUS
> ++#include "hostname-util.h"
> ++#include "network-internal.h"
> ++#include "networkd-link.h"
> ++#include "bus-util.h"
> ++
> ++#include "sd-network.h"
> ++#include "sd-netlink.h"
> ++#include "local-addresses.h"
> ++#endif
> ++
> ++#ifdef SYSTEMD_NETWORKD_DBUS
> ++int network_address_added_handler (sd_netlink* rtnl,
sd_netlink_message* m, void* userdata);
> ++int network_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message
*message, void *userdata, Address* address); /* fixme */
> ++static int method_get_address (sd_bus_message *m, void* userdata,
sd_bus_error *error); /* fixme */
> ++#endif
> ++
> + static int property_get_ether_addrs(
> +                 sd_bus *bus,
> +                 const char *path,
> +@@ -56,6 +80,11 @@ static int property_get_ether_addrs(
> +         return sd_bus_message_close_container(reply);
> + }
> +
> ++#ifdef SYSTEMD_NETWORKD_DBUS
> ++static int method_add_address (sd_bus_message *m, void* userdata,
sd_bus_error *error);
> ++static int method_del_address (sd_bus_message *m, void* userdata,
sd_bus_error *error);
> ++#endif
> ++
> + const sd_bus_vtable network_vtable[] = {
> +         SD_BUS_VTABLE_START(0),
> +
> +@@ -67,6 +96,13 @@ const sd_bus_vtable network_vtable[] = {
> +         SD_BUS_PROPERTY("MatchType", "as", NULL, offsetof(Network,
match_type), SD_BUS_VTABLE_PROPERTY_CONST),
> +         SD_BUS_PROPERTY("MatchName", "as", NULL, offsetof(Network,
match_name), SD_BUS_VTABLE_PROPERTY_CONST),
> +
> ++#ifdef SYSTEMD_NETWORKD_DBUS
> ++		     /* device, IP, netmask, family, flags, scope, gateway */
> ++    		 SD_BUS_METHOD("AddAddress", "sssyyys", "x",
method_add_address, SD_BUS_VTABLE_UNPRIVILEGED),
> ++    		 SD_BUS_METHOD("DelAddress", "sssyyys", "x",
method_del_address, SD_BUS_VTABLE_UNPRIVILEGED),
> ++		     /* (family, prefixlen, flags, scope, IP)+ gateway */
> ++    		 SD_BUS_METHOD("GetAddress", "s", "a(iyyus)s",
method_get_address, SD_BUS_VTABLE_UNPRIVILEGED),
> ++#endif
> +         SD_BUS_VTABLE_END
> + };
> +
> +@@ -152,3 +188,523 @@ int network_object_find(sd_bus *bus, const char
*path, const char *interface, vo
> +
> +         return 1;
> + }
> ++
> ++#ifdef SYSTEMD_NETWORKD_DBUS
> ++
> ++static int method_add_address (sd_bus_message *m, void* userdata,
sd_bus_error *error)
> ++{
> ++    _cleanup_bus_message_unref_ sd_bus_message*         resp    = NULL;
> ++    _cleanup_netlink_unref_ sd_netlink*                 rtnl    = NULL;
> ++    _cleanup_netlink_message_unref_ sd_netlink_message* req     = NULL;
> ++    _cleanup_netlink_message_unref_ sd_netlink_message* reply   = NULL;
> ++    _cleanup_address_free_ Address *addr                        = NULL;
> ++    _cleanup_route_free_ Route *rt                              = NULL;
> ++    Manager *mgr                                                =
userdata;
> ++    Link*               link               = NULL;
> ++    struct udev*        udev               = NULL;
> ++    struct udev_device* udev_eth           = NULL;
> ++
> ++    const char*         device             = NULL;
> ++    const char*         ipaddr             = NULL;
> ++    const char*         netmask            = NULL;
> ++    const char*         gateway            = NULL;
> ++    char                devpath [32]       = "/sys/class/net/";
> ++
> ++    unsigned char       family;
> ++    unsigned char       prefixlen;
> ++    unsigned char       flags;
> ++    unsigned char       scope;
> ++    unsigned char       ifindex;
> ++
> ++    struct in_addr      nm;
> ++    struct in_addr      ip;
> ++    struct in_addr      gw;
> ++    int r;
> ++
> ++    assert(m);
> ++    assert(mgr);
> ++
> ++    r = sd_bus_message_read (m, "sssyyys", &device, &ipaddr, &netmask,
&family, &flags, &scope, &gateway);
> ++    if (r < 0)
> ++        return r;
> ++
> ++    if (isempty (device))
> ++        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
"Invalid Device Name.");
> ++
> ++    if (isempty (ipaddr))
> ++        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
"Invalid IP Address.");
> ++
> ++    if (isempty (netmask))
> ++        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
"Invalid IP Netmask.");
> ++
> ++    assert(family == AF_INET || family == AF_INET6);
> ++
> ++    udev = udev_new();
> ++    udev_eth = udev_device_new_from_syspath(udev, strcat (devpath,
device));
> ++    if (!udev_eth)
> ++            return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Could
not find udev device");
> ++
> ++    ifindex = udev_device_get_ifindex(udev_eth);
> ++
> ++    inet_aton (netmask, &nm);
> ++    inet_aton (ipaddr, &ip);
> ++    if (!isempty (gateway)) inet_aton (gateway, &gw);
> ++
> ++    prefixlen = in_addr_netmask_to_prefixlen(&nm);
> ++    assert(prefixlen > 0);
> ++
> ++    r = address_new_dynamic(&addr);
> ++    if (r < 0)
> ++        return sd_bus_error_setf(error, SD_BUS_ERROR_NO_MEMORY, "Error
allocating new address");
> ++
> ++    r = sd_netlink_open(&rtnl);
> ++    if (r < 0)
> ++            return sd_bus_error_setf(error, SD_BUS_ERROR_IO_ERROR,
"Failed to connect to netlink");
> ++
> ++    link = new0(Link, 1);
> ++    if (!link)
> ++            return -ENOMEM;
> ++
> ++    link->network = new0(Network, 1);
> ++    if (!link->network)
> ++            return sd_bus_error_setf(error, SD_BUS_ERROR_NO_MEMORY,
"Could not alloc memory for Network");
> ++
> ++    link->n_ref                 = 1;
> ++    link->manager               = mgr;
> ++    link->manager->rtnl         = rtnl;
> ++    link->state                 = LINK_STATE_PENDING;
> ++    link->rtnl_extended_attrs   = true;
> ++    link->ifindex               = ifindex;
> ++    link->ifname                = strdup(device); /*FIXME:*/
> ++    if (!link->ifname)
> ++            return -ENOMEM;
> ++
> ++    addr->family                = family;
> ++    addr->in_addr.in.s_addr     = ip.s_addr;
> ++    addr->prefixlen             = prefixlen;
> ++    addr->broadcast.s_addr      = ip.s_addr | ~nm.s_addr;
> ++
> ++    if (!isempty (gateway))
> ++    {
> ++        r = route_new_dynamic(&rt, RTPROT_STATIC);
> ++        if (r < 0)
> ++            return r;
> ++
> ++        rt->protocol        = RTPROT_STATIC;
> ++        rt->network         = link->network;
> ++        rt->family          = family;
> ++        rt->scope           = RT_SCOPE_LINK;            /* FIXME: */
> ++        rt->dst_prefixlen   = 32;                       /* FIXME:
AF_INET assumed */
> ++        rt->dst_addr.in     = gw;
> ++
> ++        LIST_PREPEND(routes, link->network->static_routes, rt);
> ++    }
> ++
> ++    /* send an nlmsg (RTM_NEWADDR) and append address to link address
list */
> ++    r = address_update (addr, link, network_address_added_handler);
> ++    if (r < 0)
> ++        return r;
> ++
> ++    r = sd_bus_message_new_method_return(m, &resp);
> ++    if (r < 0)
> ++        return sd_bus_error_setf(error, SD_BUS_ERROR_NO_MEMORY, "Error
allocating reply messgage");
> ++
> ++    r = sd_bus_message_append(resp, "x", 0);
> ++    if (r < 0)
> ++            return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Error
appending to reply messgage");
> ++
> ++    r = sd_bus_send(mgr->bus, resp, NULL);
> ++    if (r < 0)
> ++            return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Error
sending reply messgage");
> ++
> ++    return sd_bus_reply_method_return(m, "s", "Adding IP address...");
> ++}
> ++
> ++static int method_del_address (sd_bus_message *m, void* userdata,
sd_bus_error *error)
> ++{
> ++    _cleanup_bus_message_unref_ sd_bus_message*         resp    = NULL;
> ++    _cleanup_netlink_unref_ sd_netlink*                 rtnl    = NULL;
> ++    _cleanup_netlink_message_unref_ sd_netlink_message* req     = NULL;
> ++    _cleanup_netlink_message_unref_ sd_netlink_message* reply   = NULL;
> ++    _cleanup_address_free_ Address *addr                        = NULL;
> ++    _cleanup_route_free_ Route *rt                              = NULL;
> ++    Manager *mgr                                                =
userdata;
> ++    Link*               link               = NULL;
> ++    struct udev*        udev               = NULL;
> ++    struct udev_device* udev_eth           = NULL;
> ++
> ++    const char*         device             = NULL;
> ++    const char*         ipaddr             = NULL;
> ++    const char*         netmask            = NULL;
> ++    const char*         gateway            = NULL;
> ++    char                devpath [32]       = "/sys/class/net/";
> ++
> ++    unsigned char       family;
> ++    unsigned char       prefixlen;
> ++    unsigned char       flags;
> ++    unsigned char       scope;
> ++    unsigned char       ifindex;
> ++
> ++    struct in_addr      nm;
> ++    struct in_addr      ip;
> ++    struct in_addr      gw;
> ++    int r;
> ++
> ++    assert(m);
> ++    assert(mgr);
> ++
> ++    r = sd_bus_message_read (m, "sssyyys", &device, &ipaddr, &netmask,
&family, &flags, &scope, &gateway);
> ++    if (r < 0)
> ++        return r;
> ++
> ++    if (isempty (device))
> ++        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
"Invalid Device Name.");
> ++
> ++    if (isempty (ipaddr))
> ++        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
"Invalid IP Address.");
> ++
> ++    if (isempty (netmask))
> ++        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
"Invalid IP Netmask.");
> ++
> ++    assert(family == AF_INET || family == AF_INET6);
> ++
> ++    udev = udev_new();
> ++    udev_eth = udev_device_new_from_syspath(udev, strcat (devpath,
device));
> ++    if (!udev_eth)
> ++            return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Could
not find udev device");
> ++
> ++    ifindex = udev_device_get_ifindex(udev_eth);
> ++
> ++    inet_aton (netmask, &nm);
> ++    inet_aton (ipaddr, &ip);
> ++    if (!isempty (gateway)) inet_aton (gateway, &gw);
> ++
> ++    prefixlen = in_addr_netmask_to_prefixlen(&nm);
> ++    assert(prefixlen > 0);
> ++
> ++    r = address_new_dynamic(&addr);
> ++    if (r < 0)
> ++        return sd_bus_error_setf(error, SD_BUS_ERROR_NO_MEMORY, "Error
allocating new address");
> ++
> ++    r = sd_netlink_open(&rtnl);
> ++    if (r < 0)
> ++            return sd_bus_error_setf(error, SD_BUS_ERROR_IO_ERROR,
"Failed to connect to netlink");
> ++
> ++    link = new0(Link, 1);
> ++    if (!link)
> ++            return -ENOMEM;
> ++
> ++    link->network = new0(Network, 1);
> ++    if (!link->network)
> ++            return sd_bus_error_setf(error, SD_BUS_ERROR_NO_MEMORY,
"Could not alloc memory for Network");
> ++
> ++    link->n_ref                 = 1;
> ++    link->manager               = mgr;
> ++    link->manager->rtnl         = rtnl;
> ++    link->state                 = LINK_STATE_PENDING;
> ++    link->rtnl_extended_attrs   = true;
> ++    link->ifindex               = ifindex;
> ++    link->ifname                = strdup(device);
> ++    if (!link->ifname)
> ++            return -ENOMEM;
> ++
> ++    addr->family                = family;
> ++    addr->in_addr.in.s_addr     = ip.s_addr;
> ++    addr->prefixlen             = prefixlen;
> ++    addr->broadcast.s_addr      = ip.s_addr | ~nm.s_addr;
> ++
> ++    if (!isempty (gateway))
> ++    {
> ++        r = route_new_dynamic(&rt, RTPROT_STATIC);
> ++        if (r < 0)
> ++            return r;
> ++
> ++        rt->network         = link->network;
> ++        rt->family          = family;
> ++        rt->scope           = RT_SCOPE_LINK;            /* FIXME: */
> ++        rt->dst_prefixlen   = 32;                       /* FIXME:
AF_INET assumed */
> ++        rt->dst_addr.in     = gw;
> ++
> ++        /*LIST_PREPEND(routes, link->network->static_routes, rt);*/
> ++        /* Drop the Gateway */
> ++        route_drop (rt, link, link_route_drop_handler);
> ++    }
> ++
> ++    /* send an nlmsg to delete address from address list */
> ++    r = address_drop(addr, link, link_address_drop_handler);
> ++    if (r < 0)
> ++        return r;
> ++
> ++    r = sd_bus_message_new_method_return(m, &resp);
> ++    if (r < 0)
> ++        return sd_bus_error_setf(error, SD_BUS_ERROR_NO_MEMORY, "Error
allocating reply messgage");
> ++
> ++    r = sd_bus_message_append(resp, "x", 0);
> ++    if (r < 0)
> ++            return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Error
appending to reply messgage");
> ++
> ++    r = sd_bus_send(mgr->bus, resp, NULL);
> ++    if (r < 0)
> ++            return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Error
sending reply messgage");
> ++
> ++    return sd_bus_reply_method_return(m, "s", "Deleted IP address...");
> ++}
> ++
> ++static int method_get_address (sd_bus_message *m, void* userdata,
sd_bus_error *error)
> ++{
> ++    _cleanup_netlink_unref_ sd_netlink  *rtnl   = NULL;
> ++    _cleanup_address_free_ Address      *addr   = NULL;
> ++    _cleanup_route_free_ Route          *rt     = NULL;
> ++    Manager                             *mgr    = userdata;
> ++#if 0 /* fixme: */
> ++    Link*               link               = NULL;
> ++#endif
> ++    struct udev*        udev               = NULL;
> ++    struct udev_device* udev_eth           = NULL;
> ++
> ++    const char*         device             = NULL;
> ++#if 0 /* fixme: */
> ++    const char*         ipaddr             = NULL;
> ++    const char*         netmask            = NULL;
> ++    const char*         gateway            = NULL;
> ++#endif
> ++    char                devpath [32]       = "/sys/class/net/";
> ++
> ++#if 0 /* fixme: */
> ++    unsigned char       family;
> ++    unsigned char       prefixlen;
> ++    unsigned char       flags;
> ++    unsigned char       scope;
> ++#endif
> ++    unsigned char       ifindex;
> ++
> ++#if 0 /* fixme: */
> ++    struct in_addr      nm;
> ++    struct in_addr      ip;
> ++    struct in_addr      gw;
> ++#endif
> ++    int                 r;
> ++
> ++    sd_netlink_message* maddr;
> ++
> ++    _cleanup_netlink_message_unref_ sd_netlink_message  *req    = NULL;
> ++    _cleanup_netlink_message_unref_ sd_netlink_message  *reply    =
NULL;
> ++    _cleanup_bus_message_unref_ sd_bus_message  *resp   = NULL;
> ++    _cleanup_address_free_ Address              *address = NULL;
> ++    _cleanup_free_ struct local_address         *local   = NULL;
> ++    _cleanup_free_ char                         *ipr     = NULL;
> ++    _cleanup_free_ char                         *gwr     = NULL;
> ++    int                 n;
> ++    int                 i;
> ++
> ++    assert(m);
> ++    assert(mgr);
> ++
> ++    r = sd_bus_message_read (m, "s", &device);
> ++    if (r < 0)
> ++        return r;
> ++
> ++    if (isempty (device))
> ++        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
"Invalid Device Name.");
> ++
> ++    udev = udev_new();
> ++    udev_eth = udev_device_new_from_syspath(udev, strcat (devpath,
device));
> ++    if (!udev_eth)
> ++        return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Could not
find udev device");
> ++
> ++    ifindex = udev_device_get_ifindex(udev_eth);
> ++
> ++    r = sd_netlink_open(&rtnl);
> ++    if (r < 0)
> ++            return log_error_errno(r, "Failed to connect to
netlink:"); /* fixme */
> ++
> ++    r = sd_rtnl_message_new_addr(rtnl, &req, RTM_GETADDR, 0, 0);
> ++    if (r < 0)
> ++            return r;
> ++
> ++    r = sd_netlink_message_request_dump(req, true);
> ++    if (r < 0)
> ++            return r;
> ++
> ++    r = sd_netlink_call(rtnl, req, 0, &reply); /* fixme */
> ++    if (r < 0)
> ++            return r;
> ++
> ++    r = sd_bus_message_new_method_return(m, &resp);
> ++    if (r < 0)
> ++        return sd_bus_error_setf(error, SD_BUS_ERROR_NO_MEMORY, "Error
allocating reply messgage");
> ++
> ++    r = sd_bus_message_open_container(resp, 'a',
"iyyus"); /*family,prefixlen,scope,flags,addr*/
> ++    if (r < 0)
> ++        return sd_bus_error_setf(error, SD_BUS_ERROR_NO_MEMORY, "Error
opening a container for reply message");
> ++
> ++    for (maddr = reply; maddr; maddr = sd_netlink_message_next(maddr))
{
> ++            int k;
> ++
> ++            r = address_new_dynamic(&address);
> ++            if (r < 0)
> ++                    return r;
> ++
> ++            k = network_rtnl_process_address(rtnl, maddr, mgr,
address);
> ++            if (k) {
> ++                r = sd_bus_message_append(resp, "i", address->family);
> ++                if (r < 0)
> ++                        return sd_bus_error_setf(error,
SD_BUS_ERROR_FAILED, "Error appending to reply messgage");
> ++
> ++                r = sd_bus_message_append(resp, "y", address->
prefixlen);
> ++                if (r < 0)
> ++                        return sd_bus_error_setf(error,
SD_BUS_ERROR_FAILED, "Error appending to reply messgage");
> ++
> ++                r = sd_bus_message_append(resp, "y", address->scope);
> ++                if (r < 0)
> ++                        return sd_bus_error_setf(error,
SD_BUS_ERROR_FAILED, "Error appending to reply messgage");
> ++
> ++                r = sd_bus_message_append(resp, "u", address->flags);
> ++                if (r < 0)
> ++                        return sd_bus_error_setf(error,
SD_BUS_ERROR_FAILED, "Error appending to reply messgage");
> ++
> ++                r = in_addr_to_string(address->family, &address->
in_addr, &ipr); /* fixme */
> ++                if (r < 0)
> ++                        return r;
> ++
> ++                r = sd_bus_message_append(resp, "s", ipr);
> ++                if (r < 0)
> ++                        return sd_bus_error_setf(error,
SD_BUS_ERROR_FAILED, "Error appending to reply messgage");
> ++            }
> ++    }
> ++
> ++    r = sd_bus_message_close_container(resp);
> ++    if (r < 0)
> ++            return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Error
closing reply container");
> ++
> ++    n = local_gateways(rtnl, ifindex, AF_UNSPEC, &local);
> ++    if (n < 0)
> ++            return n;
> ++
> ++    for (i = 0; i < n; i++) {
> ++
> ++            r = in_addr_to_string(local[i].family, &local[i].address,
&gwr);
> ++            if (r < 0)
> ++                    return r;
> ++    }
> ++
> ++    r = sd_bus_message_append(resp, "s", gwr);
> ++    if (r < 0)
> ++            return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Error
appending to reply messgage");
> ++
> ++    r = sd_bus_send(mgr->bus, resp, NULL);
> ++    if (r < 0)
> ++            return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Error
sending reply messgage");
> ++
> ++    return sd_bus_reply_method_return(m, "s", "Getting IP
configuration...");
> ++}
> ++
> ++
> ++int network_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message
*message, void *userdata, Address* address) {
> ++        Manager*        m       = (Manager*) userdata; /* fixme */
> ++#if 0 /* fixme */
> ++        Link*           link    = NULL;
> ++#endif
> ++        uint16_t        type;
> ++        unsigned char   flags;
> ++#if 0 /* fixme */
> ++        Address*        existing;
> ++#endif
> ++        char            buf[INET6_ADDRSTRLEN];
> ++#if 0 /* fixme */
> ++        char            valid_buf[FORMAT_TIMESPAN_MAX];
> ++        const char*     valid_str = NULL;
> ++#endif
> ++        int             ifindex;
> ++        int             r;
> ++        /*_cleanup_address_free_ Address *address = NULL;*/
> ++        sd_bus_error err    = SD_BUS_ERROR_NULL; /* fixme */
> ++        sd_bus_error* error = &err;             /* fixme */
> ++
> ++        assert(rtnl);
> ++        assert(message);
> ++        assert(m);
> ++        assert(address);
> ++
> ++        if (sd_netlink_message_is_error(message)) {
> ++                r = sd_netlink_message_get_errno(message);
> ++                if (r < 0)
> ++                        sd_bus_error_setf(error, SD_BUS_ERROR_FAILED,
"rtnl: failed to receive address: ");
> ++
> ++                return 0;
> ++        }
> ++
> ++        r = sd_netlink_message_get_type(message, &type);
> ++        if (r < 0) {
> ++                sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "rtnl:
could not get message type: ");
> ++                return 0;
> ++        } else if (type != RTM_NEWADDR && type != RTM_DELADDR) {
> ++                sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "rtnl:
received unexpected message type when processing address");
> ++                return 0;
> ++        }
> ++
> ++        r = sd_rtnl_message_addr_get_ifindex(message, &ifindex);
> ++        if (r < 0) {
> ++                sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "rtnl:
could not get ifindex from address: %m");
> ++                return 0;
> ++        } else if (ifindex <= 0) {
> ++                sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "rtnl:
received address message with invalid ifindex: %d", ifindex);
> ++                return 0;
> ++        }
> ++
> ++        r = sd_rtnl_message_addr_get_family(message, &address->
family); /* int : i*/
> ++        if (r < 0 || !IN_SET(address->family, AF_INET, AF_INET6)) {
> ++                sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "rtnl:
received address with invalid family, ignoring.");
> ++                return 0;
> ++        }
> ++
> ++        r = sd_rtnl_message_addr_get_prefixlen(message, &address->
prefixlen); /* uchar : byte : y */
> ++        if (r < 0) {
> ++                sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "rtnl:
received address with invalid prefixlen, ignoring: ");
> ++                return 0;
> ++        }
> ++
> ++        r = sd_rtnl_message_addr_get_scope(message, &address->
scope); /* uchar : byte : y*/
> ++        if (r < 0) {
> ++                sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "rtnl:
received address with invalid scope, ignoring: ");
> ++                return 0;
> ++        }
> ++
> ++        r = sd_rtnl_message_addr_get_flags(message, &flags); /*
uint32 : u*/
> ++        if (r < 0) {
> ++                sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "rtnl:
received address with invalid flags, ignoring: ");
> ++                return 0;
> ++        }
> ++        address->flags = flags;
> ++
> ++        switch (address->family) {
> ++        case AF_INET:
> ++                r = sd_netlink_message_read_in_addr(message, IFA_LOCAL,
&address->in_addr.in); /* ulong : uint64 : t */
> ++                if (r < 0) {
> ++                        sd_bus_error_setf(error, SD_BUS_ERROR_FAILED,
"rtnl: received address without valid address, ignoring: ");
> ++                        return 0;
> ++                }
> ++
> ++                break;
> ++
> ++        case AF_INET6:
> ++                r = sd_netlink_message_read_in6_addr(message,
IFA_ADDRESS, &address->in_addr.in6); /* ulong : uint64 : t */
> ++                if (r < 0) {
> ++                        sd_bus_error_setf(error, SD_BUS_ERROR_FAILED,
"rtnl: received address without valid address, ignoring: ");
> ++                        return 0;
> ++                }
> ++
> ++                break;
> ++
> ++        default:
> ++                assert_not_reached("invalid address family");
> ++        }
> ++
> ++        if (!inet_ntop(address->family, &address->in_addr, buf,
INET6_ADDRSTRLEN)) { /* string : s */
> ++                sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Could
not print address");
> ++                return 0;
> ++        }
> ++
> ++        return 1;
> ++}
> ++#endif
> +diff --git a/src/network/networkd-network.c
b/src/network/networkd-network.c
> +index 6587ea9..2616c5b 100644
> +--- a/src/network/networkd-network.c
> ++++ b/src/network/networkd-network.c
> +@@ -32,6 +32,14 @@
> + #include "network-internal.h"
> + #include "dns-domain.h"
> +
> ++#define SYSTEMD_NETWORKD_DBUS 1
> ++
> ++#ifdef SYSTEMD_NETWORKD_DBUS
> ++int network_address_added_handler (sd_netlink* rtnl,
sd_netlink_message* m, void* userdata);
> ++int network_set_gateway (Link* link);
> ++static int route_handler(sd_netlink *rtnl, sd_netlink_message *m, void
*userdata);
> ++#endif
> ++
> + static int network_load_one(Manager *manager, const char *filename) {
> +         _cleanup_network_free_ Network *network = NULL;
> +         _cleanup_fclose_ FILE *file = NULL;
> +@@ -850,3 +858,76 @@ int config_parse_hostname(const char *unit,
> +
> +         return 0;
> + }
> ++
> ++#ifdef SYSTEMD_NETWORKD_DBUS
> ++int network_address_added_handler (sd_netlink* rtnl,
sd_netlink_message* m, void* userdata)
> ++{
> ++        _cleanup_link_unref_ Link *link = userdata;
> ++        int r;
> ++
> ++        assert(link);
> ++
> ++        r = sd_netlink_message_get_errno(m);
> ++        if (r < 0 && r != -EEXIST) {
> ++                log_debug("Error in set IP address!");
> ++                link_enter_failed(link);
> ++        } else if (r >= 0)
> ++                link_rtnl_process_address(rtnl, m, link->manager);
> ++
> ++		 network_set_gateway (link);
> ++
> ++		 return 1;
> ++}
> ++
> ++/* link_enter_set_routes */
> ++int network_set_gateway (Link* link)
> ++{
> ++        Route *rt;
> ++        int r;
> ++
> ++        assert(link);
> ++        assert(link->network);
> ++        assert(link->state == LINK_STATE_SETTING_ADDRESSES);
> ++
> ++        link->state = LINK_STATE_SETTING_ROUTES;
> ++
> ++        LIST_FOREACH(routes, rt, link->network->static_routes) {
> ++                r = route_configure(rt, link, &route_handler);
> ++                if (r < 0) {
> ++                        log_debug ("Could not set Gateway!");
> ++                        link_enter_failed(link);
> ++                        return r;
> ++                }
> ++
> ++                link->link_messages ++;
> ++        }
> ++
> ++        if (link->link_messages == 0) {
> ++                link->static_configured = true;
> ++
> ++                /*link_enter_configured (link);*/
> ++                log_link_info(link, "Configured");
> ++                link->state = LINK_STATE_CONFIGURED;
> ++                link_save(link);
> ++        } else
> ++                log_debug("Setting Gateway");
> ++
> ++        return 0;
> ++}
> ++
> ++static int route_handler(sd_netlink *rtnl, sd_netlink_message *m, void
*userdata) {
> ++        _cleanup_link_unref_ Link *link = userdata;
> ++        int r;
> ++
> ++        assert(link);
> ++
> ++        r = sd_netlink_message_get_errno(m);
> ++        if (r < 0 && r != -EEXIST) {
> ++                log_debug ("Could not set route! ");
> ++                link_enter_failed(link);
> ++        }
> ++
> ++        return 1;
> ++}
> ++
> ++#endif
> +diff --git a/src/network/org.freedesktop.network1.conf
b/src/network/org.freedesktop.network1.conf
> +index 52dad33..f424b88 100644
> +--- a/src/network/org.freedesktop.network1.conf
> ++++ b/src/network/org.freedesktop.network1.conf
> +@@ -36,6 +36,23 @@
> +                        send_interface="org.freedesktop.DBus.Properties"
> +                        send_member="GetAll"/>
> +
> ++                <allow send_destination="org.freedesktop.network1"
> ++
send_interface="org.freedesktop.network1.Network"
> ++                       send_member="AddAddress"/>
> ++
> ++                <allow send_destination="org.freedesktop.network1"
> ++
send_interface="org.freedesktop.network1.Network"
> ++                       send_member="DelAddress"/>
> ++
> ++                <allow send_destination="org.freedesktop.network1"
> ++
send_interface="org.freedesktop.network1.Network"
> ++                       send_member="GetAddress"/>
> ++
> ++                <allow send_destination="org.freedesktop.network1"
> ++                       send_interface="org.freedesktop.network1.Link"
> ++                       send_member="GetAddress"/>
> ++
> ++
> +                 <allow receive_sender="org.freedesktop.network1"/>
> +         </policy>
> +
> +--
> +1.8.2.2
> +
> diff --git a/yocto-poky/meta/recipes-core/systemd/systemd_225.bb
b/yocto-poky/meta/recipes-core/systemd/systemd_225.bb
> index f7d4c7d..e3d55ec 100644
> --- a/yocto-poky/meta/recipes-core/systemd/systemd_225.bb
> +++ b/yocto-poky/meta/recipes-core/systemd/systemd_225.bb
> @@ -41,6 +41,7 @@ SRC_URI =
"git://github.com/systemd/systemd.git;protocol=git \
>             file://0012-implment-systemd-sysv-install-for-OE.patch \
>             file://0014-Revert-rules-remove-firmware-loading-rules.patch
\
>
file://0015-Revert-udev-remove-userspace-firmware-loading-suppor.patch \
> +           file://0100-systemd_networkd_dbus_setaddress.patch \
>             file://touchscreen.rules \
>             file://00-create-volatile.conf \
>             file://init \

_______________________________________________
openbmc mailing list
openbmc@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/openbmc


[-- Attachment #1.2: Type: text/html, Size: 66116 bytes --]

[-- Attachment #2: graycol.gif --]
[-- Type: image/gif, Size: 105 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2016-01-25  6:23 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-01-20 15:10 [PATCH openbmc] Dbus API for systemd/networkd for network configuration OpenBMC Patches
2016-01-20 15:10 ` OpenBMC Patches
2016-01-21  5:23   ` Cyril Bur
2016-01-21  7:06     ` Hariharasubramanian Ramasubramanian

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.