Refactored packet API to support struct layer (using union to contain different types of encapsulation headers)

This commit is contained in:
luwenpeng
2024-06-14 19:24:27 +08:00
parent 1f78881cbb
commit de4c15f43c
47 changed files with 834 additions and 701 deletions

View File

@@ -6,6 +6,7 @@
#include "uthash.h"
#include "packet_priv.h"
#include "packet_utils.h"
#include "eth_utils.h"
#include "gre_utils.h"
#include "udp_utils.h"
@@ -49,11 +50,11 @@
******************************************************************************/
static inline const char *ldbc_method_to_str(enum ldbc_method method);
static inline const char *layer_proto_to_str(enum layer_proto type);
static inline const char *layer_proto_to_str(enum layer_proto proto);
static inline void set_tuple2(const char *data, enum layer_proto type, struct tuple2 *tuple);
static inline void set_tuple4(const char *data, enum layer_proto type, struct tuple4 *tuple);
static inline void set_tuple6(const char *data, enum layer_proto type, struct tuple6 *tuple, uint64_t domain);
static inline void set_tuple2(const char *data, enum layer_proto proto, struct tuple2 *tuple);
static inline void set_tuple4(const char *data, enum layer_proto proto, struct tuple4 *tuple);
static inline void set_tuple6(const char *data, enum layer_proto proto, struct tuple6 *tuple, uint64_t domain);
static inline struct raw_layer *get_free_layer(struct packet *pkt);
@@ -112,9 +113,9 @@ static inline const char *ldbc_method_to_str(enum ldbc_method method)
}
}
static inline const char *layer_proto_to_str(enum layer_proto type)
static inline const char *layer_proto_to_str(enum layer_proto proto)
{
switch (type)
switch (proto)
{
case LAYER_PROTO_ETHER:
return "ETH";
@@ -155,12 +156,12 @@ static inline const char *layer_proto_to_str(enum layer_proto type)
}
}
static inline void set_tuple2(const char *data, enum layer_proto type, struct tuple2 *tuple)
static inline void set_tuple2(const char *data, enum layer_proto proto, struct tuple2 *tuple)
{
const struct ip *ipv4 = NULL;
const struct ip6_hdr *ipv6 = NULL;
switch (type)
switch (proto)
{
case LAYER_PROTO_IPV4:
ipv4 = (const struct ip *)data;
@@ -179,14 +180,14 @@ static inline void set_tuple2(const char *data, enum layer_proto type, struct tu
}
}
static inline void set_tuple4(const char *data, enum layer_proto type, struct tuple4 *tuple)
static inline void set_tuple4(const char *data, enum layer_proto proto, struct tuple4 *tuple)
{
const struct ip *ipv4 = NULL;
const struct ip6_hdr *ipv6 = NULL;
const struct tcphdr *tcp = NULL;
const struct udphdr *udp = NULL;
switch (type)
switch (proto)
{
case LAYER_PROTO_TCP:
tcp = (const struct tcphdr *)data;
@@ -215,7 +216,7 @@ static inline void set_tuple4(const char *data, enum layer_proto type, struct tu
}
}
static inline void set_tuple6(const char *data, enum layer_proto type, struct tuple6 *tuple, uint64_t domain)
static inline void set_tuple6(const char *data, enum layer_proto proto, struct tuple6 *tuple, uint64_t domain)
{
const struct ip *ipv4 = NULL;
const struct ip6_hdr *ipv6 = NULL;
@@ -224,7 +225,7 @@ static inline void set_tuple6(const char *data, enum layer_proto type, struct tu
tuple->domain = domain;
switch (type)
switch (proto)
{
case LAYER_PROTO_TCP:
tcp = (const struct tcphdr *)data;
@@ -265,9 +266,9 @@ static inline struct raw_layer *get_free_layer(struct packet *pkt)
return &pkt->layers[pkt->layers_used];
}
#define SET_LAYER(_pkt, _layer, _type, _hdr_len, _data, _len, _trim) \
#define SET_LAYER(_pkt, _layer, _proto, _hdr_len, _data, _len, _trim) \
{ \
(_layer)->type = (_type); \
(_layer)->proto = (_proto); \
(_layer)->hdr_offset = (_pkt)->data_len - (_pkt)->trim_len - (_len); \
(_layer)->hdr_ptr = (_data); \
(_layer)->hdr_len = (_hdr_len); \
@@ -276,7 +277,7 @@ static inline struct raw_layer *get_free_layer(struct packet *pkt)
(_pkt)->trim_len += (_trim); \
(_pkt)->layers_used++; \
PACKET_LOG_DEBUG("layer[%d/%d]: %s, hdr_offset: %d, hdr_ptr: %p, hdr_len: %d, pld_ptr: %p, pld_len: %d", \
(_pkt)->layers_used - 1, (_pkt)->layers_size, layer_proto_to_str((_type)), \
(_pkt)->layers_used - 1, (_pkt)->layers_size, layer_proto_to_str((_proto)), \
(_layer)->hdr_offset, (_layer)->hdr_ptr, (_layer)->hdr_len, (_layer)->pld_ptr, (_layer)->pld_len); \
}
@@ -1148,10 +1149,10 @@ void packet_print_str(const struct packet *pkt)
{
int used = 0;
const struct raw_layer *layer = &pkt->layers[i];
printf(" layer[%u]: %p, type: %s, hdr_offset: %u, hdr_ptr: %p, hdr_len: %u, pld_ptr: %p, pld_len: %u\n",
i, layer, layer_proto_to_str(layer->type), layer->hdr_offset,
printf(" layer[%u]: %p, proto: %s, hdr_offset: %u, hdr_ptr: %p, hdr_len: %u, pld_ptr: %p, pld_len: %u\n",
i, layer, layer_proto_to_str(layer->proto), layer->hdr_offset,
layer->hdr_ptr, layer->hdr_len, layer->pld_ptr, layer->pld_len);
switch (layer->type)
switch (layer->proto)
{
case LAYER_PROTO_ETHER:
used = eth_hdr_to_str((const struct ethhdr *)layer->hdr_ptr, buffer, sizeof(buffer));
@@ -1219,9 +1220,9 @@ int packet_get_innermost_tuple2(const struct packet *pkt, struct tuple2 *tuple)
{
layer = &pkt->layers[i];
if (layer->type == LAYER_PROTO_IPV4 || layer->type == LAYER_PROTO_IPV6)
if (layer->proto == LAYER_PROTO_IPV4 || layer->proto == LAYER_PROTO_IPV6)
{
set_tuple2((const char *)pkt->data_ptr + layer->hdr_offset, layer->type, tuple);
set_tuple2((const char *)pkt->data_ptr + layer->hdr_offset, layer->proto, tuple);
return 0;
}
}
@@ -1240,9 +1241,9 @@ int packet_get_outermost_tuple2(const struct packet *pkt, struct tuple2 *tuple)
{
layer = &pkt->layers[i];
if (layer->type == LAYER_PROTO_IPV4 || layer->type == LAYER_PROTO_IPV6)
if (layer->proto == LAYER_PROTO_IPV4 || layer->proto == LAYER_PROTO_IPV6)
{
set_tuple2((const char *)pkt->data_ptr + layer->hdr_offset, layer->type, tuple);
set_tuple2((const char *)pkt->data_ptr + layer->hdr_offset, layer->proto, tuple);
return 0;
}
}
@@ -1264,14 +1265,14 @@ int packet_get_innermost_tuple4(const struct packet *pkt, struct tuple4 *tuple)
layer = &pkt->layers[i];
// first get L4 layer
if (layer->type == LAYER_PROTO_UDP || layer->type == LAYER_PROTO_TCP)
if (layer->proto == LAYER_PROTO_UDP || layer->proto == LAYER_PROTO_TCP)
{
layer_l4 = layer;
continue;
}
// second get L3 layer
if (layer->type == LAYER_PROTO_IPV4 || layer->type == LAYER_PROTO_IPV6)
if (layer->proto == LAYER_PROTO_IPV4 || layer->proto == LAYER_PROTO_IPV6)
{
layer_l3 = layer;
break;
@@ -1280,8 +1281,8 @@ int packet_get_innermost_tuple4(const struct packet *pkt, struct tuple4 *tuple)
if (layer_l3 && layer_l4)
{
set_tuple4((const char *)pkt->data_ptr + layer_l3->hdr_offset, layer_l3->type, tuple);
set_tuple4((const char *)pkt->data_ptr + layer_l4->hdr_offset, layer_l4->type, tuple);
set_tuple4((const char *)pkt->data_ptr + layer_l3->hdr_offset, layer_l3->proto, tuple);
set_tuple4((const char *)pkt->data_ptr + layer_l4->hdr_offset, layer_l4->proto, tuple);
return 0;
}
else
@@ -1304,14 +1305,14 @@ int packet_get_outermost_tuple4(const struct packet *pkt, struct tuple4 *tuple)
layer = &pkt->layers[i];
// first get L3 layer
if (layer->type == LAYER_PROTO_IPV4 || layer->type == LAYER_PROTO_IPV6)
if (layer->proto == LAYER_PROTO_IPV4 || layer->proto == LAYER_PROTO_IPV6)
{
layer_l3 = layer;
continue;
}
// second get L4 layer
if (layer->type == LAYER_PROTO_UDP || layer->type == LAYER_PROTO_TCP)
if (layer->proto == LAYER_PROTO_UDP || layer->proto == LAYER_PROTO_TCP)
{
layer_l4 = layer;
break;
@@ -1320,8 +1321,8 @@ int packet_get_outermost_tuple4(const struct packet *pkt, struct tuple4 *tuple)
if (layer_l3 && layer_l4)
{
set_tuple4((const char *)pkt->data_ptr + layer_l3->hdr_offset, layer_l3->type, tuple);
set_tuple4((const char *)pkt->data_ptr + layer_l4->hdr_offset, layer_l4->type, tuple);
set_tuple4((const char *)pkt->data_ptr + layer_l3->hdr_offset, layer_l3->proto, tuple);
set_tuple4((const char *)pkt->data_ptr + layer_l4->hdr_offset, layer_l4->proto, tuple);
return 0;
}
else
@@ -1338,21 +1339,21 @@ int packet_get_innermost_tuple6(const struct packet *pkt, struct tuple6 *tuple)
const struct raw_layer *layer_l3 = NULL;
const struct raw_layer *layer_l4 = NULL;
const struct raw_layer *layer = NULL;
uint64_t domain = packet_get_domain(pkt);
uint64_t domain = packet_get_domain_id(pkt);
for (int8_t i = pkt->layers_used - 1; i >= 0; i--)
{
layer = &pkt->layers[i];
// first get L4 layer
if (layer->type == LAYER_PROTO_UDP || layer->type == LAYER_PROTO_TCP)
if (layer->proto == LAYER_PROTO_UDP || layer->proto == LAYER_PROTO_TCP)
{
layer_l4 = layer;
continue;
}
// second get L3 layer
if (layer->type == LAYER_PROTO_IPV4 || layer->type == LAYER_PROTO_IPV6)
if (layer->proto == LAYER_PROTO_IPV4 || layer->proto == LAYER_PROTO_IPV6)
{
layer_l3 = layer;
break;
@@ -1361,8 +1362,8 @@ int packet_get_innermost_tuple6(const struct packet *pkt, struct tuple6 *tuple)
if (layer_l3 && layer_l4 && layer_l4 - layer_l3 == 1)
{
set_tuple6((const char *)pkt->data_ptr + layer_l3->hdr_offset, layer_l3->type, tuple, domain);
set_tuple6((const char *)pkt->data_ptr + layer_l4->hdr_offset, layer_l4->type, tuple, domain);
set_tuple6((const char *)pkt->data_ptr + layer_l3->hdr_offset, layer_l3->proto, tuple, domain);
set_tuple6((const char *)pkt->data_ptr + layer_l4->hdr_offset, layer_l4->proto, tuple, domain);
return 0;
}
else
@@ -1379,21 +1380,21 @@ int packet_get_outermost_tuple6(const struct packet *pkt, struct tuple6 *tuple)
const struct raw_layer *layer_l3 = NULL;
const struct raw_layer *layer_l4 = NULL;
const struct raw_layer *layer = NULL;
uint64_t domain = packet_get_domain(pkt);
uint64_t domain = packet_get_domain_id(pkt);
for (int8_t i = 0; i < pkt->layers_used; i++)
{
layer = &pkt->layers[i];
// first get L3 layer
if (layer->type == LAYER_PROTO_IPV4 || layer->type == LAYER_PROTO_IPV6)
if (layer->proto == LAYER_PROTO_IPV4 || layer->proto == LAYER_PROTO_IPV6)
{
layer_l3 = layer;
continue;
}
// second get L4 layer
if (layer->type == LAYER_PROTO_UDP || layer->type == LAYER_PROTO_TCP)
if (layer->proto == LAYER_PROTO_UDP || layer->proto == LAYER_PROTO_TCP)
{
layer_l4 = layer;
break;
@@ -1402,8 +1403,8 @@ int packet_get_outermost_tuple6(const struct packet *pkt, struct tuple6 *tuple)
if (layer_l3 && layer_l4 && layer_l4 - layer_l3 == 1)
{
set_tuple6((const char *)pkt->data_ptr + layer_l3->hdr_offset, layer_l3->type, tuple, domain);
set_tuple6((const char *)pkt->data_ptr + layer_l4->hdr_offset, layer_l4->type, tuple, domain);
set_tuple6((const char *)pkt->data_ptr + layer_l3->hdr_offset, layer_l3->proto, tuple, domain);
set_tuple6((const char *)pkt->data_ptr + layer_l4->hdr_offset, layer_l4->proto, tuple, domain);
return 0;
}
else
@@ -1412,14 +1413,56 @@ int packet_get_outermost_tuple6(const struct packet *pkt, struct tuple6 *tuple)
}
}
const struct raw_layer *packet_get_innermost_raw_layer(const struct packet *pkt, enum layer_proto type)
const char *packet_get_raw_data(const struct packet *pkt)
{
return pkt->data_ptr;
}
uint16_t packet_get_raw_len(const struct packet *pkt)
{
return pkt->data_len;
}
const char *packet_get_payload(const struct packet *pkt)
{
if (pkt->layers_used == 0)
{
return NULL;
}
return pkt->layers[pkt->layers_used - 1].pld_ptr;
}
uint16_t packet_get_payload_len(const struct packet *pkt)
{
if (pkt->layers_used == 0)
{
return 0;
}
return pkt->layers[pkt->layers_used - 1].pld_len;
}
int packet_get_layer_count(const struct packet *pkt)
{
return pkt->layers_used;
}
const struct raw_layer *packet_get_raw_layer(const struct packet *pkt, int idx)
{
if (idx < 0 || idx >= pkt->layers_used)
{
return NULL;
}
return &pkt->layers[idx];
}
const struct raw_layer *packet_get_innermost_raw_layer(const struct packet *pkt, enum layer_proto proto)
{
const struct raw_layer *layer = NULL;
for (int8_t i = pkt->layers_used - 1; i >= 0; i--)
{
layer = &pkt->layers[i];
if (layer->type == type)
if (layer->proto == proto)
{
return layer;
}
@@ -1428,14 +1471,14 @@ const struct raw_layer *packet_get_innermost_raw_layer(const struct packet *pkt,
return NULL;
}
const struct raw_layer *packet_get_outermost_raw_layer(const struct packet *pkt, enum layer_proto type)
const struct raw_layer *packet_get_outermost_raw_layer(const struct packet *pkt, enum layer_proto proto)
{
const struct raw_layer *layer = NULL;
for (int8_t i = 0; i < pkt->layers_used; i++)
{
layer = &pkt->layers[i];
if (layer->type == type)
if (layer->proto == proto)
{
return layer;
}
@@ -1444,6 +1487,7 @@ const struct raw_layer *packet_get_outermost_raw_layer(const struct packet *pkt,
return NULL;
}
// TODO
// direction 1: E2I
// direction 0: I2E
uint64_t packet_get_hash(const struct packet *pkt, enum ldbc_method method, int direction)