11#![ no_std]
22#![ no_main]
33#![ allow( non_camel_case_types) ]
4+ #![ allow( non_snake_case) ]
45
56extern crate rex;
67
7- use core:: mem:: { offset_of , size_of, swap} ;
8+ use core:: mem:: { size_of, swap} ;
89
910use rex:: sched_cls:: * ;
1011use rex:: utils:: * ;
1112use rex:: xdp:: * ;
12- use rex:: { rex_printk, rex_tc, rex_xdp} ;
13+ use rex:: { read_field , rex_printk, rex_tc, rex_xdp} ;
1314
1415pub mod common;
1516pub mod maps;
@@ -33,37 +34,36 @@ macro_rules! swap_field {
3334fn fast_paxos_main ( obj : & xdp , ctx : & mut xdp_md ) -> Result {
3435 let header_len =
3536 size_of :: < ethhdr > ( ) + size_of :: < iphdr > ( ) + size_of :: < udphdr > ( ) ;
36- let iphdr_start = size_of :: < ethhdr > ( ) ;
37- let iphdr_end = iphdr_start + size_of :: < iphdr > ( ) ;
38- let udphdr_end = iphdr_end + size_of :: < udphdr > ( ) ;
39-
40- let protocol_start = iphdr_start + offset_of ! ( iphdr, protocol) ;
41- let protocol = convert_slice_to_struct :: < u8 > (
42- & ctx. data_slice [ protocol_start..protocol_start + size_of :: < u8 > ( ) ] ,
43- ) ;
44-
45- match u8:: from_be ( * protocol) as u32 {
37+ let iphdr_base = size_of :: < ethhdr > ( ) ;
38+ let iphdr_end = iphdr_base + size_of :: < iphdr > ( ) ;
39+
40+ match u8:: from_be ( read_field ! (
41+ ctx. data_slice,
42+ iphdr_base,
43+ iphdr,
44+ protocol,
45+ u8
46+ ) ) as u32
47+ {
4648 IPPROTO_TCP => {
4749 // NOTE: currently we only take care of UDP memcached
4850 }
4951 IPPROTO_UDP => {
50- let port_start = iphdr_end + offset_of ! ( udphdr, dest) ;
51- let port = u16:: from_be ( * convert_slice_to_struct :: < u16 > (
52- & ctx. data_slice [ port_start..port_start + size_of :: < u16 > ( ) ] ,
52+ let port = u16:: from_be ( read_field ! (
53+ ctx. data_slice,
54+ iphdr_end,
55+ udphdr,
56+ dest,
57+ u16
5358 ) ) ;
59+
5460 let payload = & mut ctx. data_slice [ header_len..] ;
5561
5662 // port check, our process bound to 12345.
5763 // don't have magic bits...
58- if port != 12345 || payload. len ( ) < MAGIC_LEN + size_of :: < u64 > ( ) {
59- return Ok ( XDP_PASS as i32 ) ;
60- }
61-
62- // NOTE: currently, we don't support reassembly.
63- if payload[ 0 ] != 0x18 ||
64- payload[ 1 ] != 0x03 ||
65- payload[ 2 ] != 0x05 ||
66- payload[ 3 ] != 0x20
64+ if port != PAXOS_PORT ||
65+ payload. len ( ) < MAGIC_LEN + size_of :: < u64 > ( ) ||
66+ !payload. starts_with ( & MAGIC_BITS )
6767 {
6868 return Ok ( XDP_PASS as i32 ) ;
6969 }
@@ -79,44 +79,39 @@ fn fast_paxos_main(obj: &xdp, ctx: &mut xdp_md) -> Result {
7979
8080#[ rex_tc]
8181fn fast_broad_cast_main ( obj : & sched_cls , skb : & mut __sk_buff ) -> Result {
82- let mut header_len =
82+ let header_len =
8383 size_of :: < iphdr > ( ) + size_of :: < ethhdr > ( ) + size_of :: < udphdr > ( ) ;
84- let iphdr_start = size_of :: < ethhdr > ( ) ;
85- let iphdr_end = iphdr_start + size_of :: < iphdr > ( ) ;
84+ let iphdr_base = size_of :: < ethhdr > ( ) ;
85+ let iphdr_end = iphdr_base + size_of :: < iphdr > ( ) ;
8686
8787 // check if the packet is long enough
8888 if skb. data_slice . len ( ) <= header_len {
8989 return Ok ( TC_ACT_OK as i32 ) ;
9090 }
9191
92- let protocol_start = iphdr_start + offset_of ! ( iphdr, protocol) ;
93- let protocol = convert_slice_to_struct :: < u8 > (
94- & skb. data_slice [ protocol_start..protocol_start + size_of :: < u8 > ( ) ] ,
95- ) ;
96- match u8:: from_be ( * protocol) as u32 {
92+ match u8:: from_be ( read_field ! (
93+ skb. data_slice,
94+ iphdr_base,
95+ iphdr,
96+ protocol,
97+ u8
98+ ) ) as u32
99+ {
97100 IPPROTO_UDP => {
98- // only port 12345 is allowed
99- let port_start = iphdr_end + offset_of ! ( udphdr, dest) ;
100- let port = u16:: from_be ( * convert_slice_to_struct :: < u16 > (
101- & skb. data_slice [ port_start..port_start + size_of :: < u16 > ( ) ] ,
101+ let port = u16:: from_be ( read_field ! (
102+ skb. data_slice,
103+ iphdr_end,
104+ udphdr,
105+ dest,
106+ u16
102107 ) ) ;
103- if port != 12345 {
104- return Ok ( TC_ACT_OK as i32 ) ;
105- }
106-
107- // check for the magic bits
108- header_len += MAGIC_LEN + size_of :: < u64 > ( ) ;
109108
110- if skb. data_slice . len ( ) < header_len {
111- rex_printk ! ( "data_slice.len() < header_len\n " ) . ok ( ) ;
112- return Ok ( TC_ACT_OK as i32 ) ;
113- }
114- let payload = & skb. data_slice ;
115-
116- if payload[ 0 ] != 0x18 ||
117- payload[ 1 ] != 0x03 ||
118- payload[ 2 ] != 0x05 ||
119- payload[ 3 ] != 0x20
109+ let payload = & skb. data_slice [ header_len..] ;
110+ // check for the magic bits and Paxos port
111+ // only port 12345 is allowed
112+ if port != PAXOS_PORT ||
113+ payload. len ( ) < MAGIC_LEN + size_of :: < u64 > ( ) ||
114+ !payload. starts_with ( & MAGIC_BITS )
120115 {
121116 return Ok ( TC_ACT_OK as i32 ) ;
122117 }
0 commit comments