diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a791d6cc..b4cb7972 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -85,13 +85,14 @@ jobs: # Block traffic to both endpoints, so that we can see kfree_skb* # in traces (test assertion) - iptables -I OUTPUT 1 -m tcp --proto tcp --dst 1.0.0.1/32 -j DROP - ip6tables -I OUTPUT 1 -m tcp --proto tcp --dst 2606:4700:4700::1001 -j DROP + iptables -I OUTPUT 1 -m tcp --proto tcp --dst 1.0.0.1/32 --dport 8080 -j DROP + ip6tables -I OUTPUT 1 -m tcp --proto tcp --dst 2606:4700:4700::1001 --dport 8080 -j DROP i=0 for addr in '1.0.0.1' '2606:4700:4700::1001'; do i=\$((i+1)) - /host/pwru/pwru --filter-dst-ip="\$addr" --output-tuple \ + port=8080 + /host/pwru/pwru --filter-dst-ip="\$addr" --filter-port="\$port" --output-tuple \ --output-file=/tmp/pwru-\$i.log \ --ready-file=/tmp/pwru-\$i.ready 2>/tmp/pwru-\$i.status & PWRU_PID=\$! @@ -102,12 +103,12 @@ jobs: if \$(echo \$addr | grep -q ':'); then url="[\$addr]"; fi echo \$url - curl -vvv -sS --fail --connect-timeout "1" -o /dev/null http://\$url || true + curl -vvv -sS --fail --connect-timeout "1" -o /dev/null http://\$url:\$port || true kill \$PWRU_PID wait \$PWRU_PID - grep "kfree_skb" /tmp/pwru-\$i.log | grep -F "\${url}:80" + grep "kfree_skb" /tmp/pwru-\$i.log | grep -F "\${url}:\${port}" done - name: Fetch artifacts diff --git a/bpf/kprobe_pwru.c b/bpf/kprobe_pwru.c index dff4c3e6..c4d33e5d 100644 --- a/bpf/kprobe_pwru.c +++ b/bpf/kprobe_pwru.c @@ -69,6 +69,7 @@ struct config { u8 l4_proto; u16 sport; u16 dport; + u16 port; u8 output_timestamp; u8 output_meta; u8 output_tuple; @@ -164,7 +165,7 @@ config_tuple_empty(struct config *cfg) { if (!cfg->l4_proto && \ addr_is_zero(cfg->saddr) && \ addr_is_zero(cfg->daddr) && \ - !cfg->sport && !cfg->dport) + !cfg->sport && !cfg->dport && !cfg->port) return true; return false; @@ -232,7 +233,7 @@ filter_l3_and_l4(struct sk_buff *skb, struct config *cfg) { if (cfg->l4_proto && l4_proto != cfg->l4_proto) return false; - if (cfg->dport || cfg->sport) { + if (cfg->dport || cfg->sport || cfg->port) { if (l4_proto == IPPROTO_TCP) { struct tcphdr *tmp = (struct tcphdr *) (skb_head + l4_off); struct tcphdr tcp; @@ -256,6 +257,9 @@ filter_l3_and_l4(struct sk_buff *skb, struct config *cfg) { if (cfg->dport && dport != cfg->dport) return false; + + if (cfg->port && (dport != cfg->port && sport != cfg->port)) + return false; } diff --git a/internal/pwru/config.go b/internal/pwru/config.go index fda52dd7..0881240c 100644 --- a/internal/pwru/config.go +++ b/internal/pwru/config.go @@ -31,6 +31,7 @@ type FilterCfg struct { FilterProto uint8 FilterSrcPort uint16 FilterDstPort uint16 + FilterPort uint16 //TODO: if there are more options later, then you can consider using a bit map OutputRelativeTS uint8 @@ -47,12 +48,15 @@ func ConfigBPFMap(flags *Flags, cfgMap *ebpf.Map) { FilterNetns: flags.FilterNetns, FilterMark: flags.FilterMark, } - - if flags.FilterSrcPort > 0 { - cfg.FilterSrcPort = byteorder.HostToNetwork16(flags.FilterSrcPort) - } - if flags.FilterDstPort > 0 { - cfg.FilterDstPort = byteorder.HostToNetwork16(flags.FilterDstPort) + if flags.FilterPort > 0 { + cfg.FilterPort = byteorder.HostToNetwork16(flags.FilterPort) + } else { + if flags.FilterSrcPort > 0 { + cfg.FilterSrcPort = byteorder.HostToNetwork16(flags.FilterSrcPort) + } + if flags.FilterDstPort > 0 { + cfg.FilterDstPort = byteorder.HostToNetwork16(flags.FilterDstPort) + } } if flags.OutputSkb { cfg.OutputSkb = 1 diff --git a/internal/pwru/types.go b/internal/pwru/types.go index 15f3c6cc..18691b32 100644 --- a/internal/pwru/types.go +++ b/internal/pwru/types.go @@ -32,6 +32,7 @@ type Flags struct { FilterDstIP string FilterSrcPort uint16 FilterDstPort uint16 + FilterPort uint16 OutputTS string OutputMeta bool @@ -63,6 +64,7 @@ func (f *Flags) SetFlags() { flag.Uint32Var(&f.FilterMark, "filter-mark", 0, "filter skb mark") flag.Uint16Var(&f.FilterSrcPort, "filter-src-port", 0, "filter source port") flag.Uint16Var(&f.FilterDstPort, "filter-dst-port", 0, "filter destination port") + flag.Uint16Var(&f.FilterPort, "filter-port", 0, "filter either destination or source port") flag.StringVar(&f.OutputTS, "timestamp", "none", "print timestamp per skb (\"current\", \"relative\", \"none\")") flag.BoolVar(&f.OutputMeta, "output-meta", false, "print skb metadata") flag.BoolVar(&f.OutputTuple, "output-tuple", false, "print L4 tuple")