Skip to content

Commit 2d61340

Browse files
committed
epbf: send the whole packet header
1 parent 30a332d commit 2d61340

File tree

3 files changed

+29
-134
lines changed

3 files changed

+29
-134
lines changed

oryx-ebpf/Cargo.lock

Lines changed: 4 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

oryx-ebpf/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ homepage = "https://github.com/pythops/oryx"
1111
aya-ebpf = "0.1.0"
1212
aya-log-ebpf = "0.1.0"
1313
oryx-common = { path = "../oryx-common" }
14-
network-types = "0.0.6"
14+
network-types = { git = "https://github.com/vadorovsky/network-types.git", rev = "e0ee8d5" }
1515

1616
[[bin]]
1717
name = "oryx"

oryx-ebpf/src/main.rs

Lines changed: 24 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
#![no_std]
22
#![no_main]
33

4-
use core::mem;
5-
use core::net::IpAddr;
6-
74
use aya_ebpf::{
85
bindings::TC_ACT_PIPE,
96
macros::{classifier, map},
@@ -12,14 +9,11 @@ use aya_ebpf::{
129
};
1310

1411
use network_types::{
12+
arp::ArpHdr,
1513
eth::{EthHdr, EtherType},
16-
icmp::IcmpHdr,
17-
ip::{IpProto, Ipv4Hdr, Ipv6Hdr},
18-
tcp::TcpHdr,
19-
udp::UdpHdr,
14+
ip::{IpHdr, IpProto, Ipv4Hdr, Ipv6Hdr},
2015
};
21-
22-
use oryx_common::{IcmpPacket, IcmpType, IpPacket, TcpPacket, UdpPacket};
16+
use oryx_common::RawPacket;
2317

2418
#[map]
2519
static DATA: RingBuf = RingBuf::with_byte_size(4096 * 40, 0);
@@ -33,125 +27,8 @@ pub fn oryx(ctx: TcContext) -> i32 {
3327
}
3428

3529
#[inline]
36-
fn ptr_at<T>(ctx: &TcContext, offset: usize) -> Result<*const T, ()> {
37-
let start = ctx.data();
38-
let end = ctx.data_end();
39-
let len = mem::size_of::<T>();
40-
41-
if start + offset + len > end {
42-
return Err(());
43-
}
44-
45-
Ok((start + offset) as *const T)
46-
}
47-
48-
#[inline]
49-
fn parse_ipv4_packet(ctx: &TcContext) -> Result<IpPacket, ()> {
50-
let header: Ipv4Hdr = ctx.load(EthHdr::LEN).map_err(|_| ())?;
51-
52-
let dst_ip: IpAddr = header.dst_addr().into();
53-
54-
let src_ip: IpAddr = header.src_addr().into();
55-
56-
match header.proto {
57-
IpProto::Tcp => {
58-
let tcphdr: *const TcpHdr = ptr_at(ctx, EthHdr::LEN + Ipv4Hdr::LEN)?;
59-
let src_port = u16::from_be(unsafe { (*tcphdr).source });
60-
let dst_port = u16::from_be(unsafe { (*tcphdr).dest });
61-
62-
let packet = TcpPacket {
63-
src_ip,
64-
dst_ip,
65-
src_port,
66-
dst_port,
67-
};
68-
69-
Ok(IpPacket::Tcp(packet))
70-
}
71-
IpProto::Udp => {
72-
let udphdr: *const UdpHdr = ptr_at(ctx, EthHdr::LEN + Ipv4Hdr::LEN)?;
73-
let src_port = u16::from_be(unsafe { (*udphdr).source });
74-
let dst_port = u16::from_be(unsafe { (*udphdr).dest });
75-
let packet = UdpPacket {
76-
src_ip,
77-
dst_ip,
78-
src_port,
79-
dst_port,
80-
};
81-
82-
Ok(IpPacket::Udp(packet))
83-
}
84-
IpProto::Icmp => {
85-
let icmp_header: *const IcmpHdr = ptr_at(ctx, EthHdr::LEN + Ipv4Hdr::LEN)?;
86-
let icmp_type = u8::from_be(unsafe { (*icmp_header).type_ });
87-
let icmp_type = match icmp_type {
88-
0 => IcmpType::EchoReply,
89-
3 => IcmpType::DestinationUnreachable,
90-
8 => IcmpType::EchoRequest,
91-
_ => return Err(()),
92-
};
93-
94-
let packet = IcmpPacket {
95-
src_ip,
96-
dst_ip,
97-
icmp_type,
98-
};
99-
Ok(IpPacket::Icmp(packet))
100-
}
101-
_ => Err(()),
102-
}
103-
}
104-
105-
#[inline]
106-
fn parse_ipv6_packet(ctx: &TcContext) -> Result<IpPacket, ()> {
107-
let header: Ipv6Hdr = ctx.load(EthHdr::LEN).map_err(|_| ())?;
108-
109-
let dst_ip: IpAddr = header.dst_addr().into();
110-
let src_ip: IpAddr = header.src_addr().into();
111-
112-
match header.next_hdr {
113-
IpProto::Tcp => {
114-
let tcphdr: *const TcpHdr = ptr_at(ctx, EthHdr::LEN + Ipv6Hdr::LEN)?;
115-
Ok(IpPacket::Tcp(TcpPacket {
116-
src_ip,
117-
dst_ip,
118-
src_port: u16::from_be(unsafe { (*tcphdr).source }),
119-
dst_port: u16::from_be(unsafe { (*tcphdr).dest }),
120-
}))
121-
}
122-
123-
IpProto::Udp => {
124-
let udphdr: *const UdpHdr = ptr_at(ctx, EthHdr::LEN + Ipv6Hdr::LEN)?;
125-
Ok(IpPacket::Udp(UdpPacket {
126-
src_ip,
127-
dst_ip,
128-
src_port: u16::from_be(unsafe { (*udphdr).source }),
129-
dst_port: u16::from_be(unsafe { (*udphdr).source }),
130-
}))
131-
}
132-
133-
IpProto::Ipv6Icmp => {
134-
let icmp_header: *const IcmpHdr = ptr_at(ctx, EthHdr::LEN + Ipv6Hdr::LEN)?;
135-
let icmp_type = match u8::from_be(unsafe { (*icmp_header).type_ }) {
136-
129 => IcmpType::EchoReply,
137-
1 => IcmpType::DestinationUnreachable,
138-
128 => IcmpType::EchoRequest,
139-
_ => return Err(()),
140-
};
141-
142-
Ok(IpPacket::Icmp(IcmpPacket {
143-
src_ip,
144-
dst_ip,
145-
icmp_type,
146-
}))
147-
}
148-
_ => Err(()),
149-
}
150-
}
151-
152-
#[inline]
153-
fn submit(packet: IpPacket) {
154-
if let Some(mut buf) = DATA.reserve::<IpPacket>(0) {
30+
fn submit(packet: RawPacket) {
31+
if let Some(mut buf) = DATA.reserve::<RawPacket>(0) {
15532
unsafe { (*buf.as_mut_ptr()) = packet };
15633
buf.submit(0);
15734
}
@@ -163,12 +40,28 @@ fn process(ctx: TcContext) -> Result<i32, ()> {
16340

16441
match ethhdr.ether_type {
16542
EtherType::Ipv4 => {
166-
submit(parse_ipv4_packet(&ctx)?);
43+
let header: Ipv4Hdr = ctx.load(EthHdr::LEN).map_err(|_| ())?;
44+
match header.proto {
45+
IpProto::Tcp | IpProto::Udp | IpProto::Icmp => {
46+
submit(RawPacket::Ip(IpHdr::V4(header)));
47+
}
48+
_ => {}
49+
}
16750
}
16851
EtherType::Ipv6 => {
169-
submit(parse_ipv6_packet(&ctx)?);
52+
let header: Ipv6Hdr = ctx.load(EthHdr::LEN).map_err(|_| ())?;
53+
match header.next_hdr {
54+
IpProto::Tcp | IpProto::Udp | IpProto::Icmp => {
55+
submit(RawPacket::Ip(IpHdr::V6(header)));
56+
}
57+
_ => {}
58+
}
59+
}
60+
EtherType::Arp => {
61+
let header: ArpHdr = ctx.load(EthHdr::LEN).map_err(|_| ())?;
62+
submit(RawPacket::Arp(header));
17063
}
171-
_ => return Ok(TC_ACT_PIPE),
64+
_ => {}
17265
};
17366

17467
Ok(TC_ACT_PIPE)

0 commit comments

Comments
 (0)