OpenVSwitch with QEMU internal(deep-dive)

박천수·2022년 5월 19일

OpenVSwitch

목록 보기
2/3

시작에 앞서..

  • 리눅스 커널 네트워크 작동 방식과 인터럽트 처리 루틴에 대한 배경지식을 필요로 한다.
  • OpenVSwitch의 System, User level 프로세스 관계도, 작동 방식에 대한 배경지식을 필요로 한다.
  • Libvirt에 관한 기본적인 배경지식을 필요로 한다.

목표

  • OpenVSwitch(이하 OVS)를 사용하는 입장에서의 심도있는 분석
  • System, User level에서의 OVS보다 한 단계 더 깊은 linux kernel level 작동 방식까지 파악
  • Qemu와 OVS 연동 방식 파악

연구/분석 대상

  • OpenVSwitch
  • Libvirt
  • Qemu
  • 리눅스 커널 OVS module

연구/분석

- OVS vPort allocation flow

① vPort생성

  • 1-1). Libvirt XML을 통해 VM이 사용할 네트워크가 OVS라면 Libvirtd는 ovs-vswitchd와 소통하여 환경을 구성한다.
  • 1-2). VM은 네트워크에 사용할 port가 필요하며, Libvirtd의 "add-port" 요청을 받은 ovs-vswitchd는 OVS kernel module로 port 생성 요청을 보낸다.
  • 1-3). OVS kernel module은 vPort를 생성한다. vPort를 net_device 구조체로 만들어 하나의 device가 있는 것처럼 관리한다. 리눅스 커널 네트워크 sofrirq인 napi의 대상으로 만들기 위함이며 "/dev/net/tun or tap"에 의한 tun/tap도 같은 방식으로 처리된다.
  • 1-4). vPort net_device를 생성하면서 자신 또한 패킷을 받을 것이라고 recv_handler를 등록한다.

② "fd" 리턴

  • 2-1). vPort를 정상적으로 생성하였다면 이를 VM에서 쓸 수 있도록 방식을 마련해주어야 하며 이는 fd를 통해 가능하다.
  • 2-2). fd는 최종적으로 요청을한 libvirtd에게 전달되며 해당 fd는 실행될 qemu의 인자로 들어간다.

- OVS vPort with QEMU

③ Use vPort in QEMU

  • 3-1). QEMU는 인자로 전달받은 fd를 통해 단순히 write, read 등 리눅스 API를 통해 kernel에 생성된 가상 net_device와 통신한다.

- OVS flow control setting

OVS flow control table setting

  • OVS가 하나의 네트워크로 작동하기 위해서 flow control이 필요하다. 해당 룰은 User level(권한 필요) interface tool인 "ovs-ofctl"로 설정가능하며 명령은 ovs-vswitchd를 거쳐 OVS kernel module에 존재하는 flow control table에 기록된다.

- OVS packet flow#1 - Receive

① NIC interrupt 발생

  • 1-1). NIC interrupt가 발생하면 해당하는 interrupt handler가 호출된다. Device에 도착한 데이터를 kernel 영역으로 올리는 Top-half가 진행된다.
  • 1-2). 이후 Bottom-half가 호출된다. softirq에 의해 적절한 하위 작업이 호출될 것이며 네트워크의 경우 napi가 해당된다.

② npoll 호출

  • 2-1). napi는 리눅스 커널 Dev에 접근할 수 있고 Dev는 OVS가 등록한 net_device의 recv_handler를 호출한다. 이 과정에서 deliver_skb가 일어나게 되고 vPort가 nic을 통해 들어온 패킷을 받게 된다.

③ Qeury flow control table

  • 3-1). vPort를 통해 들어온 패킷에 해당하는 flow control을 확인한 뒤 해당하는 것이 있다면 그에 따른 action을 수행한다.
  • 3-2). Flow table query 후 Qemu로 발송되는 패킷은 연결된 socket으로 전달된다.

- OVS packet flow#2 - Send

① Qemu write socket

  • 1-1). Qemu는 write API를 통해 패킷을 전달한다. 패킷을 전달받은 OVS kernel module은 Flow control table qeury를 진행한 후 적절한 패킷처리를 진행한다.
  • 1-2). 만약 해당하는 Flow control이 없다면 어떻게 될까?
    • OVS는 해당 패킷을 native 리눅스 네트워크 계층으로 흘려보낸다. 즉, OVS에서 처리되지 않은 패킷은 리눅스 커널의 netfilter(ip chain, routing, f/w) 정책에 기반하여 처리된다.
    • ex). VM에서 ping 8.8.8.8 발송
      • Host의 eno1 설정에 의해 default route가 외부로 설정
      • Qemu -> OVS kernel module(no flow control dst 8.8.8.8) -> linux kernel network -> lookup_hook(netfilter, nat, etc..) -> default route -> 외부

② Network character device

  • 2-1). 특별한 설정이 아닌 이상 OVS를 통해서든 혹은 lookup_hook routing rule에 의해서든 패킷은 eno1를 거치게 된다. eno1은 전달받은 패킷을 Device driver로 전달한다.

③ Network device driver

  • 3-1). Network device driver는 자신이 전달받은 패킷을 실제 NIC으로 전달한다(Control register setting, data buffer setting).

마치며..

  • OpenVSwitch와 QEMU, vPort 연동, 리눅스 OVS kernel Module에 관한 정리를 진행하였다. 위 4가지 컴포넌트 관점으로 설명하였기에 나머지 부분들은(인터럽트 처리 등..) 알고 있다고 가정하였다. 분석 내용을 읽으며 이해되지 않은 부분들은 "시작에 앞서.." 을 참고하여 배경지식을 갖추길 원한다.
profile
OS, Virtual Machine, Network velog

1개의 댓글

comment-user-thumbnail
2022년 8월 12일

천멘

답글 달기