diff --git a/extras/hs-test/infra/vppinstance.go b/extras/hs-test/infra/vppinstance.go
new file mode 100644
index 0000000..5164a54
--- /dev/null
+++ b/extras/hs-test/infra/vppinstance.go
@@ -0,0 +1,500 @@
+package hst
+
+import (
+	"context"
+	"fmt"
+	"go.fd.io/govpp/binapi/ethernet_types"
+	"io"
+	"net"
+	"os"
+	"os/exec"
+	"os/signal"
+	"strconv"
+	"strings"
+	"syscall"
+	"time"
+
+	"github.com/edwarnicke/exechelper"
+	. "github.com/onsi/ginkgo/v2"
+	"github.com/sirupsen/logrus"
+
+	"go.fd.io/govpp"
+	"go.fd.io/govpp/api"
+	"go.fd.io/govpp/binapi/af_packet"
+	interfaces "go.fd.io/govpp/binapi/interface"
+	"go.fd.io/govpp/binapi/interface_types"
+	"go.fd.io/govpp/binapi/session"
+	"go.fd.io/govpp/binapi/tapv2"
+	"go.fd.io/govpp/core"
+)
+
+const vppConfigTemplate = `unix {
+  nodaemon
+  log %[1]s%[4]s
+  full-coredump
+  cli-listen %[1]s%[2]s
+  runtime-dir %[1]s/var/run
+  gid vpp
+}
+
+api-trace {
+  on
+}
+
+api-segment {
+  gid vpp
+}
+
+socksvr {
+  socket-name %[1]s%[3]s
+}
+
+statseg {
+  socket-name %[1]s/var/run/vpp/stats.sock
+}
+
+plugins {
+  plugin default { disable }
+
+  plugin unittest_plugin.so { enable }
+  plugin quic_plugin.so { enable }
+  plugin af_packet_plugin.so { enable }
+  plugin hs_apps_plugin.so { enable }
+  plugin http_plugin.so { enable }
+  plugin http_static_plugin.so { enable }
+  plugin prom_plugin.so { enable }
+  plugin tlsopenssl_plugin.so { enable }
+  plugin ping_plugin.so { enable }
+  plugin nsim_plugin.so { enable }
+  plugin mactime_plugin.so { enable }
+}
+
+logging {
+  default-log-level debug
+  default-syslog-log-level debug
+}
+
+`
+
+const (
+	defaultCliSocketFilePath = "/var/run/vpp/cli.sock"
+	defaultApiSocketFilePath = "/var/run/vpp/api.sock"
+	defaultLogFilePath       = "/var/log/vpp/vpp.log"
+)
+
+type VppInstance struct {
+	Container        *Container
+	AdditionalConfig []Stanza
+	Connection       *core.Connection
+	ApiStream        api.Stream
+	Cpus             []int
+}
+
+func (vpp *VppInstance) getSuite() *HstSuite {
+	return vpp.Container.Suite
+}
+
+func (vpp *VppInstance) getCliSocket() string {
+	return fmt.Sprintf("%s%s", vpp.Container.GetContainerWorkDir(), defaultCliSocketFilePath)
+}
+
+func (vpp *VppInstance) getRunDir() string {
+	return vpp.Container.GetContainerWorkDir() + "/var/run/vpp"
+}
+
+func (vpp *VppInstance) getLogDir() string {
+	return vpp.Container.GetContainerWorkDir() + "/var/log/vpp"
+}
+
+func (vpp *VppInstance) getEtcDir() string {
+	return vpp.Container.GetContainerWorkDir() + "/etc/vpp"
+}
+
+func (vpp *VppInstance) Start() error {
+	maxReconnectAttempts := 3
+	// Replace default logger in govpp with our own
+	govppLogger := logrus.New()
+	govppLogger.SetOutput(io.MultiWriter(vpp.getSuite().Logger.Writer(), GinkgoWriter))
+	core.SetLogger(govppLogger)
+	// Create folders
+	containerWorkDir := vpp.Container.GetContainerWorkDir()
+
+	vpp.Container.Exec("mkdir --mode=0700 -p " + vpp.getRunDir())
+	vpp.Container.Exec("mkdir --mode=0700 -p " + vpp.getLogDir())
+	vpp.Container.Exec("mkdir --mode=0700 -p " + vpp.getEtcDir())
+
+	// Create startup.conf inside the container
+	configContent := fmt.Sprintf(
+		vppConfigTemplate,
+		containerWorkDir,
+		defaultCliSocketFilePath,
+		defaultApiSocketFilePath,
+		defaultLogFilePath,
+	)
+	configContent += vpp.generateCpuConfig()
+	for _, c := range vpp.AdditionalConfig {
+		configContent += c.ToString()
+	}
+	startupFileName := vpp.getEtcDir() + "/startup.conf"
+	vpp.Container.CreateFile(startupFileName, configContent)
+
+	// create wrapper script for vppctl with proper CLI socket path
+	cliContent := "#!/usr/bin/bash\nvppctl -s " + vpp.getRunDir() + "/cli.sock"
+	vppcliFileName := "/usr/bin/vppcli"
+	vpp.Container.CreateFile(vppcliFileName, cliContent)
+	vpp.Container.Exec("chmod 0755 " + vppcliFileName)
+
+	vpp.getSuite().Log("starting vpp")
+	if *IsVppDebug {
+		// default = 3; VPP will timeout while debugging if there are not enough attempts
+		maxReconnectAttempts = 5000
+		sig := make(chan os.Signal, 1)
+		signal.Notify(sig, syscall.SIGQUIT)
+		cont := make(chan bool, 1)
+		go func() {
+			<-sig
+			cont <- true
+		}()
+
+		vpp.Container.ExecServer("su -c \"vpp -c " + startupFileName + " &> /proc/1/fd/1\"")
+		fmt.Println("run following command in different terminal:")
+		fmt.Println("docker exec -it " + vpp.Container.Name + " gdb -ex \"attach $(docker exec " + vpp.Container.Name + " pidof vpp)\"")
+		fmt.Println("Afterwards press CTRL+\\ to continue")
+		<-cont
+		fmt.Println("continuing...")
+	} else {
+		// Start VPP
+		vpp.Container.ExecServer("su -c \"vpp -c " + startupFileName + " &> /proc/1/fd/1\"")
+	}
+
+	vpp.getSuite().Log("connecting to vpp")
+	// Connect to VPP and store the connection
+	sockAddress := vpp.Container.GetHostWorkDir() + defaultApiSocketFilePath
+	conn, connEv, err := govpp.AsyncConnect(
+		sockAddress,
+		maxReconnectAttempts,
+		core.DefaultReconnectInterval)
+	if err != nil {
+		vpp.getSuite().Log("async connect error: " + fmt.Sprint(err))
+		return err
+	}
+	vpp.Connection = conn
+
+	// ... wait for Connected event
+	e := <-connEv
+	if e.State != core.Connected {
+		vpp.getSuite().Log("connecting to VPP failed: " + fmt.Sprint(e.Error))
+	}
+
+	ch, err := conn.NewStream(
+		context.Background(),
+		core.WithRequestSize(50),
+		core.WithReplySize(50),
+		core.WithReplyTimeout(time.Second*5))
+	if err != nil {
+		vpp.getSuite().Log("creating stream failed: " + fmt.Sprint(err))
+		return err
+	}
+	vpp.ApiStream = ch
+
+	return nil
+}
+
+func (vpp *VppInstance) Vppctl(command string, arguments ...any) string {
+	vppCliCommand := fmt.Sprintf(command, arguments...)
+	containerExecCommand := fmt.Sprintf("docker exec --detach=false %[1]s vppctl -s %[2]s %[3]s",
+		vpp.Container.Name, vpp.getCliSocket(), vppCliCommand)
+	vpp.getSuite().Log(containerExecCommand)
+	output, err := exechelper.CombinedOutput(containerExecCommand)
+	vpp.getSuite().AssertNil(err)
+
+	return string(output)
+}
+
+func (vpp *VppInstance) GetSessionStat(stat string) int {
+	o := vpp.Vppctl("show session stats")
+	vpp.getSuite().Log(o)
+	for _, line := range strings.Split(o, "\n") {
+		if strings.Contains(line, stat) {
+			tokens := strings.Split(strings.TrimSpace(line), " ")
+			val, err := strconv.Atoi(tokens[0])
+			if err != nil {
+				Fail("failed to parse stat value %s" + fmt.Sprint(err))
+				return 0
+			}
+			return val
+		}
+	}
+	return 0
+}
+
+func (vpp *VppInstance) WaitForApp(appName string, timeout int) {
+	vpp.getSuite().Log("waiting for app " + appName)
+	for i := 0; i < timeout; i++ {
+		o := vpp.Vppctl("show app")
+		if strings.Contains(o, appName) {
+			return
+		}
+		time.Sleep(1 * time.Second)
+	}
+	vpp.getSuite().AssertNil(1, "Timeout while waiting for app '%s'", appName)
+}
+
+func (vpp *VppInstance) createAfPacket(
+	veth *NetInterface,
+) (interface_types.InterfaceIndex, error) {
+	createReq := &af_packet.AfPacketCreateV3{
+		Mode:            1,
+		UseRandomHwAddr: true,
+		HostIfName:      veth.Name(),
+		Flags:           af_packet.AfPacketFlags(11),
+	}
+	if veth.HwAddress != (MacAddress{}) {
+		createReq.UseRandomHwAddr = false
+		createReq.HwAddr = veth.HwAddress
+	}
+
+	vpp.getSuite().Log("create af-packet interface " + veth.Name())
+	if err := vpp.ApiStream.SendMsg(createReq); err != nil {
+		vpp.getSuite().HstFail()
+		return 0, err
+	}
+	replymsg, err := vpp.ApiStream.RecvMsg()
+	if err != nil {
+		return 0, err
+	}
+	reply := replymsg.(*af_packet.AfPacketCreateV3Reply)
+	err = api.RetvalToVPPApiError(reply.Retval)
+	if err != nil {
+		return 0, err
+	}
+
+	veth.Index = reply.SwIfIndex
+
+	// Set to up
+	upReq := &interfaces.SwInterfaceSetFlags{
+		SwIfIndex: veth.Index,
+		Flags:     interface_types.IF_STATUS_API_FLAG_ADMIN_UP,
+	}
+
+	vpp.getSuite().Log("set af-packet interface " + veth.Name() + " up")
+	if err := vpp.ApiStream.SendMsg(upReq); err != nil {
+		return 0, err
+	}
+	replymsg, err = vpp.ApiStream.RecvMsg()
+	if err != nil {
+		return 0, err
+	}
+	reply2 := replymsg.(*interfaces.SwInterfaceSetFlagsReply)
+	if err = api.RetvalToVPPApiError(reply2.Retval); err != nil {
+		return 0, err
+	}
+
+	// Add address
+	if veth.AddressWithPrefix() == (AddressWithPrefix{}) {
+		var err error
+		var ip4Address string
+		if ip4Address, err = veth.Ip4AddrAllocator.NewIp4InterfaceAddress(veth.Peer.NetworkNumber); err == nil {
+			veth.Ip4Address = ip4Address
+		} else {
+			return 0, err
+		}
+	}
+	addressReq := &interfaces.SwInterfaceAddDelAddress{
+		IsAdd:     true,
+		SwIfIndex: veth.Index,
+		Prefix:    veth.AddressWithPrefix(),
+	}
+
+	vpp.getSuite().Log("af-packet interface " + veth.Name() + " add address " + veth.Ip4Address)
+	if err := vpp.ApiStream.SendMsg(addressReq); err != nil {
+		return 0, err
+	}
+	replymsg, err = vpp.ApiStream.RecvMsg()
+	if err != nil {
+		return 0, err
+	}
+	reply3 := replymsg.(*interfaces.SwInterfaceAddDelAddressReply)
+	err = api.RetvalToVPPApiError(reply3.Retval)
+	if err != nil {
+		return 0, err
+	}
+
+	return veth.Index, nil
+}
+
+func (vpp *VppInstance) addAppNamespace(
+	secret uint64,
+	ifx interface_types.InterfaceIndex,
+	namespaceId string,
+) error {
+	req := &session.AppNamespaceAddDelV4{
+		IsAdd:       true,
+		Secret:      secret,
+		SwIfIndex:   ifx,
+		NamespaceID: namespaceId,
+		SockName:    defaultApiSocketFilePath,
+	}
+
+	vpp.getSuite().Log("add app namespace " + namespaceId)
+	if err := vpp.ApiStream.SendMsg(req); err != nil {
+		return err
+	}
+	replymsg, err := vpp.ApiStream.RecvMsg()
+	if err != nil {
+		return err
+	}
+	reply := replymsg.(*session.AppNamespaceAddDelV4Reply)
+	if err = api.RetvalToVPPApiError(reply.Retval); err != nil {
+		return err
+	}
+
+	sessionReq := &session.SessionEnableDisable{
+		IsEnable: true,
+	}
+
+	vpp.getSuite().Log("enable app namespace " + namespaceId)
+	if err := vpp.ApiStream.SendMsg(sessionReq); err != nil {
+		return err
+	}
+	replymsg, err = vpp.ApiStream.RecvMsg()
+	if err != nil {
+		return err
+	}
+	reply2 := replymsg.(*session.SessionEnableDisableReply)
+	if err = api.RetvalToVPPApiError(reply2.Retval); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (vpp *VppInstance) createTap(
+	tap *NetInterface,
+	tapId ...uint32,
+) error {
+	var id uint32 = 1
+	if len(tapId) > 0 {
+		id = tapId[0]
+	}
+	createTapReq := &tapv2.TapCreateV3{
+		ID:               id,
+		HostIfNameSet:    true,
+		HostIfName:       tap.Name(),
+		HostIP4PrefixSet: true,
+		HostIP4Prefix:    tap.Ip4AddressWithPrefix(),
+	}
+
+	vpp.getSuite().Log("create tap interface " + tap.Name())
+	// Create tap interface
+	if err := vpp.ApiStream.SendMsg(createTapReq); err != nil {
+		return err
+	}
+	replymsg, err := vpp.ApiStream.RecvMsg()
+	if err != nil {
+		return err
+	}
+	reply := replymsg.(*tapv2.TapCreateV3Reply)
+	if err = api.RetvalToVPPApiError(reply.Retval); err != nil {
+		return err
+	}
+	tap.Peer.Index = reply.SwIfIndex
+
+	// Get name and mac
+	if err := vpp.ApiStream.SendMsg(&interfaces.SwInterfaceDump{
+		SwIfIndex: reply.SwIfIndex,
+	}); err != nil {
+		return err
+	}
+	replymsg, err = vpp.ApiStream.RecvMsg()
+	if err != nil {
+		return err
+	}
+	ifDetails := replymsg.(*interfaces.SwInterfaceDetails)
+	tap.Peer.name = ifDetails.InterfaceName
+	tap.Peer.HwAddress = ifDetails.L2Address
+
+	// Add address
+	addAddressReq := &interfaces.SwInterfaceAddDelAddress{
+		IsAdd:     true,
+		SwIfIndex: reply.SwIfIndex,
+		Prefix:    tap.Peer.AddressWithPrefix(),
+	}
+
+	vpp.getSuite().Log("tap interface " + tap.Name() + " add address " + tap.Peer.Ip4Address)
+	if err := vpp.ApiStream.SendMsg(addAddressReq); err != nil {
+		return err
+	}
+	replymsg, err = vpp.ApiStream.RecvMsg()
+	if err != nil {
+		return err
+	}
+	reply2 := replymsg.(*interfaces.SwInterfaceAddDelAddressReply)
+	if err = api.RetvalToVPPApiError(reply2.Retval); err != nil {
+		return err
+	}
+
+	// Set interface to up
+	upReq := &interfaces.SwInterfaceSetFlags{
+		SwIfIndex: reply.SwIfIndex,
+		Flags:     interface_types.IF_STATUS_API_FLAG_ADMIN_UP,
+	}
+
+	vpp.getSuite().Log("set tap interface " + tap.Name() + " up")
+	if err := vpp.ApiStream.SendMsg(upReq); err != nil {
+		return err
+	}
+	replymsg, err = vpp.ApiStream.RecvMsg()
+	if err != nil {
+		return err
+	}
+	reply3 := replymsg.(*interfaces.SwInterfaceSetFlagsReply)
+	if err = api.RetvalToVPPApiError(reply3.Retval); err != nil {
+		return err
+	}
+
+	// Get host mac
+	netIntf, err := net.InterfaceByName(tap.Name())
+	if err == nil {
+		tap.HwAddress, _ = ethernet_types.ParseMacAddress(netIntf.HardwareAddr.String())
+	}
+
+	return nil
+}
+
+func (vpp *VppInstance) saveLogs() {
+	logTarget := vpp.Container.getLogDirPath() + "vppinstance-" + vpp.Container.Name + ".log"
+	logSource := vpp.Container.GetHostWorkDir() + defaultLogFilePath
+	cmd := exec.Command("cp", logSource, logTarget)
+	vpp.getSuite().Log(cmd.String())
+	cmd.Run()
+}
+
+func (vpp *VppInstance) Disconnect() {
+	vpp.Connection.Disconnect()
+	vpp.ApiStream.Close()
+}
+
+func (vpp *VppInstance) generateCpuConfig() string {
+	var c Stanza
+	var s string
+	if len(vpp.Cpus) < 1 {
+		return ""
+	}
+	c.NewStanza("cpu").
+		Append(fmt.Sprintf("main-core %d", vpp.Cpus[0]))
+	vpp.getSuite().Log(fmt.Sprintf("main-core %d", vpp.Cpus[0]))
+	workers := vpp.Cpus[1:]
+
+	if len(workers) > 0 {
+		for i := 0; i < len(workers); i++ {
+			if i != 0 {
+				s = s + ", "
+			}
+			s = s + fmt.Sprintf("%d", workers[i])
+		}
+		c.Append(fmt.Sprintf("corelist-workers %s", s))
+		vpp.getSuite().Log("corelist-workers " + s)
+	}
+	return c.Close().ToString()
+}
