LINUX.ORG.RU

Сообщения Axrud

 

Не вызывается rx_handler в модуле ядра

Форум — Development

Добрый день, прошу помощи. Написал простейший драйвер с функцией перехвата пакетов на интерфейсе(drop_packet). Зарегистрировал ее с помощью netdev_rx_handler_register. И для пакетов, пришедших извне(при посылке с ноутбука на интерфейс) drop_packet дергается исправно, но при посылке пакета, сформированного локально(пробовал scapy и ping) drop_packet не вызывается.


#include <linux/module.h>
#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/ctype.h>
#include <linux/uaccess.h>
#include <linux/string.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/ip.h>
#include <linux/if_ether.h>
#include <net/arp.h>

#define MODULE_NAME "drop_packets"
#define VERSION "1.0.0"
#define PFX MODULE_NAME": "
#define TARGET_DEV "enp0s8"
#define DBG_PRINT(fmt, args...) \
    do \
    { \
        printk(KERN_ERR PFX "%s(%d)-%s:\n"fmt"\n", __FILE__,__LINE__,__FUNCTION__,##args); \
    } while (0)

typedef struct {
    struct net_device *ndev;
    int promisc_old, promisc_count;
    int old_netpoll;

} netif_info;

static netif_info pt_netif;

#define netif_info_get_rcu(dev) \
    (rcu_dereference(dev->rx_handler_data))

static rx_handler_result_t drop_packet(struct sk_buff **pskb)
{
    struct sk_buff *const skb = *pskb;
    DBG_PRINT("LALALA %u", skb->len);
    kfree_skb(*pskb);
    *pskb = NULL;
    return RX_HANDLER_CONSUMED;
}

static int __init the_init(void)
{
    int err = 0;
    struct net *const net = current->nsproxy->net_ns;
    struct net_device *const ndev = dev_get_by_name(net, TARGET_DEV);
    DBG_PRINT("dev_name=%s %s %i", TARGET_DEV, NULL != ndev ? "OK" : "FAIL", ndev->addr_len);

    pt_netif.ndev = ndev;
    pt_netif.promisc_old = ndev->flags & IFF_PROMISC;
    pt_netif.promisc_count = 0;
    pt_netif.old_netpoll = ndev->priv_flags & IFF_DISABLE_NETPOLL;
    DBG_PRINT("priv_flags is %hx %hx", ndev->priv_flags, ndev->flags);

    rtnl_lock();
    if(!pt_netif.promisc_old) {
        err = dev_set_promiscuity(ndev, 1);
        DBG_PRINT("dev_set_promiscuity(1) %i", err);
        DBG_PRINT("priv_flags is %x %x", ndev->priv_flags, ndev->flags);
    }
    if(!pt_netif.old_netpoll) {
        ndev->priv_flags |= IFF_DISABLE_NETPOLL;
    }

    //ndev->priv_flags |= IFF_DISABLE_NETPOLL;
    //ndev->flags |= IFF_PROMISC;
    err = netdev_rx_handler_register(ndev, drop_packet, &pt_netif);
    rtnl_unlock();
    return err;
}

static void __exit the_exit(void)
{
    int err;
    struct net_device *const ndev = pt_netif.ndev;
    rtnl_lock();
    if(!pt_netif.promisc_old) {
        err = dev_set_promiscuity(ndev, -1);
        DBG_PRINT("dev_set_promiscuity(-1) %i", err);
        DBG_PRINT("priv_flags is %x %x", ndev->priv_flags, ndev->flags);
    }
    if(!pt_netif.old_netpoll) {
        ndev->priv_flags &= ~(IFF_DISABLE_NETPOLL);
    }
    netdev_rx_handler_unregister(ndev);
    rtnl_unlock();

    dev_put(ndev);
}

module_init(the_init);
module_exit(the_exit);

MODULE_VERSION(VERSION);
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Serg");
MODULE_DESCRIPTION("drop all packets received from specified net device");

 ,

Axrud
()

RSS подписка на новые темы