iovisor / iovisor/bcc

Routing from one IP to another is not working

Open
#3,653 5 comments 0 reactions 0 assignees View on GitHub
Dominant language
C
Stars
22.7k
Forks
4.1k
Avg merge
10d 4h
Merged PRs (30d)
3

Description

Hi,
I tried below code for testing the IP routing of data packets.

iplist.py -

```
`from bcc import BPF, table
import socket
import struct
import ctypes as ct
import utils
import json
import os
# from ctypes import *
from datetime import datetime
import time
import ipaddress

device = "lo"
src_file = './filter.c'

ip_list = []
ip_list.append(utils.ip_to_uint32('127.0.0.1'))

#open eBPF c source code
with open(src_file, 'r') as f:
file = ''.join(f.readlines())

b = BPF(text=file)
functions = b.load_func('udpfilter', BPF.XDP)
print("eBPF progam loaded")
b.attach_xdp(device, functions, 0)
print("eBPF program attached")

#load blacklist map
blacklist= b.get_table("iplist")
blacklist.clear()

#put the to block ip addreses in map
for item in ip_list:
blacklist[ct.c_uint32(item)] = ct.c_uint32(utils.ip_to_uint32('127.0.0.2'))

while True:
try:
b.trace_print()
time.sleep(5)
except KeyboardInterrupt:
print("Removing filter from device")
break

b.remove_xdp(device, 0)
print('done')`

```
filter.c -
```

`#define KBUILD_MODNAME "filter"
#include
#include
#include
#include
#include

BPF_TABLE("percpu_hash", uint32_t, uint32_t, iplist, 6524288);

int udpfilter(struct xdp_md *ctx) {
bpf_trace_printk("got a packet\n");
void *data = (void *)(long)ctx->data;
void *data_end = (void *)(long)ctx->data_end;
struct ethhdr *eth = data;
if ((void*)eth + sizeof(*eth) <= data_end) {
struct iphdr *ip = data + sizeof(*eth);
if ((void*)ip + sizeof(*ip) <= data_end) {
if (ip->protocol == IPPROTO_UDP) {
struct udphdr *udp = (void*)ip + sizeof(*ip);
if ((void*)udp + sizeof(*udp) <= data_end) {
uint32_t *value;
value = iplist.lookup(&(ip->daddr));
// bpf_trace_printk("%d value\n", *value);
if(value){
bpf_trace_printk("ip daddr found in the ip blacklist %lu\n",*value);
// bpf_trace_printk("port of the %lu\n",*value);

// *value += 1;
ip->daddr = *value;
bpf_trace_printk("ip daddr changed to %lu\n", ip->daddr);

}
}
}
}
}
return XDP_PASS;
}`

```
But this is not routing the packet coming at 127.0.0.1 to 127.0.0.2
I tested it with nc (netcat) commands. Is there something wrong in the code?

Also, sometimes it prints correct updated address(127.0.0.2) in uint32 format in ip->daddr and sometimes it randomly prints 0 as updated daddr.

Contributor guide

No contributing guide indexed for this repository

Research direction

Read iplist.py and filter.c first, then reproduce the reported netcat test while inspecting the BPF trace output. Compare the observed destination-address updates and packet behavior with the intended transfer from 127.0.0.1 to 127.0.0.2; done means the behavior is consistent and the zero-address result is explained or eliminated.

Written by the indexing model from the issue text.

Assessment

Tech stack
c, linux, python
Domain
networking, operating-systems
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.