Page MenuHomeVyOS Platform

[Feature] - DHCP Option 82 Support
Open, Requires assessmentPublicFEATURE REQUEST

Description

For enterprise deployments where separation of different subnet pools is necessary, option 82 provides a mechanism to specify a source VLAN in DHCP requests. Currently, VyOS can in fact support this via the subnet-parameters and shared-network-parameters, but these options are less than ideal, and other parameters need to be set in the CLI even though they're not actually necessary for ISC to function in this mode. Currently, I utilize the following configurations for Option-82:
Arista EOS 4.26.1F:

ir01#show run | s relay|helper
ip dhcp relay information option
ip dhcp relay all-subnets default
interface Vlan200
   ip dhcp relay all-subnets
interface Vlan240
   ip dhcp relay all-subnets

VyOS 1.4:

set service dhcp-server failover name 'INT'
set service dhcp-server failover remote '192.168.15.4'
set service dhcp-server failover source-address '192.168.15.3'
set service dhcp-server failover status 'primary'
set service dhcp-server shared-network-name INT description 'Internal connection to ir01'
set service dhcp-server shared-network-name INT shared-network-parameters 'class "GUEST" { match if option agent.circuit-id = "Vlan240"; }'
set service dhcp-server shared-network-name INT shared-network-parameters 'class "CLIENTS" { match if option agent.circuit-id = "Vlan200"; }'
set service dhcp-server shared-network-name INT subnet 192.168.1.0/24 default-router '192.168.1.1'
set service dhcp-server shared-network-name INT subnet 192.168.1.0/24 domain-name 'int.trae32566.org'
set service dhcp-server shared-network-name INT subnet 192.168.1.0/24 domain-search 'int.trae32566.org'
set service dhcp-server shared-network-name INT subnet 192.168.1.0/24 domain-search 'ipa.trae32566.org'
set service dhcp-server shared-network-name INT subnet 192.168.1.0/24 domain-search 'trae32566.org'
set service dhcp-server shared-network-name INT subnet 192.168.1.0/24 name-server '192.168.255.1'
set service dhcp-server shared-network-name INT subnet 192.168.1.0/24 name-server '192.168.15.10'
set service dhcp-server shared-network-name INT subnet 192.168.1.0/24 name-server '192.168.31.3'
set service dhcp-server shared-network-name INT subnet 192.168.1.0/24 ntp-server '192.168.255.2'
set service dhcp-server shared-network-name INT subnet 192.168.1.0/24 ntp-server '192.168.15.11'
set service dhcp-server shared-network-name INT subnet 192.168.1.0/24 ntp-server '192.168.31.4'
set service dhcp-server shared-network-name INT subnet 192.168.1.0/24 server-identifier '192.168.15.2'
set service dhcp-server shared-network-name INT subnet 192.168.1.0/24 static-mapping QUEST ip-address '192.168.1.17'
set service dhcp-server shared-network-name INT subnet 192.168.1.0/24 static-mapping QUEST mac-address '80:f3:ef:11:e7:e7'
set service dhcp-server shared-network-name INT subnet 192.168.1.0/24 subnet-parameters 'pool { allow members of "CLIENTS"; range 192.168.1.2 192.168.1.240; }'
set service dhcp-server shared-network-name INT subnet 192.168.6.0/24 default-router '192.168.6.1'
set service dhcp-server shared-network-name INT subnet 192.168.6.0/24 name-server '1.1.1.1'
set service dhcp-server shared-network-name INT subnet 192.168.6.0/24 name-server '1.0.0.1'
set service dhcp-server shared-network-name INT subnet 192.168.6.0/24 name-server '8.8.8.8'
set service dhcp-server shared-network-name INT subnet 192.168.6.0/24 ntp-server '50.205.57.38'
set service dhcp-server shared-network-name INT subnet 192.168.6.0/24 ntp-server '64.225.34.103'
set service dhcp-server shared-network-name INT subnet 192.168.6.0/24 ntp-server '129.250.35.251'
set service dhcp-server shared-network-name INT subnet 192.168.6.0/24 server-identifier '192.168.15.2'
set service dhcp-server shared-network-name INT subnet 192.168.6.0/24 static-mapping DUMMY2 ip-address '192.168.6.254'
set service dhcp-server shared-network-name INT subnet 192.168.6.0/24 static-mapping DUMMY2 mac-address '00:00:00:00:00:00'
set service dhcp-server shared-network-name INT subnet 192.168.6.0/24 subnet-parameters 'pool { allow members of "GUEST"; range 192.168.6.2 192.168.6.254; }'
set service dhcp-server shared-network-name INT subnet 192.168.15.0/29 default-router '192.168.15.1'
set service dhcp-server shared-network-name INT subnet 192.168.15.0/29 enable-failover
set service dhcp-server shared-network-name INT subnet 192.168.15.0/29 range DUMMY start '192.168.15.2'
set service dhcp-server shared-network-name INT subnet 192.168.15.0/29 range DUMMY stop '192.168.15.7'

Because there is no option 82 support natively, the following things (taken from above) currently have to be "hacked" in:

  • Create the appropriate classes using shared-network-parameters:
set service dhcp-server shared-network-name INT shared-network-parameters 'class "GUEST" { match if option agent.circuit-id = "Vlan240"; }'
set service dhcp-server shared-network-name INT shared-network-parameters 'class "CLIENTS" { match if option agent.circuit-id = "Vlan200"; }'
  • Define a subnet pool allow statement with a specific range using subnet-parameters
set service dhcp-server shared-network-name INT subnet 192.168.1.0/24 subnet-parameters 'pool { allow members of "CLIENTS"; range 192.168.1.2 192.168.1.240; }'
set service dhcp-server shared-network-name INT subnet 192.168.6.0/24 subnet-parameters 'pool { allow members of "GUEST"; range 192.168.6.2 192.168.6.254; }'
  • Add static mappings; at least 1 of these are needed because the range must be defined above as a subnet parameter for class mapping, as opposed to being defined in the VyOS configuration dedicated to that parameter (range):
set service dhcp-server shared-network-name INT subnet 192.168.1.0/24 static-mapping QUEST ip-address '192.168.1.17'
set service dhcp-server shared-network-name INT subnet 192.168.1.0/24 static-mapping QUEST mac-address '80:f3:ef:11:e7:e7'
set service dhcp-server shared-network-name INT subnet 192.168.6.0/24 static-mapping DUMMY2 ip-address '192.168.6.254'
set service dhcp-server shared-network-name INT subnet 192.168.6.0/24 static-mapping DUMMY2 mac-address '00:00:00:00:00:00'

As well, this breaks DHCP failover, since it requires a subnet range be defined using the dedicated VyOS range configuration option.

Details

Difficulty level
Unknown (require assessment)
Version
-
Why the issue appeared?
Will be filled on close
Is it a breaking change?
Unspecified (possibly destroys the router)
Issue type
Improvement (missing useful functionality)

Event Timeline

Any idea how you would like the CLI to look like for option 82 support?

I think this is what it would look like in service dhcp server. I left some comments to explain my thinking a bit, and I tried to make it as flexible as possible (for example the way match options are strings, so future DHCP options can be supported as soon as ISC supports them):

failover {
    name INT
    remote 192.168.15.4
    source-address 192.168.15.3
    status primary
}
shared-network-name INT {
    description "Internal connection to ir01"
    class CLIENT_MAP {
       rule 10 {
           action permit                                       # This is equivalent to dhcpd's allow/deny members of
           match option "agent.circuit_id" value "Vlan200"     # This could match any option (ex: dhcp-client-identifier)
       }
    }
    class GUEST_MAP {
       rule 10 {
           action permit
           match option "agent.circuit_id" value "Vlan240"
       }
    }
    subnet 192.168.1.0/24 {
        class CLIENT_MAP
        default-router 192.168.1.1
        domain-name int.trae32566.org
        domain-search int.trae32566.org
        domain-search ipa.trae32566.org
        domain-search trae32566.org
        enable-failover
        name-server 192.168.255.1
        name-server 192.168.15.10
        name-server 192.168.31.3
        ntp-server 192.168.255.2
        ntp-server 192.168.15.11
        ntp-server 192.168.31.4
        range CLIENTS {
            start 192.168.1.2
            stop 192.168.1.240
        }
        server-identifier 192.168.15.2
        static-mapping QUEST {
            ip-address 192.168.1.17
            mac-address 80:f3:ef:11:e7:e7
        }
    }
    subnet 192.168.6.0/24 {
        class GUEST_MAP
        default-router 192.168.6.1
        enable-failover
        name-server 1.1.1.1
        name-server 1.0.0.1
        name-server 8.8.8.8
        ntp-server 50.205.57.38
        ntp-server 64.225.34.103
        ntp-server 129.250.35.251
        server-identifier 192.168.15.2
        range GUESTS {
            start 192.168.6.2
            stop 192.168.6.254
        }
    }
    subnet 192.168.15.0/29 {        # This tells it indirectly to use the interface eth2, which is on this subnet (is there a better way?)
        default-router 192.168.15.1
        enable-failover
        range DUMMY {
            start 192.168.15.2
            stop 192.168.15.7
        }
    }
}

I'm also not sure how this will play into DHCP failover, but I would hope it works properly. I'm also hoping we can think of a better way to force it to use the correct interface than just specifying a dummy subnet; currently this is needed because when using option 82, the network being served is not directly connected (and therefore it has no idea what interface to go out).