Netgate Discussion Forum
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Search
    • Register
    • Login

    Access prefix delegations from dhcp6c's script

    Scheduled Pinned Locked Moved IPv6
    6 Posts 2 Posters 767 Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • T
      theit8514
      last edited by

      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 using dhcpd -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.

      GertjanG 1 Reply Last reply Reply Quote 0
      • GertjanG
        Gertjan @theit8514
        last edited by

        @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".

        dc1ec274-6b23-4c92-b5c3-5f6fe177aece-image.png

        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 vm0

        add 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.

        ed744224-520c-40f1-a996-5f7f883f5de7-image.png

        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.

        No "help me" PM's please. Use the forum, the community will thank you.
        Edit : and where are the logs ??

        T 1 Reply Last reply Reply Quote 0
        • T
          theit8514 @Gertjan
          last edited by

          @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 prefixes ๐Ÿ‘

          I 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.

          GertjanG 1 Reply Last reply Reply Quote 0
          • GertjanG
            Gertjan @theit8514
            last edited by

            @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 :

            b5025ff2-816b-4ebf-badc-233e0973443d-image.png

            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 :

            bc3414d5-e386-45ab-a672-9df0ca83d71e-image.png

            Is this the part that you want to use :

            7e8bacae-e8e6-471d-a01f-a35d0c2882ff-image.png

            ?
            Is it the "Delegation pool" that interest you ?

            No "help me" PM's please. Use the forum, the community will thank you.
            Edit : and where are the logs ??

            T 1 Reply Last reply Reply Quote 0
            • T
              theit8514 @Gertjan
              last edited by

              @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:

              1. 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.
              2. 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.

              T 1 Reply Last reply Reply Quote 0
              • T
                theit8514 @theit8514
                last edited by

                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 of ia->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.

                1 Reply Last reply Reply Quote 0
                • First post
                  Last post
                Copyright 2025 Rubicon Communications LLC (Netgate). All rights reserved.