mzweilin / napt66

Automatically exported from code.google.com/p/napt66
38 stars 12 forks source link

不更改内核代码使用NAPT66功能 #4

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
现在NAPT66模块要求更改内核IPv6转发代码才能使用,所以不能�
��装到现在OpenWrt中。其实有办法不用更改内核使用NAPT66。

当初更改内核IPv6转发代码是因为Linux内核IPv6协议栈限制了节�
��不能同时作为路由器和主机。
这个限制在net.ipv6.conf.all.forwarding参数中体现。下面是转载的�
��料:

=================
forwarding

Type: BOOLEAN
Default: FALSE if global forwarding is disabled (default), otherwise TRUE
設定主機/路由的interface-specific動作.

注意:推薦所有interface(界面)使用相同的設定.混合路由器/主機
的想法真是難得.

Value FALSE: By default, Host behaviour is assumed. This means:
IsRouter 標緻沒有在Neighbour Advertisements當中.
當需要的時候就發送路由請求.
如果accept_ra是TRUE (default), 接受路由廣告.
如果accept_redirects 是 TRUE (default), 接受重定向.
Value TRUE: 
如果具備本地forwarding(轉寄),路由器動作為假定.這和上面的情
況相反:
IsRouter 標緻存在於Neighbour Advertisements當中.
不發送路由請求.
忽略路由廣告.
忽略重定向.
======================

由上可知,当net.ipv6.conf.all.forwarding=1时,系统才可以转发IPv
6数据包。但这样就导致系统所有网络接口,包括WAN在内,无�
��获得IPv6地址配置信息,当然就不能给内网主机提供IPv6服务�
��。

在早前的方案中,我们更改内核的ipv6转发函数,使net.ipv6.conf
.all.forwarding=0时也转发包,这样就可以用内核自身的功能来�
��动配置WAN口IPv6信息。

如果有一个第三方的软件来自动配置WAN口IPv6信息,就可以不�
��内核限制了。即,令net.ipv6.conf.all.forwarding=1,开通IPv6转发
,然后通过第三方软件来配置WAN口IPv6信息。

因为Linux内核已经实现了无状态地址自动配置的功能,目前没
有现成的第三方软件满足我们的要求。但可以通过shell脚本调
用现成的ndisc6来实现。

ndisc6中包含了rdisc6程序,它可以向网络中发送RS报文,触发路
由器回复RA报文,并解析到shell中。比如:

# rdisc6 wlan1

Soliciting ff02::2 (ff02::2) on wlan1...

Hop limit                 :           64 (      0x40)
Stateful address conf.    :           No
Stateful other conf.      :           No
Router preference         :       medium
Router lifetime           :         1800 (0x00000708) seconds
Reachable time            :  unspecified (0x00000000)
Retransmit time           :  unspecified (0x00000000)
 Source link-layer address: 00:18:B9:2C:C2:C4
 MTU                      :         1500 bytes (valid)
 Prefix                   : 2001:da8:215:3320::/64
  Valid time              :      2592000 (0x00278d00) seconds
  Pref. time              :       604800 (0x00093a80) seconds
 from fe80::218:b9ff:fe2c:c2c4

显然,通过字符串处理工具配合ifconfig,ip等工具,就可以把I
Pv6信息配置到网络接口了。

配置WAN口IPv6参数涉及的操作有:
1) 添加接口IPv6地址。
按RFC规定,将MAC地址转为EUI-64格式,与接收到的子网前缀连��
�,生成无状态ipv6地址,用ifconfig命令配置到wan接口。
2) 添加默认路由。
默认路由涉及到路由器本地链路地址和wan接口名称,在上面��
�例子中,路由器本地链路地址是fe80::218:b9ff:fe2c:c2c4,wan接口�
��wlan1,所以用
ip -6 route add default via fe80::218:b9ff:fe2c:c2c4 dev wlan1
就可以了。

当然,完整的功能还应包括检测接口状态等。有兴趣的童鞋��
�以试一试。

Original issue reported on code.google.com by Mzwei...@gmail.com on 18 Mar 2011 at 10:20

GoogleCodeExporter commented 9 years ago
这个方案把无状态地址分配做成有状态的了,有点danteng,不�
��确实能解决问题,有助于NAPT66的推广。
今天下午看了shell编程的资料,现学现用,写了个脚本。希望
高手能帮忙改进一下它。

#!/bin/sh
link_addr=$(ifconfig $1 | grep 'Scope:Link$' | awk '{ print $3}')
rdisc6 -i $1 > /tmp/router_ad.tmp

prefix=$(cat /tmp/router_ad.tmp | grep '^ Prefix*' | awk -F ": " '{ print $2 }' 
| awk -F "/" '{ print $1 }')
ip6_addr=${prefix%*:}${link_addr##*::}
ip -6 addr add ${ip6_addr} dev $1

ip6_gw=$(cat /tmp/router_ad.tmp | grep '^ from' | awk '{ print $2 }')
ip -6 route add default via ${ip6_gw} dev $1

Original comment by Mzwei...@gmail.com on 20 Mar 2011 at 9:07

GoogleCodeExporter commented 9 years ago
以上脚本还存在一些问题:
1 未处理RA有效期属性;
2 未处理某些非标准的子网前缀。

不过应该适用于大部分情形了,希望高手能帮忙改进它。

Original comment by Mzwei...@gmail.com on 20 Mar 2011 at 9:10

GoogleCodeExporter commented 9 years ago
修正一下脚本中的参数错误。
rdisc6是不用 -i 参数的,正确的用法是rdisc6 <interface>。
修正后的saac.sh如下,用法仍为./saac <interface>。
#!/bin/sh
link_addr=$(ifconfig $1 | grep 'Scope:Link$' | awk '{ print $3}')
rdisc6 $1 > /tmp/router_ad.tmp

prefix=$(cat /tmp/router_ad.tmp | grep '^ Prefix*' | awk -F ": " '{ print $2 }' 
| awk -F "/" '{ print $1 }')
ip6_addr=${prefix%*:}${link_addr##*::}
ip -6 addr add ${ip6_addr} dev $1

ip6_gw=$(cat /tmp/router_ad.tmp | grep '^ from' | awk '{ print $2 }')
ip -6 route add default via ${ip6_gw} dev $1

Original comment by Mzwei...@gmail.com on 28 Mar 2011 at 1:38

GoogleCodeExporter commented 9 years ago
嫌以前的脚本太慢,再修改了一次,让rdisc6收到一个ra报文后
就返回。我保存在/usr/sbin/slaac中当系统命令了。

#!/bin/sh
link_addr=$(ifconfig $1 | grep 'Scope:Link$' | awk '{ print $3}')
rdisc6 $1 -1 > /tmp/router_ad.tmp
cat /tmp/router_ad.tmp
prefix=$(cat /tmp/router_ad.tmp | grep '^ Prefix*' | awk -F ": " '{ print $2 }' 
| awk -F "/" '{ print $1 }')
ip6_addr=${prefix%*:}${link_addr##*::}
ip -6 addr add ${ip6_addr} dev $1

ip6_gw=$(cat /tmp/router_ad.tmp | grep '^ from' | awk '{ print $2 }')
ip -6 route add default via ${ip6_gw} dev $1

Original comment by Mzwei...@gmail.com on 19 Apr 2011 at 3:39

GoogleCodeExporter commented 9 years ago
你好,不走内核的话,速度会不会变慢?

Original comment by q741...@gmail.com on 25 May 2011 at 11:40

GoogleCodeExporter commented 9 years ago
> 你好,不走内核的话,速度会不会变慢?

This issue is just about the network autoconfiguration. Packet forwarding is 
achieved by kernel anyhow.

Original comment by Mzwei...@gmail.com on 25 May 2011 at 11:54

GoogleCodeExporter commented 9 years ago

Original comment by Mzwei...@gmail.com on 28 May 2011 at 1:52