소켓 바인딩 장치 시 macvlan 인터페이스 간의 통신 문제

소켓 바인딩 장치 시 macvlan 인터페이스 간의 통신 문제

동일한 IP 서브넷의 동일한 물리적 인터페이스에 브리지 모드의 두 개의 macvlan 인터페이스가 추가된 Linux 설정이 있습니다.

ip link add link eth2 dev mvl0 type macvlan mode bridge
ip link add link eth2 dev mvl1 type macvlan mode bridge
ip addr add 192.168.42.16/24 dev mvl0
ip addr add 192.168.42.17/24 dev mvl1
ip link set dev mvl0 up
ip link set dev mvl1 up

mvl0인터페이스에 바인딩된 소켓 간에 통신 하고 이를 사용하여 통신 하고 싶지만 mvl1작동하지 않습니다. 예를 들어,

# ping -I mvl0 192.168.42.17

아무런 응답도 받지 못했습니다. 커널이 에서 ARP를 수행하려고 시도하는 것을 볼 수 있지만 lo응답을 받지 못하기 때문에 작동하지 않습니다.

  • 예를 들어 라우팅이나 이웃 테이블을 조작하여 이를 수행할 수 있는 방법이 있습니까?

  • 이것을 Linux 커널의 버그로 간주해야 합니까? 결국 macvlan모드의 인터페이스는 bridge서로를 볼 수 있어야 합니다.

(배경:이는 동일한 프로세스 컨텍스트에서 실행되는 두 개의 임베디드 장치에 대한 시뮬레이션입니다. 우리의 프레임워크는 통신이 실제로 필요한 인터페이스를 통과하는지 확인하기 위해 항상 소켓을 인터페이스에 바인딩합니다. 통신은 일반적으로 UDP를 통해 이루어집니다. )

답변1

(편집하다: 이전 버전은 나가는 패킷(UDP)에서만 작동했지만, 이 버전은 양방향(TCP 및 ping)에서 작동합니다. )

귀하와 같은 설정에는 다양한 문제점이 있습니다. Linux는 소스 주소가 네트워크 인터페이스 주소와 일치하는 수신 패킷을 라우팅 오류로 간주합니다(일반적인 상황에서는 라우팅 루프를 나타내기 때문입니다). 또한 기본적으로 local커널이 유지 관리하는 라우팅 테이블의 우선 순위가 가장 높으므로 패킷이 바인딩된 인터페이스 외부로 방출되는 것을 방지할 수 있습니다.

정책 라우팅은 두 번째 문제를 해결할 수 있습니다. 먼저, 겹치는 경로를 제거합니다(문제만 일으킬 수 있음).

ip route list
# overlapping routes should look like:
ip route del 192.168.42.0/24 dev mvl0 proto kernel scope link src 192.168.42.16
ip route del 192.168.42.0/24 dev mvl1 proto kernel scope link src 192.168.42.17

다음으로 local테이블에 낮은 우선순위(높은 값)를 지정합니다.

ip rule add pref 1000 lookup local
ip rule del pref 0

들어오는 패킷을 테이블로 보내서 local수락 해야 합니다.

ip rule add pref 100 to 192.168.42.16 iif mvl0 lookup local
ip rule add pref 100 to 192.168.42.17 iif mvl1 lookup local

그리고 다른 모든 (나가는) 패킷은 해당 패킷으로 이동합니다. 대상은 특수 테이블을 사용하여 다른 인터페이스에서 강제로 종료됩니다.

ip rule add pref 200 to 192.168.42.17 lookup 100
ip rule add pref 200 to 192.168.42.16 lookup 101

ip route add default dev mvl0 table 100
ip route add default dev mvl1 table 101

또한 역방향 경로 필터링을 비활성화하고(아직 비활성화되지 않은 경우) 로컬 출처의 패킷이 허용되도록 허용하여 첫 번째 문제를 해결해야 합니다.

echo "0" | tee /proc/sys/net/ipv4/conf/mvl{0,1}/rp_filter
echo "1" | tee /proc/sys/net/ipv4/conf/mvl{0,1}/accept_local

이제 인터페이스 ping중 하나에 바인딩되지 않은 경우에도 mvl작동합니다 . TCP와 UDP도 작동하며 다음을 사용하여 테스트되었습니다 socat.

socat TCP4-LISTEN:9998,so-bindtodevice=mvl0 -
echo foo | socat - TCP4:192.168.42.16:9998,so-bindtodevice=mvl1

socat UDP4-RECV:9900,so-bindtodevice=mvl0 -
echo foo | socat - UDP4-SENDTO:192.168.42.16:9900,so-bindtodevice=mvl1

관련 정보