TIL - 2020.12.06 (일)

코드 굽는 제빵사·2020년 12월 6일
0

TIL

목록 보기
11/20

리눅스 네트워크의 이해를 읽으면서

네트워크 장치 초기화

현대 운영체제의 유연함으로 인해 초기화 과정이 복잡해졌다. 먼저 디바이스 드라이버가 모듈이나 정적 컴포넌트로 로드될 수 있게 됐다. 게다가 장치 자체는 부팅 시에 존재해도되고 운영 중에 장착될 수도 있다. 후자의 경우를 핫 플러그 가능장치라고 하며, USB, PCI 카드 버스, IEEE 1394등이 포함된다.

인터럽트 종류

인터럽트를 통해 NIC는 해당 드라이버에 많은 것들을 알려줄 수 있다.

프레임 수신

  • 이것은 가장 흔하고 표준적인 상황이다.

전송 실패

  • 이런 종류의 알림은 이더넷 장치가 2진 지수 백오프라는 지연 전송(주로 NIC에서 하드웨어 레벨로 개발된다)까지 실패한 뒤에 생성되는 알림이다. 드라이버는 이 알림을 상위 네트워크 레벨까지 전다랗지 않는다는 점을 기억해야 한다. 상위 계층에서는 다른 방법으로 알게 된다(타이머 타임아웃이나 음수 ACK 등).

DMA 전송 성공적 완료

  • 보내야 할 프레임이 주어졌을 때 이것을 저장하고 있는 버퍼 영역은 NIC의 전송단 메모리로 옮겨진 후에 해제된다.

장치가 새 전송을 위한 충분한 메모리 있음

  • NIC 장치가 송신 쪽에 최대 크기의 프레임을 저장할 수 있는 여유 공간이 없어서 송신 측 큐를 정지함으로써 전송을 중단시키는 경우가 흔하게 발생한다. 메모리가 정상 상태로 돌아오면 큐가 다시 활성화된다.

핫 플러그

핫 플러그는 유명한 기능인 플러그인플레이를 제공하기 위해 리눅스 커널에 들어오게 됐다. 이 기능은 커널이 핫 플러그 가능한 장치의 삽입/제거를 감지한 후 사용자 공간 프로그램에 알려준다. 사용자 프로그램은 이 알림을 통해 필요한 드라이버를 로드하고 설정 파일에 존재할 경우 이것을 읽어 들인다.
핫 플러그는 부팅 시 핫 플러그 기능이 없는 장치도 관리하기 위해 사용될 수 있다. 개념상 작동 중인 시스템에 장치가 꽂히든 부팅 시에 장착돼 있든 상관하지 않는다. 사용자가 공간 헬퍼는 두 가지 경우 모두에 알림을 받는다. 사용자 공간 애플리케이션이 받은 이벤트에 대해 어떤 조치를 취할지 아닐지를 결정한다.

가상 장치

가상 장치는 하나 이상의 실제 장치 위에 설정된 추상화다. 가상 장치들 위에 가상 장치를 생성하는 것 역시 가능하다. 하지만 이 같은 구성이 모든 커널에서 동작하지는 않는다.

본딩

  • 이 기능을 통해 가상 장치는 물리 장치를 그룹핑해서 하나처럼 사용할 수 있다.

802.1Q

  • 이것은 802.3/이더넷 헤더 IEEE 규격을 확장한 것이다. 흔히 VLAN 헤더라고 불리는 가상 LAN을 생성할 수 있다.

브리징

  • 브리지 인터페이스는 브리지의 가상표현이다

인터페이스 에일리어싱

  • 원래 이 기능은 하나의 실제 이더넷 인터페이스를 여러 개의 가상 인터페이스(eth0:0, eth0:1등)로 확장하고 IP를 설정하기 위한 것이었다. 현재는 네티워크 코드의 발전으로 인해 여러 개의 IP를 설정하기 위해 가상 인터페이스를 생성할 필요는 없다.

True equalizer

  • 이 가상 장치는 트래픽 컨트롤에서 사용될 수 있는 큐잉 정책이다. 트래픽 컨트롤을 위해서는 특별한 장치를 생성해야 된다. 기본 개념은 본딩과 약간 유사하다.

커널 네트워크 스택과 통신

가상 장치와 실제 장치가 커널과 통신하는 방법은 약간 다르다.

초기화

  • 대부분의 가상 장치는 실제 장치와 같이 net_device_data 스트럭처를 지정 받는다. 종종 대부분 가상 장치의 net_device 함수 포인터는 실제 장치에서 사용되는 함수포인터를 래퍼 함수로 초기화한다. 하지만 모든 가상 장치가 net_device 인스턴스를 지정받진 않는다. 에일리어싱 장치를 예로 들 수 있는데, 이 장치는 실제 장치에 레이블을 붙이는 형태로 개발된다.

설정

  • 특히 해당 가상 장치에만 적용되는 상위 필드를 설정해야 하고, ifconfig 같은 표준 도구를 사용할 수 없는 경우에는 가상 장치를 설정하기 위해 별도의 사용자 공간 도구를 제공하는 것이 일반적이다.

외부 인터페이스

  • 각 가상 장치는 /proc에 파일이나 파일들을 포함한 디렉토리를 노출한다. 얼마나 복잡하고 자세한 정보가 노출될지는 가상 장치의 종류와 디자인에 따라 달라지낟.

전송

  • 가상 장치와 실제 장치와의 관계가 1:1 아닐 경우 전송 시에 사용할 실제 장치를 선택하는 루틴이 필요하다. Qos는 각 장치별로 부과되는데, 가상 장치와 실제 장치간에 다중 관계가 맺어져 있을 경우 트래픽 컨트롤 설정에 영향을 미치기 때문이다.

수신

  • 가상 장치는 소프트웨어 객체이기 때문에 IRQ 핸들러를 등록하거나 I/O 포트와 메모리를 할당 받는 것과 같이 실제 시스템 자원과 통신할 필요가 없다. 이 장치에 대한 트래픽은 실제 장치에서 위의 과정을 거친 후에 간접적으로 전달된다. 패킷 수신은 가상 장치의 종류별로 다르게 일어난다. 예를 들어 802.1Q 인터페이스는 이더타입을 등록하고 정확한 프로토콜 ID를 가진 실제 장치로 들어온 패킷만을 전달 받는다.
    반대로 브리지 인터페이스는 연관된 장치에 들어온 모든 패킷을 수신한다.

외부 알림

  • 커널 내부에서 특정 이벤트에 대해 다른 컴포넌트가 생성한 알림은 가상 장치뿐만 아니라 실제 장치도 인지해야 한다. 가상 장치의 로직은 실제 장치 위에서 개발 됐기 때문에 실제 장치는 그 로직을 알지 못해 이러한 알림을 전달할 수 없다. 본딩을 예로 들면 그룹으로 구성된 장치 중에 하나가 다운됐을 경우 트래픽을 그룹 구성 맴버에게 분산하는 알고리즘은 이 사살을 알고 장치를 더 이상 사용하지 않도록 해야 한다.
    소프트웨어가 발생한 알림과는 달리 하드웨어가 발생한 알림은 가상 장치와 연관된 하드웨어가 업식 때문에 가상 장치로 바로 보낼 수가 없다.

PCI 계층과 네트워크 인터페이스 카드

커널의 PCI 서브시스템은 PCI장치에서 사용되는 일반적인 모든 함수를 제공한다. 이 서브시스템은 장치 코드들이 깔끔한 방법으로 코드를 작성하게 만들고, 커널이 장치들의 계정 정보보다 통계 정보를 쉽게 모으고 관리 할 수 있게 함으로써 장치 개발자의 일을 많이 덜어준다.

PCI 계층에서 사용되는 몇 가지 주요 데이터 스트럭처가 있다.

pci_device_id

  • 장치 식별자로, 리눅스에서 사용되는 지역 ID가 아니라 PCI 표준을 따르는 ID다.

pci_dev

  • 각 PCI 장치는 pci_dev 인스턴스를 생성(네트워크 장치는 net_device) 커널은 이 스트럭처로 PCI 장치를 참조한다.

pci_driver

  • PCI 계층과 디바이스 드라이버 간에 인터페이스를 정의한다. 이 스트럭처는 함수 포인터로 구성된다.

0개의 댓글