#!/usr/bin/env python3 """ Vpp VCL tests """ import unittest import os import subprocess import signal import glob from config import config from framework import VppTestCase, VppTestRunner, Worker from vpp_ip_route import VppIpTable, VppIpRoute, VppRoutePath, FibPathProto iperf3 = '/usr/bin/iperf3' def have_app(app): try: subprocess.check_output([app, '-v']) except (subprocess.CalledProcessError, OSError): return False return True _have_iperf3 = have_app(iperf3) class VCLAppWorker(Worker): """ VCL Test Application Worker """ libname = "libvcl_ldpreload.so" class LibraryNotFound(Exception): pass def __init__(self, appname, executable_args, logger, env=None, role=None, *args, **kwargs): self.role = role vcl_ldpreload_glob = f"{config.vpp_install_dir}/**/{self.libname}" vcl_ldpreload_so = glob.glob(vcl_ldpreload_glob, recursive=True) if len(vcl_ldpreload_so) < 1: raise LibraryNotFound("cannot locate library: {}".format( self.libname)) vcl_ldpreload_so = vcl_ldpreload_so[0] if env is None: env = {} if "iperf" in appname: app = appname env.update({'LD_PRELOAD': vcl_ldpreload_so}) elif "sock" in appname: app = f"{config.vpp_build_dir}/vpp/bin/{appname}" env.update({'LD_PRELOAD': vcl_ldpreload_so}) else: app = f"{config.vpp_build_dir}/vpp/bin/{appname}" self.args = [app] + executable_args super(VCLAppWorker, self).__init__(self.args, logger, env, *args, **kwargs) class VCLTestCase(VppTestCase): """ VCL Test Class """ session_startup = ["poll-main"] @classmethod def setUpClass(cls): if cls.session_startup: conf = "session {" + " ".join(cls.session_startup) + "}" cls.extra_vpp_punt_config = [conf] super(VCLTestCase, cls).setUpClass() @classmethod def tearDownClass(cls): super(VCLTestCase, cls).tearDownClass() def setUp(self): self.vppDebug = 'vpp_debug' in config.vpp_install_dir self.server_addr = "127.0.0.1" self.server_port = "22000" self.server_args = [self.server_port] self.server_ipv6_addr = "::1" self.server_ipv6_args = ["-6", self.server_port] self.timeout = 20 self.echo_phrase = "Hello, world! Jenny is a friend of mine." self.pre_test_sleep = 0.3 self.post_test_sleep = 0.2 self.sapi_client_sock = "" self.sapi_server_sock = "" if os.path.isfile("/tmp/ldp_server_af_unix_socket"): os.remove("/tmp/ldp_server_af_unix_socket") super(VCLTestCase, self).setUp() def update_vcl_app_env(self, ns_id, ns_secret, attach_sock): if not ns_id: if 'VCL_APP_NAMESPACE_ID' in self.vcl_app_env: del self.vcl_app_env['VCL_APP_NAMESPACE_ID'] else: self.vcl_app_env['VCL_APP_NAMESPACE_ID'] = ns_id if not ns_secret: if 'VCL_APP_NAMESPACE_SECRET' in self.vcl_app_env: del self.vcl_app_env['VCL_APP_NAMESPACE_SECRET'] else: self.vcl_app_env['VCL_APP_NAMESPACE_SECRET'] = ns_secret if not attach_sock: self.vcl_app_env['VCL_VPP_API_SOCKET'] = self.get_api_sock_path() if 'VCL_VPP_SAPI_SOCKET' in self.vcl_app_env: del self.vcl_app_env['VCL_VPP_SAPI_SOCKET'] else: sapi_sock = "%s/app_ns_sockets/%s" % (self.tempdir, attach_sock) self.vcl_app_env['VCL_VPP_SAPI_SOCKET'] = sapi_sock if 'VCL_VPP_API_SOCKET' in self.vcl_app_env: del self.vcl_app_env['VCL_VPP_API_SOCKET'] def cut_thru_setup(self): self.vapi.session_enable_disable(is_enable=1) def cut_thru_tear_down(self): self.vapi.session_enable_disable(is_enable=0) def cut_thru_test(self, server_app, server_args, client_app, client_args): self.vcl_app_env = {'VCL_APP_SCOPE_LOCAL': "true"} self.update_vcl_app_env("", "", self.sapi_server_sock) worker_server = VCLAppWorker(server_app, server_args, self.logger, self.vcl_app_env, "server") worker_server.start() self.sleep(self.pre_test_sleep) self.update_vcl_app_env("", "", self.sapi_client_sock) worker_client = VCLAppWorker(client_app, client_args, self.logger, self.vcl_app_env, "client") worker_client.start() worker_client.join(self.timeout) try: self.validateResults(worker_client, worker_server, self.timeout) except Exception as error: self.fail("Failed with %s" % error) self.sleep(self.post_test_sleep) def thru_host_stack_setup(self): self.vapi.session_enable_disable(is_enable=1) self.create_loopback_interfaces(2) table_id = 1 for i in self.lo_interfaces: i.admin_up() if table_id != 0: tbl = VppIpTable(self, table_id) tbl.add_vpp_config() i.set_table_ip4(table_id) i.config_ip4() table_id += 1 # Configure namespaces self.vapi.app_namespace_add_del(namespace_id="1", secret=1234, sw_if_index=self.loop0.sw_if_index) self.vapi.app_namespace_add_del(namespace_id="2", secret=5678, sw_if_index=self.loop1.sw_if_index) # Add inter-table routes ip_t01 = VppIpRoute(self, self.loop1.local_ip4, 32, [VppRoutePath("0.0.0.0", 0xffffffff, nh_table_id=2)], table_id=1) ip_t10 = VppIpRoute(self, self.loop0.local_ip4, 32, [VppRoutePath("0.0.0.0", 0xffffffff, nh_table_id=1)], table_id=2) ip_t01.add_vpp_config() ip_t10.add_vpp_config() self.logger.debug(self.vapi.cli("show ip fib")) def thru_host_stack_tear_down(self): for i in self.lo_interfaces: i.unconfig_ip4() i.set_table_ip4(0) i.admin_down() def thru_host_stack_ipv6_setup(self): self.vapi.session_enable_disable(is_enable=1) self.create_loopback_interfaces(2) table_id = 1 for i in self.lo_interfaces: i.admin_up() tbl = VppIpTable(self, table_id, is_ip6=1) tbl.add_vpp_config() i.set_table_ip6(table_id) i.config_ip6() table_id += 1 # Configure namespaces self.vapi.app_namespace_add_del(namespace_id="1", secret=1234, sw_if_index=self.loop0.sw_if_index) self.vapi.app_namespace_add_del(namespace_id="2", secret=5678, sw_if_index=self.loop1.sw_if_index) # Add inter-table routes ip_t01 = VppIpRoute(self, self.loop1.local_ip6, 128, [VppRoutePath("::0", 0xffffffff, nh_table_id=2)], table_id=1) ip_t10 = VppIpRoute(self, self.loop0.local_ip6, 128, [VppRoutePath("::0", 0xffffffff, nh_table_id=1)], table_id=2) ip_t01.add_vpp_config() ip_t10.add_vpp_config() self.logger.debug(self.vapi.cli("show interface addr")) self.logger.debug(self.vapi.cli("show ip6 fib")) def thru_host_stack_ipv6_tear_down(self): for i in self.lo_interfaces: i.unconfig_ip6() i.set_table_ip6(0) i.admin_down() self.vapi.session_enable_disable(is_enable=0) @unittest.skipUnless(_have_iperf3, "'%s' not found, Skipping.") def thru_host_stack_test(self, server_app, server_args, client_app, client_args): self.vcl_app_env = {'VCL_APP_SCOPE_GLOBAL': "true"} self.update_vcl_app_env("1", "1234", self.sapi_server_sock) worker_server = VCLAppWorker(server_app, server_args, self.logger, self.vcl_app_env, "server") worker_server.start() self.sleep(self.pre_test_sleep) self.updat
/*
* Copyright (c) 2017 Cisco and/or its affiliates.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#undef CLIB_CUCKOO_TYPE
#define CLIB_CUCKOO_TYPE _8_8
#define CLIB_CUCKOO_KVP_PER_BUCKET (4)
#define CLIB_CUCKOO_LOG2_KVP_PER_BUCKET (2)
#define CLIB_CUCKOO_BFS_MAX_STEPS (2000)
#define CLIB_CUCKOO_BFS_MAX_PATH_LENGTH (8)
#ifndef __included_cuckoo_8_8_h__
#define __included_cuckoo_8_8_h__
#include <vppinfra/heap.h>
#include <vppinfra/format.h>
#include <vppinfra/pool.h>
#include <vppinfra/xxhash.h>
#include <vppinfra/cuckoo_debug.h>
#include <vppinfra/cuckoo_common.h>
#undef CLIB_CUCKOO_OPTIMIZE_PREFETCH
#undef CLIB_CUCKOO_OPTIMIZE_CMP_REDUCED_HASH
#undef CLIB_CUCKOO_OPTIMIZE_UNROLL
#undef CLIB_CUCKOO_OPTIMIZE_USE_COUNT_LIMITS_SEARCH
#define CLIB_CUCKOO_OPTIMIZE_PREFETCH 1
#define CLIB_CUCKOO_OPTIMIZE_CMP_REDUCED_HASH 1
#define CLIB_CUCKOO_OPTIMIZE_UNROLL 1
#define CLIB_CUCKOO_OPTIMIZE_USE_COUNT_LIMITS_SEARCH 1
#if __SSE4_2__ && !defined (__i386__)
#include <x86intrin.h>
#endif
/** 8 octet key, 8 octet key value pair */
typedef struct
{
u64 key; /**< the key */
u64 value; /**< the value */
} clib_cuckoo_kv_8_8_t;
/** Decide if a clib_cuckoo_kv_8_8_t instance is free
@param v- pointer to the (key,value) pair
*/
always_inline int
clib_cuckoo_kv_is_free_8_8 (const clib_cuckoo_kv_8_8_t * v)
{
if (v->key == ~0ULL && v->value == ~0ULL)
return 1;
return 0;
}
always_inline void
clib_cuckoo_kv_set_free_8_8 (clib_cuckoo_kv_8_8_t * v)
{
memset (v, 0xff, sizeof (*v));
}
/** Format a clib_cuckoo_kv_8_8_t instance
@param s - u8 * vector under construction
@param args (vararg) - the (key,value) pair to format
@return s - the u8 * vector under construction
*/
always_inline u8 *
format_cuckoo_kvp_8_8 (u8 * s, va_list * args)
{
clib_cuckoo_kv_8_8_t *v = va_arg (*args, clib_cuckoo_kv_8_8_t *);
if (clib_cuckoo_kv_is_free_8_8 (v))
{
s = format (s, " -- empty -- ", v->key, v->value);
}
else
{
s = format (s, "key %llu value %llu", v->key, v->value);
}
return s;
}
always_inline u64
clib_cuckoo_hash_8_8 (clib_cuckoo_kv_8_8_t * v)
{
#if defined(clib_crc32c_uses_intrinsics) && !defined (__i386__)
return crc32_u64 (0, v->key);
#else
return clib_xxhash (v->key);
#endif
}
/** Compare two clib_cuckoo_kv_8_8_t instances
@param a - first key
@param b - second key
*/
always_inline int
clib_cuckoo_key_compare_8_8 (u64 a, u64 b)
{
return a == b;
}
#if 0
#undef __included_cuckoo_template_h__
#include <vppinfra/cuckoo_template.h>
#endif
#endif /* __included_cuckoo_8_8_h__ */
/*
* fd.io coding-style-patch-verification: ON
*
* Local Variables:
* eval: (c-set-style "gnu")
* End:
*/