mirror of
https://github.com/vishvananda/netlink.git
synced 2025-10-04 07:26:26 +08:00
filter: Add support for the csum action in u32
This patch adds support for the U32 action that can force a csum recalculation in different layers of a packet.
This commit is contained in:

committed by
Alessandro Boch

parent
6bb6f8abbc
commit
5cb84e47ad
33
filter.go
33
filter.go
@@ -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
|
type MirredAct uint8
|
||||||
|
|
||||||
func (a MirredAct) String() string {
|
func (a MirredAct) String() string {
|
||||||
|
@@ -607,6 +607,16 @@ func EncodeActions(attr *nl.RtAttr, actions []Action) error {
|
|||||||
}
|
}
|
||||||
toTcGen(action.Attrs(), &connmark.TcGen)
|
toTcGen(action.Attrs(), &connmark.TcGen)
|
||||||
aopts.AddRtAttr(nl.TCA_CONNMARK_PARMS, connmark.Serialize())
|
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:
|
case *BpfAction:
|
||||||
table := attr.AddRtAttr(tabIndex, nil)
|
table := attr.AddRtAttr(tabIndex, nil)
|
||||||
tabIndex++
|
tabIndex++
|
||||||
@@ -675,6 +685,8 @@ func parseActions(tables []syscall.NetlinkRouteAttr) ([]Action, error) {
|
|||||||
action = &BpfAction{}
|
action = &BpfAction{}
|
||||||
case "connmark":
|
case "connmark":
|
||||||
action = &ConnmarkAction{}
|
action = &ConnmarkAction{}
|
||||||
|
case "csum":
|
||||||
|
action = &CsumAction{}
|
||||||
case "gact":
|
case "gact":
|
||||||
action = &GenericAction{}
|
action = &GenericAction{}
|
||||||
case "tunnel_key":
|
case "tunnel_key":
|
||||||
@@ -755,6 +767,14 @@ func parseActions(tables []syscall.NetlinkRouteAttr) ([]Action, error) {
|
|||||||
toAttrs(&connmark.TcGen, action.Attrs())
|
toAttrs(&connmark.TcGen, action.Attrs())
|
||||||
action.(*ConnmarkAction).Zone = connmark.Zone
|
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":
|
case "gact":
|
||||||
switch adatum.Attr.Type {
|
switch adatum.Attr.Type {
|
||||||
case nl.TCA_GACT_PARMS:
|
case nl.TCA_GACT_PARMS:
|
||||||
|
129
filter_test.go
129
filter_test.go
@@ -785,6 +785,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) {
|
func setupLinkForTestWithQdisc(t *testing.T, linkName string) (Qdisc, Link) {
|
||||||
if err := LinkAdd(&Ifb{LinkAttrs{Name: linkName}}); err != nil {
|
if err := LinkAdd(&Ifb{LinkAttrs{Name: linkName}}); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
@@ -90,6 +90,7 @@ const (
|
|||||||
SizeofTcU32Sel = 0x10 // without keys
|
SizeofTcU32Sel = 0x10 // without keys
|
||||||
SizeofTcGen = 0x14
|
SizeofTcGen = 0x14
|
||||||
SizeofTcConnmark = SizeofTcGen + 0x04
|
SizeofTcConnmark = SizeofTcGen + 0x04
|
||||||
|
SizeofTcCsum = SizeofTcGen + 0x04
|
||||||
SizeofTcMirred = SizeofTcGen + 0x08
|
SizeofTcMirred = SizeofTcGen + 0x08
|
||||||
SizeofTcTunnelKey = SizeofTcGen + 0x04
|
SizeofTcTunnelKey = SizeofTcGen + 0x04
|
||||||
SizeofTcSkbEdit = SizeofTcGen
|
SizeofTcSkbEdit = SizeofTcGen
|
||||||
@@ -694,6 +695,36 @@ func (x *TcConnmark) Serialize() []byte {
|
|||||||
return (*(*[SizeofTcConnmark]byte)(unsafe.Pointer(x)))[:]
|
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 (
|
const (
|
||||||
TCA_ACT_MIRRED = 8
|
TCA_ACT_MIRRED = 8
|
||||||
)
|
)
|
||||||
|
Reference in New Issue
Block a user