SPECS/systemd/systemd-232-query-duid.patch
99ffaade
 diff -rup systemd-232/src/libsystemd/sd-network/sd-network.c systemd-232-new/src/libsystemd/sd-network/sd-network.c
 --- systemd-232/src/libsystemd/sd-network/sd-network.c	2016-11-03 10:16:42.000000000 -0700
 +++ systemd-232-new/src/libsystemd/sd-network/sd-network.c	2016-11-18 11:49:42.311168130 -0800
 @@ -267,6 +267,51 @@ _public_ int sd_network_link_get_carrier
          return network_link_get_ifindexes(ifindex, "CARRIER_BOUND_BY", ret);
91e03b4b
  }
  
 +static int network_get_file_str(const char *key, const char *fpath, int ifindex, char **ret) {
 +        _cleanup_free_ char *p = NULL, *s = NULL;
 +        int r;
 +
 +        assert_return(ifindex > 0, -EINVAL);
 +        assert_return(fpath, -EINVAL);
 +        assert_return(ret, -EINVAL);
 +
 +        if (asprintf(&p, "%s/%d", fpath, ifindex) < 0)
 +                return -ENOMEM;
 +
 +        r = parse_env_file(p, NEWLINE, key, &s, NULL);
 +        if (r == -ENOENT)
 +                return -ENODATA;
 +        if (r < 0)
 +                return r;
 +        if (isempty(s))
 +                return -ENODATA;
 +
 +        *ret = s;
 +        s = NULL;
 +        return 0;
 +}
 +
 +_public_ int sd_network_link_get_clientid(int ifindex, char **clientid) {
 +        return network_get_file_str("CLIENTID",
 +                                    "/run/systemd/netif/leases",
 +                                    ifindex,
 +                                    clientid);
 +}
 +
 +_public_ int sd_network_link_get_iaid(int ifindex, char **iaid) {
 +        return network_get_file_str("IAID",
 +                                    "/run/systemd/netif/leases6",
 +                                    ifindex,
 +                                    iaid);
 +}
 +
 +_public_ int sd_network_link_get_duid(int ifindex, char **duid) {
 +        return network_get_file_str("DUID",
 +                                    "/run/systemd/netif/leases6",
 +                                    ifindex,
 +                                    duid);
 +}
 +
99ffaade
  static inline int MONITOR_TO_FD(sd_network_monitor *m) {
          return (int) (unsigned long) m - 1;
  }
 diff -rup systemd-232/src/libsystemd-network/dhcp6-lease-internal.h systemd-232-new/src/libsystemd-network/dhcp6-lease-internal.h
 --- systemd-232/src/libsystemd-network/dhcp6-lease-internal.h	2016-11-03 10:16:42.000000000 -0700
 +++ systemd-232-new/src/libsystemd-network/dhcp6-lease-internal.h	2016-11-18 11:51:58.231165060 -0800
 @@ -23,7 +23,7 @@
91e03b4b
  #include <stdint.h>
  
  #include "sd-dhcp6-lease.h"
99ffaade
 -
91e03b4b
 +#include "dhcp-identifier.h"
  #include "dhcp6-internal.h"
  
  struct sd_dhcp6_lease {
99ffaade
 @@ -35,6 +35,8 @@ struct sd_dhcp6_lease {
91e03b4b
          bool rapid_commit;
  
          DHCP6IA ia;
 +        struct duid *duid;
 +        size_t duid_len;
  
          DHCP6Address *addr_iter;
  
99ffaade
 @@ -63,6 +65,7 @@ int dhcp6_lease_set_rapid_commit(sd_dhcp
91e03b4b
  int dhcp6_lease_get_rapid_commit(sd_dhcp6_lease *lease, bool *rapid_commit);
  
  int dhcp6_lease_get_iaid(sd_dhcp6_lease *lease, be32_t *iaid);
 +int dhcp6_lease_set_duid(sd_dhcp6_lease *lease, struct duid *duid, size_t duid_len);
  
  int dhcp6_lease_set_dns(sd_dhcp6_lease *lease, uint8_t *optval, size_t optlen);
  int dhcp6_lease_set_domains(sd_dhcp6_lease *lease, uint8_t *optval,
99ffaade
 @@ -72,3 +75,4 @@ int dhcp6_lease_set_sntp(sd_dhcp6_lease
                           size_t optlen) ;
91e03b4b
  
  int dhcp6_lease_new(sd_dhcp6_lease **ret);
 +int dhcp6_lease_save(sd_dhcp6_lease *lease, const char *lease_file);
99ffaade
 diff -rup systemd-232/src/libsystemd-network/sd-dhcp6-client.c systemd-232-new/src/libsystemd-network/sd-dhcp6-client.c
 --- systemd-232/src/libsystemd-network/sd-dhcp6-client.c	2016-11-03 10:16:42.000000000 -0700
 +++ systemd-232-new/src/libsystemd-network/sd-dhcp6-client.c	2016-11-18 11:56:00.967159576 -0800
 @@ -222,6 +222,23 @@ int sd_dhcp6_client_set_duid(
91e03b4b
          return 0;
  }
  
 +int sd_dhcp6_client_get_duid(sd_dhcp6_client *client, uint16_t *duid_type,
 +                             const uint8_t **duid, size_t *duid_len) {
 +        assert_return(client, -EINVAL);
 +        assert_return(IN_SET(client->state, DHCP6_STATE_STOPPED), -EBUSY);
 +
 +        *duid_type = 0;
 +        *duid_len = 0;
 +        *duid = NULL;
 +        if (client->duid_len > 0) {
 +                *duid_type = be16toh(client->duid.type);
 +                *duid_len = client->duid_len - sizeof(client->duid.type);
 +                *duid = client->duid.raw.data;
 +        }
 +
 +        return 0;
 +}
 +
  int sd_dhcp6_client_set_iaid(sd_dhcp6_client *client, uint32_t iaid) {
          assert_return(client, -EINVAL);
          assert_return(IN_SET(client->state, DHCP6_STATE_STOPPED), -EBUSY);
99ffaade
 @@ -231,6 +248,14 @@ int sd_dhcp6_client_set_iaid(sd_dhcp6_cl
91e03b4b
          return 0;
  }
  
 +int sd_dhcp6_client_get_iaid(sd_dhcp6_client *client, uint32_t *iaid) {
 +        assert_return(client, -EINVAL);
 +
 +        *iaid = be32toh(client->ia_na.id);
 +
 +        return 0;
 +}
 +
  int sd_dhcp6_client_set_information_request(sd_dhcp6_client *client, int enabled) {
          assert_return(client, -EINVAL);
          assert_return(IN_SET(client->state, DHCP6_STATE_STOPPED), -EBUSY);
99ffaade
 @@ -777,6 +802,10 @@ static int client_parse_message(
91e03b4b
                          if (r < 0 && r != -ENOMSG)
                                  return r;
  
 +                        r = dhcp6_lease_set_duid(lease, &client->duid, client->duid_len);
 +                        if (r < 0)
 +                                return r;
 +
                          r = dhcp6_lease_get_iaid(lease, &iaid_lease);
                          if (r < 0)
                                  return r;
99ffaade
 diff -rup systemd-232/src/libsystemd-network/sd-dhcp6-lease.c systemd-232-new/src/libsystemd-network/sd-dhcp6-lease.c
 --- systemd-232/src/libsystemd-network/sd-dhcp6-lease.c	2016-11-03 10:16:42.000000000 -0700
 +++ systemd-232-new/src/libsystemd-network/sd-dhcp6-lease.c	2016-11-18 11:58:53.619155676 -0800
 @@ -18,11 +18,15 @@
91e03b4b
    along with systemd; If not, see <http://www.gnu.org/licenses/>.
  ***/
  
 +#include <arpa/inet.h>
  #include <errno.h>
  
  #include "alloc-util.h"
  #include "dhcp6-lease-internal.h"
  #include "dhcp6-protocol.h"
 +#include "fd-util.h"
 +#include "fileio.h"
 +#include "hexdecoct.h"
  #include "strv.h"
  #include "util.h"
  
99ffaade
 @@ -148,6 +152,15 @@ int dhcp6_lease_get_iaid(sd_dhcp6_lease
91e03b4b
          return 0;
  }
  
 +int dhcp6_lease_set_duid(sd_dhcp6_lease *lease, struct duid *duid, size_t duid_len) {
 +        assert_return(lease, -EINVAL);
 +        assert_return(duid, -EINVAL);
 +
 +        lease->duid = duid;
 +        lease->duid_len = duid_len;
 +        return 0;
 +}
 +
  int sd_dhcp6_lease_get_address(sd_dhcp6_lease *lease, struct in6_addr *addr,
                                 uint32_t *lifetime_preferred,
                                 uint32_t *lifetime_valid) {
99ffaade
 @@ -406,3 +419,74 @@ int dhcp6_lease_new(sd_dhcp6_lease **ret
91e03b4b
          *ret = lease;
          return 0;
  }
 +
 +int dhcp6_lease_save(sd_dhcp6_lease *lease, const char *lease_file) {
 +        _cleanup_free_ char *temp_path = NULL;
 +        _cleanup_fclose_ FILE *f = NULL;
 +        char addr6[INET6_ADDRSTRLEN];
 +        const char *paddr6;
 +        struct in6_addr ip6_addr;
 +        uint32_t lifetime_preferred, lifetime_valid;
 +        be32_t iaid_lease;
 +        const struct in6_addr *addresses;
 +        int r;
 +
 +        assert(lease);
 +        assert(lease_file);
 +
 +        r = fopen_temporary(lease_file, &f, &temp_path);
 +        if (r < 0)
 +                goto fail;
 +
 +        fchmod(fileno(f), 0644);
 +
 +        fprintf(f, "# This is private data. Do not parse.\n");
 +
 +        sd_dhcp6_lease_reset_address_iter(lease);
 +        do {
 +                r = sd_dhcp6_lease_get_address(lease, &ip6_addr,
 +                                               &lifetime_preferred,
 +                                               &lifetime_valid);
 +                if (r >= 0) {
 +                        paddr6 = inet_ntop(AF_INET6, &ip6_addr, addr6,
 +                                           INET6_ADDRSTRLEN);
 +                        if (paddr6 != NULL) {
 +                                fprintf(f, "ADDRESS=%s\n", paddr6);
 +                                fprintf(f, "LIFETIME_PREFERRED=%u\n", lifetime_preferred);
 +                                fprintf(f, "LIFETIME_VALID=%u\n", lifetime_valid);
 +                        }
 +                }
 +        } while (r >=0);
 +
 +        r = dhcp6_lease_get_iaid(lease, &iaid_lease);
 +        if (r == 0)
 +                fprintf(f, "IAID=%u\n", be32toh(iaid_lease));
 +
 +        if (lease->duid_len > 0) {
 +                _cleanup_free_ char *duid_hex;
 +
 +                duid_hex = hexmem(lease->duid, lease->duid_len);
 +                if (duid_hex == NULL) {
 +                        r = -ENOMEM;
 +                        goto fail;
 +                }
 +                fprintf(f, "DUID=%s\n", duid_hex);
 +        }
 +
 +        r = fflush_and_check(f);
 +        if (r < 0)
 +                goto fail;
 +
 +        if (rename(temp_path, lease_file) < 0) {
 +                r = -errno;
 +                goto fail;
 +        }
 +
 +        return 0;
 +
 +fail:
 +        if (temp_path)
 +                (void) unlink(temp_path);
 +
 +        return log_error_errno(r, "Failed to save lease data %s: %m", lease_file);
 +}
99ffaade
 diff -rup systemd-232/src/network/networkctl.c systemd-232-new/src/network/networkctl.c
 --- systemd-232/src/network/networkctl.c	2016-11-03 10:16:42.000000000 -0700
 +++ systemd-232-new/src/network/networkctl.c	2016-11-18 12:03:23.539149579 -0800
 @@ -700,6 +700,7 @@ static int link_status_one(
  
          _cleanup_strv_free_ char **dns = NULL, **ntp = NULL, **search_domains = NULL, **route_domains = NULL;
91e03b4b
          _cleanup_free_ char *setup_state = NULL, *operational_state = NULL, *tz = NULL;
 +        _cleanup_free_ char *clientid = NULL, *duid = NULL, *iaid = NULL;
99ffaade
          _cleanup_(sd_device_unrefp) sd_device *d = NULL;
91e03b4b
          char devid[2 + DECIMAL_STR_MAX(int)];
99ffaade
          _cleanup_free_ char *t = NULL, *network = NULL;
 @@ -802,6 +803,18 @@ static int link_status_one(
91e03b4b
          if (tz)
99ffaade
                  printf("       Time Zone: %s\n", tz);
  
 +        (void) sd_network_link_get_clientid(info->ifindex, &clientid);
91e03b4b
 +        if (clientid)
 +                printf("        CLIENTID: %s\n", clientid);
 +
99ffaade
 +        (void) sd_network_link_get_iaid(info->ifindex, &iaid);
91e03b4b
 +        if (iaid)
 +                printf("            IAID: %s\n", iaid);
 +
99ffaade
 +        (void) sd_network_link_get_duid(info->ifindex, &duid);
91e03b4b
 +        if (duid)
99ffaade
 +                printf("            DUID: %s\n", duid);
 +
          (void) dump_lldp_neighbors("    Connected To: ", info->ifindex);
91e03b4b
  
          return 0;
99ffaade
 diff -rup systemd-232/src/network/networkd.c systemd-232-new/src/network/networkd.c
 --- systemd-232/src/network/networkd.c	2016-11-03 10:16:42.000000000 -0700
 +++ systemd-232-new/src/network/networkd.c	2016-11-18 12:15:34.639133063 -0800
 @@ -64,6 +64,10 @@ int main(int argc, char *argv[]) {
          if (r < 0)
                  log_warning_errno(r, "Could not create runtime directory 'leases': %m");
  
 +        r = mkdir_safe_label("/run/systemd/netif/leases6", 0755, uid, gid);
 +        if (r < 0)
 +                log_warning_errno(r, "Could not create runtime directory 'leases6': %m");
 +
          r = mkdir_safe_label("/run/systemd/netif/lldp", 0755, uid, gid);
          if (r < 0)
                  log_warning_errno(r, "Could not create runtime directory 'lldp': %m");
 diff -rup systemd-232/src/network/networkd-dhcp6.c systemd-232-new/src/network/networkd-dhcp6.c
 --- systemd-232/src/network/networkd-dhcp6.c	2016-11-03 10:16:42.000000000 -0700
 +++ systemd-232-new/src/network/networkd-dhcp6.c	2016-11-18 12:07:42.279143734 -0800
 @@ -115,6 +115,7 @@ static int dhcp6_lease_address_acquired(
                  if (r < 0)
91e03b4b
                          return r;
          }
 +        link->dhcp6_lease = sd_dhcp6_lease_ref(lease);
99ffaade
  
91e03b4b
          return 0;
  }
99ffaade
 @@ -137,7 +138,9 @@ static void dhcp6_handler(sd_dhcp6_clien
91e03b4b
                  if (sd_dhcp6_client_get_lease(client, NULL) >= 0)
                          log_link_warning(link, "DHCPv6 lease lost");
  
 +                link->dhcp6_lease = sd_dhcp6_lease_unref(link->dhcp6_lease);
                  link->dhcp6_configured = false;
 +                link_dirty(link);
                  break;
  
          case SD_DHCP6_CLIENT_EVENT_IP_ACQUIRE:
99ffaade
 @@ -156,6 +159,7 @@ static void dhcp6_handler(sd_dhcp6_clien
91e03b4b
                  }
  
                  link->dhcp6_configured = true;
 +                link_dirty(link);
                  break;
  
          default:
99ffaade
 diff -rup systemd-232/src/network/networkd-link.c systemd-232-new/src/network/networkd-link.c
 --- systemd-232/src/network/networkd-link.c	2016-11-03 10:16:42.000000000 -0700
 +++ systemd-232-new/src/network/networkd-link.c	2016-11-18 12:13:35.631135751 -0800
 @@ -24,6 +24,7 @@
91e03b4b
  #include "alloc-util.h"
  #include "bus-util.h"
  #include "dhcp-lease-internal.h"
 +#include "dhcp6-lease-internal.h"
  #include "fd-util.h"
  #include "fileio.h"
99ffaade
  #include "netlink-util.h"
 @@ -459,6 +460,9 @@ static int link_new(Manager *manager, sd
          if (asprintf(&link->lease_file, "/run/systemd/netif/leases/%d", link->ifindex) < 0)
91e03b4b
                  return -ENOMEM;
  
99ffaade
 +        if (asprintf(&link->lease6_file, "/run/systemd/netif/leases6/%d", link->ifindex) < 0)
91e03b4b
 +                return -ENOMEM;
 +
99ffaade
          if (asprintf(&link->lldp_file, "/run/systemd/netif/lldp/%d", link->ifindex) < 0)
                  return -ENOMEM;
  
 @@ -506,10 +510,12 @@ static void link_free(Link *link) {
91e03b4b
          sd_dhcp_server_unref(link->dhcp_server);
          sd_dhcp_client_unref(link->dhcp_client);
          sd_dhcp_lease_unref(link->dhcp_lease);
 +        sd_dhcp_lease_unref(link->dhcp6_lease);
  
99ffaade
          link_lldp_emit_stop(link);
  
91e03b4b
          free(link->lease_file);
 +        free(link->lease6_file);
  
99ffaade
          sd_lldp_unref(link->lldp);
          free(link->lldp_file);
 @@ -3216,6 +3222,7 @@ int link_save(Link *link) {
91e03b4b
          assert(link);
          assert(link->state_file);
          assert(link->lease_file);
 +        assert(link->lease6_file);
          assert(link->manager);
  
          if (link->state == LINK_STATE_LINGER) {
99ffaade
 @@ -3461,6 +3468,31 @@ int link_save(Link *link) {
91e03b4b
          } else
                  unlink(link->lease_file);
  
 +        if (link->dhcp6_lease) {
 +                struct in6_addr addr6;
 +                uint32_t lp, lv;
 +                assert(link->network);
 +
 +                fputs("DHCP6_ADDRESS=", f);
 +
 +                sd_dhcp6_lease_reset_address_iter(link->dhcp6_lease);
 +                while (sd_dhcp6_lease_get_address(link->dhcp6_lease,
 +                                                  &addr6, &lp, &lv) >= 0) {
 +                        serialize_in6_addrs(f, &addr6, 1);
 +                        fputc(' ', f);
 +                }
 +                fputc('\n', f);
 +
 +                r = dhcp6_lease_save(link->dhcp6_lease, link->lease6_file);
 +                if (r < 0)
 +                        goto fail;
 +
 +                fprintf(f,
 +                        "DHCP6_LEASE=%s\n",
 +                        link->lease6_file);
 +        } else
 +                unlink(link->lease6_file);
 +
          if (link->ipv4ll) {
                  struct in_addr address;
  
99ffaade
 diff -rup systemd-232/src/network/networkd-link.h systemd-232-new/src/network/networkd-link.h
 --- systemd-232/src/network/networkd-link.h	2016-11-03 10:16:42.000000000 -0700
 +++ systemd-232-new/src/network/networkd-link.h	2016-11-18 12:14:27.359134583 -0800
 @@ -95,6 +95,7 @@ typedef struct Link {
91e03b4b
          sd_dhcp_client *dhcp_client;
          sd_dhcp_lease *dhcp_lease;
          char *lease_file;
 +        char *lease6_file;
          uint16_t original_mtu;
          unsigned dhcp4_messages;
          bool dhcp4_configured;
99ffaade
 @@ -118,6 +119,7 @@ typedef struct Link {
          Set *ndisc_dnssl;
91e03b4b
  
          sd_dhcp6_client *dhcp6_client;
 +        sd_dhcp6_lease *dhcp6_lease;
          bool rtnl_extended_attrs;
  
99ffaade
          /* This is about LLDP reception */
 diff -rup systemd-232/src/systemd/sd-dhcp6-client.h systemd-232-new/src/systemd/sd-dhcp6-client.h
 --- systemd-232/src/systemd/sd-dhcp6-client.h	2016-11-03 10:16:42.000000000 -0700
 +++ systemd-232-new/src/systemd/sd-dhcp6-client.h	2016-11-18 12:17:27.783130507 -0800
 @@ -98,9 +98,17 @@ int sd_dhcp6_client_set_duid(
                  uint16_t duid_type,
                  const void *duid,
                  size_t duid_len);
 +int sd_dhcp6_client_get_duid(
 +                sd_dhcp6_client *client, 
 +                uint16_t *duid_type,
 +                const uint8_t **duid, 
 +                size_t *duid_len);
  int sd_dhcp6_client_set_iaid(
                  sd_dhcp6_client *client,
                  uint32_t iaid);
 +int sd_dhcp6_client_get_iaid(
 +                sd_dhcp6_client *client, 
 +                uint32_t *iaid);
  int sd_dhcp6_client_set_information_request(
                  sd_dhcp6_client *client,
                  int enabled);
 diff -rup systemd-232/src/systemd/sd-network.h systemd-232-new/src/systemd/sd-network.h
 --- systemd-232/src/systemd/sd-network.h	2016-11-03 10:16:42.000000000 -0700
 +++ systemd-232-new/src/systemd/sd-network.h	2016-11-18 12:18:31.199129074 -0800
 @@ -145,6 +145,15 @@ int sd_network_link_get_carrier_bound_to
91e03b4b
  /* Get the CARRIERS that are bound to current link. */
99ffaade
  int sd_network_link_get_carrier_bound_by(int ifindex, int **ifindexes);
91e03b4b
  
 +/* Get the CLIENTID if the link has a IPv4 DHCP address. */
 +int sd_network_link_get_clientid(int ifindex, char **clientid);
 +
 +/* Get the IAID if the link has a IPv6 DHCP address. */
 +int sd_network_link_get_iaid(int ifindex, char **iaid);
 +
 +/* Get the DUID if the link has a IPv6 DHCP address. */
 +int sd_network_link_get_duid(int ifindex, char **duid);
 +
  /* Get the timezone that was learnt on a specific link. */
  int sd_network_link_get_timezone(int ifindex, char **timezone);