diff options
-rw-r--r-- | accel-pppd/accel-ppp.conf | 7 | ||||
-rw-r--r-- | accel-pppd/accel-ppp.conf.5 | 25 | ||||
-rw-r--r-- | accel-pppd/extra/chap-secrets.c | 6 | ||||
-rw-r--r-- | accel-pppd/extra/ipv6pool.c | 304 | ||||
-rw-r--r-- | accel-pppd/include/ap_session.h | 1 | ||||
-rw-r--r-- | accel-pppd/radius/attr_defs.h | 5 | ||||
-rw-r--r-- | accel-pppd/radius/dict.c | 2 | ||||
-rw-r--r-- | accel-pppd/radius/dict/dictionary | 1 | ||||
-rw-r--r-- | accel-pppd/radius/dict/dictionary.rfc6911 | 12 | ||||
-rw-r--r-- | accel-pppd/session.c | 5 | ||||
-rw-r--r-- | rfc/rfc6911.txt | 843 |
11 files changed, 1164 insertions, 47 deletions
diff --git a/accel-pppd/accel-ppp.conf b/accel-pppd/accel-ppp.conf index 7f341b6..acdbe4f 100644 --- a/accel-pppd/accel-ppp.conf +++ b/accel-pppd/accel-ppp.conf @@ -289,8 +289,15 @@ timeout=60 [ipv6-pool] #gw-ip6-address=fc00:0:1::1 +#vendor= +#prefix-attr=Delegated-IPv6-Prefix-Pool +#address-attr=Stateful-IPv6-Address-Pool fc00:0:1::/48,64 +fc00:0:2::/48,64,pool=pool1 +fc00:0:3::/48,64,pool=pool2,next=pool1 delegate=fc00:1::/36,48 +delegate=fc00:2::/36,48,pool=pool3 +delegate=fc00:3::/36,48,pool=pool4,next=pool3 [ipv6-dns] #fc00:1::1 diff --git a/accel-pppd/accel-ppp.conf.5 b/accel-pppd/accel-ppp.conf.5 index 982bbd1..3e6312f 100644 --- a/accel-pppd/accel-ppp.conf.5 +++ b/accel-pppd/accel-ppp.conf.5 @@ -1022,27 +1022,34 @@ If attribute is vendor-specific then specify vendor name in this option. .SH [ipv6-pool] .br Configuration of ipv6pool module. +.TP +.BI ipv6prefix/mask,prefix_len[,name=pool_name][,next=next_pool_name] .br -Format of each row is -.br -.B ipv6prefix/mask,prefix_len -for example: -.br -.B fc00:0:1::/48,64 -- specifies pool of address by dividing prefix fc00:0:1::/48 to networks with 64 prefix len, e.g: +.B fc00:0:1::/48,64 - specifies pool of address by dividing prefix fc00:0:1::/48 to networks with 64 prefix len, e.g: .br fc00:0:1:0::/64 .br fc00:0:1:1::/64 .br -... + ... +.br fc00:0:1:ffff::/64 .TP -.BI "delegate=" ipv6prefix/mask,prefix_len +.BI "delegate=" ipv6prefix/mask,prefix_len[,name=pool_name][,next=next_pool_name] Specifies range of prefixes to delegate to clients through DHCPv6 prefix delegation (rfc3633). Format is same as described above. +.TP .BI "gw-ip6-address=" ipv6address Specifies gateway address (used only for /128 prefixes) +.TP +.BI "attr-prefix=" attribute +Specifies which Radius attribute contains delegated prefix pool name. +.TP +.BI "attr-address=" attribute +Specifies which Radius attribute contains stateful address pool name. +.TP +.BI "vendor=" vendor +If attribute is vendor-specific then specify vendor name in this option. .SH [connlimit] .br This module limits connection rate from single source. diff --git a/accel-pppd/extra/chap-secrets.c b/accel-pppd/extra/chap-secrets.c index 92cfb42..2d8593c 100644 --- a/accel-pppd/extra/chap-secrets.c +++ b/accel-pppd/extra/chap-secrets.c @@ -313,6 +313,12 @@ static struct ipv4db_item_t *get_ip(struct ap_session *ses) if (ses->ipv4_pool_name) _free(ses->ipv4_pool_name); ses->ipv4_pool_name = _strdup(pd->pool); + if (ses->ipv6_pool_name) + _free(ses->ipv6_pool_name); + ses->ipv6_pool_name = _strdup(pd->pool); + if (ses->ipv6_dppool_name) + _free(ses->ipv6_dppool_name); + ses->ipv6_dppool_name = _strdup(pd->pool); return NULL; } else if (!pd->ip.peer_addr) return NULL; diff --git a/accel-pppd/extra/ipv6pool.c b/accel-pppd/extra/ipv6pool.c index 4f29a28..f00dbcf 100644 --- a/accel-pppd/extra/ipv6pool.c +++ b/accel-pppd/extra/ipv6pool.c @@ -8,31 +8,60 @@ #include <arpa/inet.h> #include <endian.h> +#include "events.h" #include "ipdb.h" #include "list.h" #include "log.h" #include "spinlock.h" +#ifdef RADIUS +#include "radius.h" +#endif + #include "memdebug.h" +enum ippool_type +{ + IPPOOL_ADDRESS, + IPPOOL_PREFIX +}; + +struct ippool_t +{ + struct list_head entry; + char *name; + struct list_head gw_list; + struct list_head items; + struct ippool_t *next; + spinlock_t lock; +}; struct ippool_item_t { struct list_head entry; + struct ippool_t *pool; struct ipv6db_item_t it; }; struct dppool_item_t { struct list_head entry; + struct ippool_t *pool; struct ipv6db_prefix_t it; }; -static LIST_HEAD(ippool); -static LIST_HEAD(dppool); -static spinlock_t pool_lock; +#ifdef RADIUS +static int conf_vendor = 0; +static int conf_dppool_attr = 171; // Delegated-IPv6-Prefix-Pool +static int conf_ippool_attr = 172; // Stateful-IPv6-Address-Pool +#endif + +static LIST_HEAD(ippool_list); +static LIST_HEAD(dppool_list); static struct ipdb_t ipdb; static struct in6_addr conf_gw_addr; +static struct ippool_t *def_ippool; +static struct ippool_t *def_dppool; static void in6_addr_add(struct in6_addr *res, const struct in6_addr *arg) { @@ -59,7 +88,40 @@ static int in6_addr_cmp(const struct in6_addr *n1, const struct in6_addr *n2) return 0; } -static void generate_ippool(struct in6_addr *addr, int mask, int prefix_len) +static struct ippool_t *create_pool(enum ippool_type type, char *name) +{ + struct ippool_t *pool = malloc(sizeof(*pool)); + struct list_head *pool_list = (type == IPPOOL_PREFIX) ? &dppool_list : &ippool_list; + + memset(pool, 0, sizeof(*pool)); + pool->name = name; + + INIT_LIST_HEAD(&pool->items); + spinlock_init(&pool->lock); + + if (name) + list_add_tail(&pool->entry, pool_list); + + return pool; +} + +static struct ippool_t *find_pool(enum ippool_type type, char *name, int create) +{ + struct ippool_t *pool; + struct list_head *pool_list = (type == IPPOOL_PREFIX) ? &dppool_list : &ippool_list; + + list_for_each_entry(pool, pool_list, entry) { + if (!strcmp(pool->name, name)) + return pool; + } + + if (create) + return create_pool(type, name); + + return NULL; +} + +static void generate_ippool(struct ippool_t *pool, struct in6_addr *addr, int mask, int prefix_len) { struct ippool_item_t *it; struct ipv6db_addr_t *a; @@ -84,6 +146,7 @@ static void generate_ippool(struct in6_addr *addr, int mask, int prefix_len) while (in6_addr_cmp(&ip, &end) <= 0) { it = malloc(sizeof(*it)); memset(it, 0, sizeof(*it)); + it->pool = pool; it->it.owner = &ipdb; INIT_LIST_HEAD(&it->it.addr_list); a = malloc(sizeof(*a)); @@ -91,12 +154,12 @@ static void generate_ippool(struct in6_addr *addr, int mask, int prefix_len) memcpy(&a->addr, &ip, sizeof(ip)); a->prefix_len = prefix_len; list_add_tail(&a->entry, &it->it.addr_list); - list_add_tail(&it->entry, &ippool); + list_add_tail(&it->entry, &pool->items); in6_addr_add(&ip, &step); } } -static void generate_dppool(struct in6_addr *addr, int mask, int prefix_len) +static void generate_dppool(struct ippool_t *pool, struct in6_addr *addr, int mask, int prefix_len) { struct dppool_item_t *it; struct in6_addr ip, end, step; @@ -121,6 +184,7 @@ static void generate_dppool(struct in6_addr *addr, int mask, int prefix_len) while (in6_addr_cmp(&ip, &end) <= 0) { it = malloc(sizeof(*it)); memset(it, 0, sizeof(*it)); + it->pool = pool; it->it.owner = &ipdb; INIT_LIST_HEAD(&it->it.prefix_list); a = malloc(sizeof(*a)); @@ -128,13 +192,12 @@ static void generate_dppool(struct in6_addr *addr, int mask, int prefix_len) memcpy(&a->addr, &ip, sizeof(ip)); a->prefix_len = prefix_len; list_add_tail(&a->entry, &it->it.prefix_list); - list_add_tail(&it->entry, &dppool); + list_add_tail(&it->entry, &pool->items); in6_addr_add(&ip, &step); } } - -static void add_prefix(int type, const char *_val) +static void add_prefix(enum ippool_type type, struct ippool_t *pool, const char *_val) { char *val = _strdup(_val); char *ptr1, *ptr2; @@ -169,10 +232,10 @@ static void add_prefix(int type, const char *_val) if (prefix_len > 128 || prefix_len < mask) goto err; - if (type) - generate_dppool(&addr, mask, prefix_len); + if (type == IPPOOL_PREFIX) + generate_dppool(pool, &addr, mask, prefix_len); else - generate_ippool(&addr, mask, prefix_len); + generate_ippool(pool, &addr, mask, prefix_len); _free(val); return; @@ -186,14 +249,24 @@ static struct ipv6db_item_t *get_ip(struct ap_session *ses) { struct ippool_item_t *it; struct ipv6db_addr_t *a; + struct ippool_t *pool; + + if (ses->ipv6_pool_name) + pool = find_pool(IPPOOL_ADDRESS, ses->ipv6_pool_name, 0); + else + pool = def_ippool; + + if (!pool) + return NULL; - spin_lock(&pool_lock); - if (!list_empty(&ippool)) { - it = list_entry(ippool.next, typeof(*it), entry); +again: + spin_lock(&pool->lock); + if (!list_empty(&pool->items)) { + it = list_entry(pool->items.next, typeof(*it), entry); list_del(&it->entry); } else it = NULL; - spin_unlock(&pool_lock); + spin_unlock(&pool->lock); if (it) { a = list_entry(it->it.addr_list.next, typeof(*a), entry); @@ -206,6 +279,9 @@ static struct ipv6db_item_t *get_ip(struct ap_session *ses) } return &it->it; + } else if (pool->next) { + pool = pool->next; + goto again; } return NULL; @@ -215,33 +291,47 @@ static void put_ip(struct ap_session *ses, struct ipv6db_item_t *it) { struct ippool_item_t *pit = container_of(it, typeof(*pit), it); - spin_lock(&pool_lock); - list_add_tail(&pit->entry, &ippool); - spin_unlock(&pool_lock); + spin_lock(&pit->pool->lock); + list_add_tail(&pit->entry, &pit->pool->items); + spin_unlock(&pit->pool->lock); } static struct ipv6db_prefix_t *get_dp(struct ap_session *ses) { struct dppool_item_t *it; + struct ippool_t *pool; - spin_lock(&pool_lock); - if (!list_empty(&dppool)) { - it = list_entry(dppool.next, typeof(*it), entry); + if (ses->ipv6_pool_name) + pool = find_pool(IPPOOL_PREFIX, ses->ipv6_dppool_name, 0); + else + pool = def_dppool; + +again: + spin_lock(&pool->lock); + if (!list_empty(&pool->items)) { + it = list_entry(pool->items.next, typeof(*it), entry); list_del(&it->entry); } else it = NULL; - spin_unlock(&pool_lock); + spin_unlock(&pool->lock); - return it ? &it->it : NULL; + if (it) + return &it->it; + else if (pool->next) { + pool = pool->next; + goto again; + } + + return NULL; } static void put_dp(struct ap_session *ses, struct ipv6db_prefix_t *it) { struct dppool_item_t *pit = container_of(it, typeof(*pit), it); - spin_lock(&pool_lock); - list_add_tail(&pit->entry, &dppool); - spin_unlock(&pool_lock); + spin_lock(&pit->pool->lock); + list_add_tail(&pit->entry, &pit->pool->items); + spin_unlock(&pit->pool->lock); } static struct ipdb_t ipdb = { @@ -251,28 +341,168 @@ static struct ipdb_t ipdb = { .put_ipv6_prefix = put_dp, }; -static void ippool_init(void) +#ifdef RADIUS +static void ev_radius_access_accept(struct ev_radius_t *ev) +{ + struct rad_attr_t *attr; + struct ap_session *ses = ev->ses; + + list_for_each_entry(attr, &ev->reply->attrs, entry) { + if (attr->attr->type != ATTR_TYPE_STRING) + continue; + if (attr->vendor && attr->vendor->id != conf_vendor) + continue; + if (!attr->vendor && conf_vendor) + continue; + + if (conf_dppool_attr && conf_dppool_attr == attr->attr->id) { + if (ses->ipv6_dppool_name) + _free(ses->ipv6_dppool_name); + ses->ipv6_dppool_name = _strdup(attr->val.string); + } else + if (conf_ippool_attr && conf_ippool_attr == attr->attr->id) { + if (ses->ipv6_pool_name) + _free(ses->ipv6_pool_name); + ses->ipv6_pool_name = _strdup(attr->val.string); + } + } +} + +static int parse_attr_opt(const char *opt) +{ + struct rad_dict_attr_t *attr; + struct rad_dict_vendor_t *vendor; + + if (conf_vendor) + vendor = rad_dict_find_vendor_id(conf_vendor); + else + vendor = NULL; + + if (conf_vendor) { + if (vendor) + attr = rad_dict_find_vendor_attr(vendor, opt); + else + attr = NULL; + } else + attr = rad_dict_find_attr(opt); + + if (attr) + return attr->id; + + return atoi(opt); +} + +static int parse_vendor_opt(const char *opt) +{ + struct rad_dict_vendor_t *vendor; + + vendor = rad_dict_find_vendor_name(opt); + if (vendor) + return vendor->id; + + return atoi(opt); +} +#endif + +static void parse_options(enum ippool_type type, const char *opt, char **pool_name, struct ippool_t **next) +{ + char *ptr1, *ptr2, *tmp; + + ptr1 = strstr(opt, ",name="); + if (ptr1) { + ptr1 += sizeof(",name=") - 1; + ptr2 = strchrnul(ptr1, ','); + *pool_name = _strndup(ptr1, ptr2 - ptr1); + } + + ptr1 = strstr(opt, ",next="); + if (ptr1) { + ptr1 += sizeof(",next=") - 1; + ptr2 = strchrnul(ptr1, ','); + if (*ptr2 == ',') { + tmp = alloca(ptr2 - ptr1 + 1); + strncpy(tmp, ptr1, ptr2 - ptr1); + ptr1 = tmp; + } + *next = find_pool(type, ptr1, 0); + if (!(*next)) + log_error("ipv6_pool: %s: next pool not found\n", opt); + } +} + +static void ippool_init1(void) +{ + ipdb_register(&ipdb); +} + +static void ippool_init2(void) { struct conf_sect_t *s = conf_get_section("ipv6-pool"); struct conf_option_t *opt; - - spinlock_init(&pool_lock); + struct ippool_t *pool, *next; + char *pool_name, *val; + enum ippool_type type; +#ifdef RADIUS + int dppool_attr = 0, ippool_attr = 0; +#endif if (!s) return; + def_ippool = create_pool(IPPOOL_ADDRESS, NULL); + def_dppool = create_pool(IPPOOL_PREFIX, NULL); + list_for_each_entry(opt, &s->items, entry) { +#ifdef RADIUS + if (triton_module_loaded("radius")) { + if (!strcmp(opt->name, "vendor")) { + conf_vendor = parse_vendor_opt(opt->val); + continue; + } + if (!strcmp(opt->name, "attr-prefix")) { + dppool_attr = parse_attr_opt(opt->val); + continue; + } + if (!strcmp(opt->name, "attr-address")) { + ippool_attr = parse_attr_opt(opt->val); + continue; + } + } +#endif if (!strcmp(opt->name, "gw-ip6-address")) { if (inet_pton(AF_INET6, opt->val, &conf_gw_addr) == 0) log_error("ipv6_pool: failed to parse gw-ip6-address\n"); - } else if (!strcmp(opt->name, "delegate")) - add_prefix(1, opt->val); - else - add_prefix(0, opt->name); + continue; + } else if (!strcmp(opt->name, "delegate")) { + type = IPPOOL_PREFIX; + val = opt->val; + pool = def_dppool; + } else { + type = IPPOOL_ADDRESS; + val = opt->name; + pool = def_ippool; + } + + pool_name = NULL; + parse_options(type, opt->raw, &pool_name, &next); + + if (pool_name) + pool = find_pool(type, pool_name, 1); + add_prefix(type, pool, val); + + pool->next = next; } - ipdb_register(&ipdb); +#ifdef RADIUS + if (triton_module_loaded("radius")) { + if (conf_vendor || dppool_attr) + conf_dppool_attr = dppool_attr; + if (conf_vendor || ippool_attr) + conf_ippool_attr = ippool_attr; + triton_event_register_handler(EV_RADIUS_ACCESS_ACCEPT, (triton_event_func)ev_radius_access_accept); + } +#endif } -DEFINE_INIT(51, ippool_init); - +DEFINE_INIT(51, ippool_init1); +DEFINE_INIT2(52, ippool_init2); diff --git a/accel-pppd/include/ap_session.h b/accel-pppd/include/ap_session.h index b2d0532..cf49e32 100644 --- a/accel-pppd/include/ap_session.h +++ b/accel-pppd/include/ap_session.h @@ -84,6 +84,7 @@ struct ap_session struct ipv6db_prefix_t *ipv6_dp; char *ipv4_pool_name; char *ipv6_pool_name; + char *ipv6_dppool_name; struct ap_net *net; const struct ap_ctrl *ctrl; diff --git a/accel-pppd/radius/attr_defs.h b/accel-pppd/radius/attr_defs.h index eb3c5de..80ae426 100644 --- a/accel-pppd/radius/attr_defs.h +++ b/accel-pppd/radius/attr_defs.h @@ -292,3 +292,8 @@ #define Framed_IPv6_Route 99 #define Framed_IPv6_Pool 100 #define Delegated_IPv6_Prefix 123 +#define Framed_IPv6_Address 168 +#define DNS_Server_IPv6_Address 169 +#define Route_IPv6_Information 170 +#define Delegated_IPv6_Prefix_Pool 171 +#define Stateful_IPv6_Address_Pool 172 diff --git a/accel-pppd/radius/dict.c b/accel-pppd/radius/dict.c index fa75dd9..cb1fb28 100644 --- a/accel-pppd/radius/dict.c +++ b/accel-pppd/radius/dict.c @@ -80,7 +80,7 @@ static int dict_load(const char *fname) f = fopen(fname, "r"); if (!f) { - log_emerg("radius: open dictioanary '%s': %s\n", fname, strerror(errno)); + log_emerg("radius: open dictionary '%s': %s\n", fname, strerror(errno)); return -1; } diff --git a/accel-pppd/radius/dict/dictionary b/accel-pppd/radius/dict/dictionary index de05680..6da511d 100644 --- a/accel-pppd/radius/dict/dictionary +++ b/accel-pppd/radius/dict/dictionary @@ -74,6 +74,7 @@ $INCLUDE dictionary.rfc4372 $INCLUDE dictionary.rfc4679 $INCLUDE dictionary.rfc4818 $INCLUDE dictionary.rfc5176 +$INCLUDE dictionary.rfc6911 $INCLUDE dictionary.microsoft $INCLUDE dictionary.cisco diff --git a/accel-pppd/radius/dict/dictionary.rfc6911 b/accel-pppd/radius/dict/dictionary.rfc6911 new file mode 100644 index 0000000..f8d5204 --- /dev/null +++ b/accel-pppd/radius/dict/dictionary.rfc6911 @@ -0,0 +1,12 @@ +# -*- text -*- +# Copyright (C) 2013 The FreeRADIUS Server project and contributors +# +# Attributes and values defined in RFC 6911 +# http://www.ietf.org/rfc/rfc6911.txt +# + +ATTRIBUTE Framed-IPv6-Address 168 ipv6addr +ATTRIBUTE DNS-Server-IPv6-Address 169 ipv6addr +ATTRIBUTE Route-IPv6-Information 170 ipv6prefix +ATTRIBUTE Delegated-IPv6-Prefix-Pool 171 string +ATTRIBUTE Stateful-IPv6-Address-Pool 172 string diff --git a/accel-pppd/session.c b/accel-pppd/session.c index bf7d712..8326ffa 100644 --- a/accel-pppd/session.c +++ b/accel-pppd/session.c @@ -239,6 +239,11 @@ void __export ap_session_finished(struct ap_session *ses) ses->ipv6_pool_name = NULL; } + if (ses->ipv6_dppool_name) { + _free(ses->ipv6_dppool_name); + ses->ipv6_dppool_name = NULL; + } + if (ses->ifname_rename) { _free(ses->ifname_rename); ses->ifname_rename = NULL; diff --git a/rfc/rfc6911.txt b/rfc/rfc6911.txt new file mode 100644 index 0000000..32b0737 --- /dev/null +++ b/rfc/rfc6911.txt @@ -0,0 +1,843 @@ + + + + + + +Internet Engineering Task Force (IETF) W. Dec, Ed. +Request for Comments: 6911 Cisco Systems, Inc. +Category: Standards Track B. Sarikaya +ISSN: 2070-1721 Huawei USA + G. Zorn, Ed. + Network Zen + D. Miles + Google + B. Lourdelet + Juniper Networks + April 2013 + + + RADIUS Attributes for IPv6 Access Networks + +Abstract + + This document specifies additional IPv6 RADIUS Attributes useful in + residential broadband network deployments. The Attributes, which are + used for authorization and accounting, enable assignment of a host + IPv6 address and an IPv6 DNS server address via DHCPv6, assignment of + an IPv6 route announced via router advertisement, assignment of a + named IPv6 delegated prefix pool, and assignment of a named IPv6 pool + for host DHCPv6 addressing. + +Status of This Memo + + This is an Internet Standards Track document. + + This document is a product of the Internet Engineering Task Force + (IETF). It represents the consensus of the IETF community. It has + received public review and has been approved for publication by the + Internet Engineering Steering Group (IESG). Further information on + Internet Standards is available in Section 2 of RFC 5741. + + Information about the current status of this document, any errata, + and how to provide feedback on it may be obtained at + http://www.rfc-editor.org/info/rfc6911. + + + + + + + + + + + + + +Dec, et al. Standards Track [Page 1] + +RFC 6911 RADIUS IPv6 Access April 2013 + + +Copyright Notice + + Copyright (c) 2013 IETF Trust and the persons identified as the + document authors. All rights reserved. + + This document is subject to BCP 78 and the IETF Trust's Legal + Provisions Relating to IETF Documents + (http://trustee.ietf.org/license-info) in effect on the date of + publication of this document. Please review these documents + carefully, as they describe your rights and restrictions with respect + to this document. Code Components extracted from this document must + include Simplified BSD License text as described in Section 4.e of + the Trust Legal Provisions and are provided without warranty as + described in the Simplified BSD License. + +Table of Contents + + 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 + 1.1. Requirements Language . . . . . . . . . . . . . . . . . . 3 + 2. Deployment Scenarios . . . . . . . . . . . . . . . . . . . . 3 + 2.1. IPv6 Address Assignment . . . . . . . . . . . . . . . . . 4 + 2.2. DNS Servers . . . . . . . . . . . . . . . . . . . . . . . 5 + 2.3. IPv6 Route Information . . . . . . . . . . . . . . . . . 5 + 2.4. Delegated IPv6 Prefix Pool . . . . . . . . . . . . . . . 6 + 2.5. Stateful IPv6 Address Pool . . . . . . . . . . . . . . . 6 + 3. Attributes . . . . . . . . . . . . . . . . . . . . . . . . . 6 + 3.1. Framed-IPv6-Address . . . . . . . . . . . . . . . . . . . 6 + 3.2. DNS-Server-IPv6-Address . . . . . . . . . . . . . . . . . 8 + 3.3. Route-IPv6-Information . . . . . . . . . . . . . . . . . 9 + 3.4. Delegated-IPv6-Prefix-Pool . . . . . . . . . . . . . . . 10 + 3.5. Stateful-IPv6-Address-Pool . . . . . . . . . . . . . . . 11 + 3.6. Table of Attributes . . . . . . . . . . . . . . . . . . . 11 + 4. Diameter Considerations . . . . . . . . . . . . . . . . . . . 12 + 5. Security Considerations . . . . . . . . . . . . . . . . . . . 12 + 6. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 12 + 7. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . 13 + 8. References . . . . . . . . . . . . . . . . . . . . . . . . . 13 + 8.1. Normative References . . . . . . . . . . . . . . . . . . 13 + 8.2. Informative References . . . . . . . . . . . . . . . . . 13 + + + + + + + + + + + + +Dec, et al. Standards Track [Page 2] + +RFC 6911 RADIUS IPv6 Access April 2013 + + +1. Introduction + + This document specifies additional RADIUS Attributes used to support + configuration of DHCPv6 and/or ICMPv6 Router Advertisement (RA) + parameters on a per-user basis. The Attributes, which complement + those defined in [RFC3162] and [RFC4818], support the following: + + o The assignment of specific IPv6 addresses to hosts via DHCPv6. + + o The assignment of an IPv6 DNS server address, via DHCPv6 or Router + Advertisement [RFC6106]. + + o The configuration of more specific routes to be announced to the + user via the Route Information Option defined in [RFC4191], + Section 2.3. + + o The assignment of a named delegated prefix pool for use with "IPv6 + Prefix Options for Dynamic Host Configuration Protocol (DHCP) + version 6" [RFC3633]. + + o The assignment of a named stateful address pool for use with + DHCPv6 stateful address assignment [RFC3315]. + +1.1. Requirements Language + + The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", + "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this + document are to be interpreted as described in RFC 2119 [RFC2119]. + +2. Deployment Scenarios + + The extensions in this document are intended to be applicable across + a wide variety of network access scenarios in which RADIUS is + involved. One such typical network scenario is illustrated in Figure + 1. It is composed of an IP Routing Residential Gateway (RG) or host; + a Layer 2 Access Node (AN), e.g., a Digital Subscriber Line Access + Multiplexer (DSLAM); an IP Network Access Server (NAS) (incorporating + an Authentication, Authorization, and Accounting (AAA) client); and a + AAA server. + + + + + + + + + + + + +Dec, et al. Standards Track [Page 3] + +RFC 6911 RADIUS IPv6 Access April 2013 + + + +-----+ + | AAA | + | | + +--+--+ + ^ + . + .(RADIUS) + . + v + +------+ +---+---+ + +------+ | | | | + | RG/ +-------| AN +-----------+----------+ NAS | + | host | | | | | + +------+ (DSL) +------+ (Ethernet) +-------+ + + Figure 1 + + In the depicted scenario, the NAS may utilize an IP address + configuration protocol (e.g., DHCPv6) to handle address assignment to + RGs/hosts. The RADIUS server authenticates each RG/host and returns + the Attributes used for authorization and accounting. These + Attributes can include a host's IPv6 address, a DNS server address, + and a set of IPv6 routes to be advertised via any suitable protocol, + e.g., ICMPv6 (Neighbor Discovery). The name of a prefix pool to be + used for DHCPv6 Prefix Delegation or the name of an address pool to + be used for DHCPv6 address assignment can also be Attributes provided + to the NAS by the RADIUS AAA server. + + The following subsections discuss how these Attributes are used in + more detail. + +2.1. IPv6 Address Assignment + + DHCPv6 [RFC3315] provides a mechanism to assign one or more non- + temporary IPv6 addresses to hosts. To provide a DHCPv6 server + residing on a NAS with one or more IPv6 addresses to be assigned, + this document specifies the Framed-IPv6-Address Attribute + (Section 3.1). + + While [RFC3162] permits the specification of an IPv6 address via the + combination of the Framed-Interface-Id and Framed-IPv6-Prefix + Attributes, this separation is more natural for use with PPP's IPv6 + Control Protocol than it is for use with DHCPv6, and the use of a + single IPv6 address Attribute makes for easier processing of + accounting records. + + + + + + +Dec, et al. Standards Track [Page 4] + +RFC 6911 RADIUS IPv6 Access April 2013 + + + Because DHCPv6 can be deployed on the same network as ICMPv6 + stateless address autoconfiguration (SLAAC) [RFC4862], it is possible + that the NAS will require both stateful and stateless configuration + information. Therefore, it is possible for the Framed-IPv6-Address, + Framed-IPv6-Prefix, and Framed-Interface-Id Attributes [RFC3162] to + be included within the same packet. To avoid ambiguity in this case, + the Framed-IPv6-Address Attribute is intended for authorization and + accounting of DHCPv6-assigned addresses, and the Framed-IPv6-Prefix + and Framed-Interface-Id Attributes are used for authorization and + accounting of addresses assigned via SLAAC. + +2.2. DNS Servers + + DHCPv6 provides an option for configuring a host with the IPv6 + address of a DNS server. The IPv6 address of a DNS server can also + be conveyed to the host using ICMPv6 with Router Advertisements, via + the Recursive DNS Server Option [RFC6106]. To provide the NAS with + the IPv6 address of one or more DNS servers, this document specifies + the DNS-Server-IPv6-Address Attribute (Section 3.2). + +2.3. IPv6 Route Information + + The IPv6 Route Information Option [RFC4191], is intended to be used + to inform a host connected to the NAS that a specific route is + reachable via any given NAS. + + This document specifies the Route-IPv6-Information Attribute + (Section 3.3) that allows the AAA server to provision the + announcement by the NAS of a specific Route Information Option to an + accessing host. The NAS may advertise this route using the method + defined in RFC 4191 or other equivalent methods. Any other + information, such as preference or lifetime values, that is to be + present in the actual announcement using a given method is assumed to + be determined by the NAS using means not specified by this document + (e.g., local configuration on the NAS). + + While the Framed-IPv6-Prefix Attribute ([RFC3162], Section 2.3) + allows the route to be advertised in an RA, it cannot be used to + configure more specific routes. While the Framed-IPv6-Route + Attribute ([RFC3162], Section 2.5) causes the route to be configured + on the NAS and potentially to be announced via an IP routing + protocol, depending on the value of Framed-Routing, it does not + result in the route being announced in an RA. + + + + + + + + +Dec, et al. Standards Track [Page 5] + +RFC 6911 RADIUS IPv6 Access April 2013 + + +2.4. Delegated IPv6 Prefix Pool + + DHCPv6 Prefix Delegation (DHCPv6-PD) [RFC3633] involves a delegating + router selecting a prefix and delegating it on a temporary basis to a + requesting router. The delegating router may implement a number of + strategies as to how it chooses what prefix is to be delegated to a + requesting router, one of them being the use of a local named prefix + pool. The Delegated-IPv6-Prefix-Pool Attribute (Section 3.4) allows + the RADIUS server to convey a prefix pool name to a NAS that is + hosting a DHCPv6-PD server and that is acting as a delegating router. + + Because DHCPv6 Prefix Delegation can be used with SLAAC on the same + network, it is possible for the Delegated-IPv6-Prefix-Pool and + Framed-IPv6-Pool Attributes to be included within the same packet. + To avoid ambiguity in this scenario, use of the Delegated-IPv6- + Prefix-Pool Attribute should be restricted to authorization and + accounting of prefix pools used in DHCPv6 Prefix Delegation, and the + Framed-IPv6-Pool Attribute should be used for authorization and + accounting of prefix pools used in SLAAC. + +2.5. Stateful IPv6 Address Pool + + DHCPv6 [RFC3315] provides a mechanism to assign one or more non- + temporary IPv6 addresses to hosts. Section 3.1 introduces the + Framed-IPv6-Address Attribute to be used to provide a DHCPv6 server + residing on a NAS with one or more IPv6 addresses to be assigned to + the clients. An alternative way to achieve a similar result is for + the NAS to select the IPv6 address to be assigned from an address + pool configured for this purpose on the NAS. This document specifies + the Stateful-IPv6-Address-Pool Attribute (Section 3.5) to allow the + RADIUS server to convey a pool name to be used for such stateful + DHCPv6-based addressing and for any subsequent accounting. + +3. Attributes + + The fields shown in the diagrams below are transmitted from left to + right. + +3.1. Framed-IPv6-Address + + The Framed-IPv6-Address Attribute indicates an IPv6 address that is + assigned to the NAS-facing interface of the RG/host. It MAY be used + in Access-Accept packets and MAY appear multiple times. It MAY be + used in an Access-Request packet as a hint by the NAS to the RADIUS + server that it would prefer this IPv6 address, but the RADIUS server + is not required to honor the hint. Because it is assumed that the + + + + + +Dec, et al. Standards Track [Page 6] + +RFC 6911 RADIUS IPv6 Access April 2013 + + + NAS will add a route corresponding to the address, it is not + necessary for the RADIUS server to also send a host Framed-IPv6-Route + Attribute for the same address. + + This Attribute can be used by a DHCPv6 process on the NAS to assign a + unique IPv6 address to the RG/host. + + A summary of the Framed-IPv6-Address Attribute format is shown below. + The format of the Address field is identical to that of the + corresponding field in the NAS-IPv6-Address Attribute [RFC3162]. + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Type | Length | Address + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + Address (cont) + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + Address (cont) + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + Address (cont) + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + Address (cont) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Type + + 168 for Framed-IPv6-Address + + Length + + 18 + + Address + + A 128-bit IPv6 address. + + + + + + + + + + + + + + + +Dec, et al. Standards Track [Page 7] + +RFC 6911 RADIUS IPv6 Access April 2013 + + +3.2. DNS-Server-IPv6-Address + + The DNS-Server-IPv6-Address Attribute contains the IPv6 address of a + DNS server. This Attribute MAY be included multiple times in Access- + Accept packets when the intention is for a NAS to announce more than + one DNS server address to an RG/host. The Attribute MAY be used in + an Access-Request packet as a hint by the NAS to the RADIUS server + regarding the DNS IPv6 address, but the RADIUS server is not required + to honor the hint. + + The content of this Attribute can be copied to an instance of the + DHCPv6 DNS Recursive Name Server Option [RFC3646] or to an IPv6 + Router Advertisement Recursive DNS Server Option [RFC6106]. If more + than one DNS-Server-IPv6-Address Attribute is present in the Access- + Accept packet, the addresses from the Attributes SHOULD be copied in + the same order as received. + + A summary of the DNS-Server-IPv6-Address Attribute format is given + below. The format of the Address field is the same as that of the + corresponding field in the NAS-IPv6-Address Attribute [RFC3162]. + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Type | Length | Address + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + Address (cont) + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + Address (cont) + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + Address (cont) + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + Address (cont) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Type + + 169 for DNS-Server-IPv6-Address + + Length + + 18 + + Address + + The 128-bit IPv6 address of a DNS server. + + + + + +Dec, et al. Standards Track [Page 8] + +RFC 6911 RADIUS IPv6 Access April 2013 + + +3.3. Route-IPv6-Information + + The Route-IPv6-Information Attribute specifies a prefix (and + corresponding route) for the user on the NAS, which is to be + announced using the Route Information Option defined in "Default + Router Preferences and More Specific Routes" [RFC4191], Section 2.3. + It is used in the Access-Accept packet and can appear multiple times. + It MAY be used in an Access-Request packet as a hint by the NAS to + the RADIUS server, but the RADIUS server is not required to honor the + hint. The Route-IPv6-Information Attribute format is depicted below. + The format of the prefix is as per [RFC3162]. + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Type | Length | Reserved | Prefix-Length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | | + . Prefix (variable) . + . . + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Type + + 170 for Route-IPv6-Information + + Length + + Length, in bytes. At least 4 and no larger than 20; typically, 12 + or less. + + Prefix Length + + 8-bit unsigned integer. The number of leading bits in the prefix + that are valid. The value can range from 0 to 128. The prefix + field is 0, 8, or 16 octets depending on Length. + + Prefix + + Variable-length field containing an IP prefix. The prefix length + field contains the number of valid leading bits in the prefix. + The bits in the prefix after the prefix length, if any, are + reserved and MUST be initialized to zero. + + + + + + + +Dec, et al. Standards Track [Page 9] + +RFC 6911 RADIUS IPv6 Access April 2013 + + +3.4. Delegated-IPv6-Prefix-Pool + + The Delegated-IPv6-Prefix-Pool Attribute contains the name of an + assigned pool that SHOULD be used to select an IPv6 delegated prefix + for the user on the NAS. If a NAS does not support prefix pools, the + NAS MUST ignore this Attribute. It MAY be used in an Access-Request + packet as a hint by the NAS to the RADIUS server regarding the pool, + but the RADIUS server is not required to honor the hint. + + A summary of the Delegated-IPv6-Prefix-Pool Attribute format is shown + below. + + 0 1 2 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Type | Length | String... + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Type + + 171 for Delegated-IPv6-Prefix-Pool + + Length + + Length, in bytes. At least 3. + + String + + The string field contains the name of an assigned IPv6 prefix pool + configured on the NAS. The field is not NULL (hexadecimal 00) + terminated. + + Note: The string data type is as documented in [RFC6158] and carries + binary data that is external to the RADIUS protocol, e.g., the name + of a pool of prefixes configured on the NAS. + + + + + + + + + + + + + + + + +Dec, et al. Standards Track [Page 10] + +RFC 6911 RADIUS IPv6 Access April 2013 + + +3.5. Stateful-IPv6-Address-Pool + + The Stateful-IPv6-Address-Pool Attribute contains the name of an + assigned pool that SHOULD be used to select an IPv6 address for the + user on the NAS. If a NAS does not support address pools, the NAS + MUST ignore this Attribute. A summary of the Stateful-IPv6-Address- + Pool Attribute format is shown below. It MAY be used in an Access- + Request packet as a hint by the NAS to the RADIUS server regarding + the pool, but the RADIUS server is not required to honor the hint. + + 0 1 2 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Type | Length | String... + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Type + + 172 for Stateful-IPv6-Address-Pool + + Length + + Length, in bytes. At least 3. + + String + + The string field contains the name of an assigned IPv6 stateful + address pool configured on the NAS. The field is not NULL + (hexadecimal 00) terminated. + + Note: The string data type is as documented in [RFC6158] and carries + binary data that is external to the RADIUS protocol, e.g., the name + of a pool of addresses configured on the NAS. + +3.6. Table of Attributes + + The following table provides a guide to which Attributes may be found + in which kinds of packets, and in what quantity. The optional + inclusion of the options in Access Request messages is intended to + allow for a NAS to provide the RADIUS server with a hint of the + Attributes in advance of user authentication, which may be useful in + cases in which a user reconnects or has a static address. The server + is under no obligation to honor such hints. + + + + + + + + +Dec, et al. Standards Track [Page 11] + +RFC 6911 RADIUS IPv6 Access April 2013 + + + Request Accept Reject Challenge Accounting # Attribute + Request + 0+ 0+ 0 0 0+ 168 Framed-IPv6-Address + 0+ 0+ 0 0 0+ 169 DNS-Server-IPv6-Address + 0+ 0+ 0 0 0+ 170 Route-IPv6-Information + 0+ 0+ 0 0 0+ 171 Delegated-IPv6-Prefix-Pool + 0+ 0+ 0 0 0+ 172 Stateful-IPv6-Address-Pool + +4. Diameter Considerations + + Given that the Attributes defined in this document are allocated from + the standard RADIUS type space (see Section 6), no special handling + is required by Diameter entities. + +5. Security Considerations + + This document specifies additional IPv6 RADIUS Attributes useful in + residential broadband network deployments. In such networks, the + RADIUS protocol may run either over IPv4 or over IPv6, and known + security vulnerabilities of the RADIUS protocol, e.g., [SECI], apply + to the Attributes defined in this document. A trust relationship + between a NAS and RADIUS server is expected to be in place, with + communication optionally secured by IPsec or Transport Layer Security + (TLS) [RFC6614]. + +6. IANA Considerations + + IANA has assigned five new RADIUS Attribute types in the "Radius + Attribute Types" registry (currently located at + http://www.iana.org/assignments/radius-types) for the following + Attributes: + + o Framed-IPv6-Address + + o DNS-Server-IPv6-Address + + o Route-IPv6-Information + + o Delegated-IPv6-Prefix-Pool + + o Stateful-IPv6-Address-Pool + + + + + + + + + + +Dec, et al. Standards Track [Page 12] + +RFC 6911 RADIUS IPv6 Access April 2013 + + +7. Acknowledgments + + The authors would like to thank Bernard Aboba, Benoit Claise, Peter + Deacon, Alan DeKok, Ralph Droms, Brian Haberman, Alfred Hines, + Stephen Farrell, Jouni Korhonen, Roberta Maglione, Pete Resnick, Mark + Smith, and Leaf Yeh for their help and comments in reviewing this + document. + +8. References + +8.1. Normative References + + [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate + Requirement Levels", BCP 14, RFC 2119, March 1997. + + [RFC4862] Thomson, S., Narten, T., and T. Jinmei, "IPv6 Stateless + Address Autoconfiguration", RFC 4862, September 2007. + +8.2. Informative References + + [RFC3162] Aboba, B., Zorn, G., and D. Mitton, "RADIUS and IPv6", RFC + 3162, August 2001. + + [RFC3315] Droms, R., Bound, J., Volz, B., Lemon, T., Perkins, C., + and M. Carney, "Dynamic Host Configuration Protocol for + IPv6 (DHCPv6)", RFC 3315, July 2003. + + [RFC3633] Troan, O. and R. Droms, "IPv6 Prefix Options for Dynamic + Host Configuration Protocol (DHCP) version 6", RFC 3633, + December 2003. + + [RFC3646] Droms, R., "DNS Configuration options for Dynamic Host + Configuration Protocol for IPv6 (DHCPv6)", RFC 3646, + December 2003. + + [RFC4191] Draves, R. and D. Thaler, "Default Router Preferences and + More-Specific Routes", RFC 4191, November 2005. + + [RFC4818] Salowey, J. and R. Droms, "RADIUS Delegated-IPv6-Prefix + Attribute", RFC 4818, April 2007. + + [RFC6106] Jeong, J., Park, S., Beloeil, L., and S. Madanapalli, + "IPv6 Router Advertisement Options for DNS Configuration", + RFC 6106, November 2010. + + [RFC6158] DeKok, A. and G. Weber, "RADIUS Design Guidelines", BCP + 158, RFC 6158, March 2011. + + + + +Dec, et al. Standards Track [Page 13] + +RFC 6911 RADIUS IPv6 Access April 2013 + + + [RFC6614] Winter, S., McCauley, M., Venaas, S., and K. Wierenga, + "Transport Layer Security (TLS) Encryption for RADIUS", + RFC 6614, May 2012. + + [SECI] Hill, J., "An Analysis of the RADIUS Authentication + Protocol", November 2001, <http://regul.uni-mb.si/~meolic/ + ptk-seminarske/radius.pdf>. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Dec, et al. Standards Track [Page 14] + +RFC 6911 RADIUS IPv6 Access April 2013 + + +Authors' Addresses + + Wojciech Dec (editor) + Cisco Systems, Inc. + Haarlerbergweg 13-19 + Amsterdam, Noord-Holland 1101 CH + Netherlands + + EMail: wdec@cisco.com + + + Behcet Sarikaya + Huawei USA + 1700 Alma Drive, Suite 500 + Plano, TX + US + + Phone: +1 972-509-5599 + EMail: sarikaya@ieee.org + + + Glen Zorn (editor) + Network Zen + 227/358 Thanon Sanphawut + Bang Na, Bangkok 10260 + Thailand + + Phone: +66 (0) 8-1000-4155 + EMail: glenzorn@gmail.com + + + David Miles + Google + + EMail: davidmiles@google.com + + + Benoit Lourdelet + Juniper Networks + France + + EMail: blourdel@juniper.net + + + + + + + + + +Dec, et al. Standards Track [Page 15] + |