Download presentation
Presentation is loading. Please wait.
1
소켓버퍼(sk_buff) 이재연
2
목 차 Sk_buff 소개 Linux Network 전체흐름 Sk_buff 자료구조 Skb함수 skb 주요함수
목 차 Sk_buff 소개 Linux Network 전체흐름 Sk_buff 자료구조 Skb함수 skb 주요함수 skb_clone skb_copy alloc_skb dev_alloc_skb skb_unlink Sk_buff_head의 linked list관련 함수 skb_queue_head skb_queue_tail skb_insert skb_append skb_dequeue skb_dequeue_tail Data버퍼 관련함수 skb_put skb_push skb_reserve skb_pull skb_trim 기타함수
3
Sk_buff 소개 sk_buff를 사용하는 목적 sk_buff의 특징
많은 네트워크 프로토콜 계층을 가지고, 각각이 다른 것의 서비스를 사용하는 방법의 문제중의 하나는, 각 프로토콜이 전송하는 데이터의 프로토콜 헤더와 꼬리를 붙이고, 받은 데이터를 처리할 때 이를 제거해야 한다는 것이다. 이는 각 프로토콜 계층마다 특별한 프로토콜 헤더와 꼬리를 찾아야 하므로 프로토콜 사이에 데이터 버퍼를 전달하는 것을 어렵게 만든다. 그래서 생각해 낸 방법중의 하나는 각 계층마다 버퍼를 복사하는 것이지만, 이는 매우 비효율적이다. 리눅스는 프로토콜 계층 사이와 네트워크 디바이스 드라이버간에 데이터를 송수신하기 위해 네트워크로 전송되는 패킷을 나타내는 자료구조로 sk_buff라는 소켓 버퍼 구조체를 사용한다. sk_buff의 특징 포인터와 길이 항목을 가지고 있어서 각 프로토콜 계층이 표준 함수를 통해 응용프로그램 데이터를 다룰 수 있게 한다. 이 sk_buff를 단위로 데이터를 하위의 링크 계층으로 보내고, 다시 그곳에서 sk_buff의 단위로 데이터를 받아서, 해당하는 소켓 구조체에 연결지어주게 된다. 하나 이상의 sk_buff로 연결된 이중연결 list형태를 가지게 된다. include/linux/skbuff.h에 정의되어 있다.
4
리눅스 네트워킹 레이어는 아래 그림과 같은 구조로 되어 있다
리눅스 네트워킹 레이어는 아래 그림과 같은 구조로 되어 있다. 각 네트워크 카드 별로 Device driver가 있으며, 네트워크 카드에 독립적인, 즉 공통부분이 되는 device Independence Routine이 있다. 그 위쪽으로 네트워크 프로토콜 계층인 IP계층이 있다. 그 위에는 UDP, TCP와 같은 Transport layer가 있다. 계속해서 INET socket layer가 있으며, BSD socket layer가 그 위에 올라가 있다. 이 BSD socket layer를 통하여 Application process와 커널 내의 네트워킹 코드 간에 데이터 송수신 및 제어를 하게 된다. 하드웨어 인터럽트가 걸렸을 때, 오랜 시간동안 이를 처리하고 있으면 안 되기 때문에, bottom Half Handler라는 별도의 루틴을 두어 네트워킹의 나머지 부분을 처리하도록 한 것이다. 즉, 하드웨어 인터럽트는 아주 중요한 부분만 처리한 후 종료된다. 대신에 mark_bh(NET_BH)를 통해 BH Handler가 나머지 부분을 처리하도록 하고 있는 것이다. Mark_bh(NET_BH)로 마킹을 해두면, 스케쥴러는 net_bh()함수를 수행하도록 한다. Net_bh()함수는 보낼 패킷이 있는지 확인후에, backlog버퍼에서 sh_buff를 가져온다. Sk_buff에 나타나 있는 type값을 보고 IP라면, ip_rcv()를 호출한다.
5
SK_Buff 자료구조 source ip address를 알려면 skb->h.th.source
dest ip address를 알려면 skb->h.th.dest
6
Sk_buff 자료구조 Head : 데이터 영역의 시작 End : 데이터 영역의 끝 Data : 현재 프로토콜 데이터의 시작
tail end 실제 전송할 혹은 받은 데이터 Head : 데이터 영역의 시작 End : 데이터 영역의 끝 Data : 현재 프로토콜 데이터의 시작 Tail : 현재 프로토콜 데이터의 끝 Len : 현재 프로토콜 패킷의 길이(tail – data) Truesize : 상대적인 데이터 버퍼의 전체 길이 (end- head)
7
Sk_buff 자료구조
8
Skb함수 skb 주요함수 Sk_buff Data copy Sk_buff Data copy
static inline void skb_clone(struct sk_buff_head *list, struct sk_buff *newsk) 실제 데이터 공간은 그대로 두고, skbuff구조체만 복사하는 기능을 한다. static inline void skb_copy(struct sk_buff_head *list, struct sk_buff *newsk) skbuff 구조체뿐만 아니라 실제 데이터까지 복사하는 함수이다 . Sk_buff Data copy extern __inline__ void __skb_queue_head(struct sk_buff_head *list, struct sk_buff *newsk) skbuff list의 머리에 새로운 skbuff를 넣는 함수이다. extern __inline__ void __skb_queue_tail(struct sk_buff_head *list, struct sk_buff *newsk) 리스트의 tail에 skbuff를 삽입하는 함수이다. Sk_buff Data copy
9
Skb함수 skb 주요함수 extern struct sk_buff *alloc_skb(unsigned int size, int priority) 새로운 skbuff를 할당한다 extern __inline__ struct sk_buff *dev_alloc_skb(unsigned int length) 주어진 길이에 16을 더한 공간으로 sk_buff를 할당한다. extern __inline__ void skb_unlink(struct sk_buff *skb) . ********* h : head d : data t : tail e : end Sk_buff Sk_buff list 1 skb 2
10
Skb함수 Sk_buff_head의 linked list관련 함수 list newsk 1 2 list 1 2 newsk
static inline void skb_queue_head(struct sk_buff_head *list, struct sk_buff *newsk) skbuff list의 head에 새로운 skbuff를 넣는 함수이다. static inline void skb_queue_tail(struct sk_buff_head *list, struct sk_buff *newsk) skbuff list의 tail에 새로운 skbuff를 넣는 함수이다. . list newsk 1 2 list 1 2 newsk extern __inline__ void __skb_queue_head(struct sk_buff_head *list, struct sk_buff *newsk) skbuff list의 머리에 새로운 skbuff를 넣는 함수이다. extern __inline__ void __skb_queue_tail(struct sk_buff_head *list, struct sk_buff *newsk) 리스트의 tail에 skbuff를 삽입하는 함수이다.
11
Skb함수 Sk_buff_head의 linked list관련 함수 list prev newsk next list 1 old
static inline void skb_insert(struct sk_buff *old, struct sk_buff *newsk) Prev와 next사이에 newsk를 삽입하는 함수이다. static inline void skb_append(struct sk_buff *old, struct sk_buff *newsk) Old바로 뒤에 newsk를 추가하는 함수이다. . list prev newsk next list 1 old newsk
12
Skb함수 Sk_buff_head의 linked list관련 함수 list 1 2 3 1 return list 1 2 3
static inline struct sk_buff *skb_dequeue(struct sk_buff_head *list) List큐로부터 head부분의 skbuff를 꺼낸다. static inline struct sk_buff *skb_dequeue_tail(struct sk_buff_head *list) List큐로부터 tail부분의 skbuff를 꺼낸다. . list 1 2 3 1 return list 1 2 3 3 return
13
Skb함수 Data버퍼 관련함수 extern __inline__ unsigned char *skb_put(struct sk_buff *skb, unsigned int len) 실제데이터크기를 len만큼 늘린다 . 1) 2) 3)
14
Skb함수 Data버퍼 관련함수 extern __inline__ unsigned char *skb_push(struct sk_buff *skb, unsigned int len) 데이터공간의 앞부분을 len만큼 확장한다. . 1) 2)
15
Skb함수 Data버퍼 관련함수 extern __inline__ void skb_reserve(struct sk_buff *skb, unsigned int len) 데이터공간의 전체를 len만큼 뒤로 옮긴다. . 1) 2) 3)
16
Skb함수 Data버퍼 관련함수 extern __inline__ unsigned char * skb_pull(struct sk_buff *skb, unsigned int len) 데이터공간의 앞부분을 len만큼 잘라버린다. .
17
Skb함수 Data버퍼 관련함수 extern __inline__ unsigned char * skb_trim(struct sk_buff *skb, unsigned int len) 데이터 공간의 크기를 len으로 한다. . 1) 2)
18
Skb함수 기타함수(리스트) extern __inline__ struct sk_buff *skb_peek(struct sk_buff_head *list_) list의 next가 가리키는 sk_buff를 리턴한다. 즉 리스트의 맨처음 sk_buff를 리턴한다. extern __inline__ struct sk_buff *skb_peek_tail(struct sk_buff_head *list_) list의 맨 마지막 sk_buff를 리턴한다. extern __inline__ void skb_queue_head_init(struct sk_buff_head *list) skbuffer list를 초기화 한다. list가 비어 있을 때, prev나 next값은 list 자체를 가리킨다. extern __inline__ int *skb_queue_empty(struct sk_buff_head *list) 가장 첫번째 버퍼인지 여부(List의 next포인터가 자기자신을 가리키면, empty상태 리턴) extern __inline__ __u32 skb_queue_len(struct sk_buff_head *list_) list의 갯수를 리턴한다. extern __inline__ void skb_queue_purge(struct sk_buff_head *list) list내를 전부 지운다 extern __inline__ void skb_orphan(struct sk_buff *skb) skb의 소켓변수 sk를 NULL로 만든다 static inline void kfree_skb(struct sk_buff *skb) Skb_buff구조체 free
19
Skb함수 기타함수(데이터) extern __inline__ int skb_headroom(struct sk_buff *skb) Headroom size를 반환 extern __inline__ int skb_tailroom(struct sk_buff *skb) tailroom size를 반환 extern __inline__ atomic_t *skb_datarefp(struct sk_buff *skb) 데이터의 끝부분(end)을 반환 extern __inline__ int skb_cloned(struct sk_buff *skb) skb가 clone되었는지 검사하는 함수 extern __inline__ int skb_shared(struct sk_buff *skb) skb버퍼의 데이터공간이 공유되고 있는지 여부를 검사하는 함수 extern __inline__ struct sk_buff *skb_unshare(struct sk_buff *skb, int pri) clone된 skb를 copy한 것으로 바꾸어, 공유하지 않도록 하는 함수. tcpdump나 forward 등등에서 유효하다. extern __inline__ struct sk_buff *skb_cow(struct sk_buff *skb, unsigned int headroom) 데이터공간의 앞부분에 16바이트 단위의 headroom을 확보한다
20
참고문헌 The Linux Networking architecture 리눅스커널완전분석 2003년 유종욱 세미나 자료
lxr에 있는 소스( 소켓자료구조.pdf (
Similar presentations