Skip to content

Commit 7745034

Browse files
authored
Add route lifetime from Router Advertisement (#429)
Currently this is only for Linux and is fairly cosmetic as dhcpcd will clean up expired routes itself as other OS's don't support route lifetimes.
1 parent 2568932 commit 7745034

File tree

5 files changed

+37
-0
lines changed

5 files changed

+37
-0
lines changed

src/common.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838

3939
#include "common.h"
4040
#include "dhcpcd.h"
41+
#include "eloop.h"
4142
#include "if-options.h"
4243

4344
const char *
@@ -214,3 +215,18 @@ is_root_local(void)
214215
return -1;
215216
#endif
216217
}
218+
219+
uint32_t
220+
lifetime_left(uint32_t lifetime, const struct timespec *acquired, const struct timespec *now)
221+
{
222+
uint32_t elapsed;
223+
224+
if (lifetime == INFINITE_LIFETIME)
225+
return lifetime;
226+
227+
elapsed = (uint32_t)eloop_timespec_diff(now, acquired, NULL);
228+
if (elapsed > lifetime)
229+
return 0;
230+
231+
return lifetime - elapsed;
232+
}

src/common.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,11 +141,14 @@
141141
# endif
142142
#endif
143143

144+
#define INFINITE_LIFETIME (~0U)
145+
144146
const char *hwaddr_ntoa(const void *, size_t, char *, size_t);
145147
size_t hwaddr_aton(uint8_t *, const char *);
146148
ssize_t readfile(const char *, void *, size_t);
147149
ssize_t writefile(const char *, mode_t, const void *, size_t);
148150
int filemtime(const char *, time_t *);
149151
char *get_line(char ** __restrict, ssize_t * __restrict);
150152
int is_root_local(void);
153+
uint32_t lifetime_left(uint32_t, const struct timespec *, const struct timespec *);
151154
#endif

src/if-linux.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,11 @@ if_copyrt(struct dhcpcd_ctx *ctx, struct rt *rt, struct nlmsghdr *nlm)
752752
}
753753
break;
754754
}
755+
case RTA_EXPIRES:
756+
{
757+
rt->rt_expires = *(uint32_t *)RTA_DATA(rta);
758+
break;
759+
}
755760
}
756761

757762
if (sa != NULL) {
@@ -1735,6 +1740,10 @@ if_route(unsigned char cmd, const struct rt *rt)
17351740
if (!sa_is_loopback(&rt->rt_gateway))
17361741
add_attr_32(&nlm.hdr, sizeof(nlm), RTA_OIF, rt->rt_ifp->index);
17371742

1743+
/* add route lifetime */
1744+
if (rt->rt_expires != 0)
1745+
add_attr_32(&nlm.hdr, sizeof(nlm), RTA_EXPIRES, rt->rt_expires);
1746+
17381747
if (rt->rt_metric != 0)
17391748
add_attr_32(&nlm.hdr, sizeof(nlm), RTA_PRIORITY,
17401749
rt->rt_metric);

src/ipv6.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2301,10 +2301,13 @@ inet6_raroutes(rb_tree_t *routes, struct dhcpcd_ctx *ctx)
23012301
const struct routeinfo *rinfo;
23022302
const struct ipv6_addr *addr;
23032303
struct in6_addr netmask;
2304+
struct timespec now;
23042305

23052306
if (ctx->ra_routers == NULL)
23062307
return 0;
23072308

2309+
clock_gettime(CLOCK_MONOTONIC, &now);
2310+
23082311
TAILQ_FOREACH(rap, ctx->ra_routers, next) {
23092312
if (rap->expired)
23102313
continue;
@@ -2325,6 +2328,7 @@ inet6_raroutes(rb_tree_t *routes, struct dhcpcd_ctx *ctx)
23252328
#ifdef HAVE_ROUTE_PREF
23262329
rt->rt_pref = ipv6nd_rtpref(rinfo->flags);
23272330
#endif
2331+
rt->rt_expires = lifetime_left(rinfo->lifetime, &rinfo->acquired, &now);
23282332

23292333
rt_proto_add(routes, rt);
23302334
}
@@ -2339,6 +2343,8 @@ inet6_raroutes(rb_tree_t *routes, struct dhcpcd_ctx *ctx)
23392343
#ifdef HAVE_ROUTE_PREF
23402344
rt->rt_pref = ipv6nd_rtpref(rap->flags);
23412345
#endif
2346+
rt->rt_expires = lifetime_left(addr->prefix_vltime, &addr->acquired, &now);
2347+
23422348
rt_proto_add(routes, rt);
23432349
}
23442350
}
@@ -2370,6 +2376,8 @@ inet6_raroutes(rb_tree_t *routes, struct dhcpcd_ctx *ctx)
23702376
#ifdef HAVE_ROUTE_PREF
23712377
rt->rt_pref = ipv6nd_rtpref(rap->flags);
23722378
#endif
2379+
rt->rt_expires = lifetime_left(rap->lifetime, &rap->acquired, &now);
2380+
23732381
rt_proto_add(routes, rt);
23742382
}
23752383
return 0;

src/route.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ struct rt {
120120
#define RTDF_GATELINK 0x40 /* Gateway is on link */
121121
size_t rt_order;
122122
rb_node_t rt_tree;
123+
uint32_t rt_expires; /* current lifetime of route */
123124
};
124125

125126
extern const rb_tree_ops_t rt_compare_list_ops;

0 commit comments

Comments
 (0)