Compare commits
34 Commits
v18.10
...
stable/1810
| 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 |
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+10
-6
@@ -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;
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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;
|
||||
|
||||
+57
-47
@@ -397,64 +397,67 @@ nat_ed_session_alloc (snat_main_t * sm, snat_user_t * u, u32 thread_index,
|
||||
u32 oldest_index;
|
||||
u64 sess_timeout_time;
|
||||
|
||||
if ((u->nsessions + u->nstaticsessions) >= sm->max_translations_per_user)
|
||||
if (PREDICT_FALSE (!(u->nsessions) && !(u->nstaticsessions)))
|
||||
goto alloc_new;
|
||||
|
||||
oldest_index =
|
||||
clib_dlist_remove_head (tsm->list_pool,
|
||||
u->sessions_per_user_list_head_index);
|
||||
oldest_elt = pool_elt_at_index (tsm->list_pool, oldest_index);
|
||||
s = pool_elt_at_index (tsm->sessions, oldest_elt->value);
|
||||
sess_timeout_time = s->last_heard + (f64) nat44_session_get_timeout (sm, s);
|
||||
if (now >= sess_timeout_time)
|
||||
{
|
||||
oldest_index =
|
||||
clib_dlist_remove_head (tsm->list_pool,
|
||||
u->sessions_per_user_list_head_index);
|
||||
oldest_elt = pool_elt_at_index (tsm->list_pool, oldest_index);
|
||||
s = pool_elt_at_index (tsm->sessions, oldest_elt->value);
|
||||
sess_timeout_time =
|
||||
s->last_heard + (f64) nat44_session_get_timeout (sm, s);
|
||||
if (now >= sess_timeout_time)
|
||||
{
|
||||
clib_dlist_addtail (tsm->list_pool,
|
||||
u->sessions_per_user_list_head_index,
|
||||
oldest_index);
|
||||
nat_free_session_data (sm, s, thread_index);
|
||||
if (snat_is_session_static (s))
|
||||
u->nstaticsessions--;
|
||||
else
|
||||
u->nsessions--;
|
||||
s->flags = 0;
|
||||
s->total_bytes = 0;
|
||||
s->total_pkts = 0;
|
||||
s->state = 0;
|
||||
s->ext_host_addr.as_u32 = 0;
|
||||
s->ext_host_port = 0;
|
||||
s->ext_host_nat_addr.as_u32 = 0;
|
||||
s->ext_host_nat_port = 0;
|
||||
}
|
||||
clib_dlist_addtail (tsm->list_pool,
|
||||
u->sessions_per_user_list_head_index, oldest_index);
|
||||
nat_free_session_data (sm, s, thread_index);
|
||||
if (snat_is_session_static (s))
|
||||
u->nstaticsessions--;
|
||||
else
|
||||
u->nsessions--;
|
||||
s->flags = 0;
|
||||
s->total_bytes = 0;
|
||||
s->total_pkts = 0;
|
||||
s->state = 0;
|
||||
s->ext_host_addr.as_u32 = 0;
|
||||
s->ext_host_port = 0;
|
||||
s->ext_host_nat_addr.as_u32 = 0;
|
||||
s->ext_host_nat_port = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
clib_dlist_addhead (tsm->list_pool,
|
||||
u->sessions_per_user_list_head_index, oldest_index);
|
||||
if ((u->nsessions + u->nstaticsessions) >=
|
||||
sm->max_translations_per_user)
|
||||
{
|
||||
clib_dlist_addhead (tsm->list_pool,
|
||||
u->sessions_per_user_list_head_index,
|
||||
oldest_index);
|
||||
nat_log_warn ("max translations per user %U", format_ip4_address,
|
||||
&u->addr);
|
||||
snat_ipfix_logging_max_entries_per_user
|
||||
(sm->max_translations_per_user, u->addr.as_u32);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
alloc_new:
|
||||
pool_get (tsm->sessions, s);
|
||||
memset (s, 0, sizeof (*s));
|
||||
|
||||
/* Create list elts */
|
||||
pool_get (tsm->list_pool, per_user_translation_list_elt);
|
||||
clib_dlist_init (tsm->list_pool,
|
||||
per_user_translation_list_elt - tsm->list_pool);
|
||||
|
||||
per_user_translation_list_elt->value = s - tsm->sessions;
|
||||
s->per_user_index = per_user_translation_list_elt - tsm->list_pool;
|
||||
s->per_user_list_head_index = u->sessions_per_user_list_head_index;
|
||||
|
||||
clib_dlist_addtail (tsm->list_pool,
|
||||
s->per_user_list_head_index,
|
||||
per_user_translation_list_elt - tsm->list_pool);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pool_get (tsm->sessions, s);
|
||||
memset (s, 0, sizeof (*s));
|
||||
|
||||
/* Create list elts */
|
||||
pool_get (tsm->list_pool, per_user_translation_list_elt);
|
||||
clib_dlist_init (tsm->list_pool,
|
||||
per_user_translation_list_elt - tsm->list_pool);
|
||||
|
||||
per_user_translation_list_elt->value = s - tsm->sessions;
|
||||
s->per_user_index = per_user_translation_list_elt - tsm->list_pool;
|
||||
s->per_user_list_head_index = u->sessions_per_user_list_head_index;
|
||||
|
||||
clib_dlist_addtail (tsm->list_pool,
|
||||
s->per_user_list_head_index,
|
||||
per_user_translation_list_elt - tsm->list_pool);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -558,6 +561,10 @@ is_snat_address_used_in_static_mapping (snat_main_t * sm, ip4_address_t addr)
|
||||
/* *INDENT-OFF* */
|
||||
pool_foreach (m, sm->static_mappings,
|
||||
({
|
||||
if (is_addr_only_static_mapping (m) ||
|
||||
is_out2in_only_static_mapping (m) ||
|
||||
is_identity_static_mapping (m))
|
||||
continue;
|
||||
if (m->external_addr.as_u32 == addr.as_u32)
|
||||
return 1;
|
||||
}));
|
||||
@@ -954,6 +961,9 @@ snat_add_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr,
|
||||
|
||||
if (identity_nat)
|
||||
{
|
||||
if (vrf_id == ~0)
|
||||
vrf_id = sm->inside_vrf_id;
|
||||
|
||||
for (i = 0; i < vec_len (m->locals); i++)
|
||||
{
|
||||
if (m->locals[i].vrf_id == vrf_id)
|
||||
|
||||
@@ -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
|
||||
@@ -673,6 +675,12 @@ unformat_function_t unformat_snat_protocol;
|
||||
*/
|
||||
#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__)
|
||||
|
||||
@@ -226,7 +226,8 @@ format_snat_static_mapping (u8 * s, va_list * args)
|
||||
s = format (s, "identity mapping %U",
|
||||
format_ip4_address, &m->local_addr);
|
||||
else
|
||||
s = format (s, "identity mapping %U:%d",
|
||||
s = format (s, "identity mapping %U %U:%d",
|
||||
format_snat_protocol, m->proto,
|
||||
format_ip4_address, &m->local_addr, m->local_port);
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1443,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;
|
||||
}
|
||||
|
||||
@@ -1474,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,
|
||||
|
||||
@@ -567,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;
|
||||
}
|
||||
|
||||
|
||||
@@ -197,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--;
|
||||
|
||||
@@ -319,7 +319,7 @@ vmxnet3_device_init (vlib_main_t * vm, vmxnet3_device_t * vd,
|
||||
ret = vmxnet3_reg_read (vd, 1, VMXNET3_REG_CMD);
|
||||
if (ret != 0)
|
||||
{
|
||||
error = clib_error_return (0, "error on quisecing device rc (%u)", ret);
|
||||
error = clib_error_return (0, "error on quiescing device rc (%u)", ret);
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -497,6 +497,9 @@ vmxnet3_create_if (vlib_main_t * vm, vmxnet3_create_if_args_t * args)
|
||||
clib_error_return (error,
|
||||
"queue size must be <= 4096, >= 64, "
|
||||
"and multiples of 64");
|
||||
vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
|
||||
format_vlib_pci_addr, &args->addr,
|
||||
"queue size must be <= 4096, >= 64, and multiples of 64");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -507,6 +510,8 @@ vmxnet3_create_if (vlib_main_t * vm, vmxnet3_create_if_args_t * args)
|
||||
args->rv = VNET_API_ERROR_INVALID_VALUE;
|
||||
args->error =
|
||||
clib_error_return (error, "PCI address in use");
|
||||
vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
|
||||
format_vlib_pci_addr, &args->addr, "pci address in use");
|
||||
return;
|
||||
}
|
||||
}));
|
||||
@@ -528,37 +533,70 @@ vmxnet3_create_if (vlib_main_t * vm, vmxnet3_create_if_args_t * args)
|
||||
args->error =
|
||||
clib_error_return (error, "pci-addr %U", format_vlib_pci_addr,
|
||||
&args->addr);
|
||||
vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default, "%U: %s",
|
||||
format_vlib_pci_addr, &args->addr,
|
||||
"error encountered on pci device open");
|
||||
return;
|
||||
}
|
||||
vd->pci_dev_handle = h;
|
||||
|
||||
/*
|
||||
* Do not use vmxnet3_log_error prior to this line since the macro
|
||||
* references vd->pci_dev_handle
|
||||
*/
|
||||
vd->pci_dev_handle = h;
|
||||
vlib_pci_set_private_data (h, vd->dev_instance);
|
||||
|
||||
if ((error = vlib_pci_bus_master_enable (h)))
|
||||
goto error;
|
||||
{
|
||||
vmxnet3_log_error (vd, "error encountered on pci bus master enable");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((error = vlib_pci_map_region (h, 0, (void **) &vd->bar[0])))
|
||||
goto error;
|
||||
{
|
||||
vmxnet3_log_error (vd, "error encountered on pci map region for bar 0");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((error = vlib_pci_map_region (h, 1, (void **) &vd->bar[1])))
|
||||
goto error;
|
||||
{
|
||||
vmxnet3_log_error (vd, "error encountered on pci map region for bar 1");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((error = vlib_pci_register_msix_handler (h, 0, 1,
|
||||
&vmxnet3_irq_0_handler)))
|
||||
goto error;
|
||||
{
|
||||
vmxnet3_log_error (vd,
|
||||
"error encountered on pci register msix handler 0");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((error = vlib_pci_register_msix_handler (h, 1, 1,
|
||||
&vmxnet3_irq_1_handler)))
|
||||
goto error;
|
||||
{
|
||||
vmxnet3_log_error (vd,
|
||||
"error encountered on pci register msix handler 1");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((error = vlib_pci_enable_msix_irq (h, 0, 2)))
|
||||
goto error;
|
||||
{
|
||||
vmxnet3_log_error (vd, "error encountered on pci enable msix irq");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((error = vlib_pci_intr_enable (h)))
|
||||
goto error;
|
||||
{
|
||||
vmxnet3_log_error (vd, "error encountered on pci interrupt enable");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((error = vmxnet3_device_init (vm, vd, args)))
|
||||
goto error;
|
||||
{
|
||||
vmxnet3_log_error (vd, "error encountered on device init");
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* create interface */
|
||||
error = ethernet_register_interface (vnm, vmxnet3_device_class.index,
|
||||
@@ -566,7 +604,11 @@ vmxnet3_create_if (vlib_main_t * vm, vmxnet3_create_if_args_t * args)
|
||||
&vd->hw_if_index, vmxnet3_flag_change);
|
||||
|
||||
if (error)
|
||||
goto error;
|
||||
{
|
||||
vmxnet3_log_error (vd,
|
||||
"error encountered on ethernet register interface");
|
||||
goto error;
|
||||
}
|
||||
|
||||
vnet_sw_interface_t *sw = vnet_get_hw_sw_interface (vnm, vd->hw_if_index);
|
||||
vd->sw_if_index = sw->sw_if_index;
|
||||
|
||||
@@ -166,7 +166,7 @@ enum
|
||||
_(7, GET_DEV_EXTRA_INFO, "get dev extra info") \
|
||||
_(8, GET_CONF_INTR, "get conf intr") \
|
||||
_(9, GET_ADAPTIVE_RING_INFO, "get adaptive ring info") \
|
||||
_(10, GET_TXDATA_DESC_SIZE, "gte txdata desc size") \
|
||||
_(10, GET_TXDATA_DESC_SIZE, "get txdata desc size") \
|
||||
_(11, RESERVED5, "reserved5")
|
||||
|
||||
enum
|
||||
@@ -496,6 +496,7 @@ typedef struct
|
||||
vlib_physmem_region_index_t physmem_region;
|
||||
u32 physmem_region_alloc;
|
||||
u16 msg_id_base;
|
||||
vlib_log_class_t log_default;
|
||||
} vmxnet3_main_t;
|
||||
|
||||
extern vmxnet3_main_t vmxnet3_main;
|
||||
@@ -531,16 +532,39 @@ format_function_t format_vmxnet3_device;
|
||||
format_function_t format_vmxnet3_device_name;
|
||||
format_function_t format_vmxnet3_input_trace;
|
||||
|
||||
#define vmxnet3_log_debug(dev, f, ...) \
|
||||
vlib_log (VLIB_LOG_LEVEL_DEBUG, vmxnet3_main.log_default, "%U: " f, \
|
||||
format_vlib_pci_addr, vlib_pci_get_addr(dev->pci_dev_handle), \
|
||||
## __VA_ARGS__)
|
||||
|
||||
#define vmxnet3_log_error(dev, f, ...) \
|
||||
vlib_log (VLIB_LOG_LEVEL_ERR, vmxnet3_main.log_default, "%U: " f, \
|
||||
format_vlib_pci_addr, vlib_pci_get_addr(dev->pci_dev_handle), \
|
||||
## __VA_ARGS__)
|
||||
|
||||
/* no log version, called by data plane */
|
||||
static_always_inline void
|
||||
vmxnet3_reg_write_inline (vmxnet3_device_t * vd, u8 bar, u32 addr, u32 val)
|
||||
{
|
||||
*(volatile u32 *) ((u8 *) vd->bar[bar] + addr) = val;
|
||||
}
|
||||
|
||||
static_always_inline void
|
||||
vmxnet3_reg_write (vmxnet3_device_t * vd, u8 bar, u32 addr, u32 val)
|
||||
{
|
||||
*(volatile u32 *) ((u8 *) vd->bar[bar] + addr) = val;
|
||||
vmxnet3_log_debug (vd, "reg wr bar %u addr 0x%x val 0x%x", bar, addr, val);
|
||||
vmxnet3_reg_write_inline (vd, bar, addr, val);
|
||||
}
|
||||
|
||||
static_always_inline u32
|
||||
vmxnet3_reg_read (vmxnet3_device_t * vd, u8 bar, u32 addr)
|
||||
{
|
||||
return *(volatile u32 *) (vd->bar[bar] + addr);
|
||||
u32 val;
|
||||
|
||||
val = *(volatile u32 *) (vd->bar[bar] + addr);
|
||||
vmxnet3_log_debug (vd, "reg rd bar %u addr 0x%x val 0x%x", bar, addr, val);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static_always_inline uword
|
||||
@@ -600,7 +624,7 @@ vmxnet3_rxq_refill_ring0 (vlib_main_t * vm, vmxnet3_device_t * vd,
|
||||
n_alloc--;
|
||||
}
|
||||
|
||||
vmxnet3_reg_write (vd, 0, VMXNET3_REG_RXPROD, ring->produce);
|
||||
vmxnet3_reg_write_inline (vd, 0, VMXNET3_REG_RXPROD, ring->produce);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -642,7 +666,7 @@ vmxnet3_rxq_refill_ring1 (vlib_main_t * vm, vmxnet3_device_t * vd,
|
||||
n_alloc--;
|
||||
}
|
||||
|
||||
vmxnet3_reg_write (vd, 0, VMXNET3_REG_RXPROD2, ring->produce);
|
||||
vmxnet3_reg_write_inline (vd, 0, VMXNET3_REG_RXPROD2, ring->produce);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -29,6 +29,8 @@ add_vpp_executable(vpp_api_test ENABLE_EXPORTS
|
||||
plugin.c
|
||||
json_format.c
|
||||
|
||||
DEPENDS api_headers
|
||||
|
||||
LINK_LIBRARIES
|
||||
vlibmemoryclient
|
||||
svm
|
||||
|
||||
@@ -20428,14 +20428,14 @@ vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
|
||||
print (vam->ofp,
|
||||
" weight %d, sw_if_index %d, is_local %d, is_drop %d, "
|
||||
"is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
|
||||
ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
|
||||
fp->weight, ntohl (fp->sw_if_index), fp->is_local,
|
||||
fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
|
||||
format_ip6_address, fp->next_hop);
|
||||
else if (fp->afi == IP46_TYPE_IP4)
|
||||
print (vam->ofp,
|
||||
" weight %d, sw_if_index %d, is_local %d, is_drop %d, "
|
||||
"is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
|
||||
ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
|
||||
fp->weight, ntohl (fp->sw_if_index), fp->is_local,
|
||||
fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
|
||||
format_ip4_address, fp->next_hop);
|
||||
}
|
||||
|
||||
@@ -51,6 +51,14 @@
|
||||
#define VLIB_BUFFER_DATA_SIZE (2048)
|
||||
#define VLIB_BUFFER_PRE_DATA_SIZE __PRE_DATA_SIZE
|
||||
|
||||
/* Minimum buffer chain segment size. Does not apply to last buffer in chain.
|
||||
Dataplane code can safely asume that specified amount of data is not split
|
||||
into 2 chained buffers */
|
||||
#define VLIB_BUFFER_MIN_CHAIN_SEG_SIZE (128)
|
||||
|
||||
/* Amount of head buffer data copied to each replica head buffer */
|
||||
#define VLIB_BUFFER_CLONE_HEAD_SIZE (256)
|
||||
|
||||
typedef u8 vlib_buffer_free_list_index_t;
|
||||
|
||||
/** \file
|
||||
@@ -212,6 +220,9 @@ vlib_buffer_advance (vlib_buffer_t * b, word l)
|
||||
ASSERT (b->current_length >= l);
|
||||
b->current_data += l;
|
||||
b->current_length -= l;
|
||||
|
||||
ASSERT ((b->flags & VLIB_BUFFER_NEXT_PRESENT) == 0 ||
|
||||
b->current_length >= VLIB_BUFFER_MIN_CHAIN_SEG_SIZE);
|
||||
}
|
||||
|
||||
/** \brief Check if there is enough space in buffer to advance
|
||||
|
||||
@@ -1269,6 +1269,143 @@ vlib_buffer_chain_compress (vlib_main_t * vm,
|
||||
(first->flags & VLIB_BUFFER_NEXT_PRESENT));
|
||||
}
|
||||
|
||||
always_inline u32
|
||||
vlib_buffer_space_left_at_end (vlib_main_t * vm, vlib_buffer_t * b)
|
||||
{
|
||||
return b->data + VLIB_BUFFER_DATA_SIZE -
|
||||
((u8 *) vlib_buffer_get_current (b) + b->current_length);
|
||||
}
|
||||
|
||||
always_inline u32
|
||||
vlib_buffer_chain_linearize (vlib_main_t * vm, vlib_buffer_t * b)
|
||||
{
|
||||
vlib_buffer_t *db = b, *sb, *first = b;
|
||||
int is_cloned = 0;
|
||||
u32 bytes_left = 0, data_size;
|
||||
u16 src_left, dst_left, n_buffers = 1;
|
||||
u8 *dp, *sp;
|
||||
u32 to_free = 0;
|
||||
|
||||
if (PREDICT_TRUE ((b->flags & VLIB_BUFFER_NEXT_PRESENT) == 0))
|
||||
return 1;
|
||||
|
||||
data_size = VLIB_BUFFER_DATA_SIZE;
|
||||
|
||||
dst_left = vlib_buffer_space_left_at_end (vm, b);
|
||||
|
||||
while (b->flags & VLIB_BUFFER_NEXT_PRESENT)
|
||||
{
|
||||
b = vlib_get_buffer (vm, b->next_buffer);
|
||||
if (b->n_add_refs > 0)
|
||||
is_cloned = 1;
|
||||
bytes_left += b->current_length;
|
||||
n_buffers++;
|
||||
}
|
||||
|
||||
/* if buffer is cloned, create completely new chain - unless everything fits
|
||||
* into one buffer */
|
||||
if (is_cloned && bytes_left >= dst_left)
|
||||
{
|
||||
u32 len = 0;
|
||||
u32 space_needed = bytes_left - dst_left;
|
||||
u32 tail;
|
||||
|
||||
if (vlib_buffer_alloc (vm, &tail, 1) == 0)
|
||||
return 0;
|
||||
|
||||
++n_buffers;
|
||||
len += data_size;
|
||||
b = vlib_get_buffer (vm, tail);
|
||||
|
||||
while (len < space_needed)
|
||||
{
|
||||
u32 bi;
|
||||
if (vlib_buffer_alloc (vm, &bi, 1) == 0)
|
||||
{
|
||||
vlib_buffer_free_one (vm, tail);
|
||||
return 0;
|
||||
}
|
||||
b->flags = VLIB_BUFFER_NEXT_PRESENT;
|
||||
b->next_buffer = bi;
|
||||
b = vlib_get_buffer (vm, bi);
|
||||
len += data_size;
|
||||
n_buffers++;
|
||||
}
|
||||
sb = vlib_get_buffer (vm, first->next_buffer);
|
||||
to_free = first->next_buffer;
|
||||
first->next_buffer = tail;
|
||||
}
|
||||
else
|
||||
sb = vlib_get_buffer (vm, first->next_buffer);
|
||||
|
||||
src_left = sb->current_length;
|
||||
sp = vlib_buffer_get_current (sb);
|
||||
dp = vlib_buffer_get_tail (db);
|
||||
|
||||
while (bytes_left)
|
||||
{
|
||||
u16 bytes_to_copy;
|
||||
|
||||
if (dst_left == 0)
|
||||
{
|
||||
if (db != first)
|
||||
db->current_data = 0;
|
||||
db->current_length = dp - (u8 *) vlib_buffer_get_current (db);
|
||||
ASSERT (db->flags & VLIB_BUFFER_NEXT_PRESENT);
|
||||
db = vlib_get_buffer (vm, db->next_buffer);
|
||||
dst_left = data_size;
|
||||
dp = db->data;
|
||||
}
|
||||
|
||||
while (src_left == 0)
|
||||
{
|
||||
ASSERT (sb->flags & VLIB_BUFFER_NEXT_PRESENT);
|
||||
sb = vlib_get_buffer (vm, sb->next_buffer);
|
||||
src_left = sb->current_length;
|
||||
sp = vlib_buffer_get_current (sb);
|
||||
}
|
||||
|
||||
bytes_to_copy = clib_min (dst_left, src_left);
|
||||
|
||||
if (dp != sp)
|
||||
{
|
||||
if (sb == db)
|
||||
bytes_to_copy = clib_min (bytes_to_copy, sp - dp);
|
||||
|
||||
clib_memcpy (dp, sp, bytes_to_copy);
|
||||
}
|
||||
|
||||
src_left -= bytes_to_copy;
|
||||
dst_left -= bytes_to_copy;
|
||||
dp += bytes_to_copy;
|
||||
sp += bytes_to_copy;
|
||||
bytes_left -= bytes_to_copy;
|
||||
}
|
||||
if (db != first)
|
||||
db->current_data = 0;
|
||||
db->current_length = dp - (u8 *) vlib_buffer_get_current (db);
|
||||
|
||||
if (is_cloned && to_free)
|
||||
vlib_buffer_free_one (vm, to_free);
|
||||
else
|
||||
{
|
||||
if (db->flags & VLIB_BUFFER_NEXT_PRESENT)
|
||||
vlib_buffer_free_one (vm, db->next_buffer);
|
||||
db->flags &= ~VLIB_BUFFER_NEXT_PRESENT;
|
||||
b = first;
|
||||
n_buffers = 1;
|
||||
while (b->flags & VLIB_BUFFER_NEXT_PRESENT)
|
||||
{
|
||||
b = vlib_get_buffer (vm, b->next_buffer);
|
||||
++n_buffers;
|
||||
}
|
||||
}
|
||||
|
||||
first->flags &= ~VLIB_BUFFER_TOTAL_LENGTH_VALID;
|
||||
|
||||
return n_buffers;
|
||||
}
|
||||
|
||||
#endif /* included_vlib_buffer_funcs_h */
|
||||
|
||||
/*
|
||||
|
||||
@@ -898,6 +898,28 @@ vlibmemory_init (vlib_main_t * vm)
|
||||
api_main_t *am = &api_main;
|
||||
svm_map_region_args_t _a, *a = &_a;
|
||||
clib_error_t *error;
|
||||
u8 *remove_path1, *remove_path2;
|
||||
|
||||
/*
|
||||
* By popular request / to avoid support fires, remove any old api segment
|
||||
* files Right Here.
|
||||
*/
|
||||
if (am->root_path == 0)
|
||||
{
|
||||
remove_path1 = format (0, "/dev/shm/global_vm%c", 0);
|
||||
remove_path2 = format (0, "/dev/shm/vpe-api%c", 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
remove_path1 = format (0, "/dev/shm/%s-global_vm%c", am->root_path, 0);
|
||||
remove_path2 = format (0, "/dev/shm/%s-vpe-api%c", am->root_path, 0);
|
||||
}
|
||||
|
||||
(void) unlink ((char *) remove_path1);
|
||||
(void) unlink ((char *) remove_path2);
|
||||
|
||||
vec_free (remove_path1);
|
||||
vec_free (remove_path2);
|
||||
|
||||
memset (a, 0, sizeof (*a));
|
||||
a->root_path = am->root_path;
|
||||
|
||||
@@ -223,7 +223,7 @@ bier_lookup (vlib_main_t * vm,
|
||||
num_cloned = vlib_buffer_clone(vm, bi0,
|
||||
blm->blm_clones[thread_index],
|
||||
n_clones,
|
||||
n_bytes + 8);
|
||||
VLIB_BUFFER_CLONE_HEAD_SIZE);
|
||||
|
||||
if (num_cloned != vec_len(blm->blm_fmasks[thread_index]))
|
||||
{
|
||||
|
||||
@@ -512,11 +512,13 @@ bond_enslave (vlib_main_t * vm, bond_enslave_args_t * args)
|
||||
ethernet_set_rx_redirect (vnm, sif_hw, 1);
|
||||
}
|
||||
|
||||
if ((bif->mode == BOND_MODE_LACP) && bm->lacp_enable_disable)
|
||||
if (bif->mode == BOND_MODE_LACP)
|
||||
{
|
||||
(*bm->lacp_enable_disable) (vm, bif, sif, 1);
|
||||
if (bm->lacp_enable_disable)
|
||||
(*bm->lacp_enable_disable) (vm, bif, sif, 1);
|
||||
}
|
||||
else
|
||||
else if (sif->port_enabled &&
|
||||
(sif_hw->flags & VNET_HW_INTERFACE_FLAG_LINK_UP))
|
||||
{
|
||||
bond_enable_collecting_distributing (vm, sif);
|
||||
}
|
||||
|
||||
+16
-17
@@ -400,19 +400,21 @@ bond_sw_interface_up_down (vnet_main_t * vnm, u32 sw_if_index, u32 flags)
|
||||
if (sif)
|
||||
{
|
||||
sif->port_enabled = flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP;
|
||||
if (sif->lacp_enabled)
|
||||
return 0;
|
||||
|
||||
if (sif->port_enabled == 0)
|
||||
{
|
||||
if (sif->lacp_enabled == 0)
|
||||
{
|
||||
bond_disable_collecting_distributing (vm, sif);
|
||||
}
|
||||
bond_disable_collecting_distributing (vm, sif);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sif->lacp_enabled == 0)
|
||||
{
|
||||
bond_enable_collecting_distributing (vm, sif);
|
||||
}
|
||||
vnet_main_t *vnm = vnet_get_main ();
|
||||
vnet_hw_interface_t *hw =
|
||||
vnet_get_sup_hw_interface (vnm, sw_if_index);
|
||||
|
||||
if (hw->flags & VNET_HW_INTERFACE_FLAG_LINK_UP)
|
||||
bond_enable_collecting_distributing (vm, sif);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -433,19 +435,16 @@ bond_hw_interface_up_down (vnet_main_t * vnm, u32 hw_if_index, u32 flags)
|
||||
sif = bond_get_slave_by_sw_if_index (sw->sw_if_index);
|
||||
if (sif)
|
||||
{
|
||||
if (sif->lacp_enabled)
|
||||
return 0;
|
||||
|
||||
if (!(flags & VNET_HW_INTERFACE_FLAG_LINK_UP))
|
||||
{
|
||||
if (sif->lacp_enabled == 0)
|
||||
{
|
||||
bond_disable_collecting_distributing (vm, sif);
|
||||
}
|
||||
bond_disable_collecting_distributing (vm, sif);
|
||||
}
|
||||
else
|
||||
else if (sif->port_enabled)
|
||||
{
|
||||
if (sif->lacp_enabled == 0)
|
||||
{
|
||||
bond_enable_collecting_distributing (vm, sif);
|
||||
}
|
||||
bond_enable_collecting_distributing (vm, sif);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -169,7 +169,6 @@ add_buffer_to_slot (vlib_main_t * vm, virtio_vring_t * vring, u32 bi,
|
||||
return n_added;
|
||||
}
|
||||
|
||||
|
||||
static_always_inline uword
|
||||
virtio_interface_tx_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
|
||||
vlib_frame_t * frame, virtio_if_t * vif)
|
||||
@@ -184,6 +183,10 @@ virtio_interface_tx_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
|
||||
|
||||
clib_spinlock_lock_if_init (&vif->lockp);
|
||||
|
||||
if ((vring->used->flags & VIRTIO_RING_FLAG_MASK_INT) == 0 &&
|
||||
vring->last_kick_avail_idx != vring->avail->idx)
|
||||
virtio_kick (vring);
|
||||
|
||||
/* free consumed buffers */
|
||||
virtio_free_used_desc (vm, vring);
|
||||
|
||||
@@ -209,10 +212,7 @@ virtio_interface_tx_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
|
||||
vring->desc_next = next;
|
||||
vring->desc_in_use = used;
|
||||
if ((vring->used->flags & VIRTIO_RING_FLAG_MASK_INT) == 0)
|
||||
{
|
||||
u64 x = 1;
|
||||
CLIB_UNUSED (int r) = write (vring->kick_fd, &x, sizeof (x));
|
||||
}
|
||||
virtio_kick (vring);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -87,17 +87,23 @@ virtio_refill_vring (vlib_main_t * vm, virtio_vring_t * vring)
|
||||
u16 sz = vring->size;
|
||||
u16 mask = sz - 1;
|
||||
|
||||
more:
|
||||
used = vring->desc_in_use;
|
||||
|
||||
if (sz - used < sz / 8)
|
||||
return;
|
||||
|
||||
n_slots = sz - used;
|
||||
/* deliver free buffers in chunks of 64 */
|
||||
n_slots = clib_min (sz - used, 64);
|
||||
|
||||
next = vring->desc_next;
|
||||
avail = vring->avail->idx;
|
||||
n_slots = vlib_buffer_alloc_to_ring (vm, vring->buffers, next, vring->size,
|
||||
n_slots);
|
||||
|
||||
if (n_slots == 0)
|
||||
return;
|
||||
|
||||
while (n_slots)
|
||||
{
|
||||
struct vring_desc *d = &vring->desc[next];;
|
||||
@@ -117,10 +123,8 @@ virtio_refill_vring (vlib_main_t * vm, virtio_vring_t * vring)
|
||||
vring->desc_in_use = used;
|
||||
|
||||
if ((vring->used->flags & VIRTIO_RING_FLAG_MASK_INT) == 0)
|
||||
{
|
||||
u64 b = 1;
|
||||
CLIB_UNUSED (int r) = write (vring->kick_fd, &b, sizeof (b));
|
||||
}
|
||||
virtio_kick (vring);
|
||||
goto more;
|
||||
}
|
||||
|
||||
static_always_inline uword
|
||||
@@ -140,6 +144,10 @@ virtio_device_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
|
||||
u16 last = vring->last_used_idx;
|
||||
u16 n_left = vring->used->idx - last;
|
||||
|
||||
if ((vring->used->flags & VIRTIO_RING_FLAG_MASK_INT) == 0 &&
|
||||
vring->last_kick_avail_idx != vring->avail->idx)
|
||||
virtio_kick (vring);
|
||||
|
||||
if (n_left == 0)
|
||||
goto refill;
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user