]> Cypherpunks repositories - gostls13.git/commitdiff
net: set up IPv6 scoped addressing zone for network facilities
authorMikio Hara <mikioh.mikioh@gmail.com>
Tue, 19 Feb 2013 23:18:04 +0000 (08:18 +0900)
committerMikio Hara <mikioh.mikioh@gmail.com>
Tue, 19 Feb 2013 23:18:04 +0000 (08:18 +0900)
This CL changes nothing to existing API behavior, just sets up
Zone in IPNet and IPAddr structures if possible.

Also does small simplification.

Update #4234.

R=rsc, dave
CC=golang-dev
https://golang.org/cl/7300081

src/pkg/net/interface_bsd.go
src/pkg/net/interface_darwin.go
src/pkg/net/interface_freebsd.go
src/pkg/net/interface_linux.go
src/pkg/net/interface_netbsd.go
src/pkg/net/interface_openbsd.go
src/pkg/net/interface_windows.go

index df9b3a2f279a4759e07f61c51a741c6019462b67..9e74845762c9e00d06ca3fca006306c29e27b091 100644 (file)
@@ -22,18 +22,16 @@ func interfaceTable(ifindex int) ([]Interface, error) {
        if err != nil {
                return nil, os.NewSyscallError("route rib", err)
        }
-
        msgs, err := syscall.ParseRoutingMessage(tab)
        if err != nil {
                return nil, os.NewSyscallError("route message", err)
        }
-
        var ift []Interface
        for _, m := range msgs {
-               switch v := m.(type) {
+               switch m := m.(type) {
                case *syscall.InterfaceMessage:
-                       if ifindex == 0 || ifindex == int(v.Header.Index) {
-                               ifi, err := newLink(v)
+                       if ifindex == 0 || ifindex == int(m.Header.Index) {
+                               ifi, err := newLink(m)
                                if err != nil {
                                        return nil, err
                                }
@@ -49,26 +47,25 @@ func newLink(m *syscall.InterfaceMessage) ([]Interface, error) {
        if err != nil {
                return nil, os.NewSyscallError("route sockaddr", err)
        }
-
        var ift []Interface
-       for _, s := range sas {
-               switch v := s.(type) {
+       for _, sa := range sas {
+               switch sa := sa.(type) {
                case *syscall.SockaddrDatalink:
                        // NOTE: SockaddrDatalink.Data is minimum work area,
                        // can be larger.
-                       m.Data = m.Data[unsafe.Offsetof(v.Data):]
+                       m.Data = m.Data[unsafe.Offsetof(sa.Data):]
                        ifi := Interface{Index: int(m.Header.Index), Flags: linkFlags(m.Header.Flags)}
                        var name [syscall.IFNAMSIZ]byte
-                       for i := 0; i < int(v.Nlen); i++ {
+                       for i := 0; i < int(sa.Nlen); i++ {
                                name[i] = byte(m.Data[i])
                        }
-                       ifi.Name = string(name[:v.Nlen])
+                       ifi.Name = string(name[:sa.Nlen])
                        ifi.MTU = int(m.Header.Data.Mtu)
-                       addr := make([]byte, v.Alen)
-                       for i := 0; i < int(v.Alen); i++ {
-                               addr[i] = byte(m.Data[int(v.Nlen)+i])
+                       addr := make([]byte, sa.Alen)
+                       for i := 0; i < int(sa.Alen); i++ {
+                               addr[i] = byte(m.Data[int(sa.Nlen)+i])
                        }
-                       ifi.HardwareAddr = addr[:v.Alen]
+                       ifi.HardwareAddr = addr[:sa.Alen]
                        ift = append(ift, ifi)
                }
        }
@@ -103,18 +100,16 @@ func interfaceAddrTable(ifindex int) ([]Addr, error) {
        if err != nil {
                return nil, os.NewSyscallError("route rib", err)
        }
-
        msgs, err := syscall.ParseRoutingMessage(tab)
        if err != nil {
                return nil, os.NewSyscallError("route message", err)
        }
-
        var ifat []Addr
        for _, m := range msgs {
-               switch v := m.(type) {
+               switch m := m.(type) {
                case *syscall.InterfaceAddrMessage:
-                       if ifindex == 0 || ifindex == int(v.Header.Index) {
-                               ifa, err := newAddr(v)
+                       if ifindex == 0 || ifindex == int(m.Header.Index) {
+                               ifa, err := newAddr(m)
                                if err != nil {
                                        return nil, err
                                }
@@ -132,30 +127,29 @@ func newAddr(m *syscall.InterfaceAddrMessage) (Addr, error) {
        if err != nil {
                return nil, os.NewSyscallError("route sockaddr", err)
        }
-
        ifa := &IPNet{}
-       for i, s := range sas {
-               switch v := s.(type) {
+       for i, sa := range sas {
+               switch sa := sa.(type) {
                case *syscall.SockaddrInet4:
                        switch i {
                        case 0:
-                               ifa.Mask = IPv4Mask(v.Addr[0], v.Addr[1], v.Addr[2], v.Addr[3])
+                               ifa.Mask = IPv4Mask(sa.Addr[0], sa.Addr[1], sa.Addr[2], sa.Addr[3])
                        case 1:
-                               ifa.IP = IPv4(v.Addr[0], v.Addr[1], v.Addr[2], v.Addr[3])
+                               ifa.IP = IPv4(sa.Addr[0], sa.Addr[1], sa.Addr[2], sa.Addr[3])
                        }
                case *syscall.SockaddrInet6:
                        switch i {
                        case 0:
                                ifa.Mask = make(IPMask, IPv6len)
-                               copy(ifa.Mask, v.Addr[:])
+                               copy(ifa.Mask, sa.Addr[:])
                        case 1:
                                ifa.IP = make(IP, IPv6len)
-                               copy(ifa.IP, v.Addr[:])
+                               copy(ifa.IP, sa.Addr[:])
                                // NOTE: KAME based IPv6 protcol stack usually embeds
                                // the interface index in the interface-local or link-
                                // local address as the kernel-internal form.
                                if ifa.IP.IsLinkLocalUnicast() {
-                                       // remove embedded scope zone ID
+                                       ifa.Zone = zoneToString(int(ifa.IP[2]<<8 | ifa.IP[3]))
                                        ifa.IP[2], ifa.IP[3] = 0, 0
                                }
                        }
index 0b5fb5fb9da11b7b3abfaa659b9f5a3ec0de70de..edf4d74dfaf29de760b72355171b3961512ec28a 100644 (file)
@@ -19,18 +19,16 @@ func interfaceMulticastAddrTable(ifindex int) ([]Addr, error) {
        if err != nil {
                return nil, os.NewSyscallError("route rib", err)
        }
-
        msgs, err := syscall.ParseRoutingMessage(tab)
        if err != nil {
                return nil, os.NewSyscallError("route message", err)
        }
-
        var ifmat []Addr
        for _, m := range msgs {
-               switch v := m.(type) {
+               switch m := m.(type) {
                case *syscall.InterfaceMulticastAddrMessage:
-                       if ifindex == 0 || ifindex == int(v.Header.Index) {
-                               ifma, err := newMulticastAddr(v)
+                       if ifindex == 0 || ifindex == int(m.Header.Index) {
+                               ifma, err := newMulticastAddr(m)
                                if err != nil {
                                        return nil, err
                                }
@@ -46,22 +44,20 @@ func newMulticastAddr(m *syscall.InterfaceMulticastAddrMessage) ([]Addr, error)
        if err != nil {
                return nil, os.NewSyscallError("route sockaddr", err)
        }
-
        var ifmat []Addr
-       for _, s := range sas {
-               switch v := s.(type) {
+       for _, sa := range sas {
+               switch sa := sa.(type) {
                case *syscall.SockaddrInet4:
-                       ifma := &IPAddr{IP: IPv4(v.Addr[0], v.Addr[1], v.Addr[2], v.Addr[3])}
+                       ifma := &IPAddr{IP: IPv4(sa.Addr[0], sa.Addr[1], sa.Addr[2], sa.Addr[3])}
                        ifmat = append(ifmat, ifma.toAddr())
                case *syscall.SockaddrInet6:
                        ifma := &IPAddr{IP: make(IP, IPv6len)}
-                       copy(ifma.IP, v.Addr[:])
+                       copy(ifma.IP, sa.Addr[:])
                        // NOTE: KAME based IPv6 protcol stack usually embeds
                        // the interface index in the interface-local or link-
                        // local address as the kernel-internal form.
-                       if ifma.IP.IsInterfaceLocalMulticast() ||
-                               ifma.IP.IsLinkLocalMulticast() {
-                               // remove embedded scope zone ID
+                       if ifma.IP.IsInterfaceLocalMulticast() || ifma.IP.IsLinkLocalMulticast() {
+                               ifma.Zone = zoneToString(int(ifma.IP[2]<<8 | ifma.IP[3]))
                                ifma.IP[2], ifma.IP[3] = 0, 0
                        }
                        ifmat = append(ifmat, ifma.toAddr())
index 3cba28fc6961d896d5cac4b2d1aa19c553c7ab0b..af3be4d3c2892f22d77ac6f5d11daec399180fe4 100644 (file)
@@ -19,18 +19,16 @@ func interfaceMulticastAddrTable(ifindex int) ([]Addr, error) {
        if err != nil {
                return nil, os.NewSyscallError("route rib", err)
        }
-
        msgs, err := syscall.ParseRoutingMessage(tab)
        if err != nil {
                return nil, os.NewSyscallError("route message", err)
        }
-
        var ifmat []Addr
        for _, m := range msgs {
-               switch v := m.(type) {
+               switch m := m.(type) {
                case *syscall.InterfaceMulticastAddrMessage:
-                       if ifindex == 0 || ifindex == int(v.Header.Index) {
-                               ifma, err := newMulticastAddr(v)
+                       if ifindex == 0 || ifindex == int(m.Header.Index) {
+                               ifma, err := newMulticastAddr(m)
                                if err != nil {
                                        return nil, err
                                }
@@ -46,22 +44,20 @@ func newMulticastAddr(m *syscall.InterfaceMulticastAddrMessage) ([]Addr, error)
        if err != nil {
                return nil, os.NewSyscallError("route sockaddr", err)
        }
-
        var ifmat []Addr
-       for _, s := range sas {
-               switch v := s.(type) {
+       for _, sa := range sas {
+               switch sa := sa.(type) {
                case *syscall.SockaddrInet4:
-                       ifma := &IPAddr{IP: IPv4(v.Addr[0], v.Addr[1], v.Addr[2], v.Addr[3])}
+                       ifma := &IPAddr{IP: IPv4(sa.Addr[0], sa.Addr[1], sa.Addr[2], sa.Addr[3])}
                        ifmat = append(ifmat, ifma.toAddr())
                case *syscall.SockaddrInet6:
                        ifma := &IPAddr{IP: make(IP, IPv6len)}
-                       copy(ifma.IP, v.Addr[:])
+                       copy(ifma.IP, sa.Addr[:])
                        // NOTE: KAME based IPv6 protcol stack usually embeds
                        // the interface index in the interface-local or link-
                        // local address as the kernel-internal form.
-                       if ifma.IP.IsInterfaceLocalMulticast() ||
-                               ifma.IP.IsLinkLocalMulticast() {
-                               // remove embedded scope zone ID
+                       if ifma.IP.IsInterfaceLocalMulticast() || ifma.IP.IsLinkLocalMulticast() {
+                               ifma.Zone = zoneToString(int(ifma.IP[2]<<8 | ifma.IP[3]))
                                ifma.IP[2], ifma.IP[3] = 0, 0
                        }
                        ifmat = append(ifmat, ifma.toAddr())
index 13a788a003e4048e70e99eb755deacd626f05eb9..5c7590b3c2a94b810a0514e415284fc59e63ddb7 100644 (file)
@@ -20,17 +20,16 @@ func interfaceTable(ifindex int) ([]Interface, error) {
        if err != nil {
                return nil, os.NewSyscallError("netlink rib", err)
        }
-
        msgs, err := syscall.ParseNetlinkMessage(tab)
        if err != nil {
                return nil, os.NewSyscallError("netlink message", err)
        }
-
        var ift []Interface
+loop:
        for _, m := range msgs {
                switch m.Header.Type {
                case syscall.NLMSG_DONE:
-                       goto done
+                       break loop
                case syscall.RTM_NEWLINK:
                        ifim := (*syscall.IfInfomsg)(unsafe.Pointer(&m.Data[0]))
                        if ifindex == 0 || ifindex == int(ifim.Index) {
@@ -43,7 +42,6 @@ func interfaceTable(ifindex int) ([]Interface, error) {
                        }
                }
        }
-done:
        return ift, nil
 }
 
@@ -98,12 +96,10 @@ func interfaceAddrTable(ifindex int) ([]Addr, error) {
        if err != nil {
                return nil, os.NewSyscallError("netlink rib", err)
        }
-
        msgs, err := syscall.ParseNetlinkMessage(tab)
        if err != nil {
                return nil, os.NewSyscallError("netlink message", err)
        }
-
        ifat, err := addrTable(msgs, ifindex)
        if err != nil {
                return nil, err
@@ -113,10 +109,11 @@ func interfaceAddrTable(ifindex int) ([]Addr, error) {
 
 func addrTable(msgs []syscall.NetlinkMessage, ifindex int) ([]Addr, error) {
        var ifat []Addr
+loop:
        for _, m := range msgs {
                switch m.Header.Type {
                case syscall.NLMSG_DONE:
-                       goto done
+                       break loop
                case syscall.RTM_NEWADDR:
                        ifam := (*syscall.IfAddrmsg)(unsafe.Pointer(&m.Data[0]))
                        ifi, err := InterfaceByIndex(int(ifam.Index))
@@ -132,7 +129,6 @@ func addrTable(msgs []syscall.NetlinkMessage, ifindex int) ([]Addr, error) {
                        }
                }
        }
-done:
        return ifat, nil
 }
 
@@ -149,6 +145,9 @@ func newAddr(attrs []syscall.NetlinkRouteAttr, ifi *Interface, ifam *syscall.IfA
                                ifa.IP = make(IP, IPv6len)
                                copy(ifa.IP, a.Value[:])
                                ifa.Mask = CIDRMask(int(ifam.Prefixlen), 8*IPv6len)
+                               if ifam.Scope == syscall.RT_SCOPE_HOST || ifam.Scope == syscall.RT_SCOPE_LINK {
+                                       ifa.Zone = zoneToString(int(ifam.Index))
+                               }
                        }
                }
        }
@@ -180,7 +179,6 @@ func parseProcNetIGMP(path string, ifi *Interface) []Addr {
                return nil
        }
        defer fd.close()
-
        var (
                ifmat []Addr
                name  string
@@ -218,7 +216,6 @@ func parseProcNetIGMP6(path string, ifi *Interface) []Addr {
                return nil
        }
        defer fd.close()
-
        var ifmat []Addr
        b := make([]byte, IPv6len)
        for l, ok := fd.readLine(); ok; l, ok = fd.readLine() {
@@ -231,6 +228,9 @@ func parseProcNetIGMP6(path string, ifi *Interface) []Addr {
                                b[i/2], _ = xtoi2(f[2][i:i+2], 0)
                        }
                        ifma := IPAddr{IP: IP{b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], b[8], b[9], b[10], b[11], b[12], b[13], b[14], b[15]}}
+                       if ifma.IP.IsInterfaceLocalMulticast() || ifma.IP.IsLinkLocalMulticast() {
+                               ifma.Zone = ifi.Name
+                       }
                        ifmat = append(ifmat, ifma.toAddr())
                }
        }
index 4150e9ad5d15dd4c37bfb837bfb3d81595341503..691d311d8d460c076bd4261313d669f3a2d9bd25 100644 (file)
@@ -10,5 +10,6 @@ package net
 // addresses for all network interfaces.  Otherwise it returns
 // addresses for a specific interface.
 func interfaceMulticastAddrTable(ifindex int) ([]Addr, error) {
+       // TODO(mikio): Implement this like other platforms.
        return nil, nil
 }
index d8adb4676531d8db6763b58890aa553721c09236..3188871031bd8ad46a4f180fc52a4626c722661d 100644 (file)
@@ -10,5 +10,6 @@ package net
 // addresses for all network interfaces.  Otherwise it returns
 // addresses for a specific interface.
 func interfaceMulticastAddrTable(ifindex int) ([]Addr, error) {
+       // TODO(mikio): Implement this like other platforms.
        return nil, nil
 }
index c7a3eac2a74c98830ccc935fce171a14423d6150..aa57fab695822e8f90682a8223da34ce8213bd76 100644 (file)
@@ -25,6 +25,9 @@ func getAdapterList() (*syscall.IpAdapterInfo, error) {
        b := make([]byte, 1000)
        l := uint32(len(b))
        a := (*syscall.IpAdapterInfo)(unsafe.Pointer(&b[0]))
+       // TODO(mikio): GetAdaptersInfo returns IP_ADAPTER_INFO that
+       // contains IPv4 address list only. We should use another API
+       // for fetching IPv6 stuff from the kernel.
        err := syscall.GetAdaptersInfo(a, &l)
        if err == syscall.ERROR_BUFFER_OVERFLOW {
                b = make([]byte, l)
@@ -154,5 +157,6 @@ func interfaceAddrTable(ifindex int) ([]Addr, error) {
 // addresses for all network interfaces.  Otherwise it returns
 // addresses for a specific interface.
 func interfaceMulticastAddrTable(ifindex int) ([]Addr, error) {
+       // TODO(mikio): Implement this like other platforms.
        return nil, nil
 }