Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

filter: Add support for the csum action in u32 #718

Merged
merged 1 commit into from
Mar 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,39 @@ func NewConnmarkAction() *ConnmarkAction {
}
}

type CsumUpdateFlags uint32

const (
TCA_CSUM_UPDATE_FLAG_IPV4HDR CsumUpdateFlags = 1
TCA_CSUM_UPDATE_FLAG_ICMP CsumUpdateFlags = 2
TCA_CSUM_UPDATE_FLAG_IGMP CsumUpdateFlags = 4
TCA_CSUM_UPDATE_FLAG_TCP CsumUpdateFlags = 8
TCA_CSUM_UPDATE_FLAG_UDP CsumUpdateFlags = 16
TCA_CSUM_UPDATE_FLAG_UDPLITE CsumUpdateFlags = 32
TCA_CSUM_UPDATE_FLAG_SCTP CsumUpdateFlags = 64
)

type CsumAction struct {
ActionAttrs
UpdateFlags CsumUpdateFlags
}

func (action *CsumAction) Type() string {
return "csum"
}

func (action *CsumAction) Attrs() *ActionAttrs {
return &action.ActionAttrs
}

func NewCsumAction() *CsumAction {
return &CsumAction{
ActionAttrs: ActionAttrs{
Action: TC_ACT_PIPE,
},
}
}

type MirredAct uint8

func (a MirredAct) String() string {
Expand Down
20 changes: 20 additions & 0 deletions filter_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,16 @@ func EncodeActions(attr *nl.RtAttr, actions []Action) error {
}
toTcGen(action.Attrs(), &connmark.TcGen)
aopts.AddRtAttr(nl.TCA_CONNMARK_PARMS, connmark.Serialize())
case *CsumAction:
table := attr.AddRtAttr(tabIndex, nil)
tabIndex++
table.AddRtAttr(nl.TCA_ACT_KIND, nl.ZeroTerminated("csum"))
aopts := table.AddRtAttr(nl.TCA_ACT_OPTIONS, nil)
csum := nl.TcCsum{
UpdateFlags: uint32(action.UpdateFlags),
}
toTcGen(action.Attrs(), &csum.TcGen)
aopts.AddRtAttr(nl.TCA_CSUM_PARMS, csum.Serialize())
case *BpfAction:
table := attr.AddRtAttr(tabIndex, nil)
tabIndex++
Expand Down Expand Up @@ -675,6 +685,8 @@ func parseActions(tables []syscall.NetlinkRouteAttr) ([]Action, error) {
action = &BpfAction{}
case "connmark":
action = &ConnmarkAction{}
case "csum":
action = &CsumAction{}
case "gact":
action = &GenericAction{}
case "tunnel_key":
Expand Down Expand Up @@ -755,6 +767,14 @@ func parseActions(tables []syscall.NetlinkRouteAttr) ([]Action, error) {
toAttrs(&connmark.TcGen, action.Attrs())
action.(*ConnmarkAction).Zone = connmark.Zone
}
case "csum":
switch adatum.Attr.Type {
case nl.TCA_CSUM_PARMS:
csum := *nl.DeserializeTcCsum(adatum.Value)
action.(*CsumAction).ActionAttrs = ActionAttrs{}
toAttrs(&csum.TcGen, action.Attrs())
action.(*CsumAction).UpdateFlags = CsumUpdateFlags(csum.UpdateFlags)
}
case "gact":
switch adatum.Attr.Type {
case nl.TCA_GACT_PARMS:
Expand Down
129 changes: 129 additions & 0 deletions filter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -784,6 +784,135 @@ func TestFilterU32ConnmarkAddDel(t *testing.T) {
}
}

func TestFilterU32CsumAddDel(t *testing.T) {
tearDown := setUpNetlinkTest(t)
defer tearDown()
if err := LinkAdd(&Ifb{LinkAttrs{Name: "foo"}}); err != nil {
t.Fatalf("add link foo error: %v", err)
}
link, err := LinkByName("foo")
if err != nil {
t.Fatalf("add link foo error: %v", err)
}
if err := LinkSetUp(link); err != nil {
t.Fatalf("set foo link up error: %v", err)
}

qdisc := &Ingress{
QdiscAttrs: QdiscAttrs{
LinkIndex: link.Attrs().Index,
Handle: MakeHandle(0xffff, 0),
Parent: HANDLE_INGRESS,
},
}
if err := QdiscAdd(qdisc); err != nil {
t.Fatal(err)
}
qdiscs, err := SafeQdiscList(link)
if err != nil {
t.Fatalf("get qdisc error: %v", err)
}

found := false
for _, v := range qdiscs {
if _, ok := v.(*Ingress); ok {
found = true
break
}
}
if !found {
t.Fatal("Qdisc is the wrong type")
}

classId := MakeHandle(1, 1)
filter := &U32{
FilterAttrs: FilterAttrs{
LinkIndex: link.Attrs().Index,
Parent: MakeHandle(0xffff, 0),
Priority: 1,
Protocol: unix.ETH_P_ALL,
},
ClassId: classId,
Actions: []Action{
&CsumAction{
ActionAttrs: ActionAttrs{
Action: TC_ACT_PIPE,
},
UpdateFlags: TCA_CSUM_UPDATE_FLAG_TCP,
},
},
}

if err := FilterAdd(filter); err != nil {
t.Fatal(err)
}

filters, err := FilterList(link, MakeHandle(0xffff, 0))
if err != nil {
t.Fatalf("get filter error: %v", err)
}

if len(filters) != 1 {
t.Fatalf("the count filters error, expect: 1, acutal: %d", len(filters))
}

ft, ok := filters[0].(*U32)
if !ok {
t.Fatal("Filter is the wrong type")
}

if ft.LinkIndex != link.Attrs().Index {
t.Fatal("link index error")
}

if len(ft.Actions) != 1 {
t.Fatalf("filter has wrong number of actions, expect: 1, acutal: %d", len(filters))
}

csum, ok := ft.Actions[0].(*CsumAction)
if !ok {
t.Fatal("action is the wrong type")
}

if csum.Attrs().Action != TC_ACT_PIPE {
t.Fatal("Csum action isn't TC_ACT_PIPE")
}

if csum.UpdateFlags != TCA_CSUM_UPDATE_FLAG_TCP {
t.Fatalf("Csum action isn't TCA_CSUM_UPDATE_FLAG_TCP, got %d", csum.UpdateFlags)
}

if err := FilterDel(ft); err != nil {
t.Fatal(err)
}
filters, err = FilterList(link, MakeHandle(0xffff, 0))
if err != nil {
t.Fatal(err)
}
if len(filters) != 0 {
t.Fatal("Failed to remove filter")
}

if err := QdiscDel(qdisc); err != nil {
t.Fatal(err)
}
qdiscs, err = SafeQdiscList(link)
if err != nil {
t.Fatal(err)
}

found = false
for _, v := range qdiscs {
if _, ok := v.(*Ingress); ok {
found = true
break
}
}
if found {
t.Fatal("Failed to remove qdisc")
}
}

func setupLinkForTestWithQdisc(t *testing.T, linkName string) (Qdisc, Link) {
if err := LinkAdd(&Ifb{LinkAttrs{Name: linkName}}); err != nil {
t.Fatal(err)
Expand Down
31 changes: 31 additions & 0 deletions nl/tc_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ const (
SizeofTcU32Sel = 0x10 // without keys
SizeofTcGen = 0x14
SizeofTcConnmark = SizeofTcGen + 0x04
SizeofTcCsum = SizeofTcGen + 0x04
SizeofTcMirred = SizeofTcGen + 0x08
SizeofTcTunnelKey = SizeofTcGen + 0x04
SizeofTcSkbEdit = SizeofTcGen
Expand Down Expand Up @@ -694,6 +695,36 @@ func (x *TcConnmark) Serialize() []byte {
return (*(*[SizeofTcConnmark]byte)(unsafe.Pointer(x)))[:]
}

const (
TCA_CSUM_UNSPEC = iota
TCA_CSUM_PARMS
TCA_CSUM_TM
TCA_CSUM_PAD
TCA_CSUM_MAX = TCA_CSUM_PAD
)

// struct tc_csum {
// tc_gen;
// __u32 update_flags;
// }

type TcCsum struct {
TcGen
UpdateFlags uint32
}

func (msg *TcCsum) Len() int {
return SizeofTcCsum
}

func DeserializeTcCsum(b []byte) *TcCsum {
return (*TcCsum)(unsafe.Pointer(&b[0:SizeofTcCsum][0]))
}

func (x *TcCsum) Serialize() []byte {
return (*(*[SizeofTcCsum]byte)(unsafe.Pointer(x)))[:]
}

const (
TCA_ACT_MIRRED = 8
)
Expand Down