Compare commits
36 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
693f4358de | ||
|
1f25d1a2ec | ||
|
a55cf2c1e5 | ||
|
584b99a012 | ||
|
cf2aa43150 | ||
|
363db88095 | ||
|
419e65629c | ||
|
90da24356f | ||
|
3c1f5321e5 | ||
|
cb74b6edd8 | ||
|
43f87e2d23 | ||
|
cf6511560e | ||
|
3f23e9a3c8 | ||
|
fe82e14267 | ||
|
1904214884 | ||
|
2671f1188d | ||
|
b98a3a87a9 | ||
|
1f752a3f8f | ||
|
45eb9713fe | ||
|
5faba3aae6 | ||
|
142db43bb6 | ||
|
a0e1f31b3d | ||
|
966bef4ad1 | ||
|
db0cf7963b | ||
|
8d9e80583f | ||
|
6795fb9f70 | ||
|
245576a438 | ||
|
68660906e6 | ||
|
3d4110fe0c | ||
|
f090a30eef | ||
|
edc40dbda0 | ||
|
aafe40deae | ||
|
205c75c8db | ||
|
1728f85066 | ||
|
2c386b26c6 | ||
|
826d4f7b1f |
@ -2,3 +2,4 @@
|
|||||||
host=gerrit.fd.io
|
host=gerrit.fd.io
|
||||||
port=29418
|
port=29418
|
||||||
project=vpp
|
project=vpp
|
||||||
|
defaultbranch=stable/1606
|
||||||
|
4
build-root/deb/debian/vpp.preinst
Normal file
4
build-root/deb/debian/vpp.preinst
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#!/bin/sh -e
|
||||||
|
|
||||||
|
# Add the vpp group
|
||||||
|
groupadd -f -r vpp
|
@ -3,6 +3,8 @@ Description=Vector Packet Processing Process
|
|||||||
After=syslog.target network.target auditd.service
|
After=syslog.target network.target auditd.service
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
|
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
|
ExecStart=/usr/bin/vpp -c /etc/vpp/startup.conf
|
||||||
Type=simple
|
Type=simple
|
||||||
Restart=on-failure
|
Restart=on-failure
|
||||||
|
@ -49,6 +49,10 @@ allocator (mheap.c), extendable printf-like interface built on top of vectors
|
|||||||
time-based function calls (timer.c).
|
time-based function calls (timer.c).
|
||||||
TODO: reference and describe only the .h files
|
TODO: reference and describe only the .h files
|
||||||
|
|
||||||
|
%pre
|
||||||
|
# Add the vpp group
|
||||||
|
groupadd -f -r vpp
|
||||||
|
|
||||||
%install
|
%install
|
||||||
#
|
#
|
||||||
# binaries
|
# binaries
|
||||||
@ -63,7 +67,7 @@ install -p -m 755 %{_vpp_build_dir}/vppapigen/vppapigen %{buildroot}%{_bindir}
|
|||||||
mkdir -p -m755 %{buildroot}/etc/vpp
|
mkdir -p -m755 %{buildroot}/etc/vpp
|
||||||
mkdir -p -m755 %{buildroot}/etc/sysctl.d
|
mkdir -p -m755 %{buildroot}/etc/sysctl.d
|
||||||
install -p -m 644 vpp.service %{buildroot}%{_unitdir}
|
install -p -m 644 vpp.service %{buildroot}%{_unitdir}
|
||||||
install -p -m 644 ../../vpp/conf/startup.conf %{buildroot}/etc/vpp
|
install -p -m 644 ../../vpp/conf/startup.uiopcigeneric.conf %{buildroot}/etc/vpp/startup.conf
|
||||||
install -p -m 644 ../../vpp/conf/80-vpp.conf %{buildroot}/etc/sysctl.d
|
install -p -m 644 ../../vpp/conf/80-vpp.conf %{buildroot}/etc/sysctl.d
|
||||||
#
|
#
|
||||||
# libraries
|
# libraries
|
||||||
|
2
build-root/scripts/csit-test-branch
Executable file
2
build-root/scripts/csit-test-branch
Executable file
@ -0,0 +1,2 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
echo csit-verified
|
@ -30,7 +30,7 @@ if [ -n "${ADDS}" ]; then
|
|||||||
print_changelog_item
|
print_changelog_item
|
||||||
fi
|
fi
|
||||||
|
|
||||||
for TAG in $(git tag -l 'v[0-9].[0-9].[0-9]' | sort -r ); do
|
for TAG in $(git tag -l 'v[0-9][0-9].[0-9][0-9]' | sort -r ); do
|
||||||
VER=$(echo ${TAG}| sed -e 's/^v//')
|
VER=$(echo ${TAG}| sed -e 's/^v//')
|
||||||
DESC=$(git tag -l -n20 ${TAG} | tail -n+2 | sed -e 's/^ */ /')
|
DESC=$(git tag -l -n20 ${TAG} | tail -n+2 | sed -e 's/^ */ /')
|
||||||
print_changelog_item
|
print_changelog_item
|
||||||
|
@ -16,12 +16,12 @@ fi
|
|||||||
if [ "$1" = "rpm-release" ]; then
|
if [ "$1" = "rpm-release" ]; then
|
||||||
[ -z "${ADD}" ] && echo release && exit
|
[ -z "${ADD}" ] && echo release && exit
|
||||||
CMT=$(git describe --dirty --match 'v*'| cut -s -d- -f3,4 | sed 's/-/_/')
|
CMT=$(git describe --dirty --match 'v*'| cut -s -d- -f3,4 | sed 's/-/_/')
|
||||||
echo ${ADD}~${CMT}${BLD}
|
echo ${ADD}${CMT:+~${CMT}}${BLD}
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -n "${ADD}" ]; then
|
if [ -n "${ADD}" ]; then
|
||||||
echo ${TAG}-${ADD}~${CMT}${BLD}
|
echo ${TAG}-${ADD}${CMT:+~${CMT}}${BLD}
|
||||||
else
|
else
|
||||||
echo ${TAG}
|
echo ${TAG}
|
||||||
fi
|
fi
|
||||||
|
@ -27,6 +27,15 @@ elif [ -f /etc/redhat-release ];then
|
|||||||
DISTRIB_CODENAME=`lsb_release -sc`
|
DISTRIB_CODENAME=`lsb_release -sc`
|
||||||
DISTRIB_DESCRIPTION=`lsb_release -sd`
|
DISTRIB_DESCRIPTION=`lsb_release -sd`
|
||||||
fi
|
fi
|
||||||
|
KERNEL_OS=`uname -o`
|
||||||
|
KERNEL_MACHINE=`uname -m`
|
||||||
|
KERNEL_RELEASE=`uname -r`
|
||||||
|
KERNEL_VERSION=`uname -v`
|
||||||
|
|
||||||
|
echo KERNEL_OS: $KERNEL_OS
|
||||||
|
echo KERNEL_MACHINE: $KERNEL_MACHINE
|
||||||
|
echo KERNEL_RELEASE: $KERNEL_RELEASE
|
||||||
|
echo KERNEL_VERSION: $KERNEL_VERSION
|
||||||
echo DISTRIB_ID: $DISTRIB_ID
|
echo DISTRIB_ID: $DISTRIB_ID
|
||||||
echo DISTRIB_RELEASE: $DISTRIB_RELEASE
|
echo DISTRIB_RELEASE: $DISTRIB_RELEASE
|
||||||
echo DISTRIB_CODENAME: $DISTRIB_CODENAME
|
echo DISTRIB_CODENAME: $DISTRIB_CODENAME
|
||||||
|
148
dpdk/dpdk-16.04_patches/0015-enic-counter_improvement.patch
Executable file
148
dpdk/dpdk-16.04_patches/0015-enic-counter_improvement.patch
Executable file
@ -0,0 +1,148 @@
|
|||||||
|
diff -ur dpdk-16.04.orig/drivers/net/enic/enic.h dpdk-16.04/drivers/net/enic/enic.h
|
||||||
|
--- dpdk-16.04.orig/drivers/net/enic/enic.h 2016-05-26 16:59:16.531326660 -0700
|
||||||
|
+++ dpdk-16.04/drivers/net/enic/enic.h 2016-05-26 16:59:52.689262489 -0700
|
||||||
|
@@ -91,6 +91,11 @@
|
||||||
|
struct enic_fdir_node *nodes[ENICPMD_FDIR_MAX];
|
||||||
|
};
|
||||||
|
|
||||||
|
+struct enic_soft_stats {
|
||||||
|
+ rte_atomic64_t rx_nombuf;
|
||||||
|
+ rte_atomic64_t rx_packet_errors;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
/* Per-instance private data structure */
|
||||||
|
struct enic {
|
||||||
|
struct enic *next;
|
||||||
|
@@ -133,6 +138,8 @@
|
||||||
|
/* interrupt resource */
|
||||||
|
struct vnic_intr intr;
|
||||||
|
unsigned int intr_count;
|
||||||
|
+
|
||||||
|
+ struct enic_soft_stats soft_stats;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline unsigned int enic_cq_rq(__rte_unused struct enic *enic, unsigned int rq)
|
||||||
|
diff -ur dpdk-16.04.orig/drivers/net/enic/enic_main.c dpdk-16.04/drivers/net/enic/enic_main.c
|
||||||
|
--- dpdk-16.04.orig/drivers/net/enic/enic_main.c 2016-05-26 16:59:16.533326822 -0700
|
||||||
|
+++ dpdk-16.04/drivers/net/enic/enic_main.c 2016-05-26 17:08:11.768801926 -0700
|
||||||
|
@@ -142,22 +142,51 @@
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
+static void enic_clear_soft_stats(struct enic *enic)
|
||||||
|
+{
|
||||||
|
+ struct enic_soft_stats *soft_stats = &enic->soft_stats;
|
||||||
|
+ rte_atomic64_clear(&soft_stats->rx_nombuf);
|
||||||
|
+ rte_atomic64_clear(&soft_stats->rx_packet_errors);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void enic_init_soft_stats(struct enic *enic)
|
||||||
|
+{
|
||||||
|
+ struct enic_soft_stats *soft_stats = &enic->soft_stats;
|
||||||
|
+ rte_atomic64_init(&soft_stats->rx_nombuf);
|
||||||
|
+ rte_atomic64_init(&soft_stats->rx_packet_errors);
|
||||||
|
+ enic_clear_soft_stats(enic);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void enic_dev_stats_clear(struct enic *enic)
|
||||||
|
{
|
||||||
|
if (vnic_dev_stats_clear(enic->vdev))
|
||||||
|
dev_err(enic, "Error in clearing stats\n");
|
||||||
|
+ enic_clear_soft_stats(enic);
|
||||||
|
}
|
||||||
|
|
||||||
|
void enic_dev_stats_get(struct enic *enic, struct rte_eth_stats *r_stats)
|
||||||
|
{
|
||||||
|
struct vnic_stats *stats;
|
||||||
|
+ struct enic_soft_stats *soft_stats = &enic->soft_stats;
|
||||||
|
+ int64_t rx_truncated;
|
||||||
|
+ uint64_t rx_packet_errors;
|
||||||
|
|
||||||
|
if (vnic_dev_stats_dump(enic->vdev, &stats)) {
|
||||||
|
dev_err(enic, "Error in getting stats\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
- r_stats->ipackets = stats->rx.rx_frames_ok;
|
||||||
|
+ /* The number of truncated packets can only be calculated by
|
||||||
|
+ * subtracting a hardware counter from error packets received by
|
||||||
|
+ * the driver. Note: this causes transient inaccuracies in the
|
||||||
|
+ * ipackets count. Also, the length of truncated packets are
|
||||||
|
+ * counted in ibytes even though truncated packets are dropped
|
||||||
|
+ * which can make ibytes be slightly higher than it should be.
|
||||||
|
+ */
|
||||||
|
+ rx_packet_errors = rte_atomic64_read(&soft_stats->rx_packet_errors);
|
||||||
|
+ rx_truncated = rx_packet_errors - stats->rx.rx_errors;
|
||||||
|
+
|
||||||
|
+ r_stats->ipackets = stats->rx.rx_frames_ok - rx_truncated;
|
||||||
|
r_stats->opackets = stats->tx.tx_frames_ok;
|
||||||
|
|
||||||
|
r_stats->ibytes = stats->rx.rx_bytes_ok;
|
||||||
|
@@ -166,10 +195,9 @@
|
||||||
|
r_stats->ierrors = stats->rx.rx_errors + stats->rx.rx_drop;
|
||||||
|
r_stats->oerrors = stats->tx.tx_errors;
|
||||||
|
|
||||||
|
- r_stats->imissed = stats->rx.rx_no_bufs;
|
||||||
|
+ r_stats->imissed = stats->rx.rx_no_bufs + rx_truncated;
|
||||||
|
|
||||||
|
- r_stats->imcasts = stats->rx.rx_multicast_frames_ok;
|
||||||
|
- r_stats->rx_nombuf = stats->rx.rx_no_bufs;
|
||||||
|
+ r_stats->rx_nombuf = rte_atomic64_read(&soft_stats->rx_nombuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void enic_del_mac_address(struct enic *enic)
|
||||||
|
@@ -755,6 +783,8 @@
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
+ enic_init_soft_stats(enic);
|
||||||
|
+
|
||||||
|
ret = enic_set_rss_nic_cfg(enic);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(enic, "Failed to config nic, aborting.\n");
|
||||||
|
diff -ur dpdk-16.04.orig/drivers/net/enic/enic_rxtx.c dpdk-16.04/drivers/net/enic/enic_rxtx.c
|
||||||
|
--- dpdk-16.04.orig/drivers/net/enic/enic_rxtx.c 2016-05-26 16:59:16.522325929 -0700
|
||||||
|
+++ dpdk-16.04/drivers/net/enic/enic_rxtx.c 2016-05-26 16:59:52.694262896 -0700
|
||||||
|
@@ -251,6 +251,7 @@
|
||||||
|
struct vnic_cq *cq;
|
||||||
|
volatile struct cq_desc *cqd_ptr;
|
||||||
|
uint8_t color;
|
||||||
|
+ uint16_t nb_err = 0;
|
||||||
|
|
||||||
|
cq = &enic->cq[enic_cq_rq(enic, rq->index)];
|
||||||
|
rx_id = cq->to_clean; /* index of cqd, rqd, mbuf_table */
|
||||||
|
@@ -278,10 +279,7 @@
|
||||||
|
/* allocate a new mbuf */
|
||||||
|
nmb = rte_rxmbuf_alloc(rq->mp);
|
||||||
|
if (nmb == NULL) {
|
||||||
|
- dev_err(enic, "RX mbuf alloc failed port=%u qid=%u",
|
||||||
|
- enic->port_id, (unsigned)rq->index);
|
||||||
|
- rte_eth_devices[enic->port_id].
|
||||||
|
- data->rx_mbuf_alloc_failed++;
|
||||||
|
+ rte_atomic64_inc(&enic->soft_stats.rx_nombuf);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -323,9 +321,10 @@
|
||||||
|
rxmb->packet_type = enic_cq_rx_flags_to_pkt_type(&cqd);
|
||||||
|
enic_cq_rx_to_pkt_flags(&cqd, rxmb);
|
||||||
|
} else {
|
||||||
|
- rxmb->pkt_len = 0;
|
||||||
|
- rxmb->packet_type = 0;
|
||||||
|
- rxmb->ol_flags = 0;
|
||||||
|
+ rte_pktmbuf_free(rxmb);
|
||||||
|
+ rte_atomic64_inc(&enic->soft_stats.rx_packet_errors);
|
||||||
|
+ nb_err++;
|
||||||
|
+ continue;
|
||||||
|
}
|
||||||
|
rxmb->data_len = rxmb->pkt_len;
|
||||||
|
|
||||||
|
@@ -337,7 +336,7 @@
|
||||||
|
rx_pkts[nb_rx++] = rxmb;
|
||||||
|
}
|
||||||
|
|
||||||
|
- nb_hold += nb_rx;
|
||||||
|
+ nb_hold += nb_rx + nb_err;
|
||||||
|
cq->to_clean = rx_id;
|
||||||
|
|
||||||
|
if (nb_hold > rq->rx_free_thresh) {
|
650
dpdk/dpdk-16.04_patches/0016-enic-scatter-rx.patch
Executable file
650
dpdk/dpdk-16.04_patches/0016-enic-scatter-rx.patch
Executable file
File diff suppressed because it is too large
Load Diff
26
svm/svm.c
26
svm/svm.c
@ -391,6 +391,11 @@ void *svm_map_region (svm_map_region_args_t *a)
|
|||||||
svm_fd = shm_open((char *) shm_name, O_RDWR | O_CREAT | O_EXCL, 0777);
|
svm_fd = shm_open((char *) shm_name, O_RDWR | O_CREAT | O_EXCL, 0777);
|
||||||
|
|
||||||
if (svm_fd >= 0) {
|
if (svm_fd >= 0) {
|
||||||
|
if (fchmod (svm_fd, 0770) < 0)
|
||||||
|
clib_unix_warning ("segment chmod");
|
||||||
|
/* This turns out to fail harmlessly if the client starts first */
|
||||||
|
if (fchown (svm_fd, a->uid, a->gid) < 0)
|
||||||
|
clib_unix_warning ("segment chown [ok if client starts first]");
|
||||||
|
|
||||||
vec_free(shm_name);
|
vec_free(shm_name);
|
||||||
|
|
||||||
@ -615,18 +620,19 @@ static void svm_mutex_cleanup (void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void svm_region_init_internal (char *root_path)
|
static void svm_region_init_internal (char *root_path, int uid, int gid)
|
||||||
{
|
{
|
||||||
svm_region_t *rp;
|
svm_region_t *rp;
|
||||||
svm_map_region_args_t *a=0;
|
svm_map_region_args_t _a, *a=&_a;
|
||||||
u64 ticks = clib_cpu_time_now();
|
u64 ticks = clib_cpu_time_now();
|
||||||
uword randomize_baseva;
|
uword randomize_baseva;
|
||||||
|
|
||||||
/* guard against klutz calls */
|
/* guard against klutz calls */
|
||||||
root_rp_refcount++;
|
|
||||||
if (root_rp)
|
if (root_rp)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
root_rp_refcount++;
|
||||||
|
|
||||||
atexit(svm_mutex_cleanup);
|
atexit(svm_mutex_cleanup);
|
||||||
|
|
||||||
/* Randomize the shared-VM base at init time */
|
/* Randomize the shared-VM base at init time */
|
||||||
@ -635,12 +641,14 @@ static void svm_region_init_internal (char *root_path)
|
|||||||
else
|
else
|
||||||
randomize_baseva = (ticks & 3) * MMAP_PAGESIZE;
|
randomize_baseva = (ticks & 3) * MMAP_PAGESIZE;
|
||||||
|
|
||||||
vec_validate(a,0);
|
memset (a, 0, sizeof (*a));
|
||||||
a->root_path = root_path;
|
a->root_path = root_path;
|
||||||
a->name = SVM_GLOBAL_REGION_NAME;
|
a->name = SVM_GLOBAL_REGION_NAME;
|
||||||
a->baseva = SVM_GLOBAL_REGION_BASEVA + randomize_baseva;
|
a->baseva = SVM_GLOBAL_REGION_BASEVA + randomize_baseva;
|
||||||
a->size = SVM_GLOBAL_REGION_SIZE;
|
a->size = SVM_GLOBAL_REGION_SIZE;
|
||||||
a->flags = SVM_FLAGS_NODATA;
|
a->flags = SVM_FLAGS_NODATA;
|
||||||
|
a->uid = uid;
|
||||||
|
a->gid = gid;
|
||||||
|
|
||||||
rp = svm_map_region (a);
|
rp = svm_map_region (a);
|
||||||
ASSERT(rp);
|
ASSERT(rp);
|
||||||
@ -663,18 +671,22 @@ static void svm_region_init_internal (char *root_path)
|
|||||||
svm_pop_heap (oldheap);
|
svm_pop_heap (oldheap);
|
||||||
}
|
}
|
||||||
region_unlock(rp);
|
region_unlock(rp);
|
||||||
vec_free (a);
|
|
||||||
root_rp = rp;
|
root_rp = rp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void svm_region_init (void)
|
void svm_region_init (void)
|
||||||
{
|
{
|
||||||
svm_region_init_internal (0);
|
svm_region_init_internal (0, 0 /* uid */, 0 /* gid */);
|
||||||
}
|
}
|
||||||
|
|
||||||
void svm_region_init_chroot (char *root_path)
|
void svm_region_init_chroot (char *root_path)
|
||||||
{
|
{
|
||||||
svm_region_init_internal (root_path);
|
svm_region_init_internal (root_path, 0 /* uid */, 0 /* gid */);
|
||||||
|
}
|
||||||
|
|
||||||
|
void svm_region_init_chroot_uid_gid (char *root_path, int uid, int gid)
|
||||||
|
{
|
||||||
|
svm_region_init_internal (root_path, uid, gid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *svm_region_find_or_create (svm_map_region_args_t *a)
|
void *svm_region_find_or_create (svm_map_region_args_t *a)
|
||||||
|
@ -74,6 +74,9 @@ typedef struct svm_map_region_args_ {
|
|||||||
uword flags;
|
uword flags;
|
||||||
char *backing_file;
|
char *backing_file;
|
||||||
uword backing_mmap_size;
|
uword backing_mmap_size;
|
||||||
|
/* uid, gid to own the svm region(s) */
|
||||||
|
int uid;
|
||||||
|
int gid;
|
||||||
} svm_map_region_args_t;
|
} svm_map_region_args_t;
|
||||||
|
|
||||||
|
|
||||||
@ -108,6 +111,7 @@ typedef struct {
|
|||||||
void *svm_region_find_or_create (svm_map_region_args_t *a);
|
void *svm_region_find_or_create (svm_map_region_args_t *a);
|
||||||
void svm_region_init(void);
|
void svm_region_init(void);
|
||||||
void svm_region_init_chroot(char *root_path);
|
void svm_region_init_chroot(char *root_path);
|
||||||
|
void svm_region_init_chroot_uid_gid(char *root_path, int uid, int gid);
|
||||||
void svm_region_exit (void);
|
void svm_region_exit (void);
|
||||||
void svm_region_unmap(void *rp_arg);
|
void svm_region_unmap(void *rp_arg);
|
||||||
void svm_client_scan (char *root_path);
|
void svm_client_scan (char *root_path);
|
||||||
|
@ -134,6 +134,10 @@ typedef struct {
|
|||||||
/* vector of message ranges */
|
/* vector of message ranges */
|
||||||
vl_api_msg_range_t *msg_ranges;
|
vl_api_msg_range_t *msg_ranges;
|
||||||
|
|
||||||
|
/* gid for the api shared memory region */
|
||||||
|
int api_gid;
|
||||||
|
int api_uid;
|
||||||
|
|
||||||
/* Client-only data structures */
|
/* Client-only data structures */
|
||||||
unix_shared_memory_queue_t *vl_input_queue;
|
unix_shared_memory_queue_t *vl_input_queue;
|
||||||
|
|
||||||
|
@ -647,6 +647,14 @@ vl_api_init (vlib_main_t *vm)
|
|||||||
once = 1;
|
once = 1;
|
||||||
|
|
||||||
am->region_name = "/unset";
|
am->region_name = "/unset";
|
||||||
|
/*
|
||||||
|
* Eventually passed to fchown, -1 => "current user"
|
||||||
|
* instead of 0 => "root". A very fine disctinction at best.
|
||||||
|
*/
|
||||||
|
if (am->api_uid == 0)
|
||||||
|
am->api_uid = -1;
|
||||||
|
if (am->api_gid == 0)
|
||||||
|
am->api_gid = -1;
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
@ -133,6 +133,8 @@ int vl_client_api_map (char *region_name);
|
|||||||
void vl_client_api_unmap (void);
|
void vl_client_api_unmap (void);
|
||||||
void vl_set_memory_region_name (char *name);
|
void vl_set_memory_region_name (char *name);
|
||||||
void vl_set_memory_root_path (char *root_path);
|
void vl_set_memory_root_path (char *root_path);
|
||||||
|
void vl_set_memory_uid (int uid);
|
||||||
|
void vl_set_memory_gid (int gid);
|
||||||
void vl_enable_disable_memory_api (vlib_main_t *vm, int yesno);
|
void vl_enable_disable_memory_api (vlib_main_t *vm, int yesno);
|
||||||
void vl_client_disconnect_from_vlib (void);
|
void vl_client_disconnect_from_vlib (void);
|
||||||
int vl_client_connect_to_vlib(char *svm_name, char *client_name,
|
int vl_client_connect_to_vlib(char *svm_name, char *client_name,
|
||||||
|
@ -197,9 +197,23 @@ void vl_set_memory_root_path (char *name)
|
|||||||
am->root_path = name;
|
am->root_path = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vl_set_memory_uid (int uid)
|
||||||
|
{
|
||||||
|
api_main_t *am = &api_main;
|
||||||
|
|
||||||
|
am->api_uid = uid;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vl_set_memory_gid (int gid)
|
||||||
|
{
|
||||||
|
api_main_t *am = &api_main;
|
||||||
|
|
||||||
|
am->api_gid = gid;
|
||||||
|
}
|
||||||
|
|
||||||
int vl_map_shmem (char *region_name, int is_vlib)
|
int vl_map_shmem (char *region_name, int is_vlib)
|
||||||
{
|
{
|
||||||
svm_map_region_args_t *a = 0;
|
svm_map_region_args_t _a, *a = &_a;
|
||||||
svm_region_t *vlib_rp, *root_rp;
|
svm_region_t *vlib_rp, *root_rp;
|
||||||
void *oldheap;
|
void *oldheap;
|
||||||
vl_shmem_hdr_t *shmem_hdr=0;
|
vl_shmem_hdr_t *shmem_hdr=0;
|
||||||
@ -210,16 +224,16 @@ int vl_map_shmem (char *region_name, int is_vlib)
|
|||||||
if (is_vlib == 0)
|
if (is_vlib == 0)
|
||||||
svm_region_init_chroot(am->root_path);
|
svm_region_init_chroot(am->root_path);
|
||||||
|
|
||||||
vec_validate (a, 0);
|
memset (a, 0, sizeof (*a));
|
||||||
|
|
||||||
a->name = region_name;
|
a->name = region_name;
|
||||||
a->size = 16<<20;
|
a->size = 16<<20;
|
||||||
a->flags = SVM_FLAGS_MHEAP;
|
a->flags = SVM_FLAGS_MHEAP;
|
||||||
|
a->uid = am->api_uid;
|
||||||
|
a->gid = am->api_gid;
|
||||||
|
|
||||||
vlib_rp = svm_region_find_or_create (a);
|
vlib_rp = svm_region_find_or_create (a);
|
||||||
|
|
||||||
vec_free (a);
|
|
||||||
|
|
||||||
if (vlib_rp == 0)
|
if (vlib_rp == 0)
|
||||||
return (-2);
|
return (-2);
|
||||||
|
|
||||||
@ -274,24 +288,8 @@ int vl_map_shmem (char *region_name, int is_vlib)
|
|||||||
pthread_mutex_lock (&root_rp->mutex);
|
pthread_mutex_lock (&root_rp->mutex);
|
||||||
svm_client_scan_this_region_nolock (root_rp);
|
svm_client_scan_this_region_nolock (root_rp);
|
||||||
pthread_mutex_unlock (&root_rp->mutex);
|
pthread_mutex_unlock (&root_rp->mutex);
|
||||||
} else {
|
}
|
||||||
pthread_mutex_unlock (&vlib_rp->mutex);
|
pthread_mutex_unlock (&vlib_rp->mutex);
|
||||||
/*
|
|
||||||
* Make sure the vlib app is really there...
|
|
||||||
* Wait up to 100 seconds...
|
|
||||||
*/
|
|
||||||
for (i = 0; i < 10000; i++) {
|
|
||||||
/* Yup, it's there, off we go... */
|
|
||||||
if (kill (am->shmem_hdr->vl_pid, 0) >= 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
ts.tv_sec = 0;
|
|
||||||
ts.tv_nsec = 10000*1000; /* 10 ms */
|
|
||||||
while (nanosleep(&ts, &tsrem) < 0)
|
|
||||||
ts = tsrem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
am->vlib_rp = vlib_rp;
|
am->vlib_rp = vlib_rp;
|
||||||
vec_add1(am->mapped_shmem_regions, vlib_rp);
|
vec_add1(am->mapped_shmem_regions, vlib_rp);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -343,7 +343,6 @@ typedef enum {
|
|||||||
|
|
||||||
static u64 vector_rate_histogram[SLEEP_N_BUCKETS];
|
static u64 vector_rate_histogram[SLEEP_N_BUCKETS];
|
||||||
|
|
||||||
static void memclnt_queue_signal (int signum);
|
|
||||||
static void memclnt_queue_callback (vlib_main_t *vm);
|
static void memclnt_queue_callback (vlib_main_t *vm);
|
||||||
|
|
||||||
static uword
|
static uword
|
||||||
@ -362,8 +361,6 @@ memclnt_process (vlib_main_t * vm,
|
|||||||
f64 vector_rate;
|
f64 vector_rate;
|
||||||
|
|
||||||
vlib_set_queue_signal_callback (vm, memclnt_queue_callback);
|
vlib_set_queue_signal_callback (vm, memclnt_queue_callback);
|
||||||
am->vlib_signal = SIGUSR1;
|
|
||||||
signal (am->vlib_signal, memclnt_queue_signal);
|
|
||||||
|
|
||||||
if ((rv = memory_api_init(am->region_name)) < 0) {
|
if ((rv = memory_api_init(am->region_name)) < 0) {
|
||||||
clib_warning("memory_api_init returned %d, wait for godot...", rv);
|
clib_warning("memory_api_init returned %d, wait for godot...", rv);
|
||||||
@ -458,6 +455,7 @@ memclnt_process (vlib_main_t * vm,
|
|||||||
}
|
}
|
||||||
|
|
||||||
event_type = vlib_process_wait_for_event_or_clock (vm, sleep_time);
|
event_type = vlib_process_wait_for_event_or_clock (vm, sleep_time);
|
||||||
|
vm->queue_signal_pending = 0;
|
||||||
vlib_process_get_events (vm, 0 /* event_data */);
|
vlib_process_get_events (vm, 0 /* event_data */);
|
||||||
|
|
||||||
if (vlib_time_now (vm) > dead_client_scan_time) {
|
if (vlib_time_now (vm) > dead_client_scan_time) {
|
||||||
@ -621,27 +619,33 @@ VLIB_REGISTER_NODE (memclnt_node,static) = {
|
|||||||
.state = VLIB_NODE_STATE_DISABLED,
|
.state = VLIB_NODE_STATE_DISABLED,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
|
||||||
memclnt_queue_signal (int signum)
|
|
||||||
{
|
|
||||||
vlib_main_t * vm = vlib_get_main();
|
|
||||||
|
|
||||||
vm->queue_signal_pending = 1;
|
|
||||||
vm->api_queue_nonempty = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
memclnt_queue_callback (vlib_main_t *vm)
|
memclnt_queue_callback (vlib_main_t *vm)
|
||||||
{
|
{
|
||||||
#if 0
|
static volatile int * cursizep;
|
||||||
/* If we need to manually suspend / resume the memclnt process */
|
|
||||||
vlib_node_t * n = vlib_get_node (vm, memclnt_node.index);
|
|
||||||
vlib_process_t * p = vlib_get_process_from_node (vm, n);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
vm->queue_signal_pending = 0;
|
if (PREDICT_FALSE (cursizep == 0))
|
||||||
vlib_process_signal_event
|
{
|
||||||
(vm, memclnt_node.index, /* event_type */ 0, /* event_data */ 0);
|
api_main_t *am = &api_main;
|
||||||
|
vl_shmem_hdr_t *shmem_hdr = am->shmem_hdr;
|
||||||
|
unix_shared_memory_queue_t * q;
|
||||||
|
|
||||||
|
if (shmem_hdr == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
q = shmem_hdr->vl_input_queue;
|
||||||
|
if (q == 0)
|
||||||
|
return;
|
||||||
|
cursizep = &q->cursize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*cursizep >= 1)
|
||||||
|
{
|
||||||
|
vm->queue_signal_pending = 1;
|
||||||
|
vm->api_queue_nonempty = 1;
|
||||||
|
vlib_process_signal_event (vm, memclnt_node.index,
|
||||||
|
/* event_type */ 0, /* event_data */ 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void vl_enable_disable_memory_api (vlib_main_t *vm, int enable)
|
void vl_enable_disable_memory_api (vlib_main_t *vm, int enable)
|
||||||
@ -1049,8 +1053,8 @@ clib_error_t *
|
|||||||
vlibmemory_init (vlib_main_t * vm)
|
vlibmemory_init (vlib_main_t * vm)
|
||||||
{
|
{
|
||||||
api_main_t *am = &api_main;
|
api_main_t *am = &api_main;
|
||||||
/* Normally NULL, can be set by cmd line "chroot {prefix foo}" */
|
/* Normally NULL / 0, set by cmd line "api-segment" */
|
||||||
svm_region_init_chroot (am->root_path);
|
svm_region_init_chroot_uid_gid (am->root_path, am->api_uid, am->api_gid);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1414,9 +1414,8 @@ static void vlib_main_loop (vlib_main_t * vm)
|
|||||||
/* frame */ 0,
|
/* frame */ 0,
|
||||||
cpu_time_now);
|
cpu_time_now);
|
||||||
|
|
||||||
if (PREDICT_FALSE(vm->queue_signal_pending))
|
if (PREDICT_TRUE (vm->queue_signal_pending == 0))
|
||||||
if (vm->queue_signal_callback)
|
vm->queue_signal_callback (vm);
|
||||||
vm->queue_signal_callback (vm);
|
|
||||||
|
|
||||||
/* Next handle interrupts. */
|
/* Next handle interrupts. */
|
||||||
{
|
{
|
||||||
@ -1533,11 +1532,15 @@ vlib_main_configure (vlib_main_t * vm, unformat_input_t * input)
|
|||||||
|
|
||||||
VLIB_EARLY_CONFIG_FUNCTION (vlib_main_configure, "vlib");
|
VLIB_EARLY_CONFIG_FUNCTION (vlib_main_configure, "vlib");
|
||||||
|
|
||||||
|
static void dummy_queue_signal_callback (vlib_main_t * vm) { }
|
||||||
|
|
||||||
/* Main function. */
|
/* Main function. */
|
||||||
int vlib_main (vlib_main_t * vm, unformat_input_t * input)
|
int vlib_main (vlib_main_t * vm, unformat_input_t * input)
|
||||||
{
|
{
|
||||||
clib_error_t * error;
|
clib_error_t * error;
|
||||||
|
|
||||||
|
vm->queue_signal_callback = dummy_queue_signal_callback;
|
||||||
|
|
||||||
clib_time_init (&vm->clib_time);
|
clib_time_init (&vm->clib_time);
|
||||||
|
|
||||||
/* Turn on event log. */
|
/* Turn on event log. */
|
||||||
|
@ -61,6 +61,8 @@
|
|||||||
#define ETH_BUFFER_VLAN_BITS (ETH_BUFFER_VLAN_1_DEEP | \
|
#define ETH_BUFFER_VLAN_BITS (ETH_BUFFER_VLAN_1_DEEP | \
|
||||||
ETH_BUFFER_VLAN_2_DEEP)
|
ETH_BUFFER_VLAN_2_DEEP)
|
||||||
|
|
||||||
|
#define LOG2_BUFFER_OUTPUT_FEAT_DONE LOG2_VLIB_BUFFER_FLAG_USER(5)
|
||||||
|
#define BUFFER_OUTPUT_FEAT_DONE (1 << LOG2_BUFFER_OUTPUT_FEAT_DONE)
|
||||||
|
|
||||||
#define foreach_buffer_opaque_union_subtype \
|
#define foreach_buffer_opaque_union_subtype \
|
||||||
_(ethernet) \
|
_(ethernet) \
|
||||||
|
@ -1136,7 +1136,10 @@ dpdk_subif_add_del_function (vnet_main_t * vnm,
|
|||||||
dpdk_device_t * xd = vec_elt_at_index (xm->devices, hw->dev_instance);
|
dpdk_device_t * xd = vec_elt_at_index (xm->devices, hw->dev_instance);
|
||||||
vnet_sw_interface_t * t = (vnet_sw_interface_t *) st;
|
vnet_sw_interface_t * t = (vnet_sw_interface_t *) st;
|
||||||
int r, vlan_offload;
|
int r, vlan_offload;
|
||||||
|
u32 prev_subifs = xd->vlan_subifs;
|
||||||
|
|
||||||
|
if (is_add) xd->vlan_subifs++;
|
||||||
|
else if (xd->vlan_subifs) xd->vlan_subifs--;
|
||||||
|
|
||||||
if (xd->dev_type != VNET_DPDK_DEV_ETH)
|
if (xd->dev_type != VNET_DPDK_DEV_ETH)
|
||||||
return 0;
|
return 0;
|
||||||
@ -1149,21 +1152,26 @@ dpdk_subif_add_del_function (vnet_main_t * vnm,
|
|||||||
if (t->sub.eth.flags.no_tags == 1)
|
if (t->sub.eth.flags.no_tags == 1)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if ((t->sub.eth.flags.one_tag != 1) || (t->sub.eth.flags.exact_match != 1 ))
|
if ((t->sub.eth.flags.one_tag != 1) || (t->sub.eth.flags.exact_match != 1 )) {
|
||||||
|
xd->vlan_subifs = prev_subifs;
|
||||||
return clib_error_return (0, "unsupported VLAN setup");
|
return clib_error_return (0, "unsupported VLAN setup");
|
||||||
|
}
|
||||||
|
|
||||||
vlan_offload = rte_eth_dev_get_vlan_offload(xd->device_index);
|
vlan_offload = rte_eth_dev_get_vlan_offload(xd->device_index);
|
||||||
vlan_offload |= ETH_VLAN_FILTER_OFFLOAD;
|
vlan_offload |= ETH_VLAN_FILTER_OFFLOAD;
|
||||||
|
|
||||||
if ((r = rte_eth_dev_set_vlan_offload(xd->device_index, vlan_offload)))
|
if ((r = rte_eth_dev_set_vlan_offload(xd->device_index, vlan_offload))) {
|
||||||
|
xd->vlan_subifs = prev_subifs;
|
||||||
return clib_error_return (0, "rte_eth_dev_set_vlan_offload[%d]: err %d",
|
return clib_error_return (0, "rte_eth_dev_set_vlan_offload[%d]: err %d",
|
||||||
xd->device_index, r);
|
xd->device_index, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if ((r = rte_eth_dev_vlan_filter(xd->device_index, t->sub.eth.outer_vlan_id, is_add)))
|
if ((r = rte_eth_dev_vlan_filter(xd->device_index, t->sub.eth.outer_vlan_id, is_add))) {
|
||||||
|
xd->vlan_subifs = prev_subifs;
|
||||||
return clib_error_return (0, "rte_eth_dev_vlan_filter[%d]: err %d",
|
return clib_error_return (0, "rte_eth_dev_vlan_filter[%d]: err %d",
|
||||||
xd->device_index, r);
|
xd->device_index, r);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -208,6 +208,9 @@ typedef struct {
|
|||||||
/* per-worker destination frame queue */
|
/* per-worker destination frame queue */
|
||||||
dpdk_frame_t * frames;
|
dpdk_frame_t * frames;
|
||||||
|
|
||||||
|
/* number of sub-interfaces */
|
||||||
|
u16 vlan_subifs;
|
||||||
|
|
||||||
dpdk_device_type_t dev_type:8;
|
dpdk_device_type_t dev_type:8;
|
||||||
dpdk_pmd_t pmd:8;
|
dpdk_pmd_t pmd:8;
|
||||||
i8 cpu_socket;
|
i8 cpu_socket;
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#define DPDK_NB_TX_DESC_10GE 2048
|
#define DPDK_NB_TX_DESC_10GE 2048
|
||||||
#define DPDK_NB_RX_DESC_40GE (4096-128)
|
#define DPDK_NB_RX_DESC_40GE (4096-128)
|
||||||
#define DPDK_NB_TX_DESC_40GE 2048
|
#define DPDK_NB_TX_DESC_40GE 2048
|
||||||
|
#define DPDK_NB_RX_DESC_ENIC (4096+1024)
|
||||||
|
|
||||||
/* These args appear by themselves */
|
/* These args appear by themselves */
|
||||||
#define foreach_eal_double_hyphen_predicate_arg \
|
#define foreach_eal_double_hyphen_predicate_arg \
|
||||||
|
@ -382,16 +382,15 @@ dpdk_lib_init (dpdk_main_t * dm)
|
|||||||
case VNET_DPDK_PMD_VICE:
|
case VNET_DPDK_PMD_VICE:
|
||||||
case VNET_DPDK_PMD_ENIC:
|
case VNET_DPDK_PMD_ENIC:
|
||||||
rte_eth_link_get_nowait(i, &l);
|
rte_eth_link_get_nowait(i, &l);
|
||||||
|
xd->nb_rx_desc = DPDK_NB_RX_DESC_ENIC;
|
||||||
if (l.link_speed == 40000)
|
if (l.link_speed == 40000)
|
||||||
{
|
{
|
||||||
xd->port_type = VNET_DPDK_PORT_TYPE_ETH_40G;
|
xd->port_type = VNET_DPDK_PORT_TYPE_ETH_40G;
|
||||||
xd->nb_rx_desc = DPDK_NB_RX_DESC_40GE;
|
|
||||||
xd->nb_tx_desc = DPDK_NB_TX_DESC_40GE;
|
xd->nb_tx_desc = DPDK_NB_TX_DESC_40GE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
xd->port_type = VNET_DPDK_PORT_TYPE_ETH_10G;
|
xd->port_type = VNET_DPDK_PORT_TYPE_ETH_10G;
|
||||||
xd->nb_rx_desc = DPDK_NB_RX_DESC_10GE;
|
|
||||||
xd->nb_tx_desc = DPDK_NB_TX_DESC_10GE;
|
xd->nb_tx_desc = DPDK_NB_TX_DESC_10GE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -303,9 +303,9 @@ dpdk_rx_next_and_error_from_mb_flags_x1 (dpdk_device_t *xd, struct rte_mbuf *mb,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
*error0 = DPDK_ERROR_NONE;
|
*error0 = DPDK_ERROR_NONE;
|
||||||
if (xd->per_interface_next_index != ~0)
|
if (PREDICT_FALSE(xd->per_interface_next_index != ~0))
|
||||||
n0 = xd->per_interface_next_index;
|
n0 = xd->per_interface_next_index;
|
||||||
else if (mb_flags & PKT_RX_VLAN_PKT)
|
else if (PREDICT_FALSE(xd->vlan_subifs || (mb_flags & PKT_RX_VLAN_PKT)))
|
||||||
n0 = DPDK_RX_NEXT_ETHERNET_INPUT;
|
n0 = DPDK_RX_NEXT_ETHERNET_INPUT;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -589,6 +589,14 @@ dpdk_vhost_user_set_vring_addr(u32 hw_if_index, u8 idx, u64 desc, \
|
|||||||
clib_warning("falied to set vring addr");
|
clib_warning("falied to set vring addr");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (vq->last_used_idx != vq->used->idx) {
|
||||||
|
clib_warning("last_used_idx (%u) and vq->used->idx (%u) mismatches; "
|
||||||
|
"some packets maybe resent for Tx and dropped for Rx",
|
||||||
|
vq->last_used_idx, vq->used->idx);
|
||||||
|
vq->last_used_idx = vq->used->idx;
|
||||||
|
vq->last_used_idx_res = vq->used->idx;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Inform the guest that there is no need to inform (kick) the
|
* Inform the guest that there is no need to inform (kick) the
|
||||||
* host when it adds buffers. kick results in vmexit and will
|
* host when it adds buffers. kick results in vmexit and will
|
||||||
|
@ -472,6 +472,14 @@ eth_identify_subint (vnet_hw_interface_t * hi,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Compare two ethernet macs. Return 1 if they are the same, 0 if different
|
||||||
|
always_inline u32
|
||||||
|
eth_mac_equal (u8 * mac1, u8 * mac2) {
|
||||||
|
return (*((u32 *)(mac1+0)) == *((u32 *)(mac2+0)) &&
|
||||||
|
*((u32 *)(mac1+2)) == *((u32 *)(mac2+2)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
always_inline ethernet_main_t *
|
always_inline ethernet_main_t *
|
||||||
vnet_get_ethernet_main (void)
|
vnet_get_ethernet_main (void)
|
||||||
{
|
{
|
||||||
|
@ -343,6 +343,7 @@ VNET_DEVICE_CLASS (ethernet_simulated_device_class) = {
|
|||||||
.format_device_name = format_simulated_ethernet_name,
|
.format_device_name = format_simulated_ethernet_name,
|
||||||
.tx_function = simulated_ethernet_interface_tx,
|
.tx_function = simulated_ethernet_interface_tx,
|
||||||
.admin_up_down_function = simulated_ethernet_admin_up_down,
|
.admin_up_down_function = simulated_ethernet_admin_up_down,
|
||||||
|
.no_flatten_output_chains = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
int vnet_create_loopback_interface (u32 * sw_if_indexp, u8 *mac_address)
|
int vnet_create_loopback_interface (u32 * sw_if_indexp, u8 *mac_address)
|
||||||
|
@ -81,14 +81,6 @@ typedef enum {
|
|||||||
} ethernet_input_variant_t;
|
} ethernet_input_variant_t;
|
||||||
|
|
||||||
|
|
||||||
// Compare two ethernet macs. Return 1 if they are the same, 0 if different
|
|
||||||
static_always_inline u32
|
|
||||||
eth_mac_equal (u8 * mac1, u8 * mac2) {
|
|
||||||
return (*((u32 *)(mac1+0)) == *((u32 *)(mac2+0)) &&
|
|
||||||
*((u32 *)(mac1+2)) == *((u32 *)(mac2+2)));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Parse the ethernet header to extract vlan tags and innermost ethertype
|
// Parse the ethernet header to extract vlan tags and innermost ethertype
|
||||||
static_always_inline void
|
static_always_inline void
|
||||||
parse_header (ethernet_input_variant_t variant,
|
parse_header (ethernet_input_variant_t variant,
|
||||||
|
@ -393,11 +393,11 @@ vnet_interface_output_node (vlib_main_t * vm,
|
|||||||
return n_buffers;
|
return n_buffers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
always_inline uword
|
||||||
uword
|
vnet_interface_output_node_no_flatten_inline (vlib_main_t * vm,
|
||||||
vnet_interface_output_node_no_flatten (vlib_main_t * vm,
|
vlib_node_runtime_t * node,
|
||||||
vlib_node_runtime_t * node,
|
vlib_frame_t * frame,
|
||||||
vlib_frame_t * frame)
|
int with_features)
|
||||||
{
|
{
|
||||||
vnet_main_t * vnm = vnet_get_main();
|
vnet_main_t * vnm = vnet_get_main();
|
||||||
vnet_interface_output_runtime_t * rt = (void *) node->runtime_data;
|
vnet_interface_output_runtime_t * rt = (void *) node->runtime_data;
|
||||||
@ -465,6 +465,7 @@ vnet_interface_output_node_no_flatten (vlib_main_t * vm,
|
|||||||
u32 bi0, bi1;
|
u32 bi0, bi1;
|
||||||
vlib_buffer_t * b0, * b1;
|
vlib_buffer_t * b0, * b1;
|
||||||
u32 tx_swif0, tx_swif1;
|
u32 tx_swif0, tx_swif1;
|
||||||
|
u32 next0, next1;
|
||||||
|
|
||||||
/* Prefetch next iteration. */
|
/* Prefetch next iteration. */
|
||||||
vlib_prefetch_buffer_with_index (vm, from[2], LOAD);
|
vlib_prefetch_buffer_with_index (vm, from[2], LOAD);
|
||||||
@ -493,19 +494,16 @@ vnet_interface_output_node_no_flatten (vlib_main_t * vm,
|
|||||||
|
|
||||||
n_bytes += n_bytes_b0 + n_bytes_b1;
|
n_bytes += n_bytes_b0 + n_bytes_b1;
|
||||||
n_packets += 2;
|
n_packets += 2;
|
||||||
|
if (with_features)
|
||||||
if (PREDICT_FALSE(si->output_feature_bitmap &&
|
|
||||||
vnet_buffer(b0)->output_features.bitmap != (1 << INTF_OUTPUT_FEAT_DONE)))
|
|
||||||
{
|
{
|
||||||
u32 next0;
|
b0->flags |= BUFFER_OUTPUT_FEAT_DONE;
|
||||||
vnet_buffer(b0)->output_features.bitmap = si->output_feature_bitmap;
|
vnet_buffer(b0)->output_features.bitmap = si->output_feature_bitmap;
|
||||||
count_trailing_zeros(next0, vnet_buffer(b0)->output_features.bitmap);
|
count_trailing_zeros(next0, vnet_buffer(b0)->output_features.bitmap);
|
||||||
vnet_buffer(b0)->output_features.bitmap &= ~(1 << next0);
|
vnet_buffer(b0)->output_features.bitmap &= ~(1 << next0);
|
||||||
vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_tx,
|
|
||||||
n_left_to_tx, bi0, next0);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
next0 = VNET_INTERFACE_OUTPUT_NEXT_TX;
|
||||||
vnet_buffer(b0)->output_features.bitmap = 0;
|
vnet_buffer(b0)->output_features.bitmap = 0;
|
||||||
|
|
||||||
if (PREDICT_FALSE(tx_swif0 != rt->sw_if_index))
|
if (PREDICT_FALSE(tx_swif0 != rt->sw_if_index))
|
||||||
@ -520,18 +518,16 @@ vnet_interface_output_node_no_flatten (vlib_main_t * vm,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PREDICT_FALSE(si->output_feature_bitmap &&
|
if (with_features)
|
||||||
vnet_buffer(b1)->output_features.bitmap != (1 << INTF_OUTPUT_FEAT_DONE)))
|
|
||||||
{
|
{
|
||||||
u32 next1;
|
b1->flags |= BUFFER_OUTPUT_FEAT_DONE;
|
||||||
vnet_buffer(b1)->output_features.bitmap = si->output_feature_bitmap;
|
vnet_buffer(b1)->output_features.bitmap = si->output_feature_bitmap;
|
||||||
count_trailing_zeros(next1, vnet_buffer(b1)->output_features.bitmap);
|
count_trailing_zeros(next1, vnet_buffer(b1)->output_features.bitmap);
|
||||||
vnet_buffer(b1)->output_features.bitmap &= ~(1 << next1);
|
vnet_buffer(b1)->output_features.bitmap &= ~(1 << next1);
|
||||||
vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_tx,
|
|
||||||
n_left_to_tx, bi1, next1);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
next1 = VNET_INTERFACE_OUTPUT_NEXT_TX;
|
||||||
vnet_buffer(b1)->output_features.bitmap = 0;
|
vnet_buffer(b1)->output_features.bitmap = 0;
|
||||||
|
|
||||||
/* update vlan subif tx counts, if required */
|
/* update vlan subif tx counts, if required */
|
||||||
@ -546,7 +542,9 @@ vnet_interface_output_node_no_flatten (vlib_main_t * vm,
|
|||||||
n_bytes_b1);
|
n_bytes_b1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (with_features)
|
||||||
|
vlib_validate_buffer_enqueue_x2(vm, node, next_index, to_tx,
|
||||||
|
n_left_to_tx, bi0, bi1, next0, next1);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (from + 1 <= from_end && n_left_to_tx >= 1)
|
while (from + 1 <= from_end && n_left_to_tx >= 1)
|
||||||
@ -572,10 +570,10 @@ vnet_interface_output_node_no_flatten (vlib_main_t * vm,
|
|||||||
n_bytes += n_bytes_b0;
|
n_bytes += n_bytes_b0;
|
||||||
n_packets += 1;
|
n_packets += 1;
|
||||||
|
|
||||||
if (PREDICT_FALSE(si->output_feature_bitmap &&
|
if (with_features)
|
||||||
vnet_buffer(b0)->output_features.bitmap != (1 << INTF_OUTPUT_FEAT_DONE)))
|
|
||||||
{
|
{
|
||||||
u32 next0;
|
u32 next0;
|
||||||
|
b0->flags |= BUFFER_OUTPUT_FEAT_DONE;
|
||||||
vnet_buffer(b0)->output_features.bitmap = si->output_feature_bitmap;
|
vnet_buffer(b0)->output_features.bitmap = si->output_feature_bitmap;
|
||||||
count_trailing_zeros(next0, vnet_buffer(b0)->output_features.bitmap);
|
count_trailing_zeros(next0, vnet_buffer(b0)->output_features.bitmap);
|
||||||
vnet_buffer(b0)->output_features.bitmap &= ~(1 << next0);
|
vnet_buffer(b0)->output_features.bitmap &= ~(1 << next0);
|
||||||
@ -613,6 +611,29 @@ vnet_interface_output_node_no_flatten (vlib_main_t * vm,
|
|||||||
return n_buffers;
|
return n_buffers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uword
|
||||||
|
vnet_interface_output_node_no_flatten (vlib_main_t * vm,
|
||||||
|
vlib_node_runtime_t * node,
|
||||||
|
vlib_frame_t * frame)
|
||||||
|
{
|
||||||
|
vnet_main_t * vnm = vnet_get_main ();
|
||||||
|
vnet_interface_output_runtime_t * rt = (void *) node->runtime_data;
|
||||||
|
vnet_sw_interface_t * si;
|
||||||
|
si = vnet_get_sw_interface (vnm, rt->sw_if_index);
|
||||||
|
|
||||||
|
if (PREDICT_FALSE(si->output_feature_bitmap))
|
||||||
|
{
|
||||||
|
/* if first pakcet in the frame have BUFFER_OUTPUT_FEAT_DONE flag set
|
||||||
|
then whole frame is arriving from feature node */
|
||||||
|
|
||||||
|
u32 * from = vlib_frame_args (frame);
|
||||||
|
vlib_buffer_t * b = vlib_get_buffer (vm, from[0]);
|
||||||
|
|
||||||
|
if ((b->flags & BUFFER_OUTPUT_FEAT_DONE) == 0)
|
||||||
|
return vnet_interface_output_node_no_flatten_inline (vm, node, frame, 1);
|
||||||
|
}
|
||||||
|
return vnet_interface_output_node_no_flatten_inline (vm, node, frame, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/* Use buffer's sw_if_index[VNET_TX] to choose output interface. */
|
/* Use buffer's sw_if_index[VNET_TX] to choose output interface. */
|
||||||
static uword
|
static uword
|
||||||
|
@ -173,6 +173,7 @@ extern ip4_main_t ip4_main;
|
|||||||
extern vlib_node_registration_t ip4_input_node;
|
extern vlib_node_registration_t ip4_input_node;
|
||||||
extern vlib_node_registration_t ip4_lookup_node;
|
extern vlib_node_registration_t ip4_lookup_node;
|
||||||
extern vlib_node_registration_t ip4_rewrite_node;
|
extern vlib_node_registration_t ip4_rewrite_node;
|
||||||
|
extern vlib_node_registration_t ip4_rewrite_local_node;
|
||||||
extern vlib_node_registration_t ip4_arp_node;
|
extern vlib_node_registration_t ip4_arp_node;
|
||||||
|
|
||||||
u32 ip4_fib_lookup_with_table (ip4_main_t * im, u32 fib_index, ip4_address_t * dst,
|
u32 ip4_fib_lookup_with_table (ip4_main_t * im, u32 fib_index, ip4_address_t * dst,
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user