summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIlya Ponetaev <iponetaev@dlink.ru>2014-09-09 12:46:21 +0100
committerSimon Kelley <simon@thekelleys.org.uk>2014-09-09 12:46:21 +0100
commit5bf50af2d028325518fcba049d705832d2991eac (patch)
tree994862a88297778b1c6fc3da66a0a9d70775f394
parentc43b8a63260d3c974ae33328c81cd73c5e0d9474 (diff)
downloaddnsmasq-5bf50af2d028325518fcba049d705832d2991eac.tar.gz
RFC4191 route information option.
-rw-r--r--CHANGELOG4
-rw-r--r--src/radv-protocol.h1
-rw-r--r--src/radv.c51
3 files changed, 44 insertions, 12 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 62f2e4a..d709adf 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -27,6 +27,10 @@ version 2.72
servers which loop back are disabled and this event is logged.
Thanks to Smoothwall for their sponsorship of this feature.
+ Include an RFC4191 route information option in router
+ advertisements for the prefix we're advertising. Thanks to
+ Ilya Ponetaev for the patch.
+
version 2.71
Subtle change to error handling to help DNSSEC validation
diff --git a/src/radv-protocol.h b/src/radv-protocol.h
index e576012..72ccda4 100644
--- a/src/radv-protocol.h
+++ b/src/radv-protocol.h
@@ -50,6 +50,7 @@ struct prefix_opt {
#define ICMP6_OPT_PREFIX 3
#define ICMP6_OPT_MTU 5
#define ICMP6_OPT_ADV_INTERVAL 7
+#define ICMP6_OPT_RT_INFO 24
#define ICMP6_OPT_RDNSS 25
#define ICMP6_OPT_DNSSL 31
diff --git a/src/radv.c b/src/radv.c
index f5b517b..87ddfae 100644
--- a/src/radv.c
+++ b/src/radv.c
@@ -32,7 +32,7 @@ struct ra_param {
char *if_name;
struct dhcp_netid *tags;
struct in6_addr link_local, link_global, ula;
- unsigned int glob_pref_time, link_pref_time, ula_pref_time, adv_interval;
+ unsigned int glob_pref_time, link_pref_time, ula_pref_time, adv_interval, prio;
};
struct search_param {
@@ -210,18 +210,7 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de
#ifdef HAVE_LINUX_NETWORK
FILE *f;
#endif
-
- save_counter(0);
- ra = expand(sizeof(struct ra_packet));
- ra->type = ND_ROUTER_ADVERT;
- ra->code = 0;
- ra->hop_limit = hop_limit;
- ra->flags = calc_prio(ra_param);
- ra->lifetime = htons(calc_lifetime(ra_param));
- ra->reachable_time = 0;
- ra->retrans_time = 0;
-
parm.ind = iface;
parm.managed = 0;
parm.other = 0;
@@ -232,7 +221,19 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de
parm.now = now;
parm.glob_pref_time = parm.link_pref_time = parm.ula_pref_time = 0;
parm.adv_interval = calc_interval(ra_param);
+ parm.prio = calc_prio(ra_param);
+
+ save_counter(0);
+ ra = expand(sizeof(struct ra_packet));
+ ra->type = ND_ROUTER_ADVERT;
+ ra->code = 0;
+ ra->hop_limit = hop_limit;
+ ra->flags = parm.prio;
+ ra->lifetime = htons(calc_lifetime(ra_param));
+ ra->reachable_time = 0;
+ ra->retrans_time = 0;
+
/* set tag with name == interface */
iface_id.net = iface_name;
iface_id.next = NULL;
@@ -648,6 +649,32 @@ static int add_prefixes(struct in6_addr *local, int prefix,
inet_ntop(AF_INET6, local, daemon->addrbuff, ADDRSTRLEN);
if (!option_bool(OPT_QUIET_RA))
my_syslog(MS_DHCP | LOG_INFO, "RTR-ADVERT(%s) %s", param->if_name, daemon->addrbuff);
+
+ /* Send Route Information option (RFC4191, 2.3) */
+ put_opt6_char(ICMP6_OPT_RT_INFO);
+ /* Length in units of 8 octets will be 1 (header) +
+ * 0, 1 or 2 (0...128 bits / 64 bit per unit) */
+ if (0 == prefix)
+ put_opt6_char(1);
+ else if (prefix < 65)
+ put_opt6_char(2);
+ else
+ put_opt6_char(3);
+
+ put_opt6_char(prefix);
+ /* Same priority and advertised prefix */
+ put_opt6_char(param->prio);
+ /* "valid lifetime" seems more reasonable than "preferred" */
+ put_opt6_long(valid);
+ /* Actual prefix, only necessary part
+ * Don't append any data in case of prefix length == 0 */
+ if (0 != prefix)
+ {
+ if (prefix < 65)
+ put_opt6((void *)local, 8);
+ else
+ put_opt6((void *)local, 16);
+ }
}
}
}