# dhclient and/or system can't add unroutable gateway



## daikichi (May 2, 2010)

I run 7-stable as a pf-based router for my home dsl network.  I get my dsl from at&t and recently moved a couple of miles away, but still have a&t dsl.  Imagine my surprise when things didn't just work again at the new house.

The setup:

dc0=192.168.0.1/24, internal network
rl0=DHCP

rl0 is plugged to my motorola dsl modem.  I run the modem in sort of a "half-bridge" mode, wherein the modem does the pppoe auth and then automagically bridges the public IP it receives over to rl0.  I'm not entirely sure how this works, but it's worked fine for a year or so.  I used to always just go with full-bridge and have FreeBSD do the pppoe too, but since the new modem could handle it, I let it.  In addition to half-bridge and full-bridge, the modem can also do a (seemingly) 1 to 1 nat.  The modem has a built in IP of 192.168.1.254, and it can dhcp out 1 address, 192.168.1.65.  It seems to forward all ports to this 65 address.

Anyway, I'm still doing the half-bridge thing.  At startup, you'll see dhclient first get 192.168.1.65 with a gateway of 192.168.1.254.  A minute later or so, dhclient replaces these addresses with the public IP and public gateway, which --before I moved-- were on the same subnet, e.g. 75.200.0.0 (IP of  75.200.12.34 and gateway of 75.200.12.35).  At this point, btw, the bsd box can still ping 192.168.1.254.  Whether this is due to magical bridging or arp cache, I don't know.

So, after I moved and saw things weren't working, I eventually saw that the bsd box had no default gateway.  What was happening was that dhclient was still getting offered the IP of 75.200.12.34, but then was offered a gateway somewhere completely different, like 151.1.2.3, which was not added to the routing table since bsd has no idea how to get there.

Manually adding the gateway doesn't work.  "route add 0.0.0.0 151.1.2.3" fails since there's no route possible.  "route add 0.0.0.0 -interface rl0" kindof does something, in that I can at least reach some things, but not many.  The best hack I could find to get the routing table how it should be is:


```
-route add 0.0.0.0 -interface rl0
-ping 151.1.2.3 (adds it to arp cache)
-route del 0.0.0.0
-route add 0.0.0.0 151.1.2.3
```

This desirable state doesn't persist forever though, as either dhcp or arp-cache-expiration or something eventually reverts the routing table to its original gateway-less state.

Of course, this all sounds like normal behavior in a sense.  After all, why should bsd be able to add a gateway that it can't route to?  My only problem with this is that Windows seems to be able to figure it out :\
If I plug a Windows box with dhcp enabled into the modem, its table shows a default route of 151.1.2.3 with an interface of 75.200.12.34.  Everything works fine.  Not sure how to explain that one.


Anyway, I realize and can do one of the other solutions, such as full-bridge like I used to (haven't tried yet, tho it would seem it may present the same problem?) or do the double-NAT (which seems to work fine actually...even for incoming connections..not sure if I should trust it though?).
I really am determined to get my original solution working again, if only on principle.  

Any ideas (besides convincing at&t to assign me a different gateway)?


----------



## SirDice (May 4, 2010)

I have a similar issue. My modem is set up to use SIP spoofing. Works fine but the default gateway the DHCP gives me is outside my subnet. This fails on *nix but works fine in Windows. I solved it by creating a /etc/dhclient-enter-hooks script:


```
add_new_resolv_conf() {
        # We don't want /etc/resolv.conf changed
        # So this is an empty function
        return 0
}

add_new_routes() {
        route add -net 10.0.0.138 -iface $new_ip_address
        route add default 10.0.0.138
}
```

The code prevents my /etc/resolv.conf from being overwritten and it adds the route in a specific way. This has been working for a few years now.


----------

