Skip to content
오늘을살자
Go back

lwIP에서 링크 복구 후 UDP가 한동안 죽어 보인다: ARP 캐시와 netif 상태를 같이 보자

Edit page

임베디드 장비에서 링크가 한번 끊겼다가 돌아오면 이상한 상태가 남을 때가 있다.

이때 DHCP부터 의심하기 쉽지만,
정작 원인은 더 아래에 있는 경우가 많다.

오늘 메모는 링크 복구 뒤 남아 있는 ARP 캐시와 netif 상태 이야기다.

먼저 현상을 나눠 보자

이 이슈는 보통 두 형태로 보인다.

1) 첫 UDP 한두 개만 사라진다

애플리케이션 로그에는 sendto()가 성공처럼 보이는데,
상대는 못 받는다.

잠시 뒤 다시 보내면 정상으로 붙는다.

2) 한동안 계속 안 되다가 갑자기 풀린다

이걸 “UDP가 불안정하다”로 보면 원인을 놓치기 쉽다.

왜 링크 복구 뒤에만 이런가

링크가 끊겼다가 올라오면
물리 상태만 바뀌는 게 아니다.

netif_set_link_up()이 호출됐다고 해서
바로 “상대 MAC을 알고 있고 바로 보낼 수 있다”가 아니다.

특히 고정 IP + UDP 주기 송신 장비는
DHCP 이벤트가 없어서 더 늦게 눈치채는 경우가 있다.

흔한 오해: IP가 있으니 바로 나가야 한다

IP가 살아 있어도
이더넷 송신은 결국 목적지 MAC이 있어야 한다.

ARP 캐시가 애매한 상태면 흐름은 대충 이렇게 된다.

UDP payload 송신 시도
-> 목적지 MAC 확인 필요
-> ARP 엔트리 stale 또는 없음
-> ARP 요청 먼저 발생
-> 응답 오기 전까지 실제 UDP payload는 대기 또는 드롭처럼 보임

그래서 “첫 패킷만 사라진다”는 체감이 나온다.

실제로는 UDP 자체보다
그 전에 필요한 L2 해상도가 늦은 것이다.

자주 틀리는 구현 포인트

케이블 빠짐을 감지했는데도
애플리케이션이 계속 송신 루프를 유지하면,
상위에서는 계속 성공처럼 보이는 로그가 쌓일 수 있다.

이 상태에서 link up이 돌아오면
이전 ARP 상태와 새 링크 상태가 섞여서
첫 복구 구간이 더 지저분해진다.

링크 up 이벤트만 보고 곧바로 주기 UDP를 재개하면,
ARP 요청/응답이 끝나기 전에 첫 payload가 걸린다.

그러면 현상은 이렇게 보인다.

3) 상대도 링크 복구 중이라는 점을 빼먹는다

내 장비 링크가 올라온 시점과
상대 스위치/상대 보드가 실제로 패킷을 받을 준비가 된 시점은 다를 수 있다.

특히 보드 간 직접 연결이 아니라
중간 스위치나 게이트웨이가 있는 환경에서는
이 시간차가 더 커진다.

실무에서 보는 패킷 흐름

이 문제를 캡처로 보면 대개 이런 순서가 나온다.

link down
-> link up
-> 첫 UDP 송신 시도
-> ARP who-has 발생
-> ARP reply 수신
-> 그 다음 UDP부터 정상

즉 첫 UDP가 없어 보이더라도
ARP가 먼저 움직였는지 확인하면 그림이 맞아떨어진다.

반대로 ARP 자체가 안 보이면,
그때는 netif 상태 전환이나 드라이버 송신 경로를 더 의심해야 한다.

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

링크 복구 이슈는 앱 로그만 보면 거의 안 풀린다.
나는 보통 아래 항목을 같은 시간축에 둔다.

  1. netif_set_link_down() / netif_set_link_up() 시각
  2. netif_set_down() / netif_set_up() 사용 여부
  3. 첫 UDP 송신 시각
  4. ARP request/reply 시각
  5. 상대가 실제 첫 UDP를 받은 시각

이걸 붙여 보면
“UDP가 죽었다”가 아니라
“ARP 해상도 끝나기 전에 첫 송신이 들어갔다”는 식으로 바로 바뀐다.

구현 쪽에서 무난한 패턴

안전하게 가려면 보통 아래 원칙이 좋다.

link down
-> 상위 송신 루프에 상태 전달
-> 필요하면 재전송/큐 정책 정리

link up
-> netif 상태 갱신
-> 첫 주기 송신을 바로 시작하지 말고 복구 상태 진입
-> ARP 해상도 또는 준비 시간 이후 정상 주기 복귀

프로젝트마다 구현은 다르지만,
핵심은 link recovery 구간을 평상시 송신과 분리하는 것이다.

예를 들면:

빠른 체크리스트

  1. 링크 복구 직후 첫 UDP 유실이 항상 같은 패턴인지 확인
  2. 그 시점에 ARP request/reply가 보이는지 확인
  3. link down 동안에도 앱이 계속 송신 중이지 않았는지 확인
  4. link up 직후 바로 주기 송신을 재개하고 있지 않은지 확인
  5. 상대 장비도 같은 시점에 복구 중인지 확인

한 줄 요약

lwIP에서 링크 복구 뒤 UDP가 한동안 죽어 보이면, UDP 스택보다 먼저 netif 링크 상태 전환과 ARP 캐시 재해상도 구간을 같이 보는 게 훨씬 빠르다.

추천 키워드

lwIP, ARP, UDP, netif, link recovery, embedded network


DevBJ | 오늘을살자, Log Today


Edit page
Share this post on:

Previous Post
DoIP에서 ECU Reset 후 다시 안 붙는다: 소켓 종료와 재연결 순서를 같이 봐야 한다
Next Post
DoIP에서 NRC 0x21이 반복된다: Busy Repeat Request를 timeout처럼 다루면 꼬인다