Мир сегодня с "Юрий Подоляка"
Мир сегодня с "Юрий Подоляка"
Труха⚡️Україна
Труха⚡️Україна
Николаевский Ванёк
Николаевский Ванёк
Мир сегодня с "Юрий Подоляка"
Мир сегодня с "Юрий Подоляка"
Труха⚡️Україна
Труха⚡️Україна
Николаевский Ванёк
Николаевский Ванёк
Welcome to the Black Parade avatar

Welcome to the Black Parade

Death has many faces, I look forward to seeing this one.
Рэйтынг TGlist
0
0
ТыпПублічны
Вертыфікацыя
Не вертыфікаваны
Надзейнасць
Не надзейны
Размяшчэнне
МоваІншая
Дата стварэння каналаJan 19, 2020
Дадана ў TGlist
Jan 25, 2025
Прыкрепленая група

Апошнія публікацыі ў групе "Welcome to the Black Parade"

我去,我才知道 ip(8) 有个 -j 可以输出 json 格式,比如获取一个网络接口的二层地址,我之前一直是
$ s ip -n node2 -br l sh nsim1 | awk '{print $3}'

用 -j | jq 心里有底气得多:
$ s ip -n node2 -j l sh nsim1 | jq -r '.[0].address'

从此再也不内耗了,再让我看到 awk/grep/sed 切字符串我直接使用纵欲卡🤬
开始吹 bpfsnoop (https://github.com/bpfsnoop/bpfsnoop),我至少会在三个场景使用它

1. disas kernel

之前我都是用 gdb -ex 'x/100i 0x'$(ksym skb_gso_validate_network_len) -ex q vmlinux /proc/kcore 这种蹩脚的方式去看汇编;若是 bpf prog 会用 bpftool p d 。但前者要手算 call 的目标函数,后者又长期有 bug (https://github.com/libbpf/bpftool/issues/109)。

但是以后我会用
bpfsnoop -d -k ip_rcv


bpfsnoop -d -p n:cil_to_overlay

来代替 gdb。输出非常好(图一),有颜色,有行号,有正确的 call 指令解析。

2. 用 --output-arg --filter-arg --filter-pkt 做 skb 观测

之前讨论过一个 nf postrouting 不会两次处理同一个 skb 的问题,本质是要观测 skb->_nfct 在生命期内的变化,用 bpfsnoop 可以一步到位:
bpfsnoop --filter-pkt 'icmp and dst host 10.244.2.2'  -t '*:(struct sk_buff *)skb' --output-pkt --output-arg 'skb->_nfct' 

虽然目前还不支持更复杂的操作,比如想观测 skb_sec_path(skb) 则需要写成 --output-arg 'skb->extensions->offset[1] << 3' 然而并不支持,但大部分简单的场景够用了。

3. 用 --output-lbr 观测 bpf prog

bpf prog 自身的观测性一直比较恶心,用 lbr 和 kprobe on bpf helpers 是目前为止我所知的唯二办法,而 bpfsnoop 是唯一实现了前者工程化的工具。(其实两者结合才是最吼的)

比如排查 https://github.com/cilium/cilium/issues/35023 的时候需要找到 bpf 运行的提前返回点,可以先无脑观测 bpf prog 退出时的 lbr
bpfsnoop -p i:7963 --output-lbr --filter-pkt 'dst host 1.1.1.1 and tcp[tcpflags]=tcp-syn' -m exit

然后再根据结果往上以 bpf helper 为节点回溯
bpfsnoop -k bpf_skb_event_output --output-lbr --filter-pkt 'dst host 1.1.1.1 and tcp[tcpflags]=tcp-syn' -m entry

最终定位代码执行流
我麻了,原来 per-cpu map 不能解决 kprobe bpf 的并发问题: https://lore.kernel.org/bpf/CAMy7=ZWPc279vnKK6L1fssp5h7cb6cqS9_EuMNbfVBg_ixmTrQ@mail.gmail.com/T/

恭喜我又贡献了一堆 bug 🐛
哇原来!是用 gas 来控制 opcode 复杂度!这听起来比 bpf verifier 先进多了?(❓)

#zzh为将来被开除的我指明方向
博德之门3里下城区“精灵之歌”酒店里有个讲笑话比赛,中文翻译一如既往的惨不忍睹,堪比神界原罪2里那灾难性的“仁义礼智信”。不如来看看那些笑话笑点究竟是什么8

Say, what’s the difference between a dwarf and a bulette? You can’t toss the bulette!
问,一个矮人和鲨蜥兽有什么区别?鲨蜥兽扔不动

Dwarf-tossing 是澳大利亚人发明的酒吧娱乐活动,就真的是把 dwarf 拿来扔比谁扔得远。。不愧是囚犯流放地,我真的黄豆流汗。。。

Hey! I asked my wizard to cast Shatter. He said, ‘Shatter? I hardly know ‘er!’
哈!我让我的法师施展精力流失。他说,”经理?我基本不认识她啊!“

模板 “X-er? I hardly know 'er!”,比如 “Liquor? I hardly know her!”,liquor 被空耳成 lick her;“Poker? I hardly know her!”,poker 被空耳成 poke her。后来被延申到所有 -er 结尾的单词,比如下次你同事问你怎么用 hrtimer 你就可以 hardly know her 不要在职场用

You know why I hate vampires? They just suck.
你知道我为什么讨厌吸血鬼?因为他们只吸不吐。

这个翻译 sucks

I tried sleeping with a dragonborn the other night, but it didn’t work out - he had reptile dysfunction.
有天晚上我打算跟一个龙裔睡觉,但是没有成功——因为他龙萎了。

reptile dysfunction 谐音 erectile dysfunction (ED)。其实这个翻译还行,“他龙,萎了”。

The Dead Three, am I right? What losers. You know why Bane worshippers will never conquer the world? They don’t have the Bhaals!
死亡三神,我说得对吗?真是。你知道班恩的崇拜者为什么从来没能征服这个世界吗?因为他们没有巴尔!

DND 中的死亡三神是纷争之神班恩、死者之神米尔寇、谋杀之神巴尔,这个笑话的笑点是 Bhaals 可以被空耳成 Balls:they don't have the balls 他们没胆。
Bhaal 在《暗黑破坏神2》里被读作 Baal 巴尔,但其实很多年前就有讨论 Bhaal 是否应该读作 Ball

A mind flayer’s duergar slave lost his nose, so I asked the illiquid, ‘How does he smell?’ and it said, ‘I have eaten its brain’.
一个夺心魔的灰矮人奴隶失去了他的鼻子,所以我问灵吸怪,“他闻起来怎么样?”,然后他说,“脑子没味儿”。

来自经典笑话 “My dog has no nose. How does he smell? Terrible!” 中文翻译完全失去了 how does he smell 在英语里双关。

Our cleric tried to cast Healing Word on a ham, but it was already cured.
我们的牧师打算对一个火腿施展治愈真言,但它已经风干了。

Cure a ham 风干火腿,翻译很难译出这种一词多义。

最后,从今天起,请叫我博得人 Baldurian.
不可思议 #NSFW
she年快乐!

Make love, not code 👩‍💻
我其实不太追新,我看着各种频道里我读不出来的 AI 名字推陈出新毫无波动,继续日常和 gpt 做英语语法检查、问答 kubectl 怎么过滤字段、问一些我理解不了的内核问题然后收获一堆胡说八道,习惯了,预期建立得低就不会失望。

但是! DeepSeek!真的太爆炸了,下面请欣赏 chatgpt 4o 回答得一塌糊涂的编程问题在 deepseek 的精彩表现。

1. 用 golang 标准库 syscall 实现 inotify watch 普通文本文件,然后输出每次修改事件的 diff。

我觉得这个问题超简单,常用 syscall 的 API 不管是文档和博客都很多,我只是要求用 go 翻译一下,结果收获了无数光怪陆离,曾经是我用来测试 AI 写代码的标准题目,还发过一贴嘲笑 AI 们连 API 小子都做不好实在太菜了,收获了一堆 👎

deepseek 则一发入魂,图一就是核心逻辑,完全正确, 有个 u32 -> i32 的类型转化搞错了,不重要,要知道 gpt 4o 还搁那儿无限 for 循环里 cat file + sleep 呢。

2. 写 tcpdump filter,过滤出指定 src + dst ip 的 ipv6 tcp reset in vxlan。

这个问题前段时间也 po 过,gpt 4o 令人失望到起手就 tcp[tcpflags]=tcp-syn,而我在提问里给的 non-vxlan 示范里已经教学使用 ip6[53]&0x4!=0 了,它理解不了为什么,我多次指出错误之后更是开始打滚输出重复错误的代码。

deepseek 就清新脱俗了,在陷入长达两分钟的长考之后(长考过程很有趣),直接给出了完全正确的表达式,见图二。震撼!

3. 用 bpftrace 读 skb 非线性区。

正是上上上上条 post,gpt 4o 在多轮对话之后害直接解引用 page 指针,我都气笑了。但是 deepseek 直接给出图三的输出,虽错,但错误的原因是它脚本适用于 CONFIG_FLATMEM 配置下的内核而我的是 CONFIG_SPARSEMEM_VMEMMAP。告诉它我的配置之后,图四几乎对了,只差一点点,只要把 kaddr("vmemmap") 改成 *(uint64*)kaddr("vmemmap_base") 就赢了。

这才是我心中的 AI,让我看看怎么给它打钱来着。现在入 AI 神教应该还来得及,我去带路先(

(prompt 见评论区)
乌克兰同事被强制征兵了😢 希望公司能帮帮他。

他在内核做了很多非平凡贡献,主导了某项目 clang10 -> clang17 的升级,是编译器专家,XDP/XSK 专家,网卡性能专家,bpf verifier 专家。

https://lore.kernel.org/netdev/?q=maximmi

我不信内核还有比 xfrm 更糟糕的用户态 api 😀

# ip x p add src 10.0.0.0/8 dst 10.36.1.0/24 dir in mark 0x58d73e00 mask 0xffffff00 
测完了 tp_btf/netif_receive_skb + bpf_skb_output 大战 kporbe/__netif_receive_skb_core + 手动拆非线性区,结果是🤬😭

rps 从 80192.46 baseline 分别下降到 60532.69 (bpf_skb_output) 和 46360.68 (手动档),下降越少越好😀 tcpdump 只下降到 63131.31 ,赢!

所以仅剩的卖点就是好玩了。不对,仅剩的卖点是可以在任意地方抓包,但我还是觉得好玩最重要!只是狂歌一曲,恍惚间就化入无穷,debug,杯莫停,人生不过一场大梦~

(下面开始找补)

其实在任意地方抓包还是有工程价值的,尤其是 tcpdump 只能在 interface 上抓,还容易被 bpf 干扰,还有美美隐身的 xfrm , slirp 转化的 vxlan0 ,ipsec offload ,还有 GRO GSO 这些之前几乎没有工具能观测的内核功能以前只能看着文档催眠自己“对就是这样的不要多想照着抄就行了”现在也终于能手动展开 skb_shared_info 而仔细灌肠。

费曼说 “What I cannot create, I do not understand” ;我说 “What I cannot see, I do not believe” 。
至此,已经可以用 bpftrace 写出最核心的 page_to_vaddr 的逻辑:
#define vmemmap_base ((uint64)0xffffffffaf6f5558)

其中 vmemmap_base 和 page_offset_base 查询 /proc/kallsyms 得到。

现在我终于可以说,我能在内核任意地方抓包了(并没有哈,kprobe 有一大堆 notrace 禁飞区,除此之外大部分地方还是可以的

Рэкорды

18.04.202523:59
497Падпісчыкаў
24.01.202523:59
100Індэкс цытавання
08.03.202514:54
165Ахоп 1 паста
07.04.202514:54
165Ахоп рэкламнага паста
09.02.202509:45
17.86%ER
08.03.202514:53
34.45%ERR

Развіццё

Падпісчыкаў
Індэкс цытавання
Ахоп 1 паста
Ахоп рэкламнага паста
ER
ERR
FEB '25MAR '25APR '25

Папулярныя публікацыі Welcome to the Black Parade

16.04.202510:47
我去,我才知道 ip(8) 有个 -j 可以输出 json 格式,比如获取一个网络接口的二层地址,我之前一直是
$ s ip -n node2 -br l sh nsim1 | awk '{print $3}'

用 -j | jq 心里有底气得多:
$ s ip -n node2 -j l sh nsim1 | jq -r '.[0].address'

从此再也不内耗了,再让我看到 awk/grep/sed 切字符串我直接使用纵欲卡🤬
07.04.202503:51
我麻了,原来 per-cpu map 不能解决 kprobe bpf 的并发问题: https://lore.kernel.org/bpf/CAMy7=ZWPc279vnKK6L1fssp5h7cb6cqS9_EuMNbfVBg_ixmTrQ@mail.gmail.com/T/

恭喜我又贡献了一堆 bug 🐛
开始吹 bpfsnoop (https://github.com/bpfsnoop/bpfsnoop),我至少会在三个场景使用它

1. disas kernel

之前我都是用 gdb -ex 'x/100i 0x'$(ksym skb_gso_validate_network_len) -ex q vmlinux /proc/kcore 这种蹩脚的方式去看汇编;若是 bpf prog 会用 bpftool p d 。但前者要手算 call 的目标函数,后者又长期有 bug (https://github.com/libbpf/bpftool/issues/109)。

但是以后我会用
bpfsnoop -d -k ip_rcv


bpfsnoop -d -p n:cil_to_overlay

来代替 gdb。输出非常好(图一),有颜色,有行号,有正确的 call 指令解析。

2. 用 --output-arg --filter-arg --filter-pkt 做 skb 观测

之前讨论过一个 nf postrouting 不会两次处理同一个 skb 的问题,本质是要观测 skb->_nfct 在生命期内的变化,用 bpfsnoop 可以一步到位:
bpfsnoop --filter-pkt 'icmp and dst host 10.244.2.2'  -t '*:(struct sk_buff *)skb' --output-pkt --output-arg 'skb->_nfct' 

虽然目前还不支持更复杂的操作,比如想观测 skb_sec_path(skb) 则需要写成 --output-arg 'skb->extensions->offset[1] << 3' 然而并不支持,但大部分简单的场景够用了。

3. 用 --output-lbr 观测 bpf prog

bpf prog 自身的观测性一直比较恶心,用 lbr 和 kprobe on bpf helpers 是目前为止我所知的唯二办法,而 bpfsnoop 是唯一实现了前者工程化的工具。(其实两者结合才是最吼的)

比如排查 https://github.com/cilium/cilium/issues/35023 的时候需要找到 bpf 运行的提前返回点,可以先无脑观测 bpf prog 退出时的 lbr
bpfsnoop -p i:7963 --output-lbr --filter-pkt 'dst host 1.1.1.1 and tcp[tcpflags]=tcp-syn' -m exit

然后再根据结果往上以 bpf helper 为节点回溯
bpfsnoop -k bpf_skb_event_output --output-lbr --filter-pkt 'dst host 1.1.1.1 and tcp[tcpflags]=tcp-syn' -m entry

最终定位代码执行流
Увайдзіце, каб разблакаваць больш функцый.