chiark / gitweb /
sd-icmp6-nd: Add support for fetching the latest expired prefix
authorPatrik Flykt <patrik.flykt@linux.intel.com>
Tue, 20 Jan 2015 17:36:03 +0000 (19:36 +0200)
committerPatrik Flykt <patrik.flykt@linux.intel.com>
Tue, 27 Jan 2015 07:35:24 +0000 (09:35 +0200)
Keep the expired prefix for the duration of the prefix expiration event
and remove it afterwards.

src/libsystemd-network/sd-icmp6-nd.c
src/systemd/sd-icmp6-nd.h

index eb00b1a..2f867e8 100644 (file)
@@ -65,6 +65,7 @@ struct sd_icmp6_nd {
         int index;
         struct ether_addr mac_addr;
         uint32_t mtu;
+        ICMP6Prefix *expired_prefix;
         LIST_HEAD(ICMP6Prefix, prefixes);
         int fd;
         sd_event_source *recv;
@@ -266,8 +267,11 @@ static int icmp6_ra_prefix_timeout(sd_event_source *s, uint64_t usec,
 
                 LIST_REMOVE(prefixes, nd->prefixes, prefix);
 
+                nd->expired_prefix = prefix;
                 icmp6_nd_notify(nd,
                                 ICMP6_EVENT_ROUTER_ADVERTISMENT_PREFIX_EXPIRED);
+                nd->expired_prefix = NULL;
+
                 prefix = icmp6_prefix_unref(prefix);
 
                 break;
@@ -372,6 +376,22 @@ int sd_icmp6_ra_get_prefixlen(sd_icmp6_nd *nd, const struct in6_addr *addr,
         return 0;
 }
 
+int sd_icmp6_ra_get_expired_prefix(sd_icmp6_nd *nd, struct in6_addr **addr,
+                                uint8_t *prefixlen)
+{
+        assert_return(nd, -EINVAL);
+        assert_return(addr, -EINVAL);
+        assert_return(prefixlen, -EINVAL);
+
+        if (!nd->expired_prefix)
+                return -EADDRNOTAVAIL;
+
+        *addr = &nd->expired_prefix->addr;
+        *prefixlen = nd->expired_prefix->len;
+
+        return 0;
+}
+
 static int icmp6_ra_prefix_update(sd_icmp6_nd *nd, ssize_t len,
                                   const struct nd_opt_prefix_info *prefix_opt) {
         int r;
index 86cf25a..79b4074 100644 (file)
@@ -58,6 +58,8 @@ int sd_icmp6_prefix_match(struct in6_addr *prefix, uint8_t prefixlen,
 int sd_icmp6_ra_get_mtu(sd_icmp6_nd *nd, uint32_t *mtu);
 int sd_icmp6_ra_get_prefixlen(sd_icmp6_nd *nd, const struct in6_addr *addr,
                         uint8_t *prefixlen);
+int sd_icmp6_ra_get_expired_prefix(sd_icmp6_nd *nd, struct in6_addr **addr,
+                                uint8_t *prefixlen);
 
 int sd_icmp6_nd_stop(sd_icmp6_nd *nd);
 int sd_icmp6_router_solicitation_start(sd_icmp6_nd *nd);