Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/publish-docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ jobs:
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and push
timeout-minutes: 60
timeout-minutes: 95
uses: docker/build-push-action@v5
with:
context: .
Expand Down
22 changes: 22 additions & 0 deletions docs/deployment/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,28 @@ All command-line arguments and configuration files are already handled by the Do

For development, direct use of dp-service is covered by the [development section](../development/).

## Host machine setup
For dpservice to work properly, host IPv6 address needs to set up on `lo` instead of separately on the NIC ports, this way the address is shared.

This address must be in the form of a network prefix `/64`, i.e. the last 64 bits of the host address must be zero. This way the 64 bit suffix can be used for containers or VMs running on the host.

It is suggested that `<host-prefix>:0000::/65` is used for host itself and `<host-prefix>:8000::/65` is then assigned special role, e.g. `<host-prefix>:f000::/68` for PodIPs, `<host-prefix>:d000::/68` for dpservice, etc.

Dpservice will generate addresses in the range from `<host-prefix>:d000::` to `<host-prefix>:dfff::`.

If meson option `-Denable_address_type=true` is used, addresses are generated based on the usage type:

| Use | Range |
|-|-|
| `<host-prefix>:d000::/80` | unused |
| `<host-prefix>:d001::/80` | NICs |
| `<host-prefix>:d002::/80` | VIPs |
| `<host-prefix>:d003::/80` | NATGateways |
| `<host-prefix>:d004::/80` | LoadBalancers |
| `<host-prefix>:d005::/80` | LoadBalancer targets |
| `<host-prefix>:d006::/80` | Prefixes |
| `<host-prefix>:d0ff::/80` | Virtual services |

## Command-line tools
All tool binaries are designed to be prefixed with `dpservice-` to enable the operator to simply type `dps<TAB>` for list of possible tools.

Expand Down
6 changes: 4 additions & 2 deletions include/dp_ipaddr.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ static_assert(sizeof(rte_be64_t) * 2 == DP_IPV6_ADDR_SIZE, "DP_IPV6_ADDR_SIZE is

#define DP_UNDERLAY_FLAG_EXTERNALLY_GENERATED 0x80
#define DP_UNDERLAY_FLAG_SECONDARY_POOL 0x40
#define DP_UNDERLAY_ADDRESS_TYPE 0xd0

// structure for holding IPv6 addresses
// this way sizeof(dp_ipv6 *) is a meaningful value and passing the pointer only is safe
Expand All @@ -36,7 +37,8 @@ union dp_ipv6 {
} _nat64;
struct __rte_packed {
rte_be64_t prefix;
rte_be16_t kernel;
uint8_t type;
uint8_t subtype;
uint8_t flags;
uint8_t random;
rte_be32_t local;
Expand Down Expand Up @@ -166,7 +168,7 @@ int dp_ipv4_to_str(uint32_t ipv4, char *dest, int dest_len);
int dp_str_to_ipv4(const char *src, uint32_t *dest);
int dp_str_to_ipv6(const char *src, union dp_ipv6 *dest);

void dp_generate_ul_ipv6(union dp_ipv6 *dest);
void dp_generate_ul_ipv6(union dp_ipv6 *dest, uint8_t addr_type);


// structure for holding dual IP addresses
Expand Down
6 changes: 1 addition & 5 deletions include/dp_port.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,11 @@ struct dp_port_async_template {

enum dp_port_async_template_type {
DP_PORT_ASYNC_TEMPLATE_PF_ISOLATION,
#ifdef ENABLE_VIRTSVC
DP_PORT_ASYNC_TEMPLATE_VIRTSVC_ISOLATION,
#endif
DP_PORT_ASYNC_TEMPLATE_COUNT,
};

enum dp_port_async_flow_type {
DP_PORT_ASYNC_FLOW_ISOLATE_IPIP,
DP_PORT_ASYNC_FLOW_ISOLATE_IPV6,
DP_PORT_ASYNC_FLOW_ISOLATE_PREFIX,
DP_PORT_ASYNC_FLOW_COUNT,
};

Expand Down
6 changes: 0 additions & 6 deletions include/dp_virtsvc.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ struct dp_virtsvc {
union dp_ipv6 ul_addr;
struct rte_hash *open_ports;
struct dp_virtsvc_conn connections[DP_VIRTSVC_PORTCOUNT];
struct rte_flow *isolation_rules[DP_MAX_PF_PORTS];
};

struct dp_virtsvc_lookup_entry {
Expand Down Expand Up @@ -105,11 +104,6 @@ void dp_virtsvc_free(void);

size_t dp_virtsvc_get_count(void);

int dp_install_virtsvc_sync_isolation_rules(uint16_t port_id);
uint16_t dp_create_virtsvc_async_isolation_rules(uint16_t port_id,
struct rte_flow_template_table *template_table);
void dp_destroy_virtsvc_async_isolation_rules(uint16_t port_id);

int dp_virtsvc_get_pf_route(struct dp_virtsvc *virtsvc,
uint16_t vf_port_id,
rte_be32_t vf_ip,
Expand Down
8 changes: 4 additions & 4 deletions include/dp_vnf.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ struct dp_grpc_responder;

enum dp_vnf_type {
DP_VNF_TYPE_UNDEFINED,
DP_VNF_TYPE_LB_ALIAS_PFX,
DP_VNF_TYPE_ALIAS_PFX,
DP_VNF_TYPE_LB,
DP_VNF_TYPE_INTERFACE_IP,
DP_VNF_TYPE_VIP,
DP_VNF_TYPE_NAT,
DP_VNF_TYPE_INTERFACE_IP,
DP_VNF_TYPE_LB,
DP_VNF_TYPE_LB_ALIAS_PFX,
DP_VNF_TYPE_ALIAS_PFX,
} __rte_packed; // for 'struct dp_flow' and 'struct flow_key'

struct dp_vnf_prefix {
Expand Down
11 changes: 0 additions & 11 deletions include/rte_flow/dp_rte_async_flow_isolation.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,12 @@
extern "C" {
#endif

#include <stdint.h>
#include <rte_flow.h>
#include "dp_ipaddr.h"
#include "dp_port.h"

int dp_create_pf_async_isolation_templates(struct dp_port *port);

int dp_create_pf_async_isolation_rules(struct dp_port *port);

#ifdef ENABLE_VIRTSVC
int dp_create_virtsvc_async_isolation_templates(struct dp_port *port);

struct rte_flow *dp_create_virtsvc_async_isolation_rule(uint16_t port_id,
struct rte_flow_template_table *template_table,
const union dp_ipv6 *ul_addr);
#endif

#ifdef __cplusplus
}
#endif
Expand Down
15 changes: 15 additions & 0 deletions include/rte_flow/dp_rte_flow_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ static const struct rte_flow_item_ipv6 dp_flow_item_ipv6_dst_mask = {
.hdr.dst_addr.a = "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff",
.hdr.proto = 0xff,
};
static const struct rte_flow_item_ipv6 dp_flow_item_ipv6_dst_pfx68_mask = {
.hdr.dst_addr.a = "\xff\xff\xff\xff\xff\xff\xff\xff\xf0\x00\x00\x00\x00\x00\x00\x00",
};
#ifdef ENABLE_VIRTSVC
static const struct rte_flow_item_ipv6 dp_flow_item_ipv6_dst_only_mask = {
.hdr.dst_addr.a = "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff",
Expand Down Expand Up @@ -201,6 +204,18 @@ void dp_set_ipv6_dst_flow_item(struct rte_flow_item *item,
item->last = NULL;
}

static __rte_always_inline
void dp_set_ipv6_dst_pfx68_flow_item(struct rte_flow_item *item,
struct rte_flow_item_ipv6 *ipv6_spec,
const union dp_ipv6 *dst)
{
dp_set_dst_ipv6(&ipv6_spec->hdr, dst);
item->type = RTE_FLOW_ITEM_TYPE_IPV6;
item->spec = ipv6_spec;
item->mask = &dp_flow_item_ipv6_dst_pfx68_mask;
item->last = NULL;
}

static __rte_always_inline
void dp_set_ipv4_dst_flow_item(struct rte_flow_item *item,
struct rte_flow_item_ipv4 *ipv4_spec,
Expand Down
26 changes: 0 additions & 26 deletions include/rte_flow/dp_rte_flow_init.h

This file was deleted.

19 changes: 19 additions & 0 deletions include/rte_flow/dp_rte_flow_isolation.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// SPDX-FileCopyrightText: 2023 SAP SE or an SAP affiliate company and IronCore contributors
// SPDX-License-Identifier: Apache-2.0

#ifndef __INCLUDE_DP_RTE_FLOW_ISOLATION_H__
#define __INCLUDE_DP_RTE_FLOW_ISOLATION_H__

#ifdef __cplusplus
extern "C" {
#endif

#include <stdint.h>

int dp_install_isolated_mode(uint16_t port_id);

#ifdef __cplusplus
}
#endif

#endif
3 changes: 3 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ endif
if get_option('enable_tests')
add_global_arguments('-DENABLE_PYTEST', language: ['c', 'cpp'])
endif
if get_option('enable_underlay_type')
add_global_arguments('-DENABLE_UNDERLAY_TYPE', language: ['c', 'cpp'])
endif

dpdk_dep = dependency('libdpdk', version: '>=21.11.0')
proto_dep = dependency('protobuf')
Expand Down
2 changes: 2 additions & 0 deletions meson_options.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,5 @@ option('compiler_suggestions', type: 'boolean', value: false, description:
'Show various compiler suggestions (warnings)')
option('build_dpservice_cli', type: 'boolean', value: false, description:
'Enable building of dpservice-cli golang gRPC client')
option('enable_underlay_type', type: 'boolean', value: false, description:
'Generate underlay address with vnf_type field')
11 changes: 9 additions & 2 deletions src/dp_ipaddr.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,19 @@ int dp_ipaddr_to_str(const struct dp_ip_address *addr, char *dest, int dest_len)
}


void dp_generate_ul_ipv6(union dp_ipv6 *dest)
void dp_generate_ul_ipv6(union dp_ipv6 *dest, uint8_t addr_type)
{
static uint32_t ul_counter = 0;

dest->_ul.prefix = dp_conf_get_underlay_ip()->_prefix; // Use the same prefix as the host
dest->_ul.kernel = dest->_ul.flags = 0;
dest->_ul.type = DP_UNDERLAY_ADDRESS_TYPE;
#ifdef ENABLE_UNDERLAY_TYPE
dest->_ul.subtype = addr_type;
#else
(void)addr_type;
dest->_ul.subtype = 0;
#endif
dest->_ul.flags = 0;
#ifdef ENABLE_STATIC_UNDERLAY_IP
dest->_ul.random = 1;
#else
Expand Down
54 changes: 8 additions & 46 deletions src/dp_port.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
#include "rte_flow/dp_rte_async_flow_template.h"
#include "rte_flow/dp_rte_flow.h"
#include "rte_flow/dp_rte_flow_capture.h"
#include "rte_flow/dp_rte_flow_init.h"
#include "rte_flow/dp_rte_flow_isolation.h"

#define DP_PORT_INIT_PF true
#define DP_PORT_INIT_VF false
Expand Down Expand Up @@ -388,10 +388,6 @@ static int dp_stop_eth_port(struct dp_port *port)
DPS_LOG_INFO("Stopping port", DP_LOG_PORT(port));

if (dp_conf_is_multiport_eswitch()) {
#ifdef ENABLE_VIRTSVC
if (port->is_pf)
dp_destroy_virtsvc_async_isolation_rules(port->port_id);
#endif
dp_destroy_async_rules(port->port_id,
port->default_async_rules.default_flows,
RTE_DIM(port->default_async_rules.default_flows));
Expand Down Expand Up @@ -425,19 +421,6 @@ void dp_ports_free(void)
}


static int dp_port_install_sync_isolated_mode(uint16_t port_id)
{
DPS_LOG_INFO("Init isolation flow rules");
if (DP_FAILED(dp_install_isolated_mode_ipip(port_id, IPPROTO_IPIP))
|| DP_FAILED(dp_install_isolated_mode_ipip(port_id, IPPROTO_IPV6)))
return DP_ERROR;
#ifdef ENABLE_VIRTSVC
return dp_install_virtsvc_sync_isolation_rules(port_id);
#else
return DP_OK;
#endif
}

static int dp_port_bind_port_hairpins(const struct dp_port *port)
{
// two pf port's hairpins are bound when processing the second port
Expand All @@ -463,30 +446,6 @@ static int dp_install_vf_init_rte_rules(struct dp_port *port)
return DP_OK;
}

static int dp_port_install_async_isolated_mode(struct dp_port *port)
{
DPS_LOG_INFO("Init async isolation flow rules");
if (DP_FAILED(dp_create_pf_async_isolation_rules(port)))
return DP_ERROR;
return DP_OK;
}

static int dp_port_create_default_pf_async_templates(struct dp_port *port)
{
DPS_LOG_INFO("Installing PF async templates", DP_LOG_PORT(port));
if (DP_FAILED(dp_create_pf_async_isolation_templates(port))) {
DPS_LOG_ERR("Failed to create pf async isolation templates", DP_LOG_PORT(port));
return DP_ERROR;
}
#ifdef ENABLE_VIRTSVC
if (DP_FAILED(dp_create_virtsvc_async_isolation_templates(port))) {
DPS_LOG_ERR("Failed to create virtsvc async isolation templates", DP_LOG_PORT(port));
return DP_ERROR;
}
#endif
return DP_OK;
}


static void dp_acquire_neigh_mac(struct dp_port *port);

Expand Down Expand Up @@ -560,12 +519,15 @@ static int dp_init_port(struct dp_port *port)

if (port->is_pf) {
if (dp_conf_is_multiport_eswitch()) {
if (DP_FAILED(dp_port_create_default_pf_async_templates(port))
|| DP_FAILED(dp_port_install_async_isolated_mode(port)))
DPS_LOG_INFO("Init async isolation flow rules");
if (DP_FAILED(dp_create_pf_async_isolation_templates(port))
|| DP_FAILED(dp_create_pf_async_isolation_rules(port)))
return DP_ERROR;
} else
if (DP_FAILED(dp_port_install_sync_isolated_mode(port->port_id)))
} else {
DPS_LOG_INFO("Init isolation flow rules");
if (DP_FAILED(dp_install_isolated_mode(port->port_id)))
return DP_ERROR;
}
}

if (dp_conf_is_offload_enabled()) {
Expand Down
Loading
Loading