Detect IPv6 settings per interface if the platform allows, fixed #241.
free(iface->state->offer);
iface->state->offer = NULL;
- if (options & DHCPCD_IPV6RS && ifo->options & DHCPCD_IPV6RS)
- ipv6rs_start(iface);
+ if (options & DHCPCD_IPV6RS && ifo->options & DHCPCD_IPV6RS) {
+ if (check_ipv6(iface->name) == 1)
+ ipv6rs_start(iface);
+ else
+ ifo->options &= ~DHCPCD_IPV6RS;
+ }
if (iface->state->arping_index < ifo->arping_len) {
start_arping(iface);
}
#endif
- if (options & DHCPCD_IPV6RS && !check_ipv6())
+ if (options & DHCPCD_IPV6RS && !check_ipv6(NULL))
options &= ~DHCPCD_IPV6RS;
if (options & DHCPCD_IPV6RS) {
ipv6rsfd = ipv6rs_open();
}
int
-check_ipv6(void)
+check_ipv6(const char *ifname)
{
+ /* BSD doesn't support these values per iface, so just reutrn 1 */
+ if (ifname)
+ return 1;
+
if (inet6_sysctl(IPV6CTL_ACCEPT_RTADV) != 1) {
syslog(LOG_WARNING,
"Kernel is not configured to accept IPv6 RAs");
return atoi(buf);
}
+static const char *prefix = "/proc/sys/net/ipv6/conf";
+
int
-check_ipv6(void)
+check_ipv6(const char *ifname)
{
+ int r;
+ char path[256];
+
+ if (ifname == NULL)
+ ifname = "all";
- if (check_proc_int("/proc/sys/net/ipv6/conf/all/accept_ra") != 1) {
+ snprintf(path, sizeof(path), "%s/%s/accept_ra", prefix, ifname);
+ r = check_proc_int(path);
+ if (r != 1 && r != 2) {
syslog(LOG_WARNING,
- "Kernel is not configured to accept IPv6 RAs");
+ "%s: not configured to accept IPv6 RAs", ifname);
return 0;
}
- if (check_proc_int("/proc/sys/net/ipv6/conf/all/forwarding") != 0) {
- syslog(LOG_WARNING,
- "Kernel is configured as a router, not a host");
- return 0;
+
+ if (r != 2) {
+ snprintf(path, sizeof(path), "%s/%s/forwarding",
+ prefix, ifname);
+ if (check_proc_int(path) != 0) {
+ syslog(LOG_WARNING,
+ "%s: configured as a router, not a host", ifname);
+ return 0;
+ }
}
return 1;
}
#ifndef PLATFORM_H
#define PLATFORM_H
-char * hardware_platform(void);
-int check_ipv6(void);
+char *hardware_platform(void);
+int check_ipv6(const char *);
#endif