Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
D
dhcp
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
72
Issues
72
List
Boards
Labels
Service Desk
Milestones
Merge Requests
18
Merge Requests
18
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ISC Open Source Projects
dhcp
Commits
1d9774ab
Commit
1d9774ab
authored
Jan 02, 2008
by
Francis Dupont
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Cleanup IA_NA dependencies
parent
96b620e5
Changes
12
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
3473 additions
and
546 deletions
+3473
-546
client/clparse.c
client/clparse.c
+391
-3
client/dhc6.c
client/dhc6.c
+418
-29
client/dhclient.c
client/dhclient.c
+32
-8
common/conflex.c
common/conflex.c
+6
-0
common/parse.c
common/parse.c
+41
-0
includes/dhcpd.h
includes/dhcpd.h
+114
-5
includes/dhctoken.h
includes/dhctoken.h
+16
-13
server/confpars.c
server/confpars.c
+601
-19
server/db.c
server/db.c
+119
-8
server/dhcpd.c
server/dhcpd.c
+9
-3
server/dhcpv6.c
server/dhcpv6.c
+76
-50
server/mdb6.c
server/mdb6.c
+1650
-408
No files found.
client/clparse.c
View file @
1d9774ab
...
...
@@ -43,8 +43,11 @@ struct option *default_requested_options[NUM_DEFAULT_REQUESTED_OPTS + 1];
static
void
parse_client_default_duid
(
struct
parse
*
cfile
);
static
void
parse_client6_lease_statement
(
struct
parse
*
cfile
);
#ifdef DHCPv6
static
struct
dhc6_ia
*
parse_client6_ia_statement
(
struct
parse
*
cfile
);
static
struct
dhc6_ia
*
parse_client6_ia_na_statement
(
struct
parse
*
cfile
);
static
struct
dhc6_ia
*
parse_client6_ia_ta_statement
(
struct
parse
*
cfile
);
static
struct
dhc6_ia
*
parse_client6_ia_pd_statement
(
struct
parse
*
cfile
);
static
struct
dhc6_addr
*
parse_client6_iaaddr_statement
(
struct
parse
*
cfile
);
static
struct
dhc6_addr
*
parse_client6_iaprefix_statement
(
struct
parse
*
cfile
);
#endif
/* DHCPv6 */
/* client-conf-file :== client-declarations END_OF_FILE
...
...
@@ -1292,7 +1295,29 @@ parse_client6_lease_statement(struct parse *cfile)
switch
(
token
)
{
case
IA_NA
:
*
ia
=
parse_client6_ia_statement
(
cfile
);
*
ia
=
parse_client6_ia_na_statement
(
cfile
);
if
(
*
ia
!=
NULL
)
{
ia
=
&
(
*
ia
)
->
next
;
has_ia
=
1
;
}
no_semi
=
1
;
break
;
case
IA_TA
:
*
ia
=
parse_client6_ia_ta_statement
(
cfile
);
if
(
*
ia
!=
NULL
)
{
ia
=
&
(
*
ia
)
->
next
;
has_ia
=
1
;
}
no_semi
=
1
;
break
;
case
IA_PD
:
*
ia
=
parse_client6_ia_pd_statement
(
cfile
);
if
(
*
ia
!=
NULL
)
{
ia
=
&
(
*
ia
)
->
next
;
has_ia
=
1
;
...
...
@@ -1461,7 +1486,7 @@ parse_client6_lease_statement(struct parse *cfile)
*/
#ifdef DHCPv6
static
struct
dhc6_ia
*
parse_client6_ia_statement
(
struct
parse
*
cfile
)
parse_client6_ia_
na_
statement
(
struct
parse
*
cfile
)
{
struct
data_string
id
;
struct
option_cache
*
oc
=
NULL
;
...
...
@@ -1476,6 +1501,7 @@ parse_client6_ia_statement(struct parse *cfile)
skip_to_semi
(
cfile
);
return
NULL
;
}
ia
->
ia_type
=
D6O_IA_NA
;
/* Get IAID. */
memset
(
&
id
,
0
,
sizeof
(
id
));
...
...
@@ -1593,6 +1619,260 @@ parse_client6_ia_statement(struct parse *cfile)
}
#endif
/* DHCPv6 */
/* Parse an ia_ta object from the client lease.
*/
#ifdef DHCPv6
static
struct
dhc6_ia
*
parse_client6_ia_ta_statement
(
struct
parse
*
cfile
)
{
struct
data_string
id
;
struct
option_cache
*
oc
=
NULL
;
struct
dhc6_ia
*
ia
;
struct
dhc6_addr
**
addr
;
const
char
*
val
;
int
token
,
no_semi
;
ia
=
dmalloc
(
sizeof
(
*
ia
),
MDL
);
if
(
ia
==
NULL
)
{
parse_warn
(
cfile
,
"Out of memory allocating IA_TA state."
);
skip_to_semi
(
cfile
);
return
NULL
;
}
ia
->
ia_type
=
D6O_IA_TA
;
/* Get IAID. */
memset
(
&
id
,
0
,
sizeof
(
id
));
if
(
parse_cshl
(
&
id
,
cfile
))
{
if
(
id
.
len
==
4
)
memcpy
(
ia
->
iaid
,
id
.
data
,
4
);
else
{
parse_warn
(
cfile
,
"Expecting IAID of length 4, got %d."
,
id
.
len
);
skip_to_semi
(
cfile
);
dfree
(
ia
,
MDL
);
return
NULL
;
}
data_string_forget
(
&
id
,
MDL
);
}
else
{
parse_warn
(
cfile
,
"Expecting IAID."
);
skip_to_semi
(
cfile
);
dfree
(
ia
,
MDL
);
return
NULL
;
}
token
=
next_token
(
NULL
,
NULL
,
cfile
);
if
(
token
!=
LBRACE
)
{
parse_warn
(
cfile
,
"Expecting open curly brace."
);
skip_to_semi
(
cfile
);
dfree
(
ia
,
MDL
);
return
NULL
;
}
option_state_allocate
(
&
ia
->
options
,
MDL
);
if
(
ia
->
options
==
NULL
)
{
parse_warn
(
cfile
,
"Unable to allocate option state."
);
skip_to_rbrace
(
cfile
,
1
);
dfree
(
ia
,
MDL
);
return
NULL
;
}
addr
=
&
ia
->
addrs
;
token
=
next_token
(
&
val
,
NULL
,
cfile
);
while
(
token
!=
RBRACE
)
{
no_semi
=
0
;
switch
(
token
)
{
case
STARTS
:
token
=
next_token
(
&
val
,
NULL
,
cfile
);
if
(
token
==
NUMBER
)
{
ia
->
starts
=
atoi
(
val
);
}
else
{
parse_warn
(
cfile
,
"Expecting a number."
);
skip_to_semi
(
cfile
);
no_semi
=
1
;
}
break
;
/* No RENEW or REBIND */
case
IAADDR
:
*
addr
=
parse_client6_iaaddr_statement
(
cfile
);
if
(
*
addr
!=
NULL
)
addr
=
&
(
*
addr
)
->
next
;
no_semi
=
1
;
break
;
case
OPTION
:
if
(
parse_option_decl
(
&
oc
,
cfile
))
{
save_option
(
oc
->
option
->
universe
,
ia
->
options
,
oc
);
option_cache_dereference
(
&
oc
,
MDL
);
}
no_semi
=
1
;
break
;
default:
parse_warn
(
cfile
,
"Unexpected token."
);
no_semi
=
1
;
skip_to_semi
(
cfile
);
break
;
}
if
(
!
no_semi
)
parse_semi
(
cfile
);
token
=
next_token
(
&
val
,
NULL
,
cfile
);
if
(
token
==
END_OF_FILE
)
{
parse_warn
(
cfile
,
"Unexpected end of file."
);
break
;
}
}
return
ia
;
}
#endif
/* DHCPv6 */
/* Parse an ia_pd object from the client lease.
*/
#ifdef DHCPv6
static
struct
dhc6_ia
*
parse_client6_ia_pd_statement
(
struct
parse
*
cfile
)
{
struct
data_string
id
;
struct
option_cache
*
oc
=
NULL
;
struct
dhc6_ia
*
ia
;
struct
dhc6_addr
**
pref
;
const
char
*
val
;
int
token
,
no_semi
;
ia
=
dmalloc
(
sizeof
(
*
ia
),
MDL
);
if
(
ia
==
NULL
)
{
parse_warn
(
cfile
,
"Out of memory allocating IA_PD state."
);
skip_to_semi
(
cfile
);
return
NULL
;
}
ia
->
ia_type
=
D6O_IA_PD
;
/* Get IAID. */
memset
(
&
id
,
0
,
sizeof
(
id
));
if
(
parse_cshl
(
&
id
,
cfile
))
{
if
(
id
.
len
==
4
)
memcpy
(
ia
->
iaid
,
id
.
data
,
4
);
else
{
parse_warn
(
cfile
,
"Expecting IAID of length 4, got %d."
,
id
.
len
);
skip_to_semi
(
cfile
);
dfree
(
ia
,
MDL
);
return
NULL
;
}
data_string_forget
(
&
id
,
MDL
);
}
else
{
parse_warn
(
cfile
,
"Expecting IAID."
);
skip_to_semi
(
cfile
);
dfree
(
ia
,
MDL
);
return
NULL
;
}
token
=
next_token
(
NULL
,
NULL
,
cfile
);
if
(
token
!=
LBRACE
)
{
parse_warn
(
cfile
,
"Expecting open curly brace."
);
skip_to_semi
(
cfile
);
dfree
(
ia
,
MDL
);
return
NULL
;
}
option_state_allocate
(
&
ia
->
options
,
MDL
);
if
(
ia
->
options
==
NULL
)
{
parse_warn
(
cfile
,
"Unable to allocate option state."
);
skip_to_rbrace
(
cfile
,
1
);
dfree
(
ia
,
MDL
);
return
NULL
;
}
pref
=
&
ia
->
addrs
;
token
=
next_token
(
&
val
,
NULL
,
cfile
);
while
(
token
!=
RBRACE
)
{
no_semi
=
0
;
switch
(
token
)
{
case
STARTS
:
token
=
next_token
(
&
val
,
NULL
,
cfile
);
if
(
token
==
NUMBER
)
{
ia
->
starts
=
atoi
(
val
);
}
else
{
parse_warn
(
cfile
,
"Expecting a number."
);
skip_to_semi
(
cfile
);
no_semi
=
1
;
}
break
;
case
RENEW
:
token
=
next_token
(
&
val
,
NULL
,
cfile
);
if
(
token
==
NUMBER
)
{
ia
->
renew
=
atoi
(
val
);
}
else
{
parse_warn
(
cfile
,
"Expecting a number."
);
skip_to_semi
(
cfile
);
no_semi
=
1
;
}
break
;
case
REBIND
:
token
=
next_token
(
&
val
,
NULL
,
cfile
);
if
(
token
==
NUMBER
)
{
ia
->
rebind
=
atoi
(
val
);
}
else
{
parse_warn
(
cfile
,
"Expecting a number."
);
skip_to_semi
(
cfile
);
no_semi
=
1
;
}
break
;
case
IAPREFIX
:
*
pref
=
parse_client6_iaprefix_statement
(
cfile
);
if
(
*
pref
!=
NULL
)
pref
=
&
(
*
pref
)
->
next
;
no_semi
=
1
;
break
;
case
OPTION
:
if
(
parse_option_decl
(
&
oc
,
cfile
))
{
save_option
(
oc
->
option
->
universe
,
ia
->
options
,
oc
);
option_cache_dereference
(
&
oc
,
MDL
);
}
no_semi
=
1
;
break
;
default:
parse_warn
(
cfile
,
"Unexpected token."
);
no_semi
=
1
;
skip_to_semi
(
cfile
);
break
;
}
if
(
!
no_semi
)
parse_semi
(
cfile
);
token
=
next_token
(
&
val
,
NULL
,
cfile
);
if
(
token
==
END_OF_FILE
)
{
parse_warn
(
cfile
,
"Unexpected end of file."
);
break
;
}
}
return
ia
;
}
#endif
/* DHCPv6 */
/* Parse an iaaddr {} structure. */
#ifdef DHCPv6
static
struct
dhc6_addr
*
...
...
@@ -1701,6 +1981,114 @@ parse_client6_iaaddr_statement(struct parse *cfile)
}
#endif
/* DHCPv6 */
/* Parse an iaprefix {} structure. */
#ifdef DHCPv6
static
struct
dhc6_addr
*
parse_client6_iaprefix_statement
(
struct
parse
*
cfile
)
{
struct
option_cache
*
oc
=
NULL
;
struct
dhc6_addr
*
pref
;
const
char
*
val
;
int
token
,
no_semi
;
pref
=
dmalloc
(
sizeof
(
*
pref
),
MDL
);
if
(
pref
==
NULL
)
{
parse_warn
(
cfile
,
"Unable to allocate IAPREFIX state."
);
skip_to_semi
(
cfile
);
return
NULL
;
}
/* Get IP prefix. */
if
(
!
parse_ip6_prefix
(
cfile
,
&
pref
->
address
,
&
pref
->
plen
))
{
skip_to_semi
(
cfile
);
dfree
(
pref
,
MDL
);
return
NULL
;
}
token
=
next_token
(
NULL
,
NULL
,
cfile
);
if
(
token
!=
LBRACE
)
{
parse_warn
(
cfile
,
"Expecting open curly bracket."
);
skip_to_semi
(
cfile
);
dfree
(
pref
,
MDL
);
return
NULL
;
}
option_state_allocate
(
&
pref
->
options
,
MDL
);
if
(
pref
->
options
==
NULL
)
{
parse_warn
(
cfile
,
"Unable to allocate option state."
);
skip_to_semi
(
cfile
);
dfree
(
pref
,
MDL
);
return
NULL
;
}
token
=
next_token
(
&
val
,
NULL
,
cfile
);
while
(
token
!=
RBRACE
)
{
no_semi
=
0
;
switch
(
token
)
{
case
STARTS
:
token
=
next_token
(
&
val
,
NULL
,
cfile
);
if
(
token
==
NUMBER
)
{
pref
->
starts
=
atoi
(
val
);
}
else
{
parse_warn
(
cfile
,
"Expecting a number."
);
skip_to_semi
(
cfile
);
no_semi
=
1
;
}
break
;
case
PREFERRED_LIFE
:
token
=
next_token
(
&
val
,
NULL
,
cfile
);
if
(
token
==
NUMBER
)
{
pref
->
preferred_life
=
atoi
(
val
);
}
else
{
parse_warn
(
cfile
,
"Expecting a number."
);
skip_to_semi
(
cfile
);
no_semi
=
1
;
}
break
;
case
MAX_LIFE
:
token
=
next_token
(
&
val
,
NULL
,
cfile
);
if
(
token
==
NUMBER
)
{
pref
->
max_life
=
atoi
(
val
);
}
else
{
parse_warn
(
cfile
,
"Expecting a number."
);
skip_to_semi
(
cfile
);
no_semi
=
1
;
}
break
;
case
OPTION
:
if
(
parse_option_decl
(
&
oc
,
cfile
))
{
save_option
(
oc
->
option
->
universe
,
pref
->
options
,
oc
);
option_cache_dereference
(
&
oc
,
MDL
);
}
no_semi
=
1
;
break
;
default:
parse_warn
(
cfile
,
"Unexpected token."
);
skip_to_rbrace
(
cfile
,
1
);
no_semi
=
1
;
break
;
}
if
(
!
no_semi
)
parse_semi
(
cfile
);
token
=
next_token
(
&
val
,
NULL
,
cfile
);
if
(
token
==
END_OF_FILE
)
{
parse_warn
(
cfile
,
"Unexpected end of file."
);
break
;
}
}
return
pref
;
}
#endif
/* DHCPv6 */
void
parse_string_list
(
cfile
,
lp
,
multiple
)
struct
parse
*
cfile
;
struct
string_list
**
lp
;
...
...
client/dhc6.c
View file @
1d9774ab
This diff is collapsed.
Click to expand it.
client/dhclient.c
View file @
1d9774ab
...
...
@@ -2487,6 +2487,7 @@ write_client6_lease(struct client_state *client, struct dhc6_lease *lease,
struct
dhc6_ia
*
ia
;
struct
dhc6_addr
*
addr
;
int
stat
;
const
char
*
ianame
;
/* This should include the current lease. */
if
(
!
rewrite
&&
(
leases_written
++
>
20
))
{
...
...
@@ -2516,21 +2517,44 @@ write_client6_lease(struct client_state *client, struct dhc6_lease *lease,
return
ISC_R_IOERROR
;
for
(
ia
=
lease
->
bindings
;
ia
!=
NULL
;
ia
=
ia
->
next
)
{
stat
=
fprintf
(
leaseFile
,
" ia-na %s {
\n
"
,
print_hex_1
(
4
,
ia
->
iaid
,
12
));
switch
(
ia
->
ia_type
)
{
case
D6O_IA_NA
:
default:
ianame
=
"ia-na"
;
break
;
case
D6O_IA_TA
:
ianame
=
"ia-ta"
;
break
;
case
D6O_IA_PD
:
ianame
=
"ia-pd"
;
break
;
}
stat
=
fprintf
(
leaseFile
,
" %s %s {
\n
"
,
ianame
,
print_hex_1
(
4
,
ia
->
iaid
,
12
));
if
(
stat
<=
0
)
return
ISC_R_IOERROR
;
stat
=
fprintf
(
leaseFile
,
" starts %d;
\n
"
" renew %u;
\n
"
" rebind %u;
\n
"
,
(
int
)
ia
->
starts
,
ia
->
renew
,
ia
->
rebind
);
if
(
ia
->
ia_type
!=
D6O_IA_TA
)
stat
=
fprintf
(
leaseFile
,
" starts %d;
\n
"
" renew %u;
\n
"
" rebind %u;
\n
"
,
(
int
)
ia
->
starts
,
ia
->
renew
,
ia
->
rebind
);
else
stat
=
fprintf
(
leaseFile
,
" starts %d;
\n
"
,
(
int
)
ia
->
starts
);
if
(
stat
<=
0
)
return
ISC_R_IOERROR
;
for
(
addr
=
ia
->
addrs
;
addr
!=
NULL
;
addr
=
addr
->
next
)
{
stat
=
fprintf
(
leaseFile
,
" iaaddr %s {
\n
"
,
piaddr
(
addr
->
address
));
if
(
ia
->
ia_type
!=
D6O_IA_PD
)
stat
=
fprintf
(
leaseFile
,
" iaaddr %s {
\n
"
,
piaddr
(
addr
->
address
));
else
stat
=
fprintf
(
leaseFile
,
" iaprefix %s/%d {
\n
"
,
piaddr
(
addr
->
address
),
(
int
)
addr
->
plen
);
if
(
stat
<=
0
)
return
ISC_R_IOERROR
;
...
...
common/conflex.c
View file @
1d9774ab
...
...
@@ -951,8 +951,14 @@ intern(char *atom, enum dhcp_token dfv) {
case
'i'
:
if
(
!
strcasecmp
(
atom
+
1
,
"a-na"
))
return
IA_NA
;
if
(
!
strcasecmp
(
atom
+
1
,
"a-ta"
))
return
IA_TA
;
if
(
!
strcasecmp
(
atom
+
1
,
"a-pd"
))
return
IA_PD
;
if
(
!
strcasecmp
(
atom
+
1
,
"aaddr"
))
return
IAADDR
;
if
(
!
strcasecmp
(
atom
+
1
,
"aprefix"
))
return
IAPREFIX
;
if
(
!
strcasecmp
(
atom
+
1
,
"nclude"
))
return
INCLUDE
;
if
(
!
strcasecmp
(
atom
+
1
,
"nteger"
))
...
...
common/parse.c
View file @
1d9774ab
...
...
@@ -434,6 +434,47 @@ parse_ip6_addr_expr(struct expression **expr,
return
make_const_data
(
expr
,
addr
.
iabuf
,
addr
.
len
,
0
,
1
,
MDL
);
}
/*
* ip6-prefix :== ip6-address "/" NUMBER
*/
int
parse_ip6_prefix
(
struct
parse
*
cfile
,
struct
iaddr
*
addr
,
u_int8_t
*
plen
)
{
enum
dhcp_token
token
;
const
char
*
val
;
int
n
;
if
(
!
parse_ip6_addr
(
cfile
,
addr
))
{
return
0
;
}
token
=
next_token
(
&
val
,
NULL
,
cfile
);
if
(
token
!=
SLASH
)
{
parse_warn
(
cfile
,
"Slash expected."
);
if
(
token
!=
SEMI
)
skip_to_semi
(
cfile
);
return
0
;
}
token
=
next_token
(
&
val
,
NULL
,
cfile
);
if
(
token
!=
NUMBER
)
{
parse_warn
(
cfile
,
"Number expected."
);
if
(
token
!=
SEMI
)
skip_to_semi
(
cfile
);
return
0
;
}
n
=
atoi
(
val
);
if
((
n
<
0
)
||
(
n
>
128
))
{
parse_warn
(
cfile
,
"Invalid IPv6 prefix length."
);
skip_to_semi
(
cfile
);
return
0
;
}
if
(
!
is_cidr_mask_valid
(
addr
,
n
))
{
parse_warn
(
cfile
,
"network mask too short."
);
skip_to_semi
(
cfile
);
return
0
;
}
*
plen
=
n
;
return
1
;
}
/*
* ip-address-with-subnet :== ip-address |
* ip-address "/" NUMBER
...
...
includes/dhcpd.h
View file @
1d9774ab
...
...
@@ -889,6 +889,7 @@ struct client_lease {
struct
dhc6_addr
{
struct
dhc6_addr
*
next
;
struct
iaddr
address
;
u_int8_t
plen
;
/* Address state flags. */
#define DHC6_ADDR_DEPREFFED 0x01
...
...
@@ -905,6 +906,7 @@ struct dhc6_addr {
struct
dhc6_ia
{
struct
dhc6_ia
*
next
;
unsigned
char
iaid
[
4
];
u_int16_t
ia_type
;
TIME
starts
;
u_int32_t
renew
;
...
...
@@ -1308,6 +1310,7 @@ typedef struct hash_table iaaddr_hash_t;
struct
iaaddr
{
int
refcnt
;
/* reference count */
struct
in6_addr
addr
;
/* IPv6 address */
u_int8_t
plen
;
/* unused/placeholder */
binding_state_t
state
;
/* state */
struct
binding_scope
*
scope
;
/* "set var = value;" */
time_t
valid_lifetime_end_time
;
/* time address expires */
...
...
@@ -1326,12 +1329,14 @@ struct iaaddr {
struct
ia_na
{
int
refcnt
;
/* reference count */
struct
data_string
iaid_duid
;
/* from the client */
u_int16_t
ia_type
;
/* IA_NA or IA_TA */
int
num_iaaddr
;
/* number of IAADDR for this IA_NA */
int
max_iaaddr
;
/* space available for IAADDR */
struct
iaaddr
**
iaaddr
;
/* pointers to the various IAADDRs */
};
extern
ia_na_hash_t
*
ia_active
;
extern
ia_na_hash_t
*
ia_na_active
;
extern
ia_na_hash_t
*
ia_ta_active
;
struct
ipv6_pool
{
int
refcnt
;
/* reference count */
...
...
@@ -1350,6 +1355,51 @@ struct ipv6_pool {
extern
struct
ipv6_pool
**
pools
;
extern
int
num_pools
;
/* Sames thing for IA_PDs */
typedef
struct
hash_table
ia_pd_hash_t
;
typedef
struct
hash_table
iaprefix_hash_t
;
struct
iaprefix
{
/* Must keep the same layout than iaaddr */
int
refcnt
;
/* reference count */
struct
in6_addr
pref
;
/* IPv6 prefix */
u_int8_t
plen
;
/* prefix length */
binding_state_t
state
;
/* state */
struct
binding_scope
*
scope
;
/* "set var = value;" */
time_t
valid_lifetime_end_time
;
/* time prefix expires */
struct
ia_pd
*
ia_pd
;
/* IA for this prefix */
struct
ipv6_ppool
*
ipv6_ppool
;
/* pool for this prefix */
int
heap_index
;
/* index into heap, or -1
(internal use only) */
};