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/podman/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"
	"net"
	"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 U32 filters that contains multiple TcU32Key. This is the type
// alias and the frontend representation of nl.TcU32Sel. It is serialized into
// canonical nl.TcU32Sel with the appropriate endianness.
type TcU32Sel = nl.TcU32Sel

// TcU32Key contained of Sel in the U32 filters. This is the type alias and the
// frontend representation of nl.TcU32Key. It is serialized into chanonical
// nl.TcU32Sel with the appropriate endianness.
type TcU32Key = nl.TcU32Key

// U32 filters on many packet related properties
type U32 struct {
	FilterAttrs
	ClassId    uint32
	Divisor    uint32 // Divisor MUST be power of 2.
	Hash       uint32
	Link       uint32
	RedirIndex int
	Sel        *TcU32Sel
	Actions    []Action
}

func (filter *U32) Attrs() *FilterAttrs {
	return &filter.FilterAttrs
}

func (filter *U32) Type() string {
	return "u32"
}

type Flower struct {
	FilterAttrs
	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
}

func (filter *Flower) Attrs() *FilterAttrs {
	return &filter.FilterAttrs
}

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)
	}
	v4IP := ip.To4()
	if v4IP == ni
    
func EncodeActions(attr *nl.RtAttr, actions []Action) error {
	tabIndex := int(nl.TCA_ACT_TAB)

	for _, action := range actions {
		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++
			table.AddRtAttr(nl.TCA_ACT_KIND, nl.ZeroTerminated("mirred"))
			aopts := table.AddRtAttr(nl.TCA_ACT_OPTIONS, nil)
			mirred := nl.TcMirred{
				Eaction: int32(action.MirredAction),
				Ifindex: uint32(action.Ifindex),
			}
			toTcGen(action.Attrs(), &mirred.TcGen)
			aopts.AddRtAttr(nl.TCA_MIRRED_PARMS, mirred.Serialize())
		case *TunnelKeyAction:
			table := attr.AddRtAttr(tabIndex, nil)
			tabIndex++
			table.AddRtAttr(nl.TCA_ACT_KIND, nl.ZeroTerminated("tunnel_key"))
			aopts := table.AddRtAttr(nl.TCA_ACT_OPTIONS, nil)
			tun := nl.TcTunnelKey{
				Action: int32(action.Action),
			}
			toTcGen(action.Attrs(), &tun.TcGen)
			aopts.AddRtAttr(nl.TCA_TUNNEL_KEY_PARMS, tun.Serialize())
			if action.Action == TCA_TUNNEL_KEY_SET {
				aopts.AddRtAttr(nl.TCA_TUNNEL_KEY_ENC_KEY_ID, htonl(action.KeyID))
				if v4 := action.SrcAddr.To4(); v4 != nil {
					aopts.AddRtAttr(nl.TCA_TUNNEL_KEY_ENC_IPV4_SRC, v4[:])
				} else if v6 := action.SrcAddr.To16(); v6 != nil {
					aopts.AddRtAttr(nl.TCA_TUNNEL_KEY_ENC_IPV6_SRC, v6[:])
				} else {
					return fmt.Errorf("invalid src addr %s for tunnel_key action", action.SrcAddr)
				}
				if v4 := action.DstAddr.To4(); v4 != nil {
					aopts.AddRtAttr(nl.TCA_TUNNEL_KEY_ENC_IPV4_DST, v4[:])
				} else if v6 := action.DstAddr.To16(); v6 != nil {
					aopts.AddRtAttr(nl.TCA_TUNNEL_KEY_ENC_IPV6_DST, v6[:])
				} else {
					return fmt.Errorf("invalid dst addr %s for tunnel_key action", action.DstAddr)
				}
				if action.DestPort != 0 {
					aopts.AddRtAttr(nl.TCA_TUNNEL_KEY_ENC_DST_PORT, htons(action.DestPort))
				}
			}
		case *SkbEditAction:
			table := attr.AddRtAttr(tabIndex, nil)
			tabIndex++
			table.AddRtAttr(nl.TCA_ACT_KIND, nl.ZeroTerminated("skbedit"))
			aopts := table.AddRtAttr(nl.TCA_ACT_OPTIONS, nil)
			skbedit := nl.TcSkbEdit{}
			toTcGen(action.Attrs(), &skbedit.TcGen)
			aopts.AddRtAttr(nl.TCA_SKBEDIT_PARMS, skbedit.Serialize())
			if action.QueueMapping != nil {
				aopts.AddRtAttr(nl.TCA_SKBEDIT_QUEUE_MAPPING, nl.Uint16Attr(*action.QueueMapping))
			}
			if action.Priority != nil {
				aopts.AddRtAttr(nl.TCA_SKBEDIT_PRIORITY, nl.Uint32Attr(*action.Priority))
			}
			if action.PType != nil {
				aopts.AddRtAttr(nl.TCA_SKBEDIT_PTYPE, nl.Uint16Attr(*action.PType))
			}
			if action.Mark != nil {
				aopts.AddRtAttr(nl.TCA_SKBEDIT_MARK, nl.Uint32Attr(*action.Mark))
			}
		case *ConnmarkAction:
			table := attr.AddRtAttr(tabIndex, nil)
			tabIndex++
			table.AddRtAttr(nl.TCA_ACT_KIND, nl.ZeroTerminated("connmark"))
			aopts := table.AddRtAttr(nl.TCA_ACT_OPTIONS, nil)
			connmark := nl.TcConnmark{
				Zone: action.Zone,
			}
			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++
			table.AddRtAttr(nl.TCA_ACT_KIND, nl.ZeroTerminated("bpf"))
			aopts := table.AddRtAttr(nl.TCA_ACT_OPTIONS, nil)
			gen := nl.TcGen{}
			toTcGen(action.Attrs(), &gen)
			aopts.AddRtAttr(nl.TCA_ACT_BPF_PARMS, gen.Serialize())
			aopts.AddRtAttr(nl.TCA_ACT_BPF_FD, nl.Uint32Attr(uint32(action.Fd)))
			aopts.AddRtAttr(nl.TCA_ACT_BPF_NAME, nl.ZeroTerminated(action.Name))
		case *GenericAction:
			table := attr.AddRtAttr(tabIndex, nil)
			tabIndex++
			table.AddRtAttr(nl.TCA_ACT_KIND, nl.ZeroTerminated("gact"))
			aopts := table.AddRtAttr(nl.TCA_ACT_OPTIONS, nil)
			gen := nl.TcGen{}
			toTcGen(action.Attrs(), &gen)
			aopts.AddRtAttr(nl.TCA_GACT_PARMS, gen.Serialize())
		}
	}
	return nil
}