Discussion:
Specify different pxeclients "next-server" for different subnet?
Drew Weaver
2009-01-09 20:57:57 UTC
Permalink
Hi there.

Is it possible to specify a different pxeclient "next-server" for each subnet?

Currently I have this in my dhcpd.conf:

class "pxeclients" {
match if substring(option vendor-class-identifier, 0, 9) = "PXEClient";
next-server 10.1.0.1;
filename "linux-install/pxelinux.0";
}

I need to be able to specify the next-server for pxeclients for each subnet.

Currently, even though we have next-server in the subnet declaration it still uses 10.1.0.1

Any ideas?

Thanks,
-Drew
Jeffrey Hutzelman
2009-01-09 21:31:39 UTC
Permalink
--On Friday, January 09, 2009 03:57:57 PM -0500 Drew Weaver
Post by Drew Weaver
Hi there.
Is it possible to specify a different pxeclient "next-server" for each subnet?
class "pxeclients" {
match if substring(option vendor-class-identifier, 0, 9) =
"PXEClient"; next-server 10.1.0.1;
filename "linux-install/pxelinux.0";
}
I need to be able to specify the next-server for pxeclients for each subnet.
Currently, even though we have next-server in the subnet declaration it still uses 10.1.0.1
Any ideas?
IIRC, options specified for a class will take precedence over those present
in a subnet declaration. If you want a next-server for the subnet to have
effect, you'll have to remove the option from the class.

Alternately, if you want to override next-server only for PXE clients, but
set it to a per-subnet value, then you can include in each subnet
declaration a statement like

set pxe_server = 10.1.2.3;

and in the class a statement like

option server.next-server = pxe_server;


-- Jeff
Drew Weaver
2009-01-09 21:56:16 UTC
Permalink
IIRC, options specified for a class will take precedence over those present
in a subnet declaration. If you want a next-server for the subnet to have
effect, you'll have to remove the option from the class.

Alternately, if you want to override next-server only for PXE clients, but
set it to a per-subnet value, then you can include in each subnet
declaration a statement like

set pxe_server = 10.1.2.3;

and in the class a statement like

option server.next-server = pxe_server;

---

Hi Jeff, and thanks for the idea.

class "pxeclients" {
match if substring(option vendor-class-identifier, 0, 9) = "PXEClient";
option server.next-server = pxe_server;
filename "linux-install/pxelinux.0";
}
subnet 192.168.0.0 netmask 255.255.255.224 {
range 192.168.0.5 192.168.0.20;
option routers 192.168.0.1;
option domain-name-servers 192.168.0.2;
set pxe_server = "192.168.0.3";
}

I added the above and it doesn't seem to work, was that pseudo config or should that have worked?

By 'didn't work' I mean that the dhcpd server didn't send a next-server.

I also tried replacing option server.next-server = pxe_server; with next-server pxe_server;

Thanks,
-Drew
Jeffrey Hutzelman
2009-01-09 22:25:50 UTC
Permalink
--On Friday, January 09, 2009 04:56:16 PM -0500 Drew Weaver
Post by Drew Weaver
set pxe_server = "192.168.0.3";
No quotes here; it makes a difference.
Now that I think about it, the server might not accept an IP address here;
in theory, the RHS of an assignment can be any expression type, but I can't
remember if the parser is clever enough to do the right thing with an IP
address. Perhaps someone who touches the parser internals more often than
I would like to comment (David?).
Post by Drew Weaver
I also tried replacing option server.next-server = pxe_server; with next-server pxe_server;
That won't work. Without the =, it becomes an option declaration rather
than an executable-statement, with the result that it's processed too early
and that the RHS is treated as a hostname/ip address and not as an
expression.

-- Jeff
Drew Weaver
2009-01-12 16:52:03 UTC
Permalink
No quotes here; it makes a difference.
Now that I think about it, the server might not accept an IP address here;
in theory, the RHS of an assignment can be any expression type, but I can't
remember if the parser is clever enough to do the right thing with an IP
address. Perhaps someone who touches the parser internals more often than
I would like to comment (David?).
Post by Drew Weaver
I also tried replacing option server.next-server = pxe_server; with next-server pxe_server;
That won't work. Without the =, it becomes an option declaration rather
than an executable-statement, with the result that it's processed too early
and that the RHS is treated as a hostname/ip address and not as an
expression.

----

Jeff,

Is it possible to put classes inside of subnets and not globally, or can you think of any other way that I could achieve this?

It seems like it should be fairly trivial to assign separate next-server options for PXEClients on a per subnet basis.

Thanks,
-Drew
David W. Hankins
2009-01-12 17:19:37 UTC
Permalink
Post by Jeffrey Hutzelman
Now that I think about it, the server might not accept an IP address here;
in theory, the RHS of an assignment can be any expression type, but I can't
remember if the parser is clever enough to do the right thing with an IP
address. Perhaps someone who touches the parser internals more often than
I would like to comment (David?).
I think anything on the right hand side of an '=' being used in
assignment is a data expression, and data expressions are either
functions that return data expressions, or colon-separated
hexadecimal.

This is why if you over-ride the PRL with a concat() (whose arguments
are defined as data expressions, and so parsed that way), you have to
specify hex.

But I've been surprised by the parser before. It could be it tries
to determine the type of expression first before parsing. The easy
answer is to try it and see what you get.
Post by Jeffrey Hutzelman
Is it possible to put classes inside of subnets and not globally, or can you think of any other way that I could achieve this?
No, class matches are searched globally. Nesting a class (or host, or
group) creates a hierarchical tree of configuration state. Placing
the class inside a subnet, for example, causes the class to inherit
all configuration parameters defined in the subnet (but the class is
still searched globally). This can be beneficial in some contrived
circumstances, but usually causes a host to get the 'option routers'
for the wrong subnet due to its class match.
Post by Jeffrey Hutzelman
It seems like it should be fairly trivial to assign separate next-server options for PXEClients on a per subnet basis.
Presuming a single class that matches all PXEClients, you could scope
the next-server parameter in a small pool inside each subnet, that
serves only pxeclients. In this case, be sure to also reduce
max-lease-time. You might also use non globally routed addresses that
have been colocated on the subnet (inside a shared-network).

You can also use an executable statement scoped inside the subnet;
this is approximately equivalent in workload for the server to using
a class match (because this statement is scoped inside the subnet,
it alone is found to execute when processing a reply).

if (substring(option vendor-class-identifier, 0, 3) = "PXE") {
next-server foo;
}
--
David W. Hankins "If you don't do it right the first time,
Software Engineer you'll just have to do it again."
Internet Systems Consortium, Inc. -- Jack T. Hankins
Jeffrey Hutzelman
2009-01-13 14:17:22 UTC
Permalink
--On Monday, January 12, 2009 09:19:37 AM -0800 "David W. Hankins"
Post by David W. Hankins
Post by Jeffrey Hutzelman
Now that I think about it, the server might not accept an IP address
here; in theory, the RHS of an assignment can be any expression type,
but I can't remember if the parser is clever enough to do the right
thing with an IP address. Perhaps someone who touches the parser
internals more often than I would like to comment (David?).
I think anything on the right hand side of an '=' being used in
assignment is a data expression, and data expressions are either
functions that return data expressions, or colon-separated
hexadecimal.
I had some time, so I went back and looked at the parser (though in a
fairly old version). What you say is true for option assignments; the RHS
is always parsed as a data expression. But variable references and
function calls are polymorphic, and the type checking is deferred until the
option cache is actually evaluated, quite late in the process.

Since variables are polymorphic, the RHS of a set statement can be any
expression type, and so is parsed with context_any. So far as I can tell,
this means that something that looks like an IP address or hostname will
fail to parse. Unfortunately, while it's fairly easy to write a constant
data expression corresponding to a particular IP address, there's no
function that does a hostname lookup and returns the resulting address as a
data expression.
Post by David W. Hankins
This is why if you over-ride the PRL with a concat() (whose arguments
are defined as data expressions, and so parsed that way), you have to
specify hex.
It may be interesting to define a function which is effectively a wrapper
around parse_option_token, constructing a data expression based on an
option syntax and an appropriate sequence of tokens, something like:

option dhcp-parameter-request-list =
concat(option dhcp-parameter-request-list,
option_value("BA", 208, 209, 210, 211));

Or maybe
option_value_str("BA", "208, 209, 210, 211")

-- Jeff
Jeffrey Hutzelman
2009-01-13 14:17:22 UTC
Permalink
--On Monday, January 12, 2009 09:19:37 AM -0800 "David W. Hankins"
Post by David W. Hankins
Post by Jeffrey Hutzelman
Now that I think about it, the server might not accept an IP address
here; in theory, the RHS of an assignment can be any expression type,
but I can't remember if the parser is clever enough to do the right
thing with an IP address. Perhaps someone who touches the parser
internals more often than I would like to comment (David?).
I think anything on the right hand side of an '=' being used in
assignment is a data expression, and data expressions are either
functions that return data expressions, or colon-separated
hexadecimal.
I had some time, so I went back and looked at the parser (though in a
fairly old version). What you say is true for option assignments; the RHS
is always parsed as a data expression. But variable references and
function calls are polymorphic, and the type checking is deferred until the
option cache is actually evaluated, quite late in the process.

Since variables are polymorphic, the RHS of a set statement can be any
expression type, and so is parsed with context_any. So far as I can tell,
this means that something that looks like an IP address or hostname will
fail to parse. Unfortunately, while it's fairly easy to write a constant
data expression corresponding to a particular IP address, there's no
function that does a hostname lookup and returns the resulting address as a
data expression.
Post by David W. Hankins
This is why if you over-ride the PRL with a concat() (whose arguments
are defined as data expressions, and so parsed that way), you have to
specify hex.
It may be interesting to define a function which is effectively a wrapper
around parse_option_token, constructing a data expression based on an
option syntax and an appropriate sequence of tokens, something like:

option dhcp-parameter-request-list =
concat(option dhcp-parameter-request-list,
option_value("BA", 208, 209, 210, 211));

Or maybe
option_value_str("BA", "208, 209, 210, 211")

-- Jeff
Jeffrey Hutzelman
2009-01-13 14:17:22 UTC
Permalink
--On Monday, January 12, 2009 09:19:37 AM -0800 "David W. Hankins"
Post by David W. Hankins
Post by Jeffrey Hutzelman
Now that I think about it, the server might not accept an IP address
here; in theory, the RHS of an assignment can be any expression type,
but I can't remember if the parser is clever enough to do the right
thing with an IP address. Perhaps someone who touches the parser
internals more often than I would like to comment (David?).
I think anything on the right hand side of an '=' being used in
assignment is a data expression, and data expressions are either
functions that return data expressions, or colon-separated
hexadecimal.
I had some time, so I went back and looked at the parser (though in a
fairly old version). What you say is true for option assignments; the RHS
is always parsed as a data expression. But variable references and
function calls are polymorphic, and the type checking is deferred until the
option cache is actually evaluated, quite late in the process.

Since variables are polymorphic, the RHS of a set statement can be any
expression type, and so is parsed with context_any. So far as I can tell,
this means that something that looks like an IP address or hostname will
fail to parse. Unfortunately, while it's fairly easy to write a constant
data expression corresponding to a particular IP address, there's no
function that does a hostname lookup and returns the resulting address as a
data expression.
Post by David W. Hankins
This is why if you over-ride the PRL with a concat() (whose arguments
are defined as data expressions, and so parsed that way), you have to
specify hex.
It may be interesting to define a function which is effectively a wrapper
around parse_option_token, constructing a data expression based on an
option syntax and an appropriate sequence of tokens, something like:

option dhcp-parameter-request-list =
concat(option dhcp-parameter-request-list,
option_value("BA", 208, 209, 210, 211));

Or maybe
option_value_str("BA", "208, 209, 210, 211")

-- Jeff
Jeffrey Hutzelman
2009-01-13 14:17:22 UTC
Permalink
--On Monday, January 12, 2009 09:19:37 AM -0800 "David W. Hankins"
Post by David W. Hankins
Post by Jeffrey Hutzelman
Now that I think about it, the server might not accept an IP address
here; in theory, the RHS of an assignment can be any expression type,
but I can't remember if the parser is clever enough to do the right
thing with an IP address. Perhaps someone who touches the parser
internals more often than I would like to comment (David?).
I think anything on the right hand side of an '=' being used in
assignment is a data expression, and data expressions are either
functions that return data expressions, or colon-separated
hexadecimal.
I had some time, so I went back and looked at the parser (though in a
fairly old version). What you say is true for option assignments; the RHS
is always parsed as a data expression. But variable references and
function calls are polymorphic, and the type checking is deferred until the
option cache is actually evaluated, quite late in the process.

Since variables are polymorphic, the RHS of a set statement can be any
expression type, and so is parsed with context_any. So far as I can tell,
this means that something that looks like an IP address or hostname will
fail to parse. Unfortunately, while it's fairly easy to write a constant
data expression corresponding to a particular IP address, there's no
function that does a hostname lookup and returns the resulting address as a
data expression.
Post by David W. Hankins
This is why if you over-ride the PRL with a concat() (whose arguments
are defined as data expressions, and so parsed that way), you have to
specify hex.
It may be interesting to define a function which is effectively a wrapper
around parse_option_token, constructing a data expression based on an
option syntax and an appropriate sequence of tokens, something like:

option dhcp-parameter-request-list =
concat(option dhcp-parameter-request-list,
option_value("BA", 208, 209, 210, 211));

Or maybe
option_value_str("BA", "208, 209, 210, 211")

-- Jeff

David W. Hankins
2009-01-12 17:19:37 UTC
Permalink
Post by Jeffrey Hutzelman
Now that I think about it, the server might not accept an IP address here;
in theory, the RHS of an assignment can be any expression type, but I can't
remember if the parser is clever enough to do the right thing with an IP
address. Perhaps someone who touches the parser internals more often than
I would like to comment (David?).
I think anything on the right hand side of an '=' being used in
assignment is a data expression, and data expressions are either
functions that return data expressions, or colon-separated
hexadecimal.

This is why if you over-ride the PRL with a concat() (whose arguments
are defined as data expressions, and so parsed that way), you have to
specify hex.

But I've been surprised by the parser before. It could be it tries
to determine the type of expression first before parsing. The easy
answer is to try it and see what you get.
Post by Jeffrey Hutzelman
Is it possible to put classes inside of subnets and not globally, or can you think of any other way that I could achieve this?
No, class matches are searched globally. Nesting a class (or host, or
group) creates a hierarchical tree of configuration state. Placing
the class inside a subnet, for example, causes the class to inherit
all configuration parameters defined in the subnet (but the class is
still searched globally). This can be beneficial in some contrived
circumstances, but usually causes a host to get the 'option routers'
for the wrong subnet due to its class match.
Post by Jeffrey Hutzelman
It seems like it should be fairly trivial to assign separate next-server options for PXEClients on a per subnet basis.
Presuming a single class that matches all PXEClients, you could scope
the next-server parameter in a small pool inside each subnet, that
serves only pxeclients. In this case, be sure to also reduce
max-lease-time. You might also use non globally routed addresses that
have been colocated on the subnet (inside a shared-network).

You can also use an executable statement scoped inside the subnet;
this is approximately equivalent in workload for the server to using
a class match (because this statement is scoped inside the subnet,
it alone is found to execute when processing a reply).

if (substring(option vendor-class-identifier, 0, 3) = "PXE") {
next-server foo;
}
--
David W. Hankins "If you don't do it right the first time,
Software Engineer you'll just have to do it again."
Internet Systems Consortium, Inc. -- Jack T. Hankins
Drew Weaver
2009-01-12 16:52:03 UTC
Permalink
No quotes here; it makes a difference.
Now that I think about it, the server might not accept an IP address here;
in theory, the RHS of an assignment can be any expression type, but I can't
remember if the parser is clever enough to do the right thing with an IP
address. Perhaps someone who touches the parser internals more often than
I would like to comment (David?).
Post by Drew Weaver
I also tried replacing option server.next-server = pxe_server; with next-server pxe_server;
That won't work. Without the =, it becomes an option declaration rather
than an executable-statement, with the result that it's processed too early
and that the RHS is treated as a hostname/ip address and not as an
expression.

----

Jeff,

Is it possible to put classes inside of subnets and not globally, or can you think of any other way that I could achieve this?

It seems like it should be fairly trivial to assign separate next-server options for PXEClients on a per subnet basis.

Thanks,
-Drew
Jeffrey Hutzelman
2009-01-09 22:25:50 UTC
Permalink
--On Friday, January 09, 2009 04:56:16 PM -0500 Drew Weaver
Post by Drew Weaver
set pxe_server = "192.168.0.3";
No quotes here; it makes a difference.
Now that I think about it, the server might not accept an IP address here;
in theory, the RHS of an assignment can be any expression type, but I can't
remember if the parser is clever enough to do the right thing with an IP
address. Perhaps someone who touches the parser internals more often than
I would like to comment (David?).
Post by Drew Weaver
I also tried replacing option server.next-server = pxe_server; with next-server pxe_server;
That won't work. Without the =, it becomes an option declaration rather
than an executable-statement, with the result that it's processed too early
and that the RHS is treated as a hostname/ip address and not as an
expression.

-- Jeff
Drew Weaver
2009-01-09 21:56:16 UTC
Permalink
IIRC, options specified for a class will take precedence over those present
in a subnet declaration. If you want a next-server for the subnet to have
effect, you'll have to remove the option from the class.

Alternately, if you want to override next-server only for PXE clients, but
set it to a per-subnet value, then you can include in each subnet
declaration a statement like

set pxe_server = 10.1.2.3;

and in the class a statement like

option server.next-server = pxe_server;

---

Hi Jeff, and thanks for the idea.

class "pxeclients" {
match if substring(option vendor-class-identifier, 0, 9) = "PXEClient";
option server.next-server = pxe_server;
filename "linux-install/pxelinux.0";
}
subnet 192.168.0.0 netmask 255.255.255.224 {
range 192.168.0.5 192.168.0.20;
option routers 192.168.0.1;
option domain-name-servers 192.168.0.2;
set pxe_server = "192.168.0.3";
}

I added the above and it doesn't seem to work, was that pseudo config or should that have worked?

By 'didn't work' I mean that the dhcpd server didn't send a next-server.

I also tried replacing option server.next-server = pxe_server; with next-server pxe_server;

Thanks,
-Drew
Jeffrey Hutzelman
2009-01-09 21:31:39 UTC
Permalink
--On Friday, January 09, 2009 03:57:57 PM -0500 Drew Weaver
Post by Drew Weaver
Hi there.
Is it possible to specify a different pxeclient "next-server" for each subnet?
class "pxeclients" {
match if substring(option vendor-class-identifier, 0, 9) =
"PXEClient"; next-server 10.1.0.1;
filename "linux-install/pxelinux.0";
}
I need to be able to specify the next-server for pxeclients for each subnet.
Currently, even though we have next-server in the subnet declaration it still uses 10.1.0.1
Any ideas?
IIRC, options specified for a class will take precedence over those present
in a subnet declaration. If you want a next-server for the subnet to have
effect, you'll have to remove the option from the class.

Alternately, if you want to override next-server only for PXE clients, but
set it to a per-subnet value, then you can include in each subnet
declaration a statement like

set pxe_server = 10.1.2.3;

and in the class a statement like

option server.next-server = pxe_server;


-- Jeff
Simon Hobson
2009-01-09 21:35:48 UTC
Permalink
Content-Language: en-US
Content-Type: multipart/alternative;
boundary="_000_B7152C470C9BF3448ED33F16A75D81C14D44E868F8exchangathena_"
Hi there.
Is it possible to specify a different pxeclient "next-server" for each subnet?
class "pxeclients" {
match if substring(option vendor-class-identifier, 0, 9) = "PXEClient";
next-server 10.1.0.1;
filename "linux-install/pxelinux.0";
}
I need to be able to specify the next-server for pxeclients for each subnet.
Currently, even though we have next-server in the subnet declaration it still uses 10.1.0.1
IIRC the class definition will override the subnet declaration.
You'll need to have multiple classes I think.

Unless someone else comes up with a better method.
--
Simon Hobson

Visit http://www.magpiesnestpublishing.co.uk/ for books by acclaimed
author Gladys Hobson. Novels - poetry - short stories - ideal as
Christmas stocking fillers. Some available as e-books.
Drew Weaver
2009-01-09 20:57:57 UTC
Permalink
Hi there.

Is it possible to specify a different pxeclient "next-server" for each subnet?

Currently I have this in my dhcpd.conf:

class "pxeclients" {
match if substring(option vendor-class-identifier, 0, 9) = "PXEClient";
next-server 10.1.0.1;
filename "linux-install/pxelinux.0";
}

I need to be able to specify the next-server for pxeclients for each subnet.

Currently, even though we have next-server in the subnet declaration it still uses 10.1.0.1

Any ideas?

Thanks,
-Drew
Jeffrey Hutzelman
2009-01-09 21:31:39 UTC
Permalink
--On Friday, January 09, 2009 03:57:57 PM -0500 Drew Weaver
Post by Drew Weaver
Hi there.
Is it possible to specify a different pxeclient "next-server" for each subnet?
class "pxeclients" {
match if substring(option vendor-class-identifier, 0, 9) =
"PXEClient"; next-server 10.1.0.1;
filename "linux-install/pxelinux.0";
}
I need to be able to specify the next-server for pxeclients for each subnet.
Currently, even though we have next-server in the subnet declaration it still uses 10.1.0.1
Any ideas?
IIRC, options specified for a class will take precedence over those present
in a subnet declaration. If you want a next-server for the subnet to have
effect, you'll have to remove the option from the class.

Alternately, if you want to override next-server only for PXE clients, but
set it to a per-subnet value, then you can include in each subnet
declaration a statement like

set pxe_server = 10.1.2.3;

and in the class a statement like

option server.next-server = pxe_server;


-- Jeff
Jeffrey Hutzelman
2009-01-09 21:31:39 UTC
Permalink
--On Friday, January 09, 2009 03:57:57 PM -0500 Drew Weaver
Post by Drew Weaver
Hi there.
Is it possible to specify a different pxeclient "next-server" for each subnet?
class "pxeclients" {
match if substring(option vendor-class-identifier, 0, 9) =
"PXEClient"; next-server 10.1.0.1;
filename "linux-install/pxelinux.0";
}
I need to be able to specify the next-server for pxeclients for each subnet.
Currently, even though we have next-server in the subnet declaration it still uses 10.1.0.1
Any ideas?
IIRC, options specified for a class will take precedence over those present
in a subnet declaration. If you want a next-server for the subnet to have
effect, you'll have to remove the option from the class.

Alternately, if you want to override next-server only for PXE clients, but
set it to a per-subnet value, then you can include in each subnet
declaration a statement like

set pxe_server = 10.1.2.3;

and in the class a statement like

option server.next-server = pxe_server;


-- Jeff
Simon Hobson
2009-01-09 21:35:48 UTC
Permalink
Content-Language: en-US
Content-Type: multipart/alternative;
boundary="_000_B7152C470C9BF3448ED33F16A75D81C14D44E868F8exchangathena_"
Hi there.
Is it possible to specify a different pxeclient "next-server" for each subnet?
class "pxeclients" {
match if substring(option vendor-class-identifier, 0, 9) = "PXEClient";
next-server 10.1.0.1;
filename "linux-install/pxelinux.0";
}
I need to be able to specify the next-server for pxeclients for each subnet.
Currently, even though we have next-server in the subnet declaration it still uses 10.1.0.1
IIRC the class definition will override the subnet declaration.
You'll need to have multiple classes I think.

Unless someone else comes up with a better method.
--
Simon Hobson

Visit http://www.magpiesnestpublishing.co.uk/ for books by acclaimed
author Gladys Hobson. Novels - poetry - short stories - ideal as
Christmas stocking fillers. Some available as e-books.
Loading...