TGINSIGHT CHAT
Welcome to the Black Parade
@TheB1ackParade
MusicDeath has many faces, I look forward to seeing this one.
Recent posts
Page 67 of 76 · 907 posts
Posted Jun 13
man 啊 man, 你令人伤心, bpf_perf_event_output 里的 flags 的高 32 位用来指示要从 (void*)ctx 开始抓多少字节到 perf event, 这么重要的信息你不写在 man 里而是偷偷写在 torvalds/linux/samples 的注释里, 靠大家口口相传, 有点闭源后门那味了.
Posted Jun 13
tc 什么都好, 结果做到练习的最后一题, 发现 bpf_redirect_map 好像不能用在 tc 上, 而 bpf_redirect 又不能跨越 netns, 这就很不爽了, 两个 netns 内部的 veth 直接 egress to ingress 虫洞, XDP 做不到, 我满心欢喜希望 tc 能做, 结果也不行.
Posted Jun 12
tc bpf 不管 ingress 还是 egress 在 veth 和 tap 都看不到 .1q, tx-vlan-stag-hw-insert 这种直接帮你卸 vlan 的居然还是默认开的, 已经开始有点恶心了. 扩张或者收缩 skb 和 xdp 也很不一样, 提供了两个不对称的 API, 一个只能扩, 另一个要求传入参数非常复杂; 扩/缩之后还不能像 xdp 一样继续操作 ctx->data, 只能通过 bpf_skb_store_bytes, 令人不爽.
Posted Jun 12
昨晚发现 bpf-helpers(7) 里有个 bpf_probe_write_user, 十分震惊, goroutine funcgraph 的任务又有新解了, 那就是直接在每个 goroutine 调用栈的第一层的 cfa+8 把 goroutine id 写到内存里, 这样在扩栈之后依然能通过回溯查到 goroutine id, 也不必 attach golang 实现相关的几个函数, 依然是一个通用的 tracing tool. 回溯到调用栈的根需要循环, 不过我亲测在 bcc 0.24.0-8f40d6f5 里的循环 unroll 已经非常好用了, 循环次数不设上限, bpf 指令数目才是上限. 这个方案本来之前被我画叉了, 标记为只适用于 ptrace(2) 的玩具, 没想到 bpf 已经放权到这种地步, 赶紧快进到允许改寄存器, 逼宫 gdb(1) 指日可待.
Posted Jun 12
tc bpf 和 xdp bpf 是有区别的, 比如做 DNAT 之后修正 checksum, xdp 直接这样写没问题: bpf_l4_csum_replace(); tcp->dest = dest; 但是 tc 这样写就会 perm deny, 让我用 bpf_probe_read_kernel, 但是就算用了也一样报错, 以下三种改法都过不了 verifier: bpf_probe_read_kernel(); bpf_l4_csum_replace(); tcp->dest = dest; bpf_skb_load_bytes(); bpf_l4_csum_replace(); tcp->dest = dest; load_half(); bpf_l4_csum_replace(); tcp->dest = dest; 结果最后才发现不是读字节的问题, 而是最后 tcp->dest = dest 写字节造成的, 改成 bpf_skb_store_bytes 解决问题. HINT 指鹿为马让人服气.
Posted Jun 12
网上都说 tcp checksum 如果被篡改坏了会被内核丢弃,导致 tcp 重传,然而我测试发现并没有被丢弃,而是依然能正常通信。 中间加了桥和 tap,在 netns 和 vm 里测试结果都一样,tcp checksum 坏掉不会被丢弃,但是 icmp / ipv4 checksum 坏掉会被丢弃。 改了改设备的 offload,不影响结果,真是奇怪。
Posted Jun 11
tc ingress 丢包和 xdp 丢包在观测性上的区别是前者可以被 tcpdump 看到而后者不能, 但是 tc egress 丢包就完全不同了, 会直接造成 send(2) 返回 -1 with errno == ENOBUFS. 而很多程序对 ENOBUFS 的处理方式是重试, 比如 ping(8). 当然这仅限 fib lookup 直连设备上的 tc egress 丢包, 如果是经过了桥, 路由, 甚至是 veth 的另一端, 都不会造成 ENOBUFS. tc egress 虽然补全了 xdp 单向 hook 的缺点, 但是有可能会造成应用程序 syscall 的行为变化, 这一定要注意.
Posted Jun 11
态度简直可以说是卑躬屈膝了, 一般来说老项目都会维护热情衰退, 看到一些设计不好之处却囿于兼容性不得不在屎山上堆屎, 这个斯德哥尔摩人却十年如一日地服务社区, 我都想去斯德哥尔摩了. 上一个 XDP 项目创造者是希腊人, 我也想去希腊.
Posted Jun 10
给 pyroute2 报了个 bug, 本以为会装死, 结果 owner 居然这么热情. 每次遇到好项目的维护者在常年 cosplay 雷锋的时候就想打钱. 可惜 pyroute2 只是一个 Python 版的 ip(8)... 向雷锋敬礼!
Posted Jun 10
其实不太明白 __be16 是啥意思. 抛开 sparse 不管, 难道它的意思不应该是 "这个字段用已经转成大端序" 吗? 比如 struct sk_buff 的 protocol 是 __be16 类型, 但是在 tc-bpf 里读这个字段, ipv4 的时候值是 8, 这根本不是大端序的 ETH_P_IP 喂! 大端序的 ETH_P_IP 是 0x0800 啊... 在尝试用更地道的方式写 bpf, 使用 __builtin_x 而不是 libc 函数, 使用 __u32 而不是 u32, 使用 bpf_ntohs 而不是 ntohs, 等等, 很细很催眠...
Posted Jun 10
man 啊 man, 你可知道这样会让我心碎. tc-bpf(8) 里对 da 模式只字未提, bcc/examples 里的 tc 用例有些是 classifier 模式有些是 da 模式, 而 TC_ACT_* 返回值只能在 da 模式下使用, 搞不清楚这些细微差别就会出现 "为什么 return TC_ACT_SHOT 才能联通而 TC_ACT_SHOT 明明是丢弃包" 这种疑问. 还好 Cilium 的开发者有人间大爱, 补充了很多内核没有的文档, 堪称现代菩萨.
Posted Jun 9
man 啊 man, 你令人伤心, bpf_perf_event_output 里的 flags 的高 32 位用来指示要从 (void*)ctx 开始抓多少字节到 perf event, 这么重要的信息你不写在 man 里而是偷偷写在 torvalds/linux/samples 的注释里, 靠大家口口相传, 有点闭源后门那味了.