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.

Reply via email to