-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
New module for setting the DSCP field (#20)
* feat: add dscp module * chore: add tests for the dscp module * feat: add test runs into the build workflow * fix: add go build cache
- Loading branch information
Showing
14 changed files
with
536 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,21 +11,53 @@ on: | |
jobs: | ||
build: | ||
runs-on: ubuntu-24.04 | ||
env: | ||
cache_name: build-and-test | ||
|
||
steps: | ||
- uses: awalsh128/cache-apt-pkgs-action@latest | ||
with: | ||
packages: meson clang python3-pyelftools libnuma-dev libpcap-dev git | ||
version: 1.0 | ||
version: 1.1 | ||
|
||
- uses: actions/checkout@v4 | ||
with: | ||
submodules: true | ||
|
||
- uses: hendrikmuhs/[email protected] | ||
name: ccache | ||
with: | ||
key: ${{ runner.os }}-build-cache | ||
- run: | | ||
meson setup build -Dbuildtype=debug | ||
meson compile -C build | ||
- uses: actions/setup-go@v5 | ||
with: | ||
go-version: '1.23.x' | ||
cache: false | ||
check-latest: true | ||
# https://github.com/actions/setup-go/issues/358 | ||
- name: Get Go environment | ||
run: | | ||
echo "cache=$(go env GOCACHE)" >> $GITHUB_ENV | ||
echo "modcache=$(go env GOMODCACHE)" >> $GITHUB_ENV | ||
- name: Set up go cache | ||
uses: actions/cache@v3 | ||
with: | ||
path: | | ||
${{ env.cache }} | ||
${{ env.modcache }} | ||
key: ${{ env.cache_name }}-${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}-${{ hashFiles('**/go.mod') }} | ||
restore-keys: | | ||
${{ env.cache_name }}-${{ runner.os }}-go- | ||
- run: | ||
meson test -C build | ||
- name: Show meson test log | ||
run: | ||
grep -v 'Inherited environment' build/meson-logs/testlog.txt | ||
|
||
- uses: cpp-linter/cpp-linter-action@main | ||
id: linter | ||
continue-on-error: true | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
|
||
#include <stdint.h> | ||
|
||
static inline uint16_t | ||
csum_plus(uint16_t val0, uint16_t val1) { | ||
uint16_t sum = val0 + val1; | ||
|
||
if (sum < val0) { | ||
++sum; | ||
} | ||
|
||
return sum; | ||
} | ||
|
||
static inline uint16_t | ||
csum_minus(uint16_t val0, uint16_t val1) { | ||
uint16_t sum = val0 - val1; | ||
|
||
if (sum > val0) { | ||
--sum; | ||
} | ||
|
||
return sum; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
#include <rte_ip.h> | ||
|
||
#include "checksum.h" | ||
#include "dscp.h" | ||
|
||
int | ||
dscp_mark_v4(struct rte_ipv4_hdr *ip4_hdr, struct dscp_config config) { | ||
uint8_t mark = ip4_hdr->type_of_service & DSCP_MARK_MASK; | ||
if (config.flag & DSCP_MARK_DEFAULT && mark != 0) { | ||
// do not remark | ||
return -1; | ||
} | ||
|
||
uint16_t checksum = ~rte_be_to_cpu_16(ip4_hdr->hdr_checksum); | ||
checksum = csum_minus(checksum, mark); | ||
uint8_t new_mark = config.mark << DSCP_MARK_SHIFT; | ||
checksum = csum_plus(checksum, new_mark); | ||
ip4_hdr->hdr_checksum = ~rte_cpu_to_be_16(checksum); | ||
|
||
uint8_t ecn = ip4_hdr->type_of_service & DSCP_ECN_MASK; | ||
ip4_hdr->type_of_service = new_mark | ecn; | ||
return 0; | ||
} | ||
|
||
static inline uint8_t | ||
get_ipv6_tc(rte_be32_t vtc_flow) { | ||
uint32_t v = rte_be_to_cpu_32(vtc_flow); | ||
return v >> RTE_IPV6_HDR_TC_SHIFT; | ||
} | ||
|
||
static inline rte_be32_t | ||
set_ipv6_tc(rte_be32_t vtc_flow, uint32_t tc) { | ||
// Shift by the length of the Flow Label - 20-bit. | ||
uint32_t v = rte_cpu_to_be_32(tc << RTE_IPV6_HDR_TC_SHIFT); | ||
vtc_flow &= ~rte_cpu_to_be_32(RTE_IPV6_HDR_TC_MASK); | ||
return (v | vtc_flow); | ||
} | ||
|
||
int | ||
dscp_mark_v6(struct rte_ipv6_hdr *ip6_hdr, struct dscp_config config) { | ||
uint8_t tc = get_ipv6_tc(ip6_hdr->vtc_flow); | ||
uint8_t mark = tc & DSCP_MARK_MASK; | ||
if (config.flag & DSCP_MARK_DEFAULT && mark != 0) { | ||
// do not remark | ||
return -1; | ||
} | ||
uint8_t new_mark = config.mark << DSCP_MARK_SHIFT; | ||
ip6_hdr->vtc_flow = set_ipv6_tc(ip6_hdr->vtc_flow, new_mark); | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
#pragma once | ||
|
||
#include <stdint.h> | ||
|
||
#define DSCP_MARK_NEVER 0 | ||
#define DSCP_MARK_DEFAULT 1 | ||
#define DSCP_MARK_ALWAYS 2 | ||
|
||
#define DSCP_MARK_MASK 0xFC | ||
#define DSCP_MARK_SHIFT 2 | ||
#define DSCP_ECN_MASK 0x03 | ||
|
||
// #include <rte_ip.h> | ||
struct rte_ipv4_hdr; | ||
struct rte_ipv6_hdr; | ||
|
||
struct dscp_config { | ||
uint8_t flag; | ||
uint8_t mark; | ||
}; | ||
|
||
int | ||
dscp_mark_v4(struct rte_ipv4_hdr *ip4_hdr, struct dscp_config config); | ||
|
||
int | ||
dscp_mark_v6(struct rte_ipv6_hdr *ip6_hdr, struct dscp_config config); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,6 +7,7 @@ sources = files( | |
'packet.c', | ||
'encap.c', | ||
'decap.c', | ||
'dscp.c', | ||
) | ||
|
||
lib_packet_dp = static_library( | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
#include "dataplane.h" | ||
|
||
#include <rte_ether.h> | ||
#include <rte_ip.h> | ||
|
||
#include "dataplane/module/module.h" | ||
#include "dataplane/packet/dscp.h" | ||
#include "dataplane/packet/packet.h" | ||
|
||
static int | ||
dscp_handle_v4(struct dscp_module_config *config, struct packet *packet) { | ||
struct rte_mbuf *mbuf = packet_to_mbuf(packet); | ||
|
||
struct rte_ipv4_hdr *header = rte_pktmbuf_mtod_offset( | ||
mbuf, struct rte_ipv4_hdr *, packet->network_header.offset | ||
); | ||
|
||
if (lpm_lookup(&config->lpm_v4, 4, (uint8_t *)&header->dst_addr) != | ||
LPM_VALUE_INVALID) { | ||
return dscp_mark_v4(header, config->dscp); | ||
} | ||
|
||
return -1; | ||
} | ||
|
||
static int | ||
dscp_handle_v6(struct dscp_module_config *config, struct packet *packet) { | ||
struct rte_mbuf *mbuf = packet_to_mbuf(packet); | ||
|
||
struct rte_ipv6_hdr *header = rte_pktmbuf_mtod_offset( | ||
mbuf, struct rte_ipv6_hdr *, packet->network_header.offset | ||
); | ||
|
||
if (lpm_lookup(&config->lpm_v6, 16, (uint8_t *)&header->dst_addr) != | ||
LPM_VALUE_INVALID) { | ||
return dscp_mark_v6(header, config->dscp); | ||
} | ||
|
||
return -1; | ||
} | ||
|
||
static inline int | ||
dscp_handle(struct dscp_module_config *config, struct packet *packet) { | ||
uint16_t type = packet->network_header.type; | ||
int result = -1; | ||
if (type == rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4)) { | ||
result = dscp_handle_v4(config, packet); | ||
} else if (type == rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6)) { | ||
result = dscp_handle_v6(config, packet); | ||
} | ||
return result; | ||
} | ||
|
||
void | ||
dscp_handle_packets( | ||
struct module *module, | ||
struct module_config *config, | ||
struct packet_front *packet_front | ||
) { | ||
(void)module; | ||
struct dscp_module_config *dscp_config = | ||
container_of(config, struct dscp_module_config, config); | ||
|
||
if (dscp_config->dscp.flag != DSCP_MARK_NEVER) { | ||
struct packet *packet; | ||
while ((packet = packet_list_pop(&packet_front->input)) != NULL | ||
) { | ||
dscp_handle(dscp_config, packet); | ||
packet_list_add(&packet_front->output, packet); | ||
} | ||
} else { | ||
packet_front_pass(packet_front); | ||
} | ||
|
||
return; | ||
} | ||
|
||
static int | ||
dscp_handle_configure( | ||
struct module *module, | ||
const void *config_data, | ||
size_t config_data_size, | ||
struct module_config **new_config | ||
) { | ||
|
||
(void)module; | ||
|
||
struct dscp_module_config *config = (struct dscp_module_config *)malloc( | ||
sizeof(struct dscp_module_config) | ||
); | ||
|
||
uint8_t ip6min[16] = {0}; | ||
uint8_t ip6max[16] = {0}; | ||
memset(ip6max, 0xff, 16); | ||
lpm_init(&config->lpm_v4); | ||
lpm_init(&config->lpm_v6); | ||
lpm_insert(&config->lpm_v4, 4, ip6min, ip6max, 1); | ||
lpm_insert(&config->lpm_v6, 16, ip6min, ip6max, 1); | ||
|
||
if (config_data_size != sizeof(struct dscp_config)) { | ||
return -1; | ||
} | ||
config->dscp = *(struct dscp_config *)config_data; | ||
|
||
*new_config = &config->config; | ||
|
||
return 0; | ||
}; | ||
|
||
struct dscp_module { | ||
struct module module; | ||
}; | ||
|
||
struct module * | ||
new_module_dscp() { | ||
struct dscp_module *module = | ||
(struct dscp_module *)malloc(sizeof(struct dscp_module)); | ||
|
||
if (module == NULL) { | ||
return NULL; | ||
} | ||
|
||
snprintf( | ||
module->module.name, sizeof(module->module.name), "%s", "dscp" | ||
); | ||
module->module.handler = dscp_handle_packets; | ||
module->module.config_handler = dscp_handle_configure; | ||
|
||
return &module->module; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
#pragma once | ||
|
||
#include "dataplane/module/module.h" | ||
#include "dataplane/packet/dscp.h" | ||
#include "lpm.h" | ||
|
||
struct dscp_module_config { | ||
struct module_config config; | ||
|
||
struct lpm lpm_v4; | ||
struct lpm lpm_v6; | ||
struct dscp_config dscp; | ||
}; | ||
|
||
struct module * | ||
new_module_kernel(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# common dependecies | ||
dependencies += lib_common_dep | ||
dependencies += lib_filter_dep | ||
|
||
# dataplane dependecies | ||
dp_dependencies = dependencies | ||
dp_dependencies += lib_packet_dp_dep | ||
|
||
dp_dependencies += lib_module_dp_dep | ||
|
||
dp_sources = files( | ||
'dataplane.c', | ||
) | ||
|
||
lib_dscp_dp = static_library( | ||
'dscp_dp', | ||
dp_sources, | ||
dependencies: dp_dependencies, | ||
install: false, | ||
) | ||
|
||
lib_dscp_dp_dep = declare_dependency( | ||
link_with: lib_dscp_dp, | ||
link_args: [ | ||
'-Wl,--defsym', '-Wl,new_module_dscp=new_module_dscp', | ||
'-Wl,--export-dynamic-symbol=new_module_dscp', | ||
], | ||
) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,3 +3,4 @@ subdir('balancer') | |
subdir('acl') | ||
subdir('route') | ||
subdir('forward') | ||
subdir('dscp') |
Oops, something went wrong.