aboutsummaryrefslogtreecommitdiffstats
path: root/debian/patches
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches')
-rw-r--r--debian/patches/series12
-rw-r--r--debian/patches/ubuntu-backport-33-vhost-user-add-error-handling-for-fd-1023.patch141
-rw-r--r--debian/patches/ubuntu-backport-38-dpdk-dev-Memory-leak-when-adding-removing-vhost_user-ports.patch63
-rw-r--r--debian/patches/ubuntu-backport-39-lpm-fix-freeing-in-compatibility-mode.patch52
-rw-r--r--debian/patches/ubuntu-backport-40-linking-fixes-stage-1-4.patch101
-rw-r--r--debian/patches/ubuntu-backport-40-linking-fixes-stage-2-4.patch556
-rw-r--r--debian/patches/ubuntu-backport-40-linking-fixes-stage-3-4.patch217
-rw-r--r--debian/patches/ubuntu-backport-40-linking-fixes-stage-4-4.patch149
-rw-r--r--debian/patches/ubuntu-backport-41-fix-install-tar-1.29.patch25
-rw-r--r--debian/patches/ubuntu-backport-42-increase-default-logging-level.patch81
-rw-r--r--debian/patches/ubuntu-backport-43-fix-level-type-retrieving.patch61
-rw-r--r--debian/patches/ubuntu-fix-vhost-user-socket-permission.patch372
-rw-r--r--debian/patches/ubuntu-fix-xenvirt-support-dynamic-page-size.patch32
13 files changed, 1862 insertions, 0 deletions
diff --git a/debian/patches/series b/debian/patches/series
new file mode 100644
index 00000000..baab84f9
--- /dev/null
+++ b/debian/patches/series
@@ -0,0 +1,12 @@
+ubuntu-backport-33-vhost-user-add-error-handling-for-fd-1023.patch
+ubuntu-backport-38-dpdk-dev-Memory-leak-when-adding-removing-vhost_user-ports.patch
+ubuntu-fix-vhost-user-socket-permission.patch
+ubuntu-backport-39-lpm-fix-freeing-in-compatibility-mode.patch
+ubuntu-fix-xenvirt-support-dynamic-page-size.patch
+ubuntu-backport-40-linking-fixes-stage-1-4.patch
+ubuntu-backport-40-linking-fixes-stage-2-4.patch
+ubuntu-backport-40-linking-fixes-stage-3-4.patch
+ubuntu-backport-40-linking-fixes-stage-4-4.patch
+ubuntu-backport-41-fix-install-tar-1.29.patch
+ubuntu-backport-42-increase-default-logging-level.patch
+ubuntu-backport-43-fix-level-type-retrieving.patch
diff --git a/debian/patches/ubuntu-backport-33-vhost-user-add-error-handling-for-fd-1023.patch b/debian/patches/ubuntu-backport-33-vhost-user-add-error-handling-for-fd-1023.patch
new file mode 100644
index 00000000..ea1ff75b
--- /dev/null
+++ b/debian/patches/ubuntu-backport-33-vhost-user-add-error-handling-for-fd-1023.patch
@@ -0,0 +1,141 @@
+Description: backport of dpdk fix for LP: #1566874
+
+Forwarded: n/a (already discussed upstream)
+Author: Christian Ehrhardt <christian.ehrhardt@canonical.com>
+Last-Update: 2016-04-11
+
+Extended by Christian Ehrhardt <christian.ehrhardt@canonical.com>
+Close fd on vserver->listenfd (Part of the upstream discussion)
+
+Original:
+From: Patrik Andersson <patrik.r.andersson@ericsson.com>
+
+Protect against DPDK crash when allocation of listen fd >= 1023.
+For events on fd:s >1023, the current implementation will trigger
+an abort due to access outside of allocated bit mask.
+
+Corrections would include:
+
+ * Match fdset_add() signature in fd_man.c to fd_man.h
+ * Handling of return codes from fdset_add()
+ * Addition of check of fd number in fdset_add_fd()
+
+The rationale behind the suggested code change is that,
+fdset_event_dispatch() could attempt access outside of the FD_SET
+bitmask if there is an event on a file descriptor that in turn
+looks up a virtio file descriptor with a value > 1023.
+Such an attempt will lead to an abort() and a restart of any
+vswitch using DPDK.
+
+A discussion topic exist in the ovs-discuss mailing list that can
+provide a little more background:
+
+http://openvswitch.org/pipermail/discuss/2016-February/020243.html
+
+Signed-off-by: Patrik Andersson <patrik.r.andersson@ericsson.com>
+---
+ fd_man.c | 11 ++++++-----
+ vhost-net-user.c | 23 +++++++++++++++++++++--
+ 2 files changed, 27 insertions(+), 7 deletions(-)
+
+Index: dpdk/lib/librte_vhost/vhost_user/fd_man.c
+===================================================================
+--- dpdk.orig/lib/librte_vhost/vhost_user/fd_man.c
++++ dpdk/lib/librte_vhost/vhost_user/fd_man.c
+@@ -71,20 +71,22 @@ fdset_find_free_slot(struct fdset *pfdse
+ return fdset_find_fd(pfdset, -1);
+ }
+
+-static void
++static int
+ fdset_add_fd(struct fdset *pfdset, int idx, int fd,
+ fd_cb rcb, fd_cb wcb, void *dat)
+ {
+ struct fdentry *pfdentry;
+
+- if (pfdset == NULL || idx >= MAX_FDS)
+- return;
++ if (pfdset == NULL || idx >= MAX_FDS || fd >= FD_SETSIZE)
++ return -1;
+
+ pfdentry = &pfdset->fd[idx];
+ pfdentry->fd = fd;
+ pfdentry->rcb = rcb;
+ pfdentry->wcb = wcb;
+ pfdentry->dat = dat;
++
++ return 0;
+ }
+
+ /**
+@@ -150,12 +152,11 @@ fdset_add(struct fdset *pfdset, int fd,
+
+ /* Find a free slot in the list. */
+ i = fdset_find_free_slot(pfdset);
+- if (i == -1) {
++ if (i == -1 || fdset_add_fd(pfdset, i, fd, rcb, wcb, dat) < 0) {
+ pthread_mutex_unlock(&pfdset->fd_mutex);
+ return -2;
+ }
+
+- fdset_add_fd(pfdset, i, fd, rcb, wcb, dat);
+ pfdset->num++;
+
+ pthread_mutex_unlock(&pfdset->fd_mutex);
+Index: dpdk/lib/librte_vhost/vhost_user/vhost-net-user.c
+===================================================================
+--- dpdk.orig/lib/librte_vhost/vhost_user/vhost-net-user.c
++++ dpdk/lib/librte_vhost/vhost_user/vhost-net-user.c
+@@ -288,6 +288,7 @@ vserver_new_vq_conn(int fd, void *dat, _
+ int fh;
+ struct vhost_device_ctx vdev_ctx = { (pid_t)0, 0 };
+ unsigned int size;
++ int ret;
+
+ conn_fd = accept(fd, NULL, NULL);
+ RTE_LOG(INFO, VHOST_CONFIG,
+@@ -317,8 +318,15 @@ vserver_new_vq_conn(int fd, void *dat, _
+
+ ctx->vserver = vserver;
+ ctx->fh = fh;
+- fdset_add(&g_vhost_server.fdset,
++ ret = fdset_add(&g_vhost_server.fdset,
+ conn_fd, vserver_message_handler, NULL, ctx);
++ if (ret < 0) {
++ free(ctx);
++ close(conn_fd);
++ RTE_LOG(ERR, VHOST_CONFIG,
++ "failed to add fd %d into vhost server fdset\n",
++ conn_fd);
++ }
+ }
+
+ /* callback when there is message on the connfd */
+@@ -453,6 +461,7 @@ int
+ rte_vhost_driver_register(const char *path)
+ {
+ struct vhost_server *vserver;
++ int ret;
+
+ pthread_mutex_lock(&g_vhost_server.server_mutex);
+
+@@ -478,8 +487,18 @@ rte_vhost_driver_register(const char *pa
+
+ vserver->path = strdup(path);
+
+- fdset_add(&g_vhost_server.fdset, vserver->listenfd,
++ ret = fdset_add(&g_vhost_server.fdset, vserver->listenfd,
+ vserver_new_vq_conn, NULL, vserver);
++ if (ret < 0) {
++ pthread_mutex_unlock(&g_vhost_server.server_mutex);
++ RTE_LOG(ERR, VHOST_CONFIG,
++ "failed to add listen fd %d to vhost server fdset\n",
++ vserver->listenfd);
++ close(vserver->listenfd);
++ free(vserver->path);
++ free(vserver);
++ return -1;
++ }
+
+ g_vhost_server.server[g_vhost_server.vserver_cnt++] = vserver;
+ pthread_mutex_unlock(&g_vhost_server.server_mutex);
diff --git a/debian/patches/ubuntu-backport-38-dpdk-dev-Memory-leak-when-adding-removing-vhost_user-ports.patch b/debian/patches/ubuntu-backport-38-dpdk-dev-Memory-leak-when-adding-removing-vhost_user-ports.patch
new file mode 100644
index 00000000..b756d8ff
--- /dev/null
+++ b/debian/patches/ubuntu-backport-38-dpdk-dev-Memory-leak-when-adding-removing-vhost_user-ports.patch
@@ -0,0 +1,63 @@
+Description: backport of dpdk 16.07 fix for LP: #1570466
+
+Backported from this discussion
+http://dpdk.org/dev/patchwork/patch/12103/
+Not accepted yet, but likely to be accepted in some form once tested and
+confirmed.
+
+Update 2016-05-17:
+Moving to 16.04 this now applies as-is without modifications, dropping the
+former backport changes.
+
+Also along the discussion vserver-fh is now initialized with -1 to avoid
+accidentially deleting the first connected port if we delete another not yet
+connected port.
+
+Forwarded: yes (based on an upstream discussion)
+Author: Christian Ehrhardt <christian.ehrhardt@canonical.com>
+Last-Update: 2016-05-17
+
+Index: dpdk/lib/librte_vhost/vhost_user/vhost-net-user.c
+===================================================================
+--- dpdk.orig/lib/librte_vhost/vhost_user/vhost-net-user.c
++++ dpdk/lib/librte_vhost/vhost_user/vhost-net-user.c
+@@ -310,6 +310,7 @@ vserver_new_vq_conn(int fd, void *dat, _
+ }
+
+ vdev_ctx.fh = fh;
++ vserver->fh = fh;
+ size = strnlen(vserver->path, PATH_MAX);
+ vhost_set_ifname(vdev_ctx, vserver->path,
+ size);
+@@ -486,6 +487,7 @@ rte_vhost_driver_register(const char *pa
+ }
+
+ vserver->path = strdup(path);
++ vserver->fh = -1;
+
+ ret = fdset_add(&g_vhost_server.fdset, vserver->listenfd,
+ vserver_new_vq_conn, NULL, vserver);
+@@ -520,6 +522,11 @@ rte_vhost_driver_unregister(const char *
+
+ for (i = 0; i < g_vhost_server.vserver_cnt; i++) {
+ if (!strcmp(g_vhost_server.server[i]->path, path)) {
++ struct vhost_device_ctx ctx;
++
++ ctx.fh = g_vhost_server.server[i]->fh;
++ vhost_destroy_device(ctx);
++
+ fdset_del(&g_vhost_server.fdset,
+ g_vhost_server.server[i]->listenfd);
+
+Index: dpdk/lib/librte_vhost/vhost_user/vhost-net-user.h
+===================================================================
+--- dpdk.orig/lib/librte_vhost/vhost_user/vhost-net-user.h
++++ dpdk/lib/librte_vhost/vhost_user/vhost-net-user.h
+@@ -43,6 +43,7 @@
+ struct vhost_server {
+ char *path; /**< The path the uds is bind to. */
+ int listenfd; /**< The listener sockfd. */
++ uint32_t fh;
+ };
+
+ /* refer to hw/virtio/vhost-user.c */
diff --git a/debian/patches/ubuntu-backport-39-lpm-fix-freeing-in-compatibility-mode.patch b/debian/patches/ubuntu-backport-39-lpm-fix-freeing-in-compatibility-mode.patch
new file mode 100644
index 00000000..4224cad8
--- /dev/null
+++ b/debian/patches/ubuntu-backport-39-lpm-fix-freeing-in-compatibility-mode.patch
@@ -0,0 +1,52 @@
+Description: backport of dpdk 16.07 fix 7cc3f2c2
+
+Author: Christian Ehrhardt <christian.ehrhardt@canonical.com>
+Date: Tue Apr 12 15:49:27 2016 +0200
+
+ lpm: fix freeing in compatibility mode
+
+ Back then when we fixed the missing free lpm I was to quickly to say yes
+ if it applies not only to the lpm6 but also to all of the lpm code.
+
+ It turned out to not apply to all of them. In rte_lpm_create_v20 there
+ is an unexpected fused allocation:
+ mem_size = sizeof(*lpm) + (sizeof(lpm->rules_tbl[0]) * max_rules);
+ [...]
+ lpm = (struct rte_lpm_v20 *)rte_zmalloc_socket(mem_name,mem_size,
+ RTE_CACHE_LINE_SIZE, socket_id);
+
+ That causes lpm->rules_tbl not to have an own struct malloc_elem that
+ can be derived via RTE_PTR_SUB(data, MALLOC_ELEM_HEADER_LEN) in
+ malloc_elem_from_data.
+ Due to that the rte_lpm_free_v20 accidentially misderives the elem and
+ assumes it is ELEM_FREE triggering in malloc_elem_free
+ if (!malloc_elem_cookies_ok(elem) || elem->state !=
+ return -1;
+
+ While it seems counter-intuitive the way to properly remove rules_tbl in
+ the old fused allocation style of rte_lpm_free_v20 is to not remove it.
+
+ The newer rte_lpm_free_v1604 is safe because in rte_lpm_create_v1604
+ rules_tbl is a separate allocation.
+
+ Fixes: d4c18f0a1d5d ("lpm: fix missing free")
+
+ Signed-off-by: Christian Ehrhardt <christian.ehrhardt@canonical.com>
+ Acked-by: Olivier Matz <olivier.matz@6wind.com>
+
+Forwarded: yes (in DPDK 16.07)
+Author: Christian Ehrhardt <christian.ehrhardt@canonical.com>
+Last-Update: 2016-05-17
+
+Index: dpdk/lib/librte_lpm/rte_lpm.c
+===================================================================
+--- dpdk.orig/lib/librte_lpm/rte_lpm.c
++++ dpdk/lib/librte_lpm/rte_lpm.c
+@@ -373,7 +373,6 @@ rte_lpm_free_v20(struct rte_lpm_v20 *lpm
+
+ rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK);
+
+- rte_free(lpm->rules_tbl);
+ rte_free(lpm);
+ rte_free(te);
+ }
diff --git a/debian/patches/ubuntu-backport-40-linking-fixes-stage-1-4.patch b/debian/patches/ubuntu-backport-40-linking-fixes-stage-1-4.patch
new file mode 100644
index 00000000..5336cd49
--- /dev/null
+++ b/debian/patches/ubuntu-backport-40-linking-fixes-stage-1-4.patch
@@ -0,0 +1,101 @@
+Description: backport of dpdk 16.07 fix for library underlinking - stage 1/4
+
+This is a merge of related upstream fixes:
+- c6417ce6: mk: add build-time library directory to linker path
+- aace9d0b: mk: cleanup leftover references to malloc library
+- bf5a46fa: mk: generate internal library dependencies
+
+Forwarded: yes (in DPDK 16.07)
+Author: Christian Ehrhardt <christian.ehrhardt@canonical.com>
+Last-Update: 2016-06-14
+
+Index: dpdk/drivers/net/cxgbe/Makefile
+===================================================================
+--- dpdk.orig/drivers/net/cxgbe/Makefile
++++ dpdk/drivers/net/cxgbe/Makefile
+@@ -82,6 +82,6 @@ SRCS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD) += t
+ # this lib depends upon:
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD) += lib/librte_eal lib/librte_ether
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD) += lib/librte_mempool lib/librte_mbuf
+-DEPDIRS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD) += lib/librte_net lib/librte_malloc
++DEPDIRS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD) += lib/librte_net
+
+ include $(RTE_SDK)/mk/rte.lib.mk
+Index: dpdk/drivers/net/ena/Makefile
+===================================================================
+--- dpdk.orig/drivers/net/ena/Makefile
++++ dpdk/drivers/net/ena/Makefile
+@@ -54,7 +54,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_ENA_PMD) += ena
+ # this lib depends upon:
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_ENA_PMD) += lib/librte_eal lib/librte_ether
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_ENA_PMD) += lib/librte_mempool lib/librte_mbuf
+-DEPDIRS-$(CONFIG_RTE_LIBRTE_ENA_PMD) += lib/librte_net lib/librte_malloc
++DEPDIRS-$(CONFIG_RTE_LIBRTE_ENA_PMD) += lib/librte_net
+
+ CFLAGS += $(INCLUDES)
+
+Index: dpdk/drivers/net/mpipe/Makefile
+===================================================================
+--- dpdk.orig/drivers/net/mpipe/Makefile
++++ dpdk/drivers/net/mpipe/Makefile
+@@ -42,6 +42,6 @@ SRCS-$(CONFIG_RTE_LIBRTE_MPIPE_PMD) += m
+
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_MPIPE_PMD) += lib/librte_eal lib/librte_ether
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_MPIPE_PMD) += lib/librte_mempool lib/librte_mbuf
+-DEPDIRS-$(CONFIG_RTE_LIBRTE_MPIPE_PMD) += lib/librte_net lib/librte_malloc
++DEPDIRS-$(CONFIG_RTE_LIBRTE_MPIPE_PMD) += lib/librte_net
+
+ include $(RTE_SDK)/mk/rte.lib.mk
+Index: dpdk/drivers/net/nfp/Makefile
+===================================================================
+--- dpdk.orig/drivers/net/nfp/Makefile
++++ dpdk/drivers/net/nfp/Makefile
+@@ -53,6 +53,6 @@ SRCS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += nfp
+ # this lib depends upon:
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += lib/librte_eal lib/librte_ether
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += lib/librte_mempool lib/librte_mbuf
+-DEPDIRS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += lib/librte_net lib/librte_malloc
++DEPDIRS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += lib/librte_net
+
+ include $(RTE_SDK)/mk/rte.lib.mk
+Index: dpdk/drivers/net/szedata2/Makefile
+===================================================================
+--- dpdk.orig/drivers/net/szedata2/Makefile
++++ dpdk/drivers/net/szedata2/Makefile
+@@ -57,7 +57,6 @@ SYMLINK-y-include +=
+ # this lib depends upon:
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_SZEDATA2) += lib/librte_mbuf
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_SZEDATA2) += lib/librte_ether
+-DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_SZEDATA2) += lib/librte_malloc
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_SZEDATA2) += lib/librte_kvargs
+
+ include $(RTE_SDK)/mk/rte.lib.mk
+Index: dpdk/mk/rte.lib.mk
+===================================================================
+--- dpdk.orig/mk/rte.lib.mk
++++ dpdk/mk/rte.lib.mk
+@@ -77,6 +77,13 @@ else
+ _CPU_LDFLAGS := $(CPU_LDFLAGS)
+ endif
+
++# Translate DEPDIRS-y into LDLIBS
++# Ignore (sub)directory dependencies which do not provide an actual library
++_IGNORE_DIRS = lib/librte_eal/% lib/librte_net lib/librte_compat
++_DEPDIRS = $(filter-out $(_IGNORE_DIRS),$(DEPDIRS-y))
++_LDDIRS = $(subst librte_ether,libethdev,$(_DEPDIRS))
++LDLIBS += $(subst lib/lib,-l,$(_LDDIRS))
++
+ O_TO_A = $(AR) crDs $(LIB) $(OBJS-y)
+ O_TO_A_STR = $(subst ','\'',$(O_TO_A)) #'# fix syntax highlight
+ O_TO_A_DISP = $(if $(V),"$(O_TO_A_STR)"," AR $(@)")
+@@ -86,8 +93,8 @@ O_TO_A_DO = @set -e; \
+ $(O_TO_A) && \
+ echo $(O_TO_A_CMD) > $(call exe2cmd,$(@))
+
+-O_TO_S = $(LD) $(_CPU_LDFLAGS) $(EXTRA_LDFLAGS) -shared $(OBJS-y) $(LDLIBS) \
+- -Wl,-soname,$(LIB) -o $(LIB)
++O_TO_S = $(LD) -L$(RTE_OUTPUT)/lib $(_CPU_LDFLAGS) $(EXTRA_LDFLAGS) \
++ -shared $(OBJS-y) $(LDLIBS) -Wl,-soname,$(LIB) -o $(LIB)
+ O_TO_S_STR = $(subst ','\'',$(O_TO_S)) #'# fix syntax highlight
+ O_TO_S_DISP = $(if $(V),"$(O_TO_S_STR)"," LD $(@)")
+ O_TO_S_DO = @set -e; \
diff --git a/debian/patches/ubuntu-backport-40-linking-fixes-stage-2-4.patch b/debian/patches/ubuntu-backport-40-linking-fixes-stage-2-4.patch
new file mode 100644
index 00000000..30ca0d50
--- /dev/null
+++ b/debian/patches/ubuntu-backport-40-linking-fixes-stage-2-4.patch
@@ -0,0 +1,556 @@
+Description: backport of dpdk 16.07 fix for library underlinking - stage 2/4
+
+This is a merge of related upstream fixes:
+- a3f34a98 log: deprecate history dump
+- 3037e5e2 eal: remove useless includes of mempool and ring
+
+Forwarded: yes (in DPDK 16.07)
+Author: Christian Ehrhardt <christian.ehrhardt@canonical.com>
+Last-Update: 2016-06-14
+
+Index: dpdk/app/test-pmd/cmdline.c
+===================================================================
+--- dpdk.orig/app/test-pmd/cmdline.c
++++ dpdk/app/test-pmd/cmdline.c
+@@ -7191,8 +7191,6 @@ static void cmd_dump_parsed(void *parsed
+ rte_dump_physmem_layout(stdout);
+ else if (!strcmp(res->dump, "dump_memzone"))
+ rte_memzone_dump(stdout);
+- else if (!strcmp(res->dump, "dump_log_history"))
+- rte_log_dump_history(stdout);
+ else if (!strcmp(res->dump, "dump_struct_sizes"))
+ dump_struct_sizes();
+ else if (!strcmp(res->dump, "dump_ring"))
+@@ -7207,7 +7205,6 @@ cmdline_parse_token_string_t cmd_dump_du
+ TOKEN_STRING_INITIALIZER(struct cmd_dump_result, dump,
+ "dump_physmem#"
+ "dump_memzone#"
+- "dump_log_history#"
+ "dump_struct_sizes#"
+ "dump_ring#"
+ "dump_mempool#"
+Index: dpdk/app/test/autotest_data.py
+===================================================================
+--- dpdk.orig/app/test/autotest_data.py
++++ dpdk/app/test/autotest_data.py
+@@ -88,12 +88,6 @@ parallel_test_group_list = [
+ "Report" : None,
+ },
+ {
+- "Name" : "Dump log history",
+- "Command" : "dump_log_history",
+- "Func" : dump_autotest,
+- "Report" : None,
+- },
+- {
+ "Name" : "Dump rings",
+ "Command" : "dump_ring",
+ "Func" : dump_autotest,
+Index: dpdk/app/test/autotest_test_funcs.py
+===================================================================
+--- dpdk.orig/app/test/autotest_test_funcs.py
++++ dpdk/app/test/autotest_test_funcs.py
+@@ -151,12 +151,6 @@ def logs_autotest(child, test_name):
+ "TESTAPP2: this is a info level message",
+ "TESTAPP2: this is a warning level message",
+ "TESTAPP1: this is a debug level message",
+- "TESTAPP1: this is a debug level message",
+- "TESTAPP1: this is a info level message",
+- "TESTAPP1: this is a warning level message",
+- "TESTAPP2: this is a info level message",
+- "TESTAPP2: this is a warning level message",
+- "TESTAPP1: this is a debug level message",
+ ]
+
+ for log_msg in log_list:
+Index: dpdk/app/test/commands.c
+===================================================================
+--- dpdk.orig/app/test/commands.c
++++ dpdk/app/test/commands.c
+@@ -150,8 +150,6 @@ static void cmd_dump_parsed(void *parsed
+ rte_dump_physmem_layout(stdout);
+ else if (!strcmp(res->dump, "dump_memzone"))
+ rte_memzone_dump(stdout);
+- else if (!strcmp(res->dump, "dump_log_history"))
+- rte_log_dump_history(stdout);
+ else if (!strcmp(res->dump, "dump_struct_sizes"))
+ dump_struct_sizes();
+ else if (!strcmp(res->dump, "dump_ring"))
+@@ -164,7 +162,7 @@ static void cmd_dump_parsed(void *parsed
+
+ cmdline_parse_token_string_t cmd_dump_dump =
+ TOKEN_STRING_INITIALIZER(struct cmd_dump_result, dump,
+- "dump_physmem#dump_memzone#dump_log_history#"
++ "dump_physmem#dump_memzone#"
+ "dump_struct_sizes#dump_ring#dump_mempool#"
+ "dump_devargs");
+
+Index: dpdk/app/test/test_logs.c
+===================================================================
+--- dpdk.orig/app/test/test_logs.c
++++ dpdk/app/test/test_logs.c
+@@ -85,8 +85,6 @@ test_logs(void)
+ RTE_LOG(DEBUG, TESTAPP1, "this is a debug level message\n");
+ RTE_LOG(DEBUG, TESTAPP2, "debug level message (not displayed)\n");
+
+- rte_log_dump_history(stdout);
+-
+ return 0;
+ }
+
+Index: dpdk/doc/guides/prog_guide/mempool_lib.rst
+===================================================================
+--- dpdk.orig/doc/guides/prog_guide/mempool_lib.rst
++++ dpdk/doc/guides/prog_guide/mempool_lib.rst
+@@ -38,9 +38,7 @@ In the DPDK, it is identified by name an
+ It provides some other optional services such as a per-core object cache and
+ an alignment helper to ensure that objects are padded to spread them equally on all DRAM or DDR3 channels.
+
+-This library is used by the
+-:ref:`Mbuf Library <Mbuf_Library>` and the
+-:ref:`Environment Abstraction Layer <Environment_Abstraction_Layer>` (for logging history).
++This library is used by the :ref:`Mbuf Library <Mbuf_Library>`.
+
+ Cookies
+ -------
+Index: dpdk/doc/guides/rel_notes/deprecation.rst
+===================================================================
+--- dpdk.orig/doc/guides/rel_notes/deprecation.rst
++++ dpdk/doc/guides/rel_notes/deprecation.rst
+@@ -8,6 +8,9 @@ API and ABI deprecation notices are to b
+ Deprecation Notices
+ -------------------
+
++* The log history is deprecated.
++ It is voided in 16.07 and will be removed in release 16.11.
++
+ * The ethdev hotplug API is going to be moved to EAL with a notification
+ mechanism added to crypto and ethdev libraries so that hotplug is now
+ available to both of them. This API will be stripped of the device arguments
+Index: dpdk/lib/librte_eal/bsdapp/eal/Makefile
+===================================================================
+--- dpdk.orig/lib/librte_eal/bsdapp/eal/Makefile
++++ dpdk/lib/librte_eal/bsdapp/eal/Makefile
+@@ -40,8 +40,6 @@ VPATH += $(RTE_SDK)/lib/librte_eal/commo
+ CFLAGS += -I$(SRCDIR)/include
+ CFLAGS += -I$(RTE_SDK)/lib/librte_eal/common
+ CFLAGS += -I$(RTE_SDK)/lib/librte_eal/common/include
+-CFLAGS += -I$(RTE_SDK)/lib/librte_ring
+-CFLAGS += -I$(RTE_SDK)/lib/librte_mempool
+ CFLAGS += $(WERROR_FLAGS) -O3
+
+ LDLIBS += -lexecinfo
+Index: dpdk/lib/librte_eal/bsdapp/eal/eal_debug.c
+===================================================================
+--- dpdk.orig/lib/librte_eal/bsdapp/eal/eal_debug.c
++++ dpdk/lib/librte_eal/bsdapp/eal/eal_debug.c
+@@ -77,9 +77,6 @@ void __rte_panic(const char *funcname, c
+ {
+ va_list ap;
+
+- /* disable history */
+- rte_log_set_history(0);
+-
+ rte_log(RTE_LOG_CRIT, RTE_LOGTYPE_EAL, "PANIC in %s():\n", funcname);
+ va_start(ap, format);
+ rte_vlog(RTE_LOG_CRIT, RTE_LOGTYPE_EAL, format, ap);
+@@ -98,9 +95,6 @@ rte_exit(int exit_code, const char *form
+ {
+ va_list ap;
+
+- /* disable history */
+- rte_log_set_history(0);
+-
+ if (exit_code != 0)
+ RTE_LOG(CRIT, EAL, "Error - exiting with code: %d\n"
+ " Cause: ", exit_code);
+Index: dpdk/lib/librte_eal/common/eal_common_log.c
+===================================================================
+--- dpdk.orig/lib/librte_eal/common/eal_common_log.c
++++ dpdk/lib/librte_eal/common/eal_common_log.c
+@@ -31,54 +31,16 @@
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+-#include <string.h>
+ #include <stdio.h>
+ #include <stdint.h>
+ #include <stdarg.h>
+-#include <sys/types.h>
+ #include <stdlib.h>
+-#include <unistd.h>
+-#include <inttypes.h>
+-#include <errno.h>
+-#include <sys/queue.h>
+
+ #include <rte_log.h>
+-#include <rte_memory.h>
+-#include <rte_memzone.h>
+-#include <rte_launch.h>
+-#include <rte_common.h>
+-#include <rte_cycles.h>
+-#include <rte_eal.h>
+ #include <rte_per_lcore.h>
+-#include <rte_lcore.h>
+-#include <rte_atomic.h>
+-#include <rte_debug.h>
+-#include <rte_spinlock.h>
+-#include <rte_branch_prediction.h>
+-#include <rte_ring.h>
+-#include <rte_mempool.h>
+
+ #include "eal_private.h"
+
+-#define LOG_ELT_SIZE 2048
+-
+-#define LOG_HISTORY_MP_NAME "log_history"
+-
+-STAILQ_HEAD(log_history_list, log_history);
+-
+-/**
+- * The structure of a message log in the log history.
+- */
+-struct log_history {
+- STAILQ_ENTRY(log_history) next;
+- unsigned size;
+- char buf[0];
+-};
+-
+-static struct rte_mempool *log_history_mp = NULL;
+-static unsigned log_history_size = 0;
+-static struct log_history_list log_history;
+-
+ /* global log structure */
+ struct rte_logs rte_logs = {
+ .type = ~0,
+@@ -86,10 +48,7 @@ struct rte_logs rte_logs = {
+ .file = NULL,
+ };
+
+-static rte_spinlock_t log_dump_lock = RTE_SPINLOCK_INITIALIZER;
+-static rte_spinlock_t log_list_lock = RTE_SPINLOCK_INITIALIZER;
+ static FILE *default_log_stream;
+-static int history_enabled = 1;
+
+ /**
+ * This global structure stores some informations about the message
+@@ -105,59 +64,16 @@ static struct log_cur_msg log_cur_msg[RT
+ /* default logs */
+
+ int
+-rte_log_add_in_history(const char *buf, size_t size)
++rte_log_add_in_history(const char *buf __rte_unused, size_t size __rte_unused)
+ {
+- struct log_history *hist_buf = NULL;
+- static const unsigned hist_buf_size = LOG_ELT_SIZE - sizeof(*hist_buf);
+- void *obj;
+-
+- if (history_enabled == 0)
+- return 0;
+-
+- rte_spinlock_lock(&log_list_lock);
+-
+- /* get a buffer for adding in history */
+- if (log_history_size > RTE_LOG_HISTORY) {
+- hist_buf = STAILQ_FIRST(&log_history);
+- if (hist_buf) {
+- STAILQ_REMOVE_HEAD(&log_history, next);
+- log_history_size--;
+- }
+- }
+- else {
+- if (rte_mempool_mc_get(log_history_mp, &obj) < 0)
+- obj = NULL;
+- hist_buf = obj;
+- }
+-
+- /* no buffer */
+- if (hist_buf == NULL) {
+- rte_spinlock_unlock(&log_list_lock);
+- return -ENOBUFS;
+- }
+-
+- /* not enough room for msg, buffer go back in mempool */
+- if (size >= hist_buf_size) {
+- rte_mempool_mp_put(log_history_mp, hist_buf);
+- rte_spinlock_unlock(&log_list_lock);
+- return -ENOBUFS;
+- }
+-
+- /* add in history */
+- memcpy(hist_buf->buf, buf, size);
+- hist_buf->buf[size] = hist_buf->buf[hist_buf_size-1] = '\0';
+- hist_buf->size = size;
+- STAILQ_INSERT_TAIL(&log_history, hist_buf, next);
+- log_history_size++;
+- rte_spinlock_unlock(&log_list_lock);
+-
+ return 0;
+ }
+
+ void
+ rte_log_set_history(int enable)
+ {
+- history_enabled = enable;
++ if (enable)
++ RTE_LOG(WARNING, EAL, "The log history is deprecated.\n");
+ }
+
+ /* Change the stream that will be used by logging system */
+@@ -224,44 +140,8 @@ int rte_log_cur_msg_logtype(void)
+
+ /* Dump log history to file */
+ void
+-rte_log_dump_history(FILE *out)
++rte_log_dump_history(FILE *out __rte_unused)
+ {
+- struct log_history_list tmp_log_history;
+- struct log_history *hist_buf;
+- unsigned i;
+-
+- /* only one dump at a time */
+- rte_spinlock_lock(&log_dump_lock);
+-
+- /* save list, and re-init to allow logging during dump */
+- rte_spinlock_lock(&log_list_lock);
+- tmp_log_history = log_history;
+- STAILQ_INIT(&log_history);
+- log_history_size = 0;
+- rte_spinlock_unlock(&log_list_lock);
+-
+- for (i=0; i<RTE_LOG_HISTORY; i++) {
+-
+- /* remove one message from history list */
+- hist_buf = STAILQ_FIRST(&tmp_log_history);
+-
+- if (hist_buf == NULL)
+- break;
+-
+- STAILQ_REMOVE_HEAD(&tmp_log_history, next);
+-
+- /* write on stdout */
+- if (fwrite(hist_buf->buf, hist_buf->size, 1, out) == 0) {
+- rte_mempool_mp_put(log_history_mp, hist_buf);
+- break;
+- }
+-
+- /* put back message structure in pool */
+- rte_mempool_mp_put(log_history_mp, hist_buf);
+- }
+- fflush(out);
+-
+- rte_spinlock_unlock(&log_dump_lock);
+ }
+
+ /*
+@@ -308,29 +188,11 @@ rte_log(uint32_t level, uint32_t logtype
+ }
+
+ /*
+- * called by environment-specific log init function to initialize log
+- * history
++ * called by environment-specific log init function
+ */
+ int
+ rte_eal_common_log_init(FILE *default_log)
+ {
+- STAILQ_INIT(&log_history);
+-
+- /* reserve RTE_LOG_HISTORY*2 elements, so we can dump and
+- * keep logging during this time */
+- log_history_mp = rte_mempool_create(LOG_HISTORY_MP_NAME, RTE_LOG_HISTORY*2,
+- LOG_ELT_SIZE, 0, 0,
+- NULL, NULL,
+- NULL, NULL,
+- SOCKET_ID_ANY, 0);
+-
+- if ((log_history_mp == NULL) &&
+- ((log_history_mp = rte_mempool_lookup(LOG_HISTORY_MP_NAME)) == NULL)){
+- RTE_LOG(ERR, EAL, "%s(): cannot create log_history mempool\n",
+- __func__);
+- return -1;
+- }
+-
+ default_log_stream = default_log;
+ rte_openlog_stream(default_log);
+ return 0;
+Index: dpdk/lib/librte_eal/common/eal_private.h
+===================================================================
+--- dpdk.orig/lib/librte_eal/common/eal_private.h
++++ dpdk/lib/librte_eal/common/eal_private.h
+@@ -49,9 +49,6 @@ int rte_eal_memzone_init(void);
+ /**
+ * Common log initialization function (private to eal).
+ *
+- * Called by environment-specific log initialization function to initialize
+- * log history.
+- *
+ * @param default_log
+ * The default log stream to be used.
+ * @return
+Index: dpdk/lib/librte_eal/common/include/rte_log.h
+===================================================================
+--- dpdk.orig/lib/librte_eal/common/include/rte_log.h
++++ dpdk/lib/librte_eal/common/include/rte_log.h
+@@ -42,6 +42,8 @@
+ * This file provides a log API to RTE applications.
+ */
+
++#include "rte_common.h" /* for __rte_deprecated macro */
++
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+@@ -179,22 +181,27 @@ int rte_log_cur_msg_loglevel(void);
+ int rte_log_cur_msg_logtype(void);
+
+ /**
++ * @deprecated
+ * Enable or disable the history (enabled by default)
+ *
+ * @param enable
+ * true to enable, or 0 to disable history.
+ */
++__rte_deprecated
+ void rte_log_set_history(int enable);
+
+ /**
++ * @deprecated
+ * Dump the log history to a file
+ *
+ * @param f
+ * A pointer to a file for output
+ */
++__rte_deprecated
+ void rte_log_dump_history(FILE *f);
+
+ /**
++ * @deprecated
+ * Add a log message to the history.
+ *
+ * This function can be called from a user-defined log stream. It adds
+@@ -209,6 +216,7 @@ void rte_log_dump_history(FILE *f);
+ * - 0: Success.
+ * - (-ENOBUFS) if there is no room to store the message.
+ */
++__rte_deprecated
+ int rte_log_add_in_history(const char *buf, size_t size);
+
+ /**
+Index: dpdk/lib/librte_eal/linuxapp/eal/eal_debug.c
+===================================================================
+--- dpdk.orig/lib/librte_eal/linuxapp/eal/eal_debug.c
++++ dpdk/lib/librte_eal/linuxapp/eal/eal_debug.c
+@@ -77,9 +77,6 @@ void __rte_panic(const char *funcname, c
+ {
+ va_list ap;
+
+- /* disable history */
+- rte_log_set_history(0);
+-
+ rte_log(RTE_LOG_CRIT, RTE_LOGTYPE_EAL, "PANIC in %s():\n", funcname);
+ va_start(ap, format);
+ rte_vlog(RTE_LOG_CRIT, RTE_LOGTYPE_EAL, format, ap);
+@@ -98,9 +95,6 @@ rte_exit(int exit_code, const char *form
+ {
+ va_list ap;
+
+- /* disable history */
+- rte_log_set_history(0);
+-
+ if (exit_code != 0)
+ RTE_LOG(CRIT, EAL, "Error - exiting with code: %d\n"
+ " Cause: ", exit_code);
+Index: dpdk/lib/librte_eal/linuxapp/eal/eal_log.c
+===================================================================
+--- dpdk.orig/lib/librte_eal/linuxapp/eal/eal_log.c
++++ dpdk/lib/librte_eal/linuxapp/eal/eal_log.c
+@@ -50,8 +50,7 @@
+ #include "eal_private.h"
+
+ /*
+- * default log function, used once mempool (hence log history) is
+- * available
++ * default log function
+ */
+ static ssize_t
+ console_log_write(__attribute__((unused)) void *c, const char *buf, size_t size)
+@@ -60,9 +59,6 @@ console_log_write(__attribute__((unused)
+ ssize_t ret;
+ uint32_t loglevel;
+
+- /* add this log in history */
+- rte_log_add_in_history(buf, size);
+-
+ /* write on stdout */
+ ret = fwrite(buf, 1, size, stdout);
+ fflush(stdout);
+@@ -110,8 +106,7 @@ rte_eal_log_init(const char *id, int fac
+ /* early logs */
+
+ /*
+- * early log function, used during boot when mempool (hence log
+- * history) is not available
++ * early log function, used before rte_eal_log_init
+ */
+ static ssize_t
+ early_log_write(__attribute__((unused)) void *c, const char *buf, size_t size)
+Index: dpdk/lib/librte_eal/linuxapp/eal/Makefile
+===================================================================
+--- dpdk.orig/lib/librte_eal/linuxapp/eal/Makefile
++++ dpdk/lib/librte_eal/linuxapp/eal/Makefile
+@@ -44,9 +44,12 @@ VPATH += $(RTE_SDK)/lib/librte_eal/commo
+ CFLAGS += -I$(SRCDIR)/include
+ CFLAGS += -I$(RTE_SDK)/lib/librte_eal/common
+ CFLAGS += -I$(RTE_SDK)/lib/librte_eal/common/include
++ifeq ($(CONFIG_RTE_LIBRTE_IVSHMEM),y)
++# workaround for circular dependency eal -> ivshmem -> ring/mempool -> eal
+ CFLAGS += -I$(RTE_SDK)/lib/librte_ring
+ CFLAGS += -I$(RTE_SDK)/lib/librte_mempool
+ CFLAGS += -I$(RTE_SDK)/lib/librte_ivshmem
++endif
+ CFLAGS += $(WERROR_FLAGS) -O3
+
+ LDLIBS += -ldl
+Index: dpdk/lib/librte_eal/linuxapp/eal/eal_interrupts.c
+===================================================================
+--- dpdk.orig/lib/librte_eal/linuxapp/eal/eal_interrupts.c
++++ dpdk/lib/librte_eal/linuxapp/eal/eal_interrupts.c
+@@ -57,10 +57,8 @@
+ #include <rte_lcore.h>
+ #include <rte_atomic.h>
+ #include <rte_branch_prediction.h>
+-#include <rte_ring.h>
+ #include <rte_debug.h>
+ #include <rte_log.h>
+-#include <rte_mempool.h>
+ #include <rte_pci.h>
+ #include <rte_malloc.h>
+ #include <rte_errno.h>
+Index: dpdk/lib/librte_eal/linuxapp/eal/eal_ivshmem.c
+===================================================================
+--- dpdk.orig/lib/librte_eal/linuxapp/eal/eal_ivshmem.c
++++ dpdk/lib/librte_eal/linuxapp/eal/eal_ivshmem.c
+@@ -49,7 +49,6 @@
+ #include <rte_string_fns.h>
+ #include <rte_errno.h>
+ #include <rte_ring.h>
+-#include <rte_mempool.h>
+ #include <rte_malloc.h>
+ #include <rte_common.h>
+ #include <rte_ivshmem.h>
+Index: dpdk/lib/librte_ivshmem/Makefile
+===================================================================
+--- dpdk.orig/lib/librte_ivshmem/Makefile
++++ dpdk/lib/librte_ivshmem/Makefile
+@@ -46,7 +46,9 @@ SRCS-$(CONFIG_RTE_LIBRTE_IVSHMEM) := rte
+ # install includes
+ SYMLINK-$(CONFIG_RTE_LIBRTE_IVSHMEM)-include := rte_ivshmem.h
+
+-# this lib needs eal
++# this lib needs EAL, ring and mempool
++DEPDIRS-$(CONFIG_RTE_LIBRTE_IVSHMEM) += lib/librte_eal
++DEPDIRS-$(CONFIG_RTE_LIBRTE_IVSHMEM) += lib/librte_ring
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_IVSHMEM) += lib/librte_mempool
+
+ include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/debian/patches/ubuntu-backport-40-linking-fixes-stage-3-4.patch b/debian/patches/ubuntu-backport-40-linking-fixes-stage-3-4.patch
new file mode 100644
index 00000000..161832e6
--- /dev/null
+++ b/debian/patches/ubuntu-backport-40-linking-fixes-stage-3-4.patch
@@ -0,0 +1,217 @@
+Description: backport of dpdk 16.07 fix for library underlinking - stage 3/4
+
+This is a merge of related upstream fixes:
+- cb8e39da mk: sort drivers in static application link list
+- ea469893 mk: fix driver dependencies order for static application
+- 4e04fd45 mk: remove library grouping during application linking
+- 6248e442 mk: prevent overlinking in applications
+- ce18c527 mk: sort libraries in level order when linking
+- 95dc3c3c mk: reduce scope of whole-archive static linking
+
+Forwarded: yes (in DPDK 16.07)
+Author: Christian Ehrhardt <christian.ehrhardt@canonical.com>
+Last-Update: 2016-06-14
+
+Index: dpdk/mk/rte.app.mk
+===================================================================
+--- dpdk.orig/mk/rte.app.mk
++++ dpdk/mk/rte.app.mk
+@@ -50,6 +50,9 @@ ifeq ($(NO_LDSCRIPT),)
+ LDSCRIPT = $(RTE_LDSCRIPT)
+ endif
+
++# Link only the libraries used in the application
++LDFLAGS += --as-needed
++
+ # default path for libs
+ _LDLIBS-y += -L$(RTE_SDK_BIN)/lib
+
+@@ -57,11 +60,6 @@ _LDLIBS-y += -L$(RTE_SDK_BIN)/lib
+ # Order is important: from higher level to lower level
+ #
+
+-_LDLIBS-y += --whole-archive
+-
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_DISTRIBUTOR) += -lrte_distributor
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_REORDER) += -lrte_reorder
+-
+ ifeq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_KNI) += -lrte_kni
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_IVSHMEM) += -lrte_ivshmem
+@@ -70,51 +68,25 @@ endif
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_PIPELINE) += -lrte_pipeline
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_TABLE) += -lrte_table
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_PORT) += -lrte_port
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_TIMER) += -lrte_timer
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_HASH) += -lrte_hash
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_JOBSTATS) += -lrte_jobstats
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_LPM) += -lrte_lpm
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_POWER) += -lrte_power
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_ACL) += -lrte_acl
++
++_LDLIBS-$(CONFIG_RTE_LIBRTE_DISTRIBUTOR) += -lrte_distributor
++_LDLIBS-$(CONFIG_RTE_LIBRTE_REORDER) += -lrte_reorder
++_LDLIBS-$(CONFIG_RTE_LIBRTE_IP_FRAG) += -lrte_ip_frag
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_METER) += -lrte_meter
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_SCHED) += -lrte_sched
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_VHOST) += -lrte_vhost
++_LDLIBS-$(CONFIG_RTE_LIBRTE_LPM) += -lrte_lpm
++_LDLIBS-$(CONFIG_RTE_LIBRTE_ACL) += -lrte_acl
++_LDLIBS-$(CONFIG_RTE_LIBRTE_JOBSTATS) += -lrte_jobstats
++_LDLIBS-$(CONFIG_RTE_LIBRTE_POWER) += -lrte_power
+
+-# The static libraries do not know their dependencies.
+-# So linking with static library requires explicit dependencies.
+-ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),n)
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_SCHED) += -lm
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_SCHED) += -lrt
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_METER) += -lm
+-ifeq ($(CONFIG_RTE_LIBRTE_VHOST_NUMA),y)
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_VHOST) += -lnuma
+-endif
+-ifeq ($(CONFIG_RTE_LIBRTE_VHOST_USER),n)
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_VHOST) += -lfuse
+-endif
+-_LDLIBS-$(CONFIG_RTE_PORT_PCAP) += -lpcap
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_PCAP) += -lpcap
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_BNX2X_PMD) += -lz
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += -libverbs
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += -libverbs
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SZEDATA2) += -lsze2
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_XENVIRT) += -lxenstore
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_MPIPE_PMD) += -lgxio
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += -lm
+-# QAT / AESNI GCM PMDs are dependent on libcrypto (from openssl)
+-# for calculating HMAC precomputes
+-ifeq ($(CONFIG_RTE_LIBRTE_PMD_QAT),y)
+-_LDLIBS-y += -lcrypto
+-else ifeq ($(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM),y)
+-_LDLIBS-y += -lcrypto
+-endif
+-endif # !CONFIG_RTE_BUILD_SHARED_LIBS
++_LDLIBS-y += --whole-archive
+
+-_LDLIBS-y += --start-group
++_LDLIBS-$(CONFIG_RTE_LIBRTE_TIMER) += -lrte_timer
++_LDLIBS-$(CONFIG_RTE_LIBRTE_HASH) += -lrte_hash
++_LDLIBS-$(CONFIG_RTE_LIBRTE_VHOST) += -lrte_vhost
+
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_KVARGS) += -lrte_kvargs
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_MBUF) += -lrte_mbuf
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_IP_FRAG) += -lrte_ip_frag
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_ETHER) += -lethdev
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += -lrte_cryptodev
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_MEMPOOL) += -lrte_mempool
+@@ -123,61 +95,65 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_EAL)
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_CMDLINE) += -lrte_cmdline
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_CFGFILE) += -lrte_cfgfile
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += -lrte_pmd_bond
+-
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_XENVIRT) += -lrte_pmd_xenvirt
++_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_XENVIRT) += -lrte_pmd_xenvirt -lxenstore
+
+ ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),n)
+ # plugins (link only if static libraries)
+
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_VMXNET3_PMD) += -lrte_pmd_vmxnet3_uio
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += -lrte_pmd_virtio
++_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AF_PACKET) += -lrte_pmd_af_packet
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_BNX2X_PMD) += -lrte_pmd_bnx2x
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD) += -lrte_pmd_cxgbe
++_LDLIBS-$(CONFIG_RTE_LIBRTE_E1000_PMD) += -lrte_pmd_e1000
++_LDLIBS-$(CONFIG_RTE_LIBRTE_ENA_PMD) += -lrte_pmd_ena
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_ENIC_PMD) += -lrte_pmd_enic
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += -lrte_pmd_i40e
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += -lrte_pmd_fm10k
++_LDLIBS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += -lrte_pmd_i40e
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += -lrte_pmd_ixgbe
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_E1000_PMD) += -lrte_pmd_e1000
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_ENA_PMD) += -lrte_pmd_ena
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += -lrte_pmd_mlx4
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += -lrte_pmd_mlx5
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += -lrte_pmd_nfp
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SZEDATA2) += -lrte_pmd_szedata2
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_MPIPE_PMD) += -lrte_pmd_mpipe
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_RING) += -lrte_pmd_ring
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_PCAP) += -lrte_pmd_pcap
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AF_PACKET) += -lrte_pmd_af_packet
++_LDLIBS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += -lrte_pmd_mlx4 -libverbs
++_LDLIBS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += -lrte_pmd_mlx5 -libverbs
++_LDLIBS-$(CONFIG_RTE_LIBRTE_MPIPE_PMD) += -lrte_pmd_mpipe -lgxio
++_LDLIBS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += -lrte_pmd_nfp -lm
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_NULL) += -lrte_pmd_null
++_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_PCAP) += -lrte_pmd_pcap -lpcap
++_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_RING) += -lrte_pmd_ring
++_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SZEDATA2) += -lrte_pmd_szedata2 -lsze2
++_LDLIBS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += -lrte_pmd_virtio
++ifeq ($(CONFIG_RTE_LIBRTE_VHOST),y)
++_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_VHOST) += -lrte_pmd_vhost
++endif # $(CONFIG_RTE_LIBRTE_VHOST)
++_LDLIBS-$(CONFIG_RTE_LIBRTE_VMXNET3_PMD) += -lrte_pmd_vmxnet3_uio
+
+ ifeq ($(CONFIG_RTE_LIBRTE_CRYPTODEV),y)
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_QAT) += -lrte_pmd_qat
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += -lrte_pmd_aesni_mb
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += -lrte_pmd_aesni_gcm
++_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += -L$(AESNI_MULTI_BUFFER_LIB_PATH) -lIPSec_MB
++_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += -lrte_pmd_aesni_gcm
++_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += -L$(AESNI_MULTI_BUFFER_LIB_PATH) -lIPSec_MB
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_NULL_CRYPTO) += -lrte_pmd_null_crypto
+-
+-# AESNI MULTI BUFFER / GCM PMDs are dependent on the IPSec_MB library
+-ifeq ($(CONFIG_RTE_LIBRTE_PMD_AESNI_MB),y)
+-_LDLIBS-y += -L$(AESNI_MULTI_BUFFER_LIB_PATH) -lIPSec_MB
+-else ifeq ($(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM),y)
+-_LDLIBS-y += -L$(AESNI_MULTI_BUFFER_LIB_PATH) -lIPSec_MB
+-endif
+-
+-# SNOW3G PMD is dependent on the LIBSSO library
++_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_QAT) += -lrte_pmd_qat
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SNOW3G) += -lrte_pmd_snow3g
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SNOW3G) += -L$(LIBSSO_PATH)/build -lsso
+ endif # CONFIG_RTE_LIBRTE_CRYPTODEV
+
+-ifeq ($(CONFIG_RTE_LIBRTE_VHOST),y)
+-
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_VHOST) += -lrte_pmd_vhost
++endif # !CONFIG_RTE_BUILD_SHARED_LIBS
+
+-endif # $(CONFIG_RTE_LIBRTE_VHOST)
++_LDLIBS-y += --no-whole-archive
+
+-endif # ! $(CONFIG_RTE_BUILD_SHARED_LIB)
++ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),n)
++# The static libraries do not know their dependencies.
++# So linking with static library requires explicit dependencies.
++_LDLIBS-$(CONFIG_RTE_LIBRTE_SCHED) += -lm
++_LDLIBS-$(CONFIG_RTE_LIBRTE_SCHED) += -lrt
++_LDLIBS-$(CONFIG_RTE_LIBRTE_METER) += -lm
++ifeq ($(CONFIG_RTE_LIBRTE_VHOST_NUMA),y)
++_LDLIBS-$(CONFIG_RTE_LIBRTE_VHOST) += -lnuma
++endif
++ifeq ($(CONFIG_RTE_LIBRTE_VHOST_USER),n)
++_LDLIBS-$(CONFIG_RTE_LIBRTE_VHOST) += -lfuse
++endif
++_LDLIBS-$(CONFIG_RTE_PORT_PCAP) += -lpcap
++endif # !CONFIG_RTE_BUILD_SHARED_LIBS
+
+ _LDLIBS-y += $(EXECENV_LDLIBS)
+-_LDLIBS-y += --end-group
+-_LDLIBS-y += --no-whole-archive
+
+ LDLIBS += $(_LDLIBS-y) $(CPU_LDLIBS) $(EXTRA_LDLIBS)
+
+Index: dpdk/mk/exec-env/linuxapp/rte.vars.mk
+===================================================================
+--- dpdk.orig/mk/exec-env/linuxapp/rte.vars.mk
++++ dpdk/mk/exec-env/linuxapp/rte.vars.mk
+@@ -45,9 +45,6 @@ else
+ EXECENV_CFLAGS = -pthread
+ endif
+
+-# Workaround lack of DT_NEEDED entry
+-EXECENV_LDFLAGS = --no-as-needed
+-
+ EXECENV_LDLIBS =
+ EXECENV_ASFLAGS =
+
diff --git a/debian/patches/ubuntu-backport-40-linking-fixes-stage-4-4.patch b/debian/patches/ubuntu-backport-40-linking-fixes-stage-4-4.patch
new file mode 100644
index 00000000..188ee2bd
--- /dev/null
+++ b/debian/patches/ubuntu-backport-40-linking-fixes-stage-4-4.patch
@@ -0,0 +1,149 @@
+Description: backport of dpdk 16.07 fix for library underlinking - stage 4/4
+
+This is a merge of related upstream fixes:
+- 473b718f mk: fix vhost dependency to pthread
+- 6cbf4f75 mk: fix missing internal dependencies
+
+Forwarded: yes (in DPDK 16.07)
+Author: Christian Ehrhardt <christian.ehrhardt@canonical.com>
+Last-Update: 2016-06-14
+
+Index: dpdk/drivers/net/vhost/Makefile
+===================================================================
+--- dpdk.orig/drivers/net/vhost/Makefile
++++ dpdk/drivers/net/vhost/Makefile
+@@ -36,6 +36,8 @@ include $(RTE_SDK)/mk/rte.vars.mk
+ #
+ LIB = librte_pmd_vhost.a
+
++LDLIBS += -lpthread
++
+ CFLAGS += -O3
+ CFLAGS += $(WERROR_FLAGS)
+
+@@ -54,6 +56,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PMD_VHOST) += r
+ SYMLINK-y-include += rte_eth_vhost.h
+
+ # this lib depends upon:
++DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_VHOST) += lib/librte_eal
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_VHOST) += lib/librte_mbuf
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_VHOST) += lib/librte_ether
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_VHOST) += lib/librte_kvargs
+Index: dpdk/drivers/crypto/null/Makefile
+===================================================================
+--- dpdk.orig/drivers/crypto/null/Makefile
++++ dpdk/drivers/crypto/null/Makefile
+@@ -55,5 +55,7 @@ SYMLINK-y-include +=
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_NULL_CRYPTO) += lib/librte_eal
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_NULL_CRYPTO) += lib/librte_mbuf
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_NULL_CRYPTO) += lib/librte_cryptodev
++DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_NULL_CRYPTO) += lib/librte_ring
++DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_NULL_CRYPTO) += lib/librte_kvargs
+
+ include $(RTE_SDK)/mk/rte.lib.mk
+Index: dpdk/drivers/net/af_packet/Makefile
+===================================================================
+--- dpdk.orig/drivers/net/af_packet/Makefile
++++ dpdk/drivers/net/af_packet/Makefile
+@@ -51,6 +51,7 @@ CFLAGS += $(WERROR_FLAGS)
+ SRCS-$(CONFIG_RTE_LIBRTE_PMD_AF_PACKET) += rte_eth_af_packet.c
+
+ # this lib depends upon:
++DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_AF_PACKET) += lib/librte_eal
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_AF_PACKET) += lib/librte_mbuf
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_AF_PACKET) += lib/librte_ether
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_AF_PACKET) += lib/librte_kvargs
+Index: dpdk/drivers/net/bonding/Makefile
+===================================================================
+--- dpdk.orig/drivers/net/bonding/Makefile
++++ dpdk/drivers/net/bonding/Makefile
+@@ -64,5 +64,7 @@ DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) +=
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += lib/librte_eal
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += lib/librte_kvargs
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += lib/librte_cmdline
++DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += lib/librte_mempool
++DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += lib/librte_ring
+
+ include $(RTE_SDK)/mk/rte.lib.mk
+Index: dpdk/drivers/net/fm10k/Makefile
+===================================================================
+--- dpdk.orig/drivers/net/fm10k/Makefile
++++ dpdk/drivers/net/fm10k/Makefile
+@@ -99,5 +99,6 @@ SRCS-$(CONFIG_RTE_LIBRTE_FM10K_INC_VECTO
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += lib/librte_eal lib/librte_ether
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += lib/librte_mempool lib/librte_mbuf
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += lib/librte_net
++DEPDIRS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += lib/librte_kvargs
+
+ include $(RTE_SDK)/mk/rte.lib.mk
+Index: dpdk/drivers/net/null/Makefile
+===================================================================
+--- dpdk.orig/drivers/net/null/Makefile
++++ dpdk/drivers/net/null/Makefile
+@@ -54,6 +54,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PMD_NULL) += rt
+ SYMLINK-y-include += rte_eth_null.h
+
+ # this lib depends upon:
++DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_NULL) += lib/librte_eal
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_NULL) += lib/librte_mbuf
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_NULL) += lib/librte_ether
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_NULL) += lib/librte_kvargs
+Index: dpdk/drivers/net/pcap/Makefile
+===================================================================
+--- dpdk.orig/drivers/net/pcap/Makefile
++++ dpdk/drivers/net/pcap/Makefile
+@@ -56,6 +56,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PMD_PCAP) += rt
+ SYMLINK-y-include +=
+
+ # this lib depends upon:
++DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_PCAP) += lib/librte_eal
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_PCAP) += lib/librte_mbuf
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_PCAP) += lib/librte_ether
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_PCAP) += lib/librte_kvargs
+Index: dpdk/lib/librte_ip_frag/Makefile
+===================================================================
+--- dpdk.orig/lib/librte_ip_frag/Makefile
++++ dpdk/lib/librte_ip_frag/Makefile
+@@ -54,6 +54,7 @@ SYMLINK-$(CONFIG_RTE_LIBRTE_IP_FRAG)-inc
+
+
+ # this library depends on rte_ether
++DEPDIRS-$(CONFIG_RTE_LIBRTE_IP_FRAG) += lib/librte_eal
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_IP_FRAG) += lib/librte_mempool lib/librte_ether
+
+ include $(RTE_SDK)/mk/rte.lib.mk
+Index: dpdk/lib/librte_pipeline/Makefile
+===================================================================
+--- dpdk.orig/lib/librte_pipeline/Makefile
++++ dpdk/lib/librte_pipeline/Makefile
+@@ -52,6 +52,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) := rt
+ SYMLINK-$(CONFIG_RTE_LIBRTE_PIPELINE)-include += rte_pipeline.h
+
+ # this lib depends upon:
++DEPDIRS-$(CONFIG_RTE_LIBRTE_PIPELINE) += lib/librte_eal
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PIPELINE) := lib/librte_table
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PIPELINE) += lib/librte_port
+
+Index: dpdk/lib/librte_port/Makefile
+===================================================================
+--- dpdk.orig/lib/librte_port/Makefile
++++ dpdk/lib/librte_port/Makefile
+@@ -75,5 +75,6 @@ DEPDIRS-$(CONFIG_RTE_LIBRTE_PORT) += lib
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PORT) += lib/librte_mempool
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PORT) += lib/librte_ether
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PORT) += lib/librte_ip_frag
++DEPDIRS-$(CONFIG_RTE_LIBRTE_PORT) += lib/librte_sched
+
+ include $(RTE_SDK)/mk/rte.lib.mk
+Index: dpdk/lib/librte_sched/Makefile
+===================================================================
+--- dpdk.orig/lib/librte_sched/Makefile
++++ dpdk/lib/librte_sched/Makefile
+@@ -59,6 +59,7 @@ SYMLINK-$(CONFIG_RTE_LIBRTE_SCHED)-inclu
+ SYMLINK-$(CONFIG_RTE_LIBRTE_SCHED)-include += rte_reciprocal.h
+
+ # this lib depends upon:
++DEPDIRS-$(CONFIG_RTE_LIBRTE_SCHED) += lib/librte_eal
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_SCHED) += lib/librte_mempool lib/librte_mbuf
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_SCHED) += lib/librte_net lib/librte_timer
+
diff --git a/debian/patches/ubuntu-backport-41-fix-install-tar-1.29.patch b/debian/patches/ubuntu-backport-41-fix-install-tar-1.29.patch
new file mode 100644
index 00000000..e485e528
--- /dev/null
+++ b/debian/patches/ubuntu-backport-41-fix-install-tar-1.29.patch
@@ -0,0 +1,25 @@
+Description: backport of dpdk 16.07 fix for tar >=1.29
+
+This is a backport of:
+- dd9ae4c7 mk: fix install with tar 1.29
+
+Forwarded: yes (in DPDK 16.07)
+Author: Christian Ehrhardt <christian.ehrhardt@canonical.com>
+Last-Update: 2016-06-14
+
+Index: dpdk/mk/rte.sdkinstall.mk
+===================================================================
+--- dpdk.orig/mk/rte.sdkinstall.mk
++++ dpdk/mk/rte.sdkinstall.mk
+@@ -116,9 +116,9 @@ install-runtime:
+ $(Q)$(call rte_mkdir, $(DESTDIR)$(libdir))
+ $(Q)cp -a $O/lib/* $(DESTDIR)$(libdir)
+ $(Q)$(call rte_mkdir, $(DESTDIR)$(bindir))
+- $(Q)tar -cf - -C $O app --exclude 'app/*.map' \
++ $(Q)tar -cf - -C $O --exclude 'app/*.map' \
+ --exclude 'app/cmdline*' --exclude app/test \
+- --exclude app/testacl --exclude app/testpipeline | \
++ --exclude app/testacl --exclude app/testpipeline app | \
+ tar -xf - -C $(DESTDIR)$(bindir) --strip-components=1 \
+ --keep-newer-files --warning=no-ignore-newer
+ $(Q)$(call rte_mkdir, $(DESTDIR)$(datadir))
diff --git a/debian/patches/ubuntu-backport-42-increase-default-logging-level.patch b/debian/patches/ubuntu-backport-42-increase-default-logging-level.patch
new file mode 100644
index 00000000..de641035
--- /dev/null
+++ b/debian/patches/ubuntu-backport-42-increase-default-logging-level.patch
@@ -0,0 +1,81 @@
+Index: dpdk/config/common_base
+===================================================================
+--- dpdk.orig/config/common_base
++++ dpdk/config/common_base
+@@ -88,7 +88,7 @@ CONFIG_RTE_MAX_NUMA_NODES=8
+ CONFIG_RTE_MAX_MEMSEG=256
+ CONFIG_RTE_MAX_MEMZONE=2560
+ CONFIG_RTE_MAX_TAILQ=32
+-CONFIG_RTE_LOG_LEVEL=8
++CONFIG_RTE_LOG_LEVEL=RTE_LOG_INFO
+ CONFIG_RTE_LOG_HISTORY=256
+ CONFIG_RTE_LIBEAL_USE_HPET=n
+ CONFIG_RTE_EAL_ALLOW_INV_SOCKET_ID=n
+Index: dpdk/doc/guides/faq/faq.rst
+===================================================================
+--- dpdk.orig/doc/guides/faq/faq.rst
++++ dpdk/doc/guides/faq/faq.rst
+@@ -88,9 +88,7 @@ the wrong socket, the application simply
+ On application startup, there is a lot of EAL information printed. Is there any way to reduce this?
+ ---------------------------------------------------------------------------------------------------
+
+-Yes, each EAL has a configuration file that is located in the /config directory. Within each configuration file, you will find CONFIG_RTE_LOG_LEVEL=8.
+-You can change this to a lower value, such as 6 to reduce this printout of debug information. The following is a list of LOG levels that can be found in the rte_log.h file.
+-You must remove, then rebuild, the EAL directory for the change to become effective as the configuration file creates the rte_config.h file in the EAL directory.
++Yes, the option ``--log-level=`` accepts one of these numbers:
+
+ .. code-block:: c
+
+@@ -103,6 +101,9 @@ You must remove, then rebuild, the EAL d
+ #define RTE_LOG_INFO 7U /* Informational. */
+ #define RTE_LOG_DEBUG 8U /* Debug-level messages. */
+
++It is also possible to change the maximum (and default level) at compile time
++with ``CONFIG_RTE_LOG_LEVEL``.
++
+
+ How can I tune my network application to achieve lower latency?
+ ---------------------------------------------------------------
+Index: dpdk/lib/librte_eal/common/eal_common_log.c
+===================================================================
+--- dpdk.orig/lib/librte_eal/common/eal_common_log.c
++++ dpdk/lib/librte_eal/common/eal_common_log.c
+@@ -195,5 +195,10 @@ rte_eal_common_log_init(FILE *default_lo
+ {
+ default_log_stream = default_log;
+ rte_openlog_stream(default_log);
++
++#if RTE_LOG_LEVEL >= RTE_LOG_DEBUG
++ RTE_LOG(NOTICE, EAL, "Debug logs available - lower performance\n");
++#endif
++
+ return 0;
+ }
+Index: dpdk/lib/librte_eal/common/eal_common_options.c
+===================================================================
+--- dpdk.orig/lib/librte_eal/common/eal_common_options.c
++++ dpdk/lib/librte_eal/common/eal_common_options.c
+@@ -141,7 +141,11 @@ eal_reset_internal_config(struct interna
+
+ internal_cfg->syslog_facility = LOG_DAEMON;
+ /* default value from build option */
++#if RTE_LOG_LEVEL >= RTE_LOG_DEBUG
++ internal_cfg->log_level = RTE_LOG_INFO;
++#else
+ internal_cfg->log_level = RTE_LOG_LEVEL;
++#endif
+
+ internal_cfg->xen_dom0_support = 0;
+
+Index: dpdk/scripts/test-build.sh
+===================================================================
+--- dpdk.orig/scripts/test-build.sh
++++ dpdk/scripts/test-build.sh
+@@ -138,6 +138,7 @@ config () # <directory> <target> <option
+ ! echo $3 | grep -q '+shared' || \
+ sed -ri 's,(SHARED_LIB=)n,\1y,' $1/.config
+ ! echo $3 | grep -q '+debug' || ( \
++ sed -ri 's,(RTE_LOG_LEVEL=).*,\1RTE_LOG_DEBUG,' $1/.config
+ sed -ri 's,(_DEBUG.*=)n,\1y,' $1/.config
+ sed -ri 's,(_STAT.*=)n,\1y,' $1/.config
+ sed -ri 's,(TEST_PMD_RECORD_.*=)n,\1y,' $1/.config )
diff --git a/debian/patches/ubuntu-backport-43-fix-level-type-retrieving.patch b/debian/patches/ubuntu-backport-43-fix-level-type-retrieving.patch
new file mode 100644
index 00000000..9a56223f
--- /dev/null
+++ b/debian/patches/ubuntu-backport-43-fix-level-type-retrieving.patch
@@ -0,0 +1,61 @@
+Index: dpdk/lib/librte_eal/common/eal_common_log.c
+===================================================================
+--- dpdk.orig/lib/librte_eal/common/eal_common_log.c
++++ dpdk/lib/librte_eal/common/eal_common_log.c
+@@ -57,9 +57,10 @@ static FILE *default_log_stream;
+ struct log_cur_msg {
+ uint32_t loglevel; /**< log level - see rte_log.h */
+ uint32_t logtype; /**< log type - see rte_log.h */
+-} __rte_cache_aligned;
+-static struct log_cur_msg log_cur_msg[RTE_MAX_LCORE]; /**< per core log */
++};
+
++ /* per core log */
++static RTE_DEFINE_PER_LCORE(struct log_cur_msg, log_cur_msg);
+
+ /* default logs */
+
+@@ -121,21 +122,13 @@ rte_get_log_type(void)
+ /* get the current loglevel for the message beeing processed */
+ int rte_log_cur_msg_loglevel(void)
+ {
+- unsigned lcore_id;
+- lcore_id = rte_lcore_id();
+- if (lcore_id >= RTE_MAX_LCORE)
+- return rte_get_log_level();
+- return log_cur_msg[lcore_id].loglevel;
++ return RTE_PER_LCORE(log_cur_msg).loglevel;
+ }
+
+ /* get the current logtype for the message beeing processed */
+ int rte_log_cur_msg_logtype(void)
+ {
+- unsigned lcore_id;
+- lcore_id = rte_lcore_id();
+- if (lcore_id >= RTE_MAX_LCORE)
+- return rte_get_log_type();
+- return log_cur_msg[lcore_id].logtype;
++ return RTE_PER_LCORE(log_cur_msg).logtype;
+ }
+
+ /* Dump log history to file */
+@@ -153,17 +146,13 @@ rte_vlog(uint32_t level, uint32_t logtyp
+ {
+ int ret;
+ FILE *f = rte_logs.file;
+- unsigned lcore_id;
+
+ if ((level > rte_logs.level) || !(logtype & rte_logs.type))
+ return 0;
+
+ /* save loglevel and logtype in a global per-lcore variable */
+- lcore_id = rte_lcore_id();
+- if (lcore_id < RTE_MAX_LCORE) {
+- log_cur_msg[lcore_id].loglevel = level;
+- log_cur_msg[lcore_id].logtype = logtype;
+- }
++ RTE_PER_LCORE(log_cur_msg).loglevel = level;
++ RTE_PER_LCORE(log_cur_msg).logtype = logtype;
+
+ ret = vfprintf(f, format, ap);
+ fflush(f);
diff --git a/debian/patches/ubuntu-fix-vhost-user-socket-permission.patch b/debian/patches/ubuntu-fix-vhost-user-socket-permission.patch
new file mode 100644
index 00000000..c2a9cdbf
--- /dev/null
+++ b/debian/patches/ubuntu-fix-vhost-user-socket-permission.patch
@@ -0,0 +1,372 @@
+Description: eal: provide option to set vhost_user socket owner/permissions
+
+The API doesn't hold a way to specify a owner/permission set for vhost_user
+created sockets.
+
+Projects consuming DPDK started to do 'their own workarounds' like openvswitch
+https://patchwork.ozlabs.org/patch/559043/
+https://patchwork.ozlabs.org/patch/559045/
+But for this specific example they are blocked/stalled behind a bigger
+rework (https://patchwork.ozlabs.org/patch/604898/).
+
+We need something now for existing code linking against DPDK. That implies to
+avoid changing API/ABI. So I created a DPDK EAL commandline option based ideas
+in the former patches.
+
+Fixes LP: #1546565
+
+*Update*
+ - with the split libs it now nees to be listed in
+ lib/librte_eal/linuxapp/eal/rte_eal_version.map to work on link steps
+ - please note that upstream gravitates towards not extending but creating a
+ new the API in DPDK as long term solution (will take a while)
+ - also as listed before most affected projects seem to create their own
+ workaround.
+ So over time we have to check when we can drop it at the price of a config
+ transition - likely OVS 2.6 won't need it anymore.
+
+Forwarded: yes
+Author: Christian Ehrhardt <christian.ehrhardt@canonical.com>
+Last-Update: 2016-05-18
+
+Index: dpdk/lib/librte_eal/common/eal_common_options.c
+===================================================================
+--- dpdk.orig/lib/librte_eal/common/eal_common_options.c
++++ dpdk/lib/librte_eal/common/eal_common_options.c
+@@ -95,6 +95,8 @@ eal_long_options[] = {
+ {OPT_VFIO_INTR, 1, NULL, OPT_VFIO_INTR_NUM },
+ {OPT_VMWARE_TSC_MAP, 0, NULL, OPT_VMWARE_TSC_MAP_NUM },
+ {OPT_XEN_DOM0, 0, NULL, OPT_XEN_DOM0_NUM },
++ {OPT_VHOST_OWNER, 1, NULL, OPT_VHOST_OWNER_NUM },
++ {OPT_VHOST_PERM, 1, NULL, OPT_VHOST_PERM_NUM },
+ {0, 0, NULL, 0 }
+ };
+
+@@ -153,6 +155,8 @@ eal_reset_internal_config(struct interna
+ #endif
+ internal_cfg->vmware_tsc_map = 0;
+ internal_cfg->create_uio_dev = 0;
++ internal_cfg->vhost_sock_owner = NULL;
++ internal_cfg->vhost_sock_perm = NULL;
+ }
+
+ static int
+Index: dpdk/lib/librte_eal/common/eal_internal_cfg.h
+===================================================================
+--- dpdk.orig/lib/librte_eal/common/eal_internal_cfg.h
++++ dpdk/lib/librte_eal/common/eal_internal_cfg.h
+@@ -83,6 +83,8 @@ struct internal_config {
+ volatile enum rte_intr_mode vfio_intr_mode;
+ const char *hugefile_prefix; /**< the base filename of hugetlbfs files */
+ const char *hugepage_dir; /**< specific hugetlbfs directory to use */
++ const char *vhost_sock_owner; /**< owner:group of vhost_user sockets */
++ const char *vhost_sock_perm; /**< permissions of vhost_user sockets */
+
+ unsigned num_hugepage_sizes; /**< how many sizes on this system */
+ struct hugepage_info hugepage_info[MAX_HUGEPAGE_SIZES];
+Index: dpdk/lib/librte_eal/common/eal_options.h
+===================================================================
+--- dpdk.orig/lib/librte_eal/common/eal_options.h
++++ dpdk/lib/librte_eal/common/eal_options.h
+@@ -83,6 +83,10 @@ enum {
+ OPT_VMWARE_TSC_MAP_NUM,
+ #define OPT_XEN_DOM0 "xen-dom0"
+ OPT_XEN_DOM0_NUM,
++#define OPT_VHOST_OWNER "vhost-owner"
++ OPT_VHOST_OWNER_NUM,
++#define OPT_VHOST_PERM "vhost-perm"
++ OPT_VHOST_PERM_NUM,
+ OPT_LONG_MAX_NUM
+ };
+
+Index: dpdk/lib/librte_vhost/vhost_user/vhost-net-user.c
+===================================================================
+--- dpdk.orig/lib/librte_vhost/vhost_user/vhost-net-user.c
++++ dpdk/lib/librte_vhost/vhost_user/vhost-net-user.c
+@@ -51,6 +51,8 @@
+ #include "vhost-net.h"
+ #include "virtio-net-user.h"
+
++#include <rte_eal.h>
++
+ #define MAX_VIRTIO_BACKLOG 128
+
+ static void vserver_new_vq_conn(int fd, void *data, int *remove);
+@@ -486,6 +488,8 @@ rte_vhost_driver_register(const char *pa
+ return -1;
+ }
+
++ rte_eal_set_socket_permissions(path);
++
+ vserver->path = strdup(path);
+ vserver->fh = -1;
+
+Index: dpdk/lib/librte_eal/linuxapp/eal/eal.c
+===================================================================
+--- dpdk.orig/lib/librte_eal/linuxapp/eal/eal.c
++++ dpdk/lib/librte_eal/linuxapp/eal/eal.c
+@@ -53,6 +53,9 @@
+ #if defined(RTE_ARCH_X86)
+ #include <sys/io.h>
+ #endif
++#include <sys/types.h>
++#include <pwd.h>
++#include <grp.h>
+
+ #include <rte_common.h>
+ #include <rte_debug.h>
+@@ -343,6 +346,8 @@ eal_usage(const char *prgname)
+ " --"OPT_CREATE_UIO_DEV" Create /dev/uioX (usually done by hotplug)\n"
+ " --"OPT_VFIO_INTR" Interrupt mode for VFIO (legacy|msi|msix)\n"
+ " --"OPT_XEN_DOM0" Support running on Xen dom0 without hugetlbfs\n"
++ " --"OPT_VHOST_OWNER" Create vhost-user sockets with this owner:group\n"
++ " --"OPT_VHOST_PERM" Create vhost-user sockets with these permissions\n"
+ "\n");
+ /* Allow the application to print its usage message too if hook is set */
+ if ( rte_application_usage_hook ) {
+@@ -618,6 +623,14 @@ eal_parse_args(int argc, char **argv)
+ internal_config.create_uio_dev = 1;
+ break;
+
++ case OPT_VHOST_OWNER_NUM:
++ internal_config.vhost_sock_owner = optarg;
++ break;
++
++ case OPT_VHOST_PERM_NUM:
++ internal_config.vhost_sock_perm = optarg;
++ break;
++
+ default:
+ if (opt < OPT_LONG_MIN_NUM && isprint(opt)) {
+ RTE_LOG(ERR, EAL, "Option %c is not supported "
+@@ -934,3 +947,172 @@ rte_eal_check_module(const char *module_
+ /* Module has been found */
+ return 1;
+ }
++
++/* Try to double the size of '*buf', return true
++ * if successful, and '*sizep' will be updated with
++ * the new size. Otherwise, return false. */
++static int
++enlarge_buffer(char **buf, size_t *sizep)
++{
++ size_t newsize = *sizep * 2;
++
++ if (newsize > *sizep) {
++ *buf = realloc(*buf, newsize);
++ *sizep = newsize;
++ return 1;
++ }
++
++ return 0;
++}
++
++static int
++get_owners_from_str(const char *user_spec, uid_t *uid, gid_t *gid)
++{
++ size_t bufsize = 4096;
++
++ char *pos = strchr(user_spec, ':');
++ user_spec += strspn(user_spec, " \t\r\n");
++ size_t len = pos ? (size_t)(pos - user_spec) : strlen(user_spec);
++
++ char *buf = NULL;
++ struct passwd pwd, *res;
++ int e;
++
++ buf = malloc(bufsize);
++ char *user_search = NULL;
++ if (len) {
++ user_search = malloc(len + 1);
++ memcpy(user_search, user_spec, len);
++ user_search[len] = '\0';
++ while ((e = getpwnam_r(user_search, &pwd, buf, bufsize, &res)) == ERANGE) {
++ if (!enlarge_buffer(&buf, &bufsize)) {
++ break;
++ }
++ }
++
++ if (e != 0) {
++ RTE_LOG(ERR, EAL,"Failed to retrive user %s's uid (%s), aborting.",
++ user_search, strerror(e));
++ goto release;
++ }
++ if (res == NULL) {
++ RTE_LOG(ERR, EAL,"user %s not found, aborting.",
++ user_search);
++ e = -1;
++ goto release;
++ }
++ } else {
++ /* User name is not specified, use current user. */
++ while ((e = getpwuid_r(getuid(), &pwd, buf, bufsize, &res)) == ERANGE) {
++ if (!enlarge_buffer(&buf, &bufsize)) {
++ break;
++ }
++ }
++
++ if (e != 0) {
++ RTE_LOG(ERR, EAL,"Failed to retrive current user's uid "
++ "(%s), aborting.", strerror(e));
++ goto release;
++ }
++ user_search = strdup(pwd.pw_name);
++ }
++
++ if (uid)
++ *uid = pwd.pw_uid;
++
++ free(buf);
++ buf = NULL;
++
++ if (pos) {
++ char *grpstr = pos + 1;
++ grpstr += strspn(grpstr, " \t\r\n");
++
++ if (*grpstr) {
++ struct group grp, *res;
++
++ bufsize = 4096;
++ buf = malloc(bufsize);
++ while ((e = getgrnam_r(grpstr, &grp, buf, bufsize, &res))
++ == ERANGE) {
++ if (!enlarge_buffer(&buf, &bufsize)) {
++ break;
++ }
++ }
++
++ if (e) {
++ RTE_LOG(ERR, EAL,"Failed to get group entry for %s, "
++ "(%s), aborting.", grpstr,
++ strerror(e));
++ goto release;
++ }
++ if (res == NULL) {
++ RTE_LOG(ERR, EAL,"Group %s not found, aborting.",
++ grpstr);
++ e = -1;
++ goto release;
++ }
++
++ if (gid)
++ *gid = grp.gr_gid;
++ }
++ }
++
++ release:
++ free(buf);
++ free(user_search);
++ return e;
++}
++
++static void
++vhost_set_permissions(const char *vhost_sock_location)
++{
++ unsigned long int mode = strtoul(internal_config.vhost_sock_perm, NULL, 0);
++ int err = chmod(vhost_sock_location, (mode_t)mode);
++ if (err) {
++ RTE_LOG(ERR, EAL,"vhost-user socket cannot set"
++ " permissions to %s (%s).\n",
++ internal_config.vhost_sock_perm, strerror(err));
++ return;
++ }
++ RTE_LOG(INFO, EAL,"Socket %s changed permissions"
++ " to %s\n", vhost_sock_location,
++ internal_config.vhost_sock_perm);
++}
++
++static void
++vhost_set_ownership(const char *vhost_sock_location)
++{
++ uid_t vhuid=0;
++ gid_t vhgid=0;
++
++ if (get_owners_from_str(internal_config.vhost_sock_owner, &vhuid, &vhgid)) {
++ RTE_LOG(ERR, EAL,"vhost-user socket unable to get"
++ " specified user/group: %s\n",
++ internal_config.vhost_sock_owner);
++ return;
++ }
++
++ int err = chown(vhost_sock_location, vhuid, vhgid);
++ if (err) {
++ RTE_LOG(ERR, EAL,"vhost-user socket unable to set"
++ " ownership to %s (%s).\n",
++ internal_config.vhost_sock_owner, strerror(err));
++ return;
++ }
++
++ RTE_LOG(INFO, EAL,"Socket %s changed ownership"
++ " to %s.\n", vhost_sock_location,
++ internal_config.vhost_sock_owner);
++}
++
++void
++rte_eal_set_socket_permissions(const char *path)
++{
++ if (internal_config.vhost_sock_perm) {
++ vhost_set_permissions(path);
++ }
++
++ if (internal_config.vhost_sock_owner) {
++ vhost_set_ownership(path);
++ }
++}
+Index: dpdk/lib/librte_eal/common/include/rte_eal.h
+===================================================================
+--- dpdk.orig/lib/librte_eal/common/include/rte_eal.h
++++ dpdk/lib/librte_eal/common/include/rte_eal.h
+@@ -252,6 +252,11 @@ static inline int rte_gettid(void)
+ return RTE_PER_LCORE(_thread_id);
+ }
+
++/**
++ * Set owner/permissions on sockets if requested on EAL commandline
++ */
++void rte_eal_set_socket_permissions(const char *);
++
+ #ifdef __cplusplus
+ }
+ #endif
+Index: dpdk/doc/guides/testpmd_app_ug/run_app.rst
+===================================================================
+--- dpdk.orig/doc/guides/testpmd_app_ug/run_app.rst
++++ dpdk/doc/guides/testpmd_app_ug/run_app.rst
+@@ -156,6 +156,25 @@ See the DPDK Getting Started Guides for
+
+ Use malloc instead of hugetlbfs.
+
++* ``--vhost-owner``
++
++ When creating vhost_user sockets change owner and group to the specified value.
++ This can be given as ``user:group``, but also only ``user`` or ``:group`` are supported.
++
++ Examples::
++
++ --vhost-owner 'libvirt-qemu:kvm'
++ --vhost-owner 'libvirt-qemu'
++ --vhost-owner ':kvm'
++
++* ``--vhost-perm``
++
++ When creating vhost_user sockets set them up with these permissions.
++
++ For example::
++
++ --vhost-perm '0664'
++
+
+ Testpmd Command-line Options
+ ----------------------------
+Index: dpdk/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+===================================================================
+--- dpdk.orig/lib/librte_eal/linuxapp/eal/rte_eal_version.map
++++ dpdk/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+@@ -138,6 +138,7 @@ DPDK_2.2 {
+ rte_keepalive_mark_alive;
+ rte_keepalive_register_core;
+ rte_xen_dom0_supported;
++ rte_eal_set_socket_permissions;
+
+ } DPDK_2.1;
+
diff --git a/debian/patches/ubuntu-fix-xenvirt-support-dynamic-page-size.patch b/debian/patches/ubuntu-fix-xenvirt-support-dynamic-page-size.patch
new file mode 100644
index 00000000..ed6fb5d0
--- /dev/null
+++ b/debian/patches/ubuntu-fix-xenvirt-support-dynamic-page-size.patch
@@ -0,0 +1,32 @@
+Author: Ricardo Salveti <ricardo.salveti@linaro.org>
+Last-Update: 2016-04-17
+Fowarded: yes
+Description: xenvirt: support dynamic page size
+
+Fix build failure since PAGE_SIZE is not defined on ARM (multiple values
+are possible, so it needs to dynamically get the page size used).
+
+http://dpdk.org/ml/archives/dev/2016-April/037586.html
+
+Signed-off-by: Ricardo Salveti <ricardo.salveti@linaro.org>
+---
+ drivers/net/xenvirt/rte_eth_xenvirt.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/xenvirt/rte_eth_xenvirt.c b/drivers/net/xenvirt/rte_eth_xenvirt.c
+index b9638d9..afc0193 100644
+--- a/drivers/net/xenvirt/rte_eth_xenvirt.c
++++ b/drivers/net/xenvirt/rte_eth_xenvirt.c
+@@ -39,6 +39,9 @@
+ #include <sys/mman.h>
+ #include <errno.h>
+ #include <sys/user.h>
++#ifndef PAGE_SIZE
++#define PAGE_SIZE sysconf(_SC_PAGE_SIZE)
++#endif
+ #include <linux/binfmts.h>
+ #include <xen/xen-compat.h>
+ #if __XEN_LATEST_INTERFACE_VERSION__ < 0x00040200
+--
+2.7.4
+