基于NXP LS1043 +FPGA ARM64位平台验证网口驱动钩子

发布于:2024-10-18 ⋅ 阅读:(82) ⋅ 点赞:(0)

之前在X86上验证过网口驱动的收发钩子,今天特意把代码放到LS1043单板上验证一下,看是否可行。
单板环境 LINUX 4.19.68
交叉编译器 GCC 7.5.0
CPU NXP LS1043 ARMV8 A53

测试代码如下:

#include   <linux/module.h>
#include   <linux/init.h>
#include   <linux/kernel.h>
#include   <linux/netfilter.h>
#include   <linux/netfilter_ipv4.h>
#include   <linux/ip.h>
#include   <net/ip.h>
#include   <linux/udp.h>
#include   <linux/in.h>
#include   <linux/skbuff.h>
#include   <linux/netdevice.h>
#include   <linux/if_ether.h>
#include   <linux/if.h>


unsigned int lan_tx_hook_fn(void *priv, struct sk_buff *skb, const struct nf_hook_state *state)
{
    const struct ethhdr *ethheader = eth_hdr(skb);
    const struct iphdr *iph = ip_hdr(skb);
    char *tail;

    if (strcmp("eth0", state->out->name))
    {
	//printk(KERN_INFO "state->out->name = %s, len=%d", state->out->name, strlen(state->out->name));
        return NF_ACCEPT;
    }
     
    printk(KERN_INFO "skb->head = 0x%08lx, data = 0x%08lx, tail = 0x%08lx,  end = 0x%08lx", 
	skb->head, skb->data, skb->tail, skb->end);

    tail = __skb_put(skb, 4);
    memset(tail, 0xaa, 4);

    //filter ip    
    if (iph->protocol == 0)
    {
        printk(KERN_INFO "send (%s) pkt protocol:%u, Src: %08x, Dst: %08x, len: %d \n",
            state->out->name, iph->protocol, ntohl(iph->saddr), ntohl(iph->daddr));
        return NF_ACCEPT;
    }

    return NF_ACCEPT;
}

unsigned int lan_rx_hook_fn(void *priv, struct sk_buff *skb, const struct nf_hook_state *state)
{
    const struct iphdr *iph = ip_hdr(skb);

    if (strcmp("eth0", state->in->name))
    {
        return NF_ACCEPT;
    }

    printk(KERN_INFO "skb->len = %d, %d", skb->len, skb->data_len);
     
    //filter ip    
    if (iph->protocol == 0)
    {
        printk(KERN_INFO "recv (%s) pkt protocol:%u, Src: %08x, Dst: %08x, len: %d \n",
            state->in->name, iph->protocol, ntohl(iph->saddr), ntohl(iph->daddr), iph->tot_len);
        return NF_ACCEPT;
    }

    return NF_ACCEPT;
}

//挂载钩子,挂在出口处理的位置
static struct nf_hook_ops nf_lan_hook[] = 
{
    {
        .hook = (nf_hookfn *)lan_tx_hook_fn,
        .pf = PF_INET,
        .hooknum = NF_INET_LOCAL_OUT,//挂载在TX处理报文的节点
        .priority = NF_IP_PRI_FIRST, //最高优先级
    },

    {
        .hook = (nf_hookfn *)lan_rx_hook_fn,
        .pf = PF_INET,
        .hooknum = NF_INET_FORWARD,      //挂载在RX报文的节点
        .priority = NF_IP_PRI_FIRST + 1, // 优先级比第一个低一点
    }
};

static int lan_hook_init(void)
{
    printk(KERN_INFO "lan_hook_init \n");
    
    /*注册钩子*/
    nf_register_net_hooks(&init_net, nf_lan_hook, ARRAY_SIZE(nf_lan_hook));

    return 0;
}

static void lan_hook_exit(void)
{
    printk(KERN_INFO "lan_hook_exit \n");
    
    /*卸载钩子*/
    nf_unregister_net_hooks(&init_net, nf_lan_hook, ARRAY_SIZE(nf_lan_hook));
}

module_init(lan_hook_init);
module_exit(lan_hook_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("bull-man");

MODULE_DESCRIPTION("lan rx/tx filter");

编写Makefile文件,如下

//KDIR是内核编译结果所在路径
KDIR:= /home/xxxx/flexbuild_lsdk1909/build/linux/linux/arm64/LS/output

obj-m :=lan_tx_hook.o

all:
	make -C $(KDIR) M=$(PWD) modules

clean:
	rm -f *.ko *.o *.mod.o *.mod.c *.symvers *.order

编译命令:
make -f Makefile ARCH=arm64

如果没有错误,则产生 lan_tx_hook.ko 内核模块

将内核文件通过TFTP加载到单板上,插入内核。执行效果如下

[root@LSDK tmp]# tftp -r lan_tx_hook.ko -g 10.8.8.114
[root@LSDK tmp]# ls
dbus            lan_tx_hook.ko
[root@LSDK tmp]# chmod 777 lan_tx_hook.ko 
[root@LSDK tmp]# insmod lan_tx_hook.ko 
[  118.406138] lan_tx_hook: loading out-of-tree module taints kernel.
[  118.412586] lan_hook_init 
[root@LSDK tmp]# 
[root@LSDK tmp]# 
[root@LSDK tmp]# 
[root@LSDK tmp]# ping 10.8.8.114
PING 10.8.8.114 (10.8.8.114): 56 data bytes
64 bytes from 10.8.8.114: seq=0 ttl=128 time=0.563 ms
[  133.893739] skb->head = 0xffff80003ccc3400, data = 0xffff80003ccc3450, tail = 0x000000a4,  end = 0x000000c0
64 bytes from 10.8.8.114: seq=1 ttl=128 time=10.098 ms
[  134.893815] skb->head = 0xffff80003ccc3200, data = 0xffff80003ccc3250, tail = 0x000000a4,  end = 0x000000c0
64 bytes from 10.8.8.114: seq=2 ttl=128 time=10.020 ms
^C
--- 10.8.8.114 ping statistics ---

以上总结,注意两点
1、内核模块编译所需要的内核源码路径要设置正确;
2、make的时候需要加ARCH参数,否则编译不过


今日签到

点亮在社区的每一天
去签到