[systemd-commits] 2 commits - src/network

Tom Gundersen tomegun at kemper.freedesktop.org
Sat Jun 14 07:02:56 PDT 2014


 src/network/networkd-netdev-gperf.gperf |    2 
 src/network/networkd-netdev.c           |   88 +++++++++++++++++++++++++++++++-
 src/network/networkd-tunnel.c           |   40 ++++++++++++++
 src/network/networkd-veth.c             |   22 +++++++-
 src/network/networkd.h                  |    2 
 5 files changed, 151 insertions(+), 3 deletions(-)

New commits:
commit 5c8f858d207992469bd65356e3e44d37fcefa4b0
Author: Tom Gundersen <teg at jklm.no>
Date:   Sat Jun 14 15:48:16 2014 +0200

    Revert "Revert "networkd: netdev - set predictable mac address when creating netdev""
    
    This reverts (and rewrites) commit 7d95c772cba1836545459760273b13f2e01dd2a8.
    
    The issue blocking this feature has now been fixed in the kernel, and backported
    to the various stable kernels.
    
    Our netdevs will now have stable MAC addresses, even if one is not specified.

diff --git a/src/network/networkd-netdev.c b/src/network/networkd-netdev.c
index 0d08e56..5f8a82c 100644
--- a/src/network/networkd-netdev.c
+++ b/src/network/networkd-netdev.c
@@ -27,6 +27,7 @@
 #include "conf-files.h"
 #include "conf-parser.h"
 #include "list.h"
+#include "siphash24.h"
 
 #define VLANID_MAX 4094
 
@@ -528,6 +529,52 @@ int netdev_set_ifindex(NetDev *netdev, sd_rtnl_message *message) {
         return 0;
 }
 
+#define HASH_KEY SD_ID128_MAKE(52,e1,45,bd,00,6f,29,96,21,c6,30,6d,83,71,04,48)
+
+static int netdev_get_mac(const char *ifname, struct ether_addr **ret) {
+        _cleanup_free_ struct ether_addr *mac = NULL;
+        uint8_t result[8];
+        size_t l, sz;
+        uint8_t *v;
+        int r;
+
+        assert(ifname);
+        assert(ret);
+
+        mac = new0(struct ether_addr, 1);
+        if (!mac)
+                return -ENOMEM;
+
+        l = strlen(ifname);
+        sz = sizeof(sd_id128_t) + l;
+        v = alloca(sz);
+
+        /* fetch some persistent data unique to the machine */
+        r = sd_id128_get_machine((sd_id128_t*) v);
+        if (r < 0)
+                return r;
+
+        /* combine with some data unique (on this machine) to this
+         * netdev */
+        memcpy(v + sizeof(sd_id128_t), ifname, l);
+
+        /* Let's hash the host machine ID plus the container name. We
+         * use a fixed, but originally randomly created hash key here. */
+        siphash24(result, v, sz, HASH_KEY.bytes);
+
+        assert_cc(ETH_ALEN <= sizeof(result));
+        memcpy(mac->ether_addr_octet, result, ETH_ALEN);
+
+        /* see eth_random_addr in the kernel */
+        mac->ether_addr_octet[0] &= 0xfe;        /* clear multicast bit */
+        mac->ether_addr_octet[0] |= 0x02;        /* set local assignment bit (IEEE802) */
+
+        *ret = mac;
+        mac = NULL;
+
+        return 0;
+}
+
 static int netdev_load_one(Manager *manager, const char *filename) {
         _cleanup_netdev_unref_ NetDev *netdev = NULL;
         _cleanup_fclose_ FILE *file = NULL;
@@ -607,14 +654,39 @@ static int netdev_load_one(Manager *manager, const char *filename) {
                              NULL, NULL, NULL, NULL, NULL, NULL) <= 0)
                 return 0;
 
+        if (!netdev->mac) {
+                r = netdev_get_mac(netdev->ifname, &netdev->mac);
+                if (r < 0) {
+                        log_error("Failed to generate predictable MAC address for %s",
+                                  netdev->ifname);
+                        return r;
+                }
+        }
+
         r = hashmap_put(netdev->manager->netdevs, netdev->ifname, netdev);
         if (r < 0)
                 return r;
 
         LIST_HEAD_INIT(netdev->callbacks);
 
-        if(netdev->kind == NETDEV_KIND_VETH)
+        if(netdev->kind == NETDEV_KIND_VETH) {
+                if (netdev->ifname_peer) {
+                        log_warning("Veth NetDev without Peer Name configured "
+                                    "in %s. Ignoring", filename);
+                        return 0;
+                }
+
+                if (!netdev->mac) {
+                        r = netdev_get_mac(netdev->ifname_peer, &netdev->mac_peer);
+                        if (r < 0) {
+                                log_error("Failed to generate predictable MAC address for %s",
+                                          netdev->ifname_peer);
+                                return r;
+                        }
+                }
+
                 return netdev_create_veth(netdev, netdev_create_handler);
+        }
 
         if (netdev->kind != NETDEV_KIND_VLAN &&
             netdev->kind != NETDEV_KIND_MACVLAN &&

commit 96c907429e3224289fd360b8d9c8fdc573f4363b
Author: Tom Gundersen <teg at jklm.no>
Date:   Sat Jun 14 15:38:35 2014 +0200

    networkd: netdev - allow setting MACAddress in .netdev files
    
    It may sometimes be necessary to specify the MAC address of a netdev.
    Let us set the correct one from the get-go, rather than having the
    kernel generate a random one, and then change it after.

diff --git a/src/network/networkd-netdev-gperf.gperf b/src/network/networkd-netdev-gperf.gperf
index dff0ae6..82cc858 100644
--- a/src/network/networkd-netdev-gperf.gperf
+++ b/src/network/networkd-netdev-gperf.gperf
@@ -23,6 +23,7 @@ NetDev.Description,      config_parse_string,                0,
 NetDev.Name,             config_parse_ifname,                0,                             offsetof(NetDev, ifname)
 NetDev.Kind,             config_parse_netdev_kind,           0,                             offsetof(NetDev, kind)
 NetDev.MTUBytes,         config_parse_iec_size,              0,                             offsetof(NetDev, mtu)
+NetDev.MACAddress,       config_parse_hwaddr,                0,                             offsetof(NetDev, mac)
 VLAN.Id,                 config_parse_uint64,                0,                             offsetof(NetDev, vlanid)
 MACVLAN.Mode,            config_parse_macvlan_mode,          0,                             offsetof(NetDev, macvlan_mode)
 Tunnel.Local,            config_parse_tunnel_address,        0,                             offsetof(NetDev, tunnel_local)
@@ -31,3 +32,4 @@ Tunnel.TOS,              config_parse_unsigned,              0,
 Tunnel.TTL,              config_parse_unsigned,              0,                             offsetof(NetDev, tunnel_ttl)
 Tunnel.DiscoverPathMTU,  config_parse_bool,                  0,                             offsetof(NetDev, tunnel_pmtudisc)
 Peer.Name,               config_parse_ifname,                0,                             offsetof(NetDev, ifname_peer)
+Peer.MACAddress,         config_parse_hwaddr,                0,                             offsetof(NetDev, mac_peer)
diff --git a/src/network/networkd-netdev.c b/src/network/networkd-netdev.c
index 1519419..0d08e56 100644
--- a/src/network/networkd-netdev.c
+++ b/src/network/networkd-netdev.c
@@ -92,6 +92,8 @@ static void netdev_free(NetDev *netdev) {
 
         free(netdev->description);
         free(netdev->ifname);
+        free(netdev->mac);
+        free(netdev->mac_peer);
 
         condition_free_list(netdev->match_host);
         condition_free_list(netdev->match_virt);
@@ -301,7 +303,7 @@ static int netdev_create(NetDev *netdev, Link *link, sd_rtnl_message_handler_t c
                 return r;
         }
 
-        if(netdev->mtu) {
+        if (netdev->mtu) {
                 r = sd_rtnl_message_append_u32(req, IFLA_MTU, netdev->mtu);
                 if (r < 0) {
                         log_error_netdev(netdev,
@@ -311,6 +313,16 @@ static int netdev_create(NetDev *netdev, Link *link, sd_rtnl_message_handler_t c
                 }
         }
 
+        if (netdev->mac) {
+                r = sd_rtnl_message_append_ether_addr(req, IFLA_ADDRESS, netdev->mac);
+                if (r < 0) {
+                        log_error_netdev(netdev,
+                                         "Colud not append IFLA_ADDRESS attribute: %s",
+                                         strerror(-r));
+                    return r;
+                }
+        }
+
         r = sd_rtnl_message_open_container(req, IFLA_LINKINFO);
         if (r < 0) {
                 log_error_netdev(netdev,
diff --git a/src/network/networkd-tunnel.c b/src/network/networkd-tunnel.c
index 60b16ba..885347a 100644
--- a/src/network/networkd-tunnel.c
+++ b/src/network/networkd-tunnel.c
@@ -60,6 +60,16 @@ static int netdev_fill_ipip_rtnl_message(Link *link, sd_rtnl_message *m) {
                 }
         }
 
+        if (netdev->mac) {
+                r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
+                if (r < 0) {
+                        log_error_netdev(netdev,
+                                         "Colud not append IFLA_ADDRESS attribute: %s",
+                                         strerror(-r));
+                    return r;
+                }
+        }
+
         r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
         if (r < 0) {
                 log_error_netdev(netdev,
@@ -157,6 +167,16 @@ static int netdev_fill_sit_rtnl_message(Link *link, sd_rtnl_message *m) {
                 }
         }
 
+        if (netdev->mac) {
+                r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
+                if (r < 0) {
+                        log_error_netdev(netdev,
+                                         "Colud not append IFLA_ADDRESS attribute: %s",
+                                         strerror(-r));
+                    return r;
+                }
+        }
+
         r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
         if (r < 0) {
                 log_error_netdev(netdev,
@@ -262,6 +282,16 @@ static int netdev_fill_ipgre_rtnl_message(Link *link, sd_rtnl_message *m) {
                 }
         }
 
+        if (netdev->mac) {
+                r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
+                if (r < 0) {
+                        log_error_netdev(netdev,
+                                         "Colud not append IFLA_ADDRESS attribute: %s",
+                                         strerror(-r));
+                    return r;
+                }
+        }
+
         r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
         if (r < 0) {
                 log_error_netdev(netdev,
@@ -367,6 +397,16 @@ static int netdev_fill_vti_rtnl_message(Link *link, sd_rtnl_message *m) {
                 }
         }
 
+        if (netdev->mac) {
+                r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
+                if (r < 0) {
+                        log_error_netdev(netdev,
+                                         "Colud not append IFLA_ADDRESS attribute: %s",
+                                         strerror(-r));
+                    return r;
+                }
+        }
+
         r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
         if (r < 0) {
                 log_error_netdev(netdev,
diff --git a/src/network/networkd-veth.c b/src/network/networkd-veth.c
index 1a5d880..3584981 100644
--- a/src/network/networkd-veth.c
+++ b/src/network/networkd-veth.c
@@ -42,6 +42,16 @@ static int netdev_fill_veth_rtnl_message(NetDev *netdev, sd_rtnl_message *m) {
                 return r;
         }
 
+        if (netdev->mac) {
+                r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
+                if (r < 0) {
+                        log_error_netdev(netdev,
+                                         "Colud not append IFLA_ADDRESS attribute: %s",
+                                         strerror(-r));
+                    return r;
+                }
+        }
+
         r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
         if (r < 0) {
                 log_error_netdev(netdev,
@@ -67,7 +77,7 @@ static int netdev_fill_veth_rtnl_message(NetDev *netdev, sd_rtnl_message *m) {
                 return r;
         }
 
-        if(netdev->ifname_peer) {
+        if (netdev->ifname_peer) {
                 r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname_peer);
                 if (r < 0) {
                         log_error("Failed to add netlink interface name: %s", strerror(-r));
@@ -75,6 +85,16 @@ static int netdev_fill_veth_rtnl_message(NetDev *netdev, sd_rtnl_message *m) {
                 }
         }
 
+        if (netdev->mac_peer) {
+                r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac_peer);
+                if (r < 0) {
+                        log_error_netdev(netdev,
+                                         "Colud not append IFLA_ADDRESS attribute: %s",
+                                         strerror(-r));
+                    return r;
+                }
+        }
+
         r = sd_rtnl_message_close_container(m);
         if (r < 0) {
                 log_error_netdev(netdev,
diff --git a/src/network/networkd.h b/src/network/networkd.h
index 102744d..f079473 100644
--- a/src/network/networkd.h
+++ b/src/network/networkd.h
@@ -103,6 +103,8 @@ struct NetDev {
         char *ifname;
         char *ifname_peer;
         size_t mtu;
+        struct ether_addr *mac;
+        struct ether_addr *mac_peer;
         NetDevKind kind;
 
         uint64_t vlanid;



More information about the systemd-commits mailing list