전체 글

전체 글

    NAPI

    NAPI

    대부분의 device(nic..) 들은 두가지 방법으로 커널과 통신한다.polling커널 측에서 수행커널이 장치의 레지스터를 읽어 주기적으로 패킷의 수신 여부를 확인장치가 새로운 패킷을 가지고 있을 경우 이를 처리CPU 리소스 절약이 가능하지만, 불필요한 리소스 소모 가능interruptdevice 측에서 수행장치가 새로운 패킷을 받을 경우 하드웨어 IRQ를 사용하여 커널에게 알려 주는 방식커널이 IRQ를 받게 되면, 해당 IRQ를 처리 하기 위해서 미리 등록된 디바이스 드라이버의 인터럽트의 수신 패킷 처리 루틴(Interrupt Handler)을 호출인터럽트 핸들러(top half handler)는 수신한 패킷을 복사하고 큐에 넣은 후softirq를 사용하여 커널이 해당 패킷을 처리 할 수 있도록 한다..

    커널 네트워크 스택 #2 데이터 링크 계층

    커널 네트워크 스택 #2 데이터 링크 계층

    네트워크 데이터가 애플리케이션에서 하드웨어까지, 또는 반대로 하드웨어에서 애플리케이션까지 흐르는 과정은 다음과 같다.프로토콜 레이어에서 인터페이스 dev_queue_xmit()는 데이터 전송에 사용되고 netif_rx()는 데이터 수신에 사용된다. 물리계층을 거친 후 device 에서 읽은 프레임이 프로토콜 스택으로 어떻게 들어오고 반대로 프로토콜 스택에서 캡슐화된 프레임이 어떻게 나가는지 분석해보자. (커널 4.14.76 버전 기반) 드라이버 관점에서는 먼저 인터럽트를 다뤄야한다.  Interrupts인터럽트 처리는 데이터 링크 계층의 전송을 분석하는 출발점이다. 예를 들어 drivers/net/ethernet/intel/i40e는 Intel의 i40e 드라이버로 Intel의 40Gbps 네트워크 어댑..

    네트워크 디바이스 드라이버별 벤더 NIC

    리눅스에서 사용하는 네트워크 드라이버는 다음과 같다. 각각 특정 제조사의 네트워크 어댑터(NIC)를 지원하며 주로 이더넷 장치를 다룬다.  사용중인 NIC에 적합한 드라이버를 확인하는 명령어lspci -nn | grep -i ethernet드라이버가 지원하는 디바이스 목록을 확인하는 명령어 modinfo  Intel NIC 드라이버(1) e1000e지원 NIC:Intel PRO/1000 기가비트 이더넷 어댑터Intel 82574, 82579 계열 NIC주요 용도:데스크톱 및 일반 서버에서 사용.(2) igb지원 NIC:Intel Ethernet Server Adapter i350, i210Intel 82576, 82580 계열 NIC주요 용도:서버급 기가비트 이더넷 환경.(3) ixgbe지원 NIC:In..

    커널 네트워크 스택 #1 NIC 드라이버에서 패킷 수신

    커널 네트워크 스택 #1 NIC 드라이버에서 패킷 수신

    패킷 수신NIC는 네트워크로부터 데이터를 수신NIC는 DMA를 사용하여 네트워크 데이터를 RAM에 씀NIC는 CPU 개입 없이 DMA를 사용해 패킷 데이터를 RAM의 링 버퍼로 전송링 버퍼는 네트워크 스택에서 패킷 처리를 위해 사용되는 메모리 영역NIC가 IRQ를 발생probe 함수에서 request_irq 핸들러 등록됨NIC 드라이버의 등록된 IRQ 핸들러가 실행IRQ는 NIC에서 지워져서 새로운 패킷이 도착할 때 IRQ를 생성할 수 있음NAPI(NIC Polling) SoftIRQ 폴 루프가 napi_schedule 호출로 시작 됨패킷 처리net_rx_action 함수(ksoftirqd 커널 스레드에서 호출됨)는 현재 CPU의 poll_list에 추가된 NAPI poll 구조체를 처리하기 시작한다.p..

    커널 네트워크 스택 #0 초기화

    커널 네트워크 스택 #0 초기화

    커널 네트워크 스택 요약NIC 에서 패킷을 수신하면 DMA를 통해 커널의 메모리 영역에 존재하는 rx ring 버퍼 에 수신한 정보를 복사하고 이 후 CPU 에 인터럽트를 걸어 request를 보내면 CPU는 커널 인터럽트 함수를 수행한다. irq 핸들러는 인터럽트 번호를 보고 드라이버 인터럽트 핸들러를 호출한다.  드라이버 인터럽트 핸들러 함수는 (napi_schedule()) 소프트웨어 인터럽트(softirq) 를 요청하는 일을 수행하는데 softirq 핸들러 함수가 net_rx_action()이다. 대략적으로 다음과 같다.드라이버가 로드되고 초기화패킷이 네트워크에서 NIC에 도착패킷은 (DMA를 통해) 커널 메모리의 링 버퍼에 복사패킷이 메모리에 있음을 시스템에 알리기 위해 하드웨어 인터럽트가 생성..

    Linux Device Driver 기초 #8 PCI 드라이버

    PCI(Peripheral Component Interconnect) 드라이버버스는 전기적 인터페이스와 프로그래밍 인터페이스로 구성된다.주로 현대 데스크탑 및 대형 컴퓨터에서는 PCI 버스 가 많이 사용된다. PCI 장치가 시스템의 하드웨어를 찾고 접근하는 방법특정 드라이버가 하드웨어를 탐지하고 접근할 수 있도록 지원 32비트 데이터 버스를 기본으로 사용하며, 64비트 확장도 포함되어 있음PCI 버스는 ISA보다 높은 클럭 속도로 더 나은 성능을 달성플랫폼 독립성을 고려한 설계로, 다양한 프로세서 아키텍처(IA-32, Alpha, PowerPC, SPARC64, IA-64 등)에서 사용됨특히 중요한 점은 PCI가 인터페이스 보드의 자동 감지 및 구성(auto-detection)을 지원한다는 점이는 점퍼가..

    [C/CPU-affinity] 프로세스 CPU Affinity 설정

    CPU Affinity 란Asymmetric multiprocessing (AMP)와 symmetric multiprocessing (SMP)는 여러 프로세서를 사용하는 멀티프로세서 시스템에서의 처리 방식이다. 이 두 방식의 차이점을 이해하면 멀티프로세서 환경에서 프로세서가 어떻게 상호작용하고 작업을 분배하는지 알 수 있다.Asymmetric Multiprocessing (AMP)하나의 메인 프로세서만 시스템 리소스(예: 메모리, 입출력 장치 등)에 직접 접근하고, 시스템의 데이터 구조에 액세스한다.장점은 시스템 설계가 단순하고, 동기화에 따른 오버헤드가 줄어들어 성능이 향상된다단점은 하나의 프로세서에 작업이 집중될 수 있다는 점이며, 시스템 확장성(scalability)에서 한계가 있다.Symmetri..

    strongswan #5 IKE SA INIT, IKE_AUTH, CHILD_SA 설정

    IKE SA 초기화 과정에서 task_manager, sender, receiver가 협력하여 패킷을 생성하고 전송하는 구조를 통해 IKEv2 초기화 패킷이 전송된다. IKE SA 초기화 1. initiate_execute()initiate_execute() 함수는 IKE SA 객체를 생성한 후, IKE SA의 initiate() 메서드를 호출하여 초기화 과정의 시작점이 된다.METHOD(job_t, initiate_execute, job_requeue_t, interface_job_t *job){ ike_sa_t *ike_sa; interface_listener_t *listener = &job->listener; peer_cfg_t *peer_cfg = listener->peer..

    strongswan #4 charon에서 패킷 처리 (sender, receiver, processor)

    strongswan #4 charon에서 패킷 처리 (sender, receiver, processor)

    Charon 프로세스 시작1. starter_start_charon()을 호출하여 fork()를 통해 Charon 프로세스를 시작한다. 2. starter_stroke_add_conn()을 통해 stroke_msg 객체(type을 STR_ADD_CONN으로 설정)를 생성하여 연결 설정 메시지를 준비한다.URI를 /etc/ipsec.d/run/charon.ctl로 설정하고 스트림을 생성stream_service_create_unix  호출하여 Unix 도메인 소켓을 생성하고 연결 Charon 초기화INIT(this, .public = { .initialize = _initialize, .start = _start, .load_loggers = _load_logge..