BPF/XDP ベリファイアに問題があります。UDP パケットをフィルタリングし、パケットの最後にタイムスタンプを書き込もうとしています ( を使用udh->len
)。はネットワーク バイト オーダーであるためudh->len
、最初に「ホスト」バイト オーダーに変換する必要があります。だから私はこのようにそれを試しました:
SEC("xdp_sock")
int xdp_sock_prog(struct xdp_md *ctx) {
const void *data = (void*)(unsigned long)ctx->data;
const void *data_end = (void*)(unsigned long)ctx->data_end;
const struct ethhdr *eth = (struct ethhdr*)(data);
if((void*)eth + sizeof(struct ethhdr) <= data_end) {
if(bpf_ntohs(eth->h_proto) == ETH_P_IP) {
const struct iphdr *iph = (struct iphdr*)(data + sizeof(struct ethhdr));
if((void*)iph + sizeof(struct iphdr) <= data_end) {
if(iph->protocol == IPPROTO_UDP) {
const __u16 iph_sz_in_bytes = iph->ihl * IP_HDR_MULT_IHL;
if((void*)iph + iph_sz_in_bytes <= data_end) {
const struct udphdr *udh = (struct udphdr*)(data + sizeof(struct ethhdr) + iph_sz_in_bytes);
if((void*)udh + sizeof(struct udphdr) <= data_end) {
const __u16 udh_sz_in_bytes = bpf_ntohs(udh->len);
if((void*)udh + udh_sz_in_bytes <= data_end) {
bpf_printk("HELLO!\n");
/* Usually I would start to write the timestamp here */
}
しかし、私は得るmath between pkt pointer and register with unbounded min value is not allowed
。
これが失敗する方法が思いつかなかったのでbpf_ntohs
、テスト目的のためだけに削除しようとしました (そのようには機能しないことはわかっています)。
SEC("xdp_sock")
int xdp_sock_prog(struct xdp_md *ctx) {
const void *data = (void*)(unsigned long)ctx->data;
const void *data_end = (void*)(unsigned long)ctx->data_end;
const struct ethhdr *eth = (struct ethhdr*)(data);
if((void*)eth + sizeof(struct ethhdr) <= data_end) {
if(bpf_ntohs(eth->h_proto) == ETH_P_IP) {
const struct iphdr *iph = (struct iphdr*)(data + sizeof(struct ethhdr));
if((void*)iph + sizeof(struct iphdr) <= data_end) {
if(iph->protocol == IPPROTO_UDP) {
const __u16 iph_sz_in_bytes = iph->ihl * IP_HDR_MULT_IHL;
if((void*)iph + iph_sz_in_bytes <= data_end) {
const struct udphdr *udh = (struct udphdr*)(data + sizeof(struct ethhdr) + iph_sz_in_bytes);
if((void*)udh + sizeof(struct udphdr) <= data_end) {
const __u16 udh_sz_in_bytes = udh->len;
if((void*)udh + udh_sz_in_bytes <= data_end) {
bpf_printk("HELLO!\n");
}
しかし、私は実際にこの方法でプログラムを実行できます-bpf_ntohs
検証エラーが発生する理由はありますか?