diff options
author | ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp> | 2016-06-01 04:59:11 +0000 |
---|---|---|
committer | ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp> | 2016-06-01 05:06:37 +0000 |
commit | addc3902e85959e525a6e577de174dc1229551ac (patch) | |
tree | 6e906d49bec9056a68739ea86b65f44d6613faf6 | |
parent | 4c9cd88c61cb848e36a45657b7cbc63b9c783dc4 (diff) |
server: support peering with ipv6 link local address
fix DialTCPTimeoutWithMD5Sig to handle ipv6 scope-id
also update ipv6 test to test this feature
Signed-off-by: ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>
-rw-r--r-- | server/server.go | 4 | ||||
-rw-r--r-- | server/sockopt_linux.go | 34 | ||||
-rw-r--r-- | test/lib/base.py | 16 | ||||
-rw-r--r-- | test/lib/gobgp.py | 7 | ||||
-rw-r--r-- | test/scenario_test/route_server_ipv4_v6_test.py | 8 |
5 files changed, 46 insertions, 23 deletions
diff --git a/server/server.go b/server/server.go index 73ac5ad1..b9c6351d 100644 --- a/server/server.go +++ b/server/server.go @@ -260,7 +260,9 @@ func (server *BgpServer) Serve() { } passConn := func(conn *net.TCPConn) { - remoteAddr, _, _ := net.SplitHostPort(conn.RemoteAddr().String()) + host, _, _ := net.SplitHostPort(conn.RemoteAddr().String()) + ipaddr, _ := net.ResolveIPAddr("ip", host) + remoteAddr := ipaddr.IP.String() peer, found := server.neighborMap[remoteAddr] if found { if peer.fsm.adminState != ADMIN_STATE_UP { diff --git a/server/sockopt_linux.go b/server/sockopt_linux.go index c764eb04..d1b08ace 100644 --- a/server/sockopt_linux.go +++ b/server/sockopt_linux.go @@ -28,30 +28,30 @@ func DialTCPTimeoutWithMD5Sig(host string, port int, localAddr, key string, msec var family int var ra, la syscall.Sockaddr - ip := net.ParseIP(host) - if ip == nil { - return nil, fmt.Errorf("invalid ip: %s", host) + ip, err := net.ResolveIPAddr("ip", host) + if err != nil { + return nil, fmt.Errorf("invalid ip: %s", err) } - l := net.ParseIP(localAddr) + l, err := net.ResolveIPAddr("ip", localAddr) if l == nil { - return nil, fmt.Errorf("invalid local ip: %s", localAddr) + return nil, fmt.Errorf("invalid local ip: %s", err) } - if (ip.To4() != nil) != (l.To4() != nil) { + if (ip.IP.To4() != nil) != (l.IP.To4() != nil) { return nil, fmt.Errorf("remote and local ip address family is not same") } switch { - case ip.To4() != nil: + case ip.IP.To4() != nil: family = syscall.AF_INET i := &syscall.SockaddrInet4{ Port: port, } for idx, _ := range i.Addr { - i.Addr[idx] = ip.To4()[idx] + i.Addr[idx] = ip.IP.To4()[idx] } ra = i j := &syscall.SockaddrInet4{} for idx, _ := range j.Addr { - j.Addr[idx] = l.To4()[idx] + j.Addr[idx] = l.IP.To4()[idx] } la = j default: @@ -60,12 +60,22 @@ func DialTCPTimeoutWithMD5Sig(host string, port int, localAddr, key string, msec Port: port, } for idx, _ := range i.Addr { - i.Addr[idx] = ip[idx] + i.Addr[idx] = ip.IP[idx] } ra = i - j := &syscall.SockaddrInet6{} + var zone uint32 + if l.Zone != "" { + intf, err := net.InterfaceByName(l.Zone) + if err != nil { + return nil, err + } + zone = uint32(intf.Index) + } + j := &syscall.SockaddrInet6{ + ZoneId: zone, + } for idx, _ := range j.Addr { - j.Addr[idx] = l[idx] + j.Addr[idx] = l.IP[idx] } la = j } diff --git a/test/lib/base.py b/test/lib/base.py index ffbf03b5..4f2e8a69 100644 --- a/test/lib/base.py +++ b/test/lib/base.py @@ -155,6 +155,7 @@ class Container(object): self.image = image self.shared_volumes = [] self.ip_addrs = [] + self.ip6_addrs = [] self.is_running = False self.eths = [] @@ -184,6 +185,9 @@ class Container(object): if line.strip().startswith("inet "): elems = [e.strip() for e in line.strip().split(' ')] self.ip_addrs.append(('eth0', elems[1], 'docker0')) + elif line.strip().startswith("inet6 "): + elems = [e.strip() for e in line.strip().split(' ')] + self.ip6_addrs.append(('eth0', elems[1], 'docker0')) return 0 def stop(self): @@ -262,15 +266,23 @@ class BGPContainer(Container): policies=None, passive=False, is_rr_client=False, cluster_id=None, flowspec=False, bridge='', reload_config=True, as2=False, - graceful_restart=None, local_as=None, prefix_limit=None): + graceful_restart=None, local_as=None, prefix_limit=None, + v6=False): neigh_addr = '' local_addr = '' - for me, you in itertools.product(self.ip_addrs, peer.ip_addrs): + it = itertools.product(self.ip_addrs, peer.ip_addrs) + if v6: + it = itertools.product(self.ip6_addrs, peer.ip6_addrs) + + for me, you in it: if bridge != '' and bridge != me[2]: continue if me[2] == you[2]: neigh_addr = you[1] local_addr = me[1] + if v6: + addr, mask = local_addr.split('/') + local_addr = "{0}%{1}/{2}".format(addr, me[0], mask) break if neigh_addr == '': diff --git a/test/lib/gobgp.py b/test/lib/gobgp.py index 7627fd50..0f86f388 100644 --- a/test/lib/gobgp.py +++ b/test/lib/gobgp.py @@ -267,11 +267,14 @@ class GoBGPContainer(BGPContainer): 'afi-safis': afi_safi_list, 'timers': {'config': { 'connect-retry': 10, - }}, + }}, + 'transport': {'config': { + 'local-address': info['local_addr'].split('/')[0], + }}, } if info['passive']: - n['transport'] = {'config': {'passive-mode': True}} + n['transport']['config']['passive-mode'] = True if info['is_rs_client']: n['route-server'] = {'config': {'route-server-client': True}} diff --git a/test/scenario_test/route_server_ipv4_v6_test.py b/test/scenario_test/route_server_ipv4_v6_test.py index c32bfecf..c79939fd 100644 --- a/test/scenario_test/route_server_ipv4_v6_test.py +++ b/test/scenario_test/route_server_ipv4_v6_test.py @@ -63,16 +63,12 @@ class GoBGPIPv6Test(unittest.TestCase): g1.add_peer(ctn, is_rs_client=True) ctn.add_peer(g1) - br02 = Bridge(name='br02', subnet='2001::/96') - br02.addif(g1) for ctn in v6: - br02.addif(ctn) - g1.add_peer(ctn, is_rs_client=True, bridge=br02.name) - ctn.add_peer(g1, bridge=br02.name) + g1.add_peer(ctn, is_rs_client=True, v6=True) + ctn.add_peer(g1, v6=True) cls.gobgp = g1 cls.quaggas = {'q1': q1, 'q2': q2, 'q3': q3, 'q4': q4} - cls.bridges = {'br02': br02} cls.ipv4s = {'q1': q1, 'q2': q2} cls.ipv6s = {'q3': q3, 'q4': q4} |