29.2 Gateways and Routes

Contributed by Coranth Gryphon.

為了讓一部電腦能找到另一部電腦,因此必需要有一種機制, 讓這部電腦知道該怎麼做,這個機制就是路由選擇 (routing)。 一條路由(“route”)是由一對位址所定義的:一個是 “目的地(destination)”以及另一個則是閘道 (“gateway”)。 這對位址表示要送到目的地的封包, 必須經過閘道。 目的地分為三種類型:主機、子網路(subnet)、 預設路由(“default route”)。 若都沒有其它的路由可以使用, 這時就會使用預設路由,稍後我們會對預設路由作進一步的說明。 此外, 閘道也可分為三種類型:主機、傳輸介面(interface,也稱為 “links”)、乙太網路硬體位址(MAC addresses)。

29.2.1 範例

為了方便說明不同類型的路由選擇(routing),以下使用 netstat 指令的結果作為介紹範例:

% netstat -r
Routing tables

Destination      Gateway            Flags     Refs     Use     Netif Expire

default          outside-gw         UGSc       37      418      ppp0
localhost        localhost          UH          0      181       lo0
test0            0:e0:b5:36:cf:4f   UHLW        5    63288       ed0     77
10.20.30.255     link#1             UHLW        1     2421
example.com      link#1             UC          0        0
host1            0:e0:a8:37:8:1e    UHLW        3     4601       lo0
host2            0:e0:a8:37:8:1e    UHLW        0        5       lo0 =>
host2.example.com link#1             UC          0        0
224              link#1             UC          0        0

前兩行是 default route( 下一小節會介紹),以及 localhost route。

The interface (在 Netif 那欄)可以看到 localhost 的 interface 是用 lo0,亦即所謂的 loopback 設備。 這表示所有通往目的地之封包,並不會透過 LAN 傳到網路上, 而是在內部處理。 因為這些流量起點跟終點都只會是同一處。

接下來則會看到 0:e0: 開頭的位址, 這些就是所謂的 MAC address。 FreeBSD 會自動識別在同一網路內的主機(比如例子中的 test0),並且將其加入路由表,然後透過 ed0 這個介面直接連過去。 這種路由都會有 timeout 機制(Expire 欄位), 若與該主機之間一直沒任何來往,在超過特定的時間後就會 timeout, 該筆路由就會自動刪除。 這些主機就是運用 RIP (Routing Information Protocol) 機制來識別,藉由 RIP 這項機制, 可以得出如何到同一網路內其他機器之間的最短路由。

FreeBSD will also add subnet routes for the local subnet (10.20.30.255 is the broadcast address for the subnet 10.20.30, and example.com is the domain name associated with that subnet). The designation link#1 refers to the first Ethernet card in the machine. You will notice no additional interface is specified for those.

Both of these groups (local network hosts and local subnets) have their routes automatically configured by a daemon called routed. If this is not run, then only routes which are statically defined (i.e. entered explicitly) will exist.

The host1 line refers to our host, which it knows by Ethernet address. Since we are the sending host, FreeBSD knows to use the loopback interface (lo0) rather than sending it out over the Ethernet interface.

The two host2 lines are an example of what happens when we use an ifconfig(8) alias (see the section on Ethernet for reasons why we would do this). The => symbol after the lo0 interface says that not only are we using the loopback (since this address also refers to the local host), but specifically it is an alias. Such routes only show up on the host that supports the alias; all other hosts on the local network will simply have a link#1 line for such routes.

The final line (destination subnet 224) deals with multicasting, which will be covered in another section.

Finally, various attributes of each route can be seen in the Flags column. Below is a short table of some of these flags and their meanings:

U Up: The route is active.
H Host: The route destination is a single host.
G Gateway: Send anything for this destination on to this remote system, which will figure out from there where to send it.
S Static: This route was configured manually, not automatically generated by the system.
C Clone: Generates a new route based upon this route for machines we connect to. This type of route is normally used for local networks.
W WasCloned: Indicated a route that was auto-configured based upon a local area network (Clone) route.
L Link: Route involves references to Ethernet hardware.

29.2.2 Default Routes

When the local system needs to make a connection to a remote host, it checks the routing table to determine if a known path exists. If the remote host falls into a subnet that we know how to reach (Cloned routes), then the system checks to see if it can connect along that interface.

If all known paths fail, the system has one last option: the “default” route. This route is a special type of gateway route (usually the only one present in the system), and is always marked with a c in the flags field. For hosts on a local area network, this gateway is set to whatever machine has a direct connection to the outside world (whether via PPP link, DSL, cable modem, T1, or another network interface).

If you are configuring the default route for a machine which itself is functioning as the gateway to the outside world, then the default route will be the gateway machine at your Internet Service Provider's (ISP) site.

Let us look at an example of default routes. This is a common configuration:

The hosts Local1 and Local2 are at your site. Local1 is connected to an ISP via a dial up PPP connection. This PPP server computer is connected through a local area network to another gateway computer through an external interface to the ISPs Internet feed.

The default routes for each of your machines will be:

Host Default Gateway Interface
Local2 Local1 Ethernet
Local1 T1-GW PPP

A common question is “Why (or how) would we set the T1-GW to be the default gateway for Local1, rather than the ISP server it is connected to?”.

Remember, since the PPP interface is using an address on the ISP's local network for your side of the connection, routes for any other machines on the ISP's local network will be automatically generated. Hence, you will already know how to reach the T1-GW machine, so there is no need for the intermediate step of sending traffic to the ISP server.

It is common to use the address X.X.X.1 as the gateway address for your local network. So (using the same example), if your local class-C address space was 10.20.30 and your ISP was using 10.9.9 then the default routes would be:

Host Default Route
Local2 (10.20.30.2) Local1 (10.20.30.1)
Local1 (10.20.30.1, 10.9.9.30) T1-GW (10.9.9.1)

You can easily define the default route via the /etc/rc.conf file. In our example, on the Local2 machine, we added the following line in /etc/rc.conf:

defaultrouter="10.20.30.1"

It is also possible to do it directly from the command line with the route(8) command:

# route add default 10.20.30.1

For more information on manual manipulation of network routing tables, consult route(8) manual page.

29.2.3 Dual Homed Hosts

There is one other type of configuration that we should cover, and that is a host that sits on two different networks. Technically, any machine functioning as a gateway (in the example above, using a PPP connection) counts as a dual-homed host. But the term is really only used to refer to a machine that sits on two local-area networks.

In one case, the machine has two Ethernet cards, each having an address on the separate subnets. Alternately, the machine may only have one Ethernet card, and be using ifconfig(8) aliasing. The former is used if two physically separate Ethernet networks are in use, the latter if there is one physical network segment, but two logically separate subnets.

Either way, routing tables are set up so that each subnet knows that this machine is the defined gateway (inbound route) to the other subnet. This configuration, with the machine acting as a router between the two subnets, is often used when we need to implement packet filtering or firewall security in either or both directions.

If you want this machine to actually forward packets between the two interfaces, you need to tell FreeBSD to enable this ability. See the next section for more details on how to do this.

29.2.4 Building a Router

A network router is simply a system that forwards packets from one interface to another. Internet standards and good engineering practice prevent the FreeBSD Project from enabling this by default in FreeBSD. You can enable this feature by changing the following variable to YES in rc.conf(5):

gateway_enable=YES          # Set to YES if this host will be a gateway

This option will set the sysctl(8) variable net.inet.ip.forwarding to 1. If you should need to stop routing temporarily, you can reset this to 0 temporarily.

Your new router will need routes to know where to send the traffic. If your network is simple enough you can use static routes. FreeBSD also comes with the standard BSD routing daemon routed(8), which speaks RIP (both version 1 and version 2) and IRDP. Support for BGP v4, OSPF v2, and other sophisticated routing protocols is available with the net/zebra package. Commercial products such as GateD® are also available for more complex network routing solutions.

29.2.5 Setting Up Static Routes

Contributed by Al Hoang.

29.2.5.1 Manual Configuration

Let us assume we have a network as follows:

In this scenario, RouterA is our FreeBSD machine that is acting as a router to the rest of the Internet. It has a default route set to 10.0.0.1 which allows it to connect with the outside world. We will assume that RouterB is already configured properly and knows how to get wherever it needs to go. (This is simple in this picture. Just add a default route on RouterB using 192.168.1.1 as the gateway.)

If we look at the routing table for RouterA we would see something like the following:

% netstat -nr
Routing tables

Internet:
Destination        Gateway            Flags    Refs      Use  Netif  Expire
default            10.0.0.1           UGS         0    49378    xl0
127.0.0.1          127.0.0.1          UH          0        6    lo0
10.0.0/24          link#1             UC          0        0    xl0
192.168.1/24       link#2             UC          0        0    xl1

With the current routing table RouterA will not be able to reach our Internal Net 2. It does not have a route for 192.168.2.0/24. One way to alleviate this is to manually add the route. The following command would add the Internal Net 2 network to RouterA's routing table using 192.168.1.2 as the next hop:

# route add -net 192.168.2.0/24 192.168.1.2

Now RouterA can reach any hosts on the 192.168.2.0/24 network.

29.2.5.2 Persistent Configuration

The above example is perfect for configuring a static route on a running system. However, one problem is that the routing information will not persist if you reboot your FreeBSD machine. The way to handle the addition of a static route is to put it in your /etc/rc.conf file:

# Add Internal Net 2 as a static route
static_routes="internalnet2"
route_internalnet2="-net 192.168.2.0/24 192.168.1.2"

The static_routes configuration variable is a list of strings separated by a space. Each string references to a route name. In our above example we only have one string in static_routes. This string is internalnet2. We then add a configuration variable called route_internalnet2 where we put all of the configuration parameters we would give to the route(8) command. For our example above we would have used the command:

# route add -net 192.168.2.0/24 192.168.1.2

so we need "-net 192.168.2.0/24 192.168.1.2".

As said above, we can have more than one string in static_routes. This allows us to create multiple static routes. The following lines shows an example of adding static routes for the 192.168.0.0/24 and 192.168.1.0/24 networks on an imaginary router:

static_routes="net1 net2"
route_net1="-net 192.168.0.0/24 192.168.0.1"
route_net2="-net 192.168.1.0/24 192.168.1.1"

29.2.6 Routing Propagation

We have already talked about how we define our routes to the outside world, but not about how the outside world finds us.

We already know that routing tables can be set up so that all traffic for a particular address space (in our examples, a class-C subnet) can be sent to a particular host on that network, which will forward the packets inbound.

When you get an address space assigned to your site, your service provider will set up their routing tables so that all traffic for your subnet will be sent down your PPP link to your site. But how do sites across the country know to send to your ISP?

There is a system (much like the distributed DNS information) that keeps track of all assigned address-spaces, and defines their point of connection to the Internet Backbone. The “Backbone” are the main trunk lines that carry Internet traffic across the country, and around the world. Each backbone machine has a copy of a master set of tables, which direct traffic for a particular network to a specific backbone carrier, and from there down the chain of service providers until it reaches your network.

It is the task of your service provider to advertise to the backbone sites that they are the point of connection (and thus the path inward) for your site. This is known as route propagation.

29.2.7 Troubleshooting

Sometimes, there is a problem with routing propagation, and some sites are unable to connect to you. Perhaps the most useful command for trying to figure out where routing is breaking down is the traceroute(8) command. It is equally useful if you cannot seem to make a connection to a remote machine (i.e. ping(8) fails).

The traceroute(8) command is run with the name of the remote host you are trying to connect to. It will show the gateway hosts along the path of the attempt, eventually either reaching the target host, or terminating because of a lack of connection.

For more information, see the manual page for traceroute(8).

29.2.8 Multicast Routing

FreeBSD supports both multicast applications and multicast routing natively. Multicast applications do not require any special configuration of FreeBSD; applications will generally run out of the box. Multicast routing requires that support be compiled into the kernel:

options MROUTING

In addition, the multicast routing daemon, mrouted(8) must be configured to set up tunnels and DVMRP via /etc/mrouted.conf. More details on multicast configuration may be found in the manual page for mrouted(8).

本文及其他文件,可由此下載:ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/

若有 FreeBSD 方面疑問,請先閱讀 FreeBSD 相關文件,如不能解決的話,再洽詢 <questions@FreeBSD.org>。
關於本文件的問題,請洽詢 <doc@FreeBSD.org>。