Reputation: 4233
I'm working on tracking network activity per process. Towards this, I've added some fields to struct sock
to keep track of the PID when the socket is created. This would then allow me to update the task_struct
when the data is finally sent/received. However, I'm having difficulty in identifying which network interface is being used.
I see that struct sk_buff
has a field struct net_device *dev
which references the network interface, but I don't understand how to reference this from struct sock
.
Is it meaningful to assume that a struct sock
is bound to an interface? If so, is there an easy way to reference the network interface that is being used?
Upvotes: 1
Views: 445
Reputation: 12357
The physical interface is determined dynamically (sort of). The socket (assuming, for simplicity, a TCP session) just represents a connection between local [IP, port] and remote [IP, pot]. So sending data to the remote requires a routing operation to be performed. This is done by looking in the kernel routing table and determining either a direct machine for the next hop (e.g. if RemoteIP is in a local subnet), or by looking for a fallback ("default gateway") as the next hop. Logically, that operation is done on a packet by packet basis, though there is a caching mechanism to prevent it really being done packet by packet.
But it's conceivable that the route/interface being used could change while a connection is ongoing. For example, you might have an established connection already using one interface (due to the default gateway setting), and then the administrator could change the default gateway to point to a different IP address, which could cause packets destined to the remote to be directed out a different interface.
Look at ip_queue_xmit
to see this working. So, yes, there is a binding to the physical interface via the sock->sk_dst_cache
which provides a struct dst_entry
containing the struct net_device
. But it is conceivable that the entry can be invalidated before the next packet is sent.
Upvotes: 1