[{"content":"My RSS Workflow I use RSS to subscribe to my favorite feeds and reliance on Karakeep for bookmarking. To streamline this, I sync Miniflux with Karakeep so that any saved items in my RSS reader are automatically saved as bookmarks. Additionally, I’ve integrated Miniflux with Telegram to easily share interesting articles with my friends.\ngraph TD A[RSS Feed Sources] --\u0026gt;|1. Auto-fetch periodically| B(Miniflux Reader) B --\u0026gt;|2. New Article Arrives| H[Trigger Telegram Bot] H --\u0026gt;|3. Auto-post| G[(Telegram Channel)] B --\u0026gt;|4. User Reads \u0026amp; Stars| C[Star Article] C --\u0026gt;|5. Sync Integration| E[(Karakeep Bookmarks)] ","permalink":"https://rmtt.github.io/posts/rss-workflow/","summary":"\u003ch1 id=\"my-rss-workflow\"\u003eMy RSS Workflow\u003c/h1\u003e\n\u003cp\u003eI use RSS to subscribe to my favorite feeds and reliance on \u003ca href=\"https://karakeep.app/\"\u003eKarakeep\u003c/a\u003e for bookmarking. To streamline this, I sync \u003ca href=\"https://miniflux.app/\"\u003eMiniflux\u003c/a\u003e with Karakeep so that any saved items in my RSS reader are automatically saved as bookmarks. Additionally, I’ve integrated Miniflux with Telegram to easily share interesting articles with my friends.\u003c/p\u003e\n\u003cpre class=\"mermaid\"\u003e\n  graph TD\n    A[RSS Feed Sources] --\u0026gt;|1. Auto-fetch periodically| B(Miniflux Reader)\n\n    B --\u0026gt;|2. New Article Arrives| H[Trigger Telegram Bot]\n    H --\u0026gt;|3. Auto-post| G[(Telegram Channel)]\n    \n    B --\u0026gt;|4. User Reads \u0026amp; Stars| C[Star Article]\n    C --\u0026gt;|5. Sync Integration| E[(Karakeep Bookmarks)]\n\u003c/pre\u003e\n\u003cscript type=\"module\"\u003e\n  import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.esm.min.mjs';\n  if (!window.mermaidInitialized) {\n    window.mermaidInitialized = true;\n    mermaid.initialize({ startOnLoad: false });\n    const render = async () =\u003e {\n      await mermaid.run({ querySelector: '.mermaid' });\n    };\n    if (document.readyState === 'loading') {\n      document.addEventListener('DOMContentLoaded', render);\n    } else {\n      render();\n    }\n  }\n\u003c/script\u003e","title":"My RSS and Bookmarks Workflow"},{"content":"How to reproduce Create a ipsec tunnel between two machines Assign ipv6 address to machines as tunnel ips Configure SRv6 End.DX4 Ping each other via srv6 end.dx4 Result: cannot ping each other\nFind root cause Let\u0026rsquo;s read kernel code and find how pocket flows with ipsec(via xfrm framework) and srv6.\nFirst, we need clarify the code path of target packets. Because we use ipsec tunnel, so every actual payload packet will be packed into a UDP via ESP protocol and the inner packet it\u0026rsquo;s a ipv6 packet with srv6 end.dx4 action which means the structure of entire packet is:\n[ ip header ] [ UDP header ] [ ESP header ] [ payload ipv6 header ] [ encaptured ipv4 packet] After the peer node receives ESP packets, it will decrypt this ESP packet and then deliver inner ipv6 packet to network stack. Then the inner ipv6 packet will be handled by the function input_action_end_dx4, after that, the actual payload packet(the inner most ipv4 packet) will be passed to ip_local_deliver.\nIf you can debug kernel via gdb, then you will find this ipv4 packet will go into function xfrm_policy_check to validate some fields of skb. Unfortunately, the life of this ipv4 packet is end there.\nAfter doing some investigation and debugging, I found the problem is that function input_action_end_dx4 only changes the protocol type and transport layer offset of original skb:\nstatic int input_action_end_dx4(struct sk_buff *skb, struct seg6_local_lwt *slwt) { if (!decap_and_validate(skb, IPPROTO_IPIP)) goto drop; if (!pskb_may_pull(skb, sizeof(struct iphdr))) goto drop; skb-\u0026gt;protocol = htons(ETH_P_IP); skb_set_transport_header(skb, sizeof(struct iphdr)); nf_reset_ct(skb); if (static_branch_unlikely(\u0026amp;nf_hooks_lwtunnel_enabled)) return NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING, dev_net(skb-\u0026gt;dev), NULL, skb, skb-\u0026gt;dev, NULL, input_action_end_dx4_finish); return input_action_end_dx4_finish(dev_net(skb-\u0026gt;dev), NULL, skb); drop: kfree_skb(skb); return -EINVAL; } But there is other important field called cb(remember the original packet is ipv6, and this field has different format in v4 and v6) of sk_buffer remains the original value(in inet6_skb_param format):\nstruct sk_buff { ... /* * This is the control buffer. It is free to use for every * layer. Please put your private variables there. If you * want to keep them across layers you have to do a skb_clone() * first. This is owned by whoever has the skb queued ATM. */ char\tcb[48] __aligned(8); ... } After the inner most ipv4 packet passed to ip_local_deliver, the cb field of original skb will be used as inet_skb_param. So, some verifications will failed because they will get a wrong value from skb-\u0026gt;cb.\n","permalink":"https://rmtt.github.io/posts/bug-recording-01/","summary":"\u003ch2 id=\"how-to-reproduce\"\u003eHow to reproduce\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003eCreate a ipsec tunnel between two machines\u003c/li\u003e\n\u003cli\u003eAssign ipv6 address to machines as tunnel ips\u003c/li\u003e\n\u003cli\u003eConfigure SRv6 End.DX4\u003c/li\u003e\n\u003cli\u003ePing each other via srv6 end.dx4\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eResult: cannot ping each other\u003c/p\u003e\n\u003ch2 id=\"find-root-cause\"\u003eFind root cause\u003c/h2\u003e\n\u003cp\u003eLet\u0026rsquo;s read kernel code and find how pocket flows with ipsec(via xfrm framework) and srv6.\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"packet_flow\" loading=\"lazy\" src=\"https://blog-img.rmtt.fun/posts/bug-recording-01/packet_flow.png\"\u003e\u003c/p\u003e\n\u003cp\u003eFirst, we need clarify the code path of target packets. Because we use ipsec tunnel, so every actual payload packet will be packed into a UDP via ESP protocol and the inner packet it\u0026rsquo;s a ipv6 packet with srv6 end.dx4 action which means the structure of entire packet is:\u003c/p\u003e","title":"IPSec tunnel doesn't work in Linux when using srv6 end.DX4"}]