mirror of
https://github.com/xdp-project/bpf-examples.git
synced 2024-05-06 15:54:53 +00:00
pping: Refactor parse_packet_identifer
Remove the saddr and daddr parmeters from parse_packet_identifier, and use the is_egress parmeter to perform the saddr/daddr swap inside the function. Also, minor style fixes. Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
This commit is contained in:
@@ -23,8 +23,6 @@
|
|||||||
*/
|
*/
|
||||||
static void map_ipv4_to_ipv6(__be32 ipv4, struct in6_addr *ipv6)
|
static void map_ipv4_to_ipv6(__be32 ipv4, struct in6_addr *ipv6)
|
||||||
{
|
{
|
||||||
/* __u16 ipv4_prefix[6] = {0x0, 0x0, 0x0, 0x0, 0x0, 0xffff}; */
|
|
||||||
/* __builtin_memcpy(ipv6, ipv4_prefix, sizeof(ipv4_prefix)); */
|
|
||||||
__builtin_memset(&ipv6->in6_u.u6_addr8[0], 0x00, 10);
|
__builtin_memset(&ipv6->in6_u.u6_addr8[0], 0x00, 10);
|
||||||
__builtin_memset(&ipv6->in6_u.u6_addr8[10], 0xff, 2);
|
__builtin_memset(&ipv6->in6_u.u6_addr8[10], 0xff, 2);
|
||||||
ipv6->in6_u.u6_addr32[3] = ipv4;
|
ipv6->in6_u.u6_addr32[3] = ipv4;
|
||||||
@@ -87,6 +85,7 @@ static int parse_tcp_ts(struct tcphdr *tcph, void *data_end, __u32 *tsval,
|
|||||||
* and dest, respectively, and 0 will be returned. On failure, -1 will be
|
* and dest, respectively, and 0 will be returned. On failure, -1 will be
|
||||||
* returned.
|
* returned.
|
||||||
*/
|
*/
|
||||||
|
// Has 6 parameters (one too many)
|
||||||
static int parse_tcp_identifier(struct hdr_cursor *nh, void *data_end,
|
static int parse_tcp_identifier(struct hdr_cursor *nh, void *data_end,
|
||||||
bool is_egress, struct flow_address *saddr,
|
bool is_egress, struct flow_address *saddr,
|
||||||
struct flow_address *daddr, __u32 *identifier)
|
struct flow_address *daddr, __u32 *identifier)
|
||||||
@@ -96,6 +95,7 @@ static int parse_tcp_identifier(struct hdr_cursor *nh, void *data_end,
|
|||||||
|
|
||||||
if (parse_tcphdr(nh, data_end, &tcph) < 0)
|
if (parse_tcphdr(nh, data_end, &tcph) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (parse_tcp_ts(tcph, data_end, &tsval, &tsecr) < 0)
|
if (parse_tcp_ts(tcph, data_end, &tsval, &tsecr) < 0)
|
||||||
return -1; //Possible TODO, fall back on seq/ack instead
|
return -1; //Possible TODO, fall back on seq/ack instead
|
||||||
|
|
||||||
@@ -108,20 +108,32 @@ static int parse_tcp_identifier(struct hdr_cursor *nh, void *data_end,
|
|||||||
/*
|
/*
|
||||||
* Attempts to parse the packet limited by the data and data_end pointers,
|
* Attempts to parse the packet limited by the data and data_end pointers,
|
||||||
* to retrieve a protocol dependent packet identifier. If sucessful, the
|
* to retrieve a protocol dependent packet identifier. If sucessful, the
|
||||||
* ipv and identifier of p_id will be set, saddr and daddr (which may be part
|
* pointed to p_id will be filled with parsed information from the packet
|
||||||
* of p_id) will be filled with the source and destionation addresses of the
|
|
||||||
* packet, and 0 will be returned. On failure, -1 will be returned.
|
* packet, and 0 will be returned. On failure, -1 will be returned.
|
||||||
|
* If is_egress saddr and daddr will match source and destination of packet,
|
||||||
|
* respectively, and identifier will be set to the identifer for an outgoing
|
||||||
|
* packet. Otherwise, saddr and daddr will be swapped (will match
|
||||||
|
* destination and source of packet, respectively), and identifier will be
|
||||||
|
* set to the identifier of a response.
|
||||||
*/
|
*/
|
||||||
static int parse_packet_identifier(void *data, void *data_end, bool is_egress,
|
static int parse_packet_identifier(void *data, void *data_end, bool is_egress,
|
||||||
struct packet_id *p_id,
|
struct packet_id *p_id)
|
||||||
struct flow_address *saddr,
|
|
||||||
struct flow_address *daddr)
|
|
||||||
{
|
{
|
||||||
|
int proto, err;
|
||||||
struct hdr_cursor nh = { .pos = data };
|
struct hdr_cursor nh = { .pos = data };
|
||||||
struct ethhdr *eth;
|
struct ethhdr *eth;
|
||||||
struct iphdr *iph;
|
struct iphdr *iph;
|
||||||
struct ipv6hdr *ip6h;
|
struct ipv6hdr *ip6h;
|
||||||
int proto, err;
|
struct flow_address *saddr, *daddr;
|
||||||
|
|
||||||
|
// Switch saddr <--> daddr on ingress to match egress
|
||||||
|
if (is_egress) {
|
||||||
|
saddr = &p_id->flow.saddr;
|
||||||
|
daddr = &p_id->flow.daddr;
|
||||||
|
} else {
|
||||||
|
saddr = &p_id->flow.daddr;
|
||||||
|
daddr = &p_id->flow.saddr;
|
||||||
|
}
|
||||||
|
|
||||||
proto = parse_ethhdr(&nh, data_end, ð);
|
proto = parse_ethhdr(&nh, data_end, ð);
|
||||||
|
|
||||||
@@ -132,18 +144,19 @@ static int parse_packet_identifier(void *data, void *data_end, bool is_egress,
|
|||||||
} else if (proto == bpf_htons(ETH_P_IPV6)) {
|
} else if (proto == bpf_htons(ETH_P_IPV6)) {
|
||||||
p_id->flow.ipv = AF_INET6;
|
p_id->flow.ipv = AF_INET6;
|
||||||
proto = parse_ip6hdr(&nh, data_end, &ip6h);
|
proto = parse_ip6hdr(&nh, data_end, &ip6h);
|
||||||
} else
|
} else {
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
// Add new protocols here
|
// Add new protocols here
|
||||||
if (proto == IPPROTO_TCP)
|
if (proto == IPPROTO_TCP) {
|
||||||
err = parse_tcp_identifier(&nh, data_end, is_egress, saddr,
|
err = parse_tcp_identifier(&nh, data_end, is_egress, saddr,
|
||||||
daddr, &p_id->identifier);
|
daddr, &p_id->identifier);
|
||||||
else
|
if (err)
|
||||||
return -1;
|
return -1;
|
||||||
|
} else {
|
||||||
if (err)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
// Sucessfully parsed packet identifier - fill in IP-addresses and return
|
// Sucessfully parsed packet identifier - fill in IP-addresses and return
|
||||||
if (p_id->flow.ipv == AF_INET) {
|
if (p_id->flow.ipv == AF_INET) {
|
||||||
|
|||||||
@@ -37,8 +37,7 @@ int tc_bpf_prog_egress(struct __sk_buff *skb)
|
|||||||
void *data = (void *)(long)skb->data;
|
void *data = (void *)(long)skb->data;
|
||||||
void *data_end = (void *)(long)skb->data_end;
|
void *data_end = (void *)(long)skb->data_end;
|
||||||
|
|
||||||
if (parse_packet_identifier(data, data_end, true, &p_id,
|
if (parse_packet_identifier(data, data_end, true, &p_id) < 0)
|
||||||
&p_id.flow.saddr, &p_id.flow.daddr) < 0)
|
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
p_ts.timestamp = bpf_ktime_get_ns(); // or bpf_ktime_get_boot_ns
|
p_ts.timestamp = bpf_ktime_get_ns(); // or bpf_ktime_get_boot_ns
|
||||||
|
|||||||
@@ -32,9 +32,7 @@ int xdp_prog_ingress(struct xdp_md *ctx)
|
|||||||
void *data = (void *)(long)ctx->data;
|
void *data = (void *)(long)ctx->data;
|
||||||
void *data_end = (void *)(long)ctx->data_end;
|
void *data_end = (void *)(long)ctx->data_end;
|
||||||
|
|
||||||
// saddr and daddr in reverse order of egress (source <--> dest)
|
if (parse_packet_identifier(data, data_end, false, &p_id) < 0)
|
||||||
if (parse_packet_identifier(data, data_end, false, &p_id,
|
|
||||||
&p_id.flow.daddr, &p_id.flow.saddr) < 0)
|
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
p_ts = bpf_map_lookup_elem(&ts_start, &p_id);
|
p_ts = bpf_map_lookup_elem(&ts_start, &p_id);
|
||||||
|
|||||||
Reference in New Issue
Block a user