Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

worker: support address mappings for IP and SCION #47

Draft
wants to merge 18 commits into
base: open-source
Choose a base branch
from
Draft
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
113 changes: 113 additions & 0 deletions src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@
#define FIELD_BYTE_BURST "byte_burst"

#define FIELD_PORT "port"
#define FIELD_SCION_DST "scion_dst"
#define FIELD_SCION_SRC "scion_src"
#define FIELD_IP "ip"
#define FIELD_IP_DST_MAP "ip_dst_map"
#define FIELD_IP_SRC_MAP "ip_src_map"
#define FIELD_IPV6 "ipv6"
#define FIELD_IP_PUBLIC "ip_public"
#define FIELD_IP_PRIVATE "ip_private"
Expand Down Expand Up @@ -483,6 +487,75 @@ parse_pkt_mod_ether(json_value *json_val, struct lf_config_pkt_mod *pkt_mod)
return -1;
}

static int
parse_pkt_mod_ip_map(char *name, json_value *json_val,
struct lf_config_pkt_mod *pkt_mod)
{
int res, error_count;
unsigned int length, i;
uint32_t from, to;
char *field_name;
json_value *field_value;

if (json_val == NULL) {
return -1;
}

if (json_val->type != json_object) {
return -1;
}

length = json_val->u.object.length;
if (length > LF_CONFIG_IP_MAP_MAX) {
LF_LOG(ERR, "Exceed ip map limit (%d:%d)\n", json_val->line,
json_val->col);
return -1;
}
error_count = 0;

for (i = 0; i < length; ++i) {
field_name = json_val->u.object.values[i].name;
field_value = json_val->u.object.values[i].value;
#if !LF_IPV6
assert(sizeof from == sizeof(struct in_addr));
res = inet_pton(AF_INET, field_name, &from);
if (res != 1) {
LF_LOG(ERR, "Invalid IPv4 address mapping (%d:%d)\n",
field_value->line, field_value->col);
error_count++;
}
res = lf_json_parse_ipv4(field_value, &to);
if (res != 0) {
LF_LOG(ERR, "Invalid IPv4 address mapping (%d:%d)\n",
field_value->line, field_value->col);
error_count++;
}
if (strcmp(name, FIELD_IP_DST_MAP) == 0) {
assert(i <
sizeof pkt_mod->ip_dst_map / sizeof pkt_mod->ip_dst_map[0]);
pkt_mod->ip_dst_map[i].from = from;
pkt_mod->ip_dst_map[i].to = to;
} else {
assert(strcmp(name, FIELD_IP_SRC_MAP) == 0);
assert(i <
sizeof pkt_mod->ip_src_map / sizeof pkt_mod->ip_src_map[0]);
pkt_mod->ip_src_map[i].from = from;
pkt_mod->ip_src_map[i].to = to;
}
#else
LF_LOG(ERR, "Detected IPv4 address but IPv6 is enabled (%d:%d)\n",
field_value->line, field_value->col);
error_count++;
#endif
}

if (error_count > 0) {
return -1;
} else {
return 0;
}
}

static int
parse_pkt_mod(json_value *json_val, struct lf_config_pkt_mod *pkt_mod)
{
Expand Down Expand Up @@ -540,6 +613,46 @@ parse_pkt_mod(json_value *json_val, struct lf_config_pkt_mod *pkt_mod)
LF_LOG(ERR, "Detected IPv4 address but IPv6 is enabled (%d:%d)\n",
field_value->line, field_value->col);
error_count++;
#endif
} else if (strcmp(field_name, FIELD_IP_DST_MAP) == 0) {
res = parse_pkt_mod_ip_map(field_name, field_value, pkt_mod);
if (res != 0) {
LF_LOG(ERR, "Invalid pkt mod IP dst map field (%d:%d)\n",
field_value->line, field_value->col);
error_count++;
}
} else if (strcmp(field_name, FIELD_IP_SRC_MAP) == 0) {
res = parse_pkt_mod_ip_map(field_name, field_value, pkt_mod);
if (res != 0) {
LF_LOG(ERR, "Invalid pkt mod IP src map field (%d:%d)\n",
field_value->line, field_value->col);
error_count++;
}
} else if (strcmp(field_name, FIELD_SCION_DST) == 0) {
#if !LF_IPV6
res = lf_json_parse_ipv4(field_value, &pkt_mod->scion_dst);
if (res != 0) {
LF_LOG(ERR, "Invalid IPv4 address (%d:%d)\n", field_value->line,
field_value->col);
error_count++;
}
#else
LF_LOG(ERR, "Detected IPv4 address but IPv6 is enabled (%d:%d)\n",
field_value->line, field_value->col);
error_count++;
#endif
} else if (strcmp(field_name, FIELD_SCION_SRC) == 0) {
#if !LF_IPV6
res = lf_json_parse_ipv4(field_value, &pkt_mod->scion_src);
if (res != 0) {
LF_LOG(ERR, "Invalid IPv4 address (%d:%d)\n", field_value->line,
field_value->col);
error_count++;
}
#else
LF_LOG(ERR, "Detected IPv4 address but IPv6 is enabled (%d:%d)\n",
field_value->line, field_value->col);
error_count++;
#endif
} else {
LF_LOG(ERR, "Unknown field %s (%d:%d)\n", field_name,
Expand Down
25 changes: 25 additions & 0 deletions src/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@
*/
#define LF_CONFIG_SV_MAX 5

/*
* Maximum number of entries in an IP address map
*/
#define LF_CONFIG_IP_MAP_MAX 5

/*
* Rate limits are always defined for bytes and packets.
*/
Expand Down Expand Up @@ -93,6 +98,26 @@ struct lf_config_pkt_mod {
uint8_t ipv6[16];
#else
uint32_t ip; /* in network byte order */
#endif
/* map source/destination IP address to specific value */
struct {
#if LF_IPV6
uint8_t from[16], to[16];
#else
uint32_t from, to;
#endif
} ip_src_map[LF_CONFIG_IP_MAP_MAX], ip_dst_map[LF_CONFIG_IP_MAP_MAX];
/* set SCION destination host address to specific value */
#if LF_IPV6
uint8_t scion_dst[16];
#else
uint32_t scion_dst; /* in network byte order */
#endif
/* set SCION source host address to specific value */
#if LF_IPV6
uint8_t scion_src[16];
#else
uint32_t scion_src; /* in network byte order */
#endif
};

Expand Down
6 changes: 3 additions & 3 deletions src/lib/aesni/aesni.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ typedef struct keystruct {
// ExpandKey128(unsigned char* enckey, void* roundkey)
// enckey: 16-byte key string input
// roundkey: 10*16-byte round key ouput buffer
//#define ExpandKey128 ExpandKey128
// #define ExpandKey128 ExpandKey128
extern void
ExpandKey128(unsigned const char *enckey, void *roundkey);

Expand All @@ -32,7 +32,7 @@ ExpandKey128(unsigned const char *enckey, void *roundkey);
// numblk: number of block (each block is 16 bytes)
// plain: unsigned char*, 16-byte buffer input plaintext
// mac: unsigned char*, 16-byte buffer for computed MAC
//#define CBCMAC CBCMAC
// #define CBCMAC CBCMAC
extern void
CBCMAC(const void *rk, int numblk, unsigned const char *plain,
unsigned char *mac);
Expand All @@ -50,7 +50,7 @@ CMAC(const void *rk, int numblk, unsigned const char *plain,

// PMAC(void* rk, int numblk, unsigned char* plain, unsigned char* mac)
// rk: keystruct to store roundkey
//#define PMAC PMAC
// #define PMAC PMAC
extern void
PMAC(const void *rk, int numblk, unsigned char *plain, unsigned char *mac);

Expand Down
42 changes: 36 additions & 6 deletions src/worker.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,18 +75,48 @@ lf_worker_pkt_mod(struct rte_mbuf *m, struct rte_ether_hdr *ether_hdr,

#if LF_IPV6
struct rte_ipv6_hdr *ipv6_hdr = (struct rte_ipv6_hdr *)l3_hdr;
if (ipv6_hdr != NULL && pkt_mod->ip_option) {
memcpy(ipv6_hdr->dst_addr, pkt_mod->ipv6, sizeof(pkt_mod->ipv6));
}
if (ipv6_hdr != NULL) {
if (pkt_mod->ip_option) {
memcpy(ipv6_hdr->dst_addr, pkt_mod->ipv6, sizeof(pkt_mod->ipv6));
}
(void)lf_pktv6_set_cksum(m, ether_hdr, ipv6_hdr, LF_OFFLOAD_CKSUM);
}
#else
struct rte_ipv4_hdr *ipv4_hdr = (struct rte_ipv4_hdr *)l3_hdr;
if (ipv4_hdr != NULL && pkt_mod->ip_option) {
ipv4_hdr->dst_addr = pkt_mod->ip;
}
if (ipv4_hdr != NULL) {
if (pkt_mod->ip_option) {
ipv4_hdr->dst_addr = pkt_mod->ip;
} else {
size_t i, n;
i = 0,
n = sizeof pkt_mod->ip_src_map / sizeof pkt_mod->ip_src_map[0];
while (i != n &&
pkt_mod->ip_src_map[i].from != ipv4_hdr->src_addr &&
(pkt_mod->ip_src_map[i].from != 0 ||
pkt_mod->ip_src_map[i].to == 0)) {
i++;
}
if (i != n) {
LF_WORKER_LOG_DP(DEBUG, "Src IP: " PRIIP " -> " PRIIP "\n",
PRIIP_VAL(ipv4_hdr->src_addr),
PRIIP_VAL(pkt_mod->ip_src_map[i].to));
ipv4_hdr->src_addr = pkt_mod->ip_src_map[i].to;
}
i = 0,
n = sizeof pkt_mod->ip_dst_map / sizeof pkt_mod->ip_dst_map[0];
while (i != n &&
pkt_mod->ip_dst_map[i].from != ipv4_hdr->dst_addr &&
(pkt_mod->ip_dst_map[i].from != 0 ||
pkt_mod->ip_dst_map[i].to == 0)) {
i++;
}
if (i != n) {
LF_WORKER_LOG_DP(DEBUG, "Dst IP: " PRIIP " -> " PRIIP "\n",
PRIIP_VAL(ipv4_hdr->dst_addr),
PRIIP_VAL(pkt_mod->ip_dst_map[i].to));
ipv4_hdr->dst_addr = pkt_mod->ip_dst_map[i].to;
}
}
(void)lf_pkt_set_cksum(m, ether_hdr, ipv4_hdr, LF_OFFLOAD_CKSUM);
}
#endif /* LF_IPV6 */
Expand Down
Loading
Loading