Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[quagga]: update quagga submodule #1698

Merged
merged 2 commits into from
May 11, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion platform/vs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ sw-srv0 (id: 5)
2. Start sonic virtual switch docker

```
$ docker run --privileged --network container:sw -d docker-sonic-vs
$ docker run --privileged --network container:sw --name vs -d docker-sonic-vs
```

3. Setup IP in the virtual switch docker
Expand Down
4 changes: 4 additions & 0 deletions platform/vs/tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Requirements:

- Enable IPv6 for docker engine
- pip install exabgp
7 changes: 7 additions & 0 deletions platform/vs/tests/bgp/files/bgpd.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
router bgp 65501
bgp router-id 1.1.1.1
no bgp default ipv4-unicast
neighbor fc00::2 remote-as 65502
address-family ipv6
neighbor fc00::2 activate
exit-address-family
19 changes: 19 additions & 0 deletions platform/vs/tests/bgp/files/invalid_nexthop.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
neighbor fc00::1 {
router-id 1.2.3.4;
local-address fc00::2;
local-as 65502;
peer-as 65501;
group-updates false;

family {
ipv4 unicast;
ipv6 unicast;
}

static {
route 3333::0/64 {
next-hop 0.0.0.0;
next-hop fc00::2;
}
}
}
32 changes: 32 additions & 0 deletions platform/vs/tests/bgp/test_invalid_nexthop.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from swsscommon import swsscommon
import os
import re
import time
import json

def test_InvalidNexthop(dvs):

dvs.copy_file("/etc/quagga/", "bgp/files/bgpd.conf")
dvs.runcmd("supervisorctl start bgpd")
dvs.runcmd("ip addr add fc00::1/126 dev Ethernet0")
dvs.runcmd("ifconfig Ethernet0 up")

dvs.servers[0].runcmd("ip addr add fc00::2/126 dev eth0")
dvs.servers[0].runcmd("ifconfig eth0 up")

time.sleep(5)

print dvs.runcmd("supervisorctl status")

p = dvs.servers[0].runcmd_async("exabgp -d bgp/files/invalid_nexthop.conf")

time.sleep(10)

output = dvs.runcmd(["vtysh", "-c", "show ipv6 bgp"])

p.terminate()
p = p.wait()

print output

assert "3333::/64" in output
231 changes: 231 additions & 0 deletions platform/vs/tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,231 @@
import os
import os.path
import re
import time
import docker
import pytest
import commands
import tarfile
import StringIO
import subprocess
from swsscommon import swsscommon

def pytest_addoption(parser):
parser.addoption("--dvsname", action="store", default=None,
help="dvs name")

class AsicDbValidator(object):
def __init__(self, dvs):
self.adb = swsscommon.DBConnector(1, dvs.redis_sock, 0)

# get default dot1q vlan id
atbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_VLAN")

keys = atbl.getKeys()
assert len(keys) == 1
self.default_vlan_id = keys[0]

# build port oid to front port name mapping
self.portoidmap = {}
self.portnamemap = {}
self.hostifoidmap = {}
self.hostifnamemap = {}
atbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_HOSTIF")
keys = atbl.getKeys()

assert len(keys) == 32
for k in keys:
(status, fvs) = atbl.get(k)

assert status == True

for fv in fvs:
if fv[0] == "SAI_HOSTIF_ATTR_OBJ_ID":
port_oid = fv[1]
elif fv[0] == "SAI_HOSTIF_ATTR_NAME":
port_name = fv[1]

self.portoidmap[port_oid] = port_name
self.portnamemap[port_name] = port_oid
self.hostifoidmap[k] = port_name
self.hostifnamemap[port_name] = k

# get default acl table and acl rules
atbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ACL_TABLE")
keys = atbl.getKeys()

assert len(keys) == 1
self.default_acl_table = keys[0]

atbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ACL_ENTRY")
keys = atbl.getKeys()

assert len(keys) == 2
self.default_acl_entries = keys

class VirtualServer(object):
def __init__(self, ctn_name, pid, i):
self.nsname = "%s-srv%d" % (ctn_name, i)
self.vifname = "vEthernet%d" % (i * 4)
self.cleanup = True

# create netns
if os.path.exists("/var/run/netns/%s" % self.nsname):
self.cleanup = False
else:
os.system("ip netns add %s" % self.nsname)

# create vpeer link
os.system("ip link add %s type veth peer name %s" % (self.nsname[0:12], self.vifname))
os.system("ip link set %s netns %s" % (self.nsname[0:12], self.nsname))
os.system("ip link set %s netns %d" % (self.vifname, pid))

# bring up link in the virtual server
os.system("ip netns exec %s ip link set dev %s name eth0" % (self.nsname, self.nsname[0:12]))
os.system("ip netns exec %s ip link set dev eth0 up" % (self.nsname))
os.system("ip netns exec %s ethtool -K eth0 tx off" % (self.nsname))

# bring up link in the virtual switch
os.system("nsenter -t %d -n ip link set dev %s up" % (pid, self.vifname))

def __del__(self):
if self.cleanup:
os.system("ip netns delete %s" % self.nsname)

def runcmd(self, cmd):
os.system("ip netns exec %s %s" % (self.nsname, cmd))

def runcmd_async(self, cmd):
return subprocess.Popen("ip netns exec %s %s" % (self.nsname, cmd), shell=True)

class DockerVirtualSwitch(object):
def __init__(self, name=None):
self.pnames = ['fpmsyncd',
'intfmgrd',
'intfsyncd',
'neighsyncd',
'orchagent',
'portsyncd',
'redis-server',
'rsyslogd',
'syncd',
'teamsyncd',
'vlanmgrd',
'zebra']
self.mount = "/var/run/redis-vs"
self.redis_sock = self.mount + '/' + "redis.sock"
self.client = docker.from_env()

self.ctn = None
self.cleanup = True
if name != None:
# get virtual switch container
for ctn in self.client.containers.list():
if ctn.name == name:
self.ctn = ctn
(status, output) = commands.getstatusoutput("docker inspect --format '{{.HostConfig.NetworkMode}}' %s" % name)
ctn_sw_id = output.split(':')[1]
self.cleanup = False
if self.ctn == None:
raise NameError("cannot find container %s" % name)

# get base container
for ctn in self.client.containers.list():
if ctn.id == ctn_sw_id or ctn.name == ctn_sw_id:
ctn_sw_name = ctn.name

(status, output) = commands.getstatusoutput("docker inspect --format '{{.State.Pid}}' %s" % ctn_sw_name)
self.ctn_sw_pid = int(output)

# create virtual servers
self.servers = []
for i in range(32):
server = VirtualServer(ctn_sw_name, self.ctn_sw_pid, i)
self.servers.append(server)

self.restart()
else:
self.ctn_sw = self.client.containers.run('debian:jessie', privileged=True, detach=True,
command="bash", stdin_open=True)
(status, output) = commands.getstatusoutput("docker inspect --format '{{.State.Pid}}' %s" % self.ctn_sw.name)
self.ctn_sw_pid = int(output)

# create virtual server
self.servers = []
for i in range(32):
server = VirtualServer(self.ctn_sw.name, self.ctn_sw_pid, i)
self.servers.append(server)

# create virtual switch container
self.ctn = self.client.containers.run('docker-sonic-vs', privileged=True, detach=True,
network_mode="container:%s" % self.ctn_sw.name,
volumes={ self.mount: { 'bind': '/var/run/redis', 'mode': 'rw' } })

self.ctn.exec_run("sysctl -w net.ipv6.conf.all.disable_ipv6=0")
self.check_ready()
self.init_asicdb_validator()

def destroy(self):
if self.cleanup:
self.ctn.remove(force=True)
self.ctn_sw.remove(force=True)
for s in self.servers:
del(s)

def check_ready(self, timeout=30):
'''check if all processes in the dvs is ready'''

re_space = re.compile('\s+')
process_status = {}
ready = False
started = 0
while True:
# get process status
out = self.ctn.exec_run("supervisorctl status")
for l in out.split('\n'):
fds = re_space.split(l)
if len(fds) < 2:
continue
process_status[fds[0]] = fds[1]

# check if all processes are running
ready = True
for pname in self.pnames:
try:
if process_status[pname] != "RUNNING":
ready = False
except KeyError:
ready = False

if ready == True:
break

started += 1
if started > timeout:
raise ValueError(out)

time.sleep(1)

def restart(self):
self.ctn.restart()

def init_asicdb_validator(self):
self.asicdb = AsicDbValidator(self)

def runcmd(self, cmd):
return self.ctn.exec_run(cmd)

def copy_file(self, path, filename):
tarstr = StringIO.StringIO()
tar = tarfile.open(fileobj=tarstr, mode="w")
tar.add(filename, os.path.basename(filename))
tar.close()
self.ctn.put_archive(path, tarstr.getvalue())
tarstr.close()

@pytest.yield_fixture(scope="module")
def dvs(request):
name = request.config.getoption("--dvsname")
dvs = DockerVirtualSwitch(name)
yield dvs
dvs.destroy()
2 changes: 1 addition & 1 deletion src/sonic-quagga