요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
.. SPDX-License-Identifier: GPL-2.0
===============
XDP RX Metadata
===============
This document describes how an eXpress Data Path (XDP) program can access
hardware metadata related to a packet using a set of helper functions,
and how it can pass that metadata on to other consumers.
General Design
==============
XDP has access to a set of kfuncs to manipulate the metadata in an XDP frame.
Every device driver that wishes to expose additional packet metadata can
implement these kfuncs. The set of kfuncs is declared in ``include/net/xdp.h``
via ``XDP_METADATA_KFUNC_xxx``.
Currently, the following kfuncs are supported. In the future, as more
metadata is supported, this set will grow:
.. kernel-doc:: net/core/xdp.c
:identifiers: bpf_xdp_metadata_rx_timestamp
.. kernel-doc:: net/core/xdp.c
:identifiers: bpf_xdp_metadata_rx_hash
.. kernel-doc:: net/core/xdp.c
:identifiers: bpf_xdp_metadata_rx_vlan_tag
An XDP program can use these kfuncs to read the metadata into stack
variables for its own consumption. Or, to pass the metadata on to other
consumers, an XDP program can store it into the metadata area carried
ahead of the packet. Not all packets will necessary have the requested
metadata available in which case the driver returns ``-ENODATA``.
Not all kfuncs have to be implemented by the device driver; when not
implemented, the default ones that return ``-EOPNOTSUPP`` will be used
to indicate the device driver have not implemented this kfunc.
Within an XDP frame, the metadata layout (accessed via ``xdp_buff``) is
as follows::
+----------+-----------------+------+
| headroom | custom metadata | data |
+----------+-----------------+------+
^ ^
| |
xdp_buff->data_meta xdp_buff->data
An XDP program can store individual metadata items into this ``data_meta``
area in whichever format it chooses. Later consumers of the metadata
will have to agree on the format by some out of band contract (like for
the AF_XDP use case, see below).
AF_XDP
======
:doc:`af_xdp` use-case implies that there is a contract between the BPF
program that redirects XDP frames into the ``AF_XDP`` socket (``XSK``) and
the final consumer. Thus the BPF program manually allocates a fixed number of
bytes out of metadata via ``bpf_xdp_adjust_meta`` and calls a subset
of kfuncs to populate it. The userspace ``XSK`` consumer computes
``xsk_umem__get_data() - METADATA_SIZE`` to locate that metadata.
Note, ``xsk_umem__get_data`` is defined in ``libxdp`` and
``METADATA_SIZE`` is an application-specific constant (``AF_XDP`` receive
descriptor does _not_ explicitly carry the size of the metadata).
Here is the ``AF_XDP`` consumer layout (note missing ``data_meta`` pointer)::
+----------+-----------------+------+
| headroom | custom metadata | data |
+----------+-----------------+------+
^
|
rx_desc->address
XDP_PASS
========
This is the path where the packets processed by the XDP program are passed
into the kernel. The kernel creates the ``skb`` out of the ``xdp_buff``
contents. Currently, every driver has custom kernel code to parse
the descriptors and populate ``skb`` metadata when doing this ``xdp_buff->skb``
conversion, and the XDP metadata is not used by the kernel when building
``skbs``. However, TC-BPF programs can access the XDP metadata area using
the ``data_meta`` pointer.
In the future, we'd like to support a case where an XDP program
can override some of the metadata used for building ``skbs``.
bpf_redirect_map
================
``bpf_redirect_map`` can redirect the frame to a different device.
Some devices (like virtual ethernet links) support running a second XDP
program after the redirect. However, the final consumer doesn't have
access to the original hardware descriptor and can't access any of
the original metadata. The same applies to XDP programs installed
into devmaps and cpumaps.
This means that for redirected packets only custom metadata is
currently supported, which has to be prepared by the initial XDP program
before redirect. If the frame is eventually passed to the kernel, the
``skb`` created from such a frame won't have any hardware metadata populated
in its ``skb``. If such a packet is later redirected into an ``XSK``,
that will also only have access to the custom metadata.
bpf_tail_call
=============
Adding programs that access metadata kfuncs to the ``BPF_MAP_TYPE_PROG_ARRAY``
is currently not supported.
Supported Devices
=================
It is possible to query which kfunc the particular netdev implements via
netlink. See ``xdp-rx-metadata-features`` attribute set in
``Documentation/netlink/specs/netdev.yaml``.
Driver Implementation
=====================
Certain devices may prepend metadata to received packets. However, as of now,
``AF_XDP`` lacks the ability to communicate the size of the ``data_meta`` area
to the consumer. Therefore, it is the responsibility of the driver to copy any
device-reserved metadata out from the metadata area and ensure that
``xdp_buff->data_meta`` is pointing to ``xdp_buff->data`` before presenting the
frame to the XDP program. This is necessary so that, after the XDP program
adjusts the metadata area, the consumer can reliably retrieve the metadata
address using ``METADATA_SIZE`` offset.
The following diagram shows how custom metadata is positioned relative to the
packet data and how pointers are adjusted for metadata access::
|<-- bpf_xdp_adjust_meta(xdp_buff, -METADATA_SIZE) --|
new xdp_buff->data_meta old xdp_buff->data_meta
| |
| xdp_buff->data
| |
+----------+----------------------------------------------------+------+
| headroom | custom metadata | data |
+----------+----------------------------------------------------+------+
| |
| xdp_desc->addr
|<------ xsk_umem__get_data() - METADATA_SIZE -------|
``bpf_xdp_adjust_meta`` ensures that ``METADATA_SIZE`` is aligned to 4 bytes,
does not exceed 252 bytes, and leaves sufficient space for building the
xdp_frame. If these conditions are not met, it returns a negative error. In this
case, the BPF program should not proceed to populate data into the ``data_meta``
area.
Example
=======
See ``tools/testing/selftests/bpf/progs/xdp_metadata.c`` and
``tools/testing/selftests/bpf/prog_tests/xdp_metadata.c`` for an example of
BPF program that handles XDP metadata.
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
문서 범위
1-11이 문서는 eXpress Data Path(XDP) program이 helper function 집합을 사용해 packet 관련 hardware metadata에 접근하는 방법과 그 metadata를 다른 consumer에게 전달하는 방법을 설명합니다.
.. SPDX-License-Identifier: GPL-2.0
===============
XDP RX Metadata
===============
This document describes how an eXpress Data Path (XDP) program can access
hardware metadata related to a packet using a set of helper functions,
and how it can pass that metadata on to other consumers.
General Design
일반 설계와 kfunc
12-56XDP는 XDP frame metadata를 다루는 kfunc 집합에 접근할 수 있습니다. 추가 packet metadata를 공개하려는 device driver가 이 kfunc를 구현하며, 집합은 `include/net/xdp.h`의 `XDP_METADATA_KFUNC_xxx`로 선언됩니다.
현재 지원 kfunc는 `bpf_xdp_metadata_rx_timestamp`, `bpf_xdp_metadata_rx_hash`, `bpf_xdp_metadata_rx_vlan_tag`이며 앞으로 metadata 종류가 늘면 집합도 확장됩니다.
XDP program은 kfunc로 metadata를 stack variable에 읽어 직접 사용하거나 packet 앞의 metadata area에 저장해 다른 consumer에게 넘길 수 있습니다. 요청 metadata가 특정 packet에 없으면 driver는 `-ENODATA`를 반환합니다.
Driver가 모든 kfunc를 구현할 필요는 없습니다. 구현하지 않은 kfunc에는 `-EOPNOTSUPP`를 반환하는 default implementation을 사용해 driver가 지원하지 않음을 나타냅니다.
`xdp_buff`에서 frame layout은 headroom, custom metadata, data 순서이고 `xdp_buff->data_meta`가 metadata 시작, `xdp_buff->data`가 packet data 시작을 가리킵니다.
원문 ASCII layout의 pointer 경계를 구조화했습니다.
XDP program은 원하는 format으로 `data_meta`에 개별 item을 저장할 수 있습니다. 이후 consumer와 producer는 AF_XDP 예처럼 out-of-band contract로 그 format에 합의해야 합니다.
Metadata availability와 implementation 여부를 구분합니다.
==============
XDP has access to a set of kfuncs to manipulate the metadata in an XDP frame.
Every device driver that wishes to expose additional packet metadata can
implement these kfuncs. The set of kfuncs is declared in ``include/net/xdp.h``
via ``XDP_METADATA_KFUNC_xxx``.
Currently, the following kfuncs are supported. In the future, as more
metadata is supported, this set will grow:
.. kernel-doc:: net/core/xdp.c
:identifiers: bpf_xdp_metadata_rx_timestamp
.. kernel-doc:: net/core/xdp.c
:identifiers: bpf_xdp_metadata_rx_hash
.. kernel-doc:: net/core/xdp.c
:identifiers: bpf_xdp_metadata_rx_vlan_tag
An XDP program can use these kfuncs to read the metadata into stack
variables for its own consumption. Or, to pass the metadata on to other
consumers, an XDP program can store it into the metadata area carried
ahead of the packet. Not all packets will necessary have the requested
metadata available in which case the driver returns ``-ENODATA``.
Not all kfuncs have to be implemented by the device driver; when not
implemented, the default ones that return ``-EOPNOTSUPP`` will be used
to indicate the device driver have not implemented this kfunc.
Within an XDP frame, the metadata layout (accessed via ``xdp_buff``) is
as follows::
+----------+-----------------+------+
| headroom | custom metadata | data |
+----------+-----------------+------+
^ ^
| |
xdp_buff->data_meta xdp_buff->data
An XDP program can store individual metadata items into this ``data_meta``
area in whichever format it chooses. Later consumers of the metadata
will have to agree on the format by some out of band contract (like for
the AF_XDP use case, see below).
AF_XDP consumer contract
57-78AF_XDP에서는 XDP frame을 `AF_XDP` socket(`XSK`)으로 redirect하는 BPF program과 최종 consumer 사이에 metadata format contract가 있습니다.
BPF program은 `bpf_xdp_adjust_meta`로 metadata에서 고정 byte 수를 직접 할당하고 필요한 kfunc를 호출해 채웁니다. Userspace XSK consumer는 `xsk_umem__get_data() - METADATA_SIZE`로 metadata 위치를 계산합니다.
`xsk_umem__get_data`는 `libxdp`에 정의되고 `METADATA_SIZE`는 application별 constant입니다. AF_XDP receive descriptor는 metadata size를 명시적으로 담지 않습니다.
AF_XDP consumer layout에도 headroom, custom metadata, data가 있지만 `data_meta` pointer는 없고 `rx_desc->address`가 data 시작을 가리킵니다.
Descriptor data address에서 고정 계약 크기만큼 역산합니다.
AF_XDP
======
:doc:`af_xdp` use-case implies that there is a contract between the BPF
program that redirects XDP frames into the ``AF_XDP`` socket (``XSK``) and
the final consumer. Thus the BPF program manually allocates a fixed number of
bytes out of metadata via ``bpf_xdp_adjust_meta`` and calls a subset
of kfuncs to populate it. The userspace ``XSK`` consumer computes
``xsk_umem__get_data() - METADATA_SIZE`` to locate that metadata.
Note, ``xsk_umem__get_data`` is defined in ``libxdp`` and
``METADATA_SIZE`` is an application-specific constant (``AF_XDP`` receive
descriptor does _not_ explicitly carry the size of the metadata).
Here is the ``AF_XDP`` consumer layout (note missing ``data_meta`` pointer)::
+----------+-----------------+------+
| headroom | custom metadata | data |
+----------+-----------------+------+
^
|
rx_desc->address
XDP_PASS와 skb 변환
79-93`XDP_PASS` 경로에서는 XDP program이 처리한 packet을 kernel로 넘기고 kernel이 `xdp_buff` 내용으로 `skb`를 만듭니다.
현재 각 driver에는 descriptor를 parse해 `xdp_buff->skb` 변환 중 `skb` metadata를 채우는 custom kernel code가 있으며, kernel은 `skb` 생성에 XDP metadata를 사용하지 않습니다. 다만 TC-BPF program은 `data_meta` pointer로 XDP metadata area에 접근할 수 있습니다.
앞으로 XDP program이 `skb`를 만들 때 사용할 일부 metadata를 override하는 경우를 지원하는 것이 목표입니다.
XDP_PASS
========
This is the path where the packets processed by the XDP program are passed
into the kernel. The kernel creates the ``skb`` out of the ``xdp_buff``
contents. Currently, every driver has custom kernel code to parse
the descriptors and populate ``skb`` metadata when doing this ``xdp_buff->skb``
conversion, and the XDP metadata is not used by the kernel when building
``skbs``. However, TC-BPF programs can access the XDP metadata area using
the ``data_meta`` pointer.
In the future, we'd like to support a case where an XDP program
can override some of the metadata used for building ``skbs``.
bpf_redirect_map
bpf_redirect_map 이후 metadata
94-110`bpf_redirect_map`은 frame을 다른 device로 redirect할 수 있습니다. Virtual Ethernet link 같은 일부 device는 redirect 뒤 두 번째 XDP program도 실행하지만 최종 consumer는 원래 hardware descriptor에 접근할 수 없어 원본 metadata를 읽지 못합니다. Devmap과 cpumap의 XDP program에도 같습니다.
따라서 redirected packet은 현재 최초 XDP program이 redirect 전에 준비한 custom metadata만 지원합니다. Frame이 나중에 kernel로 전달되어도 생성된 `skb`에는 hardware metadata가 채워지지 않습니다. 이후 XSK로 redirect해도 custom metadata만 볼 수 있습니다.
Hardware descriptor 의존 metadata는 첫 XDP stage를 넘지 못합니다.
================
``bpf_redirect_map`` can redirect the frame to a different device.
Some devices (like virtual ethernet links) support running a second XDP
program after the redirect. However, the final consumer doesn't have
access to the original hardware descriptor and can't access any of
the original metadata. The same applies to XDP programs installed
into devmaps and cpumaps.
This means that for redirected packets only custom metadata is
currently supported, which has to be prepared by the initial XDP program
before redirect. If the frame is eventually passed to the kernel, the
``skb`` created from such a frame won't have any hardware metadata populated
in its ``skb``. If such a packet is later redirected into an ``XSK``,
that will also only have access to the custom metadata.
bpf_tail_call
bpf_tail_call 제한
111-116현재 metadata kfunc에 접근하는 program을 `BPF_MAP_TYPE_PROG_ARRAY`에 추가하는 것은 지원하지 않습니다.
=============
Adding programs that access metadata kfuncs to the ``BPF_MAP_TYPE_PROG_ARRAY``
is currently not supported.
Supported Devices
지원 device 조회
117-122특정 netdev가 구현하는 kfunc는 netlink로 조회할 수 있습니다. `Documentation/netlink/specs/netdev.yaml`의 `xdp-rx-metadata-features` attribute set을 참조합니다.
=================
It is possible to query which kfunc the particular netdev implements via
netlink. See ``xdp-rx-metadata-features`` attribute set in
``Documentation/netlink/specs/netdev.yaml``.
Driver 구현 계약과 pointer 조정
123-155일부 device는 수신 packet 앞에 metadata를 붙입니다. 현재 AF_XDP는 `data_meta` area size를 consumer에게 전달할 수 없으므로 driver가 device-reserved metadata를 metadata area 밖으로 복사해야 합니다.
Frame을 XDP program에 제시하기 전 `xdp_buff->data_meta`가 `xdp_buff->data`를 가리키도록 보장해야 합니다. 그래야 program이 metadata area를 조정한 뒤 consumer가 `METADATA_SIZE` offset으로 주소를 안정적으로 복구할 수 있습니다.
`bpf_xdp_adjust_meta(xdp_buff, -METADATA_SIZE)`는 `data_meta`를 앞쪽 headroom으로 이동해 old `data_meta`/`data`와 새 `data_meta` 사이를 custom metadata로 만듭니다. AF_XDP descriptor의 data address에서 `METADATA_SIZE`를 빼면 새 metadata 시작과 일치합니다.
원문 pointer diagram을 동일한 offset 관계로 정리했습니다.
`bpf_xdp_adjust_meta`는 `METADATA_SIZE`가 4-byte aligned이고 252 bytes를 넘지 않으며 `xdp_frame`을 만들 공간을 남기는지 확인합니다. 조건을 만족하지 않으면 negative error를 반환하고 BPF program은 `data_meta`에 값을 채우면 안 됩니다.
Custom metadata allocation의 검증 규칙입니다.
Driver Implementation
=====================
Certain devices may prepend metadata to received packets. However, as of now,
``AF_XDP`` lacks the ability to communicate the size of the ``data_meta`` area
to the consumer. Therefore, it is the responsibility of the driver to copy any
device-reserved metadata out from the metadata area and ensure that
``xdp_buff->data_meta`` is pointing to ``xdp_buff->data`` before presenting the
frame to the XDP program. This is necessary so that, after the XDP program
adjusts the metadata area, the consumer can reliably retrieve the metadata
address using ``METADATA_SIZE`` offset.
The following diagram shows how custom metadata is positioned relative to the
packet data and how pointers are adjusted for metadata access::
|<-- bpf_xdp_adjust_meta(xdp_buff, -METADATA_SIZE) --|
new xdp_buff->data_meta old xdp_buff->data_meta
| |
| xdp_buff->data
| |
+----------+----------------------------------------------------+------+
| headroom | custom metadata | data |
+----------+----------------------------------------------------+------+
| |
| xdp_desc->addr
|<------ xsk_umem__get_data() - METADATA_SIZE -------|
``bpf_xdp_adjust_meta`` ensures that ``METADATA_SIZE`` is aligned to 4 bytes,
does not exceed 252 bytes, and leaves sufficient space for building the
xdp_frame. If these conditions are not met, it returns a negative error. In this
case, the BPF program should not proceed to populate data into the ``data_meta``
area.
Selftest example
156-161XDP metadata를 처리하는 BPF program 예제는 `tools/testing/selftests/bpf/progs/xdp_metadata.c`와 test harness인 `tools/testing/selftests/bpf/prog_tests/xdp_metadata.c`에서 볼 수 있습니다.
Example
=======
See ``tools/testing/selftests/bpf/progs/xdp_metadata.c`` and
``tools/testing/selftests/bpf/prog_tests/xdp_metadata.c`` for an example of
BPF program that handles XDP metadata.
요약·해설
xdp-rx-metadata.rst:1-161XDP program은 driver가 구현한 kfunc로 RX timestamp, hash, VLAN tag를 읽고 packet 앞 `data_meta` area에 custom format으로 저장할 수 있습니다. Metadata 부재와 미지원 kfunc는 서로 다른 errno로 구분됩니다.
AF_XDP는 descriptor에 metadata size가 없으므로 producer와 consumer가 고정 `METADATA_SIZE`에 합의해야 합니다. Redirect 뒤에는 original hardware descriptor가 사라져 최초 program이 복사한 custom metadata만 유지됩니다.