summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>2016-06-01 04:59:11 +0000
committerISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>2016-06-01 05:06:37 +0000
commitaddc3902e85959e525a6e577de174dc1229551ac (patch)
tree6e906d49bec9056a68739ea86b65f44d6613faf6
parent4c9cd88c61cb848e36a45657b7cbc63b9c783dc4 (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.go4
-rw-r--r--server/sockopt_linux.go34
-rw-r--r--test/lib/base.py16
-rw-r--r--test/lib/gobgp.py7
-rw-r--r--test/scenario_test/route_server_ipv4_v6_test.py8
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}