| 항목 | 내용 |
|---|---|
| 프로젝트 | OVN (Open Virtual Network) |
| 관련 릴리스 | v26.03.0 (2026-03-20) |
| 구현 커밋 | 79302556 — controller: Add experimental flow-based tunnel support (2025-08-25) |
| 설정 | external_ids:ovn-enable-flow-based-tunnels=true (실험적 기능, 기본값 false) |
| 발견 출처 | OVN v26.03.0 Release Notes의 experimental flow-based tunnel 항목 |
| 검증 근거 | 커밋 79302556의 실제 diff(controller/encaps.c, local_data.c, physical.c, ovn-controller.c, ovn-controller.8.xml) |
| 소스 라이선스 | Apache License 2.0 |
OVN v26.03은 각 원격 chassis와의 연결마다 전용 OVS tunnel port를 만드는 기존 방식을 대신해, tunnel type별 Geneve/VXLAN 포트 하나를 여러 원격 chassis가 공유하는 flow-based tunnel을 실험적으로 추가했다. 공유 포트에는 local_ip=flow, remote_ip=flow, key=flow를 설정하고, ovn-controller가 생성하는 OpenFlow action이 패킷마다 tunnel source/destination과 metadata를 채운다. 한 로컬 chassis의 tunnel port 수는 원격 chassis 수에 비례하던 구조에서 지원 tunnel type 수에 가까운 구조로 줄어든다.
OVN northbound의 logical switch/router는 중앙의 ovn-northd를 거쳐 southbound DB의 logical flow와 Port_Binding으로 변환된다. 각 hypervisor에서 실행되는 ovn-controller는 이 정보를 읽어 로컬 OVS bridge(br-int)에 OpenFlow flow를 설치한다.
목적 logical port가 다른 chassis에 있으면 패킷을 overlay tunnel로 보내야 한다. 기존 구조에서는 로컬 chassis가 원격 chassis별로 Geneve 또는 VXLAN interface를 만들고, 각 interface가 고정된 remote_ip를 가졌다. ovn-controller는 목적 Port_Binding의 chassis를 찾은 뒤 그 chassis에 대응하는 tunnel port의 ofport로 출력했다.
고정 tunnel port는 "이 OVS port는 저 chassis로 간다"는 대응 관계가 명확하다. BFD를 port endpoint에 붙이거나, IPsec의 원격 이름을 정하거나, chassis별 상태를 추적하기도 쉽다. 반면 chassis가 N개인 대규모 클러스터에서는 각 chassis가 나머지 chassis를 향한 port를 가져야 하므로 전체 port 수가 대략 N² 방향으로 증가한다. 한 chassis에 여러 encap IP 조합까지 있으면 로컬 port 수도 더 늘어난다.
OVS tunnel interface는 endpoint를 반드시 고정값으로만 받을 필요가 없다. remote_ip=flow를 사용하면 OpenFlow가 packet processing 시점에 tun_dst를 채울 수 있다. 이 기능을 쓰면 tunnel port는 전송 장치 역할만 하고, 실제 원격 endpoint 선택은 flow action으로 옮길 수 있다.
encaps_run()의 기존 경로는 southbound Chassis table을 순회하고, transport zone이 겹치는 각 원격 chassis에 대해 chassis_tunnel_add()를 호출했다. 생성된 port는 external_ids:ovn-chassis-id로 원격 chassis와 연결됐고, 물리 flow 생성 코드는 chassis_tunnels map에서 대상 chassis의 ofport를 찾아 출력했다.
[변경 전 — port-based tunnel]
Chassis A / br-int
├─ ovn-B-geneve (remote_ip=B) ─────────▶ Chassis B
├─ ovn-C-geneve (remote_ip=C) ─────────▶ Chassis C
├─ ovn-D-geneve (remote_ip=D) ─────────▶ Chassis D
└─ ovn-E-geneve (remote_ip=E) ─────────▶ Chassis E
출력 flow:
logical outport가 C에 있음 → C용 tunnel ofport로 OUTPUT
chassis가 늘 때마다 각 기존 chassis에도 새 tunnel port가 추가된다.
새 create_flow_based_tunnels()는 로컬 chassis가 지원하는 encap type을 중복 제거한 뒤, type마다 한 port만 보장한다. interface option은 다음 세 필드를 모두 flow로 둔다.
options:local_ip=flow
options:remote_ip=flow
options:key=flow
port의 external_ids:ovn-chassis-id는 특정 chassis 이름 대신 flow이고, 별도 ovn-tunnel-type에 Geneve/VXLAN 종류를 기록한다. local_nonvif_data_run()은 이 표식을 읽어 flow_tunnels[TUNNEL_TYPE_MAX] 배열에 type별 ofport를 보관한다. 기존의 chassis→tunnel hash map과 별개의 빠른 조회 경로를 만든 것이다.
목적 Port_Binding이 원격 chassis에 연결되어 있으면 put_flow_based_remote_port_redirect_overlay()가 다음 순서로 action을 만든다.
- 로컬과 원격 chassis가 함께 지원하는 tunnel type을 선택한다. 현재 우선순위는 Geneve, 그다음 VXLAN이다.
Port_Binding.encap에 지정된 endpoint가 있으면 그 IP를 쓰고, 없으면 원격 chassis의 기본 encap IP를 고른다.- 기존
put_encapsulation()으로 datapath key와 logical outport 같은 tunnel metadata를 넣는다. put_set_tunnel_ip()이 IPv4이면MFF_TUN_SRC/MFF_TUN_DST, IPv6이면MFF_TUN_IPV6_SRC/MFF_TUN_IPV6_DST에 endpoint를 load한다.- type에 대응하는 shared tunnel
ofport로 출력한다.
unicast뿐 아니라 multicast/broadcast fan-out도 원격 chassis를 순회하면서 endpoint IP를 바꿔 같은 shared port로 여러 번 출력하도록 별도 경로가 추가됐다. 수신 방향은 기존 tunnel ingress flow 생성 함수를 재사용한다. shared port의 ofport와 type으로 임시 chassis_tunnel 구조체를 만들어 decapsulation·MTU 관련 ICMP 처리 flow를 동일하게 설치한다.
기존 설계는 topology 정보를 OVSDB의 port 객체 수로 표현했다. 새 설계는 type별 port만 남기고 "이 패킷의 원격 chassis는 어디인가"를 OpenFlow action에 인코딩한다. 따라서 chassis 추가가 모든 노드의 port 생성으로 번지지 않고, 로컬 chassis 기준 port 수는 지원 type 수 O(T)에 가까워진다. 대신 physical flow 생성 코드가 remote chassis, port별 encap 선택, IPv4/IPv6 tunnel field를 모두 정확히 계산해야 한다.
flow-based 경로는 ovn-enable-flow-based-tunnels가 참일 때만 활성화되고 기본값은 거짓이다. encaps_run()과 physical flow 생성은 port-based/flow-based 분기를 모두 유지한다. 대규모 환경에는 객체 수 감소라는 이득이 크지만, 기존 port 기반 운영 도구와 장애 진단 방식은 "remote chassis마다 port가 있다"는 전제에 의존할 수 있다. 실험적 opt-in은 이 운영 모델 변화까지 함께 검증할 시간을 준다.
커밋과 man page는 알려진 제한을 명시한다.
- IPsec은 지원하지 않는다. 공유 port는 패킷마다 remote chassis가 달라져 기존처럼 port에 고정
remote_name을 둘 수 없다. - tunnel endpoint 간 BFD를 지원하지 않는다. 따라서 BFD에 의존하는 HA chassis, 예를 들어 Distributed Gateway Port redundancy를 사용할 수 없다.
- 코드에는 multi-chassis port의 강제 tunneling 경로가 flow-based tunnel을 추가 지원해야 한다는
XXX도 남아 있다.
즉 port 수를 줄인 대가는 endpoint별 port에 붙던 보안·liveness 의미를 별도의 flow-aware 모델로 다시 설계해야 한다는 것이다.
[변경 후 — flow-based tunnel]
Chassis A / br-int
├─ ovn0-geneve (local_ip=flow, remote_ip=flow, key=flow)
└─ ovn0-vxlan (local_ip=flow, remote_ip=flow, key=flow)
원격 logical port가 Chassis C에 있을 때:
Port_Binding → C의 선호 encap IP 선택
│
▼
OpenFlow actions
set tunnel metadata
load A encap IP → tun_src
load C encap IP → tun_dst
output shared Geneve ofport
│
└──────────────────────────────▶ Chassis C
원격 chassis 수가 늘어도 type이 같으면 tunnel port는 추가되지 않는다.
- endpoint별 BFD 상태를 shared port 위에서 표현하려면 어떤 key와 state model이 필요할까?
- IPsec의 peer identity를 packet별 tunnel destination과 안전하게 결합할 OVS/OVN 인터페이스가 추가될 수 있을까?
- port 수 감소가 큰 환경에서 OVSDB transaction·reconcile 시간과 OpenFlow entry 수는 각각 얼마나 달라질까?
- OVN 26.03 Release Notes — v26.03.0 기능 목록과 지원 일정
- 커밋
79302556— Add experimental flow-based tunnel support — shared port 생성, endpoint 선택, OpenFlow action, 테스트와 man page의 실제 diff - OVN All Releases — 현재 지원되는 26.03/25.09/24.03 계열
- OVN LICENSE — Apache License 2.0
본문 참고 자료로 충분했다.