Compare commits
70 Commits
master
...
stable/181
Author | SHA1 | Date | |
---|---|---|---|
|
cce845e371 | ||
|
c2f8265c1d | ||
|
1161ddaa6f | ||
|
fe18c808e2 | ||
|
a6562a22e4 | ||
|
43e7d25d9f | ||
|
0f867653e4 | ||
|
a0005702c9 | ||
|
3d09e9992d | ||
|
ca561dffe1 | ||
|
1dd1a77cfd | ||
|
a867edfb6b | ||
|
13f5dcf915 | ||
|
9858d374ad | ||
|
69a9fc053d | ||
|
a8e3001e68 | ||
|
55670421c8 | ||
|
4d1f9564da | ||
|
e351f35019 | ||
|
c90a2aa0f1 | ||
|
ad5f2de904 | ||
|
00adcceaf0 | ||
|
277681ebfd | ||
|
0858497cee | ||
|
9e182dcaca | ||
|
1d403abe1b | ||
|
45ed202905 | ||
|
6ff8790c92 | ||
|
06eaab0ea8 | ||
|
12806a3cf0 | ||
|
d23f37eeaf | ||
|
c92341d5c6 | ||
|
975b4b1f7a | ||
|
64c5a5c656 | ||
|
3a9a6f72d1 | ||
|
78d828eff3 | ||
|
9734c0a494 | ||
|
6a7103de93 | ||
|
c8f3638bea | ||
|
79e4bc2d15 | ||
|
23064dd22a | ||
|
9a1e6eafd6 | ||
|
703ee73dfb | ||
|
e1fe33d890 | ||
|
dc532e4ff7 | ||
|
c10c73ffb3 | ||
|
0d87894bf2 | ||
|
44c6e1d188 | ||
|
44c6ca6038 | ||
|
f1a1a4dbfc | ||
|
b3aff922ff | ||
|
7d76878ab3 | ||
|
84112dd4f9 | ||
|
d6a0d0e206 | ||
|
347c523c23 | ||
|
3d29e83112 | ||
|
051984c6a1 | ||
|
6a86ca9627 | ||
|
795539326b | ||
|
02a60e01a7 | ||
|
9a5f9c9a43 | ||
|
9864f87b1b | ||
|
125760947a | ||
|
0d222f88ed | ||
|
713322bd32 | ||
|
33f276e0af | ||
|
7212e61d92 | ||
|
376414f4c3 | ||
|
5551e41f78 | ||
|
90395743d3 |
@ -2,3 +2,4 @@
|
||||
host=gerrit.fd.io
|
||||
port=29418
|
||||
project=vpp
|
||||
defaultbranch=stable/1810
|
||||
|
19
Makefile
19
Makefile
@ -131,22 +131,21 @@ RPM_SUSE_PLATFORM_DEPS = distribution-release shadow rpm-build
|
||||
|
||||
ifeq ($(OS_ID),opensuse)
|
||||
ifeq ($(SUSE_NAME),Tumbleweed)
|
||||
RPM_SUSE_DEVEL_DEPS = libboost_headers-devel libboost_thread-devel gcc
|
||||
RPM_SUSE_DEVEL_DEPS = libboost_headers1_68_0-devel-1.68.0 libboost_thread1_68_0-devel-1.68.0 gcc
|
||||
RPM_SUSE_PYTHON_DEPS += python2-ply python2-virtualenv
|
||||
endif
|
||||
ifeq ($(SUSE_ID),15.0)
|
||||
RPM_SUSE_DEVEL_DEPS = libboost_headers-devel libboost_thread-devel gcc6
|
||||
RPM_SUSE_PYTHON_DEPS += python2-ply python2-virtualenv
|
||||
else
|
||||
RPM_SUSE_DEVEL_DEPS += boost_1_61-devel gcc6
|
||||
RPM_SUSE_DEVEL_DEPS += libboost_headers1_68_0-devel-1.68.0 gcc6
|
||||
RPM_SUSE_PYTHON_DEPS += python-virtualenv
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(OS_ID),opensuse-leap)
|
||||
ifeq ($(SUSE_ID),15.0)
|
||||
RPM_SUSE_DEVEL_DEPS = libboost_headers-devel libboost_thread-devel gcc6
|
||||
RPM_SUSE_PYTHON_DEPS += python2-ply python2-virtualenv
|
||||
RPM_SUSE_DEVEL_DEPS = libboost_headers-devel libboost_thread-devel gcc
|
||||
RPM_SUSE_PYTHON_DEPS += python3-ply python2-virtualenv
|
||||
endif
|
||||
endif
|
||||
|
||||
@ -296,8 +295,12 @@ endif
|
||||
@sudo -E apt-get update
|
||||
@sudo -E apt-get $(APT_ARGS) $(CONFIRM) $(FORCE) install $(DEB_DEPENDS)
|
||||
else ifneq ("$(wildcard /etc/redhat-release)","")
|
||||
@sudo -E yum groupinstall $(CONFIRM) $(RPM_DEPENDS_GROUPS)
|
||||
ifeq ($(OS_ID),rhel)
|
||||
@sudo -E yum-config-manager --enable rhel-server-rhscl-7-rpms
|
||||
else ifeq ($(OS_ID),centos)
|
||||
@sudo -E yum install $(CONFIRM) centos-release-scl-rh
|
||||
endif
|
||||
@sudo -E yum groupinstall $(CONFIRM) $(RPM_DEPENDS_GROUPS)
|
||||
@sudo -E yum install $(CONFIRM) $(RPM_DEPENDS)
|
||||
@sudo -E debuginfo-install $(CONFIRM) glibc openssl-libs mbedtls-devel zlib
|
||||
else ifeq ($(filter opensuse-tumbleweed,$(OS_ID)),$(OS_ID))
|
||||
@ -305,12 +308,12 @@ else ifeq ($(filter opensuse-tumbleweed,$(OS_ID)),$(OS_ID))
|
||||
@sudo -E zypper install -y $(RPM_SUSE_DEPENDS)
|
||||
else ifeq ($(filter opensuse-leap,$(OS_ID)),$(OS_ID))
|
||||
@sudo -E zypper refresh
|
||||
@sudo -E zypper install -y $(RPM_SUSE_DEPENDS)
|
||||
@sudo -E zypper install -y $(RPM_SUSE_DEPENDS)
|
||||
else ifeq ($(filter opensuse,$(OS_ID)),$(OS_ID))
|
||||
@sudo -E zypper refresh
|
||||
@sudo -E zypper install -y $(RPM_SUSE_DEPENDS)
|
||||
else
|
||||
$(error "This option currently works only on Ubuntu, Debian, Centos or openSUSE systems")
|
||||
$(error "This option currently works only on Ubuntu, Debian, RHEL, CentOS or openSUSE systems")
|
||||
endif
|
||||
|
||||
define make
|
||||
|
316
RELEASE.md
316
RELEASE.md
File diff suppressed because it is too large
Load Diff
@ -4,7 +4,6 @@ After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStartPre=-/bin/rm -f /dev/shm/db /dev/shm/global_vm /dev/shm/vpe-api
|
||||
ExecStartPre=-/sbin/modprobe uio_pci_generic
|
||||
ExecStart=/usr/bin/vpp -c /etc/vpp/startup.conf
|
||||
ExecStopPost=/bin/rm -f /dev/shm/db /dev/shm/global_vm /dev/shm/vpe-api
|
||||
|
@ -1,12 +1,11 @@
|
||||
description "vector packet processing engine"
|
||||
author "Cisco Systems, Inc <listname@cisco.com>"
|
||||
author "Cisco Systems, Inc <vpp-dev@lists.fd.io>"
|
||||
|
||||
manual
|
||||
|
||||
respawn
|
||||
|
||||
pre-start script
|
||||
rm -f /dev/shm/db /dev/shm/global_vm /dev/shm/vpe-api || true
|
||||
# should be there via dkms, but if not, start anyway
|
||||
modprobe uio_pci_generic || true
|
||||
end script
|
||||
|
2
build/external/Makefile
vendored
2
build/external/Makefile
vendored
@ -20,7 +20,7 @@ MAKE_ARGS ?= -j
|
||||
BUILD_DIR ?= $(CURDIR)/_build
|
||||
INSTALL_DIR ?= $(CURDIR)/_install
|
||||
PKG_VERSION ?= $(shell git describe --abbrev=0 | cut -d- -f1 | cut -dv -f2)
|
||||
PKG_SUFFIX ?= $(shell git log --oneline $$(git describe --abbrev=0).. . | wc -l)
|
||||
PKG_SUFFIX ?= $(shell git log --oneline v$(PKG_VERSION)-rc0.. . | wc -l)
|
||||
JOBS := $(if $(shell [ -f /proc/cpuinfo ] && head /proc/cpuinfo),\
|
||||
$(shell grep -c ^processor /proc/cpuinfo), 2)
|
||||
|
||||
|
@ -4,6 +4,8 @@ Test Framework Documentation {#test_framework_doc}
|
||||
PyDoc generated documentation for the "make test" framework is available for
|
||||
the following releases:
|
||||
|
||||
- [Test framework documentation for VPP 18.10](https://docs.fd.io/vpp/18.10/vpp_make_test/html)
|
||||
- [Test framework documentation for VPP 18.07](https://docs.fd.io/vpp/18.07/vpp_make_test/html)
|
||||
- [Test framework documentation for VPP 18.04](https://docs.fd.io/vpp/18.04/vpp_make_test/html)
|
||||
- [Test framework documentation for VPP 18.01](https://docs.fd.io/vpp/18.01/vpp_make_test/html)
|
||||
- [Test framework documentation for VPP 17.10](https://docs.fd.io/vpp/17.10/vpp_make_test/html)
|
||||
|
@ -34,7 +34,6 @@ import io.fd.vpp.jvpp.core.dto.ClassifyTableInfoReply;
|
||||
import io.fd.vpp.jvpp.core.dto.InputAclSetInterface;
|
||||
import io.fd.vpp.jvpp.core.dto.InputAclSetInterfaceReply;
|
||||
import io.fd.vpp.jvpp.core.future.FutureJVppCoreFacade;
|
||||
import javax.xml.bind.DatatypeConverter;
|
||||
|
||||
/**
|
||||
* <p>Tests L2 ACL creation and read.<br> Equivalent to the following vppctl commands:<br>
|
||||
@ -50,6 +49,8 @@ import javax.xml.bind.DatatypeConverter;
|
||||
public class L2AclExample {
|
||||
|
||||
private static final int LOCAL0_IFACE_ID = 0;
|
||||
private static final char[] hexArray = "0123456789ABCDEF".toCharArray();
|
||||
|
||||
|
||||
private static ClassifyAddDelTable createClassifyTable() {
|
||||
ClassifyAddDelTable request = new ClassifyAddDelTable();
|
||||
@ -67,6 +68,16 @@ public class L2AclExample {
|
||||
return request;
|
||||
}
|
||||
|
||||
private static String bytesToHex(byte[] bytes) {
|
||||
char[] hexChars = new char[bytes.length * 2];
|
||||
for ( int j = 0; j < bytes.length; j++ ) {
|
||||
int v = bytes[j] & 0xFF;
|
||||
hexChars[j * 2] = hexArray[v >>> 4];
|
||||
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
|
||||
}
|
||||
return new String(hexChars);
|
||||
}
|
||||
|
||||
private static ClassifyTableInfo createClassifyTableInfoRequest(final int tableId) {
|
||||
ClassifyTableInfo request = new ClassifyTableInfo();
|
||||
request.tableId = tableId;
|
||||
@ -120,7 +131,7 @@ public class L2AclExample {
|
||||
private static void print(final ClassifyTableInfoReply reply) {
|
||||
System.out.println(reply);
|
||||
if (reply != null) {
|
||||
System.out.println("Mask hex: " + DatatypeConverter.printHexBinary(reply.mask));
|
||||
System.out.println("Mask hex: " + bytesToHex(reply.mask));
|
||||
}
|
||||
}
|
||||
|
||||
@ -132,7 +143,7 @@ public class L2AclExample {
|
||||
System.out.println(reply);
|
||||
reply.classifySessionDetails.forEach(detail -> {
|
||||
System.out.println(detail);
|
||||
System.out.println("Match hex: " + DatatypeConverter.printHexBinary(detail.match));
|
||||
System.out.println("Match hex: " + bytesToHex(detail.match));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -392,7 +392,7 @@ fi
|
||||
/usr/share/java/*
|
||||
|
||||
%files api-python
|
||||
%defattr(644,root,root)
|
||||
%defattr(644,root,root,755)
|
||||
%{python2_sitelib}/vpp_*
|
||||
|
||||
%files selinux-policy
|
||||
|
@ -1,8 +1,8 @@
|
||||
#!/usr/bin/env python
|
||||
import os, fnmatch, subprocess
|
||||
|
||||
starttag = 'v18.07-rc0'
|
||||
endtag = 'v18.07'
|
||||
starttag = 'v18.10-rc0'
|
||||
endtag = 'v18.10'
|
||||
emit_md = True
|
||||
apifiles = []
|
||||
|
||||
|
@ -4091,12 +4091,12 @@ acl_plugin_config (vlib_main_t * vm, unformat_input_t * input)
|
||||
{
|
||||
acl_main_t *am = &acl_main;
|
||||
u32 conn_table_hash_buckets;
|
||||
u32 conn_table_hash_memory_size;
|
||||
uword conn_table_hash_memory_size;
|
||||
u32 conn_table_max_entries;
|
||||
uword main_heap_size;
|
||||
uword hash_heap_size;
|
||||
u32 hash_lookup_hash_buckets;
|
||||
u32 hash_lookup_hash_memory;
|
||||
uword hash_lookup_hash_memory;
|
||||
u32 reclassify_sessions;
|
||||
u32 use_tuple_merge;
|
||||
u32 tuple_merge_split_threshold;
|
||||
@ -4106,8 +4106,10 @@ acl_plugin_config (vlib_main_t * vm, unformat_input_t * input)
|
||||
if (unformat
|
||||
(input, "connection hash buckets %d", &conn_table_hash_buckets))
|
||||
am->fa_conn_table_hash_num_buckets = conn_table_hash_buckets;
|
||||
else if (unformat (input, "connection hash memory %d",
|
||||
&conn_table_hash_memory_size))
|
||||
else
|
||||
if (unformat
|
||||
(input, "connection hash memory %U", unformat_memory_size,
|
||||
&conn_table_hash_memory_size))
|
||||
am->fa_conn_table_hash_memory_size = conn_table_hash_memory_size;
|
||||
else if (unformat (input, "connection count max %d",
|
||||
&conn_table_max_entries))
|
||||
@ -4125,8 +4127,10 @@ acl_plugin_config (vlib_main_t * vm, unformat_input_t * input)
|
||||
else if (unformat (input, "hash lookup hash buckets %d",
|
||||
&hash_lookup_hash_buckets))
|
||||
am->hash_lookup_hash_buckets = hash_lookup_hash_buckets;
|
||||
else if (unformat (input, "hash lookup hash memory %d",
|
||||
&hash_lookup_hash_memory))
|
||||
else
|
||||
if (unformat
|
||||
(input, "hash lookup hash memory %U", unformat_memory_size,
|
||||
&hash_lookup_hash_memory))
|
||||
am->hash_lookup_hash_memory = hash_lookup_hash_memory;
|
||||
else if (unformat (input, "use tuple merge %d", &use_tuple_merge))
|
||||
am->use_tuple_merge = use_tuple_merge;
|
||||
|
@ -142,7 +142,7 @@ typedef struct {
|
||||
hash_acl_info_t *hash_acl_infos; /* corresponding hash matching housekeeping info */
|
||||
clib_bihash_48_8_t acl_lookup_hash; /* ACL lookup hash table. */
|
||||
u32 hash_lookup_hash_buckets;
|
||||
u32 hash_lookup_hash_memory;
|
||||
uword hash_lookup_hash_memory;
|
||||
|
||||
/* mheap to hold all the miscellaneous allocations related to hash-based lookups */
|
||||
void *hash_lookup_mheap;
|
||||
|
@ -607,6 +607,17 @@ hash_acl_set_heap(acl_main_t *am)
|
||||
clib_error("ACL plugin failed to allocate lookup heap of %U bytes",
|
||||
format_memory_size, am->hash_lookup_mheap_size);
|
||||
}
|
||||
#if USE_DLMALLOC != 0
|
||||
/*
|
||||
* DLMALLOC is being "helpful" in that it ignores the heap size parameter
|
||||
* by default and tries to allocate the larger amount of memory.
|
||||
*
|
||||
* Pin the heap so this does not happen and if we run out of memory
|
||||
* in this heap, we will bail out with "out of memory", rather than
|
||||
* an obscure error sometime later.
|
||||
*/
|
||||
mspace_disable_expand(am->hash_lookup_mheap);
|
||||
#endif
|
||||
}
|
||||
void *oldheap = clib_mem_set_heap(am->hash_lookup_mheap);
|
||||
return oldheap;
|
||||
@ -736,6 +747,14 @@ hash_acl_apply(acl_main_t *am, u32 lc_index, int acl_index, u32 acl_position)
|
||||
|
||||
|
||||
vec_validate(am->hash_applied_mask_info_vec_by_lc_index, lc_index);
|
||||
|
||||
/* since we know (in case of no split) how much we expand, preallocate that space */
|
||||
if (vec_len(ha->rules) > 0) {
|
||||
int old_vec_len = vec_len(*applied_hash_aces);
|
||||
vec_validate((*applied_hash_aces), old_vec_len + vec_len(ha->rules) - 1);
|
||||
_vec_len((*applied_hash_aces)) = old_vec_len;
|
||||
}
|
||||
|
||||
/* add the rules from the ACL to the hash table for lookup and append to the vector*/
|
||||
for(i=0; i < vec_len(ha->rules); i++) {
|
||||
/*
|
||||
@ -1171,6 +1190,13 @@ void hash_acl_add(acl_main_t *am, int acl_index)
|
||||
|
||||
/* walk the newly added ACL entries and ensure that for each of them there
|
||||
is a mask type, increment a reference count for that mask type */
|
||||
|
||||
/* avoid small requests by preallocating the entire vector before running the additions */
|
||||
if (a->count > 0) {
|
||||
vec_validate(ha->rules, a->count-1);
|
||||
vec_reset_length(ha->rules);
|
||||
}
|
||||
|
||||
for(i=0; i < a->count; i++) {
|
||||
hash_ace_info_t ace_info;
|
||||
fa_5tuple_t mask;
|
||||
@ -1487,6 +1513,8 @@ split_partition(acl_main_t *am, u32 first_index,
|
||||
int i=0;
|
||||
u64 collisions = vec_len(pae->colliding_rules);
|
||||
for(i=0; i<collisions; i++){
|
||||
/* reload the hash acl info as it might be a different ACL# */
|
||||
ha = vec_elt_at_index(am->hash_acl_infos, pae->acl_index);
|
||||
|
||||
DBG( "TM-collision: base_ace:%d (ace_mask:%d, first_collision_mask:%d)",
|
||||
pae->ace_index, pae->mask_type_index, coll_mask_type_index);
|
||||
|
@ -689,7 +689,7 @@ acl_fa_session_cleaner_process (vlib_main_t * vm, vlib_node_runtime_t * rt,
|
||||
}
|
||||
}
|
||||
}
|
||||
acl_log_err
|
||||
acl_log_info
|
||||
("ACL_FA_CLEANER_DELETE_BY_SW_IF_INDEX bitmap: %U, clear_all: %u",
|
||||
format_bitmap_hex, clear_sw_if_index_bitmap, clear_all);
|
||||
vec_foreach (pw0, am->per_worker_data)
|
||||
@ -727,7 +727,7 @@ acl_fa_session_cleaner_process (vlib_main_t * vm, vlib_node_runtime_t * rt,
|
||||
pw0->pending_clear_sw_if_index_bitmap =
|
||||
clib_bitmap_dup (clear_sw_if_index_bitmap);
|
||||
}
|
||||
acl_log_err
|
||||
acl_log_info
|
||||
("ACL_FA_CLEANER: thread %u, pending clear bitmap: %U",
|
||||
(am->per_worker_data - pw0), format_bitmap_hex,
|
||||
pw0->pending_clear_sw_if_index_bitmap);
|
||||
@ -738,8 +738,9 @@ acl_fa_session_cleaner_process (vlib_main_t * vm, vlib_node_runtime_t * rt,
|
||||
send_interrupts_to_workers (vm, am);
|
||||
|
||||
/* now wait till they all complete */
|
||||
acl_log_err ("CLEANER mains len: %u per-worker len: %d",
|
||||
vec_len (vlib_mains), vec_len (am->per_worker_data));
|
||||
acl_log_info ("CLEANER mains len: %u per-worker len: %d",
|
||||
vec_len (vlib_mains),
|
||||
vec_len (am->per_worker_data));
|
||||
vec_foreach (pw0, am->per_worker_data)
|
||||
{
|
||||
CLIB_MEMORY_BARRIER ();
|
||||
@ -758,7 +759,7 @@ acl_fa_session_cleaner_process (vlib_main_t * vm, vlib_node_runtime_t * rt,
|
||||
}
|
||||
}
|
||||
}
|
||||
acl_log_err ("ACL_FA_NODE_CLEAN: cleaning done");
|
||||
acl_log_info ("ACL_FA_NODE_CLEAN: cleaning done");
|
||||
clib_bitmap_free (clear_sw_if_index_bitmap);
|
||||
}
|
||||
am->fa_cleaner_cnt_delete_by_sw_index_ok++;
|
||||
|
@ -38,6 +38,23 @@ typedef enum
|
||||
UDP_PING_N_NEXT,
|
||||
} udp_ping_next_t;
|
||||
|
||||
#define foreach_udp_ping_error \
|
||||
_(BADHBH, "Malformed hop-by-hop header")
|
||||
|
||||
typedef enum
|
||||
{
|
||||
#define _(sym,str) UDP_PING_ERROR_##sym,
|
||||
foreach_udp_ping_error
|
||||
#undef _
|
||||
UDP_PING_N_ERROR,
|
||||
} udp_ping_error_t;
|
||||
|
||||
static char *udp_ping_error_strings[] = {
|
||||
#define _(sym,string) string,
|
||||
foreach_udp_ping_error
|
||||
#undef _
|
||||
};
|
||||
|
||||
udp_ping_main_t udp_ping_main;
|
||||
|
||||
uword
|
||||
@ -502,15 +519,26 @@ udp_ping_analyse_hbh (vlib_buffer_t * b0,
|
||||
*
|
||||
*/
|
||||
void
|
||||
udp_ping_local_analyse (vlib_buffer_t * b0,
|
||||
ip6_header_t * ip0,
|
||||
ip6_hop_by_hop_header_t * hbh0, u16 * next0)
|
||||
udp_ping_local_analyse (vlib_node_runtime_t * node, vlib_buffer_t * b0,
|
||||
ip6_header_t * ip0, ip6_hop_by_hop_header_t * hbh0,
|
||||
u16 * next0)
|
||||
{
|
||||
ip6_main_t *im = &ip6_main;
|
||||
ip_lookup_main_t *lm = &im->lookup_main;
|
||||
|
||||
*next0 = UDP_PING_NEXT_IP6_DROP;
|
||||
|
||||
/*
|
||||
* Sanity check: hbh header length must be less than
|
||||
* b0->current_length.
|
||||
*/
|
||||
if (PREDICT_FALSE ((hbh0->length + 1) << 3) >= b0->current_length)
|
||||
{
|
||||
*next0 = UDP_PING_NEXT_DROP;
|
||||
b0->error = node->errors[UDP_PING_ERROR_BADHBH];
|
||||
return;
|
||||
}
|
||||
|
||||
if (PREDICT_TRUE (hbh0->protocol == IP_PROTOCOL_UDP))
|
||||
{
|
||||
ip6_hop_by_hop_option_t *opt0;
|
||||
@ -600,7 +628,7 @@ end:
|
||||
* @par Graph mechanics: buffer, next index usage
|
||||
*
|
||||
* <em>Uses:</em>
|
||||
* - <code>udp_ping_local_analyse(p0, ip0, hbh0, &next0)</code>
|
||||
* - <code>udp_ping_local_analyse(node, p0, ip0, hbh0, &next0)</code>
|
||||
* - Checks packet type - request/respnse and process them.
|
||||
*
|
||||
* <em>Next Index:</em>
|
||||
@ -660,8 +688,8 @@ udp_ping_local_node_fn (vlib_main_t * vm,
|
||||
hbh0 = (ip6_hop_by_hop_header_t *) (ip0 + 1);
|
||||
hbh1 = (ip6_hop_by_hop_header_t *) (ip1 + 1);
|
||||
|
||||
udp_ping_local_analyse (p0, ip0, hbh0, &next0);
|
||||
udp_ping_local_analyse (p1, ip1, hbh1, &next1);
|
||||
udp_ping_local_analyse (node, p0, ip0, hbh0, &next0);
|
||||
udp_ping_local_analyse (node, p1, ip1, hbh1, &next1);
|
||||
|
||||
if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)))
|
||||
{
|
||||
@ -727,7 +755,7 @@ udp_ping_local_node_fn (vlib_main_t * vm,
|
||||
ip0 = vlib_buffer_get_current (p0);
|
||||
hbh0 = (ip6_hop_by_hop_header_t *) (ip0 + 1);
|
||||
|
||||
udp_ping_local_analyse (p0, ip0, hbh0, &next0);
|
||||
udp_ping_local_analyse (node, p0, ip0, hbh0, &next0);
|
||||
|
||||
if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)))
|
||||
{
|
||||
@ -774,6 +802,8 @@ VLIB_REGISTER_NODE (udp_ping_local, static) =
|
||||
.format_trace = format_udp_ping_trace,
|
||||
.type = VLIB_NODE_TYPE_INTERNAL,
|
||||
.n_next_nodes = UDP_PING_N_NEXT,
|
||||
.n_errors = UDP_PING_N_ERROR,
|
||||
.error_strings = udp_ping_error_strings,
|
||||
.next_nodes =
|
||||
{
|
||||
[UDP_PING_NEXT_DROP] = "error-drop",
|
||||
|
@ -952,8 +952,7 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (PREDICT_FALSE
|
||||
(proto0 == ~0 || proto0 == SNAT_PROTOCOL_ICMP))
|
||||
if (PREDICT_FALSE (proto0 == ~0))
|
||||
{
|
||||
next0 = SNAT_IN2OUT_NEXT_SLOW_PATH;
|
||||
goto trace00;
|
||||
@ -964,6 +963,12 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
|
||||
next0 = SNAT_IN2OUT_NEXT_REASS;
|
||||
goto trace00;
|
||||
}
|
||||
|
||||
if (PREDICT_FALSE (proto0 == SNAT_PROTOCOL_ICMP))
|
||||
{
|
||||
next0 = SNAT_IN2OUT_NEXT_SLOW_PATH;
|
||||
goto trace00;
|
||||
}
|
||||
}
|
||||
|
||||
key0.addr = ip0->src_address;
|
||||
@ -1131,8 +1136,7 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (PREDICT_FALSE
|
||||
(proto1 == ~0 || proto1 == SNAT_PROTOCOL_ICMP))
|
||||
if (PREDICT_FALSE (proto1 == ~0))
|
||||
{
|
||||
next1 = SNAT_IN2OUT_NEXT_SLOW_PATH;
|
||||
goto trace01;
|
||||
@ -1143,6 +1147,12 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
|
||||
next1 = SNAT_IN2OUT_NEXT_REASS;
|
||||
goto trace01;
|
||||
}
|
||||
|
||||
if (PREDICT_FALSE (proto1 == SNAT_PROTOCOL_ICMP))
|
||||
{
|
||||
next1 = SNAT_IN2OUT_NEXT_SLOW_PATH;
|
||||
goto trace01;
|
||||
}
|
||||
}
|
||||
|
||||
key1.addr = ip1->src_address;
|
||||
@ -1346,8 +1356,7 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (PREDICT_FALSE
|
||||
(proto0 == ~0 || proto0 == SNAT_PROTOCOL_ICMP))
|
||||
if (PREDICT_FALSE (proto0 == ~0))
|
||||
{
|
||||
next0 = SNAT_IN2OUT_NEXT_SLOW_PATH;
|
||||
goto trace0;
|
||||
@ -1358,6 +1367,12 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
|
||||
next0 = SNAT_IN2OUT_NEXT_REASS;
|
||||
goto trace0;
|
||||
}
|
||||
|
||||
if (PREDICT_FALSE (proto0 == SNAT_PROTOCOL_ICMP))
|
||||
{
|
||||
next0 = SNAT_IN2OUT_NEXT_SLOW_PATH;
|
||||
goto trace0;
|
||||
}
|
||||
}
|
||||
|
||||
key0.addr = ip0->src_address;
|
||||
@ -1672,6 +1687,7 @@ nat44_in2out_reass_node_fn (vlib_main_t * vm,
|
||||
nat_reass_ip4_t *reass0;
|
||||
udp_header_t *udp0;
|
||||
tcp_header_t *tcp0;
|
||||
icmp46_header_t *icmp0;
|
||||
snat_session_key_t key0;
|
||||
clib_bihash_kv_8_8_t kv0, value0;
|
||||
snat_session_t *s0 = 0;
|
||||
@ -1704,6 +1720,7 @@ nat44_in2out_reass_node_fn (vlib_main_t * vm,
|
||||
ip0 = (ip4_header_t *) vlib_buffer_get_current (b0);
|
||||
udp0 = ip4_next_header (ip0);
|
||||
tcp0 = (tcp_header_t *) udp0;
|
||||
icmp0 = (icmp46_header_t *) udp0;
|
||||
proto0 = ip_proto_to_snat_proto (ip0->protocol);
|
||||
|
||||
reass0 = nat_ip4_reass_find_or_create (ip0->src_address,
|
||||
@ -1722,6 +1739,25 @@ nat44_in2out_reass_node_fn (vlib_main_t * vm,
|
||||
|
||||
if (PREDICT_FALSE (ip4_is_first_fragment (ip0)))
|
||||
{
|
||||
if (PREDICT_FALSE (proto0 == SNAT_PROTOCOL_ICMP))
|
||||
{
|
||||
next0 = icmp_in2out_slow_path
|
||||
(sm, b0, ip0, icmp0, sw_if_index0, rx_fib_index0, node,
|
||||
next0, now, thread_index, &s0);
|
||||
|
||||
if (PREDICT_TRUE (next0 != SNAT_IN2OUT_NEXT_DROP))
|
||||
{
|
||||
if (s0)
|
||||
reass0->sess_index = s0 - per_thread_data->sessions;
|
||||
else
|
||||
reass0->flags |= NAT_REASS_FLAG_ED_DONT_TRANSLATE;
|
||||
nat_ip4_reass_get_frags (reass0,
|
||||
&fragments_to_loopback);
|
||||
}
|
||||
|
||||
goto trace0;
|
||||
}
|
||||
|
||||
key0.addr = ip0->src_address;
|
||||
key0.port = udp0->src_port;
|
||||
key0.protocol = proto0;
|
||||
|
@ -37,7 +37,8 @@ _(BAD_ICMP_TYPE, "unsupported ICMP type") \
|
||||
_(MAX_SESSIONS_EXCEEDED, "Maximum sessions exceeded") \
|
||||
_(DROP_FRAGMENT, "Drop fragment") \
|
||||
_(MAX_REASS, "Maximum reassemblies exceeded") \
|
||||
_(MAX_FRAG, "Maximum fragments per reassembly exceeded")
|
||||
_(MAX_FRAG, "Maximum fragments per reassembly exceeded")\
|
||||
_(NON_SYN, "non-SYN packet try to create session")
|
||||
|
||||
typedef enum
|
||||
{
|
||||
@ -254,7 +255,8 @@ slow_path_ed (snat_main_t * sm,
|
||||
u32 rx_fib_index,
|
||||
clib_bihash_kv_16_8_t * kv,
|
||||
snat_session_t ** sessionp,
|
||||
vlib_node_runtime_t * node, u32 next, u32 thread_index, f64 now)
|
||||
vlib_node_runtime_t * node, u32 next, u32 thread_index, f64 now,
|
||||
tcp_header_t * tcp)
|
||||
{
|
||||
snat_session_t *s = 0;
|
||||
snat_user_t *u;
|
||||
@ -314,6 +316,15 @@ slow_path_ed (snat_main_t * sm,
|
||||
is_sm = 1;
|
||||
}
|
||||
|
||||
if (proto == SNAT_PROTOCOL_TCP)
|
||||
{
|
||||
if (!tcp_is_init (tcp))
|
||||
{
|
||||
b->error = node->errors[NAT_IN2OUT_ED_ERROR_NON_SYN];
|
||||
return NAT_IN2OUT_ED_NEXT_DROP;
|
||||
}
|
||||
}
|
||||
|
||||
u = nat_user_get_or_create (sm, &key->l_addr, rx_fib_index, thread_index);
|
||||
if (!u)
|
||||
{
|
||||
@ -513,7 +524,19 @@ nat44_ed_not_translate_output_feature (snat_main_t * sm, ip4_header_t * ip,
|
||||
make_ed_kv (&kv, &ip->src_address, &ip->dst_address, proto, tx_fib_index,
|
||||
src_port, dst_port);
|
||||
if (!clib_bihash_search_16_8 (&tsm->out2in_ed, &kv, &value))
|
||||
return 1;
|
||||
{
|
||||
s = pool_elt_at_index (tsm->sessions, value.value);
|
||||
if (nat44_is_ses_closed (s))
|
||||
{
|
||||
nat_log_debug ("TCP close connection %U", format_snat_session,
|
||||
&sm->per_thread_data[thread_index], s);
|
||||
nat_free_session_data (sm, s, thread_index);
|
||||
nat44_delete_session (sm, s, thread_index);
|
||||
}
|
||||
else
|
||||
s->flags |= SNAT_SESSION_FLAG_OUTPUT_FEATURE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* dst NAT check */
|
||||
make_ed_kv (&kv, &ip->dst_address, &ip->src_address, proto, rx_fib_index,
|
||||
@ -613,7 +636,7 @@ icmp_match_in2out_ed (snat_main_t * sm, vlib_node_runtime_t * node,
|
||||
}
|
||||
|
||||
next = slow_path_ed (sm, b, rx_fib_index, &kv, &s, node, next,
|
||||
thread_index, vlib_time_now (sm->vlib_main));
|
||||
thread_index, vlib_time_now (sm->vlib_main), 0);
|
||||
|
||||
if (PREDICT_FALSE (next == NAT_IN2OUT_ED_NEXT_DROP))
|
||||
goto out;
|
||||
@ -1023,7 +1046,7 @@ nat44_ed_in2out_node_fn_inline (vlib_main_t * vm,
|
||||
|
||||
next0 =
|
||||
slow_path_ed (sm, b0, rx_fib_index0, &kv0, &s0, node,
|
||||
next0, thread_index, now);
|
||||
next0, thread_index, now, tcp0);
|
||||
|
||||
if (PREDICT_FALSE (next0 == NAT_IN2OUT_ED_NEXT_DROP))
|
||||
goto trace00;
|
||||
@ -1227,7 +1250,7 @@ nat44_ed_in2out_node_fn_inline (vlib_main_t * vm,
|
||||
|
||||
next1 =
|
||||
slow_path_ed (sm, b1, rx_fib_index1, &kv1, &s1, node,
|
||||
next1, thread_index, now);
|
||||
next1, thread_index, now, tcp1);
|
||||
|
||||
if (PREDICT_FALSE (next1 == NAT_IN2OUT_ED_NEXT_DROP))
|
||||
goto trace01;
|
||||
@ -1460,7 +1483,7 @@ nat44_ed_in2out_node_fn_inline (vlib_main_t * vm,
|
||||
|
||||
next0 =
|
||||
slow_path_ed (sm, b0, rx_fib_index0, &kv0, &s0, node,
|
||||
next0, thread_index, now);
|
||||
next0, thread_index, now, tcp0);
|
||||
|
||||
if (PREDICT_FALSE (next0 == NAT_IN2OUT_ED_NEXT_DROP))
|
||||
goto trace0;
|
||||
@ -1859,7 +1882,8 @@ nat44_ed_in2out_reass_node_fn_inline (vlib_main_t * vm,
|
||||
}
|
||||
|
||||
next0 = slow_path_ed (sm, b0, rx_fib_index0, &kv0,
|
||||
&s0, node, next0, thread_index, now);
|
||||
&s0, node, next0, thread_index, now,
|
||||
tcp0);
|
||||
|
||||
if (PREDICT_FALSE (next0 == NAT_IN2OUT_ED_NEXT_DROP))
|
||||
goto trace0;
|
||||
@ -1960,11 +1984,8 @@ nat44_ed_in2out_reass_node_fn_inline (vlib_main_t * vm,
|
||||
}
|
||||
|
||||
/* Hairpinning */
|
||||
if (PREDICT_TRUE (proto0 != SNAT_PROTOCOL_ICMP))
|
||||
nat44_reass_hairpinning (sm, b0, ip0, s0->out2in.port,
|
||||
s0->ext_host_port, proto0, 1);
|
||||
else
|
||||
snat_icmp_hairpinning (sm, b0, ip0, icmp0, 1);
|
||||
nat44_reass_hairpinning (sm, b0, ip0, s0->out2in.port,
|
||||
s0->ext_host_port, proto0, 1);
|
||||
|
||||
/* Accounting */
|
||||
nat44_session_update_counters (s0, now,
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -165,6 +165,7 @@ typedef enum
|
||||
#define NAT44_SES_O2I_FIN_ACK 8
|
||||
#define NAT44_SES_I2O_SYN 16
|
||||
#define NAT44_SES_O2I_SYN 32
|
||||
#define NAT44_SES_RST 64
|
||||
|
||||
/* Session flags */
|
||||
#define SNAT_SESSION_FLAG_STATIC_MAPPING 1
|
||||
@ -174,6 +175,7 @@ typedef enum
|
||||
#define SNAT_SESSION_FLAG_ENDPOINT_DEPENDENT 16
|
||||
#define SNAT_SESSION_FLAG_FWD_BYPASS 32
|
||||
#define SNAT_SESSION_FLAG_AFFINITY 64
|
||||
#define SNAT_SESSION_FLAG_OUTPUT_FEATURE 128
|
||||
|
||||
/* NAT interface flags */
|
||||
#define NAT_INTERFACE_FLAG_IS_INSIDE 1
|
||||
@ -183,6 +185,7 @@ typedef enum
|
||||
#define NAT_STATIC_MAPPING_FLAG_ADDR_ONLY 1
|
||||
#define NAT_STATIC_MAPPING_FLAG_OUT2IN_ONLY 2
|
||||
#define NAT_STATIC_MAPPING_FLAG_IDENTITY_NAT 4
|
||||
#define NAT_STATIC_MAPPING_FLAG_LB 8
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
typedef CLIB_PACKED(struct
|
||||
@ -666,6 +669,18 @@ unformat_function_t unformat_snat_protocol;
|
||||
*/
|
||||
#define is_identity_static_mapping(sm) (sm->flags & NAT_STATIC_MAPPING_FLAG_IDENTITY_NAT)
|
||||
|
||||
/** \brief Check if NAT static mapping is load-balancing.
|
||||
@param sm NAT static mapping
|
||||
@return 1 if load-balancing
|
||||
*/
|
||||
#define is_lb_static_mapping(sm) (sm->flags & NAT_STATIC_MAPPING_FLAG_LB)
|
||||
|
||||
/** \brief Check if client initiating TCP connection (received SYN from client)
|
||||
@param t TCP header
|
||||
@return 1 if client initiating TCP connection
|
||||
*/
|
||||
#define tcp_is_init(t) ((t->flags & TCP_FLAG_SYN) && !(t->flags & TCP_FLAG_ACK))
|
||||
|
||||
/* logging */
|
||||
#define nat_log_err(...) \
|
||||
vlib_log(VLIB_LOG_LEVEL_ERR, snat_main.log_class, __VA_ARGS__)
|
||||
|
@ -286,39 +286,6 @@ snat_icmp_hairpinning (snat_main_t * sm,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!is_ed)
|
||||
{
|
||||
icmp_echo_header_t *echo0 = (icmp_echo_header_t *) (icmp0 + 1);
|
||||
u16 icmp_id0 = echo0->identifier;
|
||||
key0.addr = ip0->dst_address;
|
||||
key0.port = icmp_id0;
|
||||
key0.protocol = SNAT_PROTOCOL_ICMP;
|
||||
key0.fib_index = sm->outside_fib_index;
|
||||
kv0.key = key0.as_u64;
|
||||
if (sm->num_workers > 1)
|
||||
ti =
|
||||
(clib_net_to_host_u16 (icmp_id0) - 1024) / sm->port_per_thread;
|
||||
else
|
||||
ti = sm->num_workers;
|
||||
int rv =
|
||||
clib_bihash_search_8_8 (&sm->per_thread_data[ti].out2in, &kv0,
|
||||
&value0);
|
||||
if (!rv)
|
||||
{
|
||||
si = value0.value;
|
||||
s0 = pool_elt_at_index (sm->per_thread_data[ti].sessions, si);
|
||||
new_dst_addr0 = s0->in2out.addr.as_u32;
|
||||
vnet_buffer (b0)->sw_if_index[VLIB_TX] = s0->in2out.fib_index;
|
||||
echo0->identifier = s0->in2out.port;
|
||||
sum0 = icmp0->checksum;
|
||||
sum0 = ip_csum_update (sum0, icmp_id0, s0->in2out.port,
|
||||
icmp_echo_header_t, identifier);
|
||||
icmp0->checksum = ip_csum_fold (sum0);
|
||||
goto change_addr;
|
||||
}
|
||||
ti = 0;
|
||||
}
|
||||
|
||||
key0.addr = ip0->dst_address;
|
||||
key0.port = 0;
|
||||
key0.protocol = 0;
|
||||
@ -327,7 +294,44 @@ snat_icmp_hairpinning (snat_main_t * sm,
|
||||
|
||||
if (clib_bihash_search_8_8
|
||||
(&sm->static_mapping_by_external, &kv0, &value0))
|
||||
return 1;
|
||||
{
|
||||
if (!is_ed)
|
||||
{
|
||||
icmp_echo_header_t *echo0 = (icmp_echo_header_t *) (icmp0 + 1);
|
||||
u16 icmp_id0 = echo0->identifier;
|
||||
key0.addr = ip0->dst_address;
|
||||
key0.port = icmp_id0;
|
||||
key0.protocol = SNAT_PROTOCOL_ICMP;
|
||||
key0.fib_index = sm->outside_fib_index;
|
||||
kv0.key = key0.as_u64;
|
||||
if (sm->num_workers > 1)
|
||||
ti =
|
||||
(clib_net_to_host_u16 (icmp_id0) -
|
||||
1024) / sm->port_per_thread;
|
||||
else
|
||||
ti = sm->num_workers;
|
||||
int rv =
|
||||
clib_bihash_search_8_8 (&sm->per_thread_data[ti].out2in, &kv0,
|
||||
&value0);
|
||||
if (!rv)
|
||||
{
|
||||
si = value0.value;
|
||||
s0 =
|
||||
pool_elt_at_index (sm->per_thread_data[ti].sessions, si);
|
||||
new_dst_addr0 = s0->in2out.addr.as_u32;
|
||||
vnet_buffer (b0)->sw_if_index[VLIB_TX] =
|
||||
s0->in2out.fib_index;
|
||||
echo0->identifier = s0->in2out.port;
|
||||
sum0 = icmp0->checksum;
|
||||
sum0 = ip_csum_update (sum0, icmp_id0, s0->in2out.port,
|
||||
icmp_echo_header_t, identifier);
|
||||
icmp0->checksum = ip_csum_fold (sum0);
|
||||
goto change_addr;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
m0 = pool_elt_at_index (sm->static_mappings, value0.value);
|
||||
|
||||
|
@ -1100,7 +1100,7 @@ vl_api_nat44_static_mapping_dump_t_handler (vl_api_nat44_static_mapping_dump_t
|
||||
/* *INDENT-OFF* */
|
||||
pool_foreach (m, sm->static_mappings,
|
||||
({
|
||||
if (!is_identity_static_mapping(m) && !vec_len (m->locals))
|
||||
if (!is_identity_static_mapping(m) && !is_lb_static_mapping (m))
|
||||
send_nat44_static_mapping_details (m, reg, mp->context);
|
||||
}));
|
||||
/* *INDENT-ON* */
|
||||
@ -1181,17 +1181,17 @@ static void *vl_api_nat44_add_del_identity_mapping_t_print
|
||||
|
||||
if (mp->addr_only == 0)
|
||||
s =
|
||||
format (s, "protocol %d port %d", mp->protocol,
|
||||
format (s, " protocol %d port %d", mp->protocol,
|
||||
clib_net_to_host_u16 (mp->port));
|
||||
|
||||
if (mp->vrf_id != ~0)
|
||||
s = format (s, "vrf %d", clib_net_to_host_u32 (mp->vrf_id));
|
||||
s = format (s, " vrf %d", clib_net_to_host_u32 (mp->vrf_id));
|
||||
|
||||
FINISH;
|
||||
}
|
||||
|
||||
static void
|
||||
send_nat44_identity_mapping_details (snat_static_mapping_t * m,
|
||||
send_nat44_identity_mapping_details (snat_static_mapping_t * m, int index,
|
||||
vl_api_registration_t * reg, u32 context)
|
||||
{
|
||||
vl_api_nat44_identity_mapping_details_t *rmp;
|
||||
@ -1205,7 +1205,7 @@ send_nat44_identity_mapping_details (snat_static_mapping_t * m,
|
||||
clib_memcpy (rmp->ip_address, &(m->local_addr), 4);
|
||||
rmp->port = htons (m->local_port);
|
||||
rmp->sw_if_index = ~0;
|
||||
rmp->vrf_id = htonl (m->vrf_id);
|
||||
rmp->vrf_id = htonl (m->locals[index].vrf_id);
|
||||
rmp->protocol = snat_proto_to_ip_proto (m->proto);
|
||||
rmp->context = context;
|
||||
if (m->tag)
|
||||
@ -1258,8 +1258,11 @@ static void
|
||||
/* *INDENT-OFF* */
|
||||
pool_foreach (m, sm->static_mappings,
|
||||
({
|
||||
if (is_identity_static_mapping(m) && !vec_len (m->locals))
|
||||
send_nat44_identity_mapping_details (m, reg, mp->context);
|
||||
if (is_identity_static_mapping(m) && !is_lb_static_mapping (m))
|
||||
{
|
||||
for (j = 0; j < vec_len (m->locals); j++)
|
||||
send_nat44_identity_mapping_details (m, j, reg, mp->context);
|
||||
}
|
||||
}));
|
||||
/* *INDENT-ON* */
|
||||
|
||||
@ -1689,7 +1692,7 @@ static void
|
||||
/* *INDENT-OFF* */
|
||||
pool_foreach (m, sm->static_mappings,
|
||||
({
|
||||
if (vec_len(m->locals))
|
||||
if (is_lb_static_mapping(m))
|
||||
send_nat44_lb_static_mapping_details (m, reg, mp->context);
|
||||
}));
|
||||
/* *INDENT-ON* */
|
||||
|
@ -220,6 +220,24 @@ format_snat_static_mapping (u8 * s, va_list * args)
|
||||
snat_static_mapping_t *m = va_arg (*args, snat_static_mapping_t *);
|
||||
nat44_lb_addr_port_t *local;
|
||||
|
||||
if (is_identity_static_mapping (m))
|
||||
{
|
||||
if (is_addr_only_static_mapping (m))
|
||||
s = format (s, "identity mapping %U",
|
||||
format_ip4_address, &m->local_addr);
|
||||
else
|
||||
s = format (s, "identity mapping %U %U:%d",
|
||||
format_snat_protocol, m->proto,
|
||||
format_ip4_address, &m->local_addr, m->local_port);
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
vec_foreach (local, m->locals)
|
||||
s = format (s, " vrf %d", local->vrf_id);
|
||||
/* *INDENT-ON* */
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
if (is_addr_only_static_mapping (m))
|
||||
s = format (s, "local %U external %U vrf %d %s %s",
|
||||
format_ip4_address, &m->local_addr,
|
||||
@ -230,7 +248,7 @@ format_snat_static_mapping (u8 * s, va_list * args)
|
||||
is_out2in_only_static_mapping (m) ? "out2in-only" : "");
|
||||
else
|
||||
{
|
||||
if (vec_len (m->locals))
|
||||
if (is_lb_static_mapping (m))
|
||||
{
|
||||
s = format (s, "%U external %U:%d %s %s",
|
||||
format_snat_protocol, m->proto,
|
||||
|
@ -200,6 +200,10 @@ always_inline int
|
||||
nat44_set_tcp_session_state_i2o (snat_main_t * sm, snat_session_t * ses,
|
||||
tcp_header_t * tcp, u32 thread_index)
|
||||
{
|
||||
if ((ses->state == 0) && (tcp->flags & TCP_FLAG_RST))
|
||||
ses->state = NAT44_SES_RST;
|
||||
if ((ses->state == NAT44_SES_RST) && !(tcp->flags & TCP_FLAG_RST))
|
||||
ses->state = 0;
|
||||
if ((tcp->flags & TCP_FLAG_ACK) && (ses->state & NAT44_SES_I2O_SYN) &&
|
||||
(ses->state & NAT44_SES_O2I_SYN))
|
||||
ses->state = 0;
|
||||
@ -215,7 +219,8 @@ nat44_set_tcp_session_state_i2o (snat_main_t * sm, snat_session_t * ses,
|
||||
if (clib_net_to_host_u32 (tcp->ack_number) > ses->o2i_fin_seq)
|
||||
ses->state |= NAT44_SES_O2I_FIN_ACK;
|
||||
}
|
||||
if (nat44_is_ses_closed (ses))
|
||||
if (nat44_is_ses_closed (ses)
|
||||
&& !(ses->flags & SNAT_SESSION_FLAG_OUTPUT_FEATURE))
|
||||
{
|
||||
nat_log_debug ("TCP close connection %U", format_snat_session,
|
||||
&sm->per_thread_data[thread_index], ses);
|
||||
@ -230,6 +235,10 @@ always_inline int
|
||||
nat44_set_tcp_session_state_o2i (snat_main_t * sm, snat_session_t * ses,
|
||||
tcp_header_t * tcp, u32 thread_index)
|
||||
{
|
||||
if ((ses->state == 0) && (tcp->flags & TCP_FLAG_RST))
|
||||
ses->state = NAT44_SES_RST;
|
||||
if ((ses->state == NAT44_SES_RST) && !(tcp->flags & TCP_FLAG_RST))
|
||||
ses->state = 0;
|
||||
if ((tcp->flags & TCP_FLAG_ACK) && (ses->state & NAT44_SES_I2O_SYN) &&
|
||||
(ses->state & NAT44_SES_O2I_SYN))
|
||||
ses->state = 0;
|
||||
|
@ -775,6 +775,12 @@ snat_out2in_node_fn (vlib_main_t * vm,
|
||||
goto trace0;
|
||||
}
|
||||
|
||||
if (PREDICT_FALSE (ip4_is_fragment (ip0)))
|
||||
{
|
||||
next0 = SNAT_OUT2IN_NEXT_REASS;
|
||||
goto trace0;
|
||||
}
|
||||
|
||||
if (PREDICT_FALSE (proto0 == SNAT_PROTOCOL_ICMP))
|
||||
{
|
||||
next0 = icmp_out2in_slow_path
|
||||
@ -783,12 +789,6 @@ snat_out2in_node_fn (vlib_main_t * vm,
|
||||
goto trace0;
|
||||
}
|
||||
|
||||
if (PREDICT_FALSE (ip4_is_fragment (ip0)))
|
||||
{
|
||||
next0 = SNAT_OUT2IN_NEXT_REASS;
|
||||
goto trace0;
|
||||
}
|
||||
|
||||
key0.addr = ip0->dst_address;
|
||||
key0.port = udp0->dst_port;
|
||||
key0.protocol = proto0;
|
||||
@ -936,6 +936,12 @@ snat_out2in_node_fn (vlib_main_t * vm,
|
||||
goto trace1;
|
||||
}
|
||||
|
||||
if (PREDICT_FALSE (ip4_is_fragment (ip1)))
|
||||
{
|
||||
next1 = SNAT_OUT2IN_NEXT_REASS;
|
||||
goto trace1;
|
||||
}
|
||||
|
||||
if (PREDICT_FALSE (proto1 == SNAT_PROTOCOL_ICMP))
|
||||
{
|
||||
next1 = icmp_out2in_slow_path
|
||||
@ -944,12 +950,6 @@ snat_out2in_node_fn (vlib_main_t * vm,
|
||||
goto trace1;
|
||||
}
|
||||
|
||||
if (PREDICT_FALSE (ip4_is_fragment (ip1)))
|
||||
{
|
||||
next1 = SNAT_OUT2IN_NEXT_REASS;
|
||||
goto trace1;
|
||||
}
|
||||
|
||||
key1.addr = ip1->dst_address;
|
||||
key1.port = udp1->dst_port;
|
||||
key1.protocol = proto1;
|
||||
@ -1134,6 +1134,12 @@ snat_out2in_node_fn (vlib_main_t * vm,
|
||||
goto trace00;
|
||||
}
|
||||
|
||||
if (PREDICT_FALSE (ip4_is_fragment (ip0)))
|
||||
{
|
||||
next0 = SNAT_OUT2IN_NEXT_REASS;
|
||||
goto trace00;
|
||||
}
|
||||
|
||||
if (PREDICT_FALSE (proto0 == SNAT_PROTOCOL_ICMP))
|
||||
{
|
||||
next0 = icmp_out2in_slow_path
|
||||
@ -1142,12 +1148,6 @@ snat_out2in_node_fn (vlib_main_t * vm,
|
||||
goto trace00;
|
||||
}
|
||||
|
||||
if (PREDICT_FALSE (ip4_is_fragment (ip0)))
|
||||
{
|
||||
next0 = SNAT_OUT2IN_NEXT_REASS;
|
||||
goto trace00;
|
||||
}
|
||||
|
||||
key0.addr = ip0->dst_address;
|
||||
key0.port = udp0->dst_port;
|
||||
key0.protocol = proto0;
|
||||
@ -1336,6 +1336,7 @@ nat44_out2in_reass_node_fn (vlib_main_t * vm,
|
||||
nat_reass_ip4_t *reass0;
|
||||
udp_header_t *udp0;
|
||||
tcp_header_t *tcp0;
|
||||
icmp46_header_t *icmp0;
|
||||
snat_session_key_t key0, sm0;
|
||||
clib_bihash_kv_8_8_t kv0, value0;
|
||||
snat_session_t *s0 = 0;
|
||||
@ -1369,6 +1370,7 @@ nat44_out2in_reass_node_fn (vlib_main_t * vm,
|
||||
ip0 = (ip4_header_t *) vlib_buffer_get_current (b0);
|
||||
udp0 = ip4_next_header (ip0);
|
||||
tcp0 = (tcp_header_t *) udp0;
|
||||
icmp0 = (icmp46_header_t *) udp0;
|
||||
proto0 = ip_proto_to_snat_proto (ip0->protocol);
|
||||
|
||||
reass0 = nat_ip4_reass_find_or_create (ip0->src_address,
|
||||
@ -1387,6 +1389,26 @@ nat44_out2in_reass_node_fn (vlib_main_t * vm,
|
||||
|
||||
if (PREDICT_FALSE (ip4_is_first_fragment (ip0)))
|
||||
{
|
||||
if (PREDICT_FALSE (proto0 == SNAT_PROTOCOL_ICMP))
|
||||
{
|
||||
next0 = icmp_out2in_slow_path
|
||||
(sm, b0, ip0, icmp0, sw_if_index0, rx_fib_index0, node,
|
||||
next0, now, thread_index, &s0);
|
||||
|
||||
if (PREDICT_TRUE (next0 != SNAT_OUT2IN_NEXT_DROP))
|
||||
{
|
||||
if (s0)
|
||||
reass0->sess_index = s0 - per_thread_data->sessions;
|
||||
else
|
||||
reass0->flags |= NAT_REASS_FLAG_ED_DONT_TRANSLATE;
|
||||
reass0->thread_index = thread_index;
|
||||
nat_ip4_reass_get_frags (reass0,
|
||||
&fragments_to_loopback);
|
||||
}
|
||||
|
||||
goto trace0;
|
||||
}
|
||||
|
||||
key0.addr = ip0->dst_address;
|
||||
key0.port = udp0->dst_port;
|
||||
key0.protocol = proto0;
|
||||
@ -1421,6 +1443,12 @@ nat44_out2in_reass_node_fn (vlib_main_t * vm,
|
||||
node->errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
|
||||
next0 = SNAT_OUT2IN_NEXT_DROP;
|
||||
}
|
||||
else
|
||||
{
|
||||
reass0->flags |= NAT_REASS_FLAG_ED_DONT_TRANSLATE;
|
||||
nat_ip4_reass_get_frags (reass0,
|
||||
&fragments_to_loopback);
|
||||
}
|
||||
goto trace0;
|
||||
}
|
||||
|
||||
@ -1452,6 +1480,8 @@ nat44_out2in_reass_node_fn (vlib_main_t * vm,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (reass0->flags & NAT_REASS_FLAG_ED_DONT_TRANSLATE)
|
||||
goto trace0;
|
||||
if (PREDICT_FALSE (reass0->sess_index == (u32) ~ 0))
|
||||
{
|
||||
if (nat_ip4_reass_add_fragment
|
||||
|
@ -39,7 +39,8 @@ _(NO_TRANSLATION, "No translation") \
|
||||
_(MAX_SESSIONS_EXCEEDED, "Maximum sessions exceeded") \
|
||||
_(DROP_FRAGMENT, "Drop fragment") \
|
||||
_(MAX_REASS, "Maximum reassemblies exceeded") \
|
||||
_(MAX_FRAG, "Maximum fragments per reassembly exceeded")
|
||||
_(MAX_FRAG, "Maximum fragments per reassembly exceeded")\
|
||||
_(NON_SYN, "non-SYN packet try to create session")
|
||||
|
||||
typedef enum
|
||||
{
|
||||
@ -875,6 +876,13 @@ nat44_ed_out2in_node_fn_inline (vlib_main_t * vm,
|
||||
if (PREDICT_FALSE (identity_nat0))
|
||||
goto trace00;
|
||||
|
||||
if ((proto0 == SNAT_PROTOCOL_TCP) && !tcp_is_init (tcp0))
|
||||
{
|
||||
b0->error = node->errors[NAT_OUT2IN_ED_ERROR_NON_SYN];
|
||||
next0 = NAT44_ED_OUT2IN_NEXT_DROP;
|
||||
goto trace00;
|
||||
}
|
||||
|
||||
/* Create session initiated by host from external network */
|
||||
s0 = create_session_for_static_mapping_ed (sm, b0, l_key0,
|
||||
e_key0, node,
|
||||
@ -1097,6 +1105,13 @@ nat44_ed_out2in_node_fn_inline (vlib_main_t * vm,
|
||||
if (PREDICT_FALSE (identity_nat1))
|
||||
goto trace01;
|
||||
|
||||
if ((proto1 == SNAT_PROTOCOL_TCP) && !tcp_is_init (tcp1))
|
||||
{
|
||||
b1->error = node->errors[NAT_OUT2IN_ED_ERROR_NON_SYN];
|
||||
next1 = NAT44_ED_OUT2IN_NEXT_DROP;
|
||||
goto trace01;
|
||||
}
|
||||
|
||||
/* Create session initiated by host from external network */
|
||||
s1 = create_session_for_static_mapping_ed (sm, b1, l_key1,
|
||||
e_key1, node,
|
||||
@ -1353,6 +1368,13 @@ nat44_ed_out2in_node_fn_inline (vlib_main_t * vm,
|
||||
if (PREDICT_FALSE (identity_nat0))
|
||||
goto trace0;
|
||||
|
||||
if ((proto0 == SNAT_PROTOCOL_TCP) && !tcp_is_init (tcp0))
|
||||
{
|
||||
b0->error = node->errors[NAT_OUT2IN_ED_ERROR_NON_SYN];
|
||||
next0 = NAT44_ED_OUT2IN_NEXT_DROP;
|
||||
goto trace0;
|
||||
}
|
||||
|
||||
/* Create session initiated by host from external network */
|
||||
s0 = create_session_for_static_mapping_ed (sm, b0, l_key0,
|
||||
e_key0, node,
|
||||
@ -1702,6 +1724,13 @@ nat44_ed_out2in_reass_node_fn (vlib_main_t * vm,
|
||||
goto trace0;
|
||||
}
|
||||
|
||||
if ((proto0 == SNAT_PROTOCOL_TCP) && !tcp_is_init (tcp0))
|
||||
{
|
||||
b0->error = node->errors[NAT_OUT2IN_ED_ERROR_NON_SYN];
|
||||
next0 = NAT44_ED_OUT2IN_NEXT_DROP;
|
||||
goto trace0;
|
||||
}
|
||||
|
||||
/* Create session initiated by host from external network */
|
||||
s0 = create_session_for_static_mapping_ed (sm, b0, l_key0,
|
||||
e_key0, node,
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -16,7 +16,8 @@ vfio driver can still be used with recent kernels which support no-iommu mode.
|
||||
##Known issues
|
||||
|
||||
* NUMA support
|
||||
* TSO
|
||||
* TSO/LRO
|
||||
* RSS/multiple queues
|
||||
* VLAN filter
|
||||
|
||||
## Usage
|
||||
|
@ -184,7 +184,8 @@ VLIB_CLI_COMMAND (vmxnet3_test_command, static) = {
|
||||
/* *INDENT-ON* */
|
||||
|
||||
static void
|
||||
show_vmxnet3 (vlib_main_t * vm, u32 * hw_if_indices, u8 show_descr)
|
||||
show_vmxnet3 (vlib_main_t * vm, u32 * hw_if_indices, u8 show_descr,
|
||||
u8 show_one_table, u32 which, u8 show_one_slot, u32 slot)
|
||||
{
|
||||
u32 i, desc_idx;
|
||||
vmxnet3_device_t *vd;
|
||||
@ -228,6 +229,8 @@ show_vmxnet3 (vlib_main_t * vm, u32 * hw_if_indices, u8 show_descr)
|
||||
rxq->rx_comp_ring.next);
|
||||
vlib_cli_output (vm, " RX completion generation flag 0x%x",
|
||||
rxq->rx_comp_ring.gen);
|
||||
|
||||
/* RX descriptors tables */
|
||||
for (rid = 0; rid < VMXNET3_RX_RING_SIZE; rid++)
|
||||
{
|
||||
vmxnet3_rx_ring *ring = &rxq->rx_ring[rid];
|
||||
@ -248,16 +251,70 @@ show_vmxnet3 (vlib_main_t * vm, u32 * hw_if_indices, u8 show_descr)
|
||||
vlib_cli_output (vm, " %5u 0x%016llx 0x%08x",
|
||||
desc_idx, rxd->address, rxd->flags);
|
||||
}
|
||||
}
|
||||
else if (show_one_table)
|
||||
{
|
||||
if (((which == VMXNET3_SHOW_RX_DESC0) && (rid == 0)) ||
|
||||
((which == VMXNET3_SHOW_RX_DESC1) && (rid == 1)))
|
||||
{
|
||||
vlib_cli_output (vm, "RX descriptors table");
|
||||
vlib_cli_output (vm, " %5s %18s %10s",
|
||||
"slot", "address", "flags");
|
||||
if (show_one_slot)
|
||||
{
|
||||
rxd = &rxq->rx_desc[rid][slot];
|
||||
vlib_cli_output (vm, " %5u 0x%016llx 0x%08x",
|
||||
slot, rxd->address, rxd->flags);
|
||||
}
|
||||
else
|
||||
for (desc_idx = 0; desc_idx < rxq->size; desc_idx++)
|
||||
{
|
||||
rxd = &rxq->rx_desc[rid][desc_idx];
|
||||
vlib_cli_output (vm, " %5u 0x%016llx 0x%08x",
|
||||
desc_idx, rxd->address,
|
||||
rxd->flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* RX completion table */
|
||||
if (show_descr)
|
||||
{
|
||||
vlib_cli_output (vm, "RX completion descriptors table");
|
||||
vlib_cli_output (vm, " %5s %10s %10s %10s %10s",
|
||||
"slot", "index", "rss", "len", "flags");
|
||||
for (desc_idx = 0; desc_idx < rxq->size; desc_idx++)
|
||||
{
|
||||
rx_comp = &rxq->rx_comp[desc_idx];
|
||||
vlib_cli_output (vm, " %5u 0x%08x %10u %10u 0x%08x",
|
||||
desc_idx, rx_comp->index, rx_comp->rss,
|
||||
rx_comp->len, rx_comp->flags);
|
||||
}
|
||||
}
|
||||
else if (show_one_table)
|
||||
{
|
||||
if (which == VMXNET3_SHOW_RX_COMP)
|
||||
{
|
||||
vlib_cli_output (vm, "RX completion descriptors table");
|
||||
vlib_cli_output (vm, " %5s %10s %10s %10s %10s",
|
||||
"slot", "index", "rss", "len", "flags");
|
||||
for (desc_idx = 0; desc_idx < rxq->size; desc_idx++)
|
||||
if (show_one_slot)
|
||||
{
|
||||
rx_comp = &rxq->rx_comp[desc_idx];
|
||||
rx_comp = &rxq->rx_comp[slot];
|
||||
vlib_cli_output (vm, " %5u 0x%08x %10u %10u 0x%08x",
|
||||
desc_idx, rx_comp->index, rx_comp->rss,
|
||||
slot, rx_comp->index, rx_comp->rss,
|
||||
rx_comp->len, rx_comp->flags);
|
||||
}
|
||||
else
|
||||
for (desc_idx = 0; desc_idx < rxq->size; desc_idx++)
|
||||
{
|
||||
rx_comp = &rxq->rx_comp[desc_idx];
|
||||
vlib_cli_output (vm,
|
||||
" %5u 0x%08x %10u %10u 0x%08x",
|
||||
desc_idx, rx_comp->index, rx_comp->rss,
|
||||
rx_comp->len, rx_comp->flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -285,6 +342,7 @@ show_vmxnet3 (vlib_main_t * vm, u32 * hw_if_indices, u8 show_descr)
|
||||
desc_idx, txd->address, txd->flags[0],
|
||||
txd->flags[1]);
|
||||
}
|
||||
|
||||
vlib_cli_output (vm, "TX completion descriptors table");
|
||||
vlib_cli_output (vm, " %5s %10s %10s",
|
||||
"slot", "index", "flags");
|
||||
@ -295,6 +353,50 @@ show_vmxnet3 (vlib_main_t * vm, u32 * hw_if_indices, u8 show_descr)
|
||||
desc_idx, tx_comp->index, tx_comp->flags);
|
||||
}
|
||||
}
|
||||
else if (show_one_table)
|
||||
{
|
||||
if (which == VMXNET3_SHOW_TX_DESC)
|
||||
{
|
||||
vlib_cli_output (vm, "TX descriptors table");
|
||||
vlib_cli_output (vm, " %5s %18s %10s %10s",
|
||||
"slot", "address", "flags0", "flags1");
|
||||
if (show_one_slot)
|
||||
{
|
||||
txd = &txq->tx_desc[slot];
|
||||
vlib_cli_output (vm, " %5u 0x%016llx 0x%08x 0x%08x",
|
||||
slot, txd->address, txd->flags[0],
|
||||
txd->flags[1]);
|
||||
}
|
||||
else
|
||||
for (desc_idx = 0; desc_idx < txq->size; desc_idx++)
|
||||
{
|
||||
txd = &txq->tx_desc[desc_idx];
|
||||
vlib_cli_output (vm, " %5u 0x%016llx 0x%08x 0x%08x",
|
||||
desc_idx, txd->address, txd->flags[0],
|
||||
txd->flags[1]);
|
||||
}
|
||||
}
|
||||
else if (which == VMXNET3_SHOW_TX_COMP)
|
||||
{
|
||||
vlib_cli_output (vm, "TX completion descriptors table");
|
||||
vlib_cli_output (vm, " %5s %10s %10s",
|
||||
"slot", "index", "flags");
|
||||
if (show_one_slot)
|
||||
{
|
||||
tx_comp = &txq->tx_comp[slot];
|
||||
vlib_cli_output (vm, " %5u 0x%08x 0x%08x",
|
||||
slot, tx_comp->index, tx_comp->flags);
|
||||
}
|
||||
else
|
||||
for (desc_idx = 0; desc_idx < txq->size; desc_idx++)
|
||||
{
|
||||
tx_comp = &txq->tx_comp[desc_idx];
|
||||
vlib_cli_output (vm, " %5u 0x%08x 0x%08x",
|
||||
desc_idx, tx_comp->index,
|
||||
tx_comp->flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -308,8 +410,9 @@ show_vmxnet3_fn (vlib_main_t * vm, unformat_input_t * input,
|
||||
vmxnet3_device_t *vd;
|
||||
clib_error_t *error = 0;
|
||||
u32 hw_if_index, *hw_if_indices = 0;
|
||||
vnet_hw_interface_t *hi;
|
||||
u8 show_descr = 0;
|
||||
vnet_hw_interface_t *hi = 0;
|
||||
u8 show_descr = 0, show_one_table = 0, show_one_slot = 0;
|
||||
u32 which = ~0, slot;
|
||||
|
||||
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
|
||||
{
|
||||
@ -325,8 +428,110 @@ show_vmxnet3_fn (vlib_main_t * vm, unformat_input_t * input,
|
||||
}
|
||||
vec_add1 (hw_if_indices, hw_if_index);
|
||||
}
|
||||
else if (unformat (input, "descriptors") || unformat (input, "desc"))
|
||||
else if (unformat (input, "desc"))
|
||||
show_descr = 1;
|
||||
else if (hi)
|
||||
{
|
||||
vmxnet3_device_t *vd =
|
||||
vec_elt_at_index (vmxm->devices, hi->dev_instance);
|
||||
|
||||
if (unformat (input, "rx-comp"))
|
||||
{
|
||||
show_one_table = 1;
|
||||
which = VMXNET3_SHOW_RX_COMP;
|
||||
if (unformat (input, "%u", &slot))
|
||||
{
|
||||
vmxnet3_rxq_t *rxq = vec_elt_at_index (vd->rxqs, 0);
|
||||
|
||||
if (slot >= rxq->size)
|
||||
{
|
||||
error = clib_error_return (0,
|
||||
"slot size must be < rx queue "
|
||||
"size %u", rxq->size);
|
||||
goto done;
|
||||
}
|
||||
show_one_slot = 1;
|
||||
}
|
||||
}
|
||||
else if (unformat (input, "rx-desc-0"))
|
||||
{
|
||||
show_one_table = 1;
|
||||
which = VMXNET3_SHOW_RX_DESC0;
|
||||
if (unformat (input, "%u", &slot))
|
||||
{
|
||||
vmxnet3_rxq_t *rxq = vec_elt_at_index (vd->rxqs, 0);
|
||||
|
||||
if (slot >= rxq->size)
|
||||
{
|
||||
error = clib_error_return (0,
|
||||
"slot size must be < rx queue "
|
||||
"size %u", rxq->size);
|
||||
goto done;
|
||||
}
|
||||
show_one_slot = 1;
|
||||
}
|
||||
}
|
||||
else if (unformat (input, "rx-desc-1"))
|
||||
{
|
||||
show_one_table = 1;
|
||||
which = VMXNET3_SHOW_RX_DESC1;
|
||||
if (unformat (input, "%u", &slot))
|
||||
{
|
||||
vmxnet3_rxq_t *rxq = vec_elt_at_index (vd->rxqs, 0);
|
||||
|
||||
if (slot >= rxq->size)
|
||||
{
|
||||
error = clib_error_return (0,
|
||||
"slot size must be < rx queue "
|
||||
"size %u", rxq->size);
|
||||
goto done;
|
||||
}
|
||||
show_one_slot = 1;
|
||||
}
|
||||
}
|
||||
else if (unformat (input, "tx-comp"))
|
||||
{
|
||||
show_one_table = 1;
|
||||
which = VMXNET3_SHOW_TX_COMP;
|
||||
if (unformat (input, "%u", &slot))
|
||||
{
|
||||
vmxnet3_txq_t *txq = vec_elt_at_index (vd->txqs, 0);
|
||||
|
||||
if (slot >= txq->size)
|
||||
{
|
||||
error = clib_error_return (0,
|
||||
"slot size must be < tx queue "
|
||||
"size %u", txq->size);
|
||||
goto done;
|
||||
}
|
||||
show_one_slot = 1;
|
||||
}
|
||||
}
|
||||
else if (unformat (input, "tx-desc"))
|
||||
{
|
||||
show_one_table = 1;
|
||||
which = VMXNET3_SHOW_TX_DESC;
|
||||
if (unformat (input, "%u", &slot))
|
||||
{
|
||||
vmxnet3_txq_t *txq = vec_elt_at_index (vd->txqs, 0);
|
||||
|
||||
if (slot >= txq->size)
|
||||
{
|
||||
error = clib_error_return (0,
|
||||
"slot size must be < tx queue "
|
||||
"size %u", txq->size);
|
||||
goto done;
|
||||
}
|
||||
show_one_slot = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error = clib_error_return (0, "unknown input `%U'",
|
||||
format_unformat_error, input);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error = clib_error_return (0, "unknown input `%U'",
|
||||
@ -342,7 +547,8 @@ show_vmxnet3_fn (vlib_main_t * vm, unformat_input_t * input,
|
||||
);
|
||||
}
|
||||
|
||||
show_vmxnet3 (vm, hw_if_indices, show_descr);
|
||||
show_vmxnet3 (vm, hw_if_indices, show_descr, show_one_table, which,
|
||||
show_one_slot, slot);
|
||||
|
||||
done:
|
||||
vec_free (hw_if_indices);
|
||||
@ -352,7 +558,8 @@ done:
|
||||
/* *INDENT-OFF* */
|
||||
VLIB_CLI_COMMAND (show_vmxnet3_command, static) = {
|
||||
.path = "show vmxnet3",
|
||||
.short_help = "show vmxnet3 [<interface>]",
|
||||
.short_help = "show vmxnet3 [[<interface>] ([desc] | ([rx-comp] | "
|
||||
"[rx-desc-0] | [rx-desc-1] | [tx-comp] | [tx-desc]) [<slot>])]",
|
||||
.function = show_vmxnet3_fn,
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
@ -360,9 +567,12 @@ VLIB_CLI_COMMAND (show_vmxnet3_command, static) = {
|
||||
clib_error_t *
|
||||
vmxnet3_cli_init (vlib_main_t * vm)
|
||||
{
|
||||
vmxnet3_main_t *vmxm = &vmxnet3_main;
|
||||
|
||||
/* initialize binary API */
|
||||
vmxnet3_plugin_api_hookup (vm);
|
||||
|
||||
vmxm->log_default = vlib_log_register_class ("vmxnet3", 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,7 @@
|
||||
_(BUFFER_ALLOC, "buffer alloc error") \
|
||||
_(RX_PACKET_NO_SOP, "Rx packet error - no SOP") \
|
||||
_(RX_PACKET, "Rx packet error") \
|
||||
_(RX_PACKET_EOP, "Rx packet error found on EOP") \
|
||||
_(NO_BUFFER, "Rx no buffer error")
|
||||
|
||||
typedef enum
|
||||
@ -79,7 +80,6 @@ vmxnet3_device_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
|
||||
uword n_trace = vlib_get_trace_count (vm, node);
|
||||
u32 n_rx_packets = 0, n_rx_bytes = 0;
|
||||
vmxnet3_rx_comp *rx_comp;
|
||||
u32 comp_idx;
|
||||
u32 desc_idx;
|
||||
vmxnet3_rxq_t *rxq;
|
||||
u32 thread_index = vm->thread_index;
|
||||
@ -98,16 +98,14 @@ vmxnet3_device_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
|
||||
comp_ring = &rxq->rx_comp_ring;
|
||||
bi = buffer_indices;
|
||||
next = nexts;
|
||||
rx_comp = &rxq->rx_comp[comp_ring->next];
|
||||
|
||||
while (PREDICT_TRUE (n_rx_packets < VLIB_FRAME_SIZE) &&
|
||||
(comp_ring->gen ==
|
||||
(rxq->rx_comp[comp_ring->next].flags & VMXNET3_RXCF_GEN)))
|
||||
(comp_ring->gen == (rx_comp->flags & VMXNET3_RXCF_GEN)))
|
||||
{
|
||||
vlib_buffer_t *b0;
|
||||
u32 bi0;
|
||||
|
||||
comp_idx = comp_ring->next;
|
||||
rx_comp = &rxq->rx_comp[comp_idx];
|
||||
|
||||
rid = vmxnet3_find_rid (vd, rx_comp);
|
||||
ring = &rxq->rx_ring[rid];
|
||||
|
||||
@ -117,10 +115,15 @@ vmxnet3_device_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
|
||||
{
|
||||
vlib_error_count (vm, node->node_index,
|
||||
VMXNET3_INPUT_ERROR_NO_BUFFER, 1);
|
||||
if (hb)
|
||||
{
|
||||
vlib_buffer_free_one (vm, vlib_get_buffer_index (vm, hb));
|
||||
hb = 0;
|
||||
}
|
||||
prev_b0 = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
vmxnet3_rx_comp_ring_advance_next (rxq);
|
||||
desc_idx = rx_comp->index & VMXNET3_RXC_INDEX;
|
||||
ring->consume = desc_idx;
|
||||
rxd = &rxq->rx_desc[rid][desc_idx];
|
||||
@ -146,14 +149,14 @@ vmxnet3_device_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
|
||||
{
|
||||
vlib_buffer_free_one (vm, bi0);
|
||||
vlib_error_count (vm, node->node_index,
|
||||
VMXNET3_INPUT_ERROR_RX_PACKET, 1);
|
||||
VMXNET3_INPUT_ERROR_RX_PACKET_EOP, 1);
|
||||
if (hb && vlib_get_buffer_index (vm, hb) != bi0)
|
||||
{
|
||||
vlib_buffer_free_one (vm, vlib_get_buffer_index (vm, hb));
|
||||
hb = 0;
|
||||
}
|
||||
prev_b0 = 0;
|
||||
continue;
|
||||
goto next;
|
||||
}
|
||||
|
||||
if (rx_comp->index & VMXNET3_RXCI_SOP)
|
||||
@ -199,7 +202,7 @@ vmxnet3_device_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
|
||||
vlib_buffer_free_one (vm, vlib_get_buffer_index (vm, hb));
|
||||
hb = 0;
|
||||
}
|
||||
continue;
|
||||
goto next;
|
||||
}
|
||||
}
|
||||
else if (prev_b0) // !sop && !eop
|
||||
@ -213,7 +216,15 @@ vmxnet3_device_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT (0);
|
||||
vlib_error_count (vm, node->node_index,
|
||||
VMXNET3_INPUT_ERROR_RX_PACKET, 1);
|
||||
vlib_buffer_free_one (vm, bi0);
|
||||
if (hb && vlib_get_buffer_index (vm, hb) != bi0)
|
||||
{
|
||||
vlib_buffer_free_one (vm, vlib_get_buffer_index (vm, hb));
|
||||
hb = 0;
|
||||
}
|
||||
goto next;
|
||||
}
|
||||
|
||||
n_rx_bytes += b0->current_length;
|
||||
@ -275,6 +286,10 @@ vmxnet3_device_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
|
||||
hb = 0;
|
||||
got_packet = 0;
|
||||
}
|
||||
|
||||
next:
|
||||
vmxnet3_rx_comp_ring_advance_next (rxq);
|
||||
rx_comp = &rxq->rx_comp[comp_ring->next];
|
||||
}
|
||||
|
||||
if (PREDICT_FALSE ((n_trace = vlib_get_trace_count (vm, node))))
|
||||
|
@ -143,15 +143,22 @@ VNET_DEVICE_CLASS_TX_FN (vmxnet3_device_class) (vlib_main_t * vm,
|
||||
}
|
||||
if (PREDICT_FALSE (space_left < space_needed))
|
||||
{
|
||||
vlib_buffer_free_one (vm, bi0);
|
||||
vlib_error_count (vm, node->node_index,
|
||||
VMXNET3_TX_ERROR_NO_FREE_SLOTS, 1);
|
||||
buffers++;
|
||||
n_left--;
|
||||
/*
|
||||
* Drop this packet. But we may have enough room for the next packet
|
||||
*/
|
||||
continue;
|
||||
vmxnet3_txq_release (vm, vd, txq);
|
||||
space_left = vmxnet3_tx_ring_space_left (txq);
|
||||
|
||||
if (PREDICT_FALSE (space_left < space_needed))
|
||||
{
|
||||
vlib_buffer_free_one (vm, bi0);
|
||||
vlib_error_count (vm, node->node_index,
|
||||
VMXNET3_TX_ERROR_NO_FREE_SLOTS, 1);
|
||||
buffers++;
|
||||
n_left--;
|
||||
/*
|
||||
* Drop this packet. But we may have enough room for the next
|
||||
* packet
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -190,7 +197,8 @@ VNET_DEVICE_CLASS_TX_FN (vmxnet3_device_class) (vlib_main_t * vm,
|
||||
* Device can start reading the packet
|
||||
*/
|
||||
txq->tx_desc[first_idx].flags[0] ^= VMXNET3_TXF_GEN;
|
||||
vmxnet3_reg_write (vd, 0, VMXNET3_REG_TXPROD, txq->tx_ring.produce);
|
||||
vmxnet3_reg_write_inline (vd, 0, VMXNET3_REG_TXPROD,
|
||||
txq->tx_ring.produce);
|
||||
|
||||
buffers++;
|
||||
n_left--;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user