xdp-project / xdp-tutorial

XDP tutorial
2.33k stars 562 forks source link

Modify outer IP header of GENEVE encapsulated packets #376

Open ahihi8z8z opened 7 months ago

ahihi8z8z commented 7 months ago

For my project, I want to insert a timestamp option into outer IP header of a GENEVE encapsulated packet. I tried with a BPF program which attached into egress TC hook of a GENEVE vport of OVS. My BPF program is below but it inserts option field into inner ip header. So, I have 2 questions:

  1. Can use BPF to insert IP option into IP outer header?
  2. If it is possible, How to do it?
    
    #include <linux/pkt_cls.h>
    #include <linux/if_ether.h>
    #include <linux/ip.h>
    #include <arpa/inet.h>

ifndef __section

define __section(NAME) \

    __attribute__((section(NAME), used))

endif

ifndef __inline

define __inline \

    inline __attribute__((always_inline))

endif

ifndef lock_xadd

define lock_xadd(ptr, val) \

    ((void)__sync_fetch_and_add(ptr, val))

endif

ifndef BPF_FUNC

define BPF_FUNC(NAME, ...) \

    (*NAME)(__VA_ARGS__) = (void *)BPF_FUNC_##NAME

endif

define OPT_LEN 4

define IP_HDL 20

static int BPF_FUNC(skb_adjust_room, struct sk_buff *skb, __s32 len_diff, u32 mode, __u64 flags); //static int BPF_FUNC(skb_vlan_push, struct __sk_buff *skb, uint16_t proto, uint16_t vlan_tci);

section("egress") int push_tun_opt(struct sk_buff skb) { struct ethhdr eth; struct iphdr iph; __be32 opt; volatile void data, data_end; int ret = TC_ACT_OK; //skb_vlan_push(skb,0x8100,0x1); skb_adjust_room(skb, size(OPT_LEN), BPF_ADJ_ROOM_NET, BPF_F_ADJ_ROOM_ENCAP_L3_IPV4); data = (void )(long)skb->data; data_end = (void )(long)skb->data_end; eth = (void )data; iph = (void )(eth+1); opt = (void )(iph+1); if ((void )(opt+1) > data_end) goto out; *opt = 0x1234abcd; out: return ret; }

char license[] section("license") = "GPL";