Regarding filling struct net_device structure - linux-kernel

I have a doubt regarding struct net_device in linux kernel.
Every frame in linux kernel is represented in skbuff structure. It has an instance to struct net_device which tells about the interface or physical port from which packet is received or to be transmitted.
In struct net_device we have a variable "struct net_bridge_port" which is related to port of a bridge (if enabled).
My doubt is struct net_device structure should be filled by device driver but how can it fill information regarding the "struct net_bridge_port" at device driver level ?
Thanks in advance

I don't know what kernel version you're looking at. But in the latest version (3.3-rc1 at the moment), struct net_bridge_port is only used in the bridging code in net/bridge. Everything relating to bridging is filled in by the bridge driver when an interface is added to a bridge, so there is nothing for the low-level network device driver to fill in.

Related

Linux driver: MFD over PCI

I am writing a driver for a PCI device. The device is a custom development FPGA based device. The FPGA has multiple "devices" on board. I want my driver to create the proper interfaces for those devices.
A certain part of the device will use our own "part". But for I2C busses, I would like to use the already available opencores driver. In the past I had to add the I2C compatible property to the correct "device" in my DTS under my FPGA device (FPGA to CPU was SPI).
Now this has to go over PCI.
The kernel uses my FPGA driver and probes, also created the "own part" as chardev. the I2C opencores drivers ->probe() functions seems not to be called when I create a MFD-cell with the correct compatible property. The cell is added, but never probed.
I use Linux kernel v4.9 on a 64-bit ARM based CPU.
struct x_my_dev {
struct list_head x_my_dev;
struct mfd_cell *mfd_cell;
struct device_node *of_node;
struct property *compat_prop;
struct resource *irq_resource;
struct platform_devive *pdev;
};
...
struct x_my_dev *my_dev;
...
ret = mfd_add_devices(priv->dev, PLATFORM_DEVID_NONE,
my_dev->mfd_cell, 1, NULL, irq_base, NULL)
if (ret) {
dev_err(priv->dev, "Failed to add mfd cell\n");
goto err_mfd_add;
}
...
Already checked if the opencores driver is available in the kernel
The kernel /sys/class/my_fpga/device/I2C_bus/ has only 'driver_override', 'modalias', 'power', 'subsystem' and 'uevent'. Nothing that shows what drivers needs to be used.

What is the purpose of class and class device?

I followed some tutorials that explained how to write Linux kernel modules and I am a bit confused. Even after reading the official "documentation", I have poor understanding of the concepts.
After creating a character device (register_chrdev), I see it is common to use a combination of the following functions:
class_create
class_device_create
device_create
I was not able to understand, what is a class, device and, class device and driver?
Which one of these actually responsible to create an entry under /proc/?
Rather than going into what's a class, or what's a device (I'm no expert in Linux kernel), I will address the question as follows.
After creating the character device, you want to be able to access it from the user space. To do this, you need to add a device node under /dev. You can do this in two ways.
Use mknod to manually add a device node (old)
mknod /dev/<name> c <major> <minor>
OR
Use udev
This is where the class_create and device_create or class_device_create (old) come in.
To notify udev from your kernel module, you first create a virtual device class using
struct class * class_create(owner, name)
Now, the name will appear in /sys/class/<name>.
Then, create a device and register it with sysfs.
struct device *device_create(struct class *class, struct device *parent,
dev_t devt, void *drvdata, const char *fmt, ...)
Now, device name will appear in /sys/devices/virtual/<class name>/<device name> and /dev/<device name>
It's not clear what you are asking about the /proc entry.
After your module is loaded, it will appear in /proc/modules (do a cat /proc/modules to see it). And, after you allocate the device numbers, say with
int register_chrdev_region(dev_t first, unsigned int count, char *name)
, the name will appear in /proc/devices (do a cat /proc/devices to see it).
And, please check the kernel sources for these functions as well, as they provide a good description of what they do in their comments.
The good old LDD3 does not provide these mechanisms, but it's a very good source.

Explanation of struct ieee80211_local in Linux kernel

Can anybody explain me the ieee80211_local structure and its members?
The structure is defined in /net/mac80211/ieee80211_i.h of the Linux source code, somewhere near line no. 930, it may vary with different kernel versions.
According to a presentation by Daniel Camps Mur struct ieee80211_local "…contains information about the real hardware, and is created when the interface is first added."
In another set of slides by Johannes Berg it is stated that the struct "represents a wireless device." On the same slide, you can find a statement about the element ieee80211_hw "…is the part of ieee80211_local that is visible to drivers."
Interestingly, the struct is not mentioned in the 802.11 subsystems documentation by Johannes Berg.
Looking at a source code cross reference of the Linux kernel, you can see that the
ieee80211_local struct is never used outside of the mac80211 part. Therefore, I think that it is indeed an internally used representation of a wireless device from mac80211's point of view.
In contrast, you can see that the ieee80211_hw element is used in both mac80211 and various wireless device drivers which underlines that it is used to communicate between mac80211 and drivers.
BTW, the struct was introduced with the very first commit of ieee80211_i.h by Jiri Benc in 2007.
If you need to know more details about the struct and its members, it looks like you want to do some development at the mac80211 code. I would suggest to get in touch with the active developers. The Linux wireless mailing list may be a good starting point for that.

What does actually cdev_add() do? in terms of registering a device to the kernel

What does cdev_add() actually do? I'm asking terms of registering a device with the kernel.
Does it add the pointer to cdev structure in some map which is indexed by major and minor number? How exactly does this happen when you say the device is added/registered with the kernel. I want to know what steps the cdev_add takes to register the device in the running kernel. We create a node for user-space using mknod command. Even this command is mapped using major and minor number. Does registration also do something similar?
cdev_add registers a character device with the kernel. The kernel maintains a list of character devices under cdev_map
static struct kobj_map *cdev_map;
kobj_map is basically an array of probes, which in this case is the list of character devices:
struct kobj_map {
struct probe {
struct probe *next;
dev_t dev;
unsigned long range;
struct module *owner;
kobj_probe_t *get;
int (*lock)(dev_t, void *);
void *data;
} *probes[255];
struct mutex *lock;
};
You can see that each entry in the list has the major and minor number for the device (dev_t dev), and the device structure (in the form of kobj_probe_t, which is a kernel object, which represents a cdev in this case). cdev_add adds your character device to the probes list:
int cdev_add(struct cdev *p, dev_t dev, unsigned count)
{
...
error = kobj_map(cdev_map, dev, count, NULL,
exact_match, exact_lock, p);
When you do an open on a device from a process, the kernel finds the inode associated to the filename of your device (via namei function). The inode has the major a minor number for the device (dev_t i_rdev), and flags (imode) indicating that it is a special (character) device. With this it can access the cdev list I explained above, and get the cdev structure instantiated for your device. From there it can create a struct file with the file operations to your cdev, and install a file descriptor in the process's file descriptor table.
This is what actually 'registering' a character device means and why it needs to be done. Registering a block device is similar. The kernel maintains another list for registered gendisks.
You can read Linux Device Driver. It is a little bit old, but the main ideas are the same. It is difficoult to explain a simple operation like cdev_add() and all the stuff around in few lines.
I suggest you to read the book and the source code. If you have trouble to navigate your source code, you can use some tag system like etags + emacs, or the eclipse indexer.
Please see the code comments here:
cdev_add() - add a char device to the system 464 *
#p: the cdev structure for the device 465 * #dev: the first device
number for which this device is responsible 466 * #count: the number
of consecutive minor numbers corresponding to this 467 *
device 468 * 469 * cdev_add() adds the device represented by #p to
the system, making it 470 * live immediately. A negative error code
is returned on failure. 471 */ `
the immediate answer to any such question is read the code. Thats what Linus say.
[edit]
the cdev_add basically adds the device to the system. What it means essentially is that after the cdev_add operation your new device will get visibility through the /sys/ file system. The function does all the necessary house keeping activities related to that particularly the kobj reference to your device will get inserted at its position in the object hierarchy. If you want to get more information about it, I would suggest some reading around /sysfs/ and struct kboj

How to modify struct sk_buff

I have to write a vpn module. First of all, I have wrote a kernel module that modifies all the incoming and outgoing TCP packets. It uses netfilter hooks. For the incoming packets, I have modified the bytes between (struct sk_buff)->data and (struct sk_buff)->tail pointers by incrementing them by one. For the outgoing packets, I have modified the bytes between (struct sk_buff)->data and (struct sk_buff)->tail pointers by decrementing them by one.
However, I tried to establish a TCP connection between localhost and localhost (by means of netcat) and I had not succeeded. Can you tell me what I am doing wrong? Need I modify some other fields from the struct sk_buff structure?
Is it possible to implement my simple vpn module only from kernel space?(thus without using special libraies such as libnetfilter_queue)?
Thank you.
Yes, you can do this without using libnetfilter. But given the limited information that you've provided about your project it's hard to give a good recommendation as to how to go about fixing your issue. Here's some references that should help.
1) I would recommend you take a look at the TUN/TAP interface driver APIs. This will allow you to implement your code in application space rather than kernel. See openvpn for a great example of this type of VPN.
If you're interested in doing more advanced kernel space hooking...
2) Check this article out on hooking into netfilter netfilter kernel hooks

Resources