@@ -60,7 +60,7 @@ void memcpy_var(void *to, void *from, __u64 len) {
60
60
__u8 * t8 = to , * f8 = from ;
61
61
int i ;
62
62
63
- for (i = 0 ; i < len ; i ++ ) {
63
+ for (i = 0 ; i < len && i < MAX_LOOPS ; i ++ ) {
64
64
* t8 ++ = * f8 ++ ;
65
65
}
66
66
@@ -70,7 +70,7 @@ void memset_var(void *d, __u8 c, __u64 len) {
70
70
__u8 * d8 = d ;
71
71
int i ;
72
72
73
- for (i = 0 ; i < len ; i ++ ) {
73
+ for (i = 0 ; i < len && i < MAX_LOOPS ; i ++ ) {
74
74
* d8 ++ = c ;
75
75
}
76
76
@@ -84,6 +84,8 @@ static __always_inline int write_dhcp_option_82(void *ctx, int offset,
84
84
85
85
struct dhcp_option_82 option ;
86
86
87
+ static __u8 buf [RAI_OPTION_LEN ];
88
+
87
89
option .t = DHO_DHCP_AGENT_OPTIONS ;
88
90
option .len = sizeof (struct sub_option ) + sizeof (struct sub_option );
89
91
option .circuit_id .option_id = RAI_CIRCUIT_ID ;
@@ -104,15 +106,16 @@ static __always_inline int write_dhcp_option_82(void *ctx, int offset,
104
106
* contains null bytes.
105
107
*/
106
108
107
- char buf [RAI_OPTION_LEN ];
108
109
memset (buf , 0 , sizeof (buf ));
109
110
110
111
int c = VLAN_ASCII_MAX ; /* We will need 4 bytes at most */
111
112
int i = RAI_OPTION_LEN - 1 ;
113
+
112
114
__u16 inner_vlan = vlans -> id [1 ];
113
115
__u16 outer_vlan = vlans -> id [0 ];
114
116
115
117
/* Convert inner VLAN to ASCII */
118
+ #pragma unroll VLAN_ASCII_MAX
116
119
for (c = VLAN_ASCII_MAX ; c > 0 ; c -- ) {
117
120
buf [i -- ] = (inner_vlan % 10 ) + '0' ;
118
121
inner_vlan /= 10 ;
@@ -124,6 +127,7 @@ static __always_inline int write_dhcp_option_82(void *ctx, int offset,
124
127
buf [i -- ] = '.' ;
125
128
126
129
/* Convert outer VLAN to ASCII */
130
+ #pragma unroll VLAN_ASCII_MAX
127
131
for (c = VLAN_ASCII_MAX ; c > 0 ; c -- ) {
128
132
buf [i -- ] = (outer_vlan % 10 ) + '0' ;
129
133
outer_vlan /= 10 ;
@@ -132,10 +136,10 @@ static __always_inline int write_dhcp_option_82(void *ctx, int offset,
132
136
}
133
137
}
134
138
135
-
136
139
buf [i -- ] = '.' ;
137
140
138
141
/* Append interface name */
142
+ #pragma unroll RAI_OPTION_LEN
139
143
for (c = RAI_OPTION_LEN - 1 ; c >= 0 ; c -- ) {
140
144
if (dev [c ] != 0 )
141
145
buf [i -- ] = dev [c ];
@@ -148,8 +152,9 @@ static __always_inline int write_dhcp_option_82(void *ctx, int offset,
148
152
/* Copy resulting interface name to circuit_id */
149
153
if (sizeof (option .circuit_id .val ) == sizeof (buf )) {
150
154
memcpy_var (option .circuit_id .val , buf + i , sizeof (buf ) - i );
155
+ //memcpy_var(option.circuit_id.val, buf, sizeof (buf));
151
156
}
152
-
157
+
153
158
return xdp_store_bytes (ctx , offset , & option , sizeof (option ), 0 );
154
159
}
155
160
@@ -206,10 +211,10 @@ int xdp_dhcp_relay(struct xdp_md *ctx) {
206
211
int res = bpf_xdp_adjust_tail (ctx , delta );
207
212
if (res != 0 ) {
208
213
bpf_printk ("Cannot tail extend packet, delta %i - error code %i" , delta , res );
209
- return XDP_ABORTED ;
214
+ return XDP_PASS ;
210
215
}
211
216
212
- bpf_printk ("Tail extended packet by %i bytes" , delta );
217
+ // bpf_printk("Tail extended packet by %i bytes", delta);
213
218
214
219
void * data_end = (void * ) (long ) ctx -> data_end ;
215
220
void * data = (void * ) (long ) ctx -> data ;
@@ -240,27 +245,34 @@ int xdp_dhcp_relay(struct xdp_md *ctx) {
240
245
int key = 0 ;
241
246
int len = 0 ;
242
247
243
- if (data + 1 > data_end )
244
- return XDP_ABORTED ;
248
+ if (data + 1 > data_end ) {
249
+ bpf_printk ("Empty packet\n" );
250
+ goto out ;
251
+ }
245
252
246
253
nh .pos = data ;
247
254
ether_type = parse_ethhdr_vlan (& nh , data_end , & eth , & vlans );
248
255
/* check for valid ether type */
249
256
if (ether_type < 0 ) {
250
- bpf_printk ("Cannot determine ethertype" );
251
- rc = XDP_ABORTED ;
257
+ bpf_printk ("Cannot determine ethertype\n" );
252
258
goto out ;
253
259
}
260
+
254
261
if (ether_type != bpf_htons (ETH_P_IP )) {
255
- bpf_printk ("Ethertype %# x is not ETH_P_IP" , bpf_ntohs (ether_type ));
262
+ // bpf_printk("Ethertype %x is not ETH_P_IP\n ", bpf_ntohs(ether_type));
256
263
goto out ;
257
264
}
258
265
259
- bpf_printk ("Ethertype %x" , bpf_ntohs (ether_type ));
260
-
266
+ bpf_printk ("Ethertype %x\n " , bpf_ntohs (ether_type ));
267
+
261
268
/* Check at least two vlan tags are present */
269
+ if (vlans .id [0 ] == 0 ) {
270
+ bpf_printk ("No outer VLAN tag set\n" );
271
+ goto out ;
272
+ }
273
+
262
274
if (vlans .id [1 ] == 0 ) {
263
- bpf_printk ("No VLAN tags set" );
275
+ bpf_printk ("No inner VLAN tag set\n " );
264
276
goto out ;
265
277
}
266
278
@@ -287,6 +299,8 @@ int xdp_dhcp_relay(struct xdp_md *ctx) {
287
299
288
300
/* Increase UDP length header */
289
301
udp -> len += bpf_htons (delta );
302
+
303
+ udp -> check = 0 ;
290
304
291
305
/* Read DHCP server IP from config map */
292
306
key = 0 ;
@@ -317,6 +331,7 @@ int xdp_dhcp_relay(struct xdp_md *ctx) {
317
331
// goto out;
318
332
319
333
/* Increment offset by 4 bytes for each VLAN (to accomodate VLAN headers */
334
+ #pragma unroll VLAN_MAX_DEPTH
320
335
for (i = 0 ; i < VLAN_MAX_DEPTH ; i ++ ) {
321
336
if (vlans .id [i ]) {
322
337
@@ -449,7 +464,7 @@ int xdp_dhcp_relay(struct xdp_md *ctx) {
449
464
bpf_printk ("Could not write DHCP option 82 at offset %i" , option_offset );
450
465
return XDP_ABORTED ;
451
466
}
452
-
467
+
453
468
/* Set END option */
454
469
455
470
/* Verifier check */
0 commit comments