Skip to content

Commit

Permalink
Add -n pid:x,path:x
Browse files Browse the repository at this point in the history
  • Loading branch information
jschwinger233 committed Nov 20, 2023
1 parent a08bcf7 commit 6cc78f3
Show file tree
Hide file tree
Showing 7 changed files with 134 additions and 58 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Usage of skbdump:
-i, --interface string interface to capture (default "lo")
-a, --kaddrs string kernel addresses to trace, e.g. "0xffffffffa0272110,0xffffffffa0272118"
-f, --kfuncs string kernel functions to trace, e.g. "ip_rcv,icmp_rcv"
-n, --netns string netns specifier, e.g. "pid:1234", "path:/var/run/netns/foo"
-o, --output-fields string output fields of skb, e.g. "mark,cb"
-w, --pcap-filename string output pcap filename (default "skbdump.pcap")
-s, --skb-filename string output skb filename (default "skbdump.meta")
Expand Down
41 changes: 26 additions & 15 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import (
"strings"

"github.com/jschwinger233/skbdump/bpf"
"github.com/jschwinger233/skbdump/utils"
flag "github.com/spf13/pflag"
"github.com/vishvananda/netns"
"golang.org/x/sys/unix"
"github.com/vishvananda/netlink"
)

type Config struct {
Expand All @@ -19,7 +19,8 @@ type Config struct {
PcapFilename string
PcapFilterExp string

Netns uint32
*utils.Netns
ifindex2name map[uint32]string
}

var (
Expand All @@ -35,24 +36,34 @@ func mustInitConfig() {
flag.StringVarP(&outputFields, "output-fields", "o", "", "output fields of skb, e.g. \"mark,cb\"")
flag.StringVarP(&config.SkbFilename, "skb-filename", "s", "skbdump.meta", "output skb filename")
flag.StringVarP(&config.PcapFilename, "pcap-filename", "w", "skbdump.pcap", "output pcap filename")
var netnsSpecifier string
flag.StringVarP(&netnsSpecifier, "netns", "n", "", "netns specifier, e.g. \"pid:1234\", \"path:/var/run/netns/foo\"")
flag.Parse()
if outputFields != "" {
config.OutputFields = strings.Split(outputFields, ",")
}
config.PcapFilterExp = strings.Join(flag.Args(), " ")

ns, err := netns.Get()
if err != nil {
log.Fatalf("Failed to get netns: %+v", err)
var err error
if config.Netns, err = utils.NewNetns(netnsSpecifier); err != nil {
log.Fatalf("failed to parse netns: %+v", err)
}
var s unix.Stat_t
if err = unix.Fstat(int(ns), &s); err != nil {
if err = config.Netns.Do(func() (err error) {
config.ifindex2name = make(map[uint32]string)
links, err := netlink.LinkList()
if err != nil {
return err
}
for _, link := range links {
config.ifindex2name[uint32(link.Attrs().Index)] = link.Attrs().Name
}
return
}); err != nil {
log.Fatalf("failed to get links: %+v", err)
}
config.Netns = uint32(s.Ino)

bpfObjs, err = bpf.New()
if err != nil {
if outputFields != "" {
config.OutputFields = strings.Split(outputFields, ",")
}
config.PcapFilterExp = strings.Join(flag.Args(), " ")

if bpfObjs, err = bpf.New(); err != nil {
log.Fatalf("%+v", err)
}
}
4 changes: 2 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@ func main() {
if err = bpfObjs.Load(bpf.LoadOptions{
Filter: config.PcapFilterExp,
BpfConfig: bpf.BpfConfig{
Netns: config.Netns,
Netns: config.Netns.Inode,
},
}); err != nil {
return
}

targets, err := target.Parse(config.Iface, config.Kfuncs, config.Kaddrs)
targets, err := target.Parse(config.Netns, config.Iface, config.Kfuncs, config.Kaddrs)
if err != nil {
return
}
Expand Down
7 changes: 3 additions & 4 deletions skbprint.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,9 @@ func skbPrint(skb *bpf.Skbdump, linktype layers.LinkType) {
idx++
fmt.Printf("%d %016x ", idx, skb.Meta.Skb)

ifname := "unknown"
iface, err := net.InterfaceByIndex(int(skb.Meta.Ifindex))
if err == nil {
ifname = iface.Name
ifname, ok := config.ifindex2name[skb.Meta.Ifindex]
if !ok {
ifname = "unknown"
}

ksym, off := utils.Addr2ksym(skb.Meta.At)
Expand Down
78 changes: 43 additions & 35 deletions target/dev/dev.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,43 +4,47 @@ import (
"net"

"github.com/jschwinger233/skbdump/bpf"
"github.com/pkg/errors"
"github.com/jschwinger233/skbdump/utils"
"github.com/vishvananda/netlink"
)

type Device struct {
Name string
Ifindex int
Link netlink.Link
Netns *utils.Netns

delIngress func() error
delEgress func() error
}

func GetDevices(iface string) (devices []*Device, err error) {
links := []netlink.Link{}
func GetDevices(netns *utils.Netns, iface string) (devices []*Device, _ error) {
return devices, netns.Do(func() (err error) {
links := []netlink.Link{}

if iface == "any" {
if links, err = netlink.LinkList(); err != nil {
return nil, errors.WithStack(err)
if iface == "any" {
if links, err = netlink.LinkList(); err != nil {
return
}
} else {
link, err := netlink.LinkByName(iface)
if err != nil {
return err
}
links = append(links, link)
}
} else {
link, err := netlink.LinkByName(iface)
if err != nil {
return nil, errors.WithStack(err)
}
links = append(links, link)
}

for _, link := range links {
linkAttrs := link.Attrs()
devices = append(devices, &Device{
Name: linkAttrs.Name,
Ifindex: linkAttrs.Index,
Link: link,
})
}
return
for _, link := range links {
linkAttrs := link.Attrs()
devices = append(devices, &Device{
Name: linkAttrs.Name,
Ifindex: linkAttrs.Index,
Link: link,
Netns: netns,
})
}
return
})
}

func (d *Device) IsL3Device() bool {
Expand All @@ -52,20 +56,24 @@ func (d *Device) IsLoopback() bool {
return d.Link.Attrs().Flags&net.FlagLoopback != 0
}

func (d *Device) Attach(objs bpf.Objects) (err error) {
if err = d.EnsureTcQdisc(); err != nil {
return
}
d.delIngress, err = d.AddIngressFilter(objs.TcIngress())
if err != nil {
func (d *Device) Attach(objs bpf.Objects) error {
return d.Netns.Do(func() (err error) {
if err = d.EnsureTcQdisc(); err != nil {
return
}
d.delIngress, err = d.AddIngressFilter(objs.TcIngress())
if err != nil {
return
}
d.delEgress, err = d.AddEgressFilter(objs.TcEgress())
return
}
d.delEgress, err = d.AddEgressFilter(objs.TcEgress())
return
})
}

func (d *Device) Detach() (err error) {
d.delIngress()
d.delEgress()
return
func (d *Device) Detach() error {
return d.Netns.Do(func() (err error) {
d.delIngress()
d.delEgress()
return
})
}
5 changes: 3 additions & 2 deletions target/target.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@ import (
"github.com/jschwinger233/skbdump/target/dev"
"github.com/jschwinger233/skbdump/target/kaddr"
"github.com/jschwinger233/skbdump/target/kfunc"
"github.com/jschwinger233/skbdump/utils"
)

type Target interface {
Attach(bpfObjects bpf.Objects) error
Detach() error
}

func Parse(iface, skbfuncs string, addrs string) (targets []Target, err error) {
devs, err := dev.GetDevices(iface)
func Parse(netns *utils.Netns, iface, skbfuncs string, addrs string) (targets []Target, err error) {
devs, err := dev.GetDevices(netns, iface)
if err != nil {
return
}
Expand Down
56 changes: 56 additions & 0 deletions utils/netns.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package utils

import (
"fmt"
"strconv"
"strings"

"github.com/vishvananda/netns"
"golang.org/x/sys/unix"
)

type Netns struct {
Specifier string

Inode uint32
ns netns.NsHandle
}

func NewNetns(specifier string) (_ *Netns, err error) {
var ns netns.NsHandle
switch {
case specifier == "":
ns, err = netns.Get()
case strings.HasPrefix(specifier, "pid:"):
pid, err := strconv.Atoi(specifier[4:])
if err != nil {
break
}
ns, err = netns.GetFromPid(pid)
case strings.HasPrefix(specifier, "path:"):
ns, err = netns.GetFromPath(specifier[5:])
default:
err = fmt.Errorf("invalid netns specifier: %s", specifier)
}
if err != nil {
return
}

var s unix.Stat_t
if err = unix.Fstat(int(ns), &s); err != nil {
return
}
return &Netns{Specifier: specifier, ns: ns, Inode: uint32(s.Ino)}, nil
}

func (n *Netns) Do(f func() error) (err error) {

orig, err := netns.Get()
if err != nil {
return err
}
defer orig.Close()
netns.Set(n.ns)
defer netns.Set(orig)
return f()
}

0 comments on commit 6cc78f3

Please sign in to comment.