雪龍~ <oolon.bbs@bbs.cynix.com.tw> wrote in message
news:3cGeLg$5iV@bbs.cynix.com.tw...
> ※ 引述《netmanforever@yahoo.com (網中人)》之銘言:
> > 小州 <kenduest.bbs@bbs.cynix.com.tw> wrote in message
> > news:3cG1US$5W6@bbs.cynix.com.tw...
> > >   有這種規定嗎?分別是 192.168.1.1 與 192.168.1.2 並沒有相衝突的地方。
> > 弟以為這是原理而非規定的問題。
> > 因為當一個封包被接收進來之後(來自 loopback device 的也一樣)﹐首先要做的
是檢
> > 查 route table 進行和目的地地址的比對。不過 route table 的特性之一是
first
> > match 的﹐也就是當找到第一筆符合條件的紀錄﹐就不再往下找了。換句話說﹐如
果兩
> > 張卡都在同一個 subnet 之內﹐那就會有兩筆關於同一個 subnet 的紀錄存在﹐這
時候
> > 要看第一個句子指定的是哪一個界面了。如果不是手工去修改﹐通常會是第一張﹐
所以
> > 他會以為第二張不工作了。
>
>     應該不能說是找到第一筆符合的紀錄就不再往下找, 就我所知道的好像是
>     最詳細的那一筆記錄喔. 比如說呢 192.168.1.10 的這個 ip 的位址可以
>     說是屬於 192.0.0.0 這個網路, 也可以是說屬於 192.168.0.0 的這個網
>     路, 當然也屬於 192.168.1.0 的網路, 端看你是用那一個等級的網路去看
>     待 192.168.1.10 的這個 ip , 就這個部分來說只要是對 TCP/IP 網路有
>     基本概念的人應該知道. 只不過在 route table 會針對所設定或是學習到
>     的路由資訊按照 Net IP 與 Mask 的狀況先做好排列, 所以會如你所說的找
>     到的第一筆, 就是為了增進網路效率. 不知道我這樣的說明有沒有錯誤的地
>     方, 真有的話要告訴我喔..... ^_^
>

多謝指教﹗

不過我覺得在同一個 router 上面(我想的目前討論都只講同一個 linux router 吧
﹖)﹐很少有人同時用 8bit、16bit、24bit (以及其它變動遮罩)同時描述一段
192.168.1.x 的網路吧﹖

就算有這樣的情形﹐讓我們敲 route -n 看看﹐所有 route add -host 的記錄會拍排
在前面(用 32bit mask 顯示)﹐然後到 route add -net 的記錄(也是依 mask 的 bit
數大小排列)﹐最後是 route add default 的記錄(也可以多個﹐不過卻是越遲寫的越
前面﹐請留意這個現象)。

好了﹐如果您有一張網路界面使用 192.168.1.17 ﹐不指定 mask 的話﹐將會使用預設
的 24bit (自然遮罩值)﹐否則按指定的寫入。這裡我們假設用預設好了。您或許會下
這樣的命令來完成這張界面的設定(不同的系統或許不同)﹕
ifconfig eth1 192.168.1.17 up
route add -host 192.168.1.17 dev eth1
route add -net 192.168.1.0 netmask 255.255.255.0 dev eth1
#註﹕route add -net 的 netmask 不能省﹐因為正如閣下所指出﹐不同等 mask 會指
定不同的 network﹐不過用 redhat 的 ifconfig 或許已經幫您設定好 route
add -net 了。

然後輸入 ifconfig 您會看到 eth1 會使用預設的 24bit mask。請留意﹕這非常重
要﹐因為這會求出界面所在的 net_ID (用 AND 的邏輯運算)。
再輸入 route -n 您會發現 192.168.1.17 這筆記錄是用 32bit 的 mask﹐會和其它
32bit mask 的記錄排在前端。同時您還會發現 192.168.1.0 這個 24 bit mask 的網
路之 device 會使用 eth1 。

好了﹐到這裡我們就可以進一步嘗試閣下所假設的環境﹐我們分別用 8bit 和 16bit
來增加 network 的記錄﹕
route add -net 192.168.0.0 netmask 255.255.0.0 dev eth0
route add -net 192.0.0.0 netmask 255.0.0.0 dev eth2
#注﹕我先故意使用 eth0 和 eth2 來設定這兩個 network﹐以確定路由不會經過
192.168.1.17 所在的 eth1 界面。

這時候的路由依據是什麼呢﹖(嗯~~﹐詳細的我不想重複了﹐有興趣可以參考前不久和
song 兄討論的文章﹐是關於 NAT 的)
假如我有一筆路由要傳遞給 192.168.1.18 ﹐會先檢查有沒有關於它的 32bit 的路由
記錄﹐沒有﹐那看看有沒有 netmask 指定﹖
這裡又帶出兩個情形﹕
1﹐沒有 mask﹐那好﹐套用自然遮罩會使用 24bit﹐然後求出 net_ID﹐發現是
192.168.1.0 這個 network ﹐剛好路由表有關於這個 network 的記錄﹐界面為
eth1﹐那麼將封包交由 eth1 傳遞。(之後的動作這裡不再討論了﹐請參考 arp 協定)
2﹐假如有 mask﹐那好﹐看 mask 的值﹐這裡假設用 16bit 吧﹐然後求出的 net_ID
是 192.168.0.0 ﹐再於路由表中發現這個 network 記錄﹐它的界面是 eth0﹐那麼將
封包交由 eth0 傳送。(假如 netmask 是 8 bit 也則會交由 eth2)

看這樣的過程﹐應該不會困擾吧﹖那就讓我們搞亂一下吧﹐再下這樣的命令﹕
route add -net 192.168.0.0 netmask 255.255.0.0 dev eth1
route add -net 192.0.0.0 netmask 255.0.0.0 dev eth1

哈﹐我們會同時有兩筆記錄分別是關於 192.168.0.0 和 192.0.0.0 的。這或許已經符
合這個討論的要求了吧﹖
這時﹐您就會發現越晚加入的設定會越排在前面。這也就是弟所指出的 first match
原則了。

而其後的測試(別忘了路由要雙向同時設定才有用哦)﹐還是交由您自己玩了。例如﹐您
確定 192.168.1.18 是經由 eth2 傳到 192.0.0.0 這個網路的﹐可以下這樣的命令﹕
route add -host 192.168.1.18 dev eth2
#註﹕如果還要經過另外一台 gateway﹐則要指定 gw 參數。
(這就是弟在前面文章中所說的靜態記錄了﹐應該是可行的﹐因為無需再往下比對了。)

p.s. 閣下所給出的例子﹐其實並沒運用到 first match 原則﹐因為在 route table
並沒有相同的記錄。(可用 route -n |awk '{print $1}' 來看看)