Linux�ɂ����闘�p���}���ɑ����Ă���uBerkeley Packet Filter�iBPF�j�v�ɂ��āA��b���牞�p�܂ŕ��L���Љ��A�ځB����́A�ł���{�ƂȂ�C����ɂ��BPF�v���O�����쐬���@����юg�p���@�ɂ��āB
���̋L���͉������ł��B����o�^�i�����j����ƑS�Ă������������܂��B
�@Linux�ɂ����闘�p���}���ɑ����Ă���uBerkeley Packet Filter�iBPF�j�v�ɂ��āA��b���牞�p�܂ŕ��L���Љ��A�ځuBerkeley Packet Filter�iBPF�j�����v�B�O�X���܂ł́ABPF�̊�{��BPF�̃v���O�����̍쐬���@��������܂����B�O������A�uLinux��BPF�ʼn����ł���̂��v�ɂ��ďڂ������Ă��܂��B
�@���炳�܂��܂�BPF�v���O�������쐬����BPF�̎g�������w��ł����܂��傤�B
��Ƃ��č���̓\�P�b�g�ɑ���BPF�v���O�������쐬���܂��BBPF���g���ƁA�J�[�l�����Ŏ�M�p�P�b�g���t�B���^�����O������A�p�P�b�g�̓��v�����L�^�����肷�邱�Ƃ��ł��܂��B
�@�O�X��Ő��������ʂ�ABPF�v���O�����̍쐬���@�͕�������܂��B�����ł�BPF�ɂ��ďڂ����m�邽�߂ɁA�ł���{�ƂȂ�C����ɂ��BPF�v���O�����쐬���@����юg�p���@���Љ�܂��B
�@�Ȃ������̏ꍇ�́A�����x���̃��C�u�����ibcc�Ȃǁj�𗘗p���邱�Ƃł��y��BPF�v���O�������쐬���邱�Ƃ��ł��܂��Bbcc�ɂ��Ă͎���������܂��B
�@�{�e�ł�Ubuntu 18.04.�iLinux kernel 5.0.0-31-generic�j�𗘗p���܂��BBPF�̋@�\�͔��Ɋ����ɊJ������Ă��܂��B����BPF�v���O���������삵�Ȃ��ꍇ�̓J�[�l���̃o�[�W�������m�F���Ă݂Ă��������B����쐬����BPF�v���O������Linux 4.1�ȏ�ł���Γ��삷��Ǝv���܂��B
�@�܂��ABPF�𗘗p����ɂ�BPF�Ɋւ���J�[�l���R���t�B�O���L���ł���K�v������܂��B�ȉ��̂悤�ɂ��ăJ�[�l����BPF�Ɋւ���ݒ肪�m�F�ł��܂��B
% grep BPF /boot/config-`uname -r` CONFIG_CGROUP_BPF=y CONFIG_BPF=y CONFIG_BPF_SYSCALL=y CONFIG_BPF_JIT_ALWAYS_ON=y CONFIG_IPV6_SEG6_BPF=y CONFIG_NETFILTER_XT_MATCH_BPF=m CONFIG_BPFILTER=y CONFIG_BPFILTER_UMH=m CONFIG_NET_CLS_BPF=m CONFIG_NET_ACT_BPF=m CONFIG_BPF_JIT=y CONFIG_BPF_STREAM_PARSER=y CONFIG_LWTUNNEL_BPF=y CONFIG_HAVE_EBPF_JIT=y CONFIG_BPF_EVENTS=y CONFIG_BPF_KPROBE_OVERRIDE=y CONFIG_TEST_BPF=m
�@Ubuntu 18.04�ł�BPF�@�\���L��������Ă��܂��B
�@Linux�J�[�l���̃\�[�X�ɂ�BPF�̃T���v���v���O�������܂܂�Ă��܂��i�\�[�X�f�B���N�g���j�B
�@BPF�̓����m��̂ɕ֗��ȃT���v���v���O�����ł��B����́A���̃T���v���v���O����������BPF�̓�������Ă����܂��B
�@���̃T���v���R�[�h�ł����A�J�[�l���̃r���h�V�X�e���𗘗p���Ă��邽�߁A���̂܂܂ł̓T���v���v���O�����݂̂��擾���ăR���p�C�����邱�Ƃ͂ł��܂���B�V�X�e�������p���Ă���J�[�l���̃\�[�X�R�[�h���擾���ăR���p�C������̂������ł��傤�B
�@Ubuntu�ł���A�ȉ��̂悤�ɂ��čŐV�̃\�[�X���擾�\�ł��B
sudo apt get linux-source-5.0.0 cp /usr/src/linux-source-5.0.0/linux-source-5.0.0.tar.bz2 . tar jxvf linux-source-5.0.0.tar.bz2
�@���邢�́Agit���|�W�g���������̃o�[�W�����̂��̂��擾���邱�Ƃ��ł��܂��B
git clone git://kernel.ubuntu.com/ubuntu/ubuntu-bionic.git -b Ubuntu-hwe-5.0.0-31.33_18.04.1 --depth 1
�@�V�X�e���̃J�[�l���̃o�[�W�����́ucat /proc/version_signature�v�R�}���h�Œ��ׂ邱�Ƃ��ł��܂��B�܂��u-b Ubuntu-hwe-5.0.0-31.33_18.04.1�v�R�}���h�Ń��|�W�g���̓���̃^�O���`�F�b�N�A�E�g���Ă��܂��B
�@�w��\�ȃ^�O������������m�F�ł��܂��iUbuntu bionic�̏ꍇ�B����ȊO������������T���܂��j�B
�@�\�[�X���擾�ł�����A�ȉ��̂悤�ɂ���BPF�̃T���v���v���O�������R���p�C�����܂��B
sudo apt install build-essential clang llvm flex bison libelf-dev cd <�J�[�l���\�[�X�f�B���N�g��> make olddefconfig make headers_install make samples/bpf/ # ������"/"��t����
�@samples/bpf�ȉ��ɃT���v���v���O�������R���p�C������܂��BBPF�v���O������LLVM��Clang��p����BPF�̃o�C�g�R�[�h������ELF�I�u�W�F�N�g�ɃR���p�C������Ă��܂��B
�@�ŋ߂ł̓R���e�i�̗��p�������ԕ��y���܂����B�����ŁA�R���e�i����BPF�v���O���������s���Ă݂����Ǝv����������邩������܂���B�������ABPF�̓J�[�l���̋@�\�𗘗p������̂Ȃ̂ŁA��ʂɃT���h�{�b�N�X���ł���R���e�i���ł�BPF�̗��p�͐�������܂��B
�@Docker�̓f�t�H���g�Łuseccomp�v�𗘗p�����R���e�i���ł�bpf�V�X�e���R�[���̗��p�𐧌����Ă��܂��B���̐������u--privileged�v�I�v�V������t���ăR���e�i���N�����邱�Ƃʼn���\�ł��B
�@�������A���R�Ȃ��炱�̎�@�̓R���e�i�ɓ�����^���邱�ƂɂȂ�̂ł��̓_�͒��ӂ��K�v�ł��B
�@�T���v���v���O�����̃f�B���N�g�����ł́A�uxxx_user.c�v�����[�U�[�����h�̃v���O�����A�uxxx_kern.c�v�����̃v���O�������ŗ��p�����BPF�v���O�����Ƃ����\���ɂȂ��Ă��܂��B
�@����́A���̒��̃\�P�b�g�ɑ���T���v���v���O�����usockex1_user.c�v�usockex1_kern.c�v�����Ă����܂��B
�@���̃v���O�����́ABPF��p����IP�w�b�_�̃v���g�R���^�C�v�ʂɎ�M�����p�P�b�g�̗v�̃f�[�^�T�C�Y���L�^���܂��B
�@�usockex1_user.c�v�́usockex1�v�Ƃ����v���O�����ɃR���p�C������܂��B�v���O���������s����ƁA1�b���ƂɃv���g�R���ʂɎ�M�����p�P�b�g�T�C�Y��\�����܂��B
% sudo ./sockex1 TCP 0 UDP 0 ICMP 0 bytes TCP 0 UDP 0 ICMP 196 bytes TCP 0 UDP 0 ICMP 392 bytes TCP 0 UDP 0 ICMP 588 bytes TCP 0 UDP 0 ICMP 784 bytes
�@�Ȃ��A���ɂ���Ă͏o�͂��S��0�ɂȂ邩������܂���B�M�҂����������iUbuntu 18.04.3�j���ƁA�uping localhost�v�����M����p�P�b�g��IPv6�́uHop-by-hop�w�b�_�v���t�����Ă���ICMP�p�P�b�g�Ƃ��Čv������Ă��܂���ł����B���̂悤�ȏꍇ�A�usockex1_user.c�v�̉��L�R�[�h��
f = popen("ping -c5 localhost", "r");
���L�ɕς��Ď��s���Ă݂Ă��������i�ŐV�ł̃J�[�l���ł͂���͏C������Ă��܂��j�B
f = popen("ping -4 -c5 localhost", "r");
�@�ȉ��ŋ�̓I�ȃv���O�����̓��e�����Ă����܂��B
�@�܂��A���[�U�[�����h���̃v���O�����usockex1_user.c�v�����Ă݂܂��傤�i�R�����g�͕M�҂ɂ����̂ł��j�B
// SPDX-License-Identifier: GPL-2.0 #include <stdio.h> #include <assert.h> #include <linux/bpf.h> #include <bpf/bpf.h> #include "bpf_load.h" #include "sock_example.h" #include <unistd.h> #include <arpa/inet.h> int main(int ac, char **argv) { char filename[256]; FILE *f; int i, sock; snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]); // �y1�zsockex1_kern.o�Ƃ��ăR���p�C�����ꂽBPF�v���O���������[�h // �� BPF�}�b�v�̍쐬 if (load_bpf_file(filename)) { printf("%s", bpf_log_buf); return 1; } // �y2�z���[�v�o�b�N�f�o�C�X��open sock = open_raw_sock("lo"); // �y3�z�����Ły2�z�̃\�P�b�g�ɑ��āy1�z�Ń��[�h����BPF�v���O�������A�^�b�` assert(setsockopt(sock, SOL_SOCKET, SO_ATTACH_BPF, prog_fd, sizeof(prog_fd[0])) == 0); // �y4�z�����̂��߂Ƀ��[�v�o�b�N�f�o�C�X�ɑ���ping�R�}���h�Ńp�P�b�g���M f = popen("ping -c5 localhost", "r"); (void) f; // �y5�z1�b���Ƃ�BPF�}�b�v���m�F����TCP�AUDP�AICMP�Ɋւ��ď����o�� for (i = 0; i < 5; i++) { long long tcp_cnt, udp_cnt, icmp_cnt; int key; key = IPPROTO_TCP; assert(bpf_map_lookup_elem(map_fd[0], &key, &tcp_cnt) == 0); key = IPPROTO_UDP; assert(bpf_map_lookup_elem(map_fd[0], &key, &udp_cnt) == 0); key = IPPROTO_ICMP; assert(bpf_map_lookup_elem(map_fd[0], &key, &icmp_cnt) == 0); printf("TCP %lld UDP %lld ICMP %lld bytes\n", tcp_cnt, udp_cnt, icmp_cnt); sleep(1); } return 0; }
�@�����ł̃|�C���g�̓v���O�����^�C�v���uBPF_PROG_TYPE_SOCKET_FILTER�v��BPF�v���O���������[�h���āi��Lsockex1_user.c�́y1�z�j�A������usetsockopt()�v�𗘗p���ă\�P�b�g�ɑ��ăA�^�b�`���Ă���i��Lsockex1_user.c�́y4�z�j�Ƃ����_�ł��B
�@�ubpf_map_lookup_elem()�v�́ABPF�}�b�v�ɃA�N�Z�X������ł��B�\�P�b�g�ɃA�^�b�`����BPF�v���O�������\�P�b�g�̃p�P�b�g��M�̃C�x���g�ɉ����āA����BPF�}�b�v�̏����A�b�v�f�[�g���Ă����܂��B
�@���[�U�[��Ԃ���BPF�v���O�����̑���ɗ��p����̂�bpf(2)�V�X�e���R�[���ł��B��L�̃T���v���v���O�����ł̓��C�u�������𗘗p���Ă���̂Œ���bpf�V�X�e���R�[�����Ăяo���Ă��܂��Abpf�V�X�e���R�[���ł͈ȉ��̂悤�Ȃ��Ƃ��ł��܂��B
�@���̃T���v���v���O���������p���Ă��郉�C�u�������́ulibppf�v�ƌĂ�A�utools/lib/bpf�v�ɂ���܂��B�܂�libpf�́A�J�[�l���\�[�X�����Ɨ��������|�W�g��������܂��Bbpf�V�X�e���R�[���̗��p���@���m�肽�����͂���libbpf���Q�Ƃ���Ƃ����ł��傤�B
�@�쐬����BPF�v���O�����̃A�^�b�`�́ABPF�̃v���O�����^�C�v���Ƃɕ��@���قȂ�܂��B�\�P�b�g�i�uBPF_PROG_TYPE_SOCKET_FILTER�v�j�̏ꍇ�́usetsockopt(2)�v�𗘗p���܂��BBPF�̃��[�h�����Ɋւ��Ă͏ڂ����͌�q���܂��B
�@����\�P�b�g�ɑ���eBPF�̃v���O�������A�^�b�`���Ă��܂����A�\�P�b�g�ɂ͏]����cBPF�̃v���O�������A�^�b�`���邱�Ƃ��ł��܂��B�O�҂ɂ́usetsockopt(SO_ATTACH_BPF)�v���A��҂ɂ́usetsockopt(SO_ATTACH_FILTER)�v�𗘗p���܂��B
�@�A�ڑ�3���Ő��������悤�ɁA�utcpdump�v�𗘗p����Ɨ������₷���t�B���^�[����cBPF�ɕϊ����邱�Ƃ��\�ł��B
�@�p�P�b�g�t�B���^�����O���ړI�ł��������𗘗p���������y��������܂���B
Copyright © ITmedia, Inc. All Rights Reserved.