It may be a bit late to consider this for 4.7.
.... Ken
On Wed, Feb 10, 2010 at 04:10:05PM +0300, ????? ??????? wrote:
> Hi All,
>
> could you please include to new release this patch to dhclient,
> based on FreeBSD dhclient's patch.
> The patch adds support of RFC 3442 (The Classless Static Route
> Option for Dynamic Host) by dhclient.
>
>
>
> diff -u /tmp/src/sbin/dhclient/clparse.c /usr/src/sbin/dhclient/clparse.c
> --- /tmp/src/sbin/dhclient/clparse.c Sun Jul 19 04:18:02 2009
> +++ /usr/src/sbin/dhclient/clparse.c Wed Feb 3 11:14:34 2010
> @@ -75,6 +75,8 @@
> config->requested_options
> [config->requested_option_count++] = DHO_TIME_OFFSET;
> config->requested_options
> + [config->requested_option_count++] = DHO_CLASSLESS_ROUTES;
> + config->requested_options
> [config->requested_option_count++] = DHO_ROUTERS;
> config->requested_options
> [config->requested_option_count++] = DHO_DOMAIN_NAME;
> diff -u /tmp/src/sbin/dhclient/dhclient-script
> /usr/src/sbin/dhclient/dhclient-script
> --- /tmp/src/sbin/dhclient/dhclient-script Wed Jun 3 09:12:51 2009
> +++ /usr/src/sbin/dhclient/dhclient-script Wed Feb 10 16:06:55 2010
> @@ -55,9 +55,44 @@
> fi
> }
>
> +fill_classless_routes() {
> + set $1
> + while [ $# -gt 5 ]; do
> + if [ $1 -eq 0 ]; then
> + route="default"
> + elif [ $1 -lt 9 ]; then
> + route="$2.0.0.0/$1"
> + shift
> + elif [ $1 -lt 17 ]; then
> + route="$2.$3.0.0/$1"
> + shift; shift
> + elif [ $1 -lt 25 ]; then
> + route="$2.$3.$4.0/$1"
> + shift; shift; shift
> + else
> + route="$2.$3.$4.$5/$1"
> + shift; shift; shift; shift
> + fi
> + shift
> + router="$1.$2.$3.$4"
> + classless_routes="$classless_routes $route $router"
> + shift; shift; shift; shift
> + done
> +}
> +
> delete_old_routes() {
> # Delete existing default route. We only allow one, so no need to
> # process $old_routers list.
> + if [ -n "$old_classless_routes" ]; then
> + fill_classless_routes "$old_classless_routes"
> + set $classless_routes
> + while [ $# -gt 1 ]; do
> + route delete "$1" "$2"
> + shift; shift
> + done
> + return 0;
> + fi
> +
> route -n flush -inet -iface $interface >/dev/null 2>&1
>
> if [ -n "$old_static_routes" ]; then
> @@ -73,6 +108,21 @@
>
> add_new_routes() {
> route -n flush -inet -iface $interface >/dev/null 2>&1
> +
> + if [ -n "$new_classless_routes" ]; then
> + fill_classless_routes "$new_classless_routes"
> + set $classless_routes
> + while [ $# -gt 1 ]; do
> + if [ "0.0.0.0" = "$2" ]; then
> + route add "$1" -iface "$interface"
> + else
> + route add "$1" "$2"
> + fi
> + shift; shift
> + done
> + return
> + fi
> +
> for router in $new_routers; do
> if [ "$new_ip_address" = "$router" ]; then
> route add default -iface $router >/dev/null 2>&1
> diff -u /tmp/src/sbin/dhclient/dhclient.c /usr/src/sbin/dhclient/dhclient.c
> --- /tmp/src/sbin/dhclient/dhclient.c Thu Nov 12 17:18:45 2009
> +++ /usr/src/sbin/dhclient/dhclient.c Wed Feb 3 11:14:34 2010
> @@ -88,6 +88,7 @@
> struct sockaddr *get_ifa(char *, int);
> void usage(void);
> int check_option(struct client_lease *l, int option);
> +int check_classless_option(unsigned char *data, int len);
> int ipv4addrs(char * buf);
> int res_hnok(const char *dn);
> char *option_as_string(unsigned int code, unsigned char
> *data, int len);
> @@ -2034,10 +2035,69 @@
> case DHO_DHCP_USER_CLASS_ID:
> case DHO_END:
> return (1);
> + case DHO_CLASSLESS_ROUTES:
> + return (check_classless_option(l->options[option].data,
> + l->options[option].len));
> default:
> warning("unknown dhcp option value 0x%x", option);
> return (unknown_ok);
> }
> +}
> +
> +int
> +check_classless_option(unsigned char *data, int len)
> +{
> + int i = 0;
> + unsigned char width;
> + in_addr_t addr, mask;
> +
> + if (len < 5) {
> + warning("Too small length: %d", len);
> + return (0);
> + }
> +
> + while(i < len) {
> + width = data[i++];
> + if (width == 0) {
> + i += 4; continue;
> + } else if (width < 9) {
> + addr = (in_addr_t)(data[i] << 24);
> + i += 1;
> + } else if (width < 17) {
> + addr = (in_addr_t)(data[i] << 24) +
> + (in_addr_t)(data[i + 1] << 16);
> + i += 2;
> + } else if (width < 25) {
> + addr = (in_addr_t)(data[i] << 24) +
> + (in_addr_t)(data[i + 1] << 16) +
> + (in_addr_t)(data[i + 2] << 8);
> + i += 3;
> + } else if (width < 33) {
> + addr = (in_addr_t)(data[i] << 24) +
> + (in_addr_t)(data[i + 1] << 16) +
> + (in_addr_t)(data[i + 2] << 8) +
> + data[i + 3];
> + i += 4;
> + } else {
> + warning("Incorrect subnet width: %d", width);
> + return(0);
> + }
> + mask = (in_addr_t)(~0) << (32 - width);
> + addr = ntohl(addr);
> + mask = ntohl(mask);
> +
> + if ((addr & mask) != addr) {
> + addr &= mask;
> + data[i - 1] = (unsigned char)
> + ((addr >> (((32 - width)/8)*8)) & 0xFF);
> + }
> + i += 4;
> + }
> + if (i > len) {
> + warning("Incorrect data length: %d (must be %d)", len, i);
> + return (0);
> + }
> + return (1);
> }
>
> int
> diff -u /tmp/src/sbin/dhclient/dhclient.conf.5
> /usr/src/sbin/dhclient/dhclient.conf.5
> --- /tmp/src/sbin/dhclient/dhclient.conf.5 Mon Oct 6 00:36:00 2008
> +++ /usr/src/sbin/dhclient/dhclient.conf.5 Wed Feb 3 11:14:34 2010
> @@ -514,8 +514,9 @@
> send dhcp-lease-time 3600;
> supersede domain-name "fugue.com rc.vix.com home.vix.com";
> prepend domain-name-servers 127.0.0.1;
> - request subnet-mask, broadcast-address, time-offset, routers,
> - domain-name, domain-name-servers, host-name;
> + request subnet-mask, broadcast-address, time-offset,
> + classless-routes, routers, domain-name,
> + domain-name-servers, host-name;
> require subnet-mask, domain-name-servers;
> script "/etc/dhclient-script";
> media "media 10baseT/UTP", "media 10base2/BNC";
> diff -u /tmp/src/sbin/dhclient/dhcp.h /usr/src/sbin/dhclient/dhcp.h
> --- /tmp/src/sbin/dhclient/dhcp.h Fri Feb 2 01:39:43 2007
> +++ /usr/src/sbin/dhclient/dhcp.h Wed Feb 3 11:14:34 2010
> @@ -153,6 +153,7 @@
> #define DHO_DHCP_CLASS_IDENTIFIER 60
> #define DHO_DHCP_CLIENT_IDENTIFIER 61
> #define DHO_DHCP_USER_CLASS_ID 77
> +#define DHO_CLASSLESS_ROUTES 121
> #define DHO_END 255
>
> /* DHCP message types. */
> diff -u /tmp/src/sbin/dhclient/tables.c /usr/src/sbin/dhclient/tables.c
> --- /tmp/src/sbin/dhclient/tables.c Sat Jul 16 20:31:46 2005
> +++ /usr/src/sbin/dhclient/tables.c Wed Feb 3 11:14:34 2010
> @@ -182,7 +182,7 @@
> /* 118 */ { "option-118", "X" },
> /* 119 */ { "option-119", "X" },
> /* 120 */ { "option-120", "X" },
> - /* 121 */ { "option-121", "X" },
> + /* 121 */ { "classless-routes", "BA" },
> /* 122 */ { "option-122", "X" },
> /* 123 */ { "option-123", "X" },
> /* 124 */ { "option-124", "X" },
>
>
>
>
>
> --
> Anton Kasimov