1-Openwrt ipv6之-odhcp6c客户端

wan口的拨号有好几种方式,SLAAC, stateless DHCPv6, stateful DHCPv6, DHCPv6-PD,这些请求方式在odhcpv6里面都可以配置。

1. odhcp6c客户端启动过程


开启openwrt .config配置

CONFIG_PACKAGE_odhcp6c=y
CONFIG_PACKAGE_odhcp6c_ext_prefix_class=0
CONFIG_PACKAGE_odhcp6c_ext_cer_id=0

odhcp6c的启动需要在/etc/config/network uci里面配置允许,类似IPV4的udhcpc

config globals 'globals'
        option ula_prefix 'auto'

config interface 'lan'
        option def_ifname 'eth0'
        option ifname 'eth0'
        option force_link '1'
        option type 'bridge'
        option proto 'static'
        option igmp_snooping '0'
        option ipaddr '192.168.18.1'
        option def_ipaddr '192.168.18.1'
        option res_ipaddr '10.1.2.1'
        option netmask '255.255.255.0'
        option ip6assign '60'
        option macaddr 'DC:4B:DD:1D:FA:48'

config interface 'wan'
        option ipv6 '1'
        option def_ifname 'eth1'
        option ifname 'eth1'
        option proto 'dhcp'
        option web_proto 'dhcp'
        option macaddr 'DC:4B:DD:1d:fa:49'

config interface 'wan6'
        option ifname   'eth1'
        option proto    'dhcpv6'

配置好之后需要重启/etc/init.d/network restart里面会执行ubus call network reload然后就是一系列的ubus传输,最终会调用到/lib/netifd/proto里面对应的脚本,脚本netifd-proto.sh脚本里面会调用_proto_do_setup函数,启动各个协议进程。

/lib/netifd/proto$ ls
dhcp.sh 
1.1 IPV4 CLIENT udhcpc启动

ipv4的启动在./lib/netifd/proto/dhcp.sh脚本里面的proto_dhcp_setup函数

  • dhcp.sh脚本属于netifd-2014-09-08.1模块
  • udhcpc可执行程序属于busybox-1.22.1模块
proto_export "INTERFACE=$config"
    proto_run_command "$config" udhcpc -R \
        -p /var/run/udhcpc-$iface.pid \
        -s /lib/netifd/dhcp.script \
        -f -t 0 -i "$iface" \
        ${ipaddr:+-r $ipaddr} \
        ${hostname:+-H $hostname} \
        ${vendorid:+-V $vendorid} \
        $clientid $broadcast $dhcpopts
1.2 IPV6 CLIENT odhcp6c启动

ipv6的启动在./lib/netifd/proto/dhcpv6.sh脚本里面的proto_dhcpv6_setup函数

  • dhcpv6.sh脚本和odhcp6c都属于odhcp6c-2014-12-10模块
proto_export "INTERFACE=$config"
    proto_run_command "$config" odhcp6c \
        -s /lib/netifd/dhcpv6.script \
        $opts $iface
udhcpc -R -p /var/run/udhcpc-eth1.pid -s /lib/netifd/dhcp.script -f -t 0 -i eth1 -C
odhcp6c -s /lib/netifd/dhcpv6.script -P0 -t120 eth1
1.3 进程查看

odhcp6c启动之后,在netstat下面可以看到udp的546端口,因为DHCPv6的客户端使用546端口,服务器使用的是547端口

root@zihome:/# netstat -naup | grep dhcp
netstat: showing only processes with your user ID
udp        0      0 :::546                  :::*                                1481/odhcp6c
udp        0      0 :::547                  :::*                                1347/odhcpd

2. odhcp6c拨号方式选择


上面提到了wan口的拨号是有很多种的,而且wan口的ifname也是会变化的。

2.1 dhcpv6方式

wan口拨号的uci配置在官网可以查看到
https://openwrt.org/docs/guide-user/network/ipv6/start

Name Type Required Default Description
reqaddress [try,force,none] no try Behaviour for requesting addresses
reqprefix [auto,no,0-64] no auto Behaviour for requesting prefixes (numbers denote hinted prefix length). Use 'no' if you only want a single IPv6 address for the AP itself without a subnet for routing
config globals 'globals'
        option ula_prefix 'auto'

config interface 'lan'
        option proto 'static'
        option ip6assign '60'

config interface 'wan6'
        option ifname   'eth1'
        option proto    'dhcpv6'

所以默认情况,udhcp6c的dhcpv6使用SLAAC + stateful DHCPv6 + DHCPv6-PD的方式进行拨号的。

所以路由器wan口获取到多少个ipv6地址,就看上一级的服务器能提供多少种服务。

如果上级只有dhcpv6服务器,则wan只获取到一个Global 地址,加上自己本地的Link地址,是两个ipv6地址

root@zihome:/# ifconfig eth1
eth1      Link encap:Ethernet  HWaddr 08:10:7B:A7:26:3C  
          inet6 addr: fe80::a10:7bff:fea7:263c/64 Scope:Link
          inet6 addr: 2001:db8:0:1::254/128 Scope:Global
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1510 errors:0 dropped:0 overruns:0 frame:0
          TX packets:3731 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:252070 (246.1 KiB)  TX bytes:501125 (489.3 KiB)

如果上级既有dhcpv6服务器,也有ra服务器,则就会有三个地址,一个本地Link,一个dhcp服务器分配的Global地址,一个ra服务器下发前缀算出来的Global地址。

eth1      Link encap:Ethernet  HWaddr 08:10:7B:A7:26:3C  
          inet6 addr: 2016:ac11:5cad:0:a10:7bff:fea7:263c/64 Scope:Global
          inet6 addr: fe80::a10:7bff:fea7:263c/64 Scope:Link
          inet6 addr: 2001:db8:0:1::254/128 Scope:Global
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:2288 errors:0 dropped:0 overruns:0 frame:0
          TX packets:5709 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:387179 (378.1 KiB)  TX bytes:830273 (810.8 KiB)

支持DHCP-PD功能,所以在发送DHCP Solicit消息里面如果带了IA-Prefix的请求,则服务器就会在IA Prefix字段里面附带自己要在br-lan端口设置的ipv6端口地址前缀,2001:db8:0:f00::1/60,用于下发地址给lan口的设备的地址前缀,然后设置到br-lan的ifconfig里面。

在odhcp6c客户端发送DHCP-PD之后,会在br-lan口设置dhcp服务器的IP前缀,如下2001:db8:0:f00::,这样lan端就可以使用这个前缀地址通过odhcpd服务器下发给下一级ipv6地址了。

root@zihome:/# ifconfig br-lan
br-lan    Link encap:Ethernet  HWaddr 08:10:7B:A7:26:3B  
          inet addr:192.168.18.1  Bcast:192.168.18.255  Mask:255.255.255.0
          inet6 addr: 2001:db8:0:f00::1/60 Scope:Global
          inet6 addr: fe80::a10:7bff:fea7:263b/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:391 errors:0 dropped:0 overruns:0 frame:0
          TX packets:248 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:32339 (31.5 KiB)  TX bytes:74394 (72.6 KiB)
2.2 staticv6方式

ohdcp6c的静态IP方式将uci的值单独抽出来,没有跟上面的在一起,主要有如下参数

Name Type Required Default Description
ip6addr ipv6 address yes, if no ipaddr is set (none)
ip6ifaceid ipv6 suffix no ::1
ip6gw ipv6 address no (none) Assign given IPv6 default gateway to this interface
ip6assign prefix length no (none) Delegate a prefix of given length to this interface (see Downstream configuration below)
ip6hint prefix hint (hex) no (none) Hint the subprefix-ID that should be delegated as hexadecimal number (see Downstream configuration below)
ip6prefix ipv6 prefix no (none) IPv6 prefix routed here for use on other interfaces (Barrier Breaker and later only)
ip6class list of strings no (none) Define the IPv6 prefix-classes this interface will accept
dns list of ip addresses no (none) DNS server(s)
dns_search list of domain names no (none) Search list for host-name lookup
metric integer no 0 Specifies the default route metric to use
# cat /etc/config/network
config interface wan
        option ifname   eth1
        option proto    static
        option ip6addr  2001:db80::2/64   # Own address
        option ip6gw    2001:db80::1      # Gateway address
        option ip6prefix 2001:db80:1::/48 # Prefix addresses for distribution to downstream interfaces
        option dns      2001:db80::1      # DNS server
 
config interface lan
        option proto    static
        option ip6assign 60

上面这种方式就把wan接口配置成静态ipv6了模式了,这样ipv4也得是静态模式,所以一般在wan6里面设置成static,而wan里面ipv4的还是正常的dhcp/static

# cat /etc/config/network
config interface 'wan'
        option ipv6 '1'
        option def_ifname 'eth1'
        option ifname 'eth1'
        option proto 'dhcp'
        option web_proto 'dhcp'
        option macaddr 'DC:4B:DD:1d:fa:49'
        
config interface 'wan6'
        option ifname   eth1
        option proto    static
        option ip6addr  2001:db80::2/64   # Own address
        option ip6gw    2001:db80::1      # Gateway address
        option ip6prefix 2001:db80:1::/48 # Prefix addresses for distribution to downstream interfaces
        option dns      2001:db80::1      # DNS server
 
config interface lan
        option proto    static
        option ip6assign 60

3. 查看ipv6信息


在获取到ipv6地址后,除了使用ifconfig看下信息外,还可以使用ifstatus查看

root@zihome:/tmp/state# ifstatus wan6
{
        "up": true,
        "pending": false,
        "available": true,
        "autostart": true,
        "uptime": 3195,
        "l3_device": "apcli0",
        "proto": "dhcpv6",
        "device": "apcli0",
        "metric": 0,
        "delegation": true,
        "ipv4-address": [

        ],
        "ipv6-address": [
                {
                        "address": "240e:ff:b112:7b52:dc4b:ddff:fe1d:fa08",
                        "mask": 64
                }
        ],
        "ipv6-prefix": [

        ],
        "ipv6-prefix-assignment": [

        ],
        "route": [
                {
                        "target": "240e:ff:b112:7b52::",
                        "mask": 64,
                        "nexthop": "::",
                        "metric": 256,
                        "source": "::\/0"
                },
                {
                        "target": "::",
                        "mask": 0,
                        "nexthop": "fe80::1c6e:5292:2b90:603",
                        "metric": 1024,
                        "valid": 8961,
                        "source": "240e:ff:b112:7b52:dc4b:ddff:fe1d:fa08\/64"
                },
                {
                        "target": "::",
                        "mask": 0,
                        "nexthop": "fe80::1c6e:5292:2b90:603",
                        "metric": 1024,
                        "valid": 8961,
                        "source": "::\/128"
                }
        ],
        "dns-server": [
                "fe80::1c6e:5292:2b90:603"
        ],
        "dns-search": [

        ],
        "inactive": {
                "ipv4-address": [

                ],
                "ipv6-address": [

                ],
                "route": [

                ],
                "dns-server": [

                ],
                "dns-search": [

                ]
        },
        "data": {
                "passthru": "00170010fe800000000000001c6e52922b900603"
        }
}

4. 手机热点的测试


现在的手机热点,一般都可以提供ipv6地址,中继成功后获取到如下ipv6地址,跟手机在同一个网段

手机可以在http://www.test-ipv6.com/上面看到自己的网段

然后路由器设置成无线中继模式,连接手机的热点,wan6的ifname设置成apcli0,dhcpv6模式

config interface 'wan6'
        option ifname   'apcli0'
        option proto    'dhcpv6'

连接成功后,可以看到以下信息,一个本地链路地址和一个全球单播地址。

root@zihome:/tmp/state# ifconfig apcli0
apcli0    Link encap:Ethernet  HWaddr DE:4B:DD:1D:FA:08
          inet addr:172.20.10.13  Bcast:172.20.10.15  Mask:255.255.255.240
          inet6 addr: 240e:ff:b112:7b52:dc4b:ddff:fe1d:fa08/64 Scope:Global
          inet6 addr: fe80::dc4b:ddff:fe1d:fa08/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:33129 errors:0 dropped:0 overruns:0 frame:0
          TX packets:36694 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:16662784 (15.8 MiB)  TX bytes:4734313 (4.5 MiB)

使用手机热点获取到的Global ipv6地址是通过EUI64自己算出来的,所以这个地址应该不是dhcpv6服务器下发的,而是通过RA无状态模式生成的。

另外可以看到路由器的br-lan端口是没有全球单播地址的,路由器发出的IA-PD手机没办法回复,没有提供给下一级设备使用的地址。

这时候可以在lan口设置一个同网段的ipv6地址,这样lan端的设备就可以获取到ipv6地址,不过担心会冲突吧,比较不是正在的dhcpv6/ra服务器下发的

root@zihome:/# ifconfig apcli0
apcli0    Link encap:Ethernet  HWaddr DE:4B:DD:1D:FA:08
          inet addr:172.20.10.13  Bcast:172.20.10.15  Mask:255.255.255.240
          inet6 addr: 240e:ff:b4d5:621d:dc4b:ddff:fe1d:fa08/64 Scope:Global
          inet6 addr: fe80::dc4b:ddff:fe1d:fa08/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:10193 errors:0 dropped:0 overruns:0 frame:0
          TX packets:10338 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:9429739 (8.9 MiB)  TX bytes:3842656 (3.6 MiB)

root@zihome:/# ifconfig br-lan add 240e:ff:b4d5:621d:dc4b:ddff:fe1d:fa08/64
root@zihome:/# ifconfig br-lan
br-lan    Link encap:Ethernet  HWaddr DC:4B:DD:1D:FA:48
          inet addr:192.168.18.1  Bcast:192.168.18.255  Mask:255.255.255.0
          inet6 addr: 240e:ff:b4d5:621d:dc4b:ddff:fe1d:fa08/64 Scope:Global
          inet6 addr: fe80::de4b:ddff:fe1d:fa48/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:2742 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1626 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:526741 (514.3 KiB)  TX bytes:441983 (431.6 KiB)

root@zihome:/#ifconfig br-lan add 240e:ff:b112:7b52::2012/64

你可能感兴趣的:(1-Openwrt ipv6之-odhcp6c客户端)