vpp-swan: Add plugin for vpp-swan

Added plugin vpp-swan is a plugin that helps offloading
Strongswan IPsec ESP process from Linux Kernel to VPP.

Type: feature
Signed-off-by: Gabriel Oginski <gabrielx.oginski@intel.com>
Change-Id: Iec77945892453fac1890d3c49d7d86fc6b09c893
This commit is contained in:
Gabriel Oginski
2022-06-29 12:54:30 +00:00
committed by Fan Zhang
parent cf9144e65f
commit 4e88e041ad
13 changed files with 3713 additions and 0 deletions

View File

@ -817,6 +817,12 @@ I: rpm-packaging
M: Laszlo Kiraly <laszlo.kiraly@est.tech>
F: src/extras/rpm/opensuse
VPP StrongSwan Daemon
I: vpp-swan
M: Fan Zhang <roy.fan.zhang@intel.com>
M: Gabriel Oginski <gabrielx.oginski@intel.com>
F: extras/strongswan/vpp_sswan
THE REST
I: misc
M: vpp-dev Mailing List <vpp-dev@fd.io>

View File

@ -0,0 +1,108 @@
# the directory to the strongSwan sources
SWANDIR=${CURDIR}/../../../build-root/build-vpp-native/external/sswan
# location of config.h
CONFIGH=$(SWANDIR)/config.h
# default install prefix: /usr/local or /usr
PREFIX=/usr
# location of the installed strongSwan libraries
SWANLIBS=$(PREFIX)/lib/ipsec/
# location of the strongSwan plugins
SWANPLUGINS=$(PREFIX)/lib/ipsec/plugins
# location of the strongSwan archive
SWANARCHIVE=${CURDIR}/../../../build/external/downloads
# default install configuration files:
PREFIX_SYS_CONF=/etc
# target location of the plugin config snippet: $(PREFIX)/etc/strongswan.d/charon/ or /etc/strongswan.d/charon/
PLUGINCONF=$(PREFIX_SYS_CONF)/strongswan.d/charon/
# location of the VPP libraries
VPPLIBS=$(CURDIR)/../../../build-root/install-vpp-native/vpp/lib/x86_64-linux-gnu
# the directory to the VPP sources
VPPDIR=../../../build-root/install-vpp-native/vpp/include
TARGET=libstrongswan-kernel-vpp.so
# tested only with 5.9.5 and 5.9.6 version of strongSwan
VERSION_SSWAN=5.9.6
CFLAGS=-O2 -g -Wall -Wextra -fpic
CFLAGS_I=-include $(CONFIGH) \
-I$(SWANDIR)/src/libstrongswan \
-I$(SWANDIR)/src/libcharon
LDFLAGS= -lvppinfra \
-lvlibmemoryclient \
-lvppapiclient \
-lsvm \
-lvlib
VERSION_VPP=$(shell (dpkg -s vpp | grep Version) | grep -Po '(?<=Version: )\d\d.\d\d')
# check if VPP is installed
ifneq ($(shell test "$(shell ldconfig -p | grep vppinfra.so | awk 'NR==1{print $$1;}')" && echo "yes"), yes)
# check if VPPDIR exists
ifeq ($(shell test -d $(VPPDIR) && echo "yes"), yes)
CFLAGS_I += -I$(VPPDIR)
endif
# check if VPPLIBS exists
ifeq ($(shell test -d $(VPPLIBS) && echo "yes"), yes)
LDFLAGS += -L$(VPPLIBS)
LDFLAGS += -Wl,-rpath=$(VPPLIBS)
endif
endif
SOURCES=$(wildcard *.c)
OBJECTS=$(SOURCES:.c=.o)
all: pull-swan $(TARGET)
pull-swan:
@if [ -d "${SWANDIR}" ]; then \
rm -rf ${SWANDIR} ; \
fi
@if ! [ -f "${SWANARCHIVE}/strongswan-${VERSION_SSWAN}.tar.gz" ]; then \
curl -o ${SWANARCHIVE}/strongswan-${VERSION_SSWAN}.tar.gz -LO https://github.com/strongswan/strongswan/archive/${VERSION_SSWAN}.tar.gz; \
fi
@if ! [ -d "${CURDIR}/../../../build-root/build-vpp-native/external/" ]; then \
mkdir ${CURDIR}/../../../build-root/build-vpp-native/external; \
fi
tar -zxof ${SWANARCHIVE}/strongswan-${VERSION_SSWAN}.tar.gz -C ${CURDIR}/../../../build-root/build-vpp-native/external/
mv ${CURDIR}/../../../build-root/build-vpp-native/external/strongswan-${VERSION_SSWAN} ${SWANDIR}
cd ${SWANDIR} && ./autogen.sh
cd ${SWANDIR} && ./configure --prefix=${PREFIX} --sysconfdir=${PREFIX_SYS_CONF} --enable-libipsec --enable-systemd --enable-swanctl --disable-gmp --enable-openssl
cd ${SWANDIR} && make -j$(nproc)
# cd ${SWANDIR} && sudo make install
# check if VPP is installed
ifneq ($(shell test "$(shell ldconfig -p | grep vppinfra.so | awk 'NR==1{print $$1;}')" && echo "yes"), yes)
$(info INFO: Not found installed VPP - checking if locally VPP exists)
# check if VPPDIR exists
ifneq ($(shell test -d $(VPPDIR) && echo "yes"), yes)
$(error ERROR: Not found installed VPP and locally VPP - please install or build)
else
# check if VPPLIBS exists
ifneq ($(shell test -d $(VPPLIBS) && echo "yes"), yes)
$(error ERROR: directory $(VPPLIBS) - doesn't exists, please compile VPP before build this)
else
$(info INFO: Found locally VPP)
endif
endif
else
$(info INFO: Found installed VPP in version: $(VERSION_VPP))
endif
$(TARGET): $(OBJECTS)
gcc $(CFLAGS) -shared -DPIC $(OBJECTS) $(LDFLAGS) -Wl,-soname -Wl,$(TARGET) -o $@
cp $(TARGET) ${SWANDIR}
%.o: %.c
gcc $(CFLAGS) $(CFLAGS_I) -c $< -o $@ $(LDFLAGS)
install:
cp $(TARGET) $(SWANPLUGINS)/$(TARGET)
cp kernel-vpp.conf $(PLUGINCONF)
clean:
rm -f *.so *.o
.PHONY: clean install all

View File

@ -0,0 +1,128 @@
.. _vpp_sswan_doc:
VPP-SSWAN
=======================
``VPP-SSWAN`` is a StrongSwan plugin that helps offloading Strongswan IPsec ESP
process from Linux Kernel to ``VPP``.
The kernel-vpp plugin is an interface to the IPsec and networking backend for
`VPP <https://wiki.fd.io/view/VPP>`__ platform using the
`VPP C API <https://wiki.fd.io/view/VPP/How_To_Use_The_C_API>`__.
It provides address and routing lookup functionality and installs routes for
IPsec traffic.
It installs and maintains Security Associations and Policies to the
`VPP IPsec <https://wiki.fd.io/view/VPP/IPSec_and_IKEv2#IPSec>`__.
Prerequisites
-------------
``VPP`` in release mode should be built before compiling ``vpp-swan plugin``.
The dependencies of ``StrongSwan`` should be installed before building
``VPP-SSWAN``. In addition ``libsystemd-dev`` should be installed.
Build VPP Strongswan Plugin
-------------
The following list of things will be done to build ``vpp-swan plugin``:
- download strongswan source code to:
``path/to/vpp/build/external/downloads``
- unzip source code strongswan to:
``path/to/vpp/build-root/build-vpp-native/external/sswan``
- check if you have installed packages: ``libsystemd-dev`` on your OS
- configure strongswan by:
``./configure --prefix=/usr --sysconfdir=/etc --enable-libipsec
--enable-systemd --enable-swanctl --disable-gmp --enable-openssl``
- compile strongswan in:
``path/to/vpp/build-root/build-vpp-native/external/sswan``
- compile ``vpp-swan plugin`` by:
::
./make all
- if everything it ok, copy the compiled ``vpp-swan plugin`` to:
``/usr/lib/ipsec/plugins``
Build/install Strongswan
-------------
It is recommended to use ``Strongswan`` in version ``5.9.6`` or ``5.9.5``
installed from this script, due to configuration Strongswan that is required.
Only version ``5.9.5`` and ``5.9.6`` was tested with this plugin.
To install the built Strongswan, please execute the following command:
::
path/to/vpp/build-root/build-vpp-native/external/sswan/sudo make install
Insert plugin in runtime mode
-------------
After builded this plugin and also installed Strongswan you can loaded plugin
into Strongswan directory by:
::
./make install
Or you can do manually copy ``libstrongswan-kernel-vpp.so`` into:
``/usr/lib/ipsec/plugins`` and also ``kernel-vpp.conf`` into: ``/etc/strongswan.d/charon/``
And also you should restart Strongswan by:
::
systemctl restart strongswan.service
Configuration Strongswan
-------------
In ``swanctl.conf`` file you can find example configuration to initialize
connections between two endpoints.
Copy this file into: ``/etc/swanctl/conf.d/swanctl.conf``
Configuration VPP
-------------
In your ``startup.conf`` add these following commands:
::
plugins {
plugin linux_cp_plugin.so { enable }
plugin ikev2_plugin.so { disable }
}
linux-cp {
lcp-sync
}
To enable ``CP Plugin`` and disable ``IKEv2`` plugin.
These following commands executed in ``VPP``:
::
lcp create eth2 host-if eth2
set interface state eth2 up
set interface ip address eth2 192.168.0.2/24
set int state eth1 up
set int ip addr eth1 192.168.200.1/24
To create interface by ``CP Plugin`` and also setup two ethernet interfaces.
Misc
-------------
This plugin is based on:
`https://github.com/matfabia/strongswan
<https://github.com/matfabia/strongswan>`__
Author: Matus Fabian <matfabia@cisco.com>

View File

@ -0,0 +1,7 @@
kernel-vpp {
# Whether to load the plugin. Can also be an integer to increase the
# priority of this plugin.
load = yes
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,41 @@
#ifndef KERNEL_VPP_IPSEC_H_
#define KERNEL_VPP_IPSEC_H_
/*
* Copyright (c) 2022 Intel and/or its affiliates.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <kernel/kernel_ipsec.h>
typedef struct kernel_vpp_ipsec_t kernel_vpp_ipsec_t;
/**
* Implementation of the kernel ipsec interface using Netlink.
*/
struct kernel_vpp_ipsec_t
{
/**
* Implements kernel_ipsec_t interface
*/
kernel_ipsec_t interface;
};
/**
* Create a vpp kernel ipsec interface instance.
*
* @return kernel_vpp_ipsec_t instance
*/
kernel_vpp_ipsec_t *kernel_vpp_ipsec_create ();
#endif /** KERNEL_VPP_IPSEC_H_ @}*/

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,41 @@
#ifndef KERNEL_VPP_NET_H_
#define KERNEL_VPP_NET_H_
/*
* Copyright (c) 2022 Intel and/or its affiliates.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <kernel/kernel_net.h>
typedef struct kernel_vpp_net_t kernel_vpp_net_t;
/**
* Implementation of the kernel network interface using Netlink.
*/
struct kernel_vpp_net_t
{
/**
* Implements kernel_net_t interface
*/
kernel_net_t interface;
};
/**
* Create a vpp kernel network interface instance.
*
* @return kernel_vpp_net_t instance
*/
kernel_vpp_net_t *kernel_vpp_net_create ();
#endif /** KERNEL_VPP_NET_H_ @}*/

View File

@ -0,0 +1,103 @@
/*
* Copyright (c) 2022 Intel and/or its affiliates.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <utils/debug.h>
#include <vlibapi/api.h>
#include <vlibmemory/api.h>
#define vl_typedefs
#define vl_endianfun
/* Include the (first) vlib-api API definition layer */
#include <vlibmemory/vl_memory_api_h.h>
/* Include the current layer (third) vpp API definition layer */
#include <vpp/api/vpe_types.api.h>
#include <vpp/api/vpe.api.h>
#undef vl_typedefs
#undef vl_endianfun
#include "kernel_vpp_plugin.h"
#include "kernel_vpp_shared.h"
#include "kernel_vpp_ipsec.h"
#include "kernel_vpp_net.h"
typedef struct private_kernel_vpp_plugin_t private_kernel_vpp_plugin_t;
/**
* private data of kernel vpp plugin
*/
struct private_kernel_vpp_plugin_t
{
/**
* implements plugin interface
*/
kernel_vpp_plugin_t public;
vac_t *vac;
};
METHOD (plugin_t, get_name, char *, private_kernel_vpp_plugin_t *this)
{
return "kernel-vpp";
}
METHOD (plugin_t, get_features, int, private_kernel_vpp_plugin_t *this,
plugin_feature_t *features[])
{
static plugin_feature_t f[] = {
PLUGIN_CALLBACK (kernel_ipsec_register, kernel_vpp_ipsec_create),
PLUGIN_PROVIDE (CUSTOM, "kernel-ipsec"),
PLUGIN_CALLBACK (kernel_net_register, kernel_vpp_net_create),
PLUGIN_PROVIDE (CUSTOM, "kernel-net"),
};
*features = f;
return countof (f);
}
METHOD (plugin_t, destroy, void, private_kernel_vpp_plugin_t *this)
{
if (this->vac)
{
lib->set (lib, "kernel-vpp-vac", NULL);
this->vac->destroy (this->vac);
}
free (this);
}
plugin_t *
kernel_vpp_plugin_create ()
{
private_kernel_vpp_plugin_t *this;
INIT(this,
.public = {
.plugin = {
.get_name = _get_name,
.get_features = _get_features,
.destroy = _destroy,
},
},
);
this->vac = vac_create ("strongswan");
if (!this->vac)
{
DBG1 (DBG_KNL, "vac_create failed");
destroy (this);
return NULL;
}
lib->set (lib, "kernel-vpp-vac", this->vac);
return &this->public.plugin;
}

View File

@ -0,0 +1,34 @@
#ifndef KERNEL_VPP_PLUGIN_H_
#define KERNEL_VPP_PLUGIN_H_
/*
* Copyright (c) 2022 Intel and/or its affiliates.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <plugins/plugin.h>
typedef struct kernel_vpp_plugin_t kernel_vpp_plugin_t;
/**
* vpp kernel interface plugin
*/
struct kernel_vpp_plugin_t
{
/**
* implements plugin interface
*/
plugin_t plugin;
};
#endif /** KERNEL_VPP_PLUGIN_H_ @}*/

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,85 @@
#ifndef KERNEL_VPP_SHARED_H_
#define KERNEL_VPP_SHARED_H_
/*
* Copyright (c) 2022 Intel and/or its affiliates.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
typedef struct vac_t vac_t;
/**
* Callback function invoked for received event messages.
*
* @param data associated event message, destroyed by VPP API wrapper
* @param data_len length of the event message
* @param ctx user data, as passed to register_event
*/
typedef void (*event_cb_t) (char *data, int data_len, void *ctx);
/**
* Wrapper around VPP binary API client.
*/
struct vac_t
{
/**
* Destroy the VPP API client.
*/
void (*destroy) (vac_t *this);
/**
* Send VPP API message and wait for a reply
*
* @param in VPP API message to send
* @param in_len length of the message to send
* @param out received VPP API message
* @param out_len length of the received message
*/
status_t (*send) (vac_t *this, char *in, int in_len, char **out,
int *out_len);
/**
* Send VPP API dump message and wait for a reply.
*
* @param in VPP API message to send
* @param in_len length of the message to send
* @param out received VPP API message
* @param out_len length of the received message
*/
status_t (*send_dump) (vac_t *this, char *in, int in_len, char **out,
int *out_len);
/**
* Register for VPP API event of a given kind.
*
* @param in VPP API event message to register
* @param in_len length of the event message to register
* @param cb callback function to register
* @param event_id event ID
* @param ctx user data passed to callback invocations
*/
status_t (*register_event) (vac_t *this, char *in, int in_len, event_cb_t cb,
uint16_t event_id, void *ctx);
};
extern vac_t *vac;
/**
* Establishing a binary API connection to VPP.
*
* @param name client name
* @return vac_t instance
*/
vac_t *vac_create (char *name);
#endif /* KERNEL_VPP_SHARED_H_ */

View File

@ -0,0 +1,35 @@
connections {
net-net {
local_addrs = 192.168.0.2
remote_addrs = 192.168.0.1
local {
auth = psk
id = sun.strongswan.org
}
remote {
auth = psk
id = moon.strongswan.org
}
children {
net-net {
local_ts = 192.168.200.0/24
remote_ts = 192.168.100.0/24
esp_proposals = aes128-sha1-modp2048
rekey_time = 240m
}
}
version = 2
mobike = yes
encap = no # NAT-T if needed
proposals = aes128-sha256-x25519
}
}
secrets {
ike-net-net {
id = moon.strongswan.org
secret = simplepsk
}
}
# Include config snippets
include conf.d/*.conf