Post

[Linux] Socket buffer descriptors

개요

Linux Kernel에서 sk_buff라는 구조체를 이용해서 network packet을 처리하게 됩니다. 그래서 해당 포스터에서 sk_buff라는 Socket buffer descriptors에 대해서 설명드리겠습니다.

sk_buff struct

sk_buffinclude/linux/skbuff.h에 정의되어 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
struct sk_buff {
	union {
		struct {
			/* These two members must be first to match sk_buff_head. */
			struct sk_buff		*next;
			struct sk_buff		*prev;

			union {
				struct net_device	*dev;
				/* Some protocols might use this space to store information,
				 * while device pointer would be NULL.
				 * UDP receive path is one user.
				 */
				unsigned long		dev_scratch;
			};
		};
		struct rb_node		rbnode; /* used in netem, ip4 defrag, and tcp stack */
		struct list_head	list;
		struct llist_node	ll_node;
	};

...

/* only usable after checking ->active_extensions != 0 */
	struct skb_ext		*extensions;
#endif
};

정말 많은 변수들이 선언되어 있지만, Elixir에서 찾아보면 주석으로 각 멤버에 대한 설명이 있기 때문에 생략하겠습니다.

우선 전체적인 sk_buff 구조는 아래 사진에서 잘 설명하고 있습니다. 이 중, 중요한 멤버 변수에 대해서 간단한게 설명드리겠습니다.

0sk_buff 구조

  1. nextprev: 이 두 포인터는 연결 리스트에서 sk_buff를 관리하는 데 사용됩니다. 여러 패킷이 연결된 경우, 리스트를 탐색하거나 조작할 때 사용됩니다.
  2. tstamp: 타임스탬프를 나타내며, 패킷이 생성된 시간을 기록합니다. 네트워크 디버깅 및 분석에 사용될 수 있습니다.
  3. sk: sk_buff가 속한 소켓을 가리키는 포인터입니다. 소켓은 네트워크 연결을 나타내며, sk_buff는 해당 소켓에서 발생한 데이터를 나타냅니다.
  4. dev: 패킷이 수신되거나 송신되는 네트워크 디바이스를 가리키는 포인터입니다. 네트워크 인터페이스와 관련이 있습니다.
  5. data: 패킷의 실제 데이터(가변 길이 데이터)를 포함하는 영역입니다.

💡 head <= data <= tail <= end 구조를 항상 유지해야합니다.

  1. head: frag buffer(저장 공간)의 시작 점을 가리키는 포인터입니다.
  2. tail: frag buffer의 저장 유효 공간 끝을 가리키는 포인터입니다.
  3. end: sbk의 저장 공간의 맨 마지막을 가리키는 포인터입니다.

💡 즉, sk_buff는 네트워크로 전송되는 패킷의 데이터와 각 Layer 별 헤더를 포함하고 있고 패킷이 단편화되서 전송되기 때문에 frag buffer를 관리하며 데이터를 송수신 받는 역할을 수행합니다.

참고 사이트

This post is licensed under CC BY 4.0 by the author.