Skip to content

Commit

Permalink
FV test for conntrack upgrade
Browse files Browse the repository at this point in the history
  • Loading branch information
sridhartigera committed Jun 15, 2022
1 parent e68e815 commit 66afd31
Show file tree
Hide file tree
Showing 2 changed files with 178 additions and 10 deletions.
7 changes: 6 additions & 1 deletion felix/bpf/conntrack/v2/map.go
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,12 @@ func (e Value) Upgrade() bpf.Upgradable {
if ctType == TypeNormal {
val3 = v3.NewValueNormal(created, lastSeen, flags, v3LegAB, v3LegBA)
} else {
val3 = v3.NewValueNATReverseSNAT(created, lastSeen, flags, v3LegAB, v3LegBA, data.TunIP, data.OrigDst, data.OrigSrc, data.OrigPort)

if data.OrigSrc.Equal(net.IPv4(0,0,0,0)){
val3 = v3.NewValueNATReverse(created, lastSeen, flags, v3LegAB, v3LegBA, data.TunIP, data.OrigDst, data.OrigPort)
} else {
val3 = v3.NewValueNATReverseSNAT(created, lastSeen, flags, v3LegAB, v3LegBA, data.TunIP, data.OrigDst, data.OrigSrc, data.OrigPort)
}
val3.SetOrigSport(data.OrigSPort)
}
case TypeNATForward:
Expand Down
181 changes: 172 additions & 9 deletions felix/cmd/calico-bpf/commands/conntrack.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (

"github.com/projectcalico/calico/felix/bpf"
"github.com/projectcalico/calico/felix/bpf/conntrack"
"github.com/projectcalico/calico/felix/bpf/conntrack/v2"

"github.com/docopt/docopt-go"
"github.com/pkg/errors"
Expand All @@ -42,6 +43,7 @@ func init() {
})
conntrackCmd.AddCommand(newConntrackWriteCmd())
conntrackCmd.AddCommand(newConntrackFillCmd())
conntrackCmd.AddCommand(newConntrackCreateCmd())
rootCmd.AddCommand(conntrackCmd)
}

Expand All @@ -53,12 +55,15 @@ var conntrackCmd = &cobra.Command{

type conntrackDumpCmd struct {
*cobra.Command
Version string `docopt:"<version>"`

version int
}

func newConntrackDumpCmd() *cobra.Command {
cmd := &conntrackDumpCmd{
Command: &cobra.Command{
Use: "dump",
Use: "dump [<version>]",
Short: "Dumps connection tracking table",
},
}
Expand All @@ -80,15 +85,56 @@ func (cmd *conntrackDumpCmd) Args(c *cobra.Command, args []string) error {
return errors.New(err.Error())
}

switch cmd.Version {
case "2":
cmd.version = 2
default:
cmd.version = 3
}
return nil
}

func dumpCtMapV2(ctMap bpf.Map) error {
err := ctMap.Iter(func(k, v []byte) bpf.IteratorAction {
var ctKey v2.Key
if len(k) != len(ctKey) {
log.Panic("Key has unexpected length")
}
copy(ctKey[:], k[:])

var ctVal v2.Value
if len(v) != len(ctVal) {
log.Panic("Value has unexpected length")
}
copy(ctVal[:], v[:])

fmt.Printf("%v -> %v", ctKey, ctVal)
dumpExtrav2(ctKey, ctVal)
fmt.Printf("\n")
return bpf.IterNone
})
return err
}

func (cmd *conntrackDumpCmd) Run(c *cobra.Command, _ []string) {
var ctMap bpf.Map
mc := &bpf.MapContext{}
ctMap := conntrack.Map(mc)
switch cmd.version {
case 2:
ctMap = conntrack.MapV2(mc)
default:
ctMap = conntrack.Map(mc)
}
if err := ctMap.Open(); err != nil {
log.WithError(err).Fatal("Failed to access ConntrackMap")
}
if cmd.version == 2 {
err := dumpCtMapV2(ctMap)
if err != nil {
log.WithError(err).Fatal("Failed to iterate over conntrack entries")
}
return
}
err := ctMap.Iter(func(k, v []byte) bpf.IteratorAction {
var ctKey conntrack.Key
if len(k) != len(ctKey) {
Expand All @@ -112,6 +158,35 @@ func (cmd *conntrackDumpCmd) Run(c *cobra.Command, _ []string) {
}
}

func dumpExtrav2(k v2.Key, v v2.Value) {
now := bpf.KTimeNanos()

fmt.Printf(" Age: %s Active ago %s",
time.Duration(now-v.Created()), time.Duration(now-v.LastSeen()))

if k.Proto() != conntrack.ProtoTCP {
return
}

if v.Type() == conntrack.TypeNATForward {
return
}

data := v.Data()

if (v.IsForwardDSR() && data.FINsSeenDSR()) || data.FINsSeen() {
fmt.Printf(" CLOSED")
return
}

if data.Established() {
fmt.Printf(" ESTABLISHED")
return
}

fmt.Printf(" SYN-SENT")
}

func dumpExtra(k conntrack.Key, v conntrack.Value) {
now := bpf.KTimeNanos()

Expand Down Expand Up @@ -253,20 +328,78 @@ func runClean(c *cobra.Command, _ []string) {
}
}

type conntrackCreateCmd struct {
*cobra.Command

Version string `docopt:"<version>"`

version int
}

func newConntrackCreateCmd() *cobra.Command {
cmd := &conntrackCreateCmd{
Command: &cobra.Command{
Use: "create <version>",
Short: "create a conntrack map of specified version",
},
}

cmd.Command.Args = cmd.Args
cmd.Command.Run = cmd.Run

return cmd.Command
}

func (cmd *conntrackCreateCmd) Args(c *cobra.Command, args []string) error {
a, err := docopt.ParseArgs(makeDocUsage(c), args, "")
if err != nil {
return errors.New(err.Error())
}

err = a.Bind(cmd)
if err != nil {
return errors.New(err.Error())
}

switch cmd.Version {
case "2":
cmd.version = 2
default:
cmd.version = 3
}
return nil
}

func (cmd *conntrackCreateCmd) Run(c *cobra.Command, _ []string) {
var ctMap bpf.Map
mc := &bpf.MapContext{}
switch cmd.version {
case 2:
ctMap = conntrack.MapV2(mc)
default:
ctMap = conntrack.Map(mc)
}
if err := ctMap.EnsureExists(); err != nil {
log.WithError(err).Errorf("Failed to create conntrackMap version %d", cmd.version)
}
}

type conntrackWriteCmd struct {
*cobra.Command

Version string `docopt:"<version>"`
Key string `docopt:"<key>"`
Value string `docopt:"<value>"`

key []byte
val []byte
version int
}

func newConntrackWriteCmd() *cobra.Command {
cmd := &conntrackWriteCmd{
Command: &cobra.Command{
Use: "write <key> <value>",
Use: "write [<version>] <key> <value>",
Short: "write a key-value pair, each encoded in base64",
},
}
Expand All @@ -288,22 +421,52 @@ func (cmd *conntrackWriteCmd) Args(c *cobra.Command, args []string) error {
return errors.New(err.Error())
}

switch cmd.Version {
case "2":
cmd.version = 2
default:
cmd.version = 3
}

cmd.key, err = base64.StdEncoding.DecodeString(cmd.Key)
if err != nil || len(cmd.key) != len(conntrack.Key{}) {
return errors.Errorf("failed to decode key: %s", err)
if err != nil {
switch cmd.version {
case 2:
if len(cmd.key) != len(v2.Key{}) {
return errors.Errorf("failed to decode key: %s", err)
}
default:
if len(cmd.key) != len(conntrack.Key{}) {
return errors.Errorf("failed to decode key: %s", err)
}
}
}

cmd.val, err = base64.StdEncoding.DecodeString(cmd.Value)
if err != nil || len(cmd.val) != len(conntrack.Value{}) {
return errors.Errorf("failed to decode val: %s", err)
if err != nil {
switch cmd.version {
case 2:
if len(cmd.val) != len(v2.Value{}) {
return errors.Errorf("failed to decode val: %s", err)
}
default:
if len(cmd.val) != len(conntrack.Value{}) {
return errors.Errorf("failed to decode val: %s", err)
}
}
}

return nil
}

func (cmd *conntrackWriteCmd) Run(c *cobra.Command, _ []string) {
mc := &bpf.MapContext{}
ctMap := conntrack.Map(mc)
var ctMap bpf.Map
if cmd.version == 2 {
ctMap = conntrack.MapV2(mc)
} else {
ctMap = conntrack.Map(mc)
}

if err := ctMap.Open(); err != nil {
log.WithError(err).Error("Failed to access ConntrackMap")
}
Expand Down

0 comments on commit 66afd31

Please sign in to comment.