Compare commits

...

26 Commits

Author SHA1 Message Date
Damjan Marion
cd111b2228 Fix plugin version numbers
Change-Id: Ie485e9dfa04747b5e4ba93fdeabc5802dc001d31
Signed-off-by: Damjan Marion <damarion@cisco.com>
2017-01-20 21:58:02 +01:00
Gabriel Ganne
7067350c41 vpp-python-api deb packaging - use easy_install to install the python api
(cherry picked from commit 5a68debd8173a487dbd67b3e574d962308c91bcc)

Change-Id: Iabad73d6092b4561ba9d4d22a057bb5871d850a6
Signed-off-by: Gabriel Ganne <gabriel.ganne@qosmos.com>
2017-01-20 20:29:21 +00:00
Damjan Marion
fa87080d31 Fix issue in rpm versioning for release builds
Change-Id: I851d472c0838d56ca571f9f9e3ca412ac2107c4e
Signed-off-by: Damjan Marion <damarion@cisco.com>
2017-01-20 19:09:22 +01:00
Damjan Marion
78aab80634 Release notes for release 17.01
Change-Id: I99c0898bb0cb99e1b2a28463245031e74afd401b
Signed-off-by: Damjan Marion <damarion@cisco.com>
2017-01-20 16:22:03 +00:00
Ole Troan
7104f93c75 Python API: Missing locking of results data structure.
The wrong assumption that the GIL combined with CPython's "mostly"
thread safe assurance does not hold. The combination of a slow
event handler for notification and calling the API at the same
time let to contention on the results data structure.

Added suitable locking.

Also added an atexit() to attempt a VPP disconnect on shutdown.

Also: lots more comments, docstrings, duplicated code removed.
Some of the problem here was a disagreement between caller
and author as to how the API should be used; the comments should
help.

Change-Id: I0cb7d0026db660ec141425c5ad474f14bacea36e
Signed-off-by: Ole Troan <ot@cisco.com>
Co-Authored-By: Ian Wells <iawells@cisco.com>
Signed-off-by: Ole Troan <ot@cisco.com>
2017-01-20 01:49:04 +01:00
Filip Tehlar
12713c70fc LISP: Fix fwd adding, VPP-607
Change-Id: Ie48209ba6d9aab0c5cfbd7b3cce4114cf88f952c
Signed-off-by: Filip Tehlar <ftehlar@cisco.com>
2017-01-18 18:16:22 +00:00
Wojciech Dec
1b3d4ded5f Fix crash on deleting activated vhost-user - VPP-603
Vhost-user pool getting freed prematurely

Change-Id: I90b70889d2e5a01203dc7679583b7c9eff65a374
Signed-off-by: Wojciech Dec <wdec@cisco.com>
2017-01-18 17:40:55 +00:00
Jan Gelety
cd8a22ae1f Update CSIT tests 161218 -> rls1701-170115
- update of CSIT operational branch to be used for VPP-patch test

Change-Id: I00c83fa1db7006f600207306d320628ed3075854
Signed-off-by: Jan Gelety <jgelety@cisco.com>
2017-01-17 17:45:12 +01:00
Neale Ranns
df44cc846f DHCPv6 Proxy; fix crash when DHCPv6 prxy is not configured and client packet is received
Change-Id: I0250acdee803545b8923549e2099863a95544691
Signed-off-by: Neale Ranns <neale.ranns@cisco.com>
2017-01-16 19:23:11 +00:00
Neale Ranns
257d5e25bf Account for pool realloc when importing FIB entries during VRF export
Change-Id: I8ec6d53fa9c0790f85802663f70a6b3630239f8d
Signed-off-by: Neale Ranns <neale.ranns@cisco.com>
2017-01-10 18:13:41 +01:00
Neale Ranns
bf2fcad04a Fix ARP on unnumbered interfaces (VPP-583)
Change-Id: Iea1e2c31c016c3bb6344f73173d082a2c548ffee
Signed-off-by: Neale Ranns <neale.ranns@cisco.com>
2017-01-09 20:58:37 +00:00
Neale Ranns
2d7e16330f Fix disable ip6 interface (VPP-584)
Change-Id: I73e966f9afe866e7215fc2e57daecc4531381d92
Signed-off-by: Neale Ranns <neale.ranns@cisco.com>
2017-01-09 15:27:55 +01:00
Eyal Bari
ee85bfabc9 Added basic tests for multicast vxlan tunnels
unicast flood test - test headend replication
multicast flood test - test flooding when a multicast vxlan tunnel is present in BD
multicast receive test - verify that multicast packet are received on their
   corresponding unicast tunnels and that unmatched packets are dropped

all tests run after adding and removing 200 mcast tunnels to test stability

Change-Id: Ia05108c39ac35096a5b633cf52480a9ba87c14df
Signed-off-by: Eyal Bari <ebari@cisco.com>
(cherry picked from commit c4aaee11468aa5ed7af01d0747d912493cff002d)
2017-01-08 21:07:20 +00:00
Dave Barach
b95a916dc3 Fix uninitialized stack local, VPP-581
Sporadically messes up the client message allocation ring, by setting
c->message_bounce[msg_id] non-zero. A day-1 bug, made blatantly
obvious by the python API language binding for no particular reason.

Change-Id: I11084dd884622e7b44bdabb922466c4d07138235
Signed-off-by: Dave Barach <dave@barachs.net>
2017-01-05 10:04:30 -05:00
Neale Ranns
235c64f067 FIB memory leaks (VPP-578)
1) vec_free the fe_srcs of a fib_entry_t when the fib_entry_t is itself reed
2) in the load-balance fixup if a drop path is required add this to a new vector of next-hops 'fixed_nhs'. This vector is managed by the load-balance function. The caller continues to manage its own set. The function is now const implying that the caller is safe to assume the next-hops do not change.

Change-Id: I0f29203ee16b9a270f40edf237488fa99ba65320
Signed-off-by: Neale Ranns <nranns@cisco.com>
2017-01-04 18:36:46 +00:00
Eyal Bari
cdffe06bab vxlan fix mcast tunnel delete
Change-Id: I15f7ff1e957718e808bfad811895deaacb85d2a3
Signed-off-by: Eyal Bari <ebari@cisco.com>
2017-01-03 20:48:11 +01:00
Filip Tehlar
35dc387354 LISP: fix EID addition (VPP-577)
Change-Id: I32f61ab89598a7911df3d0d8f45de1302af8aa6a
Signed-off-by: Filip Tehlar <ftehlar@cisco.com>
2017-01-03 18:23:19 +00:00
Filip Tehlar
c48b58a216 LISP: fix fwd entry addition (VPP-576)
Change-Id: Ibdc9ad21cc53cf0a6d571a3f913038d61d9282a1
Signed-off-by: Filip Tehlar <ftehlar@cisco.com>
2017-01-03 18:23:11 +00:00
Andrew Yourtchenko
856ab8aca3 VPP-574: fix the MACIP ACLs blocking ARP traffic
The initial assumption was that the MACIP ACL classifier tables would be applied
after the classification of the traffic based on the ethertype, it turned out
to be untrue, but the fix in the code did not happen.

Add the ethertype to the mask, and the logic to create the ACL classifier tables
permitting the ARP ethertype with the correct payload.

Change-Id: I70236a8a723970c662ddaef6bc9fce93d2e630c1
Signed-off-by: Andrew Yourtchenko <ayourtch@gmail.com>
2017-01-03 15:48:39 +00:00
Andrew Yourtchenko
81c09d03d8 VPP-574: fix VPP hang during security group configuration on a suspended VM
The unix connect() in vhost-user driver in VPP is blocking, and
a non-expedient accept() on the other side causes the entire VPP to hang.

Solution: set the nonblocking flag for the socket fd before calling
connect(), and set the socket back to blocking after the accept() succeeds.

Change-Id: I2d535ea9b95a92922d305d79a8d860062c95faf4
Signed-off-by: Andrew Yourtchenko <ayourtch@gmail.com>
2017-01-03 15:15:27 +00:00
Matus Fabian
b4f2525866 SNAT: fix out2in ICMP worker lookup
Change-Id: Ifce17a450a06c26670d474b0f774f2504843f221
Signed-off-by: Matus Fabian <matfabia@cisco.com>
2017-01-03 05:07:54 -08:00
Vengada
800429ddef ioam: fix Coverity warning (VPP-570)
Fix Coverity warning of uninitialized variable.
Initialize outer_fib_index to zero (vxlan_gpe_test.c)

Change-Id: If39d48c3906784c43c5af3e9e01ed9a5d5631d6e
Signed-off-by: Vengada <venggovi@cisco.com>
2017-01-02 10:13:43 +00:00
AkshayaNadahalli
e4e9fbbb7c Merging all ioam plugin libraries to single library
Change-Id: I33a646ba45848c7400df4271e4933e28e62c9ad7
Signed-off-by: AkshayaNadahalli <anadahal@cisco.com>
2016-12-24 14:11:36 +00:00
Matus Fabian
fe7cdfa629 SNAT: fix 'show snat verbose' bug - format vector as %v
Change-Id: Ia829da43a273c89dee47b32250ab032d992193cd
Signed-off-by: Matus Fabian <matfabia@cisco.com>
2016-12-23 12:04:26 +00:00
Matus Fabian
e73d0a3aab SNAT: Remove the oldest translation fix (VPP-568)
Fixed bug and add test.

Change-Id: I60fbec48abd9d9cb86be1bd1cdbb7d16f9f93c3e
Signed-off-by: Matus Fabian <matfabia@cisco.com>
2016-12-22 02:46:27 -08:00
Damjan Marion
436b319354 Change default branch in .gitreview
Change-Id: I061e4e59698407c9f96930d578cafd552c717861
Signed-off-by: Damjan Marion <damarion@cisco.com>
2016-12-21 19:01:43 +01:00
47 changed files with 914 additions and 425 deletions

View File

@ -2,3 +2,4 @@
host=gerrit.fd.io
port=29418
project=vpp
defaultbranch=stable/1701

View File

@ -7,14 +7,85 @@
@page release_notes_1701 Release notes for VPP 17.01
@note This release was for a while known as 16.12.
@todo Release 17.01 needs release notes.
## Features
- [Integrated November 2016 DPDK release](http://www.dpdk.org/doc/guides/rel_notes/release_16_11.html)
- Complete rework of Forwarding Information Base (FIB)
- Performance Improvements
- Improvements in DPDK input and output nodes
- Improvements in L2 path
- Improvmeents in IPv4 lookup node
- Feature Arcs Improvements
- Consolidation of the code
- New feature arcs
- device-input
- interface-output
- DPDK Cryptodev Support
- Software and Hardware Crypto Support
- DPDK HQoS support
- Simple Port Analyzer (SPAN)
- Bidirectional Forwarding Detection
- Basic implementation
- IPFIX Improvements
- L2 GRE over IPSec tunnels
- Link Layer Discovery Protocol (LLDP)
- Vhost-user Improvements
- Performance Improvements
- Multiqueue
- Reconnect
- LISP Enhancements
- Source/Dest control plane support
- L2 over LISP and GRE
- Map-Register/Map-Notify/RLOC-probing support
- L2 API improvements, overall code hardening
- Plugins:
- New: ACL
- New: Flow per Packet
- Improved: SNAT
- Mutlithreading
- Flow export
- Doxygen Enhancements
- Luajit API bindings
- API Refactoring
- file split
- message signatures
- Python and Scapy based unit testing infrastructure
- Infrastructure
- Various tests
- Packet Generator improvements
- TUN/TAP jumbo frames support
- Other various bug fixes and improvements
## Known issues
For the full list of issues please reffer to fd.io [JIRA](https://jira.fd.io).
## Issues fixed
For the full list of fixed issues please reffer to:
- fd.io [JIRA](https://jira.fd.io)
- git [commit log](https://git.fd.io/vpp/log/?h=stable/1701)
@page release_notes_1609 Release notes for VPP 16.09

View File

@ -0,0 +1,5 @@
#!/bin/sh -e
# after installing python-api files
python2_sitedir=$(python -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())")
easy_install --install-dir=$python2_sitedir -z $python2_sitedir/vpp_papi/vpp_papi-*.egg

View File

@ -0,0 +1,8 @@
#!/bin/sh -e
# before removing python-api files
python2_sitedir=$(python -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())")
easy_install --install-dir=$python2_sitedir -mxNq vpp_papi
# the egg has been copied during install
rm $python2_sitedir/vpp_papi-*.egg

View File

@ -1,2 +1,2 @@
#!/bin/sh
echo oper-161218
echo oper-rls1701-170115

View File

@ -50,5 +50,5 @@ fi
echo ${TAG}-${ADD}${CMT:+~${CMT}}${BLD}
fi
else
echo ${TAG}
echo ${TAG}-release
fi

View File

@ -1044,6 +1044,7 @@ typedef struct
u8 prefix_len;
u32 count;
u32 table_index;
u32 arp_table_index;
} macip_match_type_t;
static u32
@ -1127,6 +1128,34 @@ macip_create_classify_tables (acl_main_t * am, u32 macip_acl_index)
vec_sort_with_function (mvec, match_type_compare);
/* Create the classifier tables */
last_table = ~0;
/* First add ARP tables */
vec_foreach (mt, mvec)
{
int mask_len;
int is6 = mt->is_ipv6;
mt->arp_table_index = ~0;
if (!is6)
{
memset (mask, 0, sizeof (mask));
memcpy (&mask[6], mt->mac_mask, 6);
memset (&mask[12], 0xff, 2); /* ethernet protocol */
memcpy (&mask[14 + 8], mt->mac_mask, 6);
for (i = 0; i < (mt->prefix_len / 8); i++)
mask[14 + 14 + i] = 0xff;
if (mt->prefix_len % 8)
mask[14 + 14 + (mt->prefix_len / 8)] = 0xff - ((1 << (8 - mt->prefix_len % 8)) - 1);
mask_len = ((14 + 14 + ((mt->prefix_len+7) / 8) +
(sizeof (u32x4)-1))/sizeof(u32x4)) * sizeof (u32x4);
acl_classify_add_del_table_small (cm, mask, mask_len, last_table,
(~0 == last_table) ? 0 : ~0, &mt->arp_table_index,
1);
last_table = mt->arp_table_index;
}
}
/* Now add IP[46] tables */
vec_foreach (mt, mvec)
{
int mask_len;
@ -1167,13 +1196,18 @@ macip_create_classify_tables (acl_main_t * am, u32 macip_acl_index)
int l3_src_offs = get_l3_src_offset(is6);
memset (mask, 0, sizeof (mask));
memcpy (&mask[6], a->rules[i].src_mac, 6);
memset (&mask[12], 0xff, 2); /* ethernet protocol */
if (is6)
{
memcpy (&mask[l3_src_offs], &a->rules[i].src_ip_addr.ip6, 16);
mask[12] = 0x86;
mask[13] = 0xdd;
}
else
{
memcpy (&mask[l3_src_offs], &a->rules[i].src_ip_addr.ip4, 4);
mask[12] = 0x08;
mask[13] = 0x00;
}
match_type_index =
macip_find_match_type (mvec, a->rules[i].src_mac_mask,
@ -1183,6 +1217,19 @@ macip_create_classify_tables (acl_main_t * am, u32 macip_acl_index)
vnet_classify_add_del_session (cm, mvec[match_type_index].table_index,
mask, a->rules[i].is_permit ? ~0 : 0, i,
0, action, metadata, 1);
/* add ARP table entry too */
if (!is6 && (mvec[match_type_index].arp_table_index != ~0))
{
memset (mask, 0, sizeof (mask));
memcpy (&mask[6], a->rules[i].src_mac, 6);
mask[12] = 0x08;
mask[13] = 0x06;
memcpy (&mask[14 + 8], a->rules[i].src_mac, 6);
memcpy (&mask[14 + 14], &a->rules[i].src_ip_addr.ip4, 4);
vnet_classify_add_del_session (cm, mvec[match_type_index].arp_table_index,
mask, a->rules[i].is_permit ? ~0 : 0, i,
0, action, metadata, 1);
}
}
return 0;
}

View File

@ -1,4 +1,4 @@
AC_INIT(acl_plugin, 1.0)
AC_INIT(acl_plugin, 17.01)
AC_CONFIG_MACRO_DIR([../../vpp-api/java/m4])
LT_INIT
AM_INIT_AUTOMAKE

View File

@ -17,20 +17,8 @@ AM_CFLAGS = -Wall
AM_LDFLAGS = -module -shared -avoid-version
########################################
# iOAM Proof of Transit
# iOAM APIs
########################################
ioam_pot_plugin_la_SOURCES = \
ioam/lib-pot/pot_util.c \
ioam/encap/ip6_ioam_pot.c \
ioam/lib-pot/pot_util.h \
ioam/lib-pot/math64.h \
ioam/lib-pot/pot_api.c
BUILT_SOURCES = \
ioam/lib-pot/pot.api.h \
ioam/lib-pot/pot.api.json
SUFFIXES = .api.h .api
%.api.h: %.api
@ -39,129 +27,135 @@ SUFFIXES = .api.h .api
| vppapigen --input - --output $@ --show-name $@
%.api.json: %.api
@echo " JSON APIGEN " $@ ; \
@echo " JSON APIGEN " $@ ; \
mkdir -p `dirname $@` ; \
$(CC) $(CPPFLAGS) -E -P -C -x c $^ \
$(CC) $(CPPFLAGS) -E -P -C -x c $^ \
| vppapigen --input - --json $@
apidir = $(prefix)/ioam/
api_DATA = \
ioam/lib-pot/pot.api.json \
api_DATA = \
ioam/lib-pot/pot.api.json \
ioam/lib-trace/trace.api.json \
ioam/export/ioam_export.api.json
noinst_HEADERS = \
ioam/lib-pot/pot_all_api_h.h \
ioam/lib-pot/pot_msg_enum.h \
ioam/lib-pot/pot.api.h \
ioam/lib-pot/pot_util.h \
ioam/lib-pot/math64.h
########################################
# iOAM Proof of Transit
########################################
ioam_pot_test_plugin_la_SOURCES = \
IOAM_POT_SRC = \
ioam/lib-pot/pot_util.c \
ioam/encap/ip6_ioam_pot.c \
ioam/lib-pot/pot_util.h \
ioam/lib-pot/math64.h \
ioam/lib-pot/pot_api.c
IOAM_POT_BUILT_SRC = \
ioam/lib-pot/pot.api.h \
ioam/lib-pot/pot.api.json
IOAM_POT_NOINST_HDR = \
ioam/lib-pot/pot_all_api_h.h \
ioam/lib-pot/pot_msg_enum.h \
ioam/lib-pot/pot.api.h \
ioam/lib-pot/pot_util.h \
ioam/lib-pot/math64.h
ioam_pot_test_plugin_la_SOURCES = \
ioam/lib-pot/pot_test.c \
ioam/lib-pot/pot_plugin.api.h
vppapitestpluginsdir = ${libdir}/vpp_api_test_plugins
vpppluginsdir = ${libdir}/vpp_plugins
vppapitestplugins_LTLIBRARIES = ioam_pot_test_plugin.la
vppplugins_LTLIBRARIES = ioam_pot_plugin.la
########################################
# iOAM trace export for IPv6
########################################
ioam_export_plugin_la_SOURCES = \
ioam/export/ioam_export.c \
ioam/export/node.c \
ioam/export/ioam_export.api.h \
ioam/export/ioam_export_thread.c
IOAM_EXPORT_SRC = \
ioam/export/ioam_export.c \
ioam/export/node.c \
ioam/export/ioam_export.api.h \
ioam/export/ioam_export_thread.c
BUILT_SOURCES += \
IOAM_EXPORT_BUILT_SRC = \
ioam/export/ioam_export.api.h \
ioam/export/ioam_export.api.json
noinst_HEADERS += \
ioam/export/ioam_export_all_api_h.h \
ioam/export/ioam_export_msg_enum.h \
ioam/export/ioam_export.api.h
IOAM_EXPORT_NOINST_HDR = \
ioam/export/ioam_export_all_api_h.h \
ioam/export/ioam_export_msg_enum.h \
ioam/export/ioam_export.api.h
ioam_export_test_plugin_la_SOURCES = \
ioam/export/ioam_export_test.c \
ioam/export/ioam_export_plugin.api.h
ioam_export_test_plugin_la_SOURCES = \
ioam/export/ioam_export_test.c \
ioam/export/ioam_export_plugin.api.h
vppapitestplugins_LTLIBRARIES += ioam_export_test_plugin.la
vppplugins_LTLIBRARIES += ioam_export_plugin.la
########################################
# iOAM Trace
########################################
libioam_trace_plugin_la_SOURCES = \
IOAM_TRACE_SRC = \
ioam/lib-trace/trace_util.c \
ioam/encap/ip6_ioam_trace.c \
ioam/lib-trace/trace_util.h \
ioam/lib-trace/trace_api.c
BUILT_SOURCES += \
IOAM_TRACE_BUILT_SRC = \
ioam/lib-trace/trace.api.h \
ioam/lib-trace/trace.api.json
noinst_HEADERS += \
IOAM_TRACE_NOINST_HDR = \
ioam/export/ioam_export_all_api_h.h \
ioam/lib-trace/trace_all_api_h.h \
ioam/lib-trace/trace_msg_enum.h \
ioam/lib-trace/trace.api.h \
ioam/lib-trace/trace_all_api_h.h \
ioam/lib-trace/trace_msg_enum.h \
ioam/lib-trace/trace.api.h \
ioam/lib-trace/trace_util.h
ioam_trace_test_plugin_la_SOURCES = \
ioam/lib-trace/trace_test.c \
ioam/lib-trace/trace_test.c \
ioam/lib-trace/trace_plugin.api.h
vppapitestplugins_LTLIBRARIES += ioam_trace_test_plugin.la
vppplugins_LTLIBRARIES += libioam_trace_plugin.la
########################################
# VxLAN-GPE
########################################
libioam_vxlan_gpe_plugin_la_SOURCES = \
ioam/lib-vxlan-gpe/ioam_encap.c \
ioam/lib-vxlan-gpe/ioam_decap.c \
ioam/lib-vxlan-gpe/ioam_transit.c \
ioam/lib-vxlan-gpe/ioam_pop.c \
ioam/lib-vxlan-gpe/vxlan_gpe_api.c \
ioam/lib-vxlan-gpe/vxlan_gpe_ioam_trace.c \
ioam/lib-vxlan-gpe/vxlan_gpe_ioam.c \
ioam/export-vxlan-gpe/vxlan_gpe_ioam_export.c \
ioam/export-vxlan-gpe/vxlan_gpe_node.c \
ioam/export-vxlan-gpe/vxlan_gpe_ioam_export.api.h\
IOAM_VXLAN_GPE_SRC = \
ioam/lib-vxlan-gpe/ioam_encap.c \
ioam/lib-vxlan-gpe/ioam_decap.c \
ioam/lib-vxlan-gpe/ioam_transit.c \
ioam/lib-vxlan-gpe/ioam_pop.c \
ioam/lib-vxlan-gpe/vxlan_gpe_api.c \
ioam/lib-vxlan-gpe/vxlan_gpe_ioam_trace.c \
ioam/lib-vxlan-gpe/vxlan_gpe_ioam.c \
ioam/export-vxlan-gpe/vxlan_gpe_ioam_export.c \
ioam/export-vxlan-gpe/vxlan_gpe_node.c \
ioam/export-vxlan-gpe/vxlan_gpe_ioam_export.api.h \
ioam/export-vxlan-gpe/vxlan_gpe_ioam_export_thread.c
BUILT_SOURCES += \
ioam/lib-vxlan-gpe/vxlan_gpe.api.h \
ioam/lib-vxlan-gpe/vxlan_gpe.api.json \
IOAM_VXLAN_GPE_BUILT_SRC = \
ioam/lib-vxlan-gpe/vxlan_gpe.api.h \
ioam/lib-vxlan-gpe/vxlan_gpe.api.json \
ioam/export-vxlan-gpe/vxlan_gpe_ioam_export.api.h \
ioam/export-vxlan-gpe/vxlan_gpe_ioam_export.api.json
noinst_HEADERS += \
ioam/export/ioam_export_all_api_h.h \
ioam/lib-vxlan-gpe/vxlan_gpe_all_api_h.h \
ioam/lib-vxlan-gpe/vxlan_gpe_msg_enum.h \
ioam/lib-vxlan-gpe/vxlan_gpe.api.h \
ioam/lib-vxlan-gpe/vxlan_gpe_ioam_util.h \
ioam/lib-vxlan-gpe/vxlan_gpe_ioam_packet.h \
ioam/lib-vxlan-gpe/vxlan_gpe_ioam.h \
ioam/export-vxlan-gpe/vxlan_gpe_ioam_export_all_api_h.h \
ioam/export-vxlan-gpe/vxlan_gpe_ioam_export_msg_enum.h \
IOAM_VXLAN_GPE_NOINST_HDR = \
ioam/export/ioam_export_all_api_h.h \
ioam/lib-vxlan-gpe/vxlan_gpe_all_api_h.h \
ioam/lib-vxlan-gpe/vxlan_gpe_msg_enum.h \
ioam/lib-vxlan-gpe/vxlan_gpe.api.h \
ioam/lib-vxlan-gpe/vxlan_gpe_ioam_util.h \
ioam/lib-vxlan-gpe/vxlan_gpe_ioam_packet.h \
ioam/lib-vxlan-gpe/vxlan_gpe_ioam.h \
ioam/export-vxlan-gpe/vxlan_gpe_ioam_export_all_api_h.h \
ioam/export-vxlan-gpe/vxlan_gpe_ioam_export_msg_enum.h \
ioam/export-vxlan-gpe/vxlan_gpe_ioam_export.api.h
ioam_vxlan_gpe_test_plugin_la_SOURCES = \
ioam_vxlan_gpe_test_plugin_la_SOURCES = \
ioam/lib-vxlan-gpe/vxlan_gpe_test.c \
ioam/lib-vxlan-gpe/vxlan_gpe_plugin.api.h
libioam_vxlan_gpe_plugin_la_LIBADD = libioam_trace_plugin.la
vppapitestplugins_LTLIBRARIES += ioam_vxlan_gpe_test_plugin.la
vppplugins_LTLIBRARIES += libioam_vxlan_gpe_plugin.la
vxlan_gpe_ioam_export_test_plugin_la_SOURCES = \
ioam/export-vxlan-gpe/vxlan_gpe_ioam_export_test.c \
@ -170,26 +164,53 @@ vxlan_gpe_ioam_export_test_plugin_la_SOURCES = \
vppapitestplugins_LTLIBRARIES += vxlan_gpe_ioam_export_test_plugin.la
########################################
# iOAM E2E plugin
# iOAM E2E
########################################
ioam_e2e_plugin_la_SOURCES = \
IOAM_E2E_SRC = \
ioam/encap/ip6_ioam_e2e.c \
ioam/encap/ip6_ioam_seqno.c \
ioam/encap/ip6_ioam_seqno_analyse.c
noinst_HEADERS += \
ioam/encap/ip6_ioam_e2e.h \
IOAM_E2E_BUILT_SRC = \
ioam/encap/ip6_ioam_e2e.h \
ioam/encap/ip6_ioam_seqno.h
vppplugins_LTLIBRARIES += ioam_e2e_plugin.la
########################################
# iOAM plugins
########################################
vppapitestpluginsdir = ${libdir}/vpp_api_test_plugins
vpppluginsdir = ${libdir}/vpp_plugins
ioam_plugin_la_SOURCES = \
$(IOAM_POT_SRC) \
$(IOAM_EXPORT_SRC) \
$(IOAM_TRACE_SRC) \
$(IOAM_VXLAN_GPE_SRC) \
$(IOAM_E2E_SRC)
BUILT_SOURCES = \
$(IOAM_POT_BUILT_SRC) \
$(IOAM_EXPORT_BUILT_SRC) \
$(IOAM_TRACE_BUILT_SRC) \
$(IOAM_VXLAN_GPE_BUILT_SRC) \
$(IOAM_E2E_BUILT_SRC)
noinst_HEADERS = \
$(IOAM_POT_NOINST_HDR) \
$(IOAM_EXPORT_NOINST_HDR) \
$(IOAM_TRACE_NOINST_HDR) \
$(IOAM_VXLAN_GPE_NOINST_HDR) \
$(IOAM_E2E_NOINST_HDR)
vppplugins_LTLIBRARIES = ioam_plugin.la
# Remove *.la files
install-data-hook:
@(cd $(vpppluginsdir) && $(RM) $(vppplugins_LTLIBRARIES))
@(cd $(vppapitestpluginsdir) && $(RM) $(vppapitestplugins_LTLIBRARIES))
#
# Java code generation
#

View File

@ -1,4 +1,4 @@
AC_INIT(ioam_plugin, 1.0)
AC_INIT(ioam_plugin, 17.01)
LT_INIT
AC_CONFIG_MACRO_DIR([../../vpp-api/java/m4])
AM_INIT_AUTOMAKE

View File

@ -25,8 +25,6 @@
#include <vppinfra/elog.h>
#include <vnet/ip/ip6_hop_by_hop.h>
#include <vnet/plugin/plugin.h>
#include "ip6_ioam_e2e.h"
ioam_e2e_main_t ioam_e2e_main;
@ -166,23 +164,6 @@ VLIB_CLI_COMMAND (ioam_show_e2e_cmd, static) = {
.function = ioam_show_e2e_cmd_fn,
};
/*
* This routine exists to convince the vlib plugin framework that
* we haven't accidentally copied a random .dll into the plugin directory.
*
* Also collects global variable pointers passed from the vpp engine
*/
clib_error_t *
vlib_plugin_register (vlib_main_t * vm, vnet_plugin_handoff_t * h,
int from_early_init)
{
clib_error_t * error = 0;
ioam_e2e_main.vlib_main = vm;
ioam_e2e_main.vnet_main = h->vnet_main;
return error;
}
/*
* Init handler E2E headet handling.
* Init hanlder registers encap, decap, trace and Rewrite handlers.
@ -222,6 +203,9 @@ ioam_e2e_init (vlib_main_t * vm)
"HBH_OPTION_TYPE_IOAM_EDGE_TO_EDGE Flow handler failed"));
}
ioam_e2e_main.vlib_main = vm;
ioam_e2e_main.vnet_main = vnet_get_main();
return (0);
}

View File

@ -24,6 +24,7 @@
#include <vppinfra/hash.h>
#include <vppinfra/error.h>
#include <vppinfra/elog.h>
#include <vnet/plugin/plugin.h>
#include <ioam/lib-trace/trace_util.h>
@ -348,6 +349,18 @@ VLIB_CLI_COMMAND (ip6_show_ioam_trace_cmd, static) = {
};
/* *INDENT-ON* */
/*
* This routine exists to convince the vlib plugin framework that
* we haven't accidentally copied a random .dll into the plugin directory.
*
* Also collects global variable pointers passed from the vpp engine
*/
clib_error_t *
vlib_plugin_register (vlib_main_t * vm, vnet_plugin_handoff_t * h,
int from_early_init)
{
return 0;
}
static clib_error_t *
ip6_hop_by_hop_ioam_trace_init (vlib_main_t * vm)

View File

@ -76,7 +76,8 @@ typedef struct
ioam_export_main_t ioam_export_main;
ioam_export_main_t vxlan_gpe_ioam_export_main;
vlib_node_registration_t export_node;
extern vlib_node_registration_t export_node;
extern vlib_node_registration_t vxlan_export_node;
#define DEFAULT_EXPORT_SIZE (3 * CLIB_CACHE_LINE_BYTES)
/*

View File

@ -92,7 +92,7 @@ vxlan_gpe_ioam_export_enable_disable (ioam_export_main_t * em,
ip4_address_t * src_address)
{
vlib_main_t *vm = em->vlib_main;
u32 node_index = export_node.index;
u32 node_index = vxlan_export_node.index;
vlib_node_t *vxlan_gpe_decap_ioam_node = NULL;
if (is_disable == 0)

View File

@ -40,7 +40,7 @@ format_export_trace (u8 * s, va_list * args)
return s;
}
vlib_node_registration_t export_node;
vlib_node_registration_t vxlan_export_node;
#define foreach_export_error \
_(RECORDED, "Packets recorded for export")
@ -137,7 +137,7 @@ vxlan_gpe_export_node_fn (vlib_main_t * vm,
* Node for VXLAN-GPE export
*/
/* *INDENT-OFF* */
VLIB_REGISTER_NODE (export_node) =
VLIB_REGISTER_NODE (vxlan_export_node) =
{
.function = vxlan_gpe_export_node_fn,
.name = "vxlan-gpe-ioam-export",

View File

@ -81,26 +81,6 @@ do { \
#define foreach_ioam_export_plugin_api_msg \
_(IOAM_EXPORT_IP6_ENABLE_DISABLE, ioam_export_ip6_enable_disable)
/*
* This routine exists to convince the vlib plugin framework that
* we haven't accidentally copied a random .dll into the plugin directory.
*
* Also collects global variable pointers passed from the vpp engine
*/
clib_error_t *
vlib_plugin_register (vlib_main_t * vm, vnet_plugin_handoff_t * h,
int from_early_init)
{
ioam_export_main_t *em = &ioam_export_main;
clib_error_t *error = 0;
em->vlib_main = vm;
em->vnet_main = h->vnet_main;
return error;
}
/* Action function shared between message handler and debug CLI */
int
@ -250,6 +230,9 @@ ioam_export_init (vlib_main_t * vm)
u32 node_index = export_node.index;
vlib_node_t *ip6_hbyh_node = NULL;
em->vlib_main = vm;
em->vnet_main = vnet_get_main ();
name = format (0, "ioam_export_%08x%c", api_version, 0);
/* Ask for a correctly-sized block of API message decode slots */

View File

@ -213,26 +213,6 @@ static void vl_api_pot_profile_del_t_handler
REPLY_MACRO(VL_API_POT_PROFILE_DEL_REPLY);
}
/*
* This routine exists to convince the vlib plugin framework that
* we haven't accidentally copied a random .dll into the plugin directory.
*
* Also collects global variable pointers passed from the vpp engine
*/
clib_error_t *
vlib_plugin_register (vlib_main_t * vm, vnet_plugin_handoff_t * h,
int from_early_init)
{
pot_main_t * sm = &pot_main;
clib_error_t * error = 0;
sm->vlib_main = vm;
sm->vnet_main = h->vnet_main;
return error;
}
/* Set up the API message handling tables */
static clib_error_t *
pot_plugin_api_hookup (vlib_main_t *vm)
@ -273,6 +253,10 @@ static clib_error_t * pot_init (vlib_main_t * vm)
bzero(sm, sizeof(pot_main));
(void)pot_util_init();
sm->vlib_main = vm;
sm->vnet_main = vnet_get_main();
name = format (0, "ioam_pot_%08x%c", api_version, 0);
/* Ask for a correctly-sized block of API message decode slots */

View File

@ -165,25 +165,6 @@ static void vl_api_trace_profile_show_config_t_handler
}
}
/*
* This routine exists to convince the vlib plugin framework that
* we haven't accidentally copied a random .dll into the plugin directory.
*
* Also collects global variable pointers passed from the vpp engine
*/
clib_error_t *
vlib_plugin_register (vlib_main_t * vm, vnet_plugin_handoff_t * h,
int from_early_init)
{
trace_main_t *sm = &trace_main;
clib_error_t *error = 0;
sm->vlib_main = vm;
sm->vnet_main = h->vnet_main;
return error;
}
/* Set up the API message handling tables */
static clib_error_t *
trace_plugin_api_hookup (vlib_main_t * vm)
@ -225,6 +206,10 @@ trace_init (vlib_main_t * vm)
bzero (sm, sizeof (trace_main));
(void) trace_util_init ();
sm->vlib_main = vm;
sm->vnet_main = vnet_get_main ();
name = format (0, "ioam_trace_%08x%c", api_version, 0);
/* Ask for a correctly-sized block of API message decode slots */

View File

@ -284,28 +284,6 @@ static void vl_api_vxlan_gpe_ioam_transit_disable_t_handler
VXLAN_GPE_REPLY_MACRO (VL_API_VXLAN_GPE_IOAM_TRANSIT_DISABLE_REPLY);
}
/*
* This routine exists to convince the vlib plugin framework that
* we haven't accidentally copied a random .dll into the plugin directory.
*
* Also collects global variable pointers passed from the vpp engine
*/
clib_error_t *
vlib_plugin_register (vlib_main_t * vm, vnet_plugin_handoff_t * h,
int from_early_init)
{
vxlan_gpe_ioam_main_t *sm = &vxlan_gpe_ioam_main;
clib_error_t *error = 0;
sm->vlib_main = vm;
sm->vnet_main = h->vnet_main;
sm->unix_time_0 = (u32) time (0); /* Store starting time */
sm->vlib_time_0 = vlib_time_now (vm);
return error;
}
/* Set up the API message handling tables */
static clib_error_t *
vxlan_gpe_plugin_api_hookup (vlib_main_t * vm)
@ -337,6 +315,11 @@ vxlan_gpe_init (vlib_main_t * vm)
vlib_node_t *vxlan_gpe_decap_node = NULL;
uword next_node = 0;
sm->vlib_main = vm;
sm->vnet_main = vnet_get_main ();
sm->unix_time_0 = (u32) time (0); /* Store starting time */
sm->vlib_time_0 = vlib_time_now (vm);
name = format (0, "ioam_vxlan_gpe_%08x%c", api_version, 0);
/* Ask for a correctly-sized block of API message decode slots */

View File

@ -466,7 +466,7 @@ api_vxlan_gpe_ioam_transit_disable (vat_main_t * vam)
ip6_address_t local6;
u8 ipv4_set = 0, ipv6_set = 0;
u8 local_set = 0;
u32 outer_fib_index;
u32 outer_fib_index = 0;
f64 timeout;

View File

@ -1,4 +1,4 @@
AC_INIT(snat_plugin, 1.0)
AC_INIT(snat_plugin, 17.01)
AC_CONFIG_MACRO_DIR([../../vpp-api/java/m4])
AM_INIT_AUTOMAKE
AM_SILENT_RULES([yes])

View File

@ -203,7 +203,7 @@ static u32 slow_path (snat_main_t *sm, vlib_buffer_t *b0,
/* Get the session */
s = pool_elt_at_index (sm->per_thread_data[cpu_index].sessions,
session_index);
} while (!snat_is_session_static (s));
} while (snat_is_session_static (s));
/* Remove in2out, out2in keys */
kv0.key = s->in2out.as_u64;

View File

@ -872,6 +872,13 @@ snat_out2in_worker_handoff_fn (vlib_main_t * vm,
key0.port = udp0->dst_port;
key0.fib_index = rx_fib_index0;
if (PREDICT_FALSE(ip0->protocol == IP_PROTOCOL_ICMP))
{
icmp46_header_t * icmp0 = (icmp46_header_t *) udp0;
icmp_echo_header_t *echo0 = (icmp_echo_header_t *)(icmp0+1);
key0.port = echo0->identifier;
}
kv0.key = key0.as_u64;
/* Ever heard of of the "user" before? */

View File

@ -974,13 +974,13 @@ vl_api_snat_show_config_t_handler
REPLY_MACRO2(VL_API_SNAT_SHOW_CONFIG_REPLY,
({
rmp->translation_buckets = htons (sm->translation_buckets);
rmp->translation_memory_size = htons (sm->translation_memory_size);
rmp->user_buckets = htons (sm->user_buckets);
rmp->user_memory_size = htons (sm->user_memory_size);
rmp->max_translations_per_user = htons (sm->max_translations_per_user);
rmp->outside_vrf_id = htons (sm->outside_vrf_id);
rmp->inside_vrf_id = htons (sm->inside_vrf_id);
rmp->translation_buckets = htonl (sm->translation_buckets);
rmp->translation_memory_size = htonl (sm->translation_memory_size);
rmp->user_buckets = htonl (sm->user_buckets);
rmp->user_memory_size = htonl (sm->user_memory_size);
rmp->max_translations_per_user = htonl (sm->max_translations_per_user);
rmp->outside_vrf_id = htonl (sm->outside_vrf_id);
rmp->inside_vrf_id = htonl (sm->inside_vrf_id);
rmp->static_mapping_only = sm->static_mapping_only;
rmp->static_mapping_connection_tracking =
sm->static_mapping_connection_tracking;
@ -1860,7 +1860,7 @@ show_snat_command_fn (vlib_main_t * vm,
({
s = format (s, " %d", j);
}));
vlib_cli_output (vm, " %d busy ports:%s", ap->busy_ports, s);
vlib_cli_output (vm, " %d busy ports:%v", ap->busy_ports, s);
}
}
@ -1873,7 +1873,7 @@ show_snat_command_fn (vlib_main_t * vm,
{
vlib_worker_thread_t *w =
vlib_worker_threads + *worker + sm->first_worker_index;
vlib_cli_output (vm, " %s", w->name);
vlib_cli_output (vm, " %v", w->name);
}
}
}
@ -1924,7 +1924,7 @@ show_snat_command_fn (vlib_main_t * vm,
continue;
vlib_worker_thread_t *w = vlib_worker_threads + j;
vlib_cli_output (vm, "Thread %d (%s at lcore %u):", j, w->name,
vlib_cli_output (vm, "Thread %d (%v at lcore %u):", j, w->name,
w->lcore_id);
vlib_cli_output (vm, " %d list pool elements",
pool_elts (tsm->list_pool));

View File

@ -11,23 +11,28 @@ class BridgeDomain(object):
__metaclass__ = ABCMeta
@property
def frame_pg0_to_pg1(self):
""" Ethernet frame sent from pg0 and expected to arrive at pg1 """
def frame_request(self):
""" Ethernet frame modeling a generic request """
return (Ether(src='00:00:00:00:00:01', dst='00:00:00:00:00:02') /
IP(src='1.2.3.4', dst='4.3.2.1') /
UDP(sport=10000, dport=20000) /
Raw('\xa5' * 100))
@property
def frame_pg1_to_pg0(self):
""" Ethernet frame sent from pg1 and expected to arrive at pg0 """
def frame_reply(self):
""" Ethernet frame modeling a generic reply """
return (Ether(src='00:00:00:00:00:02', dst='00:00:00:00:00:01') /
IP(src='4.3.2.1', dst='1.2.3.4') /
UDP(sport=20000, dport=10000) /
Raw('\xa5' * 100))
@abstractmethod
def encapsulate(self, pkt):
def encap_mcast(self, pkt, src_ip, src_mac, vni):
""" Encapsulate mcast packet """
pass
@abstractmethod
def encapsulate(self, pkt, vni):
""" Encapsulate packet """
pass
@ -37,17 +42,30 @@ class BridgeDomain(object):
pass
@abstractmethod
def check_encapsulation(self, pkt):
def check_encapsulation(self, pkt, vni, local_only=False):
""" Verify the encapsulation """
pass
def assert_eq_pkts(self, pkt1, pkt2):
""" Verify the Ether, IP, UDP, payload are equal in both
packets
"""
self.assertEqual(pkt1[Ether].src, pkt2[Ether].src)
self.assertEqual(pkt1[Ether].dst, pkt2[Ether].dst)
self.assertEqual(pkt1[IP].src, pkt2[IP].src)
self.assertEqual(pkt1[IP].dst, pkt2[IP].dst)
self.assertEqual(pkt1[UDP].sport, pkt2[UDP].sport)
self.assertEqual(pkt1[UDP].dport, pkt2[UDP].dport)
self.assertEqual(pkt1[Raw], pkt2[Raw])
def test_decap(self):
""" Decapsulation test
Send encapsulated frames from pg0
Verify receipt of decapsulated frames on pg1
"""
encapsulated_pkt = self.encapsulate(self.frame_pg0_to_pg1)
encapsulated_pkt = self.encapsulate(self.frame_request,
self.single_tunnel_bd)
self.pg0.add_stream([encapsulated_pkt, ])
@ -61,22 +79,14 @@ class BridgeDomain(object):
'Invalid number of packets on '
'output: {}'.format(len(out)))
pkt = out[0]
# TODO: add error messages
self.assertEqual(pkt[Ether].src, self.frame_pg0_to_pg1[Ether].src)
self.assertEqual(pkt[Ether].dst, self.frame_pg0_to_pg1[Ether].dst)
self.assertEqual(pkt[IP].src, self.frame_pg0_to_pg1[IP].src)
self.assertEqual(pkt[IP].dst, self.frame_pg0_to_pg1[IP].dst)
self.assertEqual(pkt[UDP].sport, self.frame_pg0_to_pg1[UDP].sport)
self.assertEqual(pkt[UDP].dport, self.frame_pg0_to_pg1[UDP].dport)
self.assertEqual(pkt[Raw], self.frame_pg0_to_pg1[Raw])
self.assert_eq_pkts(pkt, self.frame_request)
def test_encap(self):
""" Encapsulation test
Send frames from pg1
Verify receipt of encapsulated frames on pg0
"""
self.pg1.add_stream([self.frame_pg1_to_pg0])
self.pg1.add_stream([self.frame_reply])
self.pg0.enable_capture()
@ -88,14 +98,77 @@ class BridgeDomain(object):
'Invalid number of packets on '
'output: {}'.format(len(out)))
pkt = out[0]
self.check_encapsulation(pkt)
self.check_encapsulation(pkt, self.single_tunnel_bd)
payload = self.decapsulate(pkt)
# TODO: add error messages
self.assertEqual(payload[Ether].src, self.frame_pg1_to_pg0[Ether].src)
self.assertEqual(payload[Ether].dst, self.frame_pg1_to_pg0[Ether].dst)
self.assertEqual(payload[IP].src, self.frame_pg1_to_pg0[IP].src)
self.assertEqual(payload[IP].dst, self.frame_pg1_to_pg0[IP].dst)
self.assertEqual(payload[UDP].sport, self.frame_pg1_to_pg0[UDP].sport)
self.assertEqual(payload[UDP].dport, self.frame_pg1_to_pg0[UDP].dport)
self.assertEqual(payload[Raw], self.frame_pg1_to_pg0[Raw])
self.assert_eq_pkts(payload, self.frame_reply)
def test_ucast_flood(self):
""" Unicast flood test
Send frames from pg3
Verify receipt of encapsulated frames on pg0
"""
self.pg3.add_stream([self.frame_reply])
self.pg0.enable_capture()
self.pg_start()
# Get packet from each tunnel and assert it's corectly encapsulated.
out = self.pg0.get_capture()
self.assertEqual(len(out), 10,
'Invalid number of packets on '
'output: {}'.format(len(out)))
for pkt in out:
self.check_encapsulation(pkt, self.ucast_flood_bd, True)
payload = self.decapsulate(pkt)
self.assert_eq_pkts(payload, self.frame_reply)
def test_mcast_flood(self):
""" Multicast flood test
Send frames from pg2
Verify receipt of encapsulated frames on pg0
"""
self.pg2.add_stream([self.frame_reply])
self.pg0.enable_capture()
self.pg_start()
# Pick first received frame and check if it's corectly encapsulated.
out = self.pg0.get_capture()
self.assertEqual(len(out), 1,
'Invalid number of packets on '
'output: {}'.format(len(out)))
pkt = out[0]
self.check_encapsulation(pkt, self.mcast_flood_bd, True)
payload = self.decapsulate(pkt)
self.assert_eq_pkts(payload, self.frame_reply)
@staticmethod
def ipn_to_ip(ipn):
return '.'.join(str(i) for i in bytearray(ipn))
def test_mcast_rcv(self):
""" Multicast receive test
Send 20 encapsulated frames from pg0 only 10 match unicast tunnels
Verify receipt of 10 decap frames on pg2
"""
mac = self.pg0.remote_mac
ip_range_start = 10
ip_range_end = 30
mcast_stream = [
self.encap_mcast(self.frame_request, self.ipn_to_ip(ip), mac,
self.mcast_flood_bd)
for ip in self.ip4_range(self.pg0.remote_ip4n,
ip_range_start, ip_range_end)]
self.pg0.add_stream(mcast_stream)
self.pg2.enable_capture()
self.pg_start()
out = self.pg2.get_capture()
self.assertEqual(len(out), 10,
'Invalid number of packets on '
'output: {}'.format(len(out)))
for pkt in out:
self.assert_eq_pkts(pkt, self.frame_request)

View File

@ -589,6 +589,33 @@ class TestSNAT(VppTestCase):
self.logger.error(ppp("Unexpected or invalid packet:"), p)
raise
def test_max_translations_per_user(self):
""" MAX translations per user - recycle the least recently used """
self.snat_add_address(self.snat_addr)
self.vapi.snat_interface_add_del_feature(self.pg0.sw_if_index)
self.vapi.snat_interface_add_del_feature(self.pg1.sw_if_index,
is_inside=0)
# get maximum number of translations per user
snat_config = self.vapi.snat_show_config()
# send more than maximum number of translations per user packets
pkts_num = snat_config.max_translations_per_user + 5
pkts = []
for port in range(0, pkts_num):
p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
TCP(sport=1025 + port))
pkts.append(p)
self.pg0.add_stream(pkts)
self.pg_enable_capture(self.pg_interfaces)
self.pg_start()
# verify number of translated packet
capture = self.pg1.get_capture()
self.assertEqual(pkts_num, len(capture))
def tearDown(self):
super(TestSNAT, self).tearDown()
if not self.vpp_dead:

View File

@ -1,5 +1,6 @@
#!/usr/bin/env python
import socket
import unittest
from framework import VppTestCase, VppTestRunner
from template_bd import BridgeDomain
@ -7,6 +8,7 @@ from template_bd import BridgeDomain
from scapy.layers.l2 import Ether
from scapy.layers.inet import IP, UDP
from scapy.layers.vxlan import VXLAN
from scapy.utils import atol
class TestVxlan(BridgeDomain, VppTestCase):
@ -16,7 +18,7 @@ class TestVxlan(BridgeDomain, VppTestCase):
BridgeDomain.__init__(self)
VppTestCase.__init__(self, *args)
def encapsulate(self, pkt):
def encapsulate(self, pkt, vni):
"""
Encapsulate the original payload frame by adding VXLAN header with its
UDP, IP and Ethernet fields
@ -24,7 +26,18 @@ class TestVxlan(BridgeDomain, VppTestCase):
return (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4) /
UDP(sport=self.dport, dport=self.dport, chksum=0) /
VXLAN(vni=self.vni, flags=self.flags) /
VXLAN(vni=vni, flags=self.flags) /
pkt)
def encap_mcast(self, pkt, src_ip, src_mac, vni):
"""
Encapsulate the original payload frame by adding VXLAN header with its
UDP, IP and Ethernet fields
"""
return (Ether(src=src_mac, dst=self.mcast_mac4) /
IP(src=src_ip, dst=self.mcast_ip4) /
UDP(sport=self.dport, dport=self.dport, chksum=0) /
VXLAN(vni=vni, flags=self.flags) /
pkt)
def decapsulate(self, pkt):
@ -37,21 +50,66 @@ class TestVxlan(BridgeDomain, VppTestCase):
# Method for checking VXLAN encapsulation.
#
def check_encapsulation(self, pkt):
def check_encapsulation(self, pkt, vni, local_only=False):
# TODO: add error messages
# Verify source MAC is VPP_MAC and destination MAC is MY_MAC resolved
# by VPP using ARP.
self.assertEqual(pkt[Ether].src, self.pg0.local_mac)
self.assertEqual(pkt[Ether].dst, self.pg0.remote_mac)
if not local_only:
self.assertEqual(pkt[Ether].dst, self.pg0.remote_mac)
# Verify VXLAN tunnel source IP is VPP_IP and destination IP is MY_IP.
self.assertEqual(pkt[IP].src, self.pg0.local_ip4)
self.assertEqual(pkt[IP].dst, self.pg0.remote_ip4)
if not local_only:
self.assertEqual(pkt[IP].dst, self.pg0.remote_ip4)
# Verify UDP destination port is VXLAN 4789, source UDP port could be
# arbitrary.
self.assertEqual(pkt[UDP].dport, type(self).dport)
# TODO: checksum check
# Verify VNI, based on configuration it must be 1.
self.assertEqual(pkt[VXLAN].vni, type(self).vni)
# Verify VNI
self.assertEqual(pkt[VXLAN].vni, vni)
@staticmethod
def ip4_range(ip4n, s=10, e=20):
base = str(bytearray(ip4n)[:3])
return ((base + ip) for ip in str(bytearray(range(s, e))))
@classmethod
def create_vxlan_flood_test_bd(cls, vni):
# Create 10 ucast vxlan tunnels under bd
ip_range_start = 10
ip_range_end = 20
next_hop_address = cls.pg0.remote_ip4n
for dest_addr in cls.ip4_range(next_hop_address, ip_range_start,
ip_range_end):
# add host route so dest_addr will not be resolved
cls.vapi.ip_add_del_route(dest_addr, 32, next_hop_address)
r = cls.vapi.vxlan_add_del_tunnel(
src_addr=cls.pg0.local_ip4n,
dst_addr=dest_addr,
vni=vni)
cls.vapi.sw_interface_set_l2_bridge(r.sw_if_index, bd_id=vni)
@classmethod
def add_del_mcast_load(cls, is_add):
ip_range_start = 10
ip_range_end = 210
for dest_addr in cls.ip4_range(cls.mcast_ip4n, ip_range_start,
ip_range_end):
vni = bytearray(dest_addr)[3]
cls.vapi.vxlan_add_del_tunnel(
src_addr=cls.pg0.local_ip4n,
dst_addr=dest_addr,
mcast_sw_if_index=1,
vni=vni,
is_add=is_add)
@classmethod
def add_mcast_load(cls):
cls.add_del_mcast_load(is_add=1)
@classmethod
def del_mcast_load(cls):
cls.add_del_mcast_load(is_add=0)
# Class method to start the VXLAN test case.
# Overrides setUpClass method in VppTestCase class.
@ -65,12 +123,11 @@ class TestVxlan(BridgeDomain, VppTestCase):
try:
cls.dport = 4789
cls.flags = 0x8
cls.vni = 1
# Create 2 pg interfaces.
cls.create_pg_interfaces(range(2))
cls.pg0.admin_up()
cls.pg1.admin_up()
cls.create_pg_interfaces(range(4))
for pg in cls.pg_interfaces:
pg.admin_up()
# Configure IPv4 addresses on VPP pg0.
cls.pg0.config_ip4()
@ -78,14 +135,47 @@ class TestVxlan(BridgeDomain, VppTestCase):
# Resolve MAC address for VPP's IP address on pg0.
cls.pg0.resolve_arp()
# Our Multicast address
cls.mcast_ip4 = '239.1.1.1'
cls.mcast_ip4n = socket.inet_pton(socket.AF_INET, cls.mcast_ip4)
iplong = atol(cls.mcast_ip4)
cls.mcast_mac4 = "01:00:5e:%02x:%02x:%02x" % (
(iplong >> 16) & 0x7F, (iplong >> 8) & 0xFF, iplong & 0xFF)
# Create VXLAN VTEP on VPP pg0, and put vxlan_tunnel0 and pg1
# into BD.
cls.single_tunnel_bd = 1
r = cls.vapi.vxlan_add_del_tunnel(
src_addr=cls.pg0.local_ip4n,
dst_addr=cls.pg0.remote_ip4n,
vni=cls.vni)
cls.vapi.sw_interface_set_l2_bridge(r.sw_if_index, bd_id=1)
cls.vapi.sw_interface_set_l2_bridge(cls.pg1.sw_if_index, bd_id=1)
vni=cls.single_tunnel_bd)
cls.vapi.sw_interface_set_l2_bridge(r.sw_if_index,
bd_id=cls.single_tunnel_bd)
cls.vapi.sw_interface_set_l2_bridge(cls.pg1.sw_if_index,
bd_id=cls.single_tunnel_bd)
# Setup vni 2 to test multicast flooding
cls.mcast_flood_bd = 2
cls.create_vxlan_flood_test_bd(cls.mcast_flood_bd)
r = cls.vapi.vxlan_add_del_tunnel(
src_addr=cls.pg0.local_ip4n,
dst_addr=cls.mcast_ip4n,
mcast_sw_if_index=1,
vni=cls.mcast_flood_bd)
cls.vapi.sw_interface_set_l2_bridge(r.sw_if_index,
bd_id=cls.mcast_flood_bd)
cls.vapi.sw_interface_set_l2_bridge(cls.pg2.sw_if_index,
bd_id=cls.mcast_flood_bd)
# Add and delete mcast tunnels to check stability
cls.add_mcast_load()
cls.del_mcast_load()
# Setup vni 3 to test unicast flooding
cls.ucast_flood_bd = 3
cls.create_vxlan_flood_test_bd(cls.ucast_flood_bd)
cls.vapi.sw_interface_set_l2_bridge(cls.pg3.sw_if_index,
bd_id=cls.ucast_flood_bd)
except Exception:
super(TestVxlan, cls).tearDownClass()
raise
@ -97,6 +187,9 @@ class TestVxlan(BridgeDomain, VppTestCase):
super(TestVxlan, self).tearDown()
if not self.vpp_dead:
self.logger.info(self.vapi.cli("show bridge-domain 1 detail"))
self.logger.info(self.vapi.cli("show bridge-domain 2 detail"))
self.logger.info(self.vapi.cli("show bridge-domain 3 detail"))
self.logger.info(self.vapi.cli("show vxlan tunnel"))
if __name__ == '__main__':

View File

@ -842,6 +842,12 @@ class VppPapiProvider(object):
"""
return self.api(self.papi.snat_static_mapping_dump, {})
def snat_show_config(self):
"""Show S-NAT config
:return: S-NAT config parameters
"""
return self.api(self.papi.snat_show_config, {})
def control_ping(self):
self.api(self.papi.control_ping)

View File

@ -691,6 +691,8 @@ vl_msg_api_set_handlers (int id, char *name, void *handler, void *cleanup,
vl_msg_api_msg_config_t cfg;
vl_msg_api_msg_config_t *c = &cfg;
memset (c, 0, sizeof (*c));
c->id = id;
c->name = name;
c->handler = handler;

View File

@ -347,6 +347,8 @@ memory_api_init (char *region_name)
vl_msg_api_msg_config_t cfg;
vl_msg_api_msg_config_t *c = &cfg;
memset (c, 0, sizeof (*c));
if ((rv = vl_map_shmem (region_name, 1 /* is_vlib */ )) < 0)
return rv;
@ -360,6 +362,7 @@ memory_api_init (char *region_name)
c->size = sizeof(vl_api_##n##_t); \
c->traced = 1; /* trace, so these msgs print */ \
c->replay = 0; /* don't replay client create/delete msgs */ \
c->message_bounce = 0; /* don't bounce this message */ \
vl_msg_api_config(c);} while (0);
foreach_vlib_api_msg;

Some files were not shown because too many files have changed in this diff Show More