<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://gctl.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://gctl.io/" rel="alternate" type="text/html" hreflang="en" /><updated>2026-10-17T23:17:13+05:45</updated><id>https://gctl.io/feed.xml</id><title type="html">Ishwor Gurung</title><subtitle>Notes on AI, software development, systems, UNIX, networking, and distributed systems.</subtitle><author><name>Ishwor Gurung</name><email>me@ishworgurung.com</email></author><entry><title type="html">Why Considerdone Au</title><link href="https://gctl.io/blog/2026/why-considerdone-au/" rel="alternate" type="text/html" title="Why Considerdone Au" /><published>2026-09-17T00:00:00+05:45</published><updated>2026-09-17T00:00:00+05:45</updated><id>https://gctl.io/blog/2026/why-considerdone-au</id><content type="html" xml:base="https://gctl.io/blog/2026/why-considerdone-au/">&lt;h1 id=&quot;why-considerdoneau&quot;&gt;Why ConsiderDone.au&lt;/h1&gt;

&lt;p&gt;&lt;img src=&quot;/posts/considerdone-logo.png&quot; alt=&quot;ConsiderDone logo&quot; class=&quot;post-float-image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Most home-service jobs begin with a small but annoying problem: a leaking tap, a broken appliance, a lockout, or a fault that needs an electrician. The work itself may be simple. Getting it done is not.&lt;/p&gt;

&lt;p&gt;The usual process asks the homeowner to search, compare reviews, call several businesses, explain the same problem repeatedly, wait for quotes, coordinate a time, and work out how to pay. That is a lot of effort for something people only want to think about once.&lt;/p&gt;

&lt;p&gt;I built &lt;a href=&quot;https://considerdone.au&quot;&gt;considerdone.au&lt;/a&gt; around a simple question: what if a person could say, “Find someone reliable, book them, and let me approve the price,” then get on with their day?&lt;/p&gt;

&lt;p&gt;The aim is not to replace tradespeople. It is to remove the administrative gap between a homeowner who needs help and a local business that can do the work.&lt;/p&gt;

&lt;h2 id=&quot;the-gap-in-the-current-marketplace-model&quot;&gt;The gap in the current marketplace model&lt;/h2&gt;

&lt;p&gt;Existing marketplaces are useful discovery tools, but they often stop at the hardest part. A homeowner still has to make the calls and decide what happens next. Many platforms also sell the same lead to several providers, which turns a customer’s problem into a race to respond.&lt;/p&gt;

&lt;p&gt;That is frustrating for both sides. Homeowners spend time doing coordination work. Providers pay for leads that may be shared with several competitors and may never become a booking.&lt;/p&gt;

&lt;p&gt;considerdone.au takes a different path. It starts with one plain-language request. The system searches for relevant local providers, contacts them by phone, asks about availability and price, and brings the result back to the homeowner for approval.&lt;/p&gt;

&lt;p&gt;The important distinction is that the product is designed to finish the workflow, not merely generate a lead.&lt;/p&gt;

&lt;h2 id=&quot;what-the-service-is-actively-solving&quot;&gt;What the service is actively solving&lt;/h2&gt;

&lt;p&gt;The product has three jobs to do well:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Find a suitable provider for the task and location.&lt;/li&gt;
  &lt;li&gt;Turn the request into a real booking without making the homeowner chase people.&lt;/li&gt;
  &lt;li&gt;Handle money in a way that is clear, controlled, and fair to both parties.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The first version uses local-search data to find and rank candidates. It then uses an &lt;a href=&quot;https://en.wikipedia.org/wiki/Interactive_voice_response&quot;&gt;outbound voice&lt;/a&gt; workflow to speak with businesses in the normal channel they already use: the phone. A provider does not need to join a new marketplace or adopt a new &lt;a href=&quot;https://en.wikipedia.org/wiki/Point_of_sale&quot;&gt;point-of-sale&lt;/a&gt; system before they can take a job.&lt;/p&gt;

&lt;p&gt;The homeowner stays in control. Before the system makes calls, it asks for approval. When a real quote comes back, it asks again before charging anything. Those two pauses are intentional. Delegation should reduce effort, not remove consent.&lt;/p&gt;

&lt;h2 id=&quot;how-a-job-moves-through-considerdoneau&quot;&gt;How a job moves through considerdone.au&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/posts/job-states.svg&quot; alt=&quot;ConsiderDone.au job workflow&quot; class=&quot;post-full-image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The homeowner makes the important choices. considerdone.au does the coordination work in between, and the provider stays in control of the work, availability, and completion.&lt;/p&gt;

&lt;h2 id=&quot;engineering-for-a-real-world-workflow&quot;&gt;Engineering for a real-world workflow&lt;/h2&gt;

&lt;p&gt;The difficult part is not making an AI place a phone call. The difficult part is making the whole workflow dependable when it touches real people, real calendars, and real money.&lt;/p&gt;

&lt;p&gt;That has shaped the engineering decisions behind considerdone.au.&lt;/p&gt;

&lt;h3 id=&quot;the-orchestrator-owns-the-journey&quot;&gt;The orchestrator owns the journey&lt;/h3&gt;

&lt;p&gt;A booking moves through many steps: search, calling, quote collection, approval, payment, provider details, job completion, and payout. One &lt;a href=&quot;https://en.wikipedia.org/wiki/Orchestration_(computing)&quot;&gt;orchestration&lt;/a&gt; layer coordinates those steps, while each integration stays narrowly focused on its own job.&lt;/p&gt;

&lt;p&gt;For example, the calling service does not decide who gets paid, and the payment service does not decide which provider to call next. Keeping those responsibilities separate makes failures easier to understand and changes safer to make.&lt;/p&gt;

&lt;h3 id=&quot;actions-are-designed-to-be-safe-to-retry&quot;&gt;Actions are designed to be safe to retry&lt;/h3&gt;

&lt;p&gt;External systems fail. A server can restart halfway through a task. A network request can time out after the other side has already accepted it. Retrying blindly can create duplicate calls or, worse, duplicate charges.&lt;/p&gt;

&lt;p&gt;For that reason, side-effecting operations use persistent &lt;a href=&quot;https://en.wikipedia.org/wiki/Idempotence&quot;&gt;idempotency keys&lt;/a&gt; and &lt;a href=&quot;https://en.wikipedia.org/wiki/Database_constraint&quot;&gt;database constraints&lt;/a&gt;. The system records its progress and can resume in-flight tasks after a restart instead of treating a restart as a failed job. This is less glamorous than the voice interface, but it is essential infrastructure for a service that makes bookings and moves money.&lt;/p&gt;

&lt;h3 id=&quot;structured-results-not-ai-interpretation-after-the-fact&quot;&gt;Structured results, not AI interpretation after the fact&lt;/h3&gt;

&lt;p&gt;Phone conversations are messy. The application does not use raw transcripts to make booking decisions. Instead, the call workflow returns specific structured fields such as outcome, quote, time slot, and whether the provider needs a site visit.&lt;/p&gt;

&lt;p&gt;That boundary matters. It gives the workflow defined data to act on, makes it testable, and avoids having hidden interpretation drive a payment or state change.&lt;/p&gt;

&lt;h3 id=&quot;payment-follows-approval-not-assumption&quot;&gt;Payment follows approval, not assumption&lt;/h3&gt;

&lt;p&gt;For a standard job, the system first places an &lt;a href=&quot;https://en.wikipedia.org/wiki/Authorization_hold&quot;&gt;authorisation hold&lt;/a&gt; for the homeowner’s agreed spending cap. It only captures the exact quoted amount after the homeowner approves it. If the quote is declined or no provider works out, the hold is not captured.&lt;/p&gt;

&lt;p&gt;After the job is complete, the provider submits completion through a secure, time-limited link. The homeowner can release payment, dispute it, or allow the stated review period to expire. The provider is then paid by bank transfer, less a clearly disclosed booking fee. The consumer pays the quote they approved, with no surprise surcharge added on top.&lt;/p&gt;

&lt;p&gt;This two-leg payment model reflects the real timing of a service job: booking and charging happen first; provider payout happens only after completion and review.&lt;/p&gt;

&lt;h2 id=&quot;adapting-to-how-trades-actually-quote&quot;&gt;Adapting to how trades actually quote&lt;/h2&gt;

&lt;p&gt;One of the most useful lessons from the build was that not every job can be priced on the phone.&lt;/p&gt;

&lt;p&gt;A tap washer or lockout may be straightforward. A hidden leak, electrical fault, or compliance-sensitive job often is not. In many cases, a provider needs to inspect the site before they can responsibly give a price.&lt;/p&gt;

&lt;p&gt;Rather than forcing every task into a one-call quote, considerdone.au supports two paths:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;For phone-quotable work, the homeowner can approve a quote and book directly.&lt;/li&gt;
  &lt;li&gt;For diagnosis-first work, the system can book a call-out visit first. The provider then submits an on-site price, and the homeowner gets a separate approval decision before the actual job is charged.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a deliberate product choice. A new, unknown on-site price is never automatically approved. The call-out visit is treated as its own booking, so the provider is still paid for their time even if the homeowner declines the later job price.&lt;/p&gt;

&lt;p&gt;The fee model follows that reality too. The call-out fee has a small pass-through fee, while the actual job carries the main booking fee. It is a more honest model than pretending a visit is free or expecting providers to absorb the cost of diagnosis.&lt;/p&gt;

&lt;h2 id=&quot;trust-is-a-product-feature-not-a-marketing-claim&quot;&gt;Trust is a product feature, not a marketing claim&lt;/h2&gt;

&lt;p&gt;If a system is going to act for someone, it needs strong boundaries.&lt;/p&gt;

&lt;p&gt;considerdone.au keeps card numbers out of its servers by using a browser-based &lt;a href=&quot;https://en.wikipedia.org/wiki/Tokenization_(data_security)&quot;&gt;tokenized&lt;/a&gt; payment component. It keeps an append-only &lt;a href=&quot;https://en.wikipedia.org/wiki/Audit_trail&quot;&gt;audit trail&lt;/a&gt; of state-changing events while storing event payloads as &lt;a href=&quot;https://en.wikipedia.org/wiki/Cryptographic_hash_function&quot;&gt;cryptographic hashes&lt;/a&gt; rather than raw data. Provider payout links are random, scoped to one booking, time-limited, and single-use.&lt;/p&gt;

&lt;p&gt;The product also has safety screening before a provider is contacted. Normal service requests proceed. Requests that suggest an emergency, harm, or criminal intent are stopped and handled with an appropriate response. The system does not automate reports or make high-stakes decisions from a phone transcript.&lt;/p&gt;

&lt;p&gt;There are also areas where the work is intentionally not presented as finished. Provider &lt;a href=&quot;https://en.wikipedia.org/wiki/Australian_Business_Number&quot;&gt;ABN&lt;/a&gt; and licence verification need a practical, state-by-state rollout plan. Disputes are handled manually in the first version. Preventing off-platform repeat transactions will require a better mix of customer protection, provider incentives, and repeat-booking value than a simple discount can offer.&lt;/p&gt;

&lt;p&gt;Naming those gaps is part of building trust. The point is to solve the problems that can be solved now, measure the uncertain ones, and avoid pretending a complex marketplace is complete before it is.&lt;/p&gt;

&lt;h2 id=&quot;building-toward-a-useful-local-service-agent&quot;&gt;Building toward a useful local service agent&lt;/h2&gt;

&lt;p&gt;considerdone.au is being built as a practical assistant for a very ordinary problem: something at home needs fixing, and someone needs to make the booking happen.&lt;/p&gt;

&lt;p&gt;The direction is simple. Make the first request easy. Keep the homeowner in control. Respect providers’ existing way of working. Be precise about money. Make the system recover gracefully when real life does not follow the happy path.&lt;/p&gt;

&lt;p&gt;The technology matters, but the standard is simpler: when a homeowner asks for help, the experience should leave them able to say, “consider it done.”&lt;/p&gt;

&lt;p&gt;The future here is bright. As &lt;a href=&quot;https://www.x402.org/&quot;&gt;x402&lt;/a&gt; and other &lt;a href=&quot;https://en.wikipedia.org/wiki/Agentic_AI&quot;&gt;agentic AI&lt;/a&gt; payment rails mature, more of the trusted coordination around a job can happen quietly and safely in the background: matching, permissions, booking, settlement, and the record of what was agreed. That should mean fewer hand-offs and less administrative work for homeowners and providers alike. The human part that matters most remains human: the tradesperson’s judgement, skill, and work on site, while the surrounding workflow gets steadily simpler.&lt;/p&gt;</content><author><name>Ishwor Gurung</name><email>me@ishworgurung.com</email></author><summary type="html">Why ConsiderDone.au</summary></entry><entry><title type="html">Opentelemetry</title><link href="https://gctl.io/blog/2023/opentelemetry/" rel="alternate" type="text/html" title="Opentelemetry" /><published>2023-05-27T00:00:00+05:45</published><updated>2023-05-27T00:00:00+05:45</updated><id>https://gctl.io/blog/2023/opentelemetry</id><content type="html" xml:base="https://gctl.io/blog/2023/opentelemetry/">&lt;h1 id=&quot;opentelemetry-report&quot;&gt;OpenTelemetry Report&lt;/h1&gt;

&lt;p&gt;I recently went on a couple of months long migration to &lt;a href=&quot;https://opentelemetry.io&quot;&gt;OpenTelemetry&lt;/a&gt; from DataDog, and 
here are some thoughts specific to &lt;a href=&quot;https://opentelemetry.io/docs/specs/otlp/&quot;&gt;OTLP&lt;/a&gt; that may be of interest to you.&lt;/p&gt;

&lt;h3 id=&quot;tldr&quot;&gt;TL;DR&lt;/h3&gt;

&lt;p&gt;Emitting all three signals (metrics, traces and logging) in concert and expecting to be able to easily correlate them 
in the telemetry backend is not straight forward path (also it highly depends on which telemetry backend you choose).&lt;/p&gt;

&lt;h3 id=&quot;metrics&quot;&gt;Metrics&lt;/h3&gt;

&lt;p&gt;For OpenTelemetry’s OTLP metrics, you can be assured that for a long-running service, this is pretty stable.
You can choose to ingest with OTLP and fan-out to other vendors like DataDog; there are no surprises involved.&lt;/p&gt;

&lt;p&gt;For FaaS workloads (AWS Lambda), it’s a different story. The OpenTelemetry &lt;a href=&quot;https://github.com/open-telemetry/opentelemetry-lambda&quot;&gt;Collector&lt;/a&gt;-based,
metrics in a FaaS environment is not reliable. I hope it will eventually get there, but exactly when that will happen is
unknown. It depends on some &lt;a href=&quot;https://github.com/open-telemetry/opentelemetry-lambda/blob/main/docs/design_proposal.md#2-technical-challenges&quot;&gt;key features being implemented in Lambda runtime&lt;/a&gt; to mitigate issues involved with the 
‘freeze’ and ‘thaw’ of containers.&lt;/p&gt;

&lt;h3 id=&quot;traces&quot;&gt;Traces&lt;/h3&gt;

&lt;p&gt;OTLP-based traces are pretty stable in the long-running service world. Again, you can choose to ingest 
with OTLP and fan-out to other vendors like DataDog, and there are no surprises involved.&lt;/p&gt;

&lt;p&gt;However, for FaaS workloads such as AWS Lambda, due to the aforementioned freeze &amp;amp; thaw interaction within the extensions’
environment, is yet to materialize fully.&lt;/p&gt;

&lt;h3 id=&quot;logs&quot;&gt;Logs&lt;/h3&gt;

&lt;p&gt;For OTLP-based logs are a complicated story. It varies on the log sink involved, execution environment, and other constraints.
In general, your mileage will vary. OTLP-based log pipelines are not yet widely adopted and are not production ready. 
So, this is a case of &lt;strong&gt;YMMV&lt;/strong&gt;.&lt;/p&gt;

&lt;h3 id=&quot;continuous-profiling&quot;&gt;Continuous Profiling&lt;/h3&gt;

&lt;p&gt;OTLP-based continuous profiling is unheard of; it currently exists in the &lt;em&gt;proposals’&lt;/em&gt; basket.&lt;/p&gt;

&lt;h3 id=&quot;observations&quot;&gt;Observations&lt;/h3&gt;

&lt;p&gt;OpenTelemetry’s list of dirty laundry is long, and it will take a while to get it widely adopted. But here are a few 
key ones I have observed:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Contributing vendors have many self-driven interests and agendas that do not necessarily benefit the OpenTelemetry’s
open ecosystem.&lt;/li&gt;
  &lt;li&gt;OpenTelemetry working groups often fail to come to consensus thus impacting deliveries caused by countless number of
mundane arguments on the technical merits of a given implementation and design, in addition to lack of leadership (sure,
I understand large opensource efforts are not trivial, but it does not take 2+ years to deliver &lt;em&gt;a&lt;/em&gt; feature).&lt;/li&gt;
  &lt;li&gt;OpenTelemetry development is &lt;em&gt;actually&lt;/em&gt; siloed; I probably need not say more.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of this brings me to the following conclusion:&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;Closed vendors like DataDog can charge $65 million dollars to &lt;em&gt;one&lt;/em&gt; customer (just like a raging bull) because their
o11y stack is fully baked (all four signals - metrics, traces, logs and profiling) and production ready.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;However, all is not lost. OpenTelemetry has a lot of good things going for it, and I am excited to see where it goes.
Here are some of the good things I &lt;em&gt;love&lt;/em&gt; about OpenTelemetry:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Wide number of telemetry integrations with &lt;em&gt;you name it vendor&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;An opportunity to shape the Observability landscape for the foreseeable future&lt;/li&gt;
  &lt;li&gt;Wide variety of language support, telemetry receivers, processors and exporters to choose from&lt;/li&gt;
  &lt;li&gt;A very active and responsive core team that is willing to help and contribute&lt;/li&gt;
  &lt;li&gt;Extreme momentum in the community relating to releasing features and bug fixes&lt;/li&gt;
  &lt;li&gt;Many future enhancements are shaping as we speak, such as using eBPF, client-side metrics aggregations, 
exemplars, and many Rust-based :) telemetry components are in the works, and many more.&lt;/li&gt;
&lt;/ul&gt;</content><author><name>Ishwor Gurung</name><email>me@ishworgurung.com</email></author><summary type="html">OpenTelemetry Report</summary></entry><entry><title type="html">Xdp Ebpf Firewall In Rust</title><link href="https://gctl.io/blog/2020/xdp-ebpf-firewall-in-rust/" rel="alternate" type="text/html" title="Xdp Ebpf Firewall In Rust" /><published>2020-12-26T00:00:00+05:45</published><updated>2020-12-26T00:00:00+05:45</updated><id>https://gctl.io/blog/2020/xdp-ebpf-firewall-in-rust</id><content type="html" xml:base="https://gctl.io/blog/2020/xdp-ebpf-firewall-in-rust/">&lt;h1 id=&quot;xdpebpf-ip-layer-firewall-in-rust&quot;&gt;XDP/eBPF IP-layer firewall in Rust!&lt;/h1&gt;

&lt;p&gt;One of the option available today to do sub-millisecond packet filtering at scale is to harness the facilities afforded
by XDP, eBPF, Linux kernel and support provided by various NIC manufacturers.&lt;/p&gt;

&lt;p&gt;The two (XDP and eBPF) have grown quite rapidly in the 5.x release of the Linux kernel and there is absolutely no reason
you would not want to use it for your low-latency, high-performance use case.&lt;/p&gt;

&lt;p&gt;In this post, I will be demonstrating a sample XDP code that performs IP-layer firewall function traditionally done by
Netfilter/IPtables (thanks for all the fish Rusty Russell!) but ran as a offloaded XDP program by the eBPF VM in the
Linux kernel. The walk-through was thoroughly tested on Ubuntu 20.10 with LLVM version 11.0.0 on QEMU/virtio. LLVM is required
today because it can produce eBPF targets.&lt;/p&gt;

&lt;p&gt;According to XDP developers, on a benchmark they conducted, XDP far out-performed traditional kernel network stack on
Linux on all fronts - &lt;em&gt;tx&lt;/em&gt;, &lt;em&gt;rx&lt;/em&gt; and &lt;em&gt;forward&lt;/em&gt; (in the order of 12-25x!) when used with a NIC that that offloads XDP
such as the ones from Intel/Mellanox/Netronome (mlx/ixgbe/nfp etc).&lt;/p&gt;

&lt;p&gt;This is &lt;a href=&quot;https://github.com/tohojo/xdp-paper/blob/master/xdp-the-express-data-path.pdf&quot;&gt;mind-blowing&lt;/a&gt; on 2018 network hardware.&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;We show that XDP achieves single-core packet processing per-
formance as high as 24 million packets per second, and illustrate
the flexibility of the programming model through three example
use cases: layer-3 routing, inline DDoS protection and layer-4 load
balancing&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;dependencies-installation-and-rust-setup&quot;&gt;Dependencies Installation and Rust setup&lt;/h2&gt;

&lt;p&gt;Install dependencies:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ sudo apt-get install          \
    build-essential             \    
    libelf-dev                  \
    ca-certificates             \
    ca-certificates-java        \
    zlib1g-dev                  \
    llvm-11-dev                 \
    libclang-11-dev             \
    linux-headers-$(uname -r)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Install Rust (single user) using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rustup&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ curl --proto &apos;=https&apos; --tlsv1.2 -sSf https://sh.rustup.rs | sh
$ . ~/.bashrc # or logout then login.
$ rustup install nightly
$ rustup default nightly
$ rustc --version
 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Install Rust (system-wide) using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rustup&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ sudo -i
$ curl --proto &apos;=https&apos; --tlsv1.2 -sSf https://sh.rustup.rs |       \
    env RUSTUP_HOME=/opt/rust/rustup CARGO_HOME=/opt/rust/cargo     \
    sh -s -- --default-toolchain stable --profile default --no-modify-path -y
$ tee -a /root/.bashrc &amp;lt;&amp;lt;HD
# setup Rust environment
export RUSTUP_HOME=/opt/rust/rustup
export PATH=${PATH}:/opt/rust/cargo/bin
HD
$ . /root/.bashrc # or logout then login.
$ rustup install nightly
$ rustup default nightly
$ rustc --version
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Install &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;carfgo-bpf&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ cargo install cargo-bpf
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;walk-through&quot;&gt;Walk-through&lt;/h2&gt;

&lt;p&gt;Create the eBPF project:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ cargo bpf new xdp-ebpf-fw
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Add a new eBPF program called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fw&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ cd xdp-ebpf-fw
$ cargo bpf add fw
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Source for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;xdp-ebpf-fw/Cargo.toml&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;language-toml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;package&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;xdp-ebpf-fw&quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;version&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;0.1.0&quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;edition&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;2018&apos;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dependencies&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;cty&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;0.2&quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;redbpf-macros&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;1.3&quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;redbpf-probes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;1.3&quot;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;build-dependencies&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;cargo-bpf&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;1.3&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;default-features&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;features&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;probes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lib&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;src/lib.rs&quot;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;[[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bin&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;]]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;fw&quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;src/fw/main.rs&quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;required-features&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;probes&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Source for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fw/main.rs&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-rust highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;#![no_std]&lt;/span&gt;
&lt;span class=&quot;nd&quot;&gt;#![no_main]&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;core&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;fmt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;cty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;redbpf_probes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;xdp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;prelude&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;nd&quot;&gt;program!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0xFFFFFFFE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;GPL&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TCP_XDP_DROP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;XdpAction&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;XdpAction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;Drop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;UDP_XDP_DROP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;XdpAction&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;XdpAction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;Drop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;XDP_PASS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;XdpAction&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;XdpAction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Pass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// XDP/eBPF based IP-layer firewall to drop all UDP packets.&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// And, also drop all TCP packets destined to port 80.&lt;/span&gt;
&lt;span class=&quot;nd&quot;&gt;#[xdp]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;xdp_ip_firewall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;XdpContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;XdpResult&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ip_protocol&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;get_ip_protocol&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ip_protocol&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;u32&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;IPPROTO_UDP&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UDP_XDP_DROP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// drop it on the floor&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;IPPROTO_TCP&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;transport&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.transport&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;transport&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.dest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TCP_XDP_DROP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// drop it on the floor&lt;/span&gt;
                    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;XDP_PASS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// pass it up the protocol stack&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;XDP_PASS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// pass it up the protocol stack&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;get_ip_protocol&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;XdpContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;u32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.ip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// We need to make raw pointer into a u32 so `unsafe` is required.&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;unsafe&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;.protocol&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;u32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Anything above `255` is reserved.&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0x10000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Build eBPF program:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ cargo bpf build 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;network-queues-on-qemuvirtio-for-xdp&quot;&gt;Network queues on QEMU/virtio for XDP&lt;/h2&gt;

&lt;p&gt;On QEMU, we need to add 2&lt;em&gt;N&lt;/em&gt; queues (where &lt;em&gt;N&lt;/em&gt; is the number of vCPUs). The following &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;driver&amp;gt;&lt;/code&gt; section is required 
inside &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;interface&amp;gt;&lt;/code&gt; (use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;virsh edit [vmname]&lt;/code&gt;) is required (for 4 vCPUs, allocate 8 queues) as of QEMU version 4.2.1.&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;lt;interface ...&amp;gt;
[ ... ]
&amp;lt;driver name=&apos;vhost&apos; txmode=&apos;iothread&apos; ioeventfd=&apos;on&apos; event_idx=&apos;off&apos; queues=&apos;8&apos; rx_queue_size=&apos;256&apos; tx_queue_size=&apos;256&apos;&amp;gt;
    &amp;lt;host csum=&apos;off&apos; gso=&apos;off&apos; tso4=&apos;off&apos; tso6=&apos;off&apos; ecn=&apos;off&apos; ufo=&apos;off&apos; mrg_rxbuf=&apos;off&apos;/&amp;gt;
    &amp;lt;guest csum=&apos;off&apos; tso4=&apos;off&apos; tso6=&apos;off&apos; ecn=&apos;off&apos; ufo=&apos;off&apos;/&amp;gt;
&amp;lt;/driver&amp;gt;
[ ... ]
&amp;lt;/interface&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;load-the-compiled-ebpf-program&quot;&gt;Load the compiled eBPF program!&lt;/h2&gt;

&lt;p&gt;Load the compiled eBPF program:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ cd xdp-ebpf-fw
$ cargo bpf load -i eth0 target/bpf/programs/fw/fw.elf
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;blockquote&gt;
  &lt;p&gt;Profit!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;:boom:&lt;/p&gt;

&lt;h2 id=&quot;external-resources&quot;&gt;External resources&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://lib.rs/crates/redbpf&quot;&gt;Rust redbpf crate doc&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://ingraind.org/api/cargo_bpf/&quot;&gt;redbpf intro&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=NlMQ0i09HMU&quot;&gt;Four year-old talk by Linux netdev guru David S. Miller on over-arching principles of XDP&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=p61PlC9y62k&quot;&gt;XDP sockets&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://docs.cilium.io/en/latest/bpf/&quot;&gt;cilium XDP/eBPF&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/zoidbergwill/awesome-ebpf&quot;&gt;Awesome eBPF - keep this under the pillow&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;mailto:majordomo@vger.kernel.org?subject=subscribe xdp-newbies&amp;amp;body=subscribe xdp-newbies&quot;&gt;xdp-newbies mailing list&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=kFC8Bfk3FuI&quot;&gt;Netronome smart NIC XDP&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://developers.redhat.com/blog/2018/12/06/achieving-high-performance-low-latency-networking-with-xdp-part-1/&quot;&gt;XDP in RHEL (C implementation and guides)&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/tohojo/xdp-paper/blob/master/xdp-the-express-data-path.pdf&quot;&gt;XDP Paper&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><author><name>Ishwor Gurung</name><email>me@ishworgurung.com</email></author><summary type="html">XDP/eBPF IP-layer firewall in Rust!</summary></entry><entry><title type="html">Interesting Links</title><link href="https://gctl.io/blog/2020/interesting-links/" rel="alternate" type="text/html" title="Interesting Links" /><published>2020-11-07T00:00:00+05:45</published><updated>2020-11-07T00:00:00+05:45</updated><id>https://gctl.io/blog/2020/interesting-links</id><content type="html" xml:base="https://gctl.io/blog/2020/interesting-links/">&lt;h2 id=&quot;interesting-links&quot;&gt;Interesting links&lt;/h2&gt;

&lt;hr /&gt;

&lt;p&gt;LWN’s documentation on &lt;a href=&quot;https://lwn.net/Articles/776703/&quot;&gt;io_uring&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.scylladb.com/2020/05/05/how-io_uring-and-ebpf-will-revolutionize-programming-in-linux/0/&quot;&gt;How io_uring and eBPF Will Revolutionize Programming in Linux&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Make sure you have the latest Linux kernel (something like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;v5.9.0+&lt;/code&gt;) before opening the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;io_uring&lt;/code&gt; goodness.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Got 40GigE &lt;em&gt;stream&lt;/em&gt; data to do DPI on x86? Do you have performance issue with the pattern matching library currently
in use? No problem. Enter &lt;a href=&quot;http://intel.github.io/hyperscan/dev-reference/&quot;&gt;Intel Hyperscan&lt;/a&gt;.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Both &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;io_uring&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hyperscan&lt;/code&gt; has multitude of language bindings, so you are not necessarily stuck in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;C&lt;/code&gt; lalaland.&lt;/p&gt;

&lt;p&gt;Until next interesting links, adios!&lt;/p&gt;</content><author><name>Ishwor Gurung</name><email>me@ishworgurung.com</email></author><summary type="html">Interesting links</summary></entry><entry><title type="html">Capture Kernel Crash</title><link href="https://gctl.io/blog/2020/capture-kernel-crash/" rel="alternate" type="text/html" title="Capture Kernel Crash" /><published>2020-06-01T00:00:00+05:45</published><updated>2020-06-01T00:00:00+05:45</updated><id>https://gctl.io/blog/2020/capture-kernel-crash</id><content type="html" xml:base="https://gctl.io/blog/2020/capture-kernel-crash/">&lt;h2 id=&quot;capturing-linux-kernel-panic-message-on-qemu&quot;&gt;Capturing Linux kernel panic message on QEMU&lt;/h2&gt;

&lt;p&gt;In this small post, I will cover the following:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Capture Linux kernel panic message&lt;/li&gt;
  &lt;li&gt;Using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;softdog&lt;/code&gt; module to set the watchdog to auto-reboot upon Kernel panic.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;capture-the-panic&quot;&gt;Capture the panic&lt;/h3&gt;

&lt;p&gt;Log into your guest and update &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/etc/default/grub&lt;/code&gt; and add &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;console=tty0 console=ttyS0,9600n8&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GRUB_CMDLINE_LINUX&lt;/code&gt;; Then run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;update-grub&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To capture a kernel panic message, run the virtual machine like so:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ qemu-system-x86_64 -smp 2,sockets=2,cores=1,threads=1 -m 4096 -nographic -serial mon:stdio ubuntu18.04-1.qcow2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You will be greeted with the usual boot messages.&lt;/p&gt;

&lt;p&gt;Log in and trigger a kernel panic (either via sysrq or via the faulty kernel module).&lt;/p&gt;

&lt;p&gt;Upon kernel panic, a full trace message will appear on your attached console.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[  247.009745] BUG: stack guard page was hit at 000000006c1ac1e1 (stack is 00000000487682b5..000000001262eb3a)
[  247.012648] kernel stack overflow (double-fault): 0000 [#1] SMP NOPTI
[  247.012648] Modules linked in: helloworld(POE+) binfmt_misc ppdev kvm_amd kvm irqbypass input_leds serio_raw parport_pc parport sch_fq_codel softy
[  247.012648] CPU: 1 PID: 2102 Comm: insmod Tainted: P           OE    4.15.0-64-generic #73-Ubuntu
[  247.012648] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014
[  247.012648] RIP: 0010:_ZN4core3num23_$LT$impl$u20$usize$GT$11checked_mul17h07ae83026124b5eaE+0x10/0x70 [helloworld]
[  247.012648] RSP: 0018:ffffa84b4169ffd0 EFLAGS: 00000282
[  247.012648] RAX: 00000000000000fe RBX: 0000000000000000 RCX: 0000000000000000
[  247.012648] RDX: 0000000000000000 RSI: 0000000000000003 RDI: 0000000000000001
[  247.012648] RBP: ffffa84b416a0020 R08: ffffffffc0690d60 R09: 0000000000000003
[  247.012648] R10: 0000000000000000 R11: 0000000000000000 R12: ffffffffc059edf0
[  247.070679] R13: ffff9c5d78655a00 R14: 0000000000000001 R15: ffff9c5d51aeb240
[  247.070679] FS:  00007f690a2ff540(0000) GS:ffff9c5d7fd00000(0000) knlGS:0000000000000000
[  247.070679] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  247.070679] CR2: ffffa84b4169ffc8 CR3: 0000000137068000 CR4: 00000000000006e0
[  247.070679] Call Trace:
[  247.070679]  ? _ZN4core3num23_$LT$impl$u20$usize$GT$14saturating_mul17hc7be383430829098E+0x15/0x50 [helloworld]
[  247.070679]  ? _ZN4core5slice18from_raw_parts_mut17hc0afd704cde83aefE+0x62/0xd0 [helloworld]
[  247.070679]  ? _ZN99_$LT$core..ops..range..Range$LT$usize$GT$$u20$as$u20$core..slice..SliceIndex$LT$$u5b$T$u5d$$GT$$GT$17get_unchecked_mut17h8+0x]
[  247.070679]  ? _ZN99_$LT$core..ops..range..Range$LT$usize$GT$$u20$as$u20$core..slice..SliceIndex$LT$$u5b$T$u5d$$GT$$GT$9index_mut17h59d846e1fc+0x]
[  247.070679]  ? _ZN4core3cmp6min_by17h6a1a357c03d17732E+0x3d/0x90 [helloworld]
[  247.070679]  ? _ZN4core5slice77_$LT$impl$u20$core..ops..index..IndexMut$LT$I$GT$$u20$for$u20$$u5b$T$u5d$$GT$9index_mut17h6d899aa41763834eE+0x33/0]
[  247.070679]  ? _ZN79_$LT$linux_kernel_module..printk..LogLineWriter$u20$as$u20$core..fmt..Write$GT$9write_str17hb6b9f63c86335f4fE+0x127/0x250 [he]
[  247.070679]  ? _ZN4core3fmt9Formatter12pad_integral17hea95901f585e791cE+0x260/0x8b0 [helloworld]
[  247.070679]  ? _ZN4core3num23_$LT$impl$u20$usize$GT$14saturating_mul17hc7be383430829098E+0x15/0x50 [helloworld]
[  247.070679]  ? _ZN4core5slice14from_raw_parts17hc54a1a170e771755E+0x8f/0xd0 [helloworld]
[  247.070679]  ? _ZN4core3fmt3num3imp7fmt_u6417hb10d5615ab39d4d8E+0x5e6/0x720 [helloworld]
[  247.070679]  ? _ZN4core10intrinsics19copy_nonoverlapping17h66731a07c4e66efbE+0xc2/0xd0 [helloworld]
[  247.070679]  ? _ZN4core3fmt3num3imp51_$LT$impl$u20$core..fmt..Display$u20$for$u20$u8$GT$3fmt17h8a7427ec99f7ed22E+0x80/0xa0 [helloworld]
[  247.070679]  ? _ZN4core3fmt3num49_$LT$impl$u20$core..fmt..Debug$u20$for$u20$u8$GT$3fmt17h9010dd741ac356b3E+0x64/0xa0 [helloworld]
[  247.070679]  ? _ZN42_$LT$$RF$T$u20$as$u20$core..fmt..Debug$GT$3fmt17hce45b733e98582cdE+0x18/0x30 [helloworld]
[  247.070679]  ? _ZN4core3fmt8builders10DebugInner9is_pretty17h61db7b5335d258d0E+0x14/0x30 [helloworld]
[  247.070679]  ? _ZN4core3fmt8builders10DebugInner5entry28_$u7b$$u7b$closure$u7d$$u7d$17h17d35c1353ea2e80E+0x23c/0x250 [helloworld]
[  247.070679]  ? _ZN79_$LT$linux_kernel_module..printk..LogLineWriter$u20$as$u20$core..fmt..Write$GT$9write_str17hb6b9f63c86335f4fE+0x1be/0x250 [he]
[  247.070679]  ? _ZN4core6result19Result$LT$T$C$E$GT$8and_then17hc710b76977389ea0E+0x4e/0x70 [helloworld]
[  247.070679]  ? _ZN4core3fmt8builders10DebugInner5entry17h92ae2868f0df466bE+0x43/0x70 [helloworld]
[  247.070679]  ? _ZN4core3fmt8builders9DebugList5entry17he09db0b952ed03ccE+0x23/0x30 [helloworld]
[  247.070679]  ? _ZN4core3fmt8builders9DebugList7entries17h8eb3996229be728fE+0x88/0xa0 [helloworld]
[  247.070679]  ? _ZN48_$LT$$u5b$T$u5d$$u20$as$u20$core..fmt..Debug$GT$3fmt17h9c57c882f7ac9744E+0x51/0x70 [helloworld]
[  247.070679]  ? _ZN50_$LT$$RF$mut$u20$T$u20$as$u20$core..fmt..Debug$GT$3fmt17hb8d4e0e57dc57deaE+0x2a/0x40 [helloworld]
[  247.070679]  ? _ZN4core3fmt5write17hb916ed05c0beea6fE+0x285/0x640 [helloworld]
[  247.070679]  ? _ZN4core3fmt3num3imp52_$LT$impl$u20$core..fmt..Display$u20$for$u20$u64$GT$3fmt17h67ec8b7f52fe9da3E+0xa0/0xa0 [helloworld]
[  247.070679]  ? _ZN11hello_world4foos17he560009d948fdbe9E+0x189/0x1e0 [helloworld]
[  247.070679]  ? _ZN4core3fmt3num3imp52_$LT$impl$u20$core..fmt..Display$u20$for$u20$u64$GT$3fmt17h67ec8b7f52fe9da3E+0xa0/0xa0 [helloworld]
[  247.070679]  ? _ZN4core3fmt10ArgumentV13new17hf3e64bcfe2a81583E+0x50/0x50 [helloworld]
[  247.070679]  ? _ZN4core3fmt3num3imp52_$LT$impl$u20$core..fmt..Display$u20$for$u20$u64$GT$3fmt17h67ec8b7f52fe9da3E+0xa0/0xa0 [helloworld]
[  247.070679]  ? _ZN4core3fmt10ArgumentV13new17hf3e64bcfe2a81583E+0x50/0x50 [helloworld]
[  247.070679]  ? _ZN4core3fmt3num3imp52_$LT$impl$u20$core..fmt..Display$u20$for$u20$u64$GT$3fmt17h67ec8b7f52fe9da3E+0xa0/0xa0 [helloworld]
[  247.070679]  ? _ZN83_$LT$hello_world..HelloWorldModule$u20$as$u20$linux_kernel_module..KernelModule$GT$4init17hcdf4c87881ba8bf7E+0x55/0xb0 [hello]
[  247.092990]  ? __slab_free+0x14d/0x2c0
[  247.093536]  ? __switch_to_asm+0x35/0x70
[  247.093536]  ? __slab_free+0x14d/0x2c0
[  247.093536]  ? __switch_to_asm+0x35/0x70
[  247.093536]  ? __switch_to_asm+0x41/0x70
[  247.093536]  ? init_module+0x14/0xd0 [helloworld]
[  247.093536]  ? __slab_free+0x14d/0x2c0
[  247.093536]  ? __vunmap+0x8e/0xc0
[  247.093536]  ? kfree+0x165/0x180
[  247.093536]  ? do_one_initcall+0x52/0x19f
[  247.093536]  ? __vunmap+0x8e/0xc0
[  247.093536]  ? _cond_resched+0x19/0x40
[  247.093536]  ? kmem_cache_alloc_trace+0x14e/0x1b0
[  247.093536]  ? do_init_module+0x27/0x209
[  247.093536]  ? do_init_module+0x5f/0x209
[  247.093536]  ? load_module+0x1939/0x1f30
[  247.093536]  ? ima_post_read_file+0x96/0xa0
[  247.093536]  ? SYSC_finit_module+0xfc/0x120
[  247.093536]  ? SYSC_finit_module+0xfc/0x120
[  247.093536]  ? SyS_finit_module+0xe/0x10
[  247.093536]  ? do_syscall_64+0x73/0x130
[  247.093536]  ? entry_SYSCALL_64_after_hwframe+0x3d/0xa2
[  247.093536] Code: eb 08 48 c7 45 d0 00 00 00 00 48 8b 45 d0 48 8b 55 d8 48 83 c4 50 5d c3 00 00 00 55 48 89 e5 48 83 ec 50 48 89 7d e0 48 89 75 e 
[  247.097494] RIP: _ZN4core3num23_$LT$impl$u20$usize$GT$11checked_mul17h07ae83026124b5eaE+0x10/0x70 [helloworld] RSP: ffffa84b4169ffd0
[  247.097494] ---[ end trace b512caf3cbcd6f50 ]---
[  247.097494] Kernel panic - not syncing: corrupted stack end detected inside scheduler
[  247.097494] 
[  247.097494] Kernel Offset: 0x1b400000 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff)
[  247.097494] Rebooting in 60 seconds..
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Just for your information, you can pipe the kernel panic message to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;c++filt&lt;/code&gt; to get the demangled symbols (the kernel module is written in Rust and it does not yet seem to support &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[no_mangle]&lt;/code&gt;).&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ cat panic | c++filt 
[  247.009745] BUG: stack guard page was hit at 000000006c1ac1e1 (stack is 00000000487682b5..000000001262eb3a)
[  247.012648] kernel stack overflow (double-fault): 0000 [#1] SMP NOPTI
[  247.012648] Modules linked in: helloworld(POE+) binfmt_misc ppdev kvm_amd kvm irqbypass input_leds serio_raw parport_pc parport sch_fq_codel softy
[  247.012648] CPU: 1 PID: 2102 Comm: insmod Tainted: P           OE    4.15.0-64-generic #73-Ubuntu
[  247.012648] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014
[  247.012648] RIP: 0010:core::num::&amp;lt;impl usize&amp;gt;::checked_mul::h07ae83026124b5ea+0x10/0x70 [helloworld]
[  247.012648] RSP: 0018:ffffa84b4169ffd0 EFLAGS: 00000282
[  247.012648] RAX: 00000000000000fe RBX: 0000000000000000 RCX: 0000000000000000
[  247.012648] RDX: 0000000000000000 RSI: 0000000000000003 RDI: 0000000000000001
[  247.012648] RBP: ffffa84b416a0020 R08: ffffffffc0690d60 R09: 0000000000000003
[  247.012648] R10: 0000000000000000 R11: 0000000000000000 R12: ffffffffc059edf0
[  247.070679] R13: ffff9c5d78655a00 R14: 0000000000000001 R15: ffff9c5d51aeb240
[  247.070679] FS:  00007f690a2ff540(0000) GS:ffff9c5d7fd00000(0000) knlGS:0000000000000000
[  247.070679] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  247.070679] CR2: ffffa84b4169ffc8 CR3: 0000000137068000 CR4: 00000000000006e0
[  247.070679] Call Trace:
[  247.070679]  ? core::num::&amp;lt;impl usize&amp;gt;::saturating_mul::hc7be383430829098+0x15/0x50 [helloworld]
[  247.070679]  ? core::slice::from_raw_parts_mut::hc0afd704cde83aef+0x62/0xd0 [helloworld]
[  247.070679]  ? _ZN99_$LT$core..ops..range..Range$LT$usize$GT$$u20$as$u20$core..slice..SliceIndex$LT$$u5b$T$u5d$$GT$$GT$17get_unchecked_mut17h8+0x]
[  247.070679]  ? _ZN99_$LT$core..ops..range..Range$LT$usize$GT$$u20$as$u20$core..slice..SliceIndex$LT$$u5b$T$u5d$$GT$$GT$9index_mut17h59d846e1fc+0x]
[  247.070679]  ? core::cmp::min_by::h6a1a357c03d17732+0x3d/0x90 [helloworld]
[  247.070679]  ? core::slice::&amp;lt;impl core::ops::index::IndexMut&amp;lt;I&amp;gt; for [T]&amp;gt;::index_mut::h6d899aa41763834e+0x33/0]
[  247.070679]  ? &amp;lt;linux_kernel_module::printk::LogLineWriter as core::fmt::Write&amp;gt;::write_str::hb6b9f63c86335f4f+0x127/0x250 [he]
[  247.070679]  ? core::fmt::Formatter::pad_integral::hea95901f585e791c+0x260/0x8b0 [helloworld]
[  247.070679]  ? core::num::&amp;lt;impl usize&amp;gt;::saturating_mul::hc7be383430829098+0x15/0x50 [helloworld]
[  247.070679]  ? core::slice::from_raw_parts::hc54a1a170e771755+0x8f/0xd0 [helloworld]
[  247.070679]  ? core::fmt::num::imp::fmt_u64::hb10d5615ab39d4d8+0x5e6/0x720 [helloworld]
[  247.070679]  ? core::intrinsics::copy_nonoverlapping::h66731a07c4e66efb+0xc2/0xd0 [helloworld]
[  247.070679]  ? core::fmt::num::imp::&amp;lt;impl core::fmt::Display for u8&amp;gt;::fmt::h8a7427ec99f7ed22+0x80/0xa0 [helloworld]
[  247.070679]  ? core::fmt::num::&amp;lt;impl core::fmt::Debug for u8&amp;gt;::fmt::h9010dd741ac356b3+0x64/0xa0 [helloworld]
[  247.070679]  ? &amp;lt;&amp;amp;T as core::fmt::Debug&amp;gt;::fmt::hce45b733e98582cd+0x18/0x30 [helloworld]
[  247.070679]  ? core::fmt::builders::DebugInner::is_pretty::h61db7b5335d258d0+0x14/0x30 [helloworld]
[  247.070679]  ? core::fmt::builders::DebugInner::entry::::h17d35c1353ea2e80+0x23c/0x250 [helloworld]
[  247.070679]  ? &amp;lt;linux_kernel_module::printk::LogLineWriter as core::fmt::Write&amp;gt;::write_str::hb6b9f63c86335f4f+0x1be/0x250 [he]
[  247.070679]  ? core::result::Result&amp;lt;T,E&amp;gt;::and_then::hc710b76977389ea0+0x4e/0x70 [helloworld]
[  247.070679]  ? core::fmt::builders::DebugInner::entry::h92ae2868f0df466b+0x43/0x70 [helloworld]
[  247.070679]  ? core::fmt::builders::DebugList::entry::he09db0b952ed03cc+0x23/0x30 [helloworld]
[  247.070679]  ? core::fmt::builders::DebugList::entries::h8eb3996229be728f+0x88/0xa0 [helloworld]
[  247.070679]  ? &amp;lt;[T] as core::fmt::Debug&amp;gt;::fmt::h9c57c882f7ac9744+0x51/0x70 [helloworld]
[  247.070679]  ? &amp;lt;&amp;amp;mut T as core::fmt::Debug&amp;gt;::fmt::hb8d4e0e57dc57dea+0x2a/0x40 [helloworld]
[  247.070679]  ? core::fmt::write::hb916ed05c0beea6f+0x285/0x640 [helloworld]
[  247.070679]  ? core::fmt::num::imp::&amp;lt;impl core::fmt::Display for u64&amp;gt;::fmt::h67ec8b7f52fe9da3+0xa0/0xa0 [helloworld]
[  247.070679]  ? hello_world::foos::he560009d948fdbe9+0x189/0x1e0 [helloworld]
[  247.070679]  ? core::fmt::num::imp::&amp;lt;impl core::fmt::Display for u64&amp;gt;::fmt::h67ec8b7f52fe9da3+0xa0/0xa0 [helloworld]
[  247.070679]  ? core::fmt::ArgumentV1::new::hf3e64bcfe2a81583+0x50/0x50 [helloworld]
[  247.070679]  ? core::fmt::num::imp::&amp;lt;impl core::fmt::Display for u64&amp;gt;::fmt::h67ec8b7f52fe9da3+0xa0/0xa0 [helloworld]
[  247.070679]  ? core::fmt::ArgumentV1::new::hf3e64bcfe2a81583+0x50/0x50 [helloworld]
[  247.070679]  ? core::fmt::num::imp::&amp;lt;impl core::fmt::Display for u64&amp;gt;::fmt::h67ec8b7f52fe9da3+0xa0/0xa0 [helloworld]
[  247.070679]  ? &amp;lt;hello_world::HelloWorldModule as linux_kernel_module::KernelModule&amp;gt;::init::hcdf4c87881ba8bf7+0x55/0xb0 [hello]
[  247.092990]  ? __slab_free+0x14d/0x2c0
[  247.093536]  ? __switch_to_asm+0x35/0x70
[  247.093536]  ? __slab_free+0x14d/0x2c0
[  247.093536]  ? __switch_to_asm+0x35/0x70
[  247.093536]  ? __switch_to_asm+0x41/0x70
[  247.093536]  ? init_module+0x14/0xd0 [helloworld]
[  247.093536]  ? __slab_free+0x14d/0x2c0
[  247.093536]  ? __vunmap+0x8e/0xc0
[  247.093536]  ? kfree+0x165/0x180
[  247.093536]  ? do_one_initcall+0x52/0x19f
[  247.093536]  ? __vunmap+0x8e/0xc0
[  247.093536]  ? _cond_resched+0x19/0x40
[  247.093536]  ? kmem_cache_alloc_trace+0x14e/0x1b0
[  247.093536]  ? do_init_module+0x27/0x209
[  247.093536]  ? do_init_module+0x5f/0x209
[  247.093536]  ? load_module+0x1939/0x1f30
[  247.093536]  ? ima_post_read_file+0x96/0xa0
[  247.093536]  ? SYSC_finit_module+0xfc/0x120
[  247.093536]  ? SYSC_finit_module+0xfc/0x120
[  247.093536]  ? SyS_finit_module+0xe/0x10
[  247.093536]  ? do_syscall_64+0x73/0x130
[  247.093536]  ? entry_SYSCALL_64_after_hwframe+0x3d/0xa2
[  247.093536] Code: eb 08 48 c7 45 d0 00 00 00 00 48 8b 45 d0 48 8b 55 d8 48 83 c4 50 5d c3 00 00 00 55 48 89 e5 48 83 ec 50 48 89 7d e0 48 89 75 e 
[  247.097494] RIP: core::num::&amp;lt;impl usize&amp;gt;::checked_mul::h07ae83026124b5ea+0x10/0x70 [helloworld] RSP: ffffa84b4169ffd0
[  247.097494] ---[ end trace b512caf3cbcd6f50 ]---
[  247.097494] Kernel panic - not syncing: corrupted stack end detected inside scheduler
[  247.097494] 
[  247.097494] Kernel Offset: 0x1b400000 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff)
[  247.097494] Rebooting in 60 seconds..

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I triggered the above Linux kernel panic while I was trying to understand how the Rust LKM worked; In this case, I allocated large kernel stack which was caught by the stack guard which caused an immediate Kernel panic.
If you are into Rust and Linux kernel, I definitely recommend checking out &lt;a href=&quot;https://github.com/fishinabarrel/linux-kernel-module-rust&quot;&gt;linux-kernel-module-rust&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;auto-reboot-upon-linux-kernel-panic&quot;&gt;Auto-reboot upon Linux kernel panic&lt;/h3&gt;

&lt;p&gt;If you often get kernel panic (while developing/debugging kernel module or what not) or want to ensure system uptime in the face of Kernel instabilities, you could consider enabling &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;softdog&lt;/code&gt; in-tree linux kernel module.
This LKM runs a watchdog timer with a periodic heartbeat. Upon heartbeat failure, the timer associated with the heartbeat expires due to a kernel panic upon which, the system is rebooted. 
For this to work, a kernel parameter needs to be added to GRUB - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GRUB_CMDLINE_LINUX=&quot;panic=60&quot;&lt;/code&gt; in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/etc/default/grub&lt;/code&gt; and then &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;update-grub&lt;/code&gt; (for Ubuntu-like distro) needs to be run; Then the system needs to be rebooted.&lt;/p&gt;

&lt;p&gt;Ubuntu has commented out the automatic loading of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;softdog&lt;/code&gt; kernel module, so it needs to be added back in. Remove &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;softdog&lt;/code&gt; module from files that reside in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/lib/modprobe.d/*.conf&lt;/code&gt; and then add it to auto-load in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/etc/modules-load.d&lt;/code&gt;.
Then run the following:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ sudo update-initramfs -u
$ sudo depmod -a
$ sudo systemctl reboot
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Feel free to drop a comment if anything. As usual, until next time - Adios!&lt;/p&gt;</content><author><name>Ishwor Gurung</name><email>me@ishworgurung.com</email></author><summary type="html">Capturing Linux kernel panic message on QEMU</summary></entry><entry><title type="html">Underrated Socat</title><link href="https://gctl.io/blog/2020/underrated-socat/" rel="alternate" type="text/html" title="Underrated Socat" /><published>2020-05-01T00:00:00+05:45</published><updated>2020-05-01T00:00:00+05:45</updated><id>https://gctl.io/blog/2020/underrated-socat</id><content type="html" xml:base="https://gctl.io/blog/2020/underrated-socat/">&lt;h1 id=&quot;socat&quot;&gt;Socat&lt;/h1&gt;

&lt;p&gt;Socat is one of the most underrated software in Linux. It is a tool to help in debugging and applying network 
interops in ways the original author of a software probably had not anticipated. The author of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;socat&lt;/code&gt; describes it as
&lt;em&gt;multipurpose relay&lt;/em&gt; software (socket cat). People lovingly synonymize it as &lt;em&gt;like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cat&lt;/code&gt; but for sockets&lt;/em&gt;. I first came 
across &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;socat&lt;/code&gt; when I was working as a pentester back in the day (I have worn many hats in the past) whilst 
trying to work my way through protocol debugging.&lt;/p&gt;

&lt;p&gt;TL;DR? Refer to the &lt;a href=&quot;#socat the swiss-army knife&quot;&gt;commands&lt;/a&gt; instead.&lt;/p&gt;

&lt;h2 id=&quot;the-socat-story&quot;&gt;The socat story&lt;/h2&gt;

&lt;p&gt;So, why would you need socat? Follow through on the fictionalised story below &lt;sup&gt;1&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;Let’s pretend that we want to have a TCP client sitting locally to be able to connect to a TCP server sitting
elsewhere on port 3450; i.e., a TCP network clients connect to a TCP socket on the server at port 3450. 
This is the trivial part and software libraries have evolved to abstract almost 99% of this game so engineers can have
a good sleep.&lt;/p&gt;

&lt;p&gt;Now, here’s the catch - say that &lt;em&gt;Bob the sysadmin&lt;/em&gt; appeared on the deck of this ship and said that clients can only connect
to TCP sockets on the server on port 80 and 443 &lt;sup&gt;2&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;You can use many tools in Linux and *BSDs (and that’s the beauty of it - each to their own) to achieve the precise outcome 
(HAProxy, Nginx, iptables DNATs, SSH port forwards, IPsec tunnels, sshuttle, Wireguard etc..) but in this instance I
would like to focus only on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;socat&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So, how could &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;socat&lt;/code&gt; be of help here for a quick win? The TCP client will now connect to the server on port &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;80&lt;/code&gt;. 
That is, the TCP endpoint to the client will look like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;server.ip.address:80&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;On the server, Bob, the sysadmin will spin up &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;socat&lt;/code&gt; and run a TCP relay from the listening TCP port &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;80&lt;/code&gt; to the local
loopback address’ TCP port &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;3450&lt;/code&gt;. Thus, Bob, the sysadmin will run this on the server:&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;socat &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt; tcp-listen:80,reuseaddr,fork tcp-connect:127.0.0.1:3450
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This will relay all TCP packets that connect to the server on port &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;80&lt;/code&gt; to be sent to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;127.0.0.1&lt;/code&gt; on port &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;3450&lt;/code&gt;. As
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;socat&lt;/code&gt; accepts a TCP client connection on port &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;80&lt;/code&gt;, it will fork a new child process, set up a bi-directional socket
pairs on the child process and forward all incoming and outgoing TCP packets via these descriptors. The parent process will
continue to service new TCP connections.&lt;/p&gt;

&lt;p&gt;Until a permanent solution is in place&lt;sup&gt;2&lt;/sup&gt;, Bob can now proceed to block non-standard TCP port to ingress the
server.&lt;/p&gt;

&lt;h2 id=&quot;socat-the-swiss-army-knife&quot;&gt;socat the swiss-army knife&lt;/h2&gt;

&lt;p&gt;An exhaustive list of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;socat&lt;/code&gt; capabilities is documented in the manual page for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;socat(1)&lt;/code&gt; and it is 
still the authoritative source. Below are some common ones one might need.&lt;/p&gt;

&lt;h3 id=&quot;relay-tcp-to-tcp&quot;&gt;Relay TCP to TCP&lt;/h3&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;socat &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt; tcp-listen:80,reuseaddr,fork tcp-connect:172.16.2.10:8080
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;relay-tcp-to-udp&quot;&gt;Relay TCP to UDP&lt;/h3&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;socat &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt; tcp-listen:80,reuseaddr,fork udp-connect:172.16.2.10:8080
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;relay-udp-to-udp&quot;&gt;Relay UDP to UDP&lt;/h3&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;socat &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt; udp-listen:80,reuseaddr,fork udp-connect:172.16.2.10:8080
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;relay-udp-to-tcp&quot;&gt;Relay UDP to TCP&lt;/h3&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;socat &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt; udp-listen:80,reuseaddr,fork tcp-connect:172.16.2.10:8080
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;relay-tcp-to-unix-domain-sockets&quot;&gt;Relay TCP to Unix Domain Sockets&lt;/h3&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;socat &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt; tcp-listen:80,reuseaddr,fork unix-client:/var/run/uds.sock
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;relay-unix-domain-sockets-to-tcp&quot;&gt;Relay Unix Domain Sockets to TCP&lt;/h3&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;socat &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt; unix-listen:/var/run/uds.sock,reuseaddr,fork tcp-connect:172.16.2.10:80
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;relay-udp-to-unix-domain-sockets&quot;&gt;Relay UDP to Unix Domain Sockets&lt;/h3&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;socat &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt; udp-listen:80,reuseaddr,fork unix-client:/var/run/uds.sock
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;relay-unix-domain-sockets-to-udp&quot;&gt;Relay Unix Domain Sockets to UDP&lt;/h3&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;socat &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt; unix-listen:/var/run/uds.sock,reuseaddr,fork udp-connect:172.16.2.10:80
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;relay-sctp-to-unix-domain-sockets&quot;&gt;Relay SCTP to Unix Domain Sockets&lt;/h3&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;socat &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt; sctp-listen:80,reuseaddr,fork unix-client:/var/run/uds.sock
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;relay-unix-domain-sockets-to-sctp&quot;&gt;Relay Unix Domain Sockets to SCTP&lt;/h3&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;socat &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt; unix-listen:/var/run/uds.sock,reuseaddr,fork sctp-connect:172.16.2.10:80
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;tunnel-unix-domain-socket-packets-inside-tls-relay&quot;&gt;Tunnel Unix Domain Socket packets inside TLS relay&lt;/h3&gt;
&lt;p&gt;Please avoid setting &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;verify=0&lt;/code&gt; on production if you can.&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;socat &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt;                                          &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    unix-listen:/var/run/uds.sock,reuseaddr,fork    &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    openssl:server.domain.name:443,certificate&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;cert.pem,cafile&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;cert.pem,verify&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;1,key&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;key.pem,commonname&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;server.domain.name
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;relay-tls-packets-to-unix-domain-socket-aka-virtual-patching&quot;&gt;Relay TLS packets to Unix Domain Socket (aka virtual patching)&lt;/h3&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;socat &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt;                                                                                             &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    openssl-listen:443,reuseaddr,pf&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;ip4,fork,key&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;key.pem,cafile&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;cert.pem,cert&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;cert.pem,method&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;TLS1.2   &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    unix-client:/var/run/uds.sock
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;capture-tls-packets-to-devstdout-for-quick-debugging&quot;&gt;Capture TLS packets to /dev/stdout for quick debugging&lt;/h3&gt;
&lt;p&gt;Please avoid setting &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;verify=0&lt;/code&gt; on production if you can.&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;socat &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt;                                                                                       				&lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    openssl-listen:443,reuseaddr,pf&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;ip4,fork,key&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;key.pem,cafile&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;cert.pem,cert&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;cert.pem,verify&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0,commonname&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;server.domain.name	&lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    file:/dev/stdout
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Feel free to drop me a comment if anything. Until next time adios!&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;sup&gt;1&lt;/sup&gt; Everything in this story is fictional and has been trivialised for the purpose of simplicity. I am a big
fan of KISS philosophy although I haven’t had the time to listen to the band KISS at all :smile:.&lt;/p&gt;

&lt;p&gt;&lt;sup&gt;2&lt;/sup&gt; Let’s pretend that there is a forcing function here.&lt;/p&gt;</content><author><name>Ishwor Gurung</name><email>me@ishworgurung.com</email></author><summary type="html">Socat</summary></entry><entry><title type="html">Dnssec For The Win</title><link href="https://gctl.io/blog/2020/dnssec-for-the-win/" rel="alternate" type="text/html" title="Dnssec For The Win" /><published>2020-04-15T00:00:00+05:45</published><updated>2020-04-15T00:00:00+05:45</updated><id>https://gctl.io/blog/2020/dnssec-for-the-win</id><content type="html" xml:base="https://gctl.io/blog/2020/dnssec-for-the-win/">&lt;h2 id=&quot;fast-intro&quot;&gt;Fast Intro&lt;/h2&gt;

&lt;p&gt;DNSSEC uses digital signature to verify the authenticity and integrity of DNS records. In essence, it sets up
a non-spoofable chain of trust right from the root zone down to the authoritative nameserver and further to modern caching
resolvers (e.g., BIND, Unbound etc.). Of course, there’s &lt;a href=&quot;https://youtu.be/_8M_vuFcdZU&quot;&gt;more&lt;/a&gt;, 
&lt;a href=&quot;https://www.cloudflare.com/learning/dns/dns-records/dnskey-ds-records/&quot;&gt;on it&lt;/a&gt; and 
&lt;a href=&quot;https://www.internetsociety.org/resources/deploy360/2011/dnssec-rfcs-3/&quot;&gt;some more&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;why-dnssec&quot;&gt;Why DNSSEC&lt;/h3&gt;

&lt;p&gt;There are many reasons to turn on DNSSEC, some of which some of them are outright detrimental to businesses 
(loss of revenue for instance).&lt;/p&gt;

&lt;p&gt;It may surprise you to find a number of &lt;em&gt;household&lt;/em&gt; domains do not use DNSSEC.&lt;/p&gt;

&lt;p&gt;In general these are some reasons to use DNSSEC:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;DNS Protocol Attacks&lt;/li&gt;
  &lt;li&gt;BGP Hijacking Attack&lt;sup&gt;1&lt;/sup&gt;&lt;/li&gt;
  &lt;li&gt;DNS Hijacking (Credential Theft)&lt;/li&gt;
  &lt;li&gt;Domain Theft&lt;/li&gt;
  &lt;li&gt;Cache Poisoning&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It goes without saying that DNSSEC is not a panacea :pill:&lt;/p&gt;

&lt;h3 id=&quot;turn-the-secure-bits-on&quot;&gt;Turn the secure bits on&lt;/h3&gt;

&lt;p&gt;To have DNSSEC turned on for a domain, you need three parties working in tandem with each other :revolving_hearts:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;The Domain Name Registrar (e.g., Namecheap, Godaddy, tucows etc.) of the domain&lt;/li&gt;
  &lt;li&gt;The Authoritative Name Server (e.g., BYO BIND/NSD/PDNS, Route53, Vultr, NS1 etc.) of the domain&lt;/li&gt;
  &lt;li&gt;The “abstracted” Root Name Servers (I say “abstracted” as it will appear almost invisible to us :boom:)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For illustrative purpose, I will use my domain &lt;strong&gt;ishworgurung.com&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;My personal domain &lt;strong&gt;ishworgurung.com&lt;/strong&gt; is registered using Namecheap and the authoritative name server is at Vultr.&lt;/p&gt;

&lt;p&gt;So, to setup DNSSEC for my domain, I need to generate a fresh copy of &lt;em&gt;DS Records&lt;/em&gt; (Delegation Signer) from Vultr. 
Of particular use are:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Key Tag / Key Type (A unique key per DS record used for lookups) &lt;a href=&quot;https://tools.ietf.org/html/rfc3658#section-2.4.1&quot;&gt;see here&lt;/a&gt; and &lt;a href=&quot;https://tools.ietf.org/html/rfc2535#section-4.1.6&quot;&gt;here&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Domain_Name_System_Security_Extensions#Algorithms&quot;&gt;Algorithm&lt;/a&gt; (crypto algorithm)&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Domain_Name_System_Security_Extensions#Algorithms&quot;&gt;Digest Type&lt;/a&gt; (hashing algorithm)&lt;/li&gt;
  &lt;li&gt;Digest (hexadecimal representation of the digest)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vultr by default generates three DS records, copy them to Namecheap’s DNSSEC console.&lt;/p&gt;

&lt;h3 id=&quot;handy-tools&quot;&gt;Handy tools&lt;/h3&gt;

&lt;p&gt;Some handy tools the &lt;em&gt;internets&lt;/em&gt; has to offer :100:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;https://dnsviz.net&lt;/li&gt;
  &lt;li&gt;https://dnssec-debugger.verisignlabs.com&lt;/li&gt;
  &lt;li&gt;Dig from Bind
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dig +short ds ishworgurung.com&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dig +short dnskey ishworgurung.com&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dig +short nsec ishworgurung.com&lt;/code&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;Someone on the internet said:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;DNSSEC is a tool, not a religion. Please try to understand how the tool works before criticizing it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And I agree. DNSSEC is a good thing - let’s do more of it; not less.&lt;/p&gt;

&lt;p&gt;I leave you with Dr. Casey Deccio’s &lt;a href=&quot;https://casey.byu.edu/media/hello_summer_break.mp3&quot;&gt;Hello Summer Break&lt;/a&gt; :sound:.
Dr. Casey is the original author of DNSViz :beers:&lt;/p&gt;

&lt;p&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;a href=&quot;https://isbgpsafeyet.com/&quot;&gt;Is BGP Safe Yet&lt;/a&gt;.&lt;/p&gt;</content><author><name>Ishwor Gurung</name><email>me@ishworgurung.com</email></author><summary type="html">Fast Intro</summary></entry><entry><title type="html">Vlan On Openbsd</title><link href="https://gctl.io/blog/2019/vlan-on-openbsd/" rel="alternate" type="text/html" title="Vlan On Openbsd" /><published>2019-12-07T00:00:00+05:45</published><updated>2019-12-07T00:00:00+05:45</updated><id>https://gctl.io/blog/2019/vlan-on-openbsd</id><content type="html" xml:base="https://gctl.io/blog/2019/vlan-on-openbsd/">&lt;h2 id=&quot;three-minute-guide-to-set-up-vlan-on-openbsd&quot;&gt;Three minute guide to set up VLAN on OpenBSD&lt;/h2&gt;

&lt;p&gt;If you live under the rock, go check out &lt;a href=&quot;https://www.openbsd.org&quot;&gt;OpenBSD&lt;/a&gt;. It’s pretty nice. I have been running OpenBSD on my servers for about five years and I absolutely love it. Simplicity, robust, secure and minimal - you name it; It’s all there. If you got an old intel 386 or an RaspberryPI, it will be sufficient to run the humble OpenBSD.&lt;/p&gt;

&lt;p&gt;Now onto how I VLAN my OpenBSD guest.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vio0&lt;/code&gt; NIC is based on a QEMU’ed guest on the usual &lt;a href=&quot;https://man.openbsd.org/vio&quot;&gt;VIO(4)&lt;/a&gt; driver.&lt;/p&gt;

&lt;p&gt;Get these files up:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$&amp;gt; cat /etc/hostname.vio0 
up
$&amp;gt; cat /etc/hostname.vlan8
inet 10.2.1.61 255.255.255.0 NONE vlan 8 vlandev vio0
up
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then restart the network (or simply reboot)&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$&amp;gt; sh /etc/netstart
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then after the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ifconfig&lt;/code&gt; should look like this:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$&amp;gt; ifconfig # removed listing of other interfaces for brevity
vio0: flags=8843&amp;lt;UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST&amp;gt; mtu 1500
	lladdr ab:cd:ef:ab:cd:ef
	index 1 priority 0 llprio 3
	media: Ethernet autoselect
	status: active
vlan8: flags=8843&amp;lt;UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST&amp;gt; mtu 1500
	lladdr ab:cd:ef:ab:cd:ef
	index 4 priority 0 llprio 3
	encap: vnetid 8 parent vio0 txprio packet rxprio outer
	groups: vlan egress
	media: Ethernet autoselect
	status: active
	inet 10.2.1.61 netmask 0xffffff00 broadcast 10.2.1.255
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Watch out for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;inet&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;parent&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vnetid&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;broadcast&lt;/code&gt; in the above listing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NB:&lt;/strong&gt; Please note that the interfaces that sit between the packet path should all have equal MTUs (e.g. in the above listing, the MTU is 1500). Any switches that sit in between should also support &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;802.1q&lt;/code&gt; protocol so the VLAN’ed packets can be tagged accordingly. Thanks to &lt;em&gt;martian67&lt;/em&gt; for this.&lt;/p&gt;

&lt;h2 id=&quot;psa-public-service-announcement&quot;&gt;PSA (Public Service Announcement)&lt;/h2&gt;

&lt;p&gt;If you run a network with IoT (Internet Of shit Things), consider putting them in a filtered VLAN that can only communicate within the LAN and not to the internet. This is because a lot of these IoT (Internet Of shit Things) &lt;em&gt;call home&lt;/em&gt; and could potentially ex-filtrate private informations :boom:&lt;/p&gt;</content><author><name>Ishwor Gurung</name><email>me@ishworgurung.com</email></author><summary type="html">Three minute guide to set up VLAN on OpenBSD</summary></entry><entry><title type="html">Interesting Links 8</title><link href="https://gctl.io/blog/2019/interesting-links-8/" rel="alternate" type="text/html" title="Interesting Links 8" /><published>2019-12-06T00:00:00+05:45</published><updated>2019-12-06T00:00:00+05:45</updated><id>https://gctl.io/blog/2019/interesting-links-8</id><content type="html" xml:base="https://gctl.io/blog/2019/interesting-links-8/">&lt;h2 id=&quot;interesting-links-8&quot;&gt;Interesting links #8&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=2ff-7UTg5rE&quot;&gt;Ftrace&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.brendangregg.com/bpf-performance-tools-book.html&quot;&gt;BPF Performance Tools: Linux System and Application Observability&lt;/a&gt;&lt;/p&gt;</content><author><name>Ishwor Gurung</name><email>me@ishworgurung.com</email></author><summary type="html">Interesting links #8</summary></entry><entry><title type="html">Interesting Links 7</title><link href="https://gctl.io/blog/2019/interesting-links-7/" rel="alternate" type="text/html" title="Interesting Links 7" /><published>2019-09-24T00:00:00+05:45</published><updated>2019-09-24T00:00:00+05:45</updated><id>https://gctl.io/blog/2019/interesting-links-7</id><content type="html" xml:base="https://gctl.io/blog/2019/interesting-links-7/">&lt;h2 id=&quot;interesting-links-7&quot;&gt;Interesting links #7&lt;/h2&gt;

&lt;h1 id=&quot;tldr&quot;&gt;TL;DR&lt;/h1&gt;

&lt;p&gt;Watch &lt;a href=&quot;https://www.youtube.com/watch?v=fYMDzk6HYGU&quot;&gt;Can strace make you fail? strace syscall fault injection&lt;/a&gt; by Dmitry Levin who is its current maintainer.&lt;/p&gt;

&lt;h1 id=&quot;non-tldr&quot;&gt;Non TL;DR&lt;/h1&gt;

&lt;p&gt;I find myself needing to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;strace(1)&lt;/code&gt; to debug stuffs a lot but recently, I found myself re-visiting it. 
Enter syscall tampering / fault injection - Youtube talk by Dmitry Levin &lt;a href=&quot;https://www.youtube.com/watch?v=fYMDzk6HYGU&quot;&gt;Fault Injection in strace&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The reason fault injection becomes a useful tool to have in the arsenal is because you may need to &lt;em&gt;dynamically&lt;/em&gt; inject
error path into codes developed using Go / Rust / C (amongst the modern language ecosystem). With &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;strace(1)&lt;/code&gt;, from the
application’s point of view, it is all as if Linux kernel handled the system call as per your application’s need; where
in-fact &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;strace(1)&lt;/code&gt; dynamically instrumented the target syscall and &lt;em&gt;injected&lt;/em&gt; the fault for your application.&lt;/p&gt;

&lt;p&gt;The alternative to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;strace(1)&lt;/code&gt; is a little costly - bcc/ebpf that need to be instrumented at compile-time 
(but bcc/ebpf is extremely powerful!) or &lt;em&gt;perf&lt;/em&gt; (extremely heavyweight).&lt;/p&gt;

&lt;p&gt;Until next Interesting links, keep testing injecting those faults in your code! :-)&lt;/p&gt;</content><author><name>Ishwor Gurung</name><email>me@ishworgurung.com</email></author><summary type="html">Interesting links #7</summary></entry></feed>