summaryrefslogtreecommitdiff
path: root/accel-pppd/ppp
diff options
context:
space:
mode:
authorGuillaume Nault <g.nault@alphalink.fr>2013-07-23 20:35:25 +0200
committerDmitry Kozlov <xeb@mail.ru>2013-07-24 22:32:08 +0400
commit31e20f0ce4605b7d7ec416bf88a4e98c90aa6b93 (patch)
treec5f87f55fcd80f2ed2a92f99ff09fdbd79f64493 /accel-pppd/ppp
parent4e6cf832cddf523c233ff0f0f3b244e077d87df3 (diff)
downloadaccel-ppp-31e20f0ce4605b7d7ec416bf88a4e98c90aa6b93.tar.gz
accel-ppp-31e20f0ce4605b7d7ec416bf88a4e98c90aa6b93.zip
ppp: Use link local IPv6 prefix by default during IPv6CP
When no ipdb backend can assign IPv6 addresses during IPv6CP negociation, generate an ipv6db item with an empty address list. This allows IPv6CP negociation to continue and assign a link-local IPv6 address, without the need for an IPv6 pool or special Radius configuration. Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
Diffstat (limited to 'accel-pppd/ppp')
-rw-r--r--accel-pppd/ppp/ipv6cp_opt_intfid.c42
1 files changed, 40 insertions, 2 deletions
diff --git a/accel-pppd/ppp/ipv6cp_opt_intfid.c b/accel-pppd/ppp/ipv6cp_opt_intfid.c
index a46ae17c..11b35ff7 100644
--- a/accel-pppd/ppp/ipv6cp_opt_intfid.c
+++ b/accel-pppd/ppp/ipv6cp_opt_intfid.c
@@ -37,6 +37,7 @@ static int ipaddr_send_conf_nak(struct ppp_ipv6cp_t *ipv6cp, struct ipv6cp_optio
static int ipaddr_recv_conf_req(struct ppp_ipv6cp_t *ipv6cp, struct ipv6cp_option_t *opt, uint8_t *ptr);
//static int ipaddr_recv_conf_ack(struct ppp_ipv6cp_t *ipv6cp, struct ipv6cp_option_t *opt, uint8_t *ptr);
static void ipaddr_print(void (*print)(const char *fmt,...),struct ipv6cp_option_t*, uint8_t *ptr);
+static void put_ipv6_item(struct ap_session *ses, struct ipv6db_item_t *ip6);
struct ipaddr_option_t
{
@@ -55,6 +56,41 @@ static struct ipv6cp_option_handler_t ipaddr_opt_hnd =
.print = ipaddr_print,
};
+/* ipdb backend used for generating a link-local address when all other
+ * backends (like radius and ipv6pool) failed to assign IPv6 addresses.
+ * This backend isn't registered to ipdb as it's only used as a fallback
+ * during IPv6CP negociation.
+ */
+static struct ipdb_t ipv6db = {
+ .put_ipv6 = put_ipv6_item
+};
+
+static void put_ipv6_item(struct ap_session *ses, struct ipv6db_item_t *ip6)
+{
+ _free(ip6);
+}
+
+static int gen_ipv6_item(struct ap_session *ses)
+{
+ struct ipv6db_item_t *ip6 = NULL;
+
+ ip6 = _malloc(sizeof(*ip6));
+ if (ip6 == NULL) {
+ log_ppp_warn("ppp: allocation of IPv6 address failed\n");
+ return -1;
+ }
+
+ memset(ip6, 0, sizeof(*ip6));
+ ip6->owner = &ipv6db;
+ ip6->intf_id = 0;
+ ip6->peer_intf_id = 0;
+ INIT_LIST_HEAD(&ip6->addr_list);
+
+ ses->ipv6 = ip6;
+
+ return 0;
+}
+
static struct ipv6cp_option_t *ipaddr_init(struct ppp_ipv6cp_t *ipv6cp)
{
struct ipaddr_option_t *ipaddr_opt = _malloc(sizeof(*ipaddr_opt));
@@ -165,8 +201,10 @@ static int alloc_ip(struct ppp_t *ppp)
{
ppp->ses.ipv6 = ipdb_get_ipv6(&ppp->ses);
if (!ppp->ses.ipv6) {
- log_ppp_warn("ppp: no free IPv6 address\n");
- return IPV6CP_OPT_CLOSE;
+ if (gen_ipv6_item(&ppp->ses) < 0) {
+ log_ppp_warn("ppp: no free IPv6 address\n");
+ return IPV6CP_OPT_CLOSE;
+ }
}
if (!ppp->ses.ipv6->intf_id)