sphinx.addnodesdocument)}( rawsourcechildren]( translations LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextChinese (Simplified)}parenthsba attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget"/translations/zh_CN/bpf/map_devmapmodnameN classnameN refexplicitutagnamehhh ubh)}(hhh]hChinese (Traditional)}hh2sbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget"/translations/zh_TW/bpf/map_devmapmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hItalian}hhFsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget"/translations/it_IT/bpf/map_devmapmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hJapanese}hhZsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget"/translations/ja_JP/bpf/map_devmapmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hKorean}hhnsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget"/translations/ko_KR/bpf/map_devmapmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hSpanish}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget"/translations/sp_SP/bpf/map_devmapmodnameN classnameN refexplicituh1hhh ubeh}(h]h ]h"]h$]h&]current_languageEnglishuh1h hh _documenthsourceNlineNubhcomment)}(h%SPDX-License-Identifier: GPL-2.0-onlyh]h%SPDX-License-Identifier: GPL-2.0-only}hhsbah}(h]h ]h"]h$]h&] xml:spacepreserveuh1hhhhhh or <``key``/ ``struct bpf_devmap_val``> pairs to update the maps with new net devices.h](h)}(h``BPF_MAP_TYPE_DEVMAP``h]hBPF_MAP_TYPE_DEVMAP}(hjDhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj@ubh and }(hj@hhhNhNubh)}(h``BPF_MAP_TYPE_DEVMAP_HASH``h]hBPF_MAP_TYPE_DEVMAP_HASH}(hjVhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj@ubhI are BPF maps primarily used as backend maps for the XDP BPF helper call }(hj@hhhNhNubh)}(h``bpf_redirect_map()``h]hbpf_redirect_map()}(hjhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj@ubh. }(hj@hhhNhNubh)}(h``BPF_MAP_TYPE_DEVMAP``h]hBPF_MAP_TYPE_DEVMAP}(hjzhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj@ubhc is backed by an array that uses the key as the index to lookup a reference to a net device. While }(hj@hhhNhNubh)}(h``BPF_MAP_TYPE_DEVMAP_HASH``h]hBPF_MAP_TYPE_DEVMAP_HASH}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj@ubhl is backed by a hash table that uses a key to lookup a reference to a net device. The user provides either <}(hj@hhhNhNubh)}(h``key``h]hkey}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj@ubh/ }(hj@hhhNhNubh)}(h ``ifindex``h]hifindex}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj@ubh> or <}(hj@hhhNhNubh)}(h``key``h]hkey}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj@ubh/ }hj@sbh)}(h``struct bpf_devmap_val``h]hstruct bpf_devmap_val}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj@ubh0> pairs to update the maps with new net devices.}(hj@hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK hhhhubh)}(h- The key to a hash map doesn't have to be an ``ifindex``. - While ``BPF_MAP_TYPE_DEVMAP_HASH`` allows for densely packing the net devices it comes at the cost of a hash of the key when performing a look up.h]h)}(hhh](h)}(h8The key to a hash map doesn't have to be an ``ifindex``.h]h)}(hjh](h.The key to a hash map doesn’t have to be an }(hjhhhNhNubh)}(h ``ifindex``h]hifindex}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1hhjubh)}(hWhile ``BPF_MAP_TYPE_DEVMAP_HASH`` allows for densely packing the net devices it comes at the cost of a hash of the key when performing a look up.h]h)}(hWhile ``BPF_MAP_TYPE_DEVMAP_HASH`` allows for densely packing the net devices it comes at the cost of a hash of the key when performing a look up.h](hWhile }(hj hhhNhNubh)}(h``BPF_MAP_TYPE_DEVMAP_HASH``h]hBPF_MAP_TYPE_DEVMAP_HASH}(hj(hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubhp allows for densely packing the net devices it comes at the cost of a hash of the key when performing a look up.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1hhjubeh}(h]h ]h"]h$]h&]j8j9uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1hhhhhhNhNubh)}(h}The setup and packet enqueue/send code is shared between the two types of devmap; only the lookup and insertion is different.h]h}The setup and packet enqueue/send code is shared between the two types of devmap; only the lookup and insertion is different.}(hjRhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hhh](h)}(hUsageh]hUsage}(hjchhhNhNubah}(h]h ]h"]h$]h&]uh1hhj`hhhhhKubh)}(hhh](h)}(h Kernel BPFh]h Kernel BPF}(hjthhhNhNubah}(h]h ]h"]h$]h&]uh1hhjqhhhhhKubh)}(hhh](h)}(hbpf_redirect_map()h]hbpf_redirect_map()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhK!ubh literal_block)}(h>long bpf_redirect_map(struct bpf_map *map, u32 key, u64 flags)h]h>long bpf_redirect_map(struct bpf_map *map, u32 key, u64 flags)}hjsbah}(h]h ]h"]h$]h&]hhforcelanguagechighlight_args}uh1jhhhK"hjhhubh)}(hRedirect the packet to the endpoint referenced by ``map`` at index ``key``. For ``BPF_MAP_TYPE_DEVMAP`` and ``BPF_MAP_TYPE_DEVMAP_HASH`` this map contains references to net devices (for forwarding packets through other ports).h](h2Redirect the packet to the endpoint referenced by }(hjhhhNhNubh)}(h``map``h]hmap}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh at index }(hjhhhNhNubh)}(h``key``h]hkey}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh. For }(hjhhhNhNubh)}(h``BPF_MAP_TYPE_DEVMAP``h]hBPF_MAP_TYPE_DEVMAP}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh and }(hjhhhNhNubh)}(h``BPF_MAP_TYPE_DEVMAP_HASH``h]hBPF_MAP_TYPE_DEVMAP_HASH}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubhZ this map contains references to net devices (for forwarding packets through other ports).}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK&hjhhubh)}(hX7The lower two bits of *flags* are used as the return code if the map lookup fails. This is so that the return value can be one of the XDP program return codes up to ``XDP_TX``, as chosen by the caller. The higher bits of ``flags`` can be set to ``BPF_F_BROADCAST`` or ``BPF_F_EXCLUDE_INGRESS`` as defined below.h](hThe lower two bits of }(hjhhhNhNubhemphasis)}(h*flags*h]hflags}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh are used as the return code if the map lookup fails. This is so that the return value can be one of the XDP program return codes up to }(hjhhhNhNubh)}(h ``XDP_TX``h]hXDP_TX}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh., as chosen by the caller. The higher bits of }(hjhhhNhNubh)}(h ``flags``h]hflags}(hj,hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh can be set to }(hjhhhNhNubh)}(h``BPF_F_BROADCAST``h]hBPF_F_BROADCAST}(hj>hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh or }(hjhhhNhNubh)}(h``BPF_F_EXCLUDE_INGRESS``h]hBPF_F_EXCLUDE_INGRESS}(hjPhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh as defined below.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK*hjhhubh)}(hWith ``BPF_F_BROADCAST`` the packet will be broadcast to all the interfaces in the map, with ``BPF_F_EXCLUDE_INGRESS`` the ingress interface will be excluded from the broadcast.h](hWith }(hjhhhhNhNubh)}(h``BPF_F_BROADCAST``h]hBPF_F_BROADCAST}(hjphhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhubhE the packet will be broadcast to all the interfaces in the map, with }(hjhhhhNhNubh)}(h``BPF_F_EXCLUDE_INGRESS``h]hBPF_F_EXCLUDE_INGRESS}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhubh; the ingress interface will be excluded from the broadcast.}(hjhhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK0hjhhubh)}(h- The key is ignored if BPF_F_BROADCAST is set. - The broadcast feature can also be used to implement multicast forwarding: simply create multiple DEVMAPs, each one corresponding to a single multicast group.h]h)}(hhh](h)}(h-The key is ignored if BPF_F_BROADCAST is set.h]h)}(hjh]h-The key is ignored if BPF_F_BROADCAST is set.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK5hjubah}(h]h ]h"]h$]h&]uh1hhjubh)}(hThe broadcast feature can also be used to implement multicast forwarding: simply create multiple DEVMAPs, each one corresponding to a single multicast group.h]h)}(hThe broadcast feature can also be used to implement multicast forwarding: simply create multiple DEVMAPs, each one corresponding to a single multicast group.h]hThe broadcast feature can also be used to implement multicast forwarding: simply create multiple DEVMAPs, each one corresponding to a single multicast group.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK6hjubah}(h]h ]h"]h$]h&]uh1hhjubeh}(h]h ]h"]h$]h&]j8j9uh1hhhhK5hjubah}(h]h ]h"]h$]h&]uh1hhjhhhNhNubh)}(hThis helper will return ``XDP_REDIRECT`` on success, or the value of the two lower bits of the ``flags`` argument if the map lookup fails.h](hThis helper will return }(hjhhhNhNubh)}(h``XDP_REDIRECT``h]h XDP_REDIRECT}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh7 on success, or the value of the two lower bits of the }(hjhhhNhNubh)}(h ``flags``h]hflags}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh" argument if the map lookup fails.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK9hjhhubh)}(h?More information about redirection can be found :doc:`redirect`h](h0More information about redirection can be found }(hjhhhNhNubh)}(h:doc:`redirect`h]hinline)}(hjh]hredirect}(hjhhhNhNubah}(h]h ](xrefstdstd-doceh"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]refdocbpf/map_devmap refdomainj'reftypedoc refexplicitrefwarn reftargetredirectuh1hhhhK``tools/testing/selftests/bpf/prog_tests/xdp_devmap_attach.c``h]h)}(hjh]h)}(hjh]h:tools/testing/selftests/bpf/prog_tests/xdp_devmap_attach.c}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]uh1hhhhKphjubah}(h]h ]h"]h$]h&]uh1hhjhhhhhNubh)}(hE``tools/testing/selftests/bpf/progs/test_xdp_with_devmap_helpers.c`` h]h)}(hD``tools/testing/selftests/bpf/progs/test_xdp_with_devmap_helpers.c``h]h)}(hjh]h@tools/testing/selftests/bpf/progs/test_xdp_with_devmap_helpers.c}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]uh1hhhhKqhjubah}(h]h ]h"]h$]h&]uh1hhjhhhhhNubeh}(h]h ]h"]h$]h&]j8j9uh1hhhhKphjhhubeh}(h]bpf-map-update-elemah ]h"]bpf_map_update_elem()ah$]h&]uh1hhjhhhhhKOubh)}(hhh](h)}(hbpf_map_lookup_elem()h]hbpf_map_lookup_elem()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKtubj)}(hhh]h}(h]h ]h"]h$]h&]hhjjjj}uh1jhhhKuhjhhubhindex)}(hhh]h}(h]h ]h"]h$]h&]entries](single bpf_map_lookup_elem (C function)c.bpf_map_lookup_elemhNtauh1jhjhhhNhNubhdesc)}(hhh](hdesc_signature)}(h>int bpf_map_lookup_elem(int fd, const void *key, void *value);h]hdesc_signature_line)}(h>int bpf_map_lookup_elem(int fd, const void *key, void *value);h](hdesc_sig_keyword_type)}(hinth]hint}(hjhhhNhNubah}(h]h ]ktah"]h$]h&]uh1jhjhhhhhKwubhdesc_sig_space)}(h h]h }(hj-hhhNhNubah}(h]h ]wah"]h$]h&]uh1j+hjhhhhhKwubh desc_name)}(hbpf_map_lookup_elemh]h desc_sig_name)}(hbpf_map_lookup_elemh]hbpf_map_lookup_elem}(hjDhhhNhNubah}(h]h ]nah"]h$]h&]uh1jBhj>ubah}(h]h ](sig-namedescnameeh"]h$]h&]hhuh1j<hjhhhhhKwubhdesc_parameterlist)}(h&(int fd, const void *key, void *value)h](hdesc_parameter)}(hint fdh](j)}(hinth]hint}(hjghhhNhNubah}(h]h ]j'ah"]h$]h&]uh1jhjcubj,)}(h h]h }(hjuhhhNhNubah}(h]h ]j8ah"]h$]h&]uh1j+hjcubjC)}(hfdh]hfd}(hjhhhNhNubah}(h]h ]jOah"]h$]h&]uh1jBhjcubeh}(h]h ]h"]h$]h&]noemphhhuh1jahj]ubjb)}(hconst void *keyh](hdesc_sig_keyword)}(hconsth]hconst}(hjhhhNhNubah}(h]h ]kah"]h$]h&]uh1jhjubj,)}(h h]h }(hjhhhNhNubah}(h]h ]j8ah"]h$]h&]uh1j+hjubj)}(hvoidh]hvoid}(hjhhhNhNubah}(h]h ]j'ah"]h$]h&]uh1jhjubj,)}(h h]h }(hjhhhNhNubah}(h]h ]j8ah"]h$]h&]uh1j+hjubhdesc_sig_punctuation)}(h*h]h*}(hjhhhNhNubah}(h]h ]pah"]h$]h&]uh1jhjubjC)}(hkeyh]hkey}(hjhhhNhNubah}(h]h ]jOah"]h$]h&]uh1jBhjubeh}(h]h ]h"]h$]h&]noemphhhuh1jahj]ubjb)}(h void *valueh](j)}(hvoidh]hvoid}(hjhhhNhNubah}(h]h ]j'ah"]h$]h&]uh1jhjubj,)}(h h]h }(hjhhhNhNubah}(h]h ]j8ah"]h$]h&]uh1j+hjubj)}(hjh]h*}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubjC)}(hvalueh]hvalue}(hj*hhhNhNubah}(h]h ]jOah"]h$]h&]uh1jBhjubeh}(h]h ]h"]h$]h&]noemphhhuh1jahj]ubeh}(h]h ]h"]h$]h&]hhuh1j[hjhhhhhKwubj)}(h;h]h;}(hjEhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjhhhhhKwubeh}(h]h ]h"]h$]h&]hh add_permalinkuh1jsphinx_line_type declaratorhjhhhhhKwubah}(h]jah ](sig sig-objecteh"]h$]h&] is_multiline _toc_parts) _toc_namehuh1jhhhKwhj hhubh desc_content)}(hhh]h}(h]h ]h"]h$]h&]uh1jghj hhhhhKwubeh}(h]h ](jfunctioneh"]h$]h&]domainjobjtypejudesctypejunoindex noindexentrynocontentsentryuh1j hhhjhNhNubh)}(hONet device entries can be retrieved using the ``bpf_map_lookup_elem()`` helper.h](h.Net device entries can be retrieved using the }(hjhhhNhNubh)}(h``bpf_map_lookup_elem()``h]hbpf_map_lookup_elem()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh helper.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKzhjhhubeh}(h]id1ah ]h"]h$]jah&]uh1hhjhhhhhKtjKubh)}(hhh](h)}(hbpf_map_delete_elem()h]hbpf_map_delete_elem()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhK~ubj)}(hhh]h}(h]h ]h"]h$]h&]hhjjjj}uh1jhhhKhjhhubj)}(hhh]h}(h]h ]h"]h$]h&]entries](j bpf_map_delete_elem (C function)c.bpf_map_delete_elemhNtauh1jhjhhhNhNubj )}(hhh](j)}(h1int bpf_map_delete_elem(int fd, const void *key);h]j)}(h1int bpf_map_delete_elem(int fd, const void *key);h](j)}(hinth]hint}(hjhhhNhNubah}(h]h ]j'ah"]h$]h&]uh1jhjhhhhhKubj,)}(h h]h }(hjhhhNhNubah}(h]h ]j8ah"]h$]h&]uh1j+hjhhhhhKubj=)}(hbpf_map_delete_elemh]jC)}(hbpf_map_delete_elemh]hbpf_map_delete_elem}(hjhhhNhNubah}(h]h ]jOah"]h$]h&]uh1jBhjubah}(h]h ](jVjWeh"]h$]h&]hhuh1j<hjhhhhhKubj\)}(h(int fd, const void *key)h](jb)}(hint fdh](j)}(hinth]hint}(hj hhhNhNubah}(h]h ]j'ah"]h$]h&]uh1jhj ubj,)}(h h]h }(hj$ hhhNhNubah}(h]h ]j8ah"]h$]h&]uh1j+hj ubjC)}(hfdh]hfd}(hj2 hhhNhNubah}(h]h ]jOah"]h$]h&]uh1jBhj ubeh}(h]h ]h"]h$]h&]noemphhhuh1jahj ubjb)}(hconst void *keyh](j)}(hjh]hconst}(hjK hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjG ubj,)}(h h]h }(hjX hhhNhNubah}(h]h ]j8ah"]h$]h&]uh1j+hjG ubj)}(hvoidh]hvoid}(hjf hhhNhNubah}(h]h ]j'ah"]h$]h&]uh1jhjG ubj,)}(h h]h }(hjt hhhNhNubah}(h]h ]j8ah"]h$]h&]uh1j+hjG ubj)}(hjh]h*}(hj hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjG ubjC)}(hkeyh]hkey}(hj hhhNhNubah}(h]h ]jOah"]h$]h&]uh1jBhjG ubeh}(h]h ]h"]h$]h&]noemphhhuh1jahj ubeh}(h]h ]h"]h$]h&]hhuh1j[hjhhhhhKubj)}(hjGh]h;}(hj hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjhhhhhKubeh}(h]h ]h"]h$]h&]hhjYuh1jjZj[hjhhhhhKubah}(h]jah ](j_j`eh"]h$]h&]jdje)jfhuh1jhhhKhjhhubjh)}(hhh]h}(h]h ]h"]h$]h&]uh1jghjhhhhhKubeh}(h]h ](jfunctioneh"]h$]h&]jyjjzj j{j j|j}j~uh1j hhhjhNhNubh)}(hNet device entries can be deleted using the ``bpf_map_delete_elem()`` helper. This helper will return 0 on success, or negative error in case of failure.h](h,Net device entries can be deleted using the }(hj hhhNhNubh)}(h``bpf_map_delete_elem()``h]hbpf_map_delete_elem()}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubhT helper. This helper will return 0 on success, or negative error in case of failure.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubeh}(h]bpf-map-delete-elemah ]h"]bpf_map_delete_elem()ah$]h&]uh1hhjhhhhhK~ubeh}(h] user-spaceah ]h"]h$] user spaceah&]uh1hhj`hhhhhKHjKubeh}(h]usageah ]h"]usageah$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(hExamplesh]hExamples}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhKubh)}(hhh](h)}(h Kernel BPFh]h Kernel BPF}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhKubh)}(hYThe following code snippet shows how to declare a ``BPF_MAP_TYPE_DEVMAP`` called tx_port.h](h2The following code snippet shows how to declare a }(hj- hhhNhNubh)}(h``BPF_MAP_TYPE_DEVMAP``h]hBPF_MAP_TYPE_DEVMAP}(hj5 hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj- ubh called tx_port.}(hj- hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj hhubj)}(hstruct { __uint(type, BPF_MAP_TYPE_DEVMAP); __type(key, __u32); __type(value, __u32); __uint(max_entries, 256); } tx_port SEC(".maps");h]hstruct { __uint(type, BPF_MAP_TYPE_DEVMAP); __type(key, __u32); __type(value, __u32); __uint(max_entries, 256); } tx_port SEC(".maps");}hjM sbah}(h]h ]h"]h$]h&]hhjjjj}uh1jhhhKhj hhubh)}(hbThe following code snippet shows how to declare a ``BPF_MAP_TYPE_DEVMAP_HASH`` called forward_map.h](h2The following code snippet shows how to declare a }(hj\ hhhNhNubh)}(h``BPF_MAP_TYPE_DEVMAP_HASH``h]hBPF_MAP_TYPE_DEVMAP_HASH}(hjd hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj\ ubh called forward_map.}(hj\ hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj hhubj)}(hstruct { __uint(type, BPF_MAP_TYPE_DEVMAP_HASH); __type(key, __u32); __type(value, struct bpf_devmap_val); __uint(max_entries, 32); } forward_map SEC(".maps");h]hstruct { __uint(type, BPF_MAP_TYPE_DEVMAP_HASH); __type(key, __u32); __type(value, struct bpf_devmap_val); __uint(max_entries, 32); } forward_map SEC(".maps");}hj| sbah}(h]h ]h"]h$]h&]hhjjjj}uh1jhhhKhj hhubh)}(hAThe value type in the DEVMAP above is a ``struct bpf_devmap_val``h]h)}(hj h](h(The value type in the DEVMAP above is a }(hj hhhNhNubh)}(h``struct bpf_devmap_val``h]hstruct bpf_devmap_val}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubeh}(h]h ]h"]h$]h&]uh1hhhhKhj ubah}(h]h ]h"]h$]h&]uh1hhj hhhhhNubh)}(hXThe following code snippet shows a simple xdp_redirect_map program. This program would work with a user space program that populates the devmap ``forward_map`` based on ingress ifindexes. The BPF program (below) is redirecting packets using the ingress ``ifindex`` as the ``key``.h](hThe following code snippet shows a simple xdp_redirect_map program. This program would work with a user space program that populates the devmap }(hj hhhNhNubh)}(h``forward_map``h]h forward_map}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubh^ based on ingress ifindexes. The BPF program (below) is redirecting packets using the ingress }(hj hhhNhNubh)}(h ``ifindex``h]hifindex}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubh as the }(hj hhhNhNubh)}(h``key``h]hkey}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubh.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj hhubj)}(hSEC("xdp") int xdp_redirect_map_func(struct xdp_md *ctx) { int index = ctx->ingress_ifindex; return bpf_redirect_map(&forward_map, index, 0); }h]hSEC("xdp") int xdp_redirect_map_func(struct xdp_md *ctx) { int index = ctx->ingress_ifindex; return bpf_redirect_map(&forward_map, index, 0); }}hj sbah}(h]h ]h"]h$]h&]hhjjjj}uh1jhhhKhj hhubh)}(h|The following code snippet shows a BPF program that is broadcasting packets to all the interfaces in the ``tx_port`` devmap.h](hiThe following code snippet shows a BPF program that is broadcasting packets to all the interfaces in the }(hj hhhNhNubh)}(h ``tx_port``h]htx_port}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubh devmap.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj hhubj)}(hSEC("xdp") int xdp_redirect_map_func(struct xdp_md *ctx) { return bpf_redirect_map(&tx_port, 0, BPF_F_BROADCAST | BPF_F_EXCLUDE_INGRESS); }h]hSEC("xdp") int xdp_redirect_map_func(struct xdp_md *ctx) { return bpf_redirect_map(&tx_port, 0, BPF_F_BROADCAST | BPF_F_EXCLUDE_INGRESS); }}hj# sbah}(h]h ]h"]h$]h&]hhjjjj}uh1jhhhKhj hhubeh}(h]id2ah ]h"]h$]jah&]uh1hhj hhhhhKjKubh)}(hhh](h)}(h User spaceh]h User space}(hj< hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj9 hhhhhKubh)}(hKThe following code snippet shows how to update a devmap called ``tx_port``.h](h?The following code snippet shows how to update a devmap called }(hjJ hhhNhNubh)}(h ``tx_port``h]htx_port}(hjR hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjJ ubh.}(hjJ hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj9 hhubj)}(hX#int update_devmap(int ifindex, int redirect_ifindex) { int ret; ret = bpf_map_update_elem(bpf_map__fd(tx_port), &ifindex, &redirect_ifindex, 0); if (ret < 0) { fprintf(stderr, "Failed to update devmap_ value: %s\n", strerror(errno)); } return ret; }h]hX#int update_devmap(int ifindex, int redirect_ifindex) { int ret; ret = bpf_map_update_elem(bpf_map__fd(tx_port), &ifindex, &redirect_ifindex, 0); if (ret < 0) { fprintf(stderr, "Failed to update devmap_ value: %s\n", strerror(errno)); } return ret; }}hjj sbah}(h]h ]h"]h$]h&]hhjjjj}uh1jhhhKhj9 hhubh)}(hTThe following code snippet shows how to update a hash_devmap called ``forward_map``.h](hDThe following code snippet shows how to update a hash_devmap called }(hjy hhhNhNubh)}(h``forward_map``h]h forward_map}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjy ubh.}(hjy hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj9 hhubj)}(hXhint update_devmap(int ifindex, int redirect_ifindex) { struct bpf_devmap_val devmap_val = { .ifindex = redirect_ifindex }; int ret; ret = bpf_map_update_elem(bpf_map__fd(forward_map), &ifindex, &devmap_val, 0); if (ret < 0) { fprintf(stderr, "Failed to update devmap_ value: %s\n", strerror(errno)); } return ret; }h]hXhint update_devmap(int ifindex, int redirect_ifindex) { struct bpf_devmap_val devmap_val = { .ifindex = redirect_ifindex }; int ret; ret = bpf_map_update_elem(bpf_map__fd(forward_map), &ifindex, &devmap_val, 0); if (ret < 0) { fprintf(stderr, "Failed to update devmap_ value: %s\n", strerror(errno)); } return ret; }}hj sbah}(h]h ]h"]h$]h&]hhjjjj}uh1jhhhKhj9 hhubeh}(h]id3ah ]h"]h$]j ah&]uh1hhj hhhhhKjKubeh}(h]examplesah ]h"]examplesah$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(h Referencesh]h References}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhKubh)}(hhh](h)}(h https://lwn.net/Articles/728146/h]h)}(hj h]h reference)}(hj h]h https://lwn.net/Articles/728146/}(hj hhhNhNubah}(h]h ]h"]h$]h&]refurij uh1j hj ubah}(h]h ]h"]h$]h&]uh1hhhhKhj ubah}(h]h ]h"]h$]h&]uh1hhj hhhhhNubh)}(hthttps://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git/commit/?id=6f9d451ab1a33728adb72d7ff66a7b374d665176h]h)}(hj h]j )}(hj h]hthttps://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git/commit/?id=6f9d451ab1a33728adb72d7ff66a7b374d665176}(hj hhhNhNubah}(h]h ]h"]h$]h&]refurij uh1j hj ubah}(h]h ]h"]h$]h&]uh1hhhhKhj ubah}(h]h ]h"]h$]h&]uh1hhj hhhhhNubh)}(hFhttps://elixir.bootlin.com/linux/latest/source/net/core/filter.c#L4106h]h)}(hj h]j )}(hj h]hFhttps://elixir.bootlin.com/linux/latest/source/net/core/filter.c#L4106}(hj hhhNhNubah}(h]h ]h"]h$]h&]refurij uh1j hj ubah}(h]h ]h"]h$]h&]uh1hhhhKhj ubah}(h]h ]h"]h$]h&]uh1hhj hhhhhNubeh}(h]h ]h"]h$]h&]j8j9uh1hhhhKhj hhubeh}(h] referencesah ]h"] referencesah$]h&]uh1hhhhhhhhKubeh}(h]0bpf-map-type-devmap-and-bpf-map-type-devmap-hashah ]h"]0bpf_map_type_devmap and bpf_map_type_devmap_hashah$]h&]uh1hhhhhhhhKubeh}(h]h ]h"]h$]h&]sourcehuh1hcurrent_sourceN current_lineNsettingsdocutils.frontendValues)}(hN generatorN datestampN source_linkN source_urlN toc_backlinksentryfootnote_backlinksK sectnum_xformKstrip_commentsNstrip_elements_with_classesN strip_classesN report_levelK halt_levelKexit_status_levelKdebugNwarning_streamN tracebackinput_encoding utf-8-siginput_encoding_error_handlerstrictoutput_encodingutf-8output_encoding_error_handlerji error_encodingutf-8error_encoding_error_handlerbackslashreplace language_codeenrecord_dependenciesNconfigN id_prefixhauto_id_prefixid dump_settingsNdump_internalsNdump_transformsNdump_pseudo_xmlNexpose_internalsNstrict_visitorN_disable_configN_sourceh _destinationN _config_files]7/var/lib/git/docbuild/linux/Documentation/docutils.confafile_insertion_enabled raw_enabledKline_length_limitM'pep_referencesN pep_base_urlhttps://peps.python.org/pep_file_url_templatepep-%04drfc_referencesN rfc_base_url&https://datatracker.ietf.org/doc/html/ tab_widthKtrim_footnote_reference_spacesyntax_highlightlong smart_quotessmartquotes_locales]character_level_inline_markupdoctitle_xform docinfo_xformKsectsubtitle_xform image_loadinglinkembed_stylesheetcloak_email_addressessection_self_linkenvNubreporterNindirect_targets]substitution_defs}substitution_names}refnames}refids}nameids}(jC j@ j j kernel bpfNjFjCbpf_map_lookup_elem()N user spaceNjjj j j j j; j8 u nametypes}(jC j j jFj j jj j j; uh}(j@ hj j`jjqjCjjjIj jjjjjjjj jjjj j j4 j j j9 j8 j u footnote_refs} citation_refs} autofootnotes]autofootnote_refs]symbol_footnotes]symbol_footnote_refs] footnotes] citations]autofootnote_startKsymbol_footnote_startK id_counter collectionsCounter}jw KsRparse_messages](hsystem_message)}(hhh]h)}(h8Duplicate implicit target name: "bpf_map_lookup_elem()".h]h