Skip to content
오늘을살자
Go back

lwIP에서 링크는 붙었는데 DHCP가 안 돈다: netif_set_up() / netif_set_link_up() 순서를 같이 보자

Edit page

lwIP bring-up 할 때 이런 상태를 꽤 자주 본다.

처음 보면 PHY 드라이버나 DHCP 서버부터 의심하게 된다.
그런데 실제로는 netif 상태 전환 순서가 어긋난 경우가 많다.

오늘 글은 그 순서를 짧게 정리하는 메모다.

lwIP에서 자주 헷갈리는 상태가 이 둘이다.

둘 다 이름이 “올린다”라서 같은 뜻처럼 보이는데,
실제로는 역할이 다르다.

간단히 보면 이렇다.

netif up
  = 이 인터페이스를 스택이 사용 가능 상태로 본다

link up
  = PHY/driver 기준으로 실제 링크가 살아있다

DHCP는 이 상태 전환이 맞아야 자연스럽게 붙는다.

전형적인 실패 패턴 1: link만 올리고 netif는 down 상태

드라이버 코드에서 PHY 인터럽트를 받고 바로 이런 식으로 처리하는 경우가 있다.

netif_set_link_up(&gnetif);
dhcp_start(&gnetif);

그런데 netif 자체가 아직 up이 아니면,
상태머신이 기대한 순서로 안 돌 수 있다.

증상은 보통 이렇다.

즉 “링크가 보인다”와 “인터페이스가 동작 준비됐다”를 분리해서 봐야 한다.

전형적인 실패 패턴 2: 링크 이벤트마다 dhcp_start()를 중복 호출

링크가 flap 되거나 케이블을 재삽입하면,
상태 전환이 생각보다 자주 발생한다.

이때 흔한 코드가 이거다.

link up interrupt
-> netif_set_link_up()
-> dhcp_start()

또 다른 init path
-> netif_set_up()
-> dhcp_start()

이렇게 두 군데에서 DHCP 시작을 건드리면,
테스트에 따라 멀쩡해 보이기도 하고
어떤 환경에서는 lease 재획득이 꼬이기도 한다.

특히 재연결 이슈는 “한 군데에서만 시작/정지한다” 원칙이 없으면 길어진다.

bring-up에서 무난한 순서

가장 덜 헷갈리는 흐름은 보통 이렇다.

1) netif_add()
2) netif_set_default() 필요 시 설정
3) netif_set_up()
4) PHY 링크 확인
5) 링크가 살아있으면 netif_set_link_up()
6) DHCP를 쓸 경우 dhcp_start()

링크가 나중에 올라오는 구조라면,
핵심은 상태를 한 군데에서 관리하는 것이다.

boot:
  netif_add()
  netif_set_up()

phy link callback:
  if (link up) {
    netif_set_link_up()
    dhcp_start() 또는 dhcp_network_changed() 정책 수행
  } else {
    netif_set_link_down()
    dhcp_stop() 여부는 정책에 맞게 결정
  }

프로젝트마다 DHCP 재시작 정책은 다르지만,
up/downlink up/down을 섞어 쓰면 디버깅이 어려워진다.

재연결 뒤에만 안 붙는 이유

처음 부팅에서는 잘 되는데,
케이블 재삽입이나 스위치 재연결 뒤에만 안 붙는 경우가 있다.

이건 보통 상태 복구가 반쪽이라서 그렇다.

1) 링크 down은 알렸는데 up 때 DHCP를 다시 안 건다

한 번 lease를 받았다는 이유로
재연결 뒤에는 DHCP를 따로 건드리지 않는 코드가 있다.

그런데 네트워크가 바뀌었거나,
상대 스위치/서버 상태가 달라졌으면 그대로 못 붙을 수 있다.

이 경우는 초기화 타이밍에 따라
Discover가 안 나가거나, 나가도 재시도 흐름이 예상과 다르게 보일 수 있다.

3) 드라이버 링크 이벤트가 중복/지연된다

PHY polling과 인터럽트를 같이 쓰면
상태 전환이 두 번 들어오는 경우가 있다.

그러면 로그에는 link up/down이 맞는 것처럼 보여도,
실제로는 DHCP start/stop이 꼬여 있다.

확인할 로그 포인트

이 이슈는 패킷 캡처만 보면 애매할 때가 많다.
그래서 나는 상태 로그를 같이 남긴다.

  1. netif is up/down
  2. link is up/down
  3. dhcp_start() / dhcp_stop() 호출 시각
  4. dhcp_supplied_address() 또는 IP 할당 시각
  5. PHY 이벤트 발생 순서

이 다섯 줄만 있어도 “링크는 붙었는데 DHCP 상태머신이 안 돌았다”를 빨리 확인할 수 있다.

구현 쪽 팁

특히 bring-up 초반에는,
“IP가 안 붙는다”를 DHCP 서버 탓으로 넘기기 전에
내 상태 전환 로그부터 정리하는 게 훨씬 빠르다.

빠른 체크리스트

  1. netif_set_up()이 실제로 호출되는지 확인
  2. 링크 up 전에 dhcp_start()가 먼저 호출되지 않는지 확인
  3. 링크 재삽입 뒤 DHCP 재시작 정책이 있는지 확인
  4. link 이벤트 경로가 둘 이상인지 확인(폴링 + IRQ 중복)
  5. 패킷 캡처와 상태 로그를 같은 시간축으로 비교

한 줄 요약

lwIP에서 링크는 살아있는데 DHCP가 안 붙으면, PHY보다 먼저 netif_set_up(), netif_set_link_up(), dhcp_start()의 호출 순서와 중복 상태 전환부터 확인하는 게 제일 빠르다.

추천 키워드

lwIP, DHCP, netif, link up, ethernet bring-up, embedded network


DevBJ | 오늘을살자, Log Today


Edit page
Share this post on:

Next Post
Routing Activation은 됐는데 첫 UDS가 실패한다: SA/TA와 재연결 순서를 같이 보자