I have done this in a different way, namely by 'filtering' the variables that are passed to /sbin/dhclient-script by using the 'script "/path/to/my/script"' option to run my own script, act on variables I care about (dns and default gateway) and then calling /sbin/dhclient-script in the event it still has something to do.
Honestly I think your approach is cleaner, and more likely to survive the ever eminent promise from krw@ to remove the script entirely. Thanks, Penned by Stefan Sperling on 20110816 5:08.37, we have: | In some networks (e.g. at public events using open wifi) I want | traffic not destined for the local network to go through a VPN. | | If the local network uses DHCP, I usually end up killing dhclient | because it's impossible to renew the lease without changing the | default route. | | To be clear, I end up with a command sequence like: | | dhclient wpi0 # get a local address | netstat -rn -finet | grep ^default # figure out local router | route delete default # don't use local router for everything | route add -host $VPN_SERVER_IP $LOCAL_ROUTER # just for this host | openvpn config-file # start VPN, i am too dumb for ipsec | route add default $ROUTER_BEHIND_VPN # use my trusted router as default | pkill -x dhclient # kill dhclient to avoid default route change later | | The problem is that the lease expires at some point and things | usually stop working until I perform the same tedious configuration | dance again. | | The patch below adds a new option to dhclient.conf (the VPN server is | at 10.1.1.1 in this example): | | interface "wpi0" { | host-route 10.1.1.1; | } | | Instead of adding a default route dhclient will add a host route | to the specified address. So the above sequence becomes: | | dhclient wpi0 # get a local address, add route to VPN server | openvpn config-file # start VPN | route add default $ROUTER_BEHIND_VPN # use my trusted router as default | | And the configuration remains stable. | | Is this a good approach? | Does anyone else think this is useful? | | | Index: clparse.c | =================================================================== | RCS file: /cvs/src/sbin/dhclient/clparse.c,v | retrieving revision 1.37 | diff -u -p -r1.37 clparse.c | --- clparse.c 4 Apr 2011 11:14:52 -0000 1.37 | +++ clparse.c 12 Aug 2011 18:04:02 -0000 | @@ -151,7 +151,8 @@ read_client_leases(void) | * interface-declaration | | * TOK_LEASE client-lease-statement | | * TOK_ALIAS client-lease-statement | | - * TOK_REJECT reject-statement | + * TOK_REJECT reject-statement | | + * TOK_HOST_ROUTE host-route-statement | */ | void | parse_client_statement(FILE *cfile) | @@ -234,6 +235,9 @@ parse_client_statement(FILE *cfile) | case TOK_REJECT: | parse_reject_statement(cfile); | return; | + case TOK_HOST_ROUTE: | + parse_host_route_statement(cfile); | + return; | default: | parse_warn("expecting a statement."); | skip_to_semi(cfile); | @@ -739,6 +743,25 @@ parse_reject_statement(FILE *cfile) | token = next_token(&val, cfile); | } while (token == ','); | | + if (token != ';') { | + parse_warn("expecting semicolon."); | + skip_to_semi(cfile); | + } | +} | + | +void | +parse_host_route_statement(FILE *cfile) | +{ | + char *val; | + int token; | + | + if (!parse_ip_addr(cfile, &config->host_route)) { | + parse_warn("expecting IP address."); | + skip_to_semi(cfile); | + return; | + } | + | + token = next_token(&val, cfile); | if (token != ';') { | parse_warn("expecting semicolon."); | skip_to_semi(cfile); | Index: conflex.c | =================================================================== | RCS file: /cvs/src/sbin/dhclient/conflex.c,v | retrieving revision 1.13 | diff -u -p -r1.13 conflex.c | --- conflex.c 17 Dec 2006 17:41:56 -0000 1.13 | +++ conflex.c 12 Aug 2011 18:00:51 -0000 | @@ -324,6 +324,7 @@ static const struct keywords { | { "filename", TOK_FILENAME }, | { "fixed-address", TOK_FIXED_ADDR }, | { "hardware", TOK_HARDWARE }, | + { "host-route", TOK_HOST_ROUTE }, | { "initial-interval", TOK_INITIAL_INTERVAL }, | { "interface", TOK_INTERFACE }, | { "lease", TOK_LEASE }, | Index: dhclient-script | =================================================================== | RCS file: /cvs/src/sbin/dhclient/dhclient-script,v | retrieving revision 1.22 | diff -u -p -r1.22 dhclient-script | --- dhclient-script 9 Apr 2011 19:53:00 -0000 1.22 | +++ dhclient-script 12 Aug 2011 18:06:00 -0000 | @@ -60,11 +60,16 @@ delete_old_routes() { | add_new_routes() { | route -q $rdomain -n flush -inet -iface $interface | for router in $new_routers; do | - if [ "$new_ip_address" = "$router" ]; then | - route -q $rdomain add default -iface $router | + if [ -n "$host_route" -a "$host_route" != "0.0.0.0" ]; then | + new_route="-host $host_route $router" | else | - route -q $rdomain add default $router | + if [ "$new_ip_address" = "$router" ]; then | + new_route="default -iface $router" | + else | + new_route="default $router" | + fi | fi | + route -q $rdomain add $new_route | # 2nd and subsequent default routers error out, so explicitly | # stop processing the list after the first one. | break | Index: dhclient.c | =================================================================== | RCS file: /cvs/src/sbin/dhclient/dhclient.c,v | retrieving revision 1.141 | diff -u -p -r1.141 dhclient.c | --- dhclient.c 11 May 2011 14:38:36 -0000 1.141 | +++ dhclient.c 12 Aug 2011 18:06:57 -0000 | @@ -1604,6 +1604,9 @@ supersede: | } | snprintf(tbuf, sizeof(tbuf), "%d", (int)lease->expiry); | script_set_env(prefix, "expiry", tbuf); | + | + if (config->host_route.len) | + script_set_env("", "host_route", piaddr(config->host_route)); | } | | void | Index: dhclient.conf.5 | =================================================================== | RCS file: /cvs/src/sbin/dhclient/dhclient.conf.5,v | retrieving revision 1.21 | diff -u -p -r1.21 dhclient.conf.5 | --- dhclient.conf.5 9 Apr 2011 19:53:00 -0000 1.21 | +++ dhclient.conf.5 13 Aug 2011 19:18:56 -0000 | @@ -430,6 +430,13 @@ If no lease is acquired, the script is u | any, and also called once if no valid lease can be identified. | For more information, see | .Xr dhclient.leases 5 . | +.It Ic host-route Ar ip-address ; | +The | +.Ic host-route | +statement causes the DHCP client to install a host route to the specified | +IP address instead of installing a default route. | +This is useful if the default route points to a VPN tunnel terminated | +at the specified IP address instead of a router on the local network. | .El | .Sh EXAMPLES | The following configuration file is used on a laptop | Index: dhcpd.h | =================================================================== | RCS file: /cvs/src/sbin/dhclient/dhcpd.h,v | retrieving revision 1.73 | diff -u -p -r1.73 dhcpd.h | --- dhcpd.h 11 May 2011 14:38:36 -0000 1.73 | +++ dhcpd.h 12 Aug 2011 18:03:23 -0000 | @@ -150,6 +150,7 @@ struct client_config { | enum { IGNORE, ACCEPT, PREFER } | bootp_policy; | struct iaddrlist *reject_list; | + struct iaddr host_route; | }; | | struct client_state { | @@ -344,3 +345,4 @@ void parse_client_lease_declaration(FILE | int parse_option_decl(FILE *, struct option_data *); | void parse_string_list(FILE *, struct string_list **, int); | void parse_reject_statement(FILE *); | +void parse_host_route_statement(FILE *); | Index: dhctoken.h | =================================================================== | RCS file: /cvs/src/sbin/dhclient/dhctoken.h,v | retrieving revision 1.5 | diff -u -p -r1.5 dhctoken.h | --- dhctoken.h 15 May 2006 08:10:57 -0000 1.5 | +++ dhctoken.h 12 Aug 2011 18:03:38 -0000 | @@ -79,6 +79,7 @@ | #define TOK_REJECT 292 | #define TOK_FDDI 293 | #define TOK_LINK_TIMEOUT 294 | +#define TOK_HOST_ROUTE 295 | | #define is_identifier(x) ((x) >= TOK_FIRST_TOKEN && \ | (x) != TOK_STRING && \ -- Todd Fries .. t...@fries.net _____________________________________________ | \ 1.636.410.0632 (voice) | Free Daemon Consulting, LLC \ 1.405.227.9094 (voice) | http://FreeDaemonConsulting.com \ 1.866.792.3418 (FAX) | 2525 NW Expy #525, Oklahoma City, OK 73112 \ sip:freedae...@ekiga.net | "..in support of free software solutions." \ sip:4052279...@ekiga.net \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ 37E7 D3EB 74D0 8D66 A68D B866 0326 204E 3F42 004A http://todd.fries.net/pgp.txt