You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: filter_linux.go
    path of file: ./repos/fabio/vendor/github.com/vishvananda/netlink
    
    the code of the file until where you have to start completion: package netlink

import (
	"bytes"
	"encoding/binary"
	"encoding/hex"
	"errors"
	"fmt"
	"syscall"

	"github.com/vishvananda/netlink/nl"
	"golang.org/x/sys/unix"
)

// Constants used in TcU32Sel.Flags.
const (
	TC_U32_TERMINAL  = nl.TC_U32_TERMINAL
	TC_U32_OFFSET    = nl.TC_U32_OFFSET
	TC_U32_VAROFFSET = nl.TC_U32_VAROFFSET
	TC_U32_EAT       = nl.TC_U32_EAT
)

// Sel of the U3
    
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{
		Family:  nl.FAMILY_ALL,
		Ifindex: int32(base.LinkIndex),
		Handle:  base.Handle,
		Parent:  base.Parent,
		Info:    MakeHandle(base.Priority, nl.Swap16(base.Protocol)),
	}
	req.AddData(msg)
	req.AddData(nl.NewRtAttr(nl.TCA_KIND, nl.ZeroTerminated(filter.Type())))

	options := nl.NewRtAttr(nl.TCA_OPTIONS, nil)

	switch filter := filter.(type) {
	case *U32:
		sel := filter.Sel
		if sel == nil {
			// match all
			sel = &nl.TcU32Sel{
				Nkeys: 1,
				Flags: nl.TC_U32_TERMINAL,
			}
			sel.Keys = append(sel.Keys, nl.TcU32Key{})
		}

		if native != networkOrder {
			// Copy TcU32Sel.
			cSel := *sel
			keys := make([]nl.TcU32Key, cap(sel.Keys))
			copy(keys, sel.Keys)
			cSel.Keys = keys
			sel = &cSel

			// Handle the endianness of attributes
			sel.Offmask = native.Uint16(htons(sel.Offmask))
			sel.Hmask = native.Uint32(htonl(sel.Hmask))
			for i, key := range sel.Keys {
				sel.Keys[i].Mask = native.Uint32(htonl(key.Mask))
				sel.Keys[i].Val = native.Uint32(htonl(key.Val))
			}
		}
		sel.Nkeys = uint8(len(sel.Keys))
		options.AddRtAttr(nl.TCA_U32_SEL, sel.Serialize())
		if filter.ClassId != 0 {
			options.AddRtAttr(nl.TCA_U32_CLASSID, nl.Uint32Attr(filter.ClassId))
		}
		if filter.Divisor != 0 {
			if (filter.Divisor-1)&filter.Divisor != 0 {
				return fmt.Errorf("illegal divisor %d. Must be a power of 2", filter.Divisor)
			}
			options.AddRtAttr(nl.TCA_U32_DIVISOR, nl.Uint32Attr(filter.Divisor))
		}
		if filter.Hash != 0 {
			options.AddRtAttr(nl.TCA_U32_HASH, nl.Uint32Attr(filter.Hash))
		}
		if filter.Link != 0 {
			options.AddRtAttr(nl.TCA_U32_LINK, nl.Uint32Attr(filter.Link))
		}
		actionsAttr := options.AddRtAttr(nl.TCA_U32_ACT, nil)
		// backwards compatibility
		if filter.RedirIndex != 0 {
			filter.Actions = append([]Action{NewMirredAction(filter.RedirIndex)}, filter.Actions...)
		}
		if err := EncodeActions(actionsAttr, filter.Actions); err != nil {
			return err
		}
	case *Fw:
		if filter.Mask != 0 {
			b := make([]byte, 4)
			native.PutUint32(b, filter.Mask)
			options.AddRtAttr(nl.TCA_FW_MASK, b)
		}
		if filter.InDev != "" {
			options.AddRtAttr(nl.TCA_FW_INDEV, nl.ZeroTerminated(filter.InDev))
		}
		if (filter.Police != nl.TcPolice{}) {

			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 filter.ClassId != 0 {
			b := make([]byte, 4)
			native.PutUint32(b, filter.ClassId)
			options.AddRtAttr(nl.TCA_FW_CLASSID, b)
		}
	case *BpfFilter:
		var bpfFlags uint32
		if filter.ClassId != 0 {
			options.AddRtAttr(nl.TCA_BPF_CLASSID, nl.Uint32Attr(filter.ClassId))
		}
		if filter.Fd >= 0 {
			options.AddRtAttr(nl.TCA_BPF_FD, nl.Uint32Attr((uint32(filter.Fd))))
		}
		if filter.Name != "" {
			options.AddRtAttr(nl.TCA_BPF_NAME, nl.ZeroTerminated(filter.Name))
		}
		if filter.DirectAction {
			bpfFlags |= nl.TCA_BPF_FLAG_ACT_DIRECT
		}
		options.AddRtAttr(nl.TCA_BPF_FLAGS, nl.Uint32Attr(bpfFlags))
	case *MatchAll:
		actionsAttr := options.AddRtAttr(nl.TCA_MATCHALL_ACT, nil)
		if err := EncodeActions(actionsAttr, filter.Actions); err != nil {
			return err
		}
		if filter.ClassId != 0 {
			options.AddRtAttr(nl.TCA_MATCHALL_CLASSID, nl.Uint32Attr(filter.ClassId))
		}
	}

	req.AddData(options)
	_, err := req.Execute(unix.NETLINK_ROUTE, 0)
	return err
}