SEC("xdp")
 int rx(struct xdp_md *ctx)
 {
-       void *data, *data_meta;
+       void *data, *data_meta, *data_end;
+       struct ipv6hdr *ip6h = NULL;
+       struct ethhdr *eth = NULL;
+       struct udphdr *udp = NULL;
+       struct iphdr *iph = NULL;
        struct xdp_meta *meta;
        u64 timestamp = -1;
        int ret;
 
+       data = (void *)(long)ctx->data;
+       data_end = (void *)(long)ctx->data_end;
+       eth = data;
+       if (eth + 1 < data_end) {
+               if (eth->h_proto == bpf_htons(ETH_P_IP)) {
+                       iph = (void *)(eth + 1);
+                       if (iph + 1 < data_end && iph->protocol == IPPROTO_UDP)
+                               udp = (void *)(iph + 1);
+               }
+               if (eth->h_proto == bpf_htons(ETH_P_IPV6)) {
+                       ip6h = (void *)(eth + 1);
+                       if (ip6h + 1 < data_end && ip6h->nexthdr == IPPROTO_UDP)
+                               udp = (void *)(ip6h + 1);
+               }
+               if (udp && udp + 1 > data_end)
+                       udp = NULL;
+       }
+
+       if (!udp)
+               return XDP_PASS;
+
+       /* Forwarding UDP:8080 to AF_XDP */
+       if (udp->dest != bpf_htons(8080))
+               return XDP_PASS;
+
        /* Reserve enough for all custom metadata. */
 
        ret = bpf_xdp_adjust_meta(ctx, -(int)sizeof(struct xdp_meta));