Call trace
forward a packet.
1 | > ip_rcv_finish |
1 | > > > > ip_mkroute_input |
In struct Qdisc, there are two similar fileds.
running flag is stored in __state of struct Qdisc, NOT state.
Every time, when we send a packet from qdisc, the running flag is
set by qdisc_run_begin, and after that, it is removed by qdisc_run_end.
1 | 84 unsigned long state; |
why need busylock?
We think it as a ideal and simple case:
1 | > dev_queue_xmit |
In this part, only the framework is prepared for qdisc,
and the noop_qdisc is set as default.
netdev_queues.for example: intel igb hardware has 8 hardware tx queue,
and nic driver create 8 corresponding struct netdev_queue
in the _tx of struct net_device.
mq_qdiscThe mq_qdisc is attached to the corresponding device.
In mq_qdisc private field, a default qdisc will be
create for each NIC’s hardware queue.
This is done in mq_init.
The default qdisc is pfifo_fast_ops.
mq_qdisc to netdev_queue.In mq_attach, these qdiscs are attatched to correspondingstruct netdev_queue.
Here only trace with the case mq_qdisc.
When dev is up, dev_open is called, which will call dev_activate.
Qdisc_ops is the core of a Qdisc.All kinds of the Qdisc_ops are linked in a list by qdisc_base.
The key item of different Qdisc_ops is id[IFNAMSIZ].
Note: the list is a Singly-linked list, not a common list of kernel.
1 | 158 struct Qdisc_ops { |
qdisc_base1 | 134 /* The list of all installed queueing disciplines. */ |
Two packets will be proessed by tcp server side:
内核版本 v6.14
1 | => tcp_v4_rcv(struct sk_buff *skb) |
tcp_request_sock_ops: 是一个结构体的名字,同时又是一个变量的名字。icsk_accept_queue: 在结构体struct inet_connection_sock里的这个队列并不在保存半链接队列的 req socket,而是计数。For the packet to localhost, ip_local_deliver_finish will be the
last funciton called by network layer.
In ip_local_deliver_finish, it will be process the protocol
hander of a array element of inet_protos according the protocol value
in IPv4 header.
IPv6 is very similar vs IPv4 except the name is a bit different.