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

added support for native docker networking #188

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
43 changes: 38 additions & 5 deletions common/vrnetlab.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ def gen_mac(last_octet=None):



def run_command(cmd, cwd=None, background=False):
def run_command(cmd, cwd=None, background=False,shell=False):
res = None
try:
if background:
p = subprocess.Popen(cmd, cwd=cwd)
else:
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, cwd=cwd)
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, cwd=cwd, shell=shell)
res = p.communicate()
except:
pass
Expand Down Expand Up @@ -65,6 +65,7 @@ def __init__(self, username, password, disk_image=None, num=0, ram=4096):
self.num_nics = 0
self.nics_per_pci_bus = 26 # tested to work with XRv
self.smbios = []
self.meshnet = False # Default to not do meshnet
overlay_disk_image = re.sub(r'(\.[^.]+$)', r'-overlay\1', disk_image)

if not os.path.exists(overlay_disk_image):
Expand Down Expand Up @@ -148,6 +149,27 @@ def start(self):
pass


def create_bridges(self):
""" Create a linux bridge for every attached eth interface
Returns list of bridge names
"""
run_command(["mkdir", "-p", "/etc/qemu"]) # This is to whitlist all bridges
run_command(["echo 'allow all' > /etc/qemu/bridge.conf"], shell=True)

bridges = list()
intfs = [x for x in os.listdir('/sys/class/net/') if 'eth' in x if x != 'eth0']
intfs.sort()

self.logger.info("Creating bridges for interfaces: %s" % intfs)

for idx, intf in enumerate(intfs):
run_command(["ip", "link", "add", "name", "br-%s" % idx, "type", "bridge"], background=True)
run_command(["ip", "link", "set", "br-%s" % idx, "up"], background=True)
run_command(["ip", "link", "set", intf, "master", "br-%s" % idx], background=True)
run_command(["echo 16384 > /sys/class/net/br-%s/bridge/group_fwd_mask" % idx], shell=True)
bridges.append("br-%s" % idx)
return bridges

def gen_mgmt(self):
""" Generate qemu args for the mgmt interface(s)
"""
Expand All @@ -171,6 +193,8 @@ def gen_nics(self):
""" Generate qemu args for the normal traffic carrying interface(s)
"""
res = []
if self.num_nics > 0:
bridges = self.create_bridges()
# vEOS-lab requires its Ma1 interface to be the first in the bus, so start normal nics at 2
if 'vEOS-lab' in self.image:
range_start = 2
Expand All @@ -189,9 +213,18 @@ def gen_nics(self):
'addr': addr,
'mac': gen_mac(i)
})
res.append("-netdev")
res.append("socket,id=p%(i)02d,listen=:100%(i)02d"
% { 'i': i })
if self.meshnet: # Meshnet logic
if i <= len(bridges):
bridge = bridges[i-1] # We're starting from 0
res.append("-netdev")
res.append("bridge,id=p%(i)02d,br=%(bridge)s"
% { 'i': i, 'bridge': bridge })
else: # We don't create more interfaces than we have bridges
del res[-2:] # Removing recently added interface
else:
res.append("-netdev")
res.append("socket,id=p%(i)02d,listen=:100%(i)02d"
% { 'i': i })
return res


Expand Down
10 changes: 6 additions & 4 deletions csr/docker/launch.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def trace(self, message, *args, **kws):


class CSR_vm(vrnetlab.VM):
def __init__(self, username, password, install_mode=False):
def __init__(self, username, password, install_mode=False, meshnet=False):
for e in os.listdir("/"):
if re.search(".qcow2$", e):
disk_image = "/" + e
Expand All @@ -49,6 +49,7 @@ def __init__(self, username, password, install_mode=False):

self.install_mode = install_mode
self.num_nics = 9
self.meshnet = meshnet

if self.install_mode:
logger.trace("install mode")
Expand Down Expand Up @@ -156,9 +157,9 @@ def bootstrap_config(self):


class CSR(vrnetlab.VR):
def __init__(self, username, password):
def __init__(self, username, password, meshnet=False):
super(CSR, self).__init__(username, password)
self.vms = [ CSR_vm(username, password) ]
self.vms = [ CSR_vm(username, password, meshnet=meshnet) ]


class CSR_installer(CSR):
Expand Down Expand Up @@ -188,6 +189,7 @@ def install(self):
parser.add_argument('--username', default='vrnetlab', help='Username')
parser.add_argument('--password', default='VR-netlab9', help='Password')
parser.add_argument('--install', action='store_true', help='Install CSR')
parser.add_argument('--meshnet', action='store_true', help='Native docker networking')
args = parser.parse_args()

LOG_FORMAT = "%(asctime)s: %(module)-10s %(levelname)-8s %(message)s"
Expand All @@ -202,5 +204,5 @@ def install(self):
vr = CSR_installer(args.username, args.password)
vr.install()
else:
vr = CSR(args.username, args.password)
vr = CSR(args.username, args.password, meshnet=args.meshnet)
vr.start()
12 changes: 7 additions & 5 deletions vmx/docker/launch.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,10 +167,11 @@ def wait_write(self, cmd, wait='#', timeout=None):


class VMX_vfpc(vrnetlab.VM):
def __init__(self, version):
def __init__(self, version, meshnet=False):
super(VMX_vfpc, self).__init__(None, None, disk_image = "/vmx/vfpc.img", num=1)
self.version = version
self.num_nics = 96
self.meshnet = meshnet

self.nic_type = "virtio-net-pci"
self.qemu_args.extend(["-cpu", "SandyBridge", "-M", "pc", "-smp", "3"])
Expand All @@ -191,7 +192,7 @@ def gen_mgmt(self):
res.extend(["-netdev",
"tap,ifname=vfpc-int,id=vfpc-int,script=no,downscript=no"])

if self.version in ('15.1F6.9', '16.1R2.11'):
if self.version in ('15.1F6.9', '16.1R2.11', '17.2R1.13'):
# dummy interface for some vMX versions - not sure why vFPC wants
# it but without it we get a misalignment
res.extend(["-device", "virtio-net-pci,netdev=dummy,mac=%s" %
Expand Down Expand Up @@ -233,14 +234,14 @@ class VMX(vrnetlab.VR):
""" Juniper vMX router
"""

def __init__(self, username, password):
def __init__(self, username, password, meshnet=False):
self.version = None
self.version_info = []
self.read_version()

super(VMX, self).__init__(username, password)

self.vms = [ VMX_vcp(username, password, "/vmx/" + self.vcp_image), VMX_vfpc(self.version) ]
self.vms = [ VMX_vcp(username, password, "/vmx/" + self.vcp_image), VMX_vfpc(self.version, meshnet=meshnet) ]

# set up bridge for connecting VCP with vFPC
vrnetlab.run_command(["brctl", "addbr", "int_cp"])
Expand Down Expand Up @@ -313,6 +314,7 @@ def install(self):
parser.add_argument('--username', default='vrnetlab', help='Username')
parser.add_argument('--password', default='VR-netlab9', help='Password')
parser.add_argument('--install', action='store_true', help='Install vMX')
parser.add_argument('--meshnet', action='store_true', help='Native docker networking mode')
args = parser.parse_args()

LOG_FORMAT = "%(asctime)s: %(module)-10s %(levelname)-8s %(message)s"
Expand All @@ -327,5 +329,5 @@ def install(self):
vr = VMX_installer(args.username, args.password)
vr.install()
else:
vr = VMX(args.username, args.password)
vr = VMX(args.username, args.password, meshnet=args.meshnet)
vr.start()
10 changes: 6 additions & 4 deletions xrv/docker/launch.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def trace(self, message, *args, **kws):


class XRV_vm(vrnetlab.VM):
def __init__(self, username, password):
def __init__(self, username, password, meshnet=False):
for e in os.listdir("/"):
if re.search(".vmdk", e):
disk_image = "/" + e
Expand All @@ -44,6 +44,7 @@ def __init__(self, username, password):
]

self.xr_ready = False
self.meshnet = meshnet


def bootstrap_spin(self):
Expand Down Expand Up @@ -164,9 +165,9 @@ def bootstrap_config(self):


class XRV(vrnetlab.VR):
def __init__(self, username, password):
def __init__(self, username, password, meshnet):
super(XRV, self).__init__(username, password)
self.vms = [ XRV_vm(username, password) ]
self.vms = [ XRV_vm(username, password, meshnet) ]



Expand All @@ -176,6 +177,7 @@ def __init__(self, username, password):
parser.add_argument('--trace', action='store_true', help='enable trace level logging')
parser.add_argument('--username', default='vrnetlab', help='Username')
parser.add_argument('--password', default='VR-netlab9', help='Password')
parser.add_argument('--meshnet', action='store_true', help='Native docker networking mode')
args = parser.parse_args()

LOG_FORMAT = "%(asctime)s: %(module)-10s %(levelname)-8s %(message)s"
Expand All @@ -186,5 +188,5 @@ def __init__(self, username, password):
if args.trace:
logger.setLevel(1)

vr = XRV(args.username, args.password)
vr = XRV(args.username, args.password, meshnet=args.meshnet)
vr.start()