IPv4의 일반 경로를 세 갈래로 읽습니다
아래는 Linux v6.18의 일반적인 IPv4 L3 경로를 요약한 개념도입니다. 모든 패킷이 다섯 훅을 순서대로 방문한다는 뜻이 아닙니다. 수신 패킷은 라우팅 결과에 따라 로컬 전달 또는 전달 경로로 나뉘고, 로컬 생성 패킷은 출력 경로로 들어갑니다.
- 외부에서 이 호스트로
PRE_ROUTING → 라우팅 → LOCAL_IN → 로컬 프로토콜 처리
- 이 호스트를 경유
PRE_ROUTING → 라우팅 → FORWARD → POST_ROUTING → 출력
- 이 호스트에서 생성
출력 경로 결정 → LOCAL_OUT → POST_ROUTING → 출력
ip_rcv()는 PRE_ROUTING을, ip_local_deliver()는 필요한 재조립 뒤 LOCAL_IN을 호출합니다. ip_forward()에서는 TTL·MTU 등 앞선 검사에 실패하면 FORWARD에 이르지 못할 수 있습니다. 출력은 __ip_local_out()의 LOCAL_OUT과 ip_output()의 POST_ROUTING을 대조하되, 후자는 재라우팅 플래그에 따른 건너뜀도 확인해야 합니다. 입력 경로 · 전달 경로 · 출력 경로
우선순위는 같은 훅 안의 순서입니다
nf_hook_ops는 callback, protocol family, hook 번호와 priority를 정합니다. 등록할 network namespace도 별도 인자입니다. IPv4 LOCAL_IN의 우선순위가 낮다고 PRE_ROUTING보다 먼저 실행되는 것은 아닙니다. 같은 훅에 등록된 항목은 작은 priority부터 실행하며, 동일 priority 사이의 순서에 정책을 의존하지 않습니다.
| IPv4 기준값 | 값 | 읽을 때의 조건 |
|---|---|---|
| Conntrack defrag / raw | -400 / -300 | 해당 기능이 그 훅에 등록된 경우 |
| Conntrack / mangle | -200 / -150 | 모든 훅에 같은 처리기가 있다는 뜻이 아님 |
| Destination NAT / filter | -100 / 0 | NAT와 필터의 목적·체인 종류를 구분 |
| Security / source NAT | 50 / 100 | family와 hook에 맞는 유효한 위치를 확인 |
이 값은 netfilter_ipv4.h의 기준값이지 bridge family까지 통용되는 고정 실행표가 아닙니다. nftables NAT 체인은 연결의 첫 패킷에 NAT binding을 정하는 용도이므로 모든 패킷을 검사할 필터 체인으로 쓰지 않습니다. v6.18 우선순위 정의 · family·hook별 순서 · 체인 종류와 동일 priority
ACCEPT라고 최종 전달이 보장되지는 않습니다
nf_hook_slow()의 NF_ACCEPT는 다음 등록 훅을 계속 처리하게 합니다. 뒤의 체인이나 경로에서 다시 폐기될 수 있습니다. NF_DROP은 현재 패킷을 해제하고 오류를 반환합니다. NF_QUEUE는 queue 처리 결과에 따라 대기 또는 계속 처리가 결정되며, NF_STOLEN은 callback 쪽이 패킷 소유권을 가져갔음을 뜻합니다. callback이 버퍼를 넘긴 뒤 다시 사용하거나 중복 해제하면 안 됩니다. 등록 순서와 nf_hook_slow() · 기본 verdict 정의
REJECT는 별도의 기본 NF_REJECT verdict가 아닙니다. v6.18의 legacy IPv4 ipt_REJECT target은 설정에 맞는 ICMP 오류 또는 TCP reset 응답을 시도한 뒤 원래 패킷에 NF_DROP을 반환합니다. 응답이 항상 생성·전달된다는 보장도 없습니다. 이 구현 설명을 nftables의 모든 family와 target에 그대로 확장하지 않습니다. IPv4 REJECT target · iptables의 target 판정 처리
훅 로그가 없다고 패킷 손실은 아닙니다
nftables flowtable hit는 ingress 이후의 일반 Netfilter 전달 경로를 우회할 수 있습니다. miss는 일반 경로로 돌아가며 fragment, TCP FIN/RST 등도 예외 처리를 받습니다. 따라서 FORWARD의 카운터 증가가 멈춘 현상을 패킷 손실로 바로 해석하지 않습니다. 기존 NAT 상태도 fast path에서 사용됩니다. v6.18 flowtable 동작과 예외
이 글의 세 경로는 IPv4 L3를 대상으로 합니다. IPv6, bridge, netdev ingress의 훅이나 처리 위치를 같은 그림에 무조건 대입하지 않습니다. callback의 nf_hook_state에는 hook, family, 입출력 장치, socket, network namespace 등이 있지만 priority 필드는 없습니다. 훅 등록 설정과 실행 시 상태를 구분합니다. nf_hook_state와 namespace별 훅
sk_buff의 데이터는 모두 선형 메모리에 있다고 가정할 수 없습니다. IPv4 길이·IHL·fragment 상태와 실제 접근 가능한 헤더 길이를 검증하지 않고 포인터에 오프셋만 더하는 옛 실습 예시를 일반 수신 경로에 적용하지 않습니다. sk_buff의 선형 영역과 fragment
실제 로그와 예상 출력을 구분합니다
Jayanth Ruthala의 Netfilter Hooks — Lab Session 첨부 자료는 5.11.1 실습 환경의 관찰로 읽습니다. 14쪽의 TCP 로그에는 SYN 뒤 RA(reset·acknowledgement)가 보이므로 연결 성립 증거로 해석하지 않습니다. 15쪽의 priority -1/+1 로그 쌍은 해당 실습에서 확인한 순서이며, 모든 네트워크 환경의 실행 순서를 검증한 결과가 아닙니다.
6쪽의 PRE_ROUTING DROP 예시, 12쪽의 예상 로그, 14~16쪽의 실제 실행·제거 화면과 요약표는 서로 다른 증거입니다. 요약표를 해당 DROP 실험의 실제 차단 로그로 바꾸어 기록하지 않습니다. 이 글에서는 첨부의 텍스트 16쪽과 관련 화면 5쪽을 대조했지만 커널 모듈을 실행하거나 성능·무비용 동작을 측정하지 않았습니다. 원 게시물과 첨부 자료
Linux Kernel Labs의 5.10.14 표기 실습도 과거 학습 자료입니다. 그 예시의 ACCEPT 설명, 상태 구조체, 헤더 접근법을 현재 버전의 보장으로 복사하지 않고 위의 v6.18 소스와 대조합니다. 판독하지 못한 작은 화면이나 확보하지 못한 PDF는 이 글의 근거로 사용하지 않았습니다. Linux Kernel Labs: networking
연결해서 읽을 글
이 글의 소스 기준은 Linux v6.18이며 사이트의 다른 LTS 패치 버전 분석과 혼동하지 않습니다. 연결된 원문 코드와 문서는 위의 주장에 해당하는 경로를 확인하기 위한 근거입니다.