Which Is The Correct Way to Register a New Net_Device

Which is the correct way to register a new net_device?

Yea, you missed one element in struct net_device_ops
Add .ndo_start_xmit also, And the function must return NETDEV_TX_OK or NETDEV_TX_BUSY.

use as follows

static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev)
{
return NETDEV_TX_OK;
}

And also change the open as

static int veth_open(struct net_device *dev)
{
memcpy(dev->dev_addr, "\0ABCD0", ETH_ALEN);
netif_start_queue(dev);
return 0;
}

Then in veth_ops

static struct net_device_ops veth_ops = {
.ndo_init = veth_dev_init,
.ndo_open = veth_open,
.ndo_stop = veth_close,
.ndo_start_xmit = veth_xmit,
.ndo_do_ioctl = veth_ioctl,
};

Then after inserting the module

give ifconfig my_dev 192.168.10.98 ...

What does dev_net_set do in Linux?

http://man7.org/linux/man-pages/man8/ip-netns.8.html

A network namespace is logically another copy of the network stack,
with its own routes, firewall rules, and network devices.

So for_each_net is looping over these namespaces and creating a copy of all "per net" network devices in each one.

Use ip netns list to determine whether you are using network namespaces. Often they are not used, so drivers do not necessarily need to use dev_net_set.

register_netdevice_notifier callback does not provide valid net_device

From what I can see from LXR, you need to call netdev_notifier_info_to_dev on the last parameter to get your net_device * (see here)

corrupted pointer in 'net_device'

"The bug is somewhere else. "

The second device should not interact with the existing one. If you register_netdev with an existing name, nevertheless the ndo_init virtual function is called first before the condition is detected and -EEXIST is returned. Maybe your init function does something nasty involving some global variables. (For example, does the code assume there is one device, and stash a global pointer to it during initialization?)

NetFilterHook: Displaly Interface Name

In the hook function, there is parameters const struct net_device *in and const struct net_device *out.
You can print it by:

printk(KERN_INFO "%s\n", out->name);

or:

printk(KERN_INFO "%s\n", in->name);

Note: You need to check if is null.

About the second question, you can use in the hook function in strcmp(in->name, "eth0"), and then decide drop or accept.

How to filter and intercept Linux packets by using net_dev_add() API?

You are making your module handle all ethernet packets. Linux will send packets to all matching protocol handlers. Since IP is already registered in your kernel, both your module and ip_rcv will receive all SKBs with IP headers.

You cannot change this behaviour without changing the kernel code. One possibility is to create a netfilter module instead. This way, you can intercept the packet after the ip_rcv function and drop it if you want to (in Netfilters PREROUTING hook).

Here is a small Netfilter module which I extracted from some code I had already written. This module is unfinished, but the main stuff are in place.

#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>

// Handler function
static unsigned int my_handler (
unsigned int hook,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
return NF_ACCEPT;
// or
return NF_DROP;
}

// Handler registering struct
static struct nf_hook_ops my_hook __read_mostly = {
.hook = my_handler,
.pf = NFPROTO_IPV4,
.hooknum = (1 << NF_INET_PRE_ROUTING),
.priority = NF_IP_PRI_FIRST // My hook will be run before any other netfilter hook
};

int my_init() {
int err = nf_register_hook (&my_hook);
if (err) {
printk (KERN_ERR "Could not register hook\n");
}
return err;
}

how does the tcp/ip stack get the net_device interface in linux

The hierarchy is as follows

struct inet_protosw (internet protocols) has a pointer to a struct member proto (protocol)

struct sock has a pointer to a struct member proto (protocol)

struct sock has member to a struct member sk_buff_head

struct sk_buff_head has two pointer to struct members to sk_buff (one called next, one called prev)

struct sk_buff has a pointer to struct member net_device.

I don't believe you register the net_device with inet_protosw directly.

First inet_init registers the built in network protocols by calling proto_register, then it calls inet_register_protosw to initialise the protocols, then it initialises the various inet modules (ip,tcp,icmp,etc).

The interface responsible with linking the protocols and the device later has the register_netdevice and unregister_netdevice, which do what the sound like and register and unregister network devices with kernel. To send a packet from a protocol through a device use dev_queue_xmit and netif_rx receives a packet passes from the device layer to the network layer, it then calls netif_rx_schedule to schedule the packet for further processing.

Resources and documentation on the organisation / workflow include:

  • Anatomy of the Linux Networking Stack
  • Linux Networking Kernel
  • The Linux Kernel
  • Network Data Flow through Kernel
  • Kernel Flow
  • Linux Networking Internals
  • Linux Device Drivers
  • How SKBs work
  • Writing Network Drive Drivers for Linux

why is exported net device xmit call causing kernel crash?

You're passing a structure on the stack to the register function, which is then storing a pointer to it (the copy on the stack). As soon as you return from the register function, the structure on the stack is destroyed. Then later you try to call a function via the now-reused space on the stack.

stand_alone_module_register ought to accept a pointer to a a structure (and the caller should pass the address of its structure). Then it's fine to store the pointer for later use.



Related Topics



Leave a reply



Submit