ebtables之BROUTING和PREROUTING的redirect的区别

转载 2015年08月28日 19:28:28

http://www.oschina.net/question/234345_47404


ebtables和iptables实用工具都使用了Netfilter框架,这是它们一致的一方面,然而对于这两者还真有一些需要联动的地方。很多人不明白ebtales的broute表的redirect和nat表PREROUTING的redirect的区别,其实只要记住两点即可,那就是对于相同点,它们都将数据包导向了本地的IP层;对于不同点,broute表的redirect将数据包的接收设备设置成了实际接收数据的物理网卡,而nat表将数据包的接收设备设置成了桥设备,这个可以在Linux协议栈的源代码中看个究竟。对于broute表的redirect,可以在br_handle_frame这个handle_bridge调用的回调函数中看到以下的语句: 

  1. switch (p->state) {  
  2. case BR_STATE_FORWARDING:  
  3.     rhook = rcu_dereference(br_should_route_hook);  
  4.     if (rhook != NULL) {  
  5.         if (rhook(skb))  
  6.             return skb;  
  7.         dest = eth_hdr(skb)->h_dest;  
  8.     }  
  9.     /* fall through */  
  10. case BR_STATE_LEARNING:  
  11.     if (!compare_ether_addr(p->br->dev->dev_addr, dest))  
  12.         skb->pkt_type = PACKET_HOST;  
  13.     NF_HOOK(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL,  
  14.         br_handle_frame_finish);  
  15.     break;  
  16. ...  
我们看一下br_should_route_hook这个回调函数ebt_broute: 
  1. static int ebt_broute(struct sk_buff *skb)  
  2. {  
  3.     int ret;  
  4.   
  5.     ret = ebt_do_table(NF_BR_BROUTING, skb, skb->dev, NULL,  
  6.                dev_net(skb->dev)->xt.broute_table);  
  7.     if (ret == NF_DROP)  
  8.         return 1; /* route it */  
  9.     return 0; /* bridge it */  
  10. }  
它进入了我们都熟悉xxx_do_table函数,这也就是常规的Netfilter规则查找操作,最终在找到匹配规则时,进入redirect这个target。如果没有broute表的规则,则会进入NF_HOOK这个HOOK,其间将会遍NF_BR_BROUTING所有的规则,如果有target为redirect的规则命中,则也会进入redirect这个target,这个target是什么呢?是ebt_redirect_tg这个函数: 
  1. static unsigned int  
  2. ebt_redirect_tg(struct sk_buff *skb, const struct xt_target_param *par)  
  3. {  
  4.     const struct ebt_redirect_info *info = par->targinfo;  
  5.   
  6.     if (!skb_make_writable(skb, 0))  
  7.         return EBT_DROP;  
  8.   
  9.     if (par->hooknum != NF_BR_BROUTING)  
  10.         //如果是NAT的PREROUTING,则将桥的MAC地址复制到数据包的目的MAC地址。  
  11.         memcpy(eth_hdr(skb)->h_dest,  
  12.                par->in->br_port->br->dev->dev_addr, ETH_ALEN);  
  13.     else  
  14.         //如果是broute表的BROUTING,则将实际接收数据包的物理网卡的MAC地址复制到数据包的目的MAC地址。  
  15.         memcpy(eth_hdr(skb)->h_dest, par->in->dev_addr, ETH_ALEN);  
  16.     //本机可以接收该数据包  
  17.     skb->pkt_type = PACKET_HOST;  
  18.     //一般返回DROP  
  19.     return info->target;  
  20. }  
从br_handle_frame可以看出,一旦broute表的匹配规则返回了DROP,则handle_bridge直接返回这个skb,不再向下执行,这意味着skb将在handle_bridge返回后沿着netif_receive_skb继续走下去,而如果没有匹配的broute表规则,则可能在nat表的PREROUTING链中命中,然后在执行了ebt_redirect_tg之后会调用br_handle_frame_finish继续下去,在br_handle_frame_finish中,由于目的MAC地址已经改成了本机网卡的MAC地址,因此会调用br_pass_frame_up将数据包向协议栈的上层发送: 
  1. static void br_pass_frame_up(struct net_bridge *br, struct sk_buff *skb)  
  2. {  
  3.     struct net_device *indev, *brdev = br->dev;  
  4.   
  5.     brdev->stats.rx_packets++;  
  6.     brdev->stats.rx_bytes += skb->len;  
  7.   
  8.     indev = skb->dev;  
  9.     //将skb的dev修改成了brX,这样在接下来经过LOCAL_IN之后再次调用netif_receive_skb之后,在netif_receive_skb中就不会再次进入handle_bridge的  
  10. 处理逻](我家小小按下的...)辑了。  
  11.     skb->dev = brdev;  
  12.   
  13.     NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, indev, NULL,  
  14.         netif_receive_skb);  
  15. }  
注意,在broute表中的redrect之后,数据包的接收设备是实际的物理网卡ethX,目的MAC成了物理网卡ethX的MAC地址,而在nat的PREROUTING的redirect之后,数据包的接收设备是网桥设备,目的MAC地址成了网桥设备的MAC地址,知道了这个之后,我们再看一下一个和iptables的nat表的redirect的问题。 
    设想一个配置,本机S的eth0的IP地址为1.1.1.254/24,其上开启tcp的88端口,和本机直连的一台主机H的IP地址为1.1.1.2/24,在S上配置: 
brctl addbr br0
brctl addif eth0
ifconfig br0 1.1.1.254/24
ifcongig eth0 0.0.0.0  #为了防止路由乱掉,因此删除eth0的IP地址
iptables -t nat -A PREROUTING -d 2.2.2.2 -p tcp --dport 1234 -j REDIRECT --to-ports 88
在H上执行 
route add -host 2.2.2.2 gw 1.1.1.254
telnet 2.2.2.2 1234
结果呢?不通!连syn-ack都没有收到,然而在S上删除REDIRECT规则而执行以下规则则是可以的: 
iptables -t nat -A PREROUTING -d 2.2.2.2 -p tcp --dport 1234 -j DNAT --to-destination 1.1.1.254:88
难道DNAT和REDIRECT有什么区别吗?如果你不明白这两者有什么区别,那么如果你知道SNAT和MASQUERADE的区别也不错,起码能帮助你理解。DNAT和SNAT能指定任 
意的源地址一样,可以指定任意的目的地址,那么REDIRECT则和MASQUERADE也类似,它只是内核根据自己的策略而选择出的一个目的地址,正如MASQUERADE也是内 
核根据RFC的建议以及自己的策略选择出的一个源地址一样。那么如何来选择REDIRECT的目的地址呢?看一下iptables的man手册就知道了: 
REDIRECT 

This target is only valid in the nat table, in the PREROUTING and OUTPUT chains, and user-defined chains which are only called from those 
chains. It redirects the packet to the machine itself by changing the destination IP to the primary address of the incoming interface (locally 
-generated packets are mapped to the 127.0.0.1 address). 
特别要注意的是“to the primary address of the incoming interface”这一句。内核中的REDIRECT规则是如何做到这点的呢?这还要看一下代码才知道: 
  1. static unsigned int  
  2. redirect_tg(struct sk_buff *skb, const struct xt_target_param *par)  
  3. {  
  4.     ...  
  5.     if (par->hooknum == NF_INET_LOCAL_OUT)  
  6.         newdst = htonl(0x7F000001);  
  7.     else {  
  8.         struct in_device *indev;  
  9.         struct in_ifaddr *ifa;  
  10.   
  11.         newdst = 0;  
  12.   
  13.         rcu_read_lock();  
  14.         indev = __in_dev_get_rcu(skb->dev);  
  15.         //取出接收设备的IP地址  
  16.         if (indev && (ifa = indev->ifa_list))  
  17.             newdst = ifa->ifa_local;  
  18.         rcu_read_unlock();  
  19.         //如果接收设备没有IP地址,则丢弃数据包  
  20.         if (!newdst)  
  21.             return NF_DROP;  
  22.     }  
  23.     ...  
  24.     return nf_nat_setup_info(ct, &newrange, IP_NAT_MANIP_DST);  
  25. }  
这下我们就一切都明白了,既然broute表的redirect将接收设备设置为实际的物理网卡,而此网卡的IP地址已经被删除,那么上述函数的newdst当然不存在了,因此数据包就被DROP掉了,到此为止,问题就很清晰了。可见ebtables的redirect方式直接影响到了iptables的redirect,为了让iptables的redirect在使用bridge时仍然随时可行,则必须为使能broute redirect的网卡上设置IP地址,为了不使路由冲突,考虑127.0.0.2... 
注:broute表的意义 
为何会有这样的问题?broute是原因。所谓的broute则是bridge or router,类似早先安装宽带时运营商送的那种猫,能作为桥设备也能作为路由器。如果作为路由器,根本不存在桥设备这一说,因此将接收设备设置为实际的物理网卡也是理所当然的啦。 

ebtables中的broute表介绍

ebtables中的broute表功能: 用于控制进来的数据包是需要进行bridge转发还是进行route转发,及2层转发和3层转发。 BROUTING的ACCEPT/DROP和FORWARD中...
  • zxygww
  • zxygww
  • 2015年08月28日 19:33
  • 2668

ebtables之BROUTING和PREROUTING的redirect的区别

ebtables和iptables实用工具都使用了Netfilter框架,这是它们一致的一方面,然而对于这两者还真有一些需要联动的地方。很多人不明白ebtales的broute表的redirect和n...
  • dog250
  • dog250
  • 2012年02月17日 22:43
  • 11764

ebtables的OUTPUT链DNAT问题

man一下ebtables即可知道,或者随便想一下也会知道,ebtables在OUTPUT链上可以做DNAT,修改目的MAC地址,和iptables一样,到达OUTPUT链的时候已经经过路由表了,只不...
  • dog250
  • dog250
  • 2012年03月03日 21:43
  • 4852

ebtables的使用

http://blog.163.com/dyc_888@126/blog/static/10044335120111255249503/ http://blog.chinaunix.net/uid-...
  • suiyuan19840208
  • suiyuan19840208
  • 2012年12月06日 16:29
  • 9809

ebtables基本使用

ebtables和iptables类似,都是Linux系统下网络数据包过滤的配置工具。既然称之为配置工具,就是说过滤功能是由内核底层提供支持的,这两个工具只是负责制定过滤的rules. ebtabl...
  • wuruixn
  • wuruixn
  • 2012年10月24日 16:51
  • 21988

ebtables之BROUTING和PREROUTING的redirect的区别

http://www.oschina.net/question/234345_47404 ebtables和iptables实用工具都使用了Netfilter框架,这是它们一致的一方面,然而...
  • zxygww
  • zxygww
  • 2015年08月28日 19:28
  • 885

Linux Bridge的IP NAT细节探析-填补又一坑的过程

前序近日温州皮鞋厂老板正在忙着学习Linux Bridge以及诸多虚拟网卡相关的东西,老湿给了一些指导,但最根本的还要靠温州老板自己。就好像有仙灵在聆听心声,我正因为温州老板的缘故一而再再而三地怀念曾...
  • dog250
  • dog250
  • 2017年03月23日 21:40
  • 4786

UDP数据包可靠传输实现方案

本文的主要工作是解决网关B下主机和网关C下主机之间的udp数据包可靠传输问题,采用基于udp的可靠传输协议UDT来实现udp数据包的可靠传输。网关B下的客户端A是发送udp数据包的请求端,网关C下的服...
  • tyy139719
  • tyy139719
  • 2015年09月21日 20:58
  • 1091

ebtables之BROUTING和PREROUTING的redirect的区别

ebtables和iptables实用工具都使用了Netfilter框架,这是它们一致的一方面,然而对于这两者还真有一些需要联动的地方。很多人不明白ebtales的broute表的redirect和n...
  • lee244868149
  • lee244868149
  • 2014年12月31日 10:38
  • 616

ebtables基础示例

原文地址:http://ebtables.sourceforge.net/examples/basic.html#all   Basic filtering configuration: ...
  • zahuopuboss
  • zahuopuboss
  • 2013年03月25日 16:21
  • 1744
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:ebtables之BROUTING和PREROUTING的redirect的区别
举报原因:
原因补充:

(最多只允许输入30个字)