summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--accel-pppd/extra/pppd_compat.c2
-rw-r--r--accel-pppd/ifcfg.c2
-rw-r--r--accel-pppd/ipdb.h1
-rw-r--r--accel-pppd/ipv6/dhcpv6.c2
-rw-r--r--accel-pppd/ipv6/nd.c44
5 files changed, 33 insertions, 18 deletions
diff --git a/accel-pppd/extra/pppd_compat.c b/accel-pppd/extra/pppd_compat.c
index 58581899..0ed88368 100644
--- a/accel-pppd/extra/pppd_compat.c
+++ b/accel-pppd/extra/pppd_compat.c
@@ -582,7 +582,7 @@ static void build_addr(struct ipv6db_addr_t *a, uint64_t intf_id, struct in6_add
if (a->prefix_len <= 64)
*(uint64_t *)(addr->s6_addr + 8) = intf_id;
else
- *(uint64_t *)(addr->s6_addr + 8) |= intf_id & ((1 << (128 - a->prefix_len)) - 1);
+ *(uint64_t *)(addr->s6_addr + 8) |= intf_id & htobe64((1 << (128 - a->prefix_len)) - 1);
}
static void fill_env(char **env, char *mem, struct pppd_compat_pd *pd)
diff --git a/accel-pppd/ifcfg.c b/accel-pppd/ifcfg.c
index 030b7438..b2cb0db3 100644
--- a/accel-pppd/ifcfg.c
+++ b/accel-pppd/ifcfg.c
@@ -52,7 +52,7 @@ static void devconf(struct ap_session *ses, const char *attr, const char *val)
if (a->prefix_len <= 64)
*(uint64_t *)(addr->s6_addr + 8) = intf_id;
else
- *(uint64_t *)(addr->s6_addr + 8) |= intf_id & ((1 << (128 - a->prefix_len)) - 1);
+ *(uint64_t *)(addr->s6_addr + 8) |= intf_id & htobe64((1 << (128 - a->prefix_len)) - 1);
}*/
void ap_session_ifup(struct ap_session *ses)
diff --git a/accel-pppd/ipdb.h b/accel-pppd/ipdb.h
index f2a6cee7..2565c924 100644
--- a/accel-pppd/ipdb.h
+++ b/accel-pppd/ipdb.h
@@ -17,6 +17,7 @@ struct ipv6db_addr_t
struct list_head entry;
struct in6_addr addr;
int prefix_len;
+ int flag_onlink:1;
int flag_auto:1;
int installed:1;
};
diff --git a/accel-pppd/ipv6/dhcpv6.c b/accel-pppd/ipv6/dhcpv6.c
index 9c31507a..d99165c6 100644
--- a/accel-pppd/ipv6/dhcpv6.c
+++ b/accel-pppd/ipv6/dhcpv6.c
@@ -169,7 +169,7 @@ static void build_addr(struct ipv6db_addr_t *a, uint64_t intf_id, struct in6_add
if (a->prefix_len <= 64)
*(uint64_t *)(addr->s6_addr + 8) = intf_id;
else
- *(uint64_t *)(addr->s6_addr + 8) |= intf_id & ((1 << (128 - a->prefix_len)) - 1);
+ *(uint64_t *)(addr->s6_addr + 8) |= intf_id & htobe64((1 << (128 - a->prefix_len)) - 1);
}
static void insert_dp_routes(struct ap_session *ses, struct dhcpv6_pd *pd)
diff --git a/accel-pppd/ipv6/nd.c b/accel-pppd/ipv6/nd.c
index 1d70ae95..f2a259ad 100644
--- a/accel-pppd/ipv6/nd.c
+++ b/accel-pppd/ipv6/nd.c
@@ -42,6 +42,7 @@ static int conf_AdvCurHopLimit = 64;
static int conf_AdvDefaultLifetime;
static int conf_AdvPrefixValidLifetime = 2592000;
static int conf_AdvPrefixPreferredLifetime = 604800;
+static int conf_AdvPrefixOnLinkFlag;
static int conf_AdvPrefixAutonomousFlag;
@@ -128,22 +129,30 @@ static void ipv6_nd_send_ra(struct ipv6_nd_handler_t *h, struct sockaddr_in6 *ad
pinfo = (struct nd_opt_prefix_info *)(adv + 1);
list_for_each_entry(a, &h->ses->ipv6->addr_list, entry) {
- memset(pinfo, 0, sizeof(*pinfo));
- pinfo->nd_opt_pi_type = ND_OPT_PREFIX_INFORMATION;
- pinfo->nd_opt_pi_len = 4;
- pinfo->nd_opt_pi_prefix_len = a->prefix_len;
- pinfo->nd_opt_pi_flags_reserved = ND_OPT_PI_FLAG_ONLINK |
- (a->flag_auto || (conf_AdvPrefixAutonomousFlag && a->prefix_len == 64)) ? ND_OPT_PI_FLAG_AUTO : 0;
- pinfo->nd_opt_pi_valid_time = htonl(conf_AdvPrefixValidLifetime);
- pinfo->nd_opt_pi_preferred_time = htonl(conf_AdvPrefixPreferredLifetime);
- memcpy(&pinfo->nd_opt_pi_prefix, &a->addr, 8);
- pinfo++;
+ if (a->prefix_len < 128) {
+ memset(pinfo, 0, sizeof(*pinfo));
+ pinfo->nd_opt_pi_type = ND_OPT_PREFIX_INFORMATION;
+ pinfo->nd_opt_pi_len = 4;
+ pinfo->nd_opt_pi_prefix_len = a->prefix_len;
+ pinfo->nd_opt_pi_flags_reserved =
+ ((a->flag_onlink || conf_AdvPrefixOnLinkFlag) ? ND_OPT_PI_FLAG_ONLINK : 0) |
+ ((a->flag_auto || (conf_AdvPrefixAutonomousFlag && a->prefix_len == 64)) ? ND_OPT_PI_FLAG_AUTO : 0);
+ pinfo->nd_opt_pi_valid_time = htonl(conf_AdvPrefixValidLifetime);
+ pinfo->nd_opt_pi_preferred_time = htonl(conf_AdvPrefixPreferredLifetime);
+ memcpy(&pinfo->nd_opt_pi_prefix, &a->addr, (a->prefix_len + 7) / 8);
+ pinfo->nd_opt_pi_prefix.s6_addr[a->prefix_len / 8] &= ~(0xff >> (a->prefix_len % 8));
+ pinfo++;
+ }
if (!a->installed) {
- struct in6_addr addr;
- memcpy(addr.s6_addr, &a->addr, 8);
- memcpy(addr.s6_addr + 8, &h->ses->ipv6->intf_id, 8);
- ip6addr_add(h->ses->ifindex, &addr, a->prefix_len);
+ if (a->prefix_len > 64)
+ ip6route_add(h->ses->ifindex, &a->addr, a->prefix_len, 0);
+ else {
+ struct in6_addr addr;
+ memcpy(addr.s6_addr, &a->addr, 8);
+ memcpy(addr.s6_addr + 8, &h->ses->ipv6->intf_id, 8);
+ ip6addr_add(h->ses->ifindex, &addr, a->prefix_len);
+ }
a->installed = 1;
}
}
@@ -369,7 +378,7 @@ static void ev_ses_started(struct ap_session *ses)
return;
list_for_each_entry(a, &ses->ipv6->addr_list, entry) {
- if (a->prefix_len == 64) {
+ if (a->prefix_len) {
ipv6_nd_start(ses);
break;
}
@@ -489,6 +498,7 @@ static void load_config(void)
conf_AdvManagedFlag = triton_module_loaded("ipv6_dhcp");
conf_AdvOtherConfigFlag = triton_module_loaded("ipv6_dhcp");
+ conf_AdvPrefixOnLinkFlag = 1;
conf_AdvPrefixAutonomousFlag = !conf_AdvManagedFlag;
conf_rdnss_lifetime = conf_MaxRtrAdvInterval;
@@ -539,6 +549,10 @@ static void load_config(void)
if (opt)
conf_AdvPrefixPreferredLifetime = atoi(opt);
+ opt = conf_get_opt("ipv6-nd", "AdvOnLinkFlag");
+ if (opt)
+ conf_AdvPrefixOnLinkFlag = atoi(opt);
+
opt = conf_get_opt("ipv6-nd", "AdvAutonomousFlag");
if (opt)
conf_AdvPrefixAutonomousFlag = atoi(opt);