Failed to call bpf_l3_csum_replace() twice for IPIP tunnel

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



hello, I am trying to modify the src addr (both inner and outer) of IPIP tunnel.

this is the testing code:

=======================================

void *data = (void *)(long)skb->data;
void *data_end = (void *)(long)skb->data_end;

struct ethhdr *eth = data;
struct iphdr *ip_outer = (void *)(eth + 1);

if (ip_outer->ihl != 5 || ip_outer + 1 > data_end)
        return;

struct iphdr *ip_inner = (void *)(ip4_outer + 1);

if (ip_inner->ihl != 5 || ip_inner + 1 > data_end)
    return;

src = 0x11111111;

/* First I modify the inner ip */
bpf_l3_csum_replace(skb, IP4_CSUM_OFF + sizeof(struct iphdr),
ip_inner->saddr, src, sizeof(src));
bpf_skb_store_bytes(skb, IP4_SRC_OFF + sizeof(struct iphdr), &src,
sizeof(src), 0);

/* Second I modify the outer ip */
bpf_l3_csum_replace(skb, IP4_CSUM_OFF, ip_outer->saddr, src, sizeof(src));
bpf_skb_store_bytes(skb, IP4_SRC_OFF, &src, sizeof(src), 0);

========================================

I found that I could only modify one of the src addr (inner or outer).
If both, the kernel always rejected the code at the first
bpf_l3_csum_replace():

========================================

Prog section '__xxxxx' rejected: Permission denied (13)!
 - Type:         3
 - Instructions: 171 (0 over limit)
 - License:      GPL

.....

96: (85) call bpf_l3_csum_replace#10
97: (61) r4 = *(u32 *)(r7 +0)
 R0=inv(id=0) R6=ctx(id=0,off=0,imm=0)
R7=map_value(id=0,off=0,ks=4,vs=4,imm=0) R8=inv(id=0) R9=inv(id=0)
R10=fp0
98: (61) r3 = *(u32 *)(r9 +26)
R9 invalid mem access 'inv'

Error fetching program/map!
Unable to load program

========================================

I tried to validate the pointer again before the second modification.
But nothing good has happened.

if (ip_outer->ihl != 5 || ip_outer + 1 > data_end)
        return;
/* Second I modify the outer ip */
bpf_l3_csum_replace(skb, IP4_CSUM_OFF, ip_outer->saddr, src, sizeof(src));
bpf_skb_store_bytes(skb, IP4_SRC_OFF, &src, sizeof(src), 0);


Any idea?
Thanks very much



[Index of Archives]     [Linux Networking Development]     [Fedora Linux Users]     [Linux SCTP]     [DCCP]     [Gimp]     [Yosemite Campsites]

  Powered by Linux