BPF学习笔记(六)-- 使用bpf实现xdp的例子

        本篇文章参考《Linux  Observability with BPF》中第7章的例子,主要功能是借助于ip命令作为前端,对其他主机访问tcp的8000端口进行限制,这里需要使用较新版本的iproute2软件工具包. 

1. 下载编译iproute2 工具包,使用最新的ip命令,支持配置xdp

   git clone git://git.kernel.org/pub/scm/linux/kernel/git/shemminger/iproute2.git 

 在编译iproute2时,需要开启支持libbpf的选项信息,在iproute2目录下配置使用下面的配置选项信息 

  ./configure --libbpf_force=on --LIBBPF_DIR=/usr/local/lib64

        执行上面的命令,可能出现下面的错误信息,

确定libbpf的pk-config配置文件位置,/usr/local/lib64/pkgconfig/libbpf.pc  使用

export PKG_CONFIG_PATH=/usr/local/lib64/pkgconfig/ 导入libbpf的配置文件,

使用pkg-config --list-all | grep libbpf 查看是否配置libbpf

然后执行,make && make install 进行安装。

2. 编写bpf程序

       本bpf程序对于访问本机的tcp的协议的8000端口进行限制,

#include <linux/bpf.h>

#include <linux/if_ether.h>

#include <linux/in.h>

#include <linux/ip.h>

#include <linux/if_packet.h>

#include <bpf/bpf_helpers.h>

#include <linux/if_vlan.h>

#include <linux/types.h>

#include <linux/tcp.h>

#include <linux/udp.h>

#include <bpf/bpf_helpers.h>

#include <bpf/bpf_endian.h>



static __always_inline int get_dport(void *trans_data, void *data_end, int protocol)

{

    struct tcphdr *th;

    struct udphdr *uh;


    switch (protocol) {

        case IPPROTO_TCP:

            th = (struct tcphdr *)trans_data;

            if ((void*)(th + 1) > data_end)

                return -1;

            return th->dest;

        case IPPROTO_UDP:

            uh = (struct udphdr *)trans_data;

            if ((void *)(uh + 1) > data_end)

                return -1;

            return uh->dest;

        default:

            return 0;

    }


}


SEC("mysection")

int myprogram(struct xdp_md *ctx) {

  void *data = (void *)(long)ctx->data;

  void *data_end = (void *)(long)ctx->data_end;

  char fmt[] = "source = %d \n";

  struct iphdr *ip;

  int dport;

  int hdport;

  struct ethhdr *eth = data;

  struct iphdr *iph = data + sizeof(struct ethhdr);


    if ((void *)(iph + 1) > data_end) {

        return XDP_DROP;

    }


  dport = get_dport(iph + 1, data_end,iph->protocol);


  if (dport == -1 || dport == bpf_htons(8000)) {

        bpf_trace_printk(fmt,sizeof(fmt),bpf_ntohs(dport));

      return XDP_DROP;

  }


  return XDP_PASS;

}

char _license [] SEC ("license") = "GPL";

使用下面的命令进行编译:clang -g -c -O2 -target bpf -c program.c -o program.o

编译完成后,使用下面的ip命令对某个网卡进行价值xdp文件。

ip link set dev eth0 xdp obj program.o sec mysection   

通过上面的命令加载后,在接口上出现加载的xdp的类型和ID,表明加载成功。


使用python3 -m http.server在本地主机上其中http服务器,并监听8000端口。

使用另一台主机上使用nmap命令扫描对方监听的端口。nmap -sS 10.9.4.222,扫描结果如下:

ip link set dev eth0 xdp off 关闭加载的xdp程序。再次使用nmap扫描

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值