mirror of
https://github.com/vishvananda/netlink
synced 2025-01-13 18:45:05 +00:00
add tc flower pedit action
add pedit action in tc flower to support installing netlink hardware offload rules authored-by: tangchen <tangchen.1@bytedance.com>
This commit is contained in:
parent
d649c02e2b
commit
004274e828
27
filter.go
27
filter.go
@ -418,3 +418,30 @@ func (filter *GenericFilter) Attrs() *FilterAttrs {
|
||||
func (filter *GenericFilter) Type() string {
|
||||
return filter.FilterType
|
||||
}
|
||||
|
||||
type PeditAction struct {
|
||||
ActionAttrs
|
||||
Proto uint8
|
||||
SrcMacAddr net.HardwareAddr
|
||||
DstMacAddr net.HardwareAddr
|
||||
SrcIP net.IP
|
||||
DstIP net.IP
|
||||
SrcPort uint16
|
||||
DstPort uint16
|
||||
}
|
||||
|
||||
func (p *PeditAction) Attrs() *ActionAttrs {
|
||||
return &p.ActionAttrs
|
||||
}
|
||||
|
||||
func (p *PeditAction) Type() string {
|
||||
return "pedit"
|
||||
}
|
||||
|
||||
func NewPeditAction() *PeditAction {
|
||||
return &PeditAction{
|
||||
ActionAttrs: ActionAttrs{
|
||||
Action: TC_ACT_PIPE,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -692,6 +692,29 @@ func EncodeActions(attr *nl.RtAttr, actions []Action) error {
|
||||
gen := nl.TcGen{}
|
||||
toTcGen(action.Attrs(), &gen)
|
||||
aopts.AddRtAttr(nl.TCA_GACT_PARMS, gen.Serialize())
|
||||
case *PeditAction:
|
||||
table := attr.AddRtAttr(tabIndex, nil)
|
||||
tabIndex++
|
||||
pedit := nl.TcPedit{}
|
||||
if action.SrcMacAddr != nil {
|
||||
pedit.SetEthSrc(action.SrcMacAddr)
|
||||
}
|
||||
if action.DstMacAddr != nil {
|
||||
pedit.SetEthDst(action.DstMacAddr)
|
||||
}
|
||||
if action.SrcIP != nil {
|
||||
pedit.SetSrcIP(action.SrcIP)
|
||||
}
|
||||
if action.DstIP != nil {
|
||||
pedit.SetDstIP(action.DstIP)
|
||||
}
|
||||
if action.SrcPort != 0 {
|
||||
pedit.SetSrcPort(action.SrcPort, action.Proto)
|
||||
}
|
||||
if action.DstPort != 0 {
|
||||
pedit.SetDstPort(action.DstPort, action.Proto)
|
||||
}
|
||||
pedit.Encode(table)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@ -752,6 +775,8 @@ func parseActions(tables []syscall.NetlinkRouteAttr) ([]Action, error) {
|
||||
action = &SkbEditAction{}
|
||||
case "police":
|
||||
action = &PoliceAction{}
|
||||
case "pedit":
|
||||
action = &PeditAction{}
|
||||
default:
|
||||
break nextattr
|
||||
}
|
||||
|
160
filter_test.go
160
filter_test.go
@ -1921,6 +1921,166 @@ func TestFilterFlowerAddDel(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterIPv6FlowerPedit(t *testing.T) {
|
||||
tearDown := setUpNetlinkTest(t)
|
||||
defer tearDown()
|
||||
if err := LinkAdd(&Ifb{LinkAttrs{Name: "foo"}}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := LinkAdd(&Ifb{LinkAttrs{Name: "bar"}}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
link, err := LinkByName("foo")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := LinkSetUp(link); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
redir, err := LinkByName("bar")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := LinkSetUp(redir); err != nil {
|
||||
t.Fatal(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.Fatal(err)
|
||||
}
|
||||
|
||||
found := false
|
||||
for _, v := range qdiscs {
|
||||
if _, ok := v.(*Ingress); ok {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
t.Fatal("Qdisc is the wrong type")
|
||||
}
|
||||
|
||||
testMask := net.CIDRMask(64, 128)
|
||||
|
||||
ipproto := new(nl.IPProto)
|
||||
*ipproto = nl.IPPROTO_TCP
|
||||
|
||||
filter := &Flower{
|
||||
FilterAttrs: FilterAttrs{
|
||||
LinkIndex: link.Attrs().Index,
|
||||
Parent: MakeHandle(0xffff, 0),
|
||||
Priority: 1,
|
||||
Protocol: unix.ETH_P_ALL,
|
||||
},
|
||||
DestIP: net.ParseIP("ffff::fff1"),
|
||||
DestIPMask: testMask,
|
||||
EthType: unix.ETH_P_IPV6,
|
||||
IPProto: ipproto,
|
||||
DestPort: 6666,
|
||||
Actions: []Action{},
|
||||
}
|
||||
|
||||
peditAction := NewPeditAction()
|
||||
peditAction.Proto = uint8(nl.IPPROTO_TCP)
|
||||
peditAction.SrcPort = 7777
|
||||
peditAction.SrcIP = net.ParseIP("ffff::fff2")
|
||||
filter.Actions = append(filter.Actions, peditAction)
|
||||
|
||||
miaAction := &MirredAction{
|
||||
ActionAttrs: ActionAttrs{
|
||||
Action: TC_ACT_REDIRECT,
|
||||
},
|
||||
MirredAction: TCA_EGRESS_REDIR,
|
||||
Ifindex: redir.Attrs().Index,
|
||||
}
|
||||
filter.Actions = append(filter.Actions, miaAction)
|
||||
|
||||
if err := FilterAdd(filter); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
filters, err := FilterList(link, MakeHandle(0xffff, 0))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(filters) != 1 {
|
||||
t.Fatal("Failed to add filter")
|
||||
}
|
||||
flower, ok := filters[0].(*Flower)
|
||||
if !ok {
|
||||
t.Fatal("Filter is the wrong type")
|
||||
}
|
||||
|
||||
if filter.EthType != flower.EthType {
|
||||
t.Fatalf("Flower EthType doesn't match")
|
||||
}
|
||||
if !filter.DestIP.Equal(flower.DestIP) {
|
||||
t.Fatalf("Flower DestIP doesn't match")
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(filter.DestIPMask, testMask) {
|
||||
t.Fatalf("Flower DestIPMask doesn't match")
|
||||
}
|
||||
|
||||
if flower.IPProto == nil || *filter.IPProto != *flower.IPProto {
|
||||
t.Fatalf("Flower IPProto doesn't match")
|
||||
}
|
||||
if filter.DestPort != flower.DestPort {
|
||||
t.Fatalf("Flower DestPort doesn't match")
|
||||
}
|
||||
|
||||
_, ok = flower.Actions[0].(*PeditAction)
|
||||
if !ok {
|
||||
t.Fatal("Unable to find pedit action")
|
||||
}
|
||||
|
||||
_, ok = flower.Actions[1].(*MirredAction)
|
||||
if !ok {
|
||||
t.Fatal("Unable to find mirred action")
|
||||
}
|
||||
|
||||
if err := FilterDel(filter); 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 TestFilterU32PoliceAddDel(t *testing.T) {
|
||||
tearDown := setUpNetlinkTest(t)
|
||||
defer tearDown()
|
||||
|
393
nl/tc_linux.go
393
nl/tc_linux.go
@ -1,8 +1,10 @@
|
||||
package nl
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"net"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
@ -1175,3 +1177,394 @@ func (i IPProto) String() string {
|
||||
}
|
||||
return fmt.Sprintf("%d", i)
|
||||
}
|
||||
|
||||
const (
|
||||
MaxOffs = 128
|
||||
SizeOfPeditSel = 24
|
||||
SizeOfPeditKey = 24
|
||||
|
||||
TCA_PEDIT_KEY_EX_HTYPE = 1
|
||||
TCA_PEDIT_KEY_EX_CMD = 2
|
||||
)
|
||||
|
||||
const (
|
||||
TCA_PEDIT_UNSPEC = iota
|
||||
TCA_PEDIT_TM
|
||||
TCA_PEDIT_PARMS
|
||||
TCA_PEDIT_PAD
|
||||
TCA_PEDIT_PARMS_EX
|
||||
TCA_PEDIT_KEYS_EX
|
||||
TCA_PEDIT_KEY_EX
|
||||
)
|
||||
|
||||
// /* TCA_PEDIT_KEY_EX_HDR_TYPE_NETWROK is a special case for legacy users. It
|
||||
// * means no specific header type - offset is relative to the network layer
|
||||
// */
|
||||
type PeditHeaderType uint16
|
||||
|
||||
const (
|
||||
TCA_PEDIT_KEY_EX_HDR_TYPE_NETWORK = iota
|
||||
TCA_PEDIT_KEY_EX_HDR_TYPE_ETH
|
||||
TCA_PEDIT_KEY_EX_HDR_TYPE_IP4
|
||||
TCA_PEDIT_KEY_EX_HDR_TYPE_IP6
|
||||
TCA_PEDIT_KEY_EX_HDR_TYPE_TCP
|
||||
TCA_PEDIT_KEY_EX_HDR_TYPE_UDP
|
||||
__PEDIT_HDR_TYPE_MAX
|
||||
)
|
||||
|
||||
type PeditCmd uint16
|
||||
|
||||
const (
|
||||
TCA_PEDIT_KEY_EX_CMD_SET = 0
|
||||
TCA_PEDIT_KEY_EX_CMD_ADD = 1
|
||||
)
|
||||
|
||||
type TcPeditSel struct {
|
||||
TcGen
|
||||
NKeys uint8
|
||||
Flags uint8
|
||||
}
|
||||
|
||||
func DeserializeTcPeditKey(b []byte) *TcPeditKey {
|
||||
return (*TcPeditKey)(unsafe.Pointer(&b[0:SizeOfPeditKey][0]))
|
||||
}
|
||||
|
||||
func DeserializeTcPedit(b []byte) (*TcPeditSel, []TcPeditKey) {
|
||||
x := &TcPeditSel{}
|
||||
copy((*(*[SizeOfPeditSel]byte)(unsafe.Pointer(x)))[:SizeOfPeditSel], b)
|
||||
|
||||
var keys []TcPeditKey
|
||||
|
||||
next := SizeOfPeditKey
|
||||
var i uint8
|
||||
for i = 0; i < x.NKeys; i++ {
|
||||
keys = append(keys, *DeserializeTcPeditKey(b[next:]))
|
||||
next += SizeOfPeditKey
|
||||
}
|
||||
|
||||
return x, keys
|
||||
}
|
||||
|
||||
type TcPeditKey struct {
|
||||
Mask uint32
|
||||
Val uint32
|
||||
Off uint32
|
||||
At uint32
|
||||
OffMask uint32
|
||||
Shift uint32
|
||||
}
|
||||
|
||||
type TcPeditKeyEx struct {
|
||||
HeaderType PeditHeaderType
|
||||
Cmd PeditCmd
|
||||
}
|
||||
|
||||
type TcPedit struct {
|
||||
Sel TcPeditSel
|
||||
Keys []TcPeditKey
|
||||
KeysEx []TcPeditKeyEx
|
||||
Extend uint8
|
||||
}
|
||||
|
||||
func (p *TcPedit) Encode(parent *RtAttr) {
|
||||
parent.AddRtAttr(TCA_ACT_KIND, ZeroTerminated("pedit"))
|
||||
actOpts := parent.AddRtAttr(TCA_ACT_OPTIONS, nil)
|
||||
|
||||
bbuf := bytes.NewBuffer(make([]byte, 0, int(unsafe.Sizeof(p.Sel)+unsafe.Sizeof(p.Keys))))
|
||||
|
||||
bbuf.Write((*(*[SizeOfPeditSel]byte)(unsafe.Pointer(&p.Sel)))[:])
|
||||
|
||||
for i := uint8(0); i < p.Sel.NKeys; i++ {
|
||||
bbuf.Write((*(*[SizeOfPeditKey]byte)(unsafe.Pointer(&p.Keys[i])))[:])
|
||||
}
|
||||
actOpts.AddRtAttr(TCA_PEDIT_PARMS_EX, bbuf.Bytes())
|
||||
|
||||
exAttrs := actOpts.AddRtAttr(int(TCA_PEDIT_KEYS_EX|NLA_F_NESTED), nil)
|
||||
for i := uint8(0); i < p.Sel.NKeys; i++ {
|
||||
keyAttr := exAttrs.AddRtAttr(int(TCA_PEDIT_KEY_EX|NLA_F_NESTED), nil)
|
||||
|
||||
htypeBuf := make([]byte, 2)
|
||||
cmdBuf := make([]byte, 2)
|
||||
|
||||
NativeEndian().PutUint16(htypeBuf, uint16(p.KeysEx[i].HeaderType))
|
||||
NativeEndian().PutUint16(cmdBuf, uint16(p.KeysEx[i].Cmd))
|
||||
|
||||
keyAttr.AddRtAttr(TCA_PEDIT_KEY_EX_HTYPE, htypeBuf)
|
||||
keyAttr.AddRtAttr(TCA_PEDIT_KEY_EX_CMD, cmdBuf)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *TcPedit) SetEthDst(mac net.HardwareAddr) {
|
||||
u32 := NativeEndian().Uint32(mac)
|
||||
u16 := NativeEndian().Uint16(mac[4:])
|
||||
|
||||
tKey := TcPeditKey{}
|
||||
tKeyEx := TcPeditKeyEx{}
|
||||
|
||||
tKey.Val = u32
|
||||
|
||||
tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_ETH
|
||||
tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
|
||||
|
||||
p.Keys = append(p.Keys, tKey)
|
||||
p.KeysEx = append(p.KeysEx, tKeyEx)
|
||||
p.Sel.NKeys++
|
||||
|
||||
tKey = TcPeditKey{}
|
||||
tKeyEx = TcPeditKeyEx{}
|
||||
|
||||
tKey.Val = uint32(u16)
|
||||
tKey.Mask = 0xffff0000
|
||||
tKey.Off = 4
|
||||
tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_ETH
|
||||
tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
|
||||
|
||||
p.Keys = append(p.Keys, tKey)
|
||||
p.KeysEx = append(p.KeysEx, tKeyEx)
|
||||
|
||||
p.Sel.NKeys++
|
||||
}
|
||||
|
||||
func (p *TcPedit) SetEthSrc(mac net.HardwareAddr) {
|
||||
u16 := NativeEndian().Uint16(mac)
|
||||
u32 := NativeEndian().Uint32(mac[2:])
|
||||
|
||||
tKey := TcPeditKey{}
|
||||
tKeyEx := TcPeditKeyEx{}
|
||||
|
||||
tKey.Val = uint32(u16) << 16
|
||||
tKey.Mask = 0x0000ffff
|
||||
tKey.Off = 4
|
||||
|
||||
tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_ETH
|
||||
tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
|
||||
|
||||
p.Keys = append(p.Keys, tKey)
|
||||
p.KeysEx = append(p.KeysEx, tKeyEx)
|
||||
p.Sel.NKeys++
|
||||
|
||||
tKey = TcPeditKey{}
|
||||
tKeyEx = TcPeditKeyEx{}
|
||||
|
||||
tKey.Val = u32
|
||||
tKey.Mask = 0
|
||||
tKey.Off = 8
|
||||
|
||||
tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_ETH
|
||||
tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
|
||||
|
||||
p.Keys = append(p.Keys, tKey)
|
||||
p.KeysEx = append(p.KeysEx, tKeyEx)
|
||||
|
||||
p.Sel.NKeys++
|
||||
}
|
||||
|
||||
func (p *TcPedit) SetIPv6Src(ip6 net.IP) {
|
||||
u32 := NativeEndian().Uint32(ip6[:4])
|
||||
|
||||
tKey := TcPeditKey{}
|
||||
tKeyEx := TcPeditKeyEx{}
|
||||
|
||||
tKey.Val = u32
|
||||
tKey.Off = 8
|
||||
tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_IP6
|
||||
tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
|
||||
|
||||
p.Keys = append(p.Keys, tKey)
|
||||
p.KeysEx = append(p.KeysEx, tKeyEx)
|
||||
p.Sel.NKeys++
|
||||
|
||||
u32 = NativeEndian().Uint32(ip6[4:8])
|
||||
tKey = TcPeditKey{}
|
||||
tKeyEx = TcPeditKeyEx{}
|
||||
|
||||
tKey.Val = u32
|
||||
tKey.Off = 12
|
||||
tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_IP6
|
||||
tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
|
||||
|
||||
p.Keys = append(p.Keys, tKey)
|
||||
p.KeysEx = append(p.KeysEx, tKeyEx)
|
||||
|
||||
p.Sel.NKeys++
|
||||
|
||||
u32 = NativeEndian().Uint32(ip6[8:12])
|
||||
tKey = TcPeditKey{}
|
||||
tKeyEx = TcPeditKeyEx{}
|
||||
|
||||
tKey.Val = u32
|
||||
tKey.Off = 16
|
||||
tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_IP6
|
||||
tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
|
||||
|
||||
p.Keys = append(p.Keys, tKey)
|
||||
p.KeysEx = append(p.KeysEx, tKeyEx)
|
||||
|
||||
p.Sel.NKeys++
|
||||
|
||||
u32 = NativeEndian().Uint32(ip6[12:16])
|
||||
tKey = TcPeditKey{}
|
||||
tKeyEx = TcPeditKeyEx{}
|
||||
|
||||
tKey.Val = u32
|
||||
tKey.Off = 20
|
||||
tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_IP6
|
||||
tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
|
||||
|
||||
p.Keys = append(p.Keys, tKey)
|
||||
p.KeysEx = append(p.KeysEx, tKeyEx)
|
||||
|
||||
p.Sel.NKeys++
|
||||
}
|
||||
|
||||
func (p *TcPedit) SetDstIP(ip net.IP) {
|
||||
if ip.To4() != nil {
|
||||
p.SetIPv4Dst(ip)
|
||||
} else {
|
||||
p.SetIPv6Dst(ip)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *TcPedit) SetSrcIP(ip net.IP) {
|
||||
if ip.To4() != nil {
|
||||
p.SetIPv4Src(ip)
|
||||
} else {
|
||||
p.SetIPv6Src(ip)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *TcPedit) SetIPv6Dst(ip6 net.IP) {
|
||||
u32 := NativeEndian().Uint32(ip6[:4])
|
||||
|
||||
tKey := TcPeditKey{}
|
||||
tKeyEx := TcPeditKeyEx{}
|
||||
|
||||
tKey.Val = u32
|
||||
tKey.Off = 24
|
||||
tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_IP6
|
||||
tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
|
||||
|
||||
p.Keys = append(p.Keys, tKey)
|
||||
p.KeysEx = append(p.KeysEx, tKeyEx)
|
||||
p.Sel.NKeys++
|
||||
|
||||
u32 = NativeEndian().Uint32(ip6[4:8])
|
||||
tKey = TcPeditKey{}
|
||||
tKeyEx = TcPeditKeyEx{}
|
||||
|
||||
tKey.Val = u32
|
||||
tKey.Off = 28
|
||||
tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_IP6
|
||||
tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
|
||||
|
||||
p.Keys = append(p.Keys, tKey)
|
||||
p.KeysEx = append(p.KeysEx, tKeyEx)
|
||||
|
||||
p.Sel.NKeys++
|
||||
|
||||
u32 = NativeEndian().Uint32(ip6[8:12])
|
||||
tKey = TcPeditKey{}
|
||||
tKeyEx = TcPeditKeyEx{}
|
||||
|
||||
tKey.Val = u32
|
||||
tKey.Off = 32
|
||||
tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_IP6
|
||||
tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
|
||||
|
||||
p.Keys = append(p.Keys, tKey)
|
||||
p.KeysEx = append(p.KeysEx, tKeyEx)
|
||||
|
||||
p.Sel.NKeys++
|
||||
|
||||
u32 = NativeEndian().Uint32(ip6[12:16])
|
||||
tKey = TcPeditKey{}
|
||||
tKeyEx = TcPeditKeyEx{}
|
||||
|
||||
tKey.Val = u32
|
||||
tKey.Off = 36
|
||||
tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_IP6
|
||||
tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
|
||||
|
||||
p.Keys = append(p.Keys, tKey)
|
||||
p.KeysEx = append(p.KeysEx, tKeyEx)
|
||||
|
||||
p.Sel.NKeys++
|
||||
}
|
||||
|
||||
func (p *TcPedit) SetIPv4Src(ip net.IP) {
|
||||
u32 := NativeEndian().Uint32(ip[:4])
|
||||
|
||||
tKey := TcPeditKey{}
|
||||
tKeyEx := TcPeditKeyEx{}
|
||||
|
||||
tKey.Val = u32
|
||||
tKey.Off = 12
|
||||
tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_IP4
|
||||
tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
|
||||
|
||||
p.Keys = append(p.Keys, tKey)
|
||||
p.KeysEx = append(p.KeysEx, tKeyEx)
|
||||
p.Sel.NKeys++
|
||||
}
|
||||
|
||||
func (p *TcPedit) SetIPv4Dst(ip net.IP) {
|
||||
u32 := NativeEndian().Uint32(ip[:4])
|
||||
|
||||
tKey := TcPeditKey{}
|
||||
tKeyEx := TcPeditKeyEx{}
|
||||
|
||||
tKey.Val = u32
|
||||
tKey.Off = 16
|
||||
tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_IP4
|
||||
tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
|
||||
|
||||
p.Keys = append(p.Keys, tKey)
|
||||
p.KeysEx = append(p.KeysEx, tKeyEx)
|
||||
p.Sel.NKeys++
|
||||
}
|
||||
|
||||
// SetDstPort only tcp and udp are supported to set port
|
||||
func (p *TcPedit) SetDstPort(dstPort uint16, protocol uint8) {
|
||||
tKey := TcPeditKey{}
|
||||
tKeyEx := TcPeditKeyEx{}
|
||||
|
||||
switch protocol {
|
||||
case unix.IPPROTO_TCP:
|
||||
tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_TCP
|
||||
case unix.IPPROTO_UDP:
|
||||
tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_UDP
|
||||
default:
|
||||
return
|
||||
}
|
||||
|
||||
tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
|
||||
|
||||
tKey.Val = uint32(Swap16(dstPort)) << 16
|
||||
tKey.Mask = 0x0000ffff
|
||||
p.Keys = append(p.Keys, tKey)
|
||||
p.KeysEx = append(p.KeysEx, tKeyEx)
|
||||
p.Sel.NKeys++
|
||||
}
|
||||
|
||||
// SetSrcPort only tcp and udp are supported to set port
|
||||
func (p *TcPedit) SetSrcPort(srcPort uint16, protocol uint8) {
|
||||
tKey := TcPeditKey{}
|
||||
tKeyEx := TcPeditKeyEx{}
|
||||
|
||||
switch protocol {
|
||||
case unix.IPPROTO_TCP:
|
||||
tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_TCP
|
||||
case unix.IPPROTO_UDP:
|
||||
tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_UDP
|
||||
default:
|
||||
return
|
||||
}
|
||||
|
||||
tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
|
||||
|
||||
tKey.Val = uint32(Swap16(srcPort))
|
||||
tKey.Mask = 0xffff0000
|
||||
p.Keys = append(p.Keys, tKey)
|
||||
p.KeysEx = append(p.KeysEx, tKeyEx)
|
||||
p.Sel.NKeys++
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user