summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--accel-pppd/ifcfg.c5
-rw-r--r--accel-pppd/ipdb.h3
-rw-r--r--accel-pppd/ipv6/dhcpv6.c17
-rw-r--r--accel-pppd/ipv6/nd.c9
-rw-r--r--accel-pppd/libnetlink/iputils.c32
-rw-r--r--accel-pppd/libnetlink/iputils.h1
6 files changed, 61 insertions, 6 deletions
diff --git a/accel-pppd/ifcfg.c b/accel-pppd/ifcfg.c
index 39e87b4..685e1de 100644
--- a/accel-pppd/ifcfg.c
+++ b/accel-pppd/ifcfg.c
@@ -166,15 +166,16 @@ void __export ap_session_accounting_started(struct ap_session *ses)
}
list_for_each_entry(a, &ses->ipv6->addr_list, entry) {
+ a->installed = 0;
/*if (a->prefix_len < 128) {
build_addr(a, ses->ipv6->intf_id, &ifr6.ifr6_addr);
ifr6.ifr6_prefixlen = a->prefix_len;
if (ioctl(sock6_fd, SIOCSIFADDR, &ifr6))
log_ppp_error("failed to add IPv6 address: %s\n", strerror(errno));
- } else*/
+ } else
if (ip6route_add(ses->ifindex, &a->addr, a->prefix_len, 0))
- log_ppp_error("failed to add IPv6 route: %s\n", strerror(errno));
+ log_ppp_error("failed to add IPv6 route: %s\n", strerror(errno));*/
}
}
diff --git a/accel-pppd/ipdb.h b/accel-pppd/ipdb.h
index fc0fe6f..d461c88 100644
--- a/accel-pppd/ipdb.h
+++ b/accel-pppd/ipdb.h
@@ -1,8 +1,6 @@
#ifndef IPDB_H
#define IPDB_H
-#include <netinet/in.h>
-
#include "ppp.h"
#include "list.h"
@@ -20,6 +18,7 @@ struct ipv6db_addr_t
struct in6_addr addr;
int prefix_len;
int flag_auto:1;
+ int installed:1;
};
struct ipv6db_item_t
diff --git a/accel-pppd/ipv6/dhcpv6.c b/accel-pppd/ipv6/dhcpv6.c
index 62f20bb..3f9df71 100644
--- a/accel-pppd/ipv6/dhcpv6.c
+++ b/accel-pppd/ipv6/dhcpv6.c
@@ -21,11 +21,12 @@
#include "ppp.h"
#include "ipdb.h"
#include "events.h"
-
-#include "memdebug.h"
+#include "iputils.h"
#include "dhcpv6.h"
+#include "memdebug.h"
+
#define BUF_SIZE 65536
#define MAX_DNS_COUNT 3
@@ -295,6 +296,18 @@ static void dhcpv6_send_reply(struct dhcpv6_packet *req, struct dhcpv6_pd *pd, i
ia_addr->pref_lifetime = htonl(conf_pref_lifetime);
ia_addr->valid_lifetime = htonl(conf_valid_lifetime);
+
+ if (a->installed) {
+ if (a->prefix_len > 64)
+ ip6route_add(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, &ses->ipv6->intf_id, 8);
+ ip6addr_add(ses->ifindex, &addr, a->prefix_len);
+ }
+ a->installed = 1;
+ }
}
list_for_each_entry(opt2, &opt->opt_list, entry) {
diff --git a/accel-pppd/ipv6/nd.c b/accel-pppd/ipv6/nd.c
index ff8b64b..19a3d7d 100644
--- a/accel-pppd/ipv6/nd.c
+++ b/accel-pppd/ipv6/nd.c
@@ -17,6 +17,7 @@
#include "events.h"
#include "mempool.h"
#include "ipdb.h"
+#include "iputils.h"
#include "memdebug.h"
@@ -137,6 +138,14 @@ static void ipv6_nd_send_ra(struct ipv6_nd_handler_t *h, struct sockaddr_in6 *ad
pinfo->nd_opt_pi_preferred_time = htonl(conf_AdvPrefixPreferredLifetime);
memcpy(&pinfo->nd_opt_pi_prefix, &a->addr, 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);
+ a->installed = 1;
+ }
}
/*rinfo = (struct nd_opt_route_info_local *)pinfo;
diff --git a/accel-pppd/libnetlink/iputils.c b/accel-pppd/libnetlink/iputils.c
index 1544508..480f028 100644
--- a/accel-pppd/libnetlink/iputils.c
+++ b/accel-pppd/libnetlink/iputils.c
@@ -416,6 +416,38 @@ int __export ip6route_add(int ifindex, struct in6_addr *dst, int pref_len, int p
}
+int __export ip6addr_add(int ifindex, struct in6_addr *addr, int prefix_len)
+{
+ struct ipaddr_req {
+ struct nlmsghdr n;
+ struct ifaddrmsg i;
+ char buf[4096];
+ } req;
+
+ if (!rth)
+ open_rth();
+
+ if (!rth)
+ return -1;
+
+ memset(&req, 0, sizeof(req) - 4096);
+
+ req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
+ req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE;
+ req.n.nlmsg_type = RTM_NEWADDR;
+ req.i.ifa_family = AF_INET6;
+ req.i.ifa_index = ifindex;
+ req.i.ifa_prefixlen = prefix_len;
+ req.i.ifa_flags = IFA_F_NODAD;
+
+ addattr_l(&req.n, sizeof(req), IFA_ADDRESS, addr, 16);
+
+ if (rtnl_talk(rth, &req.n, 0, 0, NULL, NULL, NULL, 0) < 0)
+ return -1;
+
+ return 0;
+}
+
in_addr_t __export iproute_get(in_addr_t dst, in_addr_t *gw)
{
struct ipaddr_req {
diff --git a/accel-pppd/libnetlink/iputils.h b/accel-pppd/libnetlink/iputils.h
index b9a6488..6097627 100644
--- a/accel-pppd/libnetlink/iputils.h
+++ b/accel-pppd/libnetlink/iputils.h
@@ -19,6 +19,7 @@ int iproute_del(int ifindex, in_addr_t dst, int proto);
in_addr_t iproute_get(in_addr_t dst, in_addr_t *gw);
int ip6route_add(int ifindex, struct in6_addr *dst, int prefix_len, int proto);
+int ip6addr_add(int ifindex, struct in6_addr *addr, int prefix_len);
int iprule_add(uint32_t addr, int table);
int iprule_del(uint32_t addr, int table);