Conditional evaluation question.

Stewart Walters stw at bgc.com.au
Thu Apr 8 06:46:07 UTC 2010


Hi Glenn,

Sorry, I re-read your reply and ultimately found the answer.  You said, 
as does the man page, host definitions get processed before classes.

If anyone else in future wants to know how to get this to work 
(particularly Sunray users attempting the same thing) - this is 
essentially how to structure dhcpd.conf to manage multiple Sunray 
environments:

--- snip ---
authoritative;

options.... # fill out all global options here

#----------
#  Sunray DHCP Vendor Encapsulated Options Definitions
#----------
# Setup the vendor encapulated options specific to Sun Ray DTUs.  Run 
'man 5 dhcp-options' and search for 'VENDOR ENCAPSULATED OPTIONS' for 
more information.

# Production Environment
option space SunRay-ProdEnv;  # 'SunRay-ProdEnv' is an arbitary value, 
but needs to be used consistently for all the 'options' that apply to 
this space.
option SunRay-ProdEnv.altauth         code 35 = array of ip-address;     
# Optional    List of Sun Ray server IP addresses
option SunRay-ProdEnv.authsrvr        code 21 = ip-address;              
# Mandatory   Single Sun Ray server IP address
option SunRay-ProdEnv.authport        code 22 = unsigned integer 16;     
# Optional    Sun Ray server port
option SunRay-ProdEnv.barrierlevel    code 36 = unsigned integer 32;     
# Mandatory   Firmware Download: barrier level
option SunRay-ProdEnv.fwsrvr          code 31 = ip-address;              
# Optional    Firmware tftp server IP address
option SunRay-ProdEnv.intf            code 29 = text;                    
# Optional    Sun Ray server interface name
option SunRay-ProdEnv.loghost         code 24 = ip-address;              
# Optional    Syslog server IP address
option SunRay-ProdEnv.logkern         code 25 = unsigned integer 8;      
# Optional    Log level for kernel
option SunRay-ProdEnv.lognet          code 26 = unsigned integer 8;      
# Optional    Log level for network
option SunRay-ProdEnv.logusb          code 27 = unsigned integer 8;      
# Optional    Log level for USB
option SunRay-ProdEnv.logvid          code 28 = unsigned integer 8;      
# Optional    Log level for video
option SunRay-ProdEnv.logappl         code 28 = unsigned integer 8;      
# Optional    Sun Ray server interface namea (== logvid??)
option SunRay-ProdEnv.newtbw          code 30 = unsigned integer 32;     
# Optional    Bandwidth cap
option SunRay-ProdEnv.newtpispindx    code 32 = unsigned integer 32;     
# Optional    Obsolete. Do not use.
option SunRay-ProdEnv.newtflags       code 34 = unsigned integer 32;     
# Optional    Obsolete. Do not use.
option SunRay-ProdEnv.newtver         code 23 = text;                    
# Optional    Desired firmware version

# Test Environment
option space SunRay-TestEnv;  # 'SunRay-TestEnv' is an arbitary value, 
but needs to be used consistently for all the 'options' that apply to 
this space.
option SunRay-TestEnv.altauth         code 35 = array of ip-address;     
# Optional    List of Sun Ray server IP addresses
option SunRay-TestEnv.authsrvr        code 21 = ip-address;              
# Mandatory   Single Sun Ray server IP address
option SunRay-TestEnv.authport        code 22 = unsigned integer 16;     
# Optional    Sun Ray server port
option SunRay-TestEnv.barrierlevel    code 36 = unsigned integer 32;     
# Mandatory   Firmware Download: barrier level
option SunRay-TestEnv.fwsrvr          code 31 = ip-address;              
# Optional    Firmware tftp server IP address
option SunRay-TestEnv.intf            code 29 = text;                    
# Optional    Sun Ray server interface name
option SunRay-TestEnv.loghost         code 24 = ip-address;              
# Optional    Syslog server IP address
option SunRay-TestEnv.logkern         code 25 = unsigned integer 8;      
# Optional    Log level for kernel
option SunRay-TestEnv.lognet          code 26 = unsigned integer 8;      
# Optional    Log level for network
option SunRay-TestEnv.logusb          code 27 = unsigned integer 8;      
# Optional    Log level for USB
option SunRay-TestEnv.logvid          code 28 = unsigned integer 8;      
# Optional    Log level for video
option SunRay-TestEnv.logappl         code 28 = unsigned integer 8;      
# Optional    Sun Ray server interface namea (== logvid??)
option SunRay-TestEnv.newtbw          code 30 = unsigned integer 32;     
# Optional    Bandwidth cap
option SunRay-TestEnv.newtpispindx    code 32 = unsigned integer 32;     
# Optional    Obsolete. Do not use.
option SunRay-TestEnv.newtflags       code 34 = unsigned integer 32;     
# Optional    Obsolete. Do not use.
option SunRay-TestEnv.newtver         code 23 = text;                    
# Optional    Desired firmware version

#----------
# Define Production & Testing Sunray Environments Section
#----------
# dhcpd checks host statements before checking class statements.
#
# An excert from that section:
#
#       When a client is to be booted, its boot parameters are 
determined by consulting that client's host declaration (if any), and 
then  consulting  any
#       class  declarations  matching  the client, followed by the pool, 
subnet and shared-network declarations for the IP address assigned to 
the client.
#       Each of these declarations itself appears within a lexical 
scope, and all declarations at less specific lexical  scopes  are  also  
consulted  for
#       client  option declarations.   Scopes are never considered 
twice, and if parameters are declared in more than one scope, the 
parameter declared in
#       the most specific scope is the one that is used.
#
# Run 'man 5 dhcpd.conf' and read the 'DESCRIPTION' section for more 
infomation.

# Production Sunray Class
class "ProductionSunray" {
   match if vendor-class-identifier = "SUNW.NewT.SUNW";
   option dhcp-parameter-request-list  1,2,3,23,43,51,54,49,62;
   vendor-option-space                 SunRay-ProdEnv;
   option SunRay-ProdEnv.altauth       prodsunray2.example.com, 
prodsunray3.example.com, prodsunray4.example.com;
   option SunRay-ProdEnv.authsrvr      prodsunray1.example.com;
   option SunRay-ProdEnv.fwsrvr        prodsunray1.example.com;
   option SunRay-ProdEnv.loghost       prodsunray1.example.com;
}

# Testing Suray Group
group "TestingSunray" {
   option dhcp-parameter-request-list  1,2,3,23,43,51,54,49,62;
   vendor-option-space                 SunRay-TestEnv;
   option SunRay-TestEnv.altauth       testsunray1.example.com;
   option SunRay-TestEnv.authsrvr      testsunray1.example.com;
   option SunRay-TestEnv.fwsrvr        testsunray1.example.com;
   option SunRay-TestEnv.loghost       testsunray1.example.com;

#  Training Room Sunrays
   host sunray01 { hardware ethernet xx:xx:xx:xx:xx:xx; } # Asset Number 
XXXXX; Owned by Joe Bloggs
   host sunray02 { hardware ethernet yy:yy:yy:yy:yy:yy; } # Asset Number 
XXXXX; Owned by Jane Bloggs
   host sunray03 { hardware ethernet zz:zz:zz:zz:zz:zz; } # Asset Number 
XXXXX; Owned by Fred Bloggs
   host sunray04 { hardware ethernet aa:aa:aa:aa:aa:aa; } # Asset Number 
XXXXX; Owned by Peter Bloggs
   host sunray05 { hardware ethernet bb:bb:bb:bb:bb:bb; } # Asset Number 
XXXXX; Owned by Madonna Bloggs
   host sunray06 { hardware ethernet cc:cc:cc:cc:cc:cc; } # Asset Number 
XXXXX; Owned by Bloggy Bloggs
}

subnet 192.168.1.0 netmask 255.255.255.0 {
   option routers 192.168.1.1;
   option subnet-mask 255.255.255.0;
   option broadcast-address 192.168.1.255;
   pool {
      range 192.168.1.30 192.168.1.254;
   }
}
--- snip ---

Regards,

Stewart




Stewart Walters wrote:
> Hi Glenn, Mailinglist,
>
> Thanks for the reply.
>
> Do you know at all if it's possible to do multiple match statements?
>
> e.g.
>
> class "TestingSunray" {
> match vendor-class-identifier = "SUNW.NewT.SUNW" and hardware;
> option space...
> option...
> }
>
> Or even like this?
>
> class "ProductionSunray {
> if not match class "TestingSunray" and match vendor-class-identifier = 
> "SUNW.NewT.SUNW";
> option space...
> option...
> }
>
> I'm just spitballing ideas here, not really sure if dhcpd is capable 
> in this regard.
>
> Regards,
>
> Stewart
>
>
>
> Glenn Satchell wrote:
>> On 04/07/10 19:00, Stewart Walters wrote:
>>> Hi,
>>>
>>> I'm trying to work out what's the best way to configure dhcpd using 
>>> some
>>> form of evaluation to send different vendor encapsulated options to our
>>> Sunray thin clients.
>>>
>>> We currently have a server which provides a Production Sunray desktop
>>> environment to our userbase.
>>>
>>> If it helps - here is an example of how to set up dhcpd for passing a
>>> single Sunray environment to 100% of Sunray clients
>>> (http://blogs.sun.com/lewiz/entry/configuring_sun_ray_dhcp)
>>>
>>> As shown in that example, 100% of Sunray clients can be evaluated via
>>> the vendor-class-identifier = "SUNW.NewT.SUNW"; statement.
>>
>> I did something similar many years ago with ISC dhcpd on Solaris.
>>
>>> But I want to create a Test Sunray desktop evironment and move 10% of
>>> our users (determined by MAC address) to a different Testing
>>> environment. If the conditional evaluation doesn't qualify in the 
>>> 10%, I
>>> want the remaining 90% of our Sunray clients to receive the Production
>>> environment options.
>>>
>>> I've been reading through dhcp-options(5), dhcpd.conf(5) and
>>> dhcp-eval(5), as well as several online posts relating to this.
>>>
>>> But I'm a little perplexed about what the best approach for this 
>>> kind of
>>> setup would be.
>>>
>>> Would it be better to go, for example:
>>>
>>> --- snip ---
>>> class "TestingSunray" {
>>> match <some match criteria here>
>>> <insert Testing vendor encapsulated options here>
>>> }
>>>
>>> subclass "TestingSunray" 1:xx:xx:xx:xx:xx:xx;
>>> subclass "TestingSunray" 1:yy:yy:yy:yy:yy:yy;
>>> subclass "TestingSunray" 1:zz:zz:zz:zz:zz:zz;
>>
>> The syntax for whatever is in the match line of the class is what 
>> goes in the match portion of the subclass. So in the class if you said:
>>
>> class "TestingSunray" {
>>     match hardware;
>>     option space ...
>>     option ...
>> }
>>
>> Then in the subclass you use the hardware address. This needs a 
>> leading 1 which represents ethernet.
>>
>> subclass "TestingSunray" 1:xx:xx:xx:xx:xx:xx;
>>
>> The sub-class uses a fast hashing algorithm to determine membership, 
>> so it's efficient even where there are lots of clients. See 
>> dhcpd.conf SUBCLASSES section.
>>
>>> class "ProductionSunray" {
>>> match if vendor-class-identifier = "SUNW.NewT.SUNW";
>>> <insert Production vendor encapsulated options here>
>>> }
>>
>> If you are going to be filling in the option space in different 
>> places, then you should put the option space definitions in the 
>> global scope, and assign the values in the classes or groups.
>>
>>> --- snip ---
>>>
>>> Does dhcpd even process class matching in the order in which it's 
>>> listed
>>> in dhcpd.conf? Am I guaranteed in that configuration that a Test Sunray
>>> wont be classified as Production just because the Testing class is
>>> defined first?
>>
>> What happens here is that some clients will be in *both* classes. 
>> It's not about only matching the first class you come across. 
>> Unfortunately things are not clear about which class definition is 
>> the most specific, ie which one "wins" when both define the same 
>> options. If this point can be clearly defined then the subclass 
>> solution is the definite winner.
>>
>> Now for some other ways to clearly use the most specific group. 
>> Consider this paragraph from the dhcpd.conf man page, which specifies 
>> the scoping order:
>>
>>      When a client is to  be  booted,  its  boot  parameters  are
>>      determined  by consulting that client's host declaration (if
>>      any), and then consulting any  class  declarations  matching
>>      the  client, followed by the pool, subnet and shared-network
>>      declarations for the IP  address  assigned  to  the  client.
>>      Each  of  these declarations itself appears within a lexical
>>      scope, and all declarations at less specific lexical  scopes
>>      are  also consulted for client option declarations.   Scopes
>>      are never considered twice, and if parameters  are  declared
>>      in  more  than one scope, the parameter declared in the most
>>      specific scope is the one that is used.
>>
>> We could use a group and host statements to make sure we are more 
>> specific than a class. For example this group, and the 
>> ProductionSunrays class above. You only need to put in the options 
>> that are different for testing, as these clients are still members of 
>> ProductionSunrays and will pick up other options from there.
>>
>> # testing sunrays
>> group {
>>     option ...
>>     host "host1" { hardware ethernet xx:xx:xx:xx:xx:xx; }
>>     host "host2" { hardware ethernet xx:xx:xx:xx:xx:xx; }
>> }
>>
>>> Or is it better to do this?
>>>
>>> --- snip ---
>>> class "Sunray" {
>>> match if substring(hardware,1,3)=xx:xx:xx:xx:xx:xx or
>>> elsif substring(hardware,1,3)=yy:yy:yy:yy:yy:yy or
>>> elsif substring(hardware,1,3)=zz:zz:zz:zz:zz:zz;
>>> <insert Testing vendor encapsulated options here>
>>> else
>>> match if option vendor-class-identifier = "SUNW.NewT.SUNW";
>>> <insert Production vendor encapsulated options here>
>>> }
>>> --- snip ---
>>> (I probably made a bunch of minor syntax errors above, but I can work
>>> those out later)
>>
>> That doesn't scale very well and the logic is not quite right.
>>
>> class "Sunray" {
>>     match if option vendor-class-identifier = "SUNW.NewT.SUNW";
>>     # default options for all
>>     option ...
>>
>>     # option for testing sunrays
>>     if hardware = xx:xx:xx:xx:xx:xx
>>     or substring(hardware,1,3) = yy:yy:yy
>>     or ... {
>>         option ...
>>     }
>> }
>>
>>> Or should I be doing some complicated if and else statements as 
>>> shown in
>>> the example at
>>> http://www.linuxforums.org/forum/servers/69851-dhcpd-conf-multiple-subnet-single-physical-network-configuration.html 
>>>
>>
>> Having just looked at that page I would *not* recommend using those 
>> methods at all. That guy is deliberately trying to make things as 
>> difficult and complicated as possible. Difficult and complicated 
>> means hard to understand, hard to get working and hard to fix if 
>> things aren't quite right.
>>
>>> As you can see, I'm not exactly sure to which way might be best for me.
>>> Let me say thanks in advance for any assistance you can provide on the
>>> matter.
>>
>> Ah, it is a very interesting question, but the solution comes down to 
>> being able to define the subset of clients that are going to get 
>> different options. That's all.
>>
> _______________________________________________
> dhcp-users mailing list
> dhcp-users at lists.isc.org
> https://lists.isc.org/mailman/listinfo/dhcp-users



More information about the dhcp-users mailing list