Skip to content
오늘을살자
Go back

lwIP에서 ping은 되는데 TCP나 UDP만 이상하다: checksum offload를 반만 켜면 증상이 더 헷갈린다

Edit page

lwIP 포팅 초기에 제일 헷갈리는 상태 중 하나가 이거다.

이때 socket 코드나 방화벽부터 의심하기 쉽다.
하지만 보드 포팅에서는 더 아래층이 먼저 틀린 경우가 많다.

오늘 메모는 lwIP와 Ethernet MAC 드라이버가 checksum 책임을 서로 다르게 이해할 때 보이는 증상이다.

결론부터

checksum offload는 “하드웨어가 대신 해 준다” 한 줄로 끝나지 않는다.

중요한 것은 누가 checksum을 만들고, 누가 검증하는지 양쪽이 같은 가정을 갖는가다.

lwIP thinks:
  hardware will fill TCP/UDP/IP checksum

driver / MAC thinks:
  software already filled checksum

이렇게 어긋나면 패킷은 나가도
상대가 조용히 버릴 수 있다.

반대로 RX 쪽에서도:

hardware does not verify checksum
but driver marks packet as verified

처럼 처리하면 손상된 패킷이 상위로 올라와
증상이 더 랜덤해진다.

즉 checksum offload는
lwIP 옵션, 드라이버 descriptor 설정, RX/TX 완료 처리가 같이 맞아야 한다.

왜 ping은 되는데 TCP/UDP만 더 이상해 보이나

초기 bring-up에서는 ICMP echo만 먼저 시험하는 경우가 많다.

그런데 이 단계만 보고 “네트워크는 된다”고 결론 내리면 위험하다.

그래서 체감상으로는:

처럼 보일 수 있다.

흔한 패턴 1: lwIP에서 checksum 생성을 끄고 드라이버는 아무것도 안 한다

이 경우가 가장 직관적이다.

lwIP config:
  CHECKSUM_GEN_IP/TCP/UDP = 0

driver:
  TX descriptor offload bit not set

그러면 TX 패킷 checksum 필드가 비정상인 채로 나갈 수 있다.

증상은 보통 이렇다.

특히 하드웨어가 자동 계산해 줄 거라고 믿고
lwIP checksum 생성을 꺼 둔 뒤,
드라이버 descriptor 설정을 빠뜨리면 바로 여기로 간다.

흔한 패턴 2: RX checksum 검증 결과를 드라이버가 과신한다

수신 쪽도 비슷하게 틀릴 수 있다.

hardware RX checksum status is invalid or unsupported
-> driver still marks packet as clean
-> lwIP skips software verification

그러면 실제로는 손상된 패킷이 상위로 올라가고,
문제는 애플리케이션이나 프로토콜 로직처럼 보일 수 있다.

증상은 꽤 지저분하다.

즉 RX offload는 “상태 비트를 믿어도 되는지”까지 확인해야 한다.

흔한 패턴 3: IP만 offload하고 TCP/UDP는 빠뜨린다

칩 문서를 보면 오프로드 옵션이 한 덩어리처럼 보여도,
실제로는 비트가 나뉘어 있는 경우가 많다.

IP header checksum     -> enabled
TCP checksum           -> disabled
UDP checksum           -> disabled

그러면 아래 같은 이상한 상태가 나온다.

이때 “프로토콜별 버그인가?”로 가기 쉽지만,
실제로는 드라이버 descriptor 비트 조합이 틀린 경우가 많다.

캡처에서 어떻게 보이나

가장 빠른 확인은 패킷 캡처다.

TX 쪽에서 보면 대개 이런 그림이 나온다.

ARP request/reply 정상
ICMP echo 가능
TCP SYN 전송
-> 상대 응답 없음

또는:

UDP payload 전송
-> 상대 수신 로그 없음
-> 캡처에 checksum warning

중요한 점은 캡처 위치다.

를 같이 봐야 한다.

즉 Wireshark 한 줄만 보고 바로 단정하지 말고,
실제 wire에서 어떤 값으로 나가는지를 확인하는 편이 안전하다.

구현 쪽에서 무난한 패턴

bring-up 초기에는 한쪽 책임만 먼저 명확히 두는 편이 좋다.

1. 처음에는 소프트웨어 checksum으로 완전히 확인

lwIP generates/checks checksum
driver does not claim offload

이 상태로 통신이 안정적인지 먼저 본다.

2. 그다음 하드웨어 offload를 켜고 역할을 다시 맞춘다

lwIP generation/check options updated
driver TX/RX descriptor offload bits enabled
RX status interpretation verified

즉 처음부터 “하드웨어가 다 해 주겠지”보다
기준점을 하나 만든 뒤 옮겨 가는 편이 디버깅이 빠르다.

로그를 이렇게 남기면 빨라진다

이 문제는 앱 로그만으로 거의 안 풀린다.

나는 보통 아래 항목을 같이 남긴다.

  1. lwIP checksum 관련 빌드 옵션 값
  2. TX descriptor에 넣은 checksum offload 비트
  3. RX descriptor에서 읽은 checksum 상태 비트
  4. Wireshark 또는 미러 포트 캡처 시각
  5. 프로토콜별 증상 구분: ICMP, UDP, TCP

이 다섯 줄이 있으면
“TCP만 이상하다”는 현상을
“checksum 책임 분담 불일치”로 빨리 좁힐 수 있다.

빠른 체크리스트

  1. CHECKSUM_GEN_IP, CHECKSUM_GEN_TCP, CHECKSUM_GEN_UDP와 드라이버 TX offload 설정이 같은 가정을 보는지 확인
  2. CHECKSUM_CHECK_IP, CHECKSUM_CHECK_TCP, CHECKSUM_CHECK_UDP와 드라이버 RX 검증 결과 처리가 맞는지 확인
  3. IP만 offload하고 TCP/UDP는 빠뜨린 descriptor 설정이 없는지 확인
  4. 캡처 지점이 NIC offload 착시를 만들고 있지 않은지 확인
  5. bring-up 초기에는 software checksum만으로 먼저 기준 통신을 확인했는지 점검

한 줄 요약

lwIP에서 ping은 되는데 TCP나 UDP만 이상하다면, 애플리케이션보다 먼저 checksum을 누가 만들고 누가 검증하는지 lwIP 옵션과 MAC 드라이버가 같은 가정을 보고 있는지 확인하는 편이 빠르다.

추천 키워드

lwIP, TCPIP, checksum offload, Ethernet MAC, DMA, embedded network


DevBJ | 오늘을살자, Log Today


Edit page
Share this post on:

Next Post
DoIP에서 두 테스터가 같은 Source Address를 쓰면 응답이 꼬인다: SA 충돌을 timeout처럼 보면 오래 헤맨다