Ip addr add 와 ifconfig 의 차이점에서 Linux NIC 의 IP 주소 구조를 볼 수 있습니다
각 노드가 나타내는 IP 주소는 네트워크 세그먼트를 식별합니다. 이 노드의 IP 는 이 네트워크 세그먼트의 기본 주소이고, 그 아래의 IP 는 이 네트워크 세그먼트의 보조 주소입니다. 즉, 네트워크 카드는 각 노드의 연결된 목록 길이 합계를 가질 수 있으며, 이러한 IP 는 선형이 아니라 위에서 설명한 현수선 구조입니다. 이것이 어떤 이점이 있는지 봅시다. 씨스코 라우터를 해본 친구들은 논리적 서브넷을 만들 수 있는 보조 IP 개념이 있다는 것을 알고 있을 것입니다. 즉, 하나의 물리적 네트워크 포트에 두 개의 서브넷을 연결할 수 있습니다. 이것은 믿을 수 없을 것 같지만, 사실은 매우 간단하다. 예를 들어 이 네트워크 포트가 스위치에 연결되어 있고 이 네트워크 포트에 보조 IP 가 구성되어 있지 않은 경우 스위치는 하나의 네트워크 세그먼트 호스트에만 연결할 수 있습니다. 예를 들면192.168.1..1/24 입니다. 그러나 보조 IP 를 구성한 경우192.168.1/24 와 같은 두 네트워크 세그먼트의 호스트를 연결할 수 있습니다. 위의 예에서 보조 IP 는 여기서 말하는 Linux 의 보조 주소가 아닙니다. 반면 Linux 에서는 네트워크 카드에 구성된 IP 가 네트워크 세그먼트가 아닌 한 1 차 IP, 즉 매달린 체인 구조 위의 1 차 체인에 있는 IP, Linux 의 2 차 주소가 1 차 링크 점의 하위 링크 점에 있는 IP 입니다. 개념을 혼동해서는 안 된다는 점에 유의해야 한다. 내가 위에서 말한 것은 단지 주사슬이 상승사슬에서 작용하는 역할일 뿐인데, 그럼 자사슬은요? 사실 상상은 매우 간단하다. 프록시 서버 또는 로드 밸런싱 서비스를 실행하는 시스템에 비해 프록시 서버 또는 로드 밸런싱 서비스 및 주 서버가 동일한 포트를 수신하려면 secondary address 를 사용하여 해결할 수 있습니다. 동일한 네트워크 세그먼트에서 동일한 포트의 응용 프로그램을 수신해야 하는 한 매달린 체인에 하위 체인이 존재하는 이유입니다. 따라서 주 체인은 외부 또는 아래쪽 링크 레이어에서 여러 개의 네트워크 카드를 가상으로, 하위 체인은 상위 가상 여러 대의 시스템을 향해 있다고 할 수 있습니다. 현수선 구조의 Linux 호스트에 하나의 네트워크 카드만 있는 경우 외부에서는 여러 개의 네트워크 카드가 있는 것으로 간주되고 내부에서는 애플리케이션 계층이 서로 다른 호스트에 있는 것으로 간주합니다. 이것이 효과입니다. -응?
위의 일반적인 소개 외에도 많은 세부 사항이 있습니다. 주 체인에는 주 체인이 없고, 하위 체인의 첫 번째 노드를 제외한 모든 노드는 평행하지만, 하위 체인의 첫 번째 노드는 주 체인에서 항상 연결되어 있으며, 그들이 가지고 있는 주소는 주 주소이고, 그 아래 하위 체인이 가지고 있는 주소는 이 주 주소의 보조 주소입니다. 이런 식으로, 일단 주 사슬의 한 노드가 삭제되면, 그러나 이런 전략은 항상 그리 좋지 않다. 아버지가 잘못을 저질렀을 때 아들이 재앙을 당하기 때문에 현대 사회에서는 이미 수시로 발생하므로 메커니즘을 바꿔야 하기 때문이다. 따라서 Linux 에는 1 차 주소를 삭제할 때 2 차 주소가 있는 경우 첫 번째 2 차 주소 (장남) 가 삭제된 1 차 주소의 위치를 1 차 주소로 상속하는 옵션이 있습니다. 그렇지 않으면 프로그램이 기본 주소를 삭제할 때 보조 주소를 사용하거나 삭제를 연기하거나 프로그램이 충돌하는 경우 자동 프로모션 정책을 사용해도 문제가 없습니다. -응?
IP 별칭의 경우 이전 버전에서 있었던 것이 구현 문제입니다. 해결 된 문제는 현재 보조 IP 메커니즘과 동일합니다. 주로 물리적 네트워크 카드의 이름에 접미어를 추가하여 가상 네트워크 인터페이스가 되며 본질적으로 보조 IP 메커니즘과 동일합니다. 차이점은 IP 별칭이 그렇게 직관적이지 않다는 것입니다. 그러나 보조 IP 를 사용하면 응용 프로그램에서 하나의 네트워크 카드의 여러 주소를 볼 수 있습니다. 예를 들어 IP 별칭을 사용하면 eth0:0 이 무엇인지 묻는 경우가 있습니다. 커널에서 네트워크 장치 eth0:0 의 등록 코드를 찾으려고 노력했지만, 나는 미쳐서 찾을 수 없었다. 사실 나는 바보가 아니다. 단지 그 빌어먹을 이름이 바보짓을 했기 때문이다. -응?
리눅스 커널의 구현 코드를 살펴 보겠습니다. 먼저 일부 데이터 구조를 이해하고, 가장 중요한 것은 net_device, in_device, in_ifaddr 입니다. 이 세 가지 데이터 구조를 이해하면 모든 것이 이해됩니다. 사실입니다. -응?
Struct? Net_device?
{?
...?
Void * IP _ ptr? //net_device 와 분리된 in_device 구조를 가리키면 하나의 NIC 가 여러 네트워크 계층 프로토콜을 지원할 수 있음을 알 수 있습니까?
...?
}?
Struct? In_device?
{?
Struct? Net_device? * dev? //자신이 속한 net_device, 즉 네트워크 카드를 가리킵니까?
Atomic _ trefcnt? //참조 개수?
Int? 죽은; -응?
Struct? In _ ifaddr * IFA _ list// 모든 IP 주소 링크 목록?
...?
} -응?
Struct? In_ifaddr? //는 IP 주소를 나타냅니까?
{?
Struct? In _ ifaddr * IFA _ next? //위 in_device 의 ifa_list 필드가 이 필드에 연결되어 있습니까?
Struct? In_device * IFA _ dev// in _ device 구조를 다시 가리킵니까?
Struct? Rcu_head? Rcu _ head?
U32? Ifa _ local? //ip 주소?
U32? Ifa _ address?
U32? Ifa _ mask// 마스크?
U32? Ifa _ 방송 -응? //브로드캐스트 주소?
U32? Ifa _ anycast?
서명되지 않았습니까? 샤일? Ifa _ scope
서명되지 않았습니까? 샤일? Ifa _ flags? //IFA_F_SECONDARY 플래그만 있습니다. 그 외 기본 주소이기 때문입니다.
서명되지 않았습니까? 샤일? Ifa _ prefixlen?
Charifa _ label [ifnamsiz]; -응? //이름, IP? 별칭 시대에는 ethx:y 의 형태일 수도 있고, 2 급일 수도 있어요? Ip 시대에, 그것의 통일은 ethx 인가?
} 참고: 위의 구조는 Linux 네트워크 카드의 IP 주소 구조가 매달린 체인 구조라는 것을 의미하지는 않습니다. 이른바 체인 구조란 논리밖에 없다. 데이터 구조에서 네트워크 카드의 모든 IP 주소는 ifa_list 에서 선형 링크 테이블로 연결됩니다. 기본 주소인지 보조 주소인지는 in_ifaddr 의 ifa_flags 도메인에 따라 다릅니다. 새 주소를 설정할 때 항상 Inet_insert_ifa 를 호출합니다. Linux 가 IP 주소를 현수선 구조로 코드로 표시하지 않는 이유는 무엇입니까? 잘 모르겠어요. 개인은 net_device 에 1 차 IP 링크 목록이 있고 각 1 차 IP 노드에 2 차 IP 링크 목록이 있는 것이 더 좋다고 생각합니다. 나는 inet_insert_ifa 의 구현이 매우 나쁘다고 생각한다. 두 개의 사용자 공간 프로그램은 주소를 추가할 수 있습니다. 하나는 ifconfig 이고 다른 하나는 IP addr add 입니다. Ifconfig 는 ioctl 을 기반으로 주소를 추가하고 IP 프로그램은 netlink 를 기반으로 주소를 추가합니다. 두 방법 모두 목적을 달성할 수 있다. 이제 또 다른 질문을 볼 수 있습니다. 왜 IP addr add 를 사용하여 추가한 IP 주소인 ifconfig 는 볼 수 없고 ifconfig 가 설정한 IP addr show 는 볼 수 있습니다. 이 문제는 코드만 보면 알 수 있다. Ifconfig 가 IP 주소를 받으면 코드:?
뭐 때문에? (ifap? =? & ampin _ dev-& gt;; Ifa _ list? (IFA? =? *ifap)? ! =? 널? Ifap? =? & ampIFA-& gt;; Ifa_next)?
{?
만약? (! Strcmp(ifr.ifr_name, IFA-& gt;; Ifa_label)? & amp& amp? Sin_orig.sin_addr.s_addr? = =? IFA-& gt;; Ifa_address)?
{?
깨뜨리다 -응?
}?
} 은 (는) 찾은 IFA 의 IP 주소입니다. 우리는 모든 IFA 가 선형 체인 테이블에 연결되어 있다는 것을 알고 있습니다. 첫 번째 것을 찾으면 돌아가지 않습니다. 따라서 하나의 결과, 즉 연결된 목록 앞에 있는 결과만 얻을 수 있습니다. IP add show 는 다릅니다. inet_dump_ifaddr 함수에서 구현됩니다. 먼저 IP addr add 를 사용하여 동일한 네트워크 세그먼트에 있지 않은 여러 개의 기본 IP 주소를 추가한 다음 ifconfig 와 이전 IP 가 동일한 네트워크 세그먼트에 없는 IP 를 추가한 다음 ifconfig 를 사용하여 ifconfig 를 통해 방금 IFconfig 로 설정된 IP 가 아니라 IP addr add 로 추가된 것을 확인할 수 있습니다. 즉, ifconfig 는 항상 IFA 링크 목록의 첫 번째입니다. 또한 IP addr add 를 사용하여 많은 보조 IP 주소를 추가하면 ifconfig 로 설정한 IP 주소와 그 보조 IP 가 같은 네트워크 세그먼트에 있으면 모든 보조 IP 가 삭제됩니다. 이는 보조 IP 사양에 의해 결정되며 코드에도 반영됩니다. 또한 라우팅 테이블의 항목은 기본 IP 를 기반으로 합니다. 모든 작업은 경로를 추가할 때와 같이 기본 IP 를 기반으로 하기 때문입니다.
무효화? Fib_add_ifaddr(struct? In_ifaddr? *ifa)?
{?
Struct? In_device? *in_dev? =? IFA-& gt;; Ifa _ dev?
Struct? Net_device? *dev? =? In _ dev-& gt;; Dev?
Struct? In_ifaddr? * 프림? =? Ifa?
...?
만약? (IFA-& gt;; Ifa _ flags & ampIFA 중학교)? {? //IFA 가 보조 주소인 경우 해당 주소가 속한 1 차 주소를 찾아 이 1 차 주소에 따라 설정합니까?
프림. =? Inet_ifa_byprefix(in_dev, 접두어,? 마스크 팩); -응?
만약? "프림? = =? NULL)? {?
Printk(KERN _ 디버그? "fib_add_ifaddr:? 버그:? 프림. = =? Null/n); -응?
반환; -응?
}?
}?
Fib_magic(RTM_NEWROUTE,? RTN_LOCAL,? Addr? 32,? Prim); //라우팅 테이블에 추가?
...?
지금까지 우리는 많은 것을 배웠다. 가장 중요한 것은 Linux 에서 네트워크 카드 IP 주소의 매달린 체인 구조와 이러한 설계의 장점입니다. 또한 IP 주소를 설정하는 ioctl 및 netlink 방법도 있습니다. 사실, 다중 IP 네트워크 카드는 충돌을 일으키지 않습니다. 본질적으로 IP 는 네트워크 카드와 관련이 없습니다. 그들의 유일한 관계는 네트워크 계층 모델에 의해 연결되어 있고, 세부 사항은 노선에 의해 연결되어 있다. 예를 들어, 경로를 추가할 때 대상 주소, 다음 홉 IP 주소 및 네트워크 카드 출구를 지정하면 커널은 제공된 대상 주소를 기준으로 콤보 위치에 경로를 삽입합니다. 그런 다음 NH 의 네트워크 장치를 제공한 네트워크 카드의 출구로 설정하면 데이터를 전송할 때 출구를 찾을 수 있는 경로를 찾을 수 있습니다. 이렇게 간단합니다. 수동으로 설정된 경로는 임의로 설정할 수 있으며 커널은 완전히 잘못된 경우에도 라우팅 테이블에 추가합니다. 또 다른 경로는 커널에서 자동으로 생성됩니다. 즉, 네트워크 카드가 처음 올라왔을 때 네트워크 카드의 net_device 를 통해 in_device 를 찾은 다음 IP 주소를 찾습니다. 이러한 경로를 링크 라우팅이라고 합니다. -응?
2 차 IP 메커니즘을 통해 컴퓨터에 많은 네트워크 카드가 있다고 생각할 수 있습니다. 응용 프로그램의 경우 동일한 포트를 수신하는 응용 프로그램은 LAN 의 다른 시스템에 있는 것으로 간주합니다. 혼동 없이 이 IP 주소를 자유롭게 사용할 수 있습니다. 물론 라우트를 올바르게 설정하면 라우트와 기본 ARP 가 이 모든 것을 처리합니다. -응?
첨부: 사용자 공간에는 ifup/ifdown, /sbin/ip, ifconfig, netplugd 데몬이 있습니다. 이것들은 그것과 관련이 있습니까? 중간 IP 프로그램은 가장 기본이며 전략이 없습니다. 정책은 매개 변수를 지정하거나 다른 프로그램이 호출하는 반면, netplugd 는 netlink 를 통해 네트워크 카드의 상태를 모니터링하고 다른 모니터링 결과에 따라 /etc/netplug.d/netplug 스크립트를 호출한 모니터링 데몬이며 ifup/ifdown 스크립트를 호출할 수 있습니다 Ifup-eth footer 가 호출되고 매개변수가 최종 정리된 후 IP 프로그램 (일반적으로 IP link set eth0 up/down) 이 호출됩니다. 물론 IP 프로그램도 직접 호출할 수 있습니다 (예: IP addr add, IP route add 등). Ifconfig 는 이렇게 우회하지는 않지만 ioctl 을 통해 설정되고 strace 를 통해 관찰할 수 있습니다. 이러한 신비는 전략과 메커니즘이 분리되어 있으며 리눅스의 많은 기능이 매우 작은 프로그램으로 구성되어 있음을 보여줍니다.
Linux 의 IP 주소의 매달린 체인 구조와 IP 주소의 주소 지정 특성 ("IP 네트워크 세그먼트 간 상호 액세스에 대한 문제-라우팅은 근본적" 참조) 은 Linux 의 스택이 얼마나 완벽한지, 계층 캡슐화 모델에 완전히 부합하는지, 하위 계층의 논리와 상위 계층의 논리가 완전히 분리되었다는 것을 잘 보여 줍니다. 즉, IP 계층은 링크 계층과 물리적 계층의 물리적 레이아웃에 전혀 의존하지 않습니다. 마지막으로, 주소 지정 라우팅 등 IP 계층의 일은 IP 계층에서만 이루어진다는 점을 기억하십시오. 링크 계층에서 발견한 모든 경로는 전적으로 편의를 위한 것입니다.