summaryrefslogtreecommitdiff
path: root/vendor/github.com/vishvananda/netlink/filter_linux.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/vishvananda/netlink/filter_linux.go')
-rw-r--r--vendor/github.com/vishvananda/netlink/filter_linux.go306
1 files changed, 220 insertions, 86 deletions
diff --git a/vendor/github.com/vishvananda/netlink/filter_linux.go b/vendor/github.com/vishvananda/netlink/filter_linux.go
index 2cd46266c..3cfea4586 100644
--- a/vendor/github.com/vishvananda/netlink/filter_linux.go
+++ b/vendor/github.com/vishvananda/netlink/filter_linux.go
@@ -6,6 +6,7 @@ import (
"encoding/hex"
"errors"
"fmt"
+ "net"
"syscall"
"github.com/vishvananda/netlink/nl"
@@ -50,74 +51,129 @@ func (filter *U32) Type() string {
return "u32"
}
-// Fw filter filters on firewall marks
-// NOTE: this is in filter_linux because it refers to nl.TcPolice which
-// is defined in nl/tc_linux.go
-type Fw struct {
+type Flower struct {
FilterAttrs
- ClassId uint32
- // TODO remove nl type from interface
- Police nl.TcPolice
- InDev string
- // TODO Action
- Mask uint32
- AvRate uint32
- Rtab [256]uint32
- Ptab [256]uint32
-}
-
-func NewFw(attrs FilterAttrs, fattrs FilterFwAttrs) (*Fw, error) {
- var rtab [256]uint32
- var ptab [256]uint32
- rcellLog := -1
- pcellLog := -1
- avrate := fattrs.AvRate / 8
- police := nl.TcPolice{}
- police.Rate.Rate = fattrs.Rate / 8
- police.PeakRate.Rate = fattrs.PeakRate / 8
- buffer := fattrs.Buffer
- linklayer := nl.LINKLAYER_ETHERNET
+ DestIP net.IP
+ DestIPMask net.IPMask
+ SrcIP net.IP
+ SrcIPMask net.IPMask
+ EthType uint16
+ EncDestIP net.IP
+ EncDestIPMask net.IPMask
+ EncSrcIP net.IP
+ EncSrcIPMask net.IPMask
+ EncDestPort uint16
+ EncKeyId uint32
+
+ Actions []Action
+}
- if fattrs.LinkLayer != nl.LINKLAYER_UNSPEC {
- linklayer = fattrs.LinkLayer
- }
+func (filter *Flower) Attrs() *FilterAttrs {
+ return &filter.FilterAttrs
+}
- police.Action = int32(fattrs.Action)
- if police.Rate.Rate != 0 {
- police.Rate.Mpu = fattrs.Mpu
- police.Rate.Overhead = fattrs.Overhead
- if CalcRtable(&police.Rate, rtab[:], rcellLog, fattrs.Mtu, linklayer) < 0 {
- return nil, errors.New("TBF: failed to calculate rate table")
- }
- police.Burst = Xmittime(uint64(police.Rate.Rate), uint32(buffer))
+func (filter *Flower) Type() string {
+ return "flower"
+}
+
+func (filter *Flower) encodeIP(parent *nl.RtAttr, ip net.IP, mask net.IPMask, v4Type, v6Type int, v4MaskType, v6MaskType int) {
+ ipType := v4Type
+ maskType := v4MaskType
+
+ encodeMask := mask
+ if mask == nil {
+ encodeMask = net.CIDRMask(32, 32)
}
- police.Mtu = fattrs.Mtu
- if police.PeakRate.Rate != 0 {
- police.PeakRate.Mpu = fattrs.Mpu
- police.PeakRate.Overhead = fattrs.Overhead
- if CalcRtable(&police.PeakRate, ptab[:], pcellLog, fattrs.Mtu, linklayer) < 0 {
- return nil, errors.New("POLICE: failed to calculate peak rate table")
- }
+ v4IP := ip.To4()
+ if v4IP == nil {
+ ipType = v6Type
+ maskType = v6MaskType
+ if mask == nil {
+ encodeMask = net.CIDRMask(128, 128)
+ }
+ } else {
+ ip = v4IP
}
- return &Fw{
- FilterAttrs: attrs,
- ClassId: fattrs.ClassId,
- InDev: fattrs.InDev,
- Mask: fattrs.Mask,
- Police: police,
- AvRate: avrate,
- Rtab: rtab,
- Ptab: ptab,
- }, nil
+ parent.AddRtAttr(ipType, ip)
+ parent.AddRtAttr(maskType, encodeMask)
}
-func (filter *Fw) Attrs() *FilterAttrs {
- return &filter.FilterAttrs
+func (filter *Flower) encode(parent *nl.RtAttr) error {
+ if filter.EthType != 0 {
+ parent.AddRtAttr(nl.TCA_FLOWER_KEY_ETH_TYPE, htons(filter.EthType))
+ }
+ if filter.SrcIP != nil {
+ filter.encodeIP(parent, filter.SrcIP, filter.SrcIPMask,
+ nl.TCA_FLOWER_KEY_IPV4_SRC, nl.TCA_FLOWER_KEY_IPV6_SRC,
+ nl.TCA_FLOWER_KEY_IPV4_SRC_MASK, nl.TCA_FLOWER_KEY_IPV6_SRC_MASK)
+ }
+ if filter.DestIP != nil {
+ filter.encodeIP(parent, filter.DestIP, filter.DestIPMask,
+ nl.TCA_FLOWER_KEY_IPV4_DST, nl.TCA_FLOWER_KEY_IPV6_DST,
+ nl.TCA_FLOWER_KEY_IPV4_DST_MASK, nl.TCA_FLOWER_KEY_IPV6_DST_MASK)
+ }
+ if filter.EncSrcIP != nil {
+ filter.encodeIP(parent, filter.EncSrcIP, filter.EncSrcIPMask,
+ nl.TCA_FLOWER_KEY_ENC_IPV4_SRC, nl.TCA_FLOWER_KEY_ENC_IPV6_SRC,
+ nl.TCA_FLOWER_KEY_ENC_IPV4_SRC_MASK, nl.TCA_FLOWER_KEY_ENC_IPV6_SRC_MASK)
+ }
+ if filter.EncDestIP != nil {
+ filter.encodeIP(parent, filter.EncDestIP, filter.EncSrcIPMask,
+ nl.TCA_FLOWER_KEY_ENC_IPV4_DST, nl.TCA_FLOWER_KEY_ENC_IPV6_DST,
+ nl.TCA_FLOWER_KEY_ENC_IPV4_DST_MASK, nl.TCA_FLOWER_KEY_ENC_IPV6_DST_MASK)
+ }
+ if filter.EncDestPort != 0 {
+ parent.AddRtAttr(nl.TCA_FLOWER_KEY_ENC_UDP_DST_PORT, htons(filter.EncDestPort))
+ }
+ if filter.EncKeyId != 0 {
+ parent.AddRtAttr(nl.TCA_FLOWER_KEY_ENC_KEY_ID, htonl(filter.EncKeyId))
+ }
+
+ actionsAttr := parent.AddRtAttr(nl.TCA_FLOWER_ACT, nil)
+ if err := EncodeActions(actionsAttr, filter.Actions); err != nil {
+ return err
+ }
+ return nil
}
-func (filter *Fw) Type() string {
- return "fw"
+func (filter *Flower) decode(data []syscall.NetlinkRouteAttr) error {
+ for _, datum := range data {
+ switch datum.Attr.Type {
+ case nl.TCA_FLOWER_KEY_ETH_TYPE:
+ filter.EthType = ntohs(datum.Value)
+ case nl.TCA_FLOWER_KEY_IPV4_SRC, nl.TCA_FLOWER_KEY_IPV6_SRC:
+ filter.SrcIP = datum.Value
+ case nl.TCA_FLOWER_KEY_IPV4_SRC_MASK, nl.TCA_FLOWER_KEY_IPV6_SRC_MASK:
+ filter.SrcIPMask = datum.Value
+ case nl.TCA_FLOWER_KEY_IPV4_DST, nl.TCA_FLOWER_KEY_IPV6_DST:
+ filter.DestIP = datum.Value
+ case nl.TCA_FLOWER_KEY_IPV4_DST_MASK, nl.TCA_FLOWER_KEY_IPV6_DST_MASK:
+ filter.DestIPMask = datum.Value
+ case nl.TCA_FLOWER_KEY_ENC_IPV4_SRC, nl.TCA_FLOWER_KEY_ENC_IPV6_SRC:
+ filter.EncSrcIP = datum.Value
+ case nl.TCA_FLOWER_KEY_ENC_IPV4_SRC_MASK, nl.TCA_FLOWER_KEY_ENC_IPV6_SRC_MASK:
+ filter.EncSrcIPMask = datum.Value
+ case nl.TCA_FLOWER_KEY_ENC_IPV4_DST, nl.TCA_FLOWER_KEY_ENC_IPV6_DST:
+ filter.EncDestIP = datum.Value
+ case nl.TCA_FLOWER_KEY_ENC_IPV4_DST_MASK, nl.TCA_FLOWER_KEY_ENC_IPV6_DST_MASK:
+ filter.EncDestIPMask = datum.Value
+ case nl.TCA_FLOWER_KEY_ENC_UDP_DST_PORT:
+ filter.EncDestPort = ntohs(datum.Value)
+ case nl.TCA_FLOWER_KEY_ENC_KEY_ID:
+ filter.EncKeyId = ntohl(datum.Value)
+ case nl.TCA_FLOWER_ACT:
+ tables, err := nl.ParseRouteAttr(datum.Value)
+ if err != nil {
+ return err
+ }
+ filter.Actions, err = parseActions(tables)
+ if err != nil {
+ return err
+ }
+ }
+ }
+ return nil
}
// FilterDel will delete a filter from the system.
@@ -169,7 +225,6 @@ func (h *Handle) FilterReplace(filter Filter) error {
}
func (h *Handle) filterModify(filter Filter, flags int) error {
- native = nl.NativeEndian()
req := h.newNetlinkRequest(unix.RTM_NEWTFILTER, flags|unix.NLM_F_ACK)
base := filter.Attrs()
msg := &nl.TcMsg{
@@ -237,7 +292,7 @@ func (h *Handle) filterModify(filter Filter, flags int) error {
if err := EncodeActions(actionsAttr, filter.Actions); err != nil {
return err
}
- case *Fw:
+ case *FwFilter:
if filter.Mask != 0 {
b := make([]byte, 4)
native.PutUint32(b, filter.Mask)
@@ -246,17 +301,10 @@ func (h *Handle) filterModify(filter Filter, flags int) error {
if filter.InDev != "" {
options.AddRtAttr(nl.TCA_FW_INDEV, nl.ZeroTerminated(filter.InDev))
}
- if (filter.Police != nl.TcPolice{}) {
-
+ if filter.Police != nil {
police := options.AddRtAttr(nl.TCA_FW_POLICE, nil)
- police.AddRtAttr(nl.TCA_POLICE_TBF, filter.Police.Serialize())
- if (filter.Police.Rate != nl.TcRateSpec{}) {
- payload := SerializeRtab(filter.Rtab)
- police.AddRtAttr(nl.TCA_POLICE_RATE, payload)
- }
- if (filter.Police.PeakRate != nl.TcRateSpec{}) {
- payload := SerializeRtab(filter.Ptab)
- police.AddRtAttr(nl.TCA_POLICE_PEAKRATE, payload)
+ if err := encodePolice(police, filter.Police); err != nil {
+ return err
}
}
if filter.ClassId != 0 {
@@ -287,6 +335,10 @@ func (h *Handle) filterModify(filter Filter, flags int) error {
if filter.ClassId != 0 {
options.AddRtAttr(nl.TCA_MATCHALL_CLASSID, nl.Uint32Attr(filter.ClassId))
}
+ case *Flower:
+ if err := filter.encode(options); err != nil {
+ return err
+ }
}
req.AddData(options)
@@ -350,11 +402,13 @@ func (h *Handle) FilterList(link Link, parent uint32) ([]Filter, error) {
case "u32":
filter = &U32{}
case "fw":
- filter = &Fw{}
+ filter = &FwFilter{}
case "bpf":
filter = &BpfFilter{}
case "matchall":
filter = &MatchAll{}
+ case "flower":
+ filter = &Flower{}
default:
filter = &GenericFilter{FilterType: filterType}
}
@@ -384,6 +438,11 @@ func (h *Handle) FilterList(link Link, parent uint32) ([]Filter, error) {
if err != nil {
return nil, err
}
+ case "flower":
+ detailed, err = parseFlowerData(filter, data)
+ if err != nil {
+ return nil, err
+ }
default:
detailed = true
}
@@ -415,6 +474,53 @@ func toAttrs(tcgen *nl.TcGen, attrs *ActionAttrs) {
attrs.Bindcnt = int(tcgen.Bindcnt)
}
+func encodePolice(attr *nl.RtAttr, action *PoliceAction) error {
+ var rtab [256]uint32
+ var ptab [256]uint32
+ police := nl.TcPolice{}
+ police.Index = uint32(action.Attrs().Index)
+ police.Bindcnt = int32(action.Attrs().Bindcnt)
+ police.Capab = uint32(action.Attrs().Capab)
+ police.Refcnt = int32(action.Attrs().Refcnt)
+ police.Rate.Rate = action.Rate
+ police.PeakRate.Rate = action.PeakRate
+ police.Action = int32(action.ExceedAction)
+
+ if police.Rate.Rate != 0 {
+ police.Rate.Mpu = action.Mpu
+ police.Rate.Overhead = action.Overhead
+ if CalcRtable(&police.Rate, rtab[:], action.RCellLog, action.Mtu, action.LinkLayer) < 0 {
+ return errors.New("TBF: failed to calculate rate table")
+ }
+ police.Burst = Xmittime(uint64(police.Rate.Rate), action.Burst)
+ }
+
+ police.Mtu = action.Mtu
+ if police.PeakRate.Rate != 0 {
+ police.PeakRate.Mpu = action.Mpu
+ police.PeakRate.Overhead = action.Overhead
+ if CalcRtable(&police.PeakRate, ptab[:], action.PCellLog, action.Mtu, action.LinkLayer) < 0 {
+ return errors.New("POLICE: failed to calculate peak rate table")
+ }
+ }
+
+ attr.AddRtAttr(nl.TCA_POLICE_TBF, police.Serialize())
+ if police.Rate.Rate != 0 {
+ attr.AddRtAttr(nl.TCA_POLICE_RATE, SerializeRtab(rtab))
+ }
+ if police.PeakRate.Rate != 0 {
+ attr.AddRtAttr(nl.TCA_POLICE_PEAKRATE, SerializeRtab(ptab))
+ }
+ if action.AvRate != 0 {
+ attr.AddRtAttr(nl.TCA_POLICE_AVRATE, nl.Uint32Attr(action.AvRate))
+ }
+ if action.NotExceedAction != 0 {
+ attr.AddRtAttr(nl.TCA_POLICE_RESULT, nl.Uint32Attr(uint32(action.NotExceedAction)))
+ }
+
+ return nil
+}
+
func EncodeActions(attr *nl.RtAttr, actions []Action) error {
tabIndex := int(nl.TCA_ACT_TAB)
@@ -422,6 +528,14 @@ func EncodeActions(attr *nl.RtAttr, actions []Action) error {
switch action := action.(type) {
default:
return fmt.Errorf("unknown action type %s", action.Type())
+ case *PoliceAction:
+ table := attr.AddRtAttr(tabIndex, nil)
+ tabIndex++
+ table.AddRtAttr(nl.TCA_ACT_KIND, nl.ZeroTerminated("police"))
+ aopts := table.AddRtAttr(nl.TCA_ACT_OPTIONS, nil)
+ if err := encodePolice(aopts, action); err != nil {
+ return err
+ }
case *MirredAction:
table := attr.AddRtAttr(tabIndex, nil)
tabIndex++
@@ -516,6 +630,29 @@ func EncodeActions(attr *nl.RtAttr, actions []Action) error {
return nil
}
+func parsePolice(data syscall.NetlinkRouteAttr, police *PoliceAction) {
+ switch data.Attr.Type {
+ case nl.TCA_POLICE_RESULT:
+ police.NotExceedAction = TcPolAct(native.Uint32(data.Value[0:4]))
+ case nl.TCA_POLICE_AVRATE:
+ police.AvRate = native.Uint32(data.Value[0:4])
+ case nl.TCA_POLICE_TBF:
+ p := *nl.DeserializeTcPolice(data.Value)
+ police.ActionAttrs = ActionAttrs{}
+ police.Attrs().Index = int(p.Index)
+ police.Attrs().Bindcnt = int(p.Bindcnt)
+ police.Attrs().Capab = int(p.Capab)
+ police.Attrs().Refcnt = int(p.Refcnt)
+ police.ExceedAction = TcPolAct(p.Action)
+ police.Rate = p.Rate.Rate
+ police.PeakRate = p.PeakRate.Rate
+ police.Burst = Xmitsize(uint64(p.Rate.Rate), p.Burst)
+ police.Mtu = p.Mtu
+ police.LinkLayer = int(p.Rate.Linklayer) & nl.TC_LINKLAYER_MASK
+ police.Overhead = p.Rate.Overhead
+ }
+}
+
func parseActions(tables []syscall.NetlinkRouteAttr) ([]Action, error) {
var actions []Action
for _, table := range tables {
@@ -544,6 +681,8 @@ func parseActions(tables []syscall.NetlinkRouteAttr) ([]Action, error) {
action = &TunnelKeyAction{}
case "skbedit":
action = &SkbEditAction{}
+ case "police":
+ action = &PoliceAction{}
default:
break nextattr
}
@@ -622,6 +761,8 @@ func parseActions(tables []syscall.NetlinkRouteAttr) ([]Action, error) {
gen := *nl.DeserializeTcGen(adatum.Value)
toAttrs(&gen, action.Attrs())
}
+ case "police":
+ parsePolice(adatum, action.(*PoliceAction))
}
}
}
@@ -632,7 +773,6 @@ func parseActions(tables []syscall.NetlinkRouteAttr) ([]Action, error) {
}
func parseU32Data(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error) {
- native = nl.NativeEndian()
u32 := filter.(*U32)
detailed := false
for _, datum := range data {
@@ -678,8 +818,7 @@ func parseU32Data(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error)
}
func parseFwData(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error) {
- native = nl.NativeEndian()
- fw := filter.(*Fw)
+ fw := filter.(*FwFilter)
detailed := true
for _, datum := range data {
switch datum.Attr.Type {
@@ -690,24 +829,18 @@ func parseFwData(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error) {
case nl.TCA_FW_INDEV:
fw.InDev = string(datum.Value[:len(datum.Value)-1])
case nl.TCA_FW_POLICE:
+ var police PoliceAction
adata, _ := nl.ParseRouteAttr(datum.Value)
for _, aattr := range adata {
- switch aattr.Attr.Type {
- case nl.TCA_POLICE_TBF:
- fw.Police = *nl.DeserializeTcPolice(aattr.Value)
- case nl.TCA_POLICE_RATE:
- fw.Rtab = DeserializeRtab(aattr.Value)
- case nl.TCA_POLICE_PEAKRATE:
- fw.Ptab = DeserializeRtab(aattr.Value)
- }
+ parsePolice(aattr, &police)
}
+ fw.Police = &police
}
}
return detailed, nil
}
func parseBpfData(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error) {
- native = nl.NativeEndian()
bpf := filter.(*BpfFilter)
detailed := true
for _, datum := range data {
@@ -733,7 +866,6 @@ func parseBpfData(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error)
}
func parseMatchAllData(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error) {
- native = nl.NativeEndian()
matchall := filter.(*MatchAll)
detailed := true
for _, datum := range data {
@@ -754,6 +886,10 @@ func parseMatchAllData(filter Filter, data []syscall.NetlinkRouteAttr) (bool, er
return detailed, nil
}
+func parseFlowerData(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error) {
+ return true, filter.(*Flower).decode(data)
+}
+
func AlignToAtm(size uint) uint {
var linksize, cells int
cells = int(size / nl.ATM_CELL_PAYLOAD)
@@ -801,14 +937,12 @@ func CalcRtable(rate *nl.TcRateSpec, rtab []uint32, cellLog int, mtu uint32, lin
func DeserializeRtab(b []byte) [256]uint32 {
var rtab [256]uint32
- native := nl.NativeEndian()
r := bytes.NewReader(b)
_ = binary.Read(r, native, &rtab)
return rtab
}
func SerializeRtab(rtab [256]uint32) []byte {
- native := nl.NativeEndian()
var w bytes.Buffer
_ = binary.Write(&w, native, rtab)
return w.Bytes()