네트워크 데이터가 애플리케이션에서 하드웨어까지, 또는 반대로 하드웨어에서 애플리케이션까지 흐르는 과정은 다음과 같다.
프로토콜 레이어에서 인터페이스 dev_queue_xmit()는 데이터 전송에 사용되고 netif_rx()는 데이터 수신에 사용된다.
물리계층을 거친 후 device 에서 읽은 프레임이 프로토콜 스택으로 어떻게 들어오고 반대로 프로토콜 스택에서 캡슐화된 프레임이 어떻게 나가는지 분석해보자. (커널 4.14.76 버전 기반)
드라이버 관점에서는 먼저 인터럽트를 다뤄야한다.
Interrupts
인터럽트 처리는 데이터 링크 계층의 전송을 분석하는 출발점이다.
예를 들어 drivers/net/ethernet/intel/i40e는 Intel의 i40e 드라이버로 Intel의 40Gbps 네트워크 어댑터에서 사용된다.
i40e 드라이버에서 프레임 수신의 시작점은 인터럽트 핸들러가 호출되면서 시작된다.
- i40e_napi_poll
- 수신된 패킷을 처리
- Intel NIC는 NAPI (New API) 기반으로 동작하며, 소프트웨어 인터럽트로 전환
- 패킷은 RX 큐(Receive Queue)에서 읽어와 상위 계층으로 전달
int i40e_napi_poll(struct napi_struct *napi, int budget)
{
struct i40e_q_vector *q_vector =
container_of(napi, struct i40e_q_vector, napi);
...
// RX 큐에서 패킷을 처리
i40e_for_each_ring(ring, q_vector->rx) {
int cleaned = i40e_clean_rx_irq(ring, budget_per_ring);
work_done += cleaned;
/* if we clean as many as budgeted, we must not be done */
if (cleaned >= budget_per_ring)
clean_complete = false;
}
...
// 작업이 끝났으면 NAPI 종료
napi_complete_done(napi, work_done);
return min(work_done, budget - 1);
}
- i40e_clean_rx_irq
- RX 인터럽트를 처리하여 수신 패킷을 NAPI 버퍼로 복사
- RX 큐에서 DMA를 통해 데이터가 메모리로 전송된 후, 이를 커널의 네트워크 스택으로 전달
프레임을 전송할 충분한 공간이 생기면, i40e 드라이버는 netif_wake_queue를 호출해 전송을 재개한다.
- i40e_xmit_frame_ring
- 네트워크 스택에서 전달된 프레임을 TX 큐(Transmit Queue)에 추가
- TX 큐가 가득 차면 netif_stop_queue를 호출해 전송을 일시 중지
static netdev_tx_t i40e_xmit_frame_ring(struct sk_buff *skb,
struct i40e_ring *tx_ring)
{
// TX 링에 충분한 공간이 있는지 확인하고, 부족하면 전송을 중단
if (i40e_maybe_stop_tx(tx_ring, count + 4 + 1)) {
tx_ring->tx_stats.tx_busy++;
return NETDEV_TX_BUSY;
}
// DMA 매핑 및 데이터 전송
if (i40e_tx_map(tx_ring, skb, first, tx_flags, hdr_len,
td_cmd, td_offset))
goto cleanup_tx_tstamp;
// 전송 실패 시 에러 처리 및 패킷 드롭
out_drop:
dev_kfree_skb_any(first->skb);
first->skb = NULL;
}
Receive Livelock
Device Polling
NAPI
주요 Data Structure
Netfilter Framework
References
- https://doc-en.rvspace.org/VisionFive2/PG_Ethernet/JH7110_SDK/network_device_framework.html
- https://bootlin.com/pub/conferences/2021/fosdem/chevallier-network-performance-in-the-linux-kernel/chevallier-network-performance-in-the-linux-kernel.pdf
- https://balodeamit.blogspot.com/2013/10/receive-side-scaling-and-receive-packet.html
- ㅇㄹㅇㄹ
'네트워크 보안 > 네트워크' 카테고리의 다른 글
NAPI (0) | 2024.11.18 |
---|---|
네트워크 디바이스 드라이버별 벤더 NIC (0) | 2024.11.18 |
커널 네트워크 스택 #1 NIC 드라이버에서 패킷 수신 (0) | 2024.11.18 |
커널 네트워크 스택 #0 초기화 (0) | 2024.11.17 |
strongswan #5 IKE SA INIT, IKE_AUTH, CHILD_SA 설정 (0) | 2024.11.10 |