I don't think we need a knob for this, doing it per default if we
have the source link layer address should be fine.
See RFC 7772 why this is a good thing.
OK?
diff --git rtadvd.c rtadvd.c
index 1f470a06c31..219b357e50b 100644
--- rtadvd.c
+++ rtadvd.c
@@ -141,7 +141,7 @@ static int prefix_check(struct nd_opt_prefix_info *, struct
rainfo *,
static int nd6_options(struct nd_opt_hdr *, int,
union nd_opts *, u_int32_t);
static void free_ndopts(union nd_opts *);
-static void ra_output(struct rainfo *);
+static void ra_output(struct rainfo *, struct sockaddr_in6 *);
static struct rainfo *if_indextorainfo(int);
static int rdaemon(int);
@@ -293,7 +293,7 @@ die_cb(int sig, short event, void *arg)
}
for (i = 0; i < retrans; i++) {
SLIST_FOREACH(ra, &ralist, entry)
- ra_output(ra);
+ ra_output(ra, &sin6_allnodes);
sleep(MIN_DELAY_BETWEEN_RAS);
}
exit(0);
@@ -651,11 +651,13 @@ rs_input(int len, struct nd_router_solicit *rs,
ra->rsinput++; /* increment statistics */
- /*
- * Decide whether to send RA according to the rate-limit
- * consideration.
- */
- {
+ if (ndopts.nd_opts_src_lladdr)
+ ra_output(ra, from);
+ else {
+ /*
+ * Decide whether to send RA according to the rate-limit
+ * consideration.
+ */
long delay; /* must not be greater than 1000000 */
struct timeval interval, now, min_delay, tm_tmp, next,
computed;
@@ -1038,6 +1040,8 @@ nd6_options(struct nd_opt_hdr *hdr, int limit,
switch (hdr->nd_opt_type) {
case ND_OPT_SOURCE_LINKADDR:
+ ndopts->nd_opt_array[hdr->nd_opt_type] = hdr;
+ break;
case ND_OPT_TARGET_LINKADDR:
case ND_OPT_REDIRECTED_HEADER:
case ND_OPT_ROUTE_INFO:
@@ -1212,7 +1216,7 @@ if_indextorainfo(int index)
}
static void
-ra_output(struct rainfo *rainfo)
+ra_output(struct rainfo *rainfo, struct sockaddr_in6 *to)
{
struct cmsghdr *cm;
struct in6_pktinfo *pi;
@@ -1225,7 +1229,7 @@ ra_output(struct rainfo *rainfo)
make_packet(rainfo); /* XXX: inefficient */
- sndmhdr.msg_name = &sin6_allnodes;
+ sndmhdr.msg_name = to;
sndmhdr.msg_iov[0].iov_base = rainfo->ra_data;
sndmhdr.msg_iov[0].iov_len = rainfo->ra_datalen;
@@ -1263,11 +1267,13 @@ ra_output(struct rainfo *rainfo)
rainfo->initcounter++;
rainfo->raoutput++;
- /* update timestamp */
- gettimeofday(&rainfo->lastsent, NULL);
+ if (memcmp(to, &sin6_allnodes, sizeof(sin6_allnodes)) == 0) {
+ /* update timestamp */
+ gettimeofday(&rainfo->lastsent, NULL);
- /* reset waiting counter */
- rainfo->waiting = 0;
+ /* reset waiting counter */
+ rainfo->waiting = 0;
+ }
}
/* process RA timer */
@@ -1278,7 +1284,7 @@ timer_cb(int fd, short event, void *data)
log_debug("RA timer on %s is expired", rai->ifname);
- ra_output(rai);
+ ra_output(rai, &sin6_allnodes);
ra_timer_update(rai);
evtimer_add(&rai->timer.ev, &rai->timer.tm);
--
I'm not entirely sure you are real.