IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> libbpf eBPF对TCP下手了 -> 正文阅读

[系统运维]libbpf eBPF对TCP下手了

eBPF这项新技术会成为又一个内核玩家们的新圣地。

而我对eBPF了解的越多,就愈发追捧这门技术,乃至有些痴迷,“eBPF造万物”的字眼快要在我嘴里破口而出,背后的原因,是内核给了eBPF足够的空间,去接管系统的一切。

但一个TCP玩家,学习eBPF的目的自然还是服务本源。TCP是我现在的工作,所以我只好把目光从全局回缩一下,先试着捣鼓eBPF对TCP的玩法。

BPF是我的新武器,所以我总想着在这玩出点什么名堂。

于是乎,我放弃了BCC这类框架,直接上手libbpf。

如果感兴趣,请戳下面链接:
有关BCC、libbpf和BPF CO-RE

刚接触eBPF,会偏执的认为这只是一个白盒测试,最有价值的是在于可以追踪应用程序/内核程序的一切信息,动态追踪是它的助燃器。尽管如此,我已经觉得eBPF很厉害了。

但玩了一段时间后,渐渐从BCC这些应用层框架的阵地偏向了kernel(kernel里实现了libbpf、bpftool等)。于是乎,我在kernel里熟悉着libbpf,bpftool、cgroup的同时,也掀开了BPF的幕帘。

eBPF 不仅能监控系统上的数据,甚至可以拿来改变系统的行为。

并且,它绝对安全!

对eBPF有了解的,大多都知道XDP可以在网络收发包的流程里,操作数据包内容,这也是XDP兴起的主要原因。但当内核协议栈拥有了实时处理数据包内容的能力时,相比XDP,就意味着不需要知道偏移量等背景信息,不需要考虑网络包分片的影响,在每个封包/解包的过程中去处理工作。在指定过程中自定义操作,如:二层对Ethernet头处理,三层对IP头处理,四层对TCP、UDP头处理等等。

所以,当你有需要对数据包内容进行自定义操作时,除了XDP,你也可以选用内核协议栈的BPF,(内核协议栈的ebpf技术实现依赖于libbpf)。

实例

最后,给出一个样例:在数据包TCP头部封装时,往TCP Options里注入IP:Port二元组。

// SPDX-License-Identifier: GPL-2.0
#include <stddef.h>
#include <linux/bpf.h>
#include <linux/types.h>
#include <linux/socket.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_endian.h>

// * 程序版本信息
int _version SEC("version") = 1;

// reserved option number
 #define TCPOPT_TOA 77

struct tcp_option {
	__u8 kind;
	__u8 len;
	__u16 port;
    __u32 addr;
} __attribute__((packed));

SEC("sockops")
int bpf_tcpoptionstoa(struct bpf_sock_ops *skops)
{
    //return value for bpf program
	int rv = -1;
    //struct tcp_option option_buffer;
	int op = (int) skops->op;
    //update_event_map(op);
	switch (op) {
        //* client side
        case BPF_SOCK_OPS_TCP_CONNECT_CB:
            break;
        //* client side
        case BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB: {
            char fmt2[] = "client: active established\n";
            bpf_trace_printk(fmt2, sizeof(fmt2));
            /* Client will send option */
            //* BPF_SOCK_OPS_WRITE_HDR_OPT_CB_FLAG enables writing tcp options
            //* bpf_sock_ops_cb_flags_set用来调用修改flag的bpf程序——BPF_SOCK_OPS_HDR_OPT_LEN_CB/BPF_SOCK_OPS_WRITE_HDR_OPT_CB
            //* send new option from server side
            
            bpf_sock_ops_cb_flags_set(skops, BPF_SOCK_OPS_WRITE_HDR_OPT_CB_FLAG);
            
            break;
        }
        // * server side
        case BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB:{
                char fmt3[] = "server: passive established\n";
                bpf_trace_printk(fmt3, sizeof(fmt3));
                /* Server will send option */
                //* BPF_SOCK_OPS_WRITE_HDR_OPT_CB_FLAG enables writing tcp options
                //* bpf_sock_ops_cb_flags_set用来调用修改flag的bpf程序——BPF_SOCK_OPS_HDR_OPT_LEN_CB/BPF_SOCK_OPS_WRITE_HDR_OPT_CB
                //* send new option from server side
                //bpf_sock_ops_cb_flags_set(skops, BPF_SOCK_OPS_WRITE_HDR_OPT_CB_FLAG);
                break;
            //return 1;
            //bpf_printk("rv := %d",rv);
        }
        case BPF_SOCK_OPS_HDR_OPT_LEN_CB: {
            
            //reserved space
            int option_len = sizeof(struct tcp_option);
            /* args[1] is the second argument */
            if (skops->args[1] + option_len <= 40) {
                rv = option_len;
            }
            else rv = 0;
            //* 保留空间已经验证成功
            // bpf_printk("option len is %d",rv);
		    bpf_reserve_hdr_opt(skops, rv, 0);
            // bpf_printk("err: %d",err);
            break;
        }

        case BPF_SOCK_OPS_WRITE_HDR_OPT_CB: {
            //bpf_printk("",skops->);
            struct tcp_option opt = {
                .kind = TCPOPT_TOA,
                .len  = 8,	// of this option struct
                .port = __bpf_htons(0xeB9F),
                .addr = __bpf_htonl(0x93d4860a),
            };
      
            / * Server sends option */
            // * write the option
            bpf_store_hdr_opt(skops, &opt, sizeof(opt), 0);
			// cancel the settings
            bpf_sock_ops_cb_flags_set(skops, skops->bpf_sock_ops_cb_flags& ~BPF_SOCK_OPS_WRITE_HDR_OPT_CB_FLAG);
            break;
        }
         
        default:
            rv = -1;
        }
	skops->reply = rv;
	return 1;
}
// * 必要的许可信息
char _license[] SEC("license") = "GPL";

你也完全可以对IP头部的IP Options做如上注入信息的操作。

结果

性能基准工具iperf3结合tcpdump数据包分析
在这里插入图片描述

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-04-18 18:25:00  更:2022-04-18 18:27:45 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 20:35:17-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码