aboutsummaryrefslogtreecommitdiffstats
path: root/vicn
diff options
context:
space:
mode:
authorMarcel Enguehard <mengueha+fdio@cisco.com>2017-10-09 08:44:59 +0200
committerMarcel Enguehard <mengueha+fdio@cisco.com>2017-10-09 08:55:46 +0200
commit5f8867a3454164ad20ae427dc9d2c7d65ea00a90 (patch)
treec8ff40fb147a76af2baa77790ba8a6ac968e51b4 /vicn
parentaf2dd545d04cfca7e7ec066035abf78c3d541915 (diff)
Several fixes related to async_set, ip addressing, and memif interfaces for VPP
Change-Id: I26b7928751f41ea66ba47bb1becac33cf5195915 Signed-off-by: Marcel Enguehard <mengueha+fdio@cisco.com>
Diffstat (limited to 'vicn')
-rw-r--r--vicn/core/resource.py9
-rw-r--r--vicn/core/resource_mgr.py12
-rw-r--r--vicn/resource/icn/central.py6
-rw-r--r--vicn/resource/icn/cicn.py7
-rw-r--r--vicn/resource/ip/central.py4
-rw-r--r--vicn/resource/lxd/lxc_container.py1
-rw-r--r--vicn/resource/vpp/interface.py74
-rw-r--r--vicn/resource/vpp/memif_link.py2
-rw-r--r--vicn/resource/vpp/scripts.py2
-rw-r--r--vicn/resource/vpp/vpp.py5
-rw-r--r--vicn/resource/vpp/vpp_commands.py3
11 files changed, 91 insertions, 34 deletions
diff --git a/vicn/core/resource.py b/vicn/core/resource.py
index 878a8108..a80e09ed 100644
--- a/vicn/core/resource.py
+++ b/vicn/core/resource.py
@@ -467,7 +467,7 @@ class BaseResource(Object): #, ABC, metaclass=ResourceMetaclass):
self._state.manager.attribute_set(self, attribute_name, value)
async def async_set(self, attribute_name, value, current=False,
- set_reverse=True, blocking=None):
+ set_reverse=True):
"""
Example:
- setting the ip address on a node's interface
@@ -478,7 +478,12 @@ class BaseResource(Object): #, ABC, metaclass=ResourceMetaclass):
"""
value = self._set(attribute_name, value, current=current,
set_reverse=set_reverse)
- await self._state.manager.attribute_set_async(self, attribute_name, value)
+ if self.is_local_attribute(attribute_name) or current:
+ if value is None:
+ attribute = self.get_attribute(attribute_name)
+ vars(self)[attribute_name] = value
+ else:
+ await self._state.manager.attribute_async_set(self, attribute_name, value)
def set_many(self, attribute_dict, current=False):
if not attribute_dict:
diff --git a/vicn/core/resource_mgr.py b/vicn/core/resource_mgr.py
index 8db7f04d..b4aa6bb7 100644
--- a/vicn/core/resource_mgr.py
+++ b/vicn/core/resource_mgr.py
@@ -587,7 +587,7 @@ class ResourceManager(metaclass=Singleton):
await self.wait_attr_init(resource, attribute)
return resource.get(attribute)
- async def _attribute_set(self, resource, attribute_name, value):
+ async def _attribute_set(self, resource, attribute_name, value, blocking=False):
with await resource._state.write_lock:
attr_state = resource._state.attr_state[attribute_name]
@@ -632,8 +632,8 @@ class ResourceManager(metaclass=Singleton):
raise RuntimeError("Resource cannot be in state".format(
resource_state))
-# if blocking:
-# await self.wait_attr_clean(resource, attribute_name)
+ if blocking:
+ await self.wait_attr_clean(resource, attribute_name)
def attribute_set(self, resource, attribute_name, value):
# Add the current operation to the pending list
@@ -643,15 +643,13 @@ class ResourceManager(metaclass=Singleton):
value)
asyncio.ensure_future(self._attribute_set(resource, attribute_name, value))
- async def attribute_set_async(self, resource, attribute_name, value):
+ async def attribute_async_set(self, resource, attribute_name, value):
# Add the current operation to the pending list
# NOTE: collections are unordered and can be updated concurrently
#self._attribute_set_pending_value(resource, attribute_name)
resource._state.dirty[attribute_name].trigger(Operations.SET,
value)
- await self._attribute_set(resource, attribute_name, value)
-
-
+ await self._attribute_set(resource, attribute_name, value, blocking=True)
#---------------------------------------------------------------------------
# Resource dependency management
diff --git a/vicn/resource/icn/central.py b/vicn/resource/icn/central.py
index aa8ea357..fd272bf6 100644
--- a/vicn/resource/icn/central.py
+++ b/vicn/resource/icn/central.py
@@ -81,6 +81,8 @@ class ICNFaces(Resource):
def __delete__(self):
raise NotImplementedError
+ def __after__(self):
+ return ("VPPInterface",)
#--------------------------------------------------------------------------
# Internal methods
#--------------------------------------------------------------------------
@@ -102,7 +104,11 @@ class ICNFaces(Resource):
map_ = data['map_node_interface']
src = self._state.manager.by_uuid(map_[src_node_uuid])
+ if src.has_vpp_child:
+ src = src.vppinterface
dst = self._state.manager.by_uuid(map_[dst_node_uuid])
+ if dst.has_vpp_child:
+ dst = dst.vppinterface
log.debug('{} -> {} ({} -> {})'.format(src_node_uuid,
dst_node_uuid, src.device_name, dst.device_name))
diff --git a/vicn/resource/icn/cicn.py b/vicn/resource/icn/cicn.py
index 8ab36ec9..597692c8 100644
--- a/vicn/resource/icn/cicn.py
+++ b/vicn/resource/icn/cicn.py
@@ -71,7 +71,7 @@ class CICNForwarder(Forwarder):
@inherit_parent
def __get__(self):
def parse(rv):
- if rv.return_value > 0 or 'cicn: not enabled' in rv.stdout:
+ if rv.return_value > 0 or 'cicn: not enabled' in rv.stdout or "Forwarder : disabled" in rv.stdout:
raise ResourceNotFound
return BashTask(self.node, CMD_VPP_CICN_GET,
lock = self.node.vpp.vppctl_lock, parse=parse)
@@ -134,6 +134,9 @@ class CICNForwarder(Forwarder):
def _get_cache_size(self):
def parse(rv):
- return int(rv.stdout)
+ if not rv.stdout:
+ return 0
+ else:
+ return int(rv.stdout)
return BashTask(self.node, CMD_VPP_CICN_GET_CACHE_SIZE, parse=parse,
lock = self.node.vpp.vppctl_lock)
diff --git a/vicn/resource/ip/central.py b/vicn/resource/ip/central.py
index 0c397728..75b590e1 100644
--- a/vicn/resource/ip/central.py
+++ b/vicn/resource/ip/central.py
@@ -82,7 +82,8 @@ class IPRoutes(Resource):
node_uuid = interface.node._state.uuid
if not node_uuid in origins:
origins[node_uuid] = list()
- origins[node_uuid].append(interface.ip4_address.canonical_prefix())
+ if interface.ip4_address:
+ origins[node_uuid].append(interface.ip4_address.canonical_prefix())
if interface.ip6_address:
origins[node_uuid].append(interface.ip6_address.canonical_prefix())
return origins
@@ -113,7 +114,6 @@ class IPRoutes(Resource):
# Avoid duplicate routes due to multiple paths in the network
if not src_node in ip_routes:
ip_routes[src_node] = set()
- #XXX Untested for VPP
#When you set up an IP address ip/prefix_len (ip addr add), you already create a route
#towards ip/prefix_len
for interface in src_node.interfaces:
diff --git a/vicn/resource/lxd/lxc_container.py b/vicn/resource/lxd/lxc_container.py
index a9f8483d..3222cc8a 100644
--- a/vicn/resource/lxd/lxc_container.py
+++ b/vicn/resource/lxd/lxc_container.py
@@ -19,6 +19,7 @@
import logging
import shlex
import time
+import requests
# Suppress logging from pylxd dependency on ws4py
# (this needs to be included before pylxd)
diff --git a/vicn/resource/vpp/interface.py b/vicn/resource/vpp/interface.py
index 9dbd7fc3..f845e2df 100644
--- a/vicn/resource/vpp/interface.py
+++ b/vicn/resource/vpp/interface.py
@@ -34,11 +34,18 @@ from vicn.resource.vpp.vpp_commands import CMD_VPP_CREATE_IFACE, CMD_VPP_CREATE_
from vicn.resource.vpp.vpp_commands import CMD_VPP_SET_IP, CMD_VPP_SET_UP
from vicn.resource.vpp.memif_device import MemifDevice
+VPP_vers = (17, 7)
+
GREP_MEMIF_INFO = 'vppctl_wrapper show memif | grep interface --no-group-separator -A 1'
def parse_memif(rv, vppinterface):
kw_interface = pp.CaselessKeyword('interface')
kw_key = pp.CaselessKeyword('key')
+ kw_remote_name = pp.CaselessKeyword('remote-name')
+ kw_remote_if = pp.CaselessKeyword('remote-interface')
+ kw_id = pp.CaselessKeyword('id')
+ kw_mode = pp.CaselessKeyword('mode')
+ kw_ethernet = pp.CaselessKeyword('ethernet')
kw_file = pp.CaselessKeyword('file')
kw_listener = pp.CaselessKeyword('listener')
kw_connfd = pp.CaselessKeyword('conn-fd')
@@ -51,20 +58,41 @@ def parse_memif(rv, vppinterface):
r_path = ' *(/[a-zA-Z0-9_\-]*)*\.[a-zA-Z0-9_\-]*'
r_id = ' *-+[0-9]*'
- single = kw_interface.suppress() + pp.Word(pp.alphanums).setResultsName('interface') + \
- kw_key.suppress() + pp.Word(pp.alphanums).setResultsName('key') + \
- kw_file.suppress() + pp.Regex(r_path).setResultsName('path') # + \
- # kw_listener.suppress() + pp.Word(pp.alphanums).setResultsName('listener') + \
- # kw_connfd.suppress() + pp.Regex(r_id).setResultsName('conn-fd') + \
- # kw_intfd.suppress() + pp.Regex(r_id).setResultsName('int-fd') + \
- # kw_ringsize.suppress() + pp.Word(pp.nums).setResultsName('ring-size') + \
- # kw_numc2srings.suppress() + pp.Word(pp.nums).setResultsName('num-c2s-rings') + \
- # kw_nums2crings.suppress() + pp.Word(pp.nums).setResultsName('num-s2c-rings') + \
- # kw_buffersize.suppress() + pp.Word(pp.nums).setResultsName('buffer-size')
+ r_remote_name = '"[A-Z]+ [0-9\.]+-[a-z]+"'
+ r_remote_if = '"[a-zA-Z0-9_\-]+"'
+
+ if VPP_vers >= (17, 7):
+ single = kw_interface.suppress() + pp.Word(pp.alphanums).setResultsName('interface') + \
+ pp.Optional(kw_remote_name.suppress() + pp.Regex(r_remote_name).setResultsName('remote_name') + \
+ kw_remote_if.suppress() + pp.Regex(r_remote_if).setResultsName('remote_if')) + \
+ kw_id.suppress() + pp.Word(pp.alphanums).setResultsName('key') + \
+ kw_mode.suppress() + kw_ethernet.suppress() + \
+ kw_file.suppress() + pp.Regex(r_path).setResultsName('path') # + \
+ # kw_listener.suppress() + pp.Word(pp.alphanums).setResultsName('listener') + \
+ # kw_connfd.suppress() + pp.Regex(r_id).setResultsName('conn-fd') + \
+ # kw_intfd.suppress() + pp.Regex(r_id).setResultsName('int-fd') + \
+ # kw_ringsize.suppress() + pp.Word(pp.nums).setResultsName('ring-size') + \
+ # kw_numc2srings.suppress() + pp.Word(pp.nums).setResultsName('num-c2s-rings') + \
+ # kw_nums2crings.suppress() + pp.Word(pp.nums).setResultsName('num-s2c-rings') + \
+ # kw_buffersize.suppress() + pp.Word(pp.nums).setResultsName('buffer-size')
+ else:
+ single = kw_interface.suppress() + pp.Word(pp.alphanums).setResultsName('interface') + \
+ kw_key.suppress() + pp.Word(pp.alphanums).setResultsName('key') + \
+ kw_file.suppress() + pp.Regex(r_path).setResultsName('path') # + \
+ # kw_listener.suppress() + pp.Word(pp.alphanums).setResultsName('listener') + \
+ # kw_connfd.suppress() + pp.Regex(r_id).setResultsName('conn-fd') + \
+ # kw_intfd.suppress() + pp.Regex(r_id).setResultsName('int-fd') + \
+ # kw_ringsize.suppress() + pp.Word(pp.nums).setResultsName('ring-size') + \
+ # kw_numc2srings.suppress() + pp.Word(pp.nums).setResultsName('num-c2s-rings') + \
+ # kw_nums2crings.suppress() + pp.Word(pp.nums).setResultsName('num-s2c-rings') + \
+ # kw_buffersize.suppress() + pp.Word(pp.nums).setResultsName('buffer-size')
multiple = pp.OneOrMore(pp.Group(single))
- results = multiple.parseString(rv.stdout)
+ try:
+ results = multiple.parseString(rv.stdout)
+ except Exception as e:
+ import pdb; pdb.set_trace()
for interface in results:
if interface['path'] == vppinterface.parent.path_unix_socket + vppinterface.parent.socket_name:
@@ -108,7 +136,7 @@ class VPPInterface(Resource):
"""
We need CentralIP to get the parent interface IP address
"""
- return ['CentralIP']
+ return ['CentralIP', 'IpAssignment']
@inherit_parent
@inline_task
@@ -126,9 +154,23 @@ class VPPInterface(Resource):
self.parent.has_vpp_child = True
self.up = True
+ self.ip4_address = self.parent.ip4_address
+ self.ip6_address = self.parent.ip6_address
+
if isinstance(self.parent, MemifDevice):
+ self.device_name = self.parent.device_name
+
#TODO: add output parsing to get the interface name
- create_task = BashTask(self.vpp.node, CMD_VPP_CREATE_MEMIFACE, {
+ if VPP_vers >= (17, 7):
+ create_task = BashTask(self.vpp.node, CMD_VPP_CREATE_MEMIFACE, {
+ 'key_label': 'id',
+ 'key': self.parent.key,
+ 'vpp_interface': self,
+ 'master_slave': 'master' if self.parent.master else 'slave'},
+ lock = self.vpp.vppctl_lock)
+ else:
+ create_task = BashTask(self.vpp.node, CMD_VPP_CREATE_MEMIFACE, {
+ 'key_label': 'key',
'key': hex(self.parent.key),
'vpp_interface': self,
'master_slave': 'master' if self.parent.master else 'slave'},
@@ -143,8 +185,8 @@ class VPPInterface(Resource):
# Remove ip address in the parent device, it must only be set in
# the vpp interface otherwise vpp and the linux kernel will reply
# to non-icn request (e.g., ARP replies, port ureachable etc)
- self.ip4_address = self.parent.ip4_address
- self.ip6_address = self.parent.ip6_address
+ self.parent.ip4_address = None
+ self.parent.ip6_address = None
self.device_name = 'host-' + self.parent.device_name
create_task = BashTask(self.vpp.node, CMD_VPP_CREATE_IFACE,
@@ -155,8 +197,6 @@ class VPPInterface(Resource):
self.parent.remote.set('offload', False)
elif self.parent.get_type() == 'dpdkdevice':
- self.ip4_address = self.parent.ip4_address
- self.ip6_address = self.parent.ip6_address
self.device_name = self.parent.device_name
else :
# Currently assume naively that everything else will be a physical
diff --git a/vicn/resource/vpp/memif_link.py b/vicn/resource/vpp/memif_link.py
index 62de03c6..25cfeea3 100644
--- a/vicn/resource/vpp/memif_link.py
+++ b/vicn/resource/vpp/memif_link.py
@@ -90,7 +90,7 @@ class MemifLink(Channel):
foldername = SHARED_FOLDER_PATH.format(self.src_node.name + '-' + self.dst_node.name),
permission = 777)
- self.key = random.randint(0, 2**64)
+ self.key = random.randint(0, 2**31)
self._src = MemifDevice(node = self.src_node,
channel = self,
diff --git a/vicn/resource/vpp/scripts.py b/vicn/resource/vpp/scripts.py
index 06da7404..b467df6c 100644
--- a/vicn/resource/vpp/scripts.py
+++ b/vicn/resource/vpp/scripts.py
@@ -282,7 +282,7 @@ api-segment {
'''
APPARMOR_VPP_PROFILE = '''
-lxc.aa_profile = lxc-dpdk
+lxc.apparmor.profile = lxc-dpdk
lxc.mount.entry = hugetlbfs dev/hugepages hugetlbfs rw,relatime,create=dir 0 0
lxc.mount.auto = sys:rw'''
diff --git a/vicn/resource/vpp/vpp.py b/vicn/resource/vpp/vpp.py
index 9d4f7068..a185c039 100644
--- a/vicn/resource/vpp/vpp.py
+++ b/vicn/resource/vpp/vpp.py
@@ -147,7 +147,10 @@ class VPP(LinuxApplication):
if numa in socket_mem:
socket_mem_str = socket_mem_str + str(socket_mem[numa])
else:
- socket_mem_str = socket_mem_str + '0'
+ if None in socket_mem: #No numa nodes on machine but DpdkDevice has socket mem
+ socket_mem_str = socket_mem_str+str(socket_mem[None])
+ else:
+ socket_mem_str = socket_mem_str + '0'
if numa < numa_mgr.get_number_of_numa()-1:
socket_mem_str = socket_mem_str + ','
diff --git a/vicn/resource/vpp/vpp_commands.py b/vicn/resource/vpp/vpp_commands.py
index acc89640..e0b71517 100644
--- a/vicn/resource/vpp/vpp_commands.py
+++ b/vicn/resource/vpp/vpp_commands.py
@@ -6,6 +6,7 @@ CMD_VPP_DISABLE = 'systemctl disable vpp.service'
# 'sleep 1' ensures that VPP has enough time to start
CMD_VPP_START = '''
flock /tmp/vppctl.lock -c "systemctl start vpp"
+sleep 2
'''
CMD_VPP_STOP = '''
flock /tmp/vppctl.lock -c "systemctl stop vpp"
@@ -25,7 +26,7 @@ vppctl_wrapper set interface state {vpp_interface.device_name} up
# generated by VPP, preventing any reboot of VPP and recreation of commands
CMD_VPP_CREATE_MEMIFACE = '''
# Create vpp interface from shared_memory
-vppctl_wrapper create memif key {key} socket {vpp_interface.parent.path_unix_socket}{vpp_interface.parent.socket_name} hw-addr {vpp_interface.parent.mac_address} {master_slave}
+vppctl_wrapper create memif {key_label} {key} socket {vpp_interface.parent.path_unix_socket}{vpp_interface.parent.socket_name} hw-addr {vpp_interface.parent.mac_address} {master_slave}
'''
CMD_VPP_SET_IP = 'vppctl_wrapper set int ip address {device_name} {ip_address}/{prefix_len}'
CMD_VPP_SET_UP = 'vppctl_wrapper set int state {netdevice.device_name} {state}'