Just starting - display some packet info

This commit is contained in:
Herbert Wolverson 2024-02-05 11:28:31 -06:00
parent 3ab165a591
commit f7c9e82173
3 changed files with 73 additions and 51 deletions

View File

@ -278,11 +278,11 @@ static __always_inline bool dissector_find_l3_offset(
static __always_inline struct tcphdr *get_tcp_header(struct dissector_t *dissector)
{
if (dissector->eth_type == ETH_P_IP)
if (dissector->eth_type == ETH_P_IP && dissector->ip_header.iph->protocol == IPPROTO_TCP)
{
return (struct tcphdr *)((char *)dissector->ip_header.iph + (dissector->ip_header.iph->ihl * 4));
}
else if (dissector->eth_type == ETH_P_IPV6)
else if (dissector->eth_type == ETH_P_IPV6 && dissector->ip_header.ip6h->nexthdr == IPPROTO_TCP)
{
return (struct tcphdr *)(dissector->ip_header.ip6h + 1);
}
@ -424,4 +424,4 @@ static __always_inline bool dissector_find_ip_header(
default:
return false;
}
}
}

View File

@ -47,60 +47,39 @@ struct {
__uint(map_flags, BPF_F_NO_PREALLOC);
} map_ip_to_cpu_and_tc_recip SEC(".maps");
// Determine the effective direction of a packet
static __always_inline int determine_effective_direction(int direction, __be16 internet_vlan, struct dissector_t * dissector) {
if (direction < 3) {
return direction;
} else {
if (dissector->current_vlan == internet_vlan) {
return 1;
} else {
return 2;
}
}
}
// Performs an LPM lookup for an `ip_hash.h` encoded address, taking
// into account redirection and "on a stick" setup.
static __always_inline struct ip_hash_info * setup_lookup_key_and_tc_cpu(
// The "direction" constant from the main program. 1 = Internet,
// 2 = LAN, 3 = Figure it out from VLAN tags
// This must have been pre-calculated by `determine_effective_direction`.
int direction,
// Pointer to the "lookup key", which should contain the IP address
// to search for. Prefix length will be set for you.
struct ip_hash_key * lookup_key,
// Pointer to the traffic dissector.
struct dissector_t * dissector,
// Which VLAN represents the Internet, in redirection scenarios? (i.e.
// when direction == 3)
__be16 internet_vlan,
// Out variable setting the real "direction" of traffic when it has to
// be calculated.
int * out_effective_direction
struct dissector_t * dissector
)
{
lookup_key->prefixlen = 128;
// Normal preset 2-interface setup, no need to calculate any direction
// related VLANs.
if (direction < 3) {
lookup_key->address = (direction == 1) ? dissector->dst_ip :
dissector->src_ip;
*out_effective_direction = direction;
struct ip_hash_info * ip_info = bpf_map_lookup_elem(
&map_ip_to_cpu_and_tc,
lookup_key
);
return ip_info;
} else {
if (dissector->current_vlan == internet_vlan) {
// Packet is coming IN from the Internet.
// Therefore it is download.
lookup_key->address = dissector->dst_ip;
*out_effective_direction = 1;
struct ip_hash_info * ip_info = bpf_map_lookup_elem(
&map_ip_to_cpu_and_tc,
lookup_key
);
return ip_info;
} else {
// Packet is coming IN from the ISP.
// Therefore it is UPLOAD.
lookup_key->address = dissector->src_ip;
*out_effective_direction = 2;
struct ip_hash_info * ip_info = bpf_map_lookup_elem(
&map_ip_to_cpu_and_tc_recip,
lookup_key
);
return ip_info;
}
}
lookup_key->address = (direction == 1) ? dissector->dst_ip :
dissector->src_ip;
struct ip_hash_info * ip_info = bpf_map_lookup_elem(
&map_ip_to_cpu_and_tc,
lookup_key
);
return ip_info;
}
// For the TC side, the dissector is different. Operates similarly to

View File

@ -98,19 +98,62 @@ int xdp_prog(struct xdp_md *ctx)
// is requested.
if (!dissector_find_l3_offset(&dissector, vlan_redirect)) return XDP_PASS;
if (!dissector_find_ip_header(&dissector)) return XDP_PASS;
int effective_direction = determine_effective_direction(
direction,
internet_vlan,
&dissector
);
// Per-Flow RTT Tracking
//bpf_debug("Checking for TCP");
struct tcphdr * tcp = get_tcp_header(&dissector);
if (tcp != NULL) {
if (tcp + 1 < dissector.end)
{
//bpf_debug("TCP found");
if (tcp->syn) {
// We've found a SYN packet, so the connection is just starting.
if (effective_direction == 1) {
bpf_debug("SYN->WAN, %d <-> %d", tcp->seq, tcp->ack_seq);
} else {
bpf_debug("SYN->LAN, %d <-> %d", tcp->seq, tcp->ack_seq);
}
} else if (tcp->fin) {
// We've found a FIN packet, so the connection is expecting to end.
bpf_debug("FIN packet, %d", effective_direction);
} else if (tcp->rst) {
// We've found a RST packet, so the connection is being reset.
bpf_debug("RST packet, %d", effective_direction);
} else if (tcp->ack) {
// We've found an ACK packet, so the connection is established.
void *nh_pos = (tcp + 1) + (tcp->doff << 2);
bool is_valid = nh_pos - dissector.start < ctx->data_end - ctx->data;
if (is_valid) {
//bpf_debug("ACK packet");
if (effective_direction == 1) {
// To the internet
bpf_debug("ACK->WAN, %d <-> %d", tcp->seq, tcp->ack_seq);
} else {
// To the LAN
bpf_debug("ACK->LAN, %d <-> %d", tcp->seq, tcp->ack_seq);
}
}
}
}
}
#ifdef VERBOSE
bpf_debug("(XDP) Spotted VLAN: %u", dissector.current_vlan);
#endif
// Determine the lookup key by direction
struct ip_hash_key lookup_key;
int effective_direction = 0;
struct ip_hash_info * ip_info = setup_lookup_key_and_tc_cpu(
direction,
effective_direction,
&lookup_key,
&dissector,
internet_vlan,
&effective_direction
&dissector
);
#ifdef VERBOSE
bpf_debug("(XDP) Effective direction: %d", effective_direction);