From 7fc3d1044d3a46903dac0acd96b4e1c50602b309 Mon Sep 17 00:00:00 2001 From: Vladislav Grishenko Date: Thu, 12 May 2016 21:17:48 +0500 Subject: ipv6: nd: add AdvOnLinkFlag option support --- accel-pppd/ipv6/nd.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'accel-pppd/ipv6') diff --git a/accel-pppd/ipv6/nd.c b/accel-pppd/ipv6/nd.c index 1d70ae95..205aeefd 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; @@ -132,8 +133,9 @@ static void ipv6_nd_send_ra(struct ipv6_nd_handler_t *h, struct sockaddr_in6 *ad 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_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, 8); @@ -489,6 +491,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 +542,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); -- cgit v1.2.3 From 2aa6aeaca2691403e52ea007d3574cb7f662b0e7 Mon Sep 17 00:00:00 2001 From: Vladislav Grishenko Date: Thu, 12 May 2016 20:56:16 +0500 Subject: ipv6: nd: fix interface id addresses generation for prefixes > /64 --- accel-pppd/extra/pppd_compat.c | 2 +- accel-pppd/ifcfg.c | 2 +- accel-pppd/ipv6/dhcpv6.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'accel-pppd/ipv6') 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/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) -- cgit v1.2.3 From 504b093a9878e758af1397aa82eda44b1bf0f608 Mon Sep 17 00:00:00 2001 From: Vladislav Grishenko Date: Thu, 12 May 2016 22:20:42 +0500 Subject: ipv6: nd: add non-/64 prefixes support non-/64 subnets still needs Router Advertimenets for the default route & RDNSS. --- accel-pppd/ipv6/nd.c | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) (limited to 'accel-pppd/ipv6') diff --git a/accel-pppd/ipv6/nd.c b/accel-pppd/ipv6/nd.c index 205aeefd..f2a259ad 100644 --- a/accel-pppd/ipv6/nd.c +++ b/accel-pppd/ipv6/nd.c @@ -129,23 +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 = - ((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, 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; } } @@ -371,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; } -- cgit v1.2.3