Access prefix delegations from dhcp6c's script
-
On my WAN interface I have a configuration file override set for the DHCP6 client that allows me to get the 7 /64 prefixes (not contiguous) that are available via DHCPv6-PD from my upstream modem. The configuration looks like this:
interface igb0 { send ia-na 0; send ia-pd 0; send ia-pd 1; send ia-pd 2; send ia-pd 3; send ia-pd 4; send ia-pd 5; send ia-pd 6; #request domain-name-servers; #request domain-name; script "/var/etc/dhcp6c_wan_dhcp6withoutra_script.sh"; }; id-assoc na 0 { }; id-assoc pd 0 { prefix-interface igb2 { sla-id 0; sla-len 0; }; }; id-assoc pd 1 { }; id-assoc pd 2 { }; id-assoc pd 3 { }; id-assoc pd 4 { }; id-assoc pd 5 { }; id-assoc pd 6 { };
I have igb2 set as a track interface so this configuration assigns the first prefix to that interface, but I would like to use the others for DHCPv6 Server prefix delegation. As far as I can tell, these prefix delegations do not get written to anywhere except the log file when debug mode is enabled. I'm not opposed to reading the log file, but is there some configuration I'm missing that would write it to an easier to read format?
My end goal would be to use the leftover prefixes to send to downstream clients via DHCPv6-PD. I think in order to do that I'll need to override the
dhcpd -6
configuration file to add the prefixes. My tests with pfSense usingdhcpd -6
with a custom config seem to suggest this is possible.For example, this will properly allow clients to request a prefix assignment, I just need to know what those prefixes are and update the
dhcpd -6
config file when my WAN dhcp6c gets new prefix delegations.subnet6 2001:db8:3001::/64 { range6 2001:db8:3001::1000 2001:db8:3001::2000; do-forward-updates false; #option dhcp6.name-servers --; prefix6 2001:db8:4000:: 2001:db8:4000:: /64; prefix6 2001:db8:4001:: 2001:db8:4001:: /64; prefix6 2001:db8:4002:: 2001:db8:4002:: /64; prefix6 2001:db8:4003:: 2001:db8:4003:: /64; prefix6 2001:db8:4005:: 2001:db8:4005:: /64; prefix6 2001:db8:4006:: 2001:db8:4006:: /64; prefix6 2001:db8:4007:: 2001:db8:4007:: /64; }
Mar 14 02:34:54 pfSense dhcp6c[45309]: send request to ff02::1:2%vmx0
Mar 14 02:34:54 pfSense dhcp6c[45309]: reset a timer on vmx0, state=REQUEST, timeo=0, retrans=1081
Mar 14 02:34:54 pfSense dhcp6c[45309]: receive reply from fe80::250:56ff:fe9b:177b%vmx0 on vmx0
Mar 14 02:34:54 pfSense dhcp6c[45309]: get DHCP option identity association, len 40
Mar 14 02:34:54 pfSense dhcp6c[45309]: IA_NA: ID=0, T1=0, T2=0
Mar 14 02:34:54 pfSense dhcp6c[45309]: get DHCP option IA address, len 24
Mar 14 02:34:54 pfSense dhcp6c[45309]: IA_NA address: 2001:db8:3001::2000 pltime=4500 vltime=7200
Mar 14 02:34:54 pfSense dhcp6c[45309]: get DHCP option IA_PD, len 41
Mar 14 02:34:54 pfSense dhcp6c[45309]: IA_PD: ID=0, T1=0, T2=0
Mar 14 02:34:54 pfSense dhcp6c[45309]: get DHCP option IA_PD prefix, len 25
Mar 14 02:34:54 pfSense dhcp6c[45309]: IA_PD prefix: 2001:db8:4000::/64 pltime=4500 vltime=17294375700760894496
Mar 14 02:34:54 pfSense dhcp6c[45309]: get DHCP option IA_PD, len 41
Mar 14 02:34:54 pfSense dhcp6c[45309]: IA_PD: ID=1, T1=0, T2=0
Mar 14 02:34:54 pfSense dhcp6c[45309]: get DHCP option IA_PD prefix, len 25
Mar 14 02:34:54 pfSense dhcp6c[45309]: IA_PD prefix: 2001:db8:4001::/64 pltime=4500 vltime=17294375700760894496
Mar 14 02:34:54 pfSense dhcp6c[45309]: get DHCP option IA_PD, len 41
Mar 14 02:34:54 pfSense dhcp6c[45309]: IA_PD: ID=2, T1=0, T2=0
Mar 14 02:34:54 pfSense dhcp6c[45309]: get DHCP option IA_PD prefix, len 25
Mar 14 02:34:54 pfSense dhcp6c[45309]: IA_PD prefix: 2001:db8:4002::/64 pltime=4500 vltime=17294375700760894496
Mar 14 02:34:54 pfSense dhcp6c[45309]: get DHCP option IA_PD, len 41
Mar 14 02:34:54 pfSense dhcp6c[45309]: IA_PD: ID=3, T1=0, T2=0
Mar 14 02:34:54 pfSense dhcp6c[45309]: get DHCP option IA_PD prefix, len 25
Mar 14 02:34:54 pfSense dhcp6c[45309]: IA_PD prefix: 2001:db8:4003::/64 pltime=4500 vltime=17294375700760894496
Mar 14 02:34:54 pfSense dhcp6c[45309]: get DHCP option IA_PD, len 41
Mar 14 02:34:54 pfSense dhcp6c[45309]: IA_PD: ID=4, T1=0, T2=0
Mar 14 02:34:54 pfSense dhcp6c[45309]: get DHCP option IA_PD prefix, len 25
Mar 14 02:34:54 pfSense dhcp6c[45309]: IA_PD prefix: 2001:db8:4005::/64 pltime=4500 vltime=17294375700760894496
Mar 14 02:34:54 pfSense dhcp6c[45309]: get DHCP option IA_PD, len 41
Mar 14 02:34:54 pfSense dhcp6c[45309]: IA_PD: ID=5, T1=0, T2=0
Mar 14 02:34:54 pfSense dhcp6c[45309]: get DHCP option IA_PD prefix, len 25
Mar 14 02:34:54 pfSense dhcp6c[45309]: IA_PD prefix: 2001:db8:4006::/64 pltime=4500 vltime=17294375700760894496
Mar 14 02:34:54 pfSense dhcp6c[45309]: get DHCP option IA_PD, len 41
Mar 14 02:34:54 pfSense dhcp6c[45309]: IA_PD: ID=6, T1=0, T2=0
Mar 14 02:34:54 pfSense dhcp6c[45309]: get DHCP option IA_PD prefix, len 25
Mar 14 02:34:54 pfSense dhcp6c[45309]: IA_PD prefix: 2001:db8:4007::/64 pltime=4500 vltime=17294375700760894496
Mar 14 02:34:54 pfSense dhcp6c[45309]: get DHCP option client ID, len 14
Mar 14 02:34:54 pfSense dhcp6c[45309]: DUID: 00:01:00:01:2d:85:13:1e:00:50:56:9b:9c:a7
Mar 14 02:34:54 pfSense dhcp6c[45309]: get DHCP option server ID, len 14
Mar 14 02:34:54 pfSense dhcp6c[45309]: DUID: 00:01:00:01:2d:85:17:5f:00:50:56:9b:17:7b
Mar 14 02:34:54 pfSense dhcp6c[45309]: dhcp6c Received REQUEST
Mar 14 02:34:54 pfSense dhcp6c[45309]: make an IA: PD-0
Mar 14 02:34:54 pfSense dhcp6c[45309]: create a prefix 2001:db8:4000::/64 pltime=4500, vltime=7200
Mar 14 02:34:54 pfSense dhcp6c[45309]: T1(2250) and/or T2(3600) is locally determined
Mar 14 02:34:54 pfSense dhcp6c[45309]: make an IA: PD-1
Mar 14 02:34:54 pfSense dhcp6c[45309]: create a prefix 2001:db8:4001::/64 pltime=4500, vltime=7200
Mar 14 02:34:54 pfSense dhcp6c[45309]: T1(2250) and/or T2(3600) is locally determined
Mar 14 02:34:54 pfSense dhcp6c[45309]: make an IA: PD-2
Mar 14 02:34:54 pfSense dhcp6c[45309]: create a prefix 2001:db8:4002::/64 pltime=4500, vltime=7200
Mar 14 02:34:54 pfSense dhcp6c[45309]: T1(2250) and/or T2(3600) is locally determined
Mar 14 02:34:54 pfSense dhcp6c[45309]: make an IA: PD-3
Mar 14 02:34:54 pfSense dhcp6c[45309]: create a prefix 2001:db8:4003::/64 pltime=4500, vltime=7200
Mar 14 02:34:54 pfSense dhcp6c[45309]: T1(2250) and/or T2(3600) is locally determined
Mar 14 02:34:54 pfSense dhcp6c[45309]: make an IA: PD-4
Mar 14 02:34:54 pfSense dhcp6c[45309]: create a prefix 2001:db8:4005::/64 pltime=4500, vltime=7200
Mar 14 02:34:54 pfSense dhcp6c[45309]: T1(2250) and/or T2(3600) is locally determined
Mar 14 02:34:54 pfSense dhcp6c[45309]: make an IA: PD-5
Mar 14 02:34:54 pfSense dhcp6c[45309]: create a prefix 2001:db8:4006::/64 pltime=4500, vltime=7200
Mar 14 02:34:54 pfSense dhcp6c[45309]: T1(2250) and/or T2(3600) is locally determined
Mar 14 02:34:54 pfSense dhcp6c[45309]: make an IA: PD-6
Mar 14 02:34:54 pfSense dhcp6c[45309]: create a prefix 2001:db8:4007::/64 pltime=4500, vltime=7200
Mar 14 02:34:54 pfSense dhcp6c[45309]: T1(2250) and/or T2(3600) is locally determined
Mar 14 02:34:54 pfSense dhcp6c[45309]: make an IA: NA-0
Mar 14 02:34:54 pfSense dhcp6c[45309]: create an address 2001:db8:3001::2000 pltime=4500, vltime=34359745568
Mar 14 02:34:54 pfSense dhcp6c[45309]: add an address 2001:db8:3001::2000/128 on vmx0
Mar 14 02:34:54 pfSense dhcp6c[45309]: T1(2250) and/or T2(3600) is locally determined
Mar 14 02:34:54 pfSense dhcp6c[45309]: removing an event on vmx0, state=REQUEST
Mar 14 02:34:54 pfSense dhcp6c[45309]: removing server (ID: 00:01:00:01:2d:85:17:5f:00:50:56:9b:17:7b)
Mar 14 02:34:54 pfSense dhcp6c[45309]: got an expected reply, sleeping.Has anyone worked with such a configuration before? I'm attempting to understand the dhcp6 package source to see if there's additional configuration but my C is not that great.
-
@theit8514 said in Access prefix delegations from dhcp6c's script:
I have igb2 set as a track interface so this configuration assigns the first prefix to that interface, but I would like to use the others for DHCPv6 Server prefix delegation. As far as I can tell, these prefix delegations do not get written to anywhere except the log file when debug mode is enabled.
You've used one prefix on igb2.
Probably with tracking ID "0".Now, add another LAN , use IPv6 tracking , and select ID "1".
Your ID runs from 0 to 6, as you've set up.
And the up stream DHCP6 server actually gave you a WAN IPv6, and 6 /64 prefixes@theit8514 said in Access prefix delegations from dhcp6c's script:
I'm not opposed to reading the log file
Euhhhh .... reading logs is - IMHO - mandatory. That's how the system communicates with you ^^
Btw : keep in mind : while dhcpc, the IPv4 counterpart, has been well defined, and most equipment and ISPs on earth respect the rules (RFCs), this is not the case with IPv6 : it's still a mess.
Every ISP oit there has its own interpretation of how IPv6 (the dhcpd client server relation) should be interpreted.
That said, while looking at your log, it looks like a close to if not perfect reading about how to get a WAN IP and 7 prefixes, your IPv6 was assigned to vm0add an address 2001:db8:xxxx::2000/128 on vmx0
@theit8514 said in Access prefix delegations from dhcp6c's script:
but my C is not that great
Go for the man pages first. You won't find them on pfSense, but dhcp6c is a FreeBSD 14.0 binary, so it's available on the net.
@theit8514 said in Access prefix delegations from dhcp6c's script:
Has anyone worked with such a configuration before?
Oh, yes.
As I have an ISP that says it has a /56 for me.But when I ask for several prefixes, using the default pfSense config, or create, like you, my own dhcp6c config file, they only give me one /64 prefix, not more. It's a known stupid limitation of my ISP (their boxes actually, as the box has access to the /56 but its dhcp6 server is very limited).
Some how, my ISP doesn't know that behind their 'box' clients (me) can place another router (pfSense) which more then one LAN. -
@Gertjan said in Access prefix delegations from dhcp6c's script:
Now, add another LAN , use IPv6 tracking , and select ID "1".
Your ID runs from 0 to 6, as you've set up.
And the up stream DHCP6 server actually gave you a WAN IPv6, and 6 /64 prefixesI think you misunderstand what I'm trying to accomplish. I understand I can assign prefixes to interfaces directly. I want to assign those prefixes from my WAN to the DHCPv6 Server as prefix delegations. Right now DHCPv6 Server configuration only supports a single, contiguous prefix delegation block, and not multiple prefix delegations.
Euhhhh .... reading logs is - IMHO - mandatory. That's how the system communicates with you ^^
I should have said parsing not reading. The prefixes appear to only be written to the /var/log/dhcpd.log file and only when debug mode is enabled. In order to write them as an override to the DHCPv6 Server config, I would need to parse them from the log and write them as prefix6 statements as shown in my original message. I'm just looking to see if there's a better way to get the information from the DHCPv6 Client process than parsing the log file.
-
@theit8514 said in Access prefix delegations from dhcp6c's script:
ight now DHCPv6 Server configuration only supports a single, contiguous prefix delegation block, and not multiple prefix delegations.
You received 7 prefixes.
On My (a) LAN interface, where I've selected 'IPv6 Tracking', I've selected :Where my ID is "0 to 0" as I have only one prefix.
Does yours show "0 to 6 ?"
I presume you have 7 LAN's, and you should be able (?) to assign one prefix to every LAN.
My DHCP6 LAN Server shows :Is this the part that you want to use :
?
Is it the "Delegation pool" that interest you ? -
@Gertjan said in Access prefix delegations from dhcp6c's script:
Where my ID is "0 to 0" as I have only one prefix.
Since I'm using a custom configuration, I also only have 0 to 0. Only a single prefix can be assigned to a directly attached interface. I'm doing it manually via the custom DHCPv6 client configuration:
id-assoc pd 0 { prefix-interface igb2 { sla-id 0; sla-len 0; }; };
@Gertjan said in Access prefix delegations from dhcp6c's script:
Is it the "Delegation pool" that interest you ?
Yes, this is where I would like to assign the other 6 prefixes I get from my modem. However the field only accepts a single block of IPv6 Prefixes. I can either:
- Select the delegation size of /61 and delegate the whole /61 which is 4000-4007. This will incorrectly delegate a 4004 prefix which was not delegated to me by the modem.
- Select the delegation size of /64 and set the range to 4000 to 4007. This will incorrectly delegate a 4004 prefix which was not delegated to me by the modem.
As you can see, my issue is that I don't have a contiguous block of IPv6 prefixes to assign out, so this configuration page is no use to me as it only writes a single prefix6 statement to the dhcpv6.conf file.
In my tests, I am able to define multiple prefix6 statements in the dhcpv6.conf file and the
dhcp -6
process correctly assigns out those prefixes, but I can't configure that from the Prefix Delegation Pool settings page. I would need a custom dhcpv6.conf file and I would need to generate it from the known delegated prefixes that I get from the DHCPv6 client. The only way I can seem to get this data is from the log file, which is difficult to parse (I've seen multiple DHCP packets overlap in the config, and the data I need is not written to a single line). I think my best bet would be to change how it logs this data so I can easily parse it without debug mode, thus my look into the dhcp6 package source.In addition to all that, the pfsense prefixes.php that parses the leases file and generates routes for PD does not correctly handle multiple prefixes assigned to a single ia-na. I have a patch ready for that.
-
Been working on a patch for dhcp6c. I have gotten to the point where I can collect all the information needed in one place and easily parsable by a script:
grep "prefix allocated" /var/log/dhcpd.log Mar 23 17:04:09 pfSense dhcp6c[70335]: prefix allocated 2001:db8:4000::/64 iaid=0 ifname=vmx2 Mar 23 17:04:09 pfSense dhcp6c[70335]: prefix allocated 2001:db8:4001::/64 iaid=1 floating=true Mar 23 17:04:09 pfSense dhcp6c[70335]: prefix allocated 2001:db8:4002::/64 iaid=2 floating=true Mar 23 17:04:09 pfSense dhcp6c[70335]: prefix allocated 2001:db8:4003::/64 iaid=3 floating=true Mar 23 17:04:09 pfSense dhcp6c[70335]: prefix allocated 2001:db8:4005::/64 iaid=4 floating=true Mar 23 17:04:09 pfSense dhcp6c[70335]: prefix allocated 2001:db8:4006::/64 iaid=5 floating=true Mar 23 17:04:09 pfSense dhcp6c[70335]: prefix allocated 2001:db8:4007::/64 iaid=6 floating=true
Patch is below. Pretty sure it can be optimized further. If any expert in C happens to know why I can't seem to use
struct ia *ia
's copy ofia->conf->iaid
that would save me having to pass the dhcp6_ia struct. I get:prefixconf.c:231:6: error: incomplete definition of type 'struct ia'
diff --git a/dhcp6c_ia.c b/dhcp6c_ia.c index 9f9ca84..473fc58 100644 --- a/dhcp6c_ia.c +++ b/dhcp6c_ia.c @@ -152,7 +152,7 @@ update_ia(iatype, ialist, ifp, serverid, authparam) case DHCP6_LISTVAL_PREFIX6: /* add or update the prefix */ iapdc = (struct iapd_conf *)iac; - if (update_prefix(ia, &siav->val_prefix6, + if (update_prefix(ia, &iav->val_ia, &siav->val_prefix6, &iapdc->iapd_pif_list, ifp, &ia->ctl, callback)) { d_printf(LOG_NOTICE, FNAME, diff --git a/prefixconf.c b/prefixconf.c index bbb4d6e..582f192 100644 --- a/prefixconf.c +++ b/prefixconf.c @@ -119,8 +119,9 @@ extern struct dhcp6_timer *client6_timo __P((void *)); static int pd_ifaddrconf __P((ifaddrconf_cmd_t, struct dhcp6_ifprefix *ifpfx)); int -update_prefix(ia, pinfo, pifc, dhcpifp, ctlp, callback) +update_prefix(ia, iinfo, pinfo, pifc, dhcpifp, ctlp, callback) struct ia *ia; + struct dhcp6_ia *iinfo; struct dhcp6_prefix *pinfo; struct pifc_list *pifc; struct dhcp6_if *dhcpifp; @@ -197,6 +198,7 @@ update_prefix(ia, pinfo, pifc, dhcpifp, ctlp, callback) in6addr2str(&pinfo->addr, 0), pinfo->plen, pinfo->pltime, pinfo->vltime); + int allocated = 0; /* update prefix interfaces if necessary */ if (sp->prefix.vltime != 0 && spcreate) { for (pif = TAILQ_FIRST(iac_pd->pifc_head); pif; @@ -215,10 +217,21 @@ update_prefix(ia, pinfo, pifc, dhcpifp, ctlp, callback) continue; } + allocated = 1; + d_printf(LOG_INFO, FNAME, "prefix allocated %s/%d iaid=%u ifname=%s", + in6addr2str(&pinfo->addr, 0), pinfo->plen, + iinfo->iaid, + pif->ifname); add_ifprefix(sp, pinfo, pif); } } + if (allocated == 0) { + d_printf(LOG_INFO, FNAME, "prefix allocated %s/%d iaid=%u floating=true", + in6addr2str(&pinfo->addr, 0), pinfo->plen, + iinfo->iaid); + } + /* * If the new vltime is 0, this prefix immediately expires. * Otherwise, set up or update the associated timer. diff --git a/prefixconf.h b/prefixconf.h index dcff695..3dd5986 100644 --- a/prefixconf.h +++ b/prefixconf.h @@ -32,7 +32,7 @@ typedef enum { PREFIX6S_ACTIVE, PREFIX6S_RENEW, PREFIX6S_REBIND} prefix6state_t; -extern int update_prefix __P((struct ia *, struct dhcp6_prefix *, +extern int update_prefix __P((struct ia *, struct dhcp6_ia *, struct dhcp6_prefix *, struct pifc_list *, struct dhcp6_if *, struct iactl **, void (*)__P((struct ia *)))); extern int prefix6_add __P((struct dhcp6_if *, struct dhcp6_prefix *,
Next steps for me will be looking at adding a custom DHCPv6 server configuration file field to the UI, like can be done for the interface DHCPv6 client configuration.