Documentation
¶
Overview ¶
Package etherconn is a golang pkg that allow user to send/receive Ethernet payload (like IP pkt) or UDP packet ,with custom Ethernet encapsulation like MAC address, VLAN tags, without creating corresponding interface in OS;
For example, with etherconn, a program could send/recive a UDP or IP packet with a source MAC address and VLAN tags don't exists/provisioned in any of OS interfaces;
Another benefit is since etherconn bypasses "normal" OS kernel routing and IP stack, in scale setup like tens of thousands conns no longer subject to linux kernel limitation like # of socket/fd limitations, UDP buffer size...etc;
Lastly etherconn.RUDPConn implements the net.PacketConn interface, so it could be easily integrated into existing code;
Usage:
interface <---> PacketRelay <----> EtherConn <---> RUDPConn <----> EtherConn <---> RUDPConn <----> EtherConn <---> RUDPConn
1. Create a PacketRelay instance and bound to an interface.PacketRelay is the "forward engine" that does actual packet sending/receiving for all EtherConn instances registered with it; PacketRelay send/receive Ethernet packet; PacketRelay is a GO interface, currently there are two implementations:
- RawSocketRelay: uses AF_PACKET socket, linux only
- XDPRelay: uses xdp socket, linux only
- RawSocketRelayPcap: uses libpcap, windows and linux
2. Create one EtherConn for each source MAC+VLAN(s)+EtherType(s) combination needed, and register with the PacketRelay instance. EtherConn send/receive Ethernet payload like IP packet;
3. Create one RUDPConn instance for each UDP endpoint (IP+Port) needed, with a EtherConn. RUDPConn send/receive UDP payload.
4. RUDPConn and EtherConn is 1:1 mapping, while EtherConn and PacketRelay is N:1 mapping; since EtherConn and RUDPConn is 1:1 mapping, which means EtherConn will forward all received UDP pkts to RUDPConn even when its IP/UDP port is different from RUDPConn's endpoint, and RUDPConn could either only accept correct pkt or accept any UDP packet;
Egress direction:
UDP_payload -> RUDPConn(add UDP&IP header) -> EtherConn(add Ethernet header) -> PacketRelay
Ingress direction:
Ethernet_pkt -> (BPFilter) PacketRelay (parse pkt) --- EtherPayload(e.g IP_pkt) --> EtherConn Ethernet_pkt -> (BPFilter) PacketRelay (parse pkt) --- UDP_payload --> RUDPConn (option to accept any UDP pkt)
Note: PacketRelay parse pkt for Ethernet payload based on following rules: * PacketRelay has default BPFilter set to only allow IPv4/ARP/IPv6 packet * If Ethernet pkt doesn't have VLAN tag, dstMAC + EtherType in Ethernet header is used to locate registered EtherConn * else, dstMAC + VLANs + EtherType in last VLAN tag is used
Limitations:
- linux only
- since etherconn bypassed linux IP stack, it is user's job to provide functions like:
- routing next-hop lookup
- IP -> MAC address resolution
- no IP packet fragementation/reassembly support
- using of etherconn requires root privileges
Example:
// This is an example of using RUDPConn, a DHCPv4 client // it also uses "github.com/insomniacslk/dhcp/dhcpv4/nclient4" for dhcpv4 client part // create PacketRelay for interface "enp0s10" relay, err := etherconn.NewRawSocketRelay(context.Background(), "enp0s10") if err != nil { log.Fatalf("failed to create PacketRelay,%v", err) } defer relay.Stop() mac, _ := net.ParseMAC("aa:bb:cc:11:22:33") vlanLlist := []*etherconn.VLAN{ ðerconn.VLAN{ ID: 100, EtherType: 0x8100, }, } // create EtherConn, with src mac "aa:bb:cc:11:22:33" , VLAN 100 and DefaultEtherTypes, // with DOT1Q EtherType 0x8100, the mac/vlan doesn't need to be provisioned in OS econn := etherconn.NewEtherConn(mac, relay, etherconn.WithVLANs(vlanLlist)) // create RUDPConn to use 0.0.0.0 and UDP port 68 as source, with option to accept any UDP packet // since DHCP server will send reply to assigned IP address rudpconn, err := etherconn.NewRUDPConn("0.0.0.0:68", econn, etherconn.WithAcceptAny(true)) if err != nil { log.Fatalf("failed to create RUDPConn,%v", err) } // create DHCPv4 client with the RUDPConn clnt, err := nclient4.NewWithConn(rudpconn, mac, nclient4.WithDebugLogger()) if err != nil { log.Fatalf("failed to create dhcpv4 client for %v", err) } // do DORA _, _, err = clnt.Request(context.Background()) if err != nil { log.Fatalf("failed to finish DORA,%v", err) }
XDPRelay uses Linux AF_XDP socket as the underlying forwarding mechinism, so it achives higher performance than RawSocketRelay in multi-core setup, XDPRelay usage notes:
- for virtio interface, the number of queues provisioned needs to be 2x of number CPU cores VM has, binding will fail otherwise.
- AF_XDP is still relative new, see XDP kernel&driver support status: https://github.com/iovisor/bcc/blob/master/docs/kernel-versions.md#xdp
- For best performance: a) use NIC multiple queues and multiple routine(with runtime.LockOSThread()) to drive the traffic b) the number of routines >= number of NIC queues
Index ¶
- Constants
- Variables
- func GetIFQueueNum(ifname string) (int, error)
- func GetIfNameViaDesc(desc string) (string, error)
- func ResolveNexhopMACWithBrodcast(ip net.IP) net.HardwareAddr
- func SetIfVLANOffloading(ifname string, enable bool) error
- func SetPromisc(ifname string) error
- type AncillaryVLAN
- type ChanMap
- func (cm *ChanMap) CloseAll()
- func (cm *ChanMap) Del(k interface{})
- func (cm *ChanMap) DelList(ks []interface{})
- func (cm *ChanMap) Get(k interface{}) chan *RelayReceival
- func (cm *ChanMap) GetList() []chan *RelayReceival
- func (cm *ChanMap) Set(k interface{}, v chan *RelayReceival)
- func (cm *ChanMap) SetList(ks []interface{}, v chan *RelayReceival)
- type EtherConn
- func (ec *EtherConn) Close() error
- func (ec *EtherConn) GetEtherTypes() []uint16
- func (ec *EtherConn) LocalAddr() *L2Endpoint
- func (ec *EtherConn) ReadPkt() ([]byte, *L2Endpoint, error)
- func (ec *EtherConn) ReadPktFrom(p []byte) (int, *L2Endpoint, error)
- func (ec *EtherConn) SetDeadline(t time.Time) error
- func (ec *EtherConn) SetReadDeadline(t time.Time) error
- func (ec *EtherConn) SetWriteDeadline(t time.Time) error
- func (ec *EtherConn) WriteIPPktTo(p []byte, dstmac net.HardwareAddr) (int, error)
- func (ec *EtherConn) WriteIPPktToFrom(p []byte, srcmac, dstmac net.HardwareAddr, vlans VLANs) (int, error)
- func (ec *EtherConn) WritePktTo(p []byte, etype uint16, dstmac net.HardwareAddr) (int, error)
- func (ec *EtherConn) WritePktToFrom(p []byte, etype uint16, srcmac, dstmac net.HardwareAddr, vlans VLANs) (int, error)
- type EtherConnOption
- type L2Endpoint
- type L2EndpointKey
- type L4RecvKey
- type LogFunc
- type PacketRelay
- type PcapConn
- type RUDPConn
- func (ruc *RUDPConn) Close() error
- func (ruc *RUDPConn) LocalAddr() net.Addr
- func (ruc *RUDPConn) ReadFrom(p []byte) (int, net.Addr, error)
- func (ruc *RUDPConn) SetAddr(src *net.UDPAddr)
- func (ruc *RUDPConn) SetDeadline(t time.Time) error
- func (ruc *RUDPConn) SetReadDeadline(t time.Time) error
- func (ruc *RUDPConn) SetWriteDeadline(t time.Time) error
- func (ruc *RUDPConn) WriteTo(p []byte, addr net.Addr) (int, error)
- func (ruc *RUDPConn) WriteToFrom(p []byte, srcaddr, dstaddr net.Addr) (int, error)
- type RUDPConnOption
- type RawSocketRelay
- func (rsr *RawSocketRelay) Deregister(ks []L2EndpointKey)
- func (rsr *RawSocketRelay) GetStats() *RelayPacketStats
- func (rsr *RawSocketRelay) IfName() string
- func (rsr *RawSocketRelay) Register(ks []L2EndpointKey, recvMulticast bool) (chan *RelayReceival, chan []byte, chan struct{})
- func (rsr *RawSocketRelay) RegisterDefault() (chan *RelayReceival, chan []byte, chan struct{})
- func (rsr *RawSocketRelay) Stop()
- func (rsr *RawSocketRelay) Type() RelayType
- type RelayOption
- func WithBPFFilter(filter string) RelayOption
- func WithDebug(debug bool) RelayOption
- func WithDefaultReceival(mirroring bool) RelayOption
- func WithMaxEtherFrameSize(size uint) RelayOption
- func WithMultiEngine(count uint) RelayOption
- func WithPerClntChanRecvDepth(depth uint) RelayOption
- func WithRecvTimeout(t time.Duration) RelayOption
- func WithSendChanDepth(depth uint) RelayOption
- type RelayPacketStats
- type RelayReceival
- type RelayType
- type SharedEconn
- type SharedEtherConn
- func (sec *SharedEtherConn) Close()
- func (sec *SharedEtherConn) Register(k L4RecvKey) (torecvch chan *RelayReceival)
- func (sec *SharedEtherConn) RegisterList(keys []L4RecvKey) (torecvch chan *RelayReceival)
- func (sec *SharedEtherConn) SetWriteDeadline(t time.Time) error
- func (sec *SharedEtherConn) WriteIPPktTo(p []byte, dstmac net.HardwareAddr) (int, error)
- func (sec *SharedEtherConn) WriteIPPktToFrom(p []byte, srcmac, dstmac net.HardwareAddr, vlans VLANs) (int, error)
- func (sec *SharedEtherConn) WritePktTo(p []byte, etype uint16, dstmac net.HardwareAddr) (int, error)
- func (sec *SharedEtherConn) WritePktToFrom(p []byte, etype uint16, srcmac, dstmac net.HardwareAddr, vlans VLANs) (int, error)
- type SharedEtherConnOption
- type SharingRUDPConn
- func (sruc *SharingRUDPConn) Close() error
- func (sruc *SharingRUDPConn) LocalAddr() net.Addr
- func (sruc *SharingRUDPConn) ReadFrom(p []byte) (int, net.Addr, error)
- func (sruc *SharingRUDPConn) SetDeadline(t time.Time) error
- func (sruc *SharingRUDPConn) SetReadDeadline(t time.Time) error
- func (sruc *SharingRUDPConn) SetWriteDeadline(t time.Time) error
- func (sruc *SharingRUDPConn) WriteTo(p []byte, addr net.Addr) (int, error)
- type SharingRUDPConnOptions
- type VLAN
- type VLANs
- func (vlans VLANs) Clone() VLANs
- func (vlans *VLANs) Copy(vlans2 VLANs)
- func (vlans VLANs) Equal(vlans2 VLANs) bool
- func (vlans VLANs) IDs() []uint16
- func (vlans VLANs) MarshalBinary() (data []byte, err error)
- func (vlans VLANs) MarshalText() (text []byte, err error)
- func (vlans VLANs) SetIDs(ids []uint16) error
- func (vlans VLANs) String() string
- func (vlans *VLANs) UnmarshalBinary(data []byte) error
- func (vlans *VLANs) UnmarshalText(text []byte) error
- type XDPRelay
- func (xr *XDPRelay) Deregister(ks []L2EndpointKey)
- func (xr *XDPRelay) GetStats() *RelayPacketStats
- func (xr *XDPRelay) IfName() string
- func (xr *XDPRelay) NumSocket() int
- func (xr *XDPRelay) Register(ks []L2EndpointKey, recvMulticast bool) (chan *RelayReceival, chan []byte, chan struct{})
- func (xr *XDPRelay) RegisterDefault() (chan *RelayReceival, chan []byte, chan struct{})
- func (xr *XDPRelay) Stop()
- func (xr *XDPRelay) Type() RelayType
- type XDPRelayOption
- func WithQueueID(qidlist []int) XDPRelayOption
- func WithSendingMode(m XDPSendingMode) XDPRelayOption
- func WithXDPDebug(debug bool) XDPRelayOption
- func WithXDPDefaultReceival(mirroring bool) XDPRelayOption
- func WithXDPEtherTypes(ets []uint16) XDPRelayOption
- func WithXDPExtProg(fname, prog, qmap, xskmap, etypemap string) XDPRelayOption
- func WithXDPPerClntRecvChanDepth(depth uint) XDPRelayOption
- func WithXDPSendChanDepth(depth uint) XDPRelayOption
- func WithXDPUMEMChunkSize(fsize uint) XDPRelayOption
- func WithXDPUMEMNumOfTrunk(num uint) XDPRelayOption
- type XDPSendingMode
- type XDPSocketPktHandler
- type XdpSockStats
- type XdpSockStatsList
Constants ¶
const ( // DefaultSendChanDepth is the default value for PacketRelay send channel depth, e.g. send buffer DefaultSendChanDepth = 1024 // DefaultPerClntRecvChanDepth is the defaul value for per registered client(EtherConn)'s receive channel depth. e.g. recv buffer DefaultPerClntRecvChanDepth = 1024 // DefaultMaxEtherFrameSize is the deafult max size of Ethernet frame that PacketRelay could receive from the interface DefaultMaxEtherFrameSize = 2048 // DefaultRelayRecvTimeout is the default value for PacketReceive receiving timeout DefaultRelayRecvTimeout = time.Second DefaultTTL = 255 )
const ( // MaxNumVLAN specifies max number vlan this pkg supports MaxNumVLAN = 2 // L2EndpointKeySize is the size of L2EndpointKey in bytes L2EndpointKeySize = 6 + 2*MaxNumVLAN + 2 //must be 6+2*n )
const DefaultVLANEtype = 0x8100
DefaultVLANEtype is the default Ethernet type for vlan tags, used by function GetVLANs()
const (
//DefaultXDPChunkSize is the default size for XDP UMEM chunk
DefaultXDPChunkSize = 4096
)
const (
// DefaultXDPUMEMNumOfTrunk is the default number of UMEM trunks
DefaultXDPUMEMNumOfTrunk = 16384
)
const (
// NOVLANTAG is the value to represents NO vlan tag in L2EndpointKey
NOVLANTAG = 0xffff
)
Variables ¶
var ( // ErrTimeOut is the error returned when opeartion timeout ErrTimeOut = fmt.Errorf("timeout") // ErrRelayStopped is the error returned when relay already stopped ErrRelayStopped = fmt.Errorf("relay stopped") // BroadCastMAC is the broadcast MAC address BroadCastMAC = net.HardwareAddr{0xff, 0xff, 0xff, 0xff, 0xff, 0xff} )
var DefaultEtherTypes = []uint16{ uint16(layers.EthernetTypeARP), uint16(layers.EthernetTypeIPv4), uint16(layers.EthernetTypeIPv6)}
DefaultEtherTypes is the default list of Ethernet types for RawPacketRelay and EtherConn
Functions ¶
func GetIFQueueNum ¶ added in v0.4.0
GetIFQueueNum use ethtool to get number of combined queue of the interface, return 1 if failed to get the info
func GetIfNameViaDesc ¶ added in v0.6.0
GetIfNameViaDesc returns interface name via its description, this could be used on windows to get the interface name
func ResolveNexhopMACWithBrodcast ¶
func ResolveNexhopMACWithBrodcast(ip net.IP) net.HardwareAddr
ResolveNexhopMACWithBrodcast is the default resolve function that always return broadcast mac
func SetIfVLANOffloading ¶ added in v0.4.1
SetIfVLANOffloading set the HW VLAN offloading feature on/off for the interface, turning the feautre off is needed when using XDPRelay and can't get expected vlan tags in received packet.
func SetPromisc ¶ added in v0.6.0
SetPromisc put the interface in Promisc mode
Types ¶
type AncillaryVLAN ¶ added in v0.6.0
type AncillaryVLAN struct { // The VLAN VID provided by the kernel. VLAN int }
type ChanMap ¶ added in v0.4.3
type ChanMap struct {
// contains filtered or unexported fields
}
ChanMap is an GO routine safe map, key is interfce{}, val is a chan *RelayReceival;
func NewChanMap ¶ added in v0.4.3
func NewChanMap() *ChanMap
NewChanMap creates a new instance of ChanMap
func (*ChanMap) CloseAll ¶ added in v0.4.3
func (cm *ChanMap) CloseAll()
CloseAll close all channel in cm
func (*ChanMap) Del ¶ added in v0.4.3
func (cm *ChanMap) Del(k interface{})
Del delete entry with key as k
func (*ChanMap) DelList ¶ added in v0.4.3
func (cm *ChanMap) DelList(ks []interface{})
DelList deletes entries with key as k in ks
func (*ChanMap) Get ¶ added in v0.4.3
func (cm *ChanMap) Get(k interface{}) chan *RelayReceival
Get return the channel map to k
func (*ChanMap) GetList ¶ added in v0.4.3
func (cm *ChanMap) GetList() []chan *RelayReceival
GetList return all channels in cm
func (*ChanMap) Set ¶ added in v0.4.3
func (cm *ChanMap) Set(k interface{}, v chan *RelayReceival)
Set (k,v) into cm
func (*ChanMap) SetList ¶ added in v0.4.3
func (cm *ChanMap) SetList(ks []interface{}, v chan *RelayReceival)
SetList set a (k,v) into cm for each k in ks
type EtherConn ¶
type EtherConn struct {
// contains filtered or unexported fields
}
EtherConn send/recv Ethernet payload like IP packet with customizable Ethernet encapsualtion like MAC and VLANs without provisioning them in OS. it needs to be registed with a PacketRelay instance to work.
func NewEtherConn ¶
func NewEtherConn(mac net.HardwareAddr, relay PacketRelay, options ...EtherConnOption) *EtherConn
NewEtherConn creates a new EtherConn instance, mac is used as part of EtherConn's L2Endpoint; relay is the PacketRelay that EtherConn instance register with; options specifies EtherConnOption(s) to use;
func (*EtherConn) Close ¶
Close implements net.PacketConn interface, deregister itself from PacketRelay
func (*EtherConn) GetEtherTypes ¶ added in v0.5.0
GetEtherTypes returns list of EtherType ec recevies
func (*EtherConn) LocalAddr ¶
func (ec *EtherConn) LocalAddr() *L2Endpoint
LocalAddr return EtherConn's L2Endpoint
func (*EtherConn) ReadPkt ¶
func (ec *EtherConn) ReadPkt() ([]byte, *L2Endpoint, error)
ReadPkt return received Ethernet payload bytes with an already allocated byte slice, along with remote L2Endpoint ReadPkt only return payload that matches one of underlying PacketRelay's configured EtherTypes
func (*EtherConn) ReadPktFrom ¶
func (ec *EtherConn) ReadPktFrom(p []byte) (int, *L2Endpoint, error)
ReadPktFrom copies the received Ethernet payload to p; it calls ReadPkt to get the payload, it return number bytes of IP packet, remote MAC address
func (*EtherConn) SetDeadline ¶
SetDeadline implements net.PacketConn interface
func (*EtherConn) SetReadDeadline ¶
SetReadDeadline implements net.PacketConn interface
func (*EtherConn) SetWriteDeadline ¶
SetWriteDeadline implements net.PacketConn interface
func (*EtherConn) WriteIPPktTo ¶
WriteIPPktTo sends an IPv4/IPv6 packet, the pkt will be sent to dstmac, along with EtherConn.L2EP.VLANs.
func (*EtherConn) WriteIPPktToFrom ¶ added in v0.2.0
func (ec *EtherConn) WriteIPPktToFrom(p []byte, srcmac, dstmac net.HardwareAddr, vlans VLANs) (int, error)
WriteIPPktToFrom is same as WriteIPPktTo beside send pkt with srcmac
func (*EtherConn) WritePktTo ¶
WritePktTo sends an Ethernet payload, along with specified EtherType, the pkt will be sent to dstmac, along with EtherConn.L2EP.VLANs.
func (*EtherConn) WritePktToFrom ¶ added in v0.2.0
func (ec *EtherConn) WritePktToFrom(p []byte, etype uint16, srcmac, dstmac net.HardwareAddr, vlans VLANs) (int, error)
WritePktToFrom is same as WritePktTo except with srcmac
type EtherConnOption ¶
type EtherConnOption func(ec *EtherConn)
EtherConnOption is a function use to provide customized option when creating EtherConn
func WithDefault ¶ added in v0.2.0
func WithDefault() EtherConnOption
WithDefault will register the EtherConn to be the default EtherConn for received traffic, see PacketRelay.RegisterDefault for details. if relay is created with mirroring to default, then the etherconn will get a copy of all received pkt by the relay
func WithEtherTypes ¶ added in v0.2.0
func WithEtherTypes(ets []uint16) EtherConnOption
WithEtherTypes specifies a list of Ethernet types that this EtherConn is interested in, the specified Ethernet types is the types of inner payload, the default list is DefaultEtherTypes
func WithRecvMulticast ¶ added in v0.1.2
func WithRecvMulticast(recv bool) EtherConnOption
WithRecvMulticast allow/disallow EtherConn to receive multicast/broadcast Ethernet traffic
func WithVLANs ¶
func WithVLANs(vlans VLANs) EtherConnOption
WithVLANs specifies VLAN(s) as part of EtherConn's L2Endpoint. by default, there is no VLAN.
type L2Endpoint ¶
type L2Endpoint struct { HwAddr net.HardwareAddr VLANs []uint16 Etype uint16 //inner most EtherType (e.g payload type) }
L2Endpoint represents a layer2 endpoint that send/receives Ethernet frame
func NewL2EndpointFromMACVLAN ¶
func NewL2EndpointFromMACVLAN(mac net.HardwareAddr, vlans VLANs) *L2Endpoint
NewL2EndpointFromMACVLAN creates a new L2Endpoint from mac and vlans; its Etype is set to any
func NewL2EndpointFromMACVLANEtype ¶ added in v0.2.0
func NewL2EndpointFromMACVLANEtype(mac net.HardwareAddr, vlans VLANs, etype uint16) *L2Endpoint
NewL2EndpointFromMACVLANEtype creates a new L2Endpoint from mac, vlans and etype
func (*L2Endpoint) GetKey ¶
func (l2e *L2Endpoint) GetKey() (key L2EndpointKey)
GetKey returns the key of the L2Endpoint
func (*L2Endpoint) GetVLANsWithDefaultEtype ¶ added in v0.2.0
func (l2e *L2Endpoint) GetVLANsWithDefaultEtype() (r VLANs)
GetVLANsWithDefaultEtype return an instance of VLANs with VLAN ethernet type set as DefaultVLANEtype
func (*L2Endpoint) Network ¶
func (l2e *L2Endpoint) Network() string
Network implements net.Addr interface, return "l2ep"
func (*L2Endpoint) String ¶
func (l2e *L2Endpoint) String() (s string)
String implements net.Addr interface, return a string with format: l2ep&<l2EndpointKey_str>, see L2EndpointKey.String for format of <l2EndpointKey_str>
type L2EndpointKey ¶
type L2EndpointKey [L2EndpointKeySize]byte
L2EndpointKey is key identify a L2EndPoint,first 6 bytes are MAC address, VLAN Ids in order (from outside to inner), each VLAN id are two bytes in network endian, if VLAN id is NOVLANTAG,then it means no such tag; last two bytes are inner most EtherType.
func (L2EndpointKey) String ¶
func (l2epkey L2EndpointKey) String() string
type L4RecvKey ¶ added in v0.3.0
type L4RecvKey [19]byte
L4RecvKey resprsents a Layer4 recv endpoint: [0:15] bytes is the IP address, [16] is the IP protocol, [17:18] is the port number, in big endian
func NewL4RecvKeyViaUDPAddr ¶ added in v0.3.0
NewL4RecvKeyViaUDPAddr returns a L4RecvKey from a net.UDPAddr
type PacketRelay ¶
type PacketRelay interface { // Register register a list of L2EndpointKey of a EtherConn, PacketRely send/recv pkt on its behalf, // it returns following channels: // recv is the channel used to recive; // send is the channel used to send; // stop is a channel that will be closed when PacketRelay stops sending; // if recvMulticast is true, then multicast ethernet traffic will be recvied as well; // if one of key is already registered, then existing key will be overriden; Register(ks []L2EndpointKey, recvMulticast bool) (recv chan *RelayReceival, send chan []byte, stop chan struct{}) // RegisterDefault return default receive channel, // meaning a received pkt doesn't match any other specific EtherConn registered with L2Endpointkey will be send to this channel; // multicast traffic will be also sent to this channel; RegisterDefault() (recv chan *RelayReceival, send chan []byte, stop chan struct{}) // Deregister removes L2EndpointKey from registration Deregister(ks []L2EndpointKey) // Stop stops the forwarding of PacketRelay Stop() // IfName return binding interface name IfName() string // GetStats returns stats GetStats() *RelayPacketStats // Type returns relay type Type() RelayType }
PacketRelay is a interface for the packet forwarding engine, RawSocketRelay implements this interface;
type PcapConn ¶ added in v0.6.0
func NewPcapConn ¶ added in v0.6.0
NewPcapConn creates a new PcapRelay instances for specified ifname. Note: on windows, the ifname is the "\Device\NPF_xxxx"
type RUDPConn ¶
type RUDPConn struct {
// contains filtered or unexported fields
}
RUDPConn implement net.PacketConn interface; it used to send/recv UDP payload, using a underlying EtherConn for pkt forwarding.
func NewRUDPConn ¶
func NewRUDPConn(src string, c *EtherConn, options ...RUDPConnOption) (*RUDPConn, error)
NewRUDPConn creates a new RUDPConn, with specified EtherConn, and, optionally RUDPConnOption(s). src is the string represents its UDP Address as format supported by net.ResolveUDPAddr(). note the src UDP address could be any IP address, even address not provisioned in OS, like 0.0.0.0
func (*RUDPConn) ReadFrom ¶
ReadFrom implements net.PacketConn interface, it copy UDP payload to p; note: the underlying EtherConn will send all received pkts as *RelayReceival to RUDPConn, RUDPConn will ignore pkts that is not destined to its UDPAddr, unless WithAcceptAny(true) is specified when creating the RUDPConn, in that case, RUDPConn will accept any UDP packet;
func (*RUDPConn) SetDeadline ¶
SetDeadline implements net.PacketConn interface
func (*RUDPConn) SetReadDeadline ¶
SetReadDeadline implements net.PacketConn interface
func (*RUDPConn) SetWriteDeadline ¶
SetWriteDeadline implements net.PacketConn interface
func (*RUDPConn) WriteTo ¶
WriteTo implements net.PacketConn interface, it sends UDP payload; This function adds UDP and IP header, and uses RUDPConn's resolve function to get nexthop's MAC address, and use underlying EtherConn to send IP packet, with EtherConn's Ethernet encapsulation, to nexthop MAC address; by default ResolveNexhopMACWithBrodcast is used for nexthop mac resolvement
type RUDPConnOption ¶
type RUDPConnOption func(rudpc *RUDPConn)
RUDPConnOption is a function use to provide customized option when creating RUDPConn
func WithAcceptAny ¶
func WithAcceptAny(accept bool) RUDPConnOption
WithAcceptAny allows RUDPConn to accept any UDP pkts, even it is not destinated to its address
func WithResolveNextHopMacFunc ¶
func WithResolveNextHopMacFunc(f func(net.IP) net.HardwareAddr) RUDPConnOption
WithResolveNextHopMacFunc specifies a function to resolve a destination IP address to next-hop MAC address; by default, ResolveNexhopMACWithBrodcast is used.
type RawSocketRelay ¶
type RawSocketRelay struct {
// contains filtered or unexported fields
}
RawSocketRelay implements PacketRelay interface, using AF_PACKET socket or libpcap. use NewRawSocketRelayPcap or NewRawSocketRelay create new instances.
func NewRawSocketRelay ¶
func NewRawSocketRelay(parentctx context.Context, ifname string, options ...RelayOption) (*RawSocketRelay, error)
NewRawSocketRelayPcap creates a new RawSocketRelay instance using AF_PACKET socket , bound to the interface ifname, optionally with RelayOption functions. This function will put the interface in promisc mode, which means it requires root privilage.
func NewRawSocketRelayPcap ¶ added in v0.6.0
func NewRawSocketRelayPcap(parentctx context.Context, ifname string, options ...RelayOption) (*RawSocketRelay, error)
NewRawSocketRelayPcap creates a new RawSocketRelay instance using libpcap, bound to the interface ifname, optionally with RelayOption functions. This function will put the interface in promisc mode, which means it requires root privilage.
func (*RawSocketRelay) Deregister ¶
func (rsr *RawSocketRelay) Deregister(ks []L2EndpointKey)
Deregister implements PacketRelay interface;
func (*RawSocketRelay) GetStats ¶
func (rsr *RawSocketRelay) GetStats() *RelayPacketStats
GetStats return pkt forwarding stats as *RelayPacketStats
func (*RawSocketRelay) IfName ¶ added in v0.1.3
func (rsr *RawSocketRelay) IfName() string
IfName returns the name of the binding interface
func (*RawSocketRelay) Register ¶
func (rsr *RawSocketRelay) Register(ks []L2EndpointKey, recvMulticast bool) (chan *RelayReceival, chan []byte, chan struct{})
Register implements PacketRelay interface;
func (*RawSocketRelay) RegisterDefault ¶ added in v0.2.0
func (rsr *RawSocketRelay) RegisterDefault() (chan *RelayReceival, chan []byte, chan struct{})
RegisterDefault implements PacketRelay interface
func (*RawSocketRelay) Stop ¶
func (rsr *RawSocketRelay) Stop()
Stop implements PacketRelay interface
func (*RawSocketRelay) Type ¶ added in v0.6.0
func (rsr *RawSocketRelay) Type() RelayType
Type returns rsr's type
type RelayOption ¶
type RelayOption func(*RawSocketRelay)
RelayOption is a function use to provide customized option when creating RawSocketRelay
func WithBPFFilter ¶ added in v0.1.2
func WithBPFFilter(filter string) RelayOption
WithBPFFilter set BPF filter, which is a pcap filter string; if filter is an empty string, then it means no filter; by default, Relay will have a filter only allow traffic with specified EtherType.
func WithDefaultReceival ¶ added in v0.2.0
func WithDefaultReceival(mirroring bool) RelayOption
WithDefaultReceival creates a default receiving channel, all received pkt doesn't match any explicit EtherConn, will be sent to this channel; using RegisterDefault to get the default receiving channel. if mirroring is true, then every received pkt will be sent to this channel.
func WithMaxEtherFrameSize ¶
func WithMaxEtherFrameSize(size uint) RelayOption
WithMaxEtherFrameSize specifies the max Ethernet frame size the RawSocketRelay could receive
func WithMultiEngine ¶ added in v0.4.0
func WithMultiEngine(count uint) RelayOption
WithMultiEngine specifies the number of internal send/recv routine, count must >=1, default value is 1
func WithPerClntChanRecvDepth ¶
func WithPerClntChanRecvDepth(depth uint) RelayOption
WithPerClntChanRecvDepth specifies the per Client(EtherConn) receive channel depth, By default, DefaultPerClntRecvChanDepth is used
func WithRecvTimeout ¶
func WithRecvTimeout(t time.Duration) RelayOption
WithRecvTimeout specifies the receive timeout for RawSocketRelay
func WithSendChanDepth ¶
func WithSendChanDepth(depth uint) RelayOption
WithSendChanDepth specifies the send channel depth, by default, DefaultSendChanDepth is used
type RelayPacketStats ¶
type RelayPacketStats struct { // Tx is number of pkts sent successfully Tx *uint64 // RxOffered is number of pkts relay get from interface RxOffered *uint64 // RxInvalid is nunber of pkts relay get but ignored due to failed valid check RxInvalid *uint64 // RxBufferFull is the number of pkts can't send to receiver's channel right away due to it is full RxBufferFull *uint64 // RxMiss is the number of pkts relay can't find receiver RxMiss *uint64 // Rx is the number of pkts relay successfully deliver to receiver, not including pkt sent to default channel Rx *uint64 // RxDefault is the number of pkts relay deliver to the default rcv channel RxDefault *uint64 // RxNonHitMulticast is the number of multicast pkts that doesn't have direct receiver, but deliver to a multicast recevier RxNonHitMulticast *uint64 // RxMulticastIgnored is the number of multicast pkts ignored RxMulticastIgnored *uint64 }
RelayPacketStats is the PacketRelay's forwding stats; use atomic.LoadUint64 to read the values
func (RelayPacketStats) String ¶
func (rps RelayPacketStats) String() string
type RelayReceival ¶
type RelayReceival struct {
//LocalEndpoint/RemoteEndpoint is the local/remote L2Endpoint
LocalEndpoint, RemoteEndpoint *L2Endpoint
// EtherBytes is the Ethernet frame bytes
EtherBytes []byte
// EtherPayloadBytes is the Ethernet payload bytes within the EtherBytes,
// where payload belongs to the specified EtherTypes,
// default are 0x0800 (IPv4) and 0x86dd (IPv6),
// nil if there is no payload with specified EtherTypes;
EtherPayloadBytes []byte
// TransportPayloadBytes is the transport layer(UDP/TCP/SCTP) payload bytes within the IPBytes,nil for unsupport transport layer
TransportPayloadBytes []byte
// RemoteIP is the remote IP address
RemoteIP net.IP
// RemotePort is the remote transport layer port, 0 for unsupport transport layer
RemotePort uint16
// Protocol is the IP protocol number
Protocol uint8
// LocalIP is the local IP address
LocalIP net.IP
// LocalPort is the local transport layer port, 0 for unsupport transport layer
LocalPort uint16
}
RelayReceival is the what PacketRelay received and parsed
func (*RelayReceival) GetL4Key ¶ added in v0.3.0
func (rr *RelayReceival) GetL4Key() (r L4RecvKey)
type RelayType ¶ added in v0.6.0
type RelayType string
func (RelayType) MarshalText ¶ added in v0.6.1
MarshalText implements encoding.TextMarshaler interface
func (*RelayType) UnmarshalText ¶ added in v0.6.1
UnmarshalText implements encoding.TextUnmarshaler interface
type SharedEconn ¶ added in v0.4.3
type SharedEconn interface {}
type SharedEtherConn ¶ added in v0.3.0
type SharedEtherConn struct {
// contains filtered or unexported fields
}
SharedEtherConn could be mapped to multiple RUDPConn
func NewSharedEtherConn ¶ added in v0.3.0
func NewSharedEtherConn(parentctx context.Context, mac net.HardwareAddr, relay PacketRelay, ecopts []EtherConnOption, options ...SharedEtherConnOption) *SharedEtherConn
NewSharedEtherConn creates a new SharedEtherConn; mac is the SharedEtherConn's own MAC address; relay is the underlying PacketRelay; ecopts is a list of EtherConnOption that could be used to customized new SharedEtherConnOption, all currently defined EtherConnOption could also be used for SharedEtherConn. options is a list of SharedEtherConnOption, not used currently;
func (*SharedEtherConn) Close ¶ added in v0.3.0
func (sec *SharedEtherConn) Close()
Close stop the SharedEtherConn
func (*SharedEtherConn) Register ¶ added in v0.3.0
func (sec *SharedEtherConn) Register(k L4RecvKey) (torecvch chan *RelayReceival)
Register register a key, return following channels: torecvch is the channel which is used to store received packets has one of registered key in keys;
func (*SharedEtherConn) RegisterList ¶ added in v0.3.0
func (sec *SharedEtherConn) RegisterList(keys []L4RecvKey) (torecvch chan *RelayReceival)
RegisterList register a set of keys, return following channels: torecvch is the channel which is used to store received packets has one of registered key in keys;
func (*SharedEtherConn) SetWriteDeadline ¶ added in v0.4.3
func (sec *SharedEtherConn) SetWriteDeadline(t time.Time) error
func (*SharedEtherConn) WriteIPPktTo ¶ added in v0.3.0
func (sec *SharedEtherConn) WriteIPPktTo(p []byte, dstmac net.HardwareAddr) (int, error)
WriteIPPktTo sends an IP packet to dstmac, with EtherConn's vlan encapsualtaion, if any;
func (*SharedEtherConn) WriteIPPktToFrom ¶ added in v0.3.0
func (sec *SharedEtherConn) WriteIPPktToFrom(p []byte, srcmac, dstmac net.HardwareAddr, vlans VLANs) (int, error)
WriteIPPktToFrom is same as WriteIPPktTo beside send pkt with srcmac
func (*SharedEtherConn) WritePktTo ¶ added in v0.3.0
func (sec *SharedEtherConn) WritePktTo(p []byte, etype uint16, dstmac net.HardwareAddr) (int, error)
WritePktTo sends an Ethernet payload, along with specified EtherType, the pkt will be sent to dstmac, along with EtherConn.L2EP.VLANs.
func (*SharedEtherConn) WritePktToFrom ¶ added in v0.3.0
func (sec *SharedEtherConn) WritePktToFrom(p []byte, etype uint16, srcmac, dstmac net.HardwareAddr, vlans VLANs) (int, error)
WritePktToFrom is same as WritePktTo except with srcmac
type SharedEtherConnOption ¶ added in v0.3.0
type SharedEtherConnOption func(sec *SharedEtherConn)
SharedEtherConnOption is the option to customize new SharedEtherConnOption
func WithSharedEConnPerClntRecvChanDepth ¶ added in v0.4.0
func WithSharedEConnPerClntRecvChanDepth(depth uint) SharedEtherConnOption
type SharingRUDPConn ¶ added in v0.3.0
type SharingRUDPConn struct {
// contains filtered or unexported fields
}
SharingRUDPConn is the UDP connection could share same SharedEtherConn;
func NewSharingRUDPConn ¶ added in v0.3.0
func NewSharingRUDPConn(src string, c SharedEconn, roptions []RUDPConnOption, options ...SharingRUDPConnOptions) (*SharingRUDPConn, error)
NewSharingRUDPConn creates a new SharingRUDPConn, src is the string represents its UDP Address as format supported by net.ResolveUDPAddr(). c is the underlying SharedEtherConn, roptions is a list of RUDPConnOptions that use for customization, supported are: WithResolveNextHopMacFunc; note unlike RUDPConn, SharingRUDPConn doesn't support acceptting pkt is not destinated to own address
func (*SharingRUDPConn) Close ¶ added in v0.3.0
func (sruc *SharingRUDPConn) Close() error
Close implements net.PacketConn interface, it closes underlying EtherConn
func (*SharingRUDPConn) LocalAddr ¶ added in v0.3.0
func (sruc *SharingRUDPConn) LocalAddr() net.Addr
LocalAddr implements net.PacketConn interface, it returns its UDPAddr
func (*SharingRUDPConn) ReadFrom ¶ added in v0.3.0
ReadFrom implment net.PacketConn interface, it returns UDP payload;
func (*SharingRUDPConn) SetDeadline ¶ added in v0.3.0
func (sruc *SharingRUDPConn) SetDeadline(t time.Time) error
SetDeadline implements net.PacketConn interface
func (*SharingRUDPConn) SetReadDeadline ¶ added in v0.3.0
func (sruc *SharingRUDPConn) SetReadDeadline(t time.Time) error
SetReadDeadline implements net.PacketConn interface
func (*SharingRUDPConn) SetWriteDeadline ¶ added in v0.3.0
func (sruc *SharingRUDPConn) SetWriteDeadline(t time.Time) error
SetWriteDeadline implements net.PacketConn interface
func (*SharingRUDPConn) WriteTo ¶ added in v0.3.0
WriteTo implements net.PacketConn interface, it sends UDP payload; This function adds UDP and IP header, and uses sruc's resolve function to get nexthop's MAC address, and use underlying SharedEtherConn to send IP packet, with SharedEtherConn's Ethernet encapsulation, to nexthop MAC address; by default ResolveNexhopMACWithBrodcast is used for nexthop mac resolvement
type SharingRUDPConnOptions ¶ added in v0.3.0
type SharingRUDPConnOptions func(srudpc *SharingRUDPConn)
SharingRUDPConnOptions is is the option to customize new SharingRUDPConn
type VLAN ¶
VLAN reprents a VLAN tag. Note: VLAN shouldn't be used directly, use VLANs instead even if there is only one tag
func (VLAN) IsUnspecified ¶ added in v0.9.0
IsUnspecified return true if both vlan's ID and EtherType is zero
func (VLAN) MarshalBinary ¶ added in v0.7.0
MarshalBinary implements encoding.BinaryMarshaler interface
func (*VLAN) UnmarshalBinary ¶ added in v0.7.0
UnmarshalBinary implements encoding.BinaryUnmarshaler interface
type VLANs ¶ added in v0.1.1
type VLANs []*VLAN
VLANs is a slice of VLAN
func (VLANs) MarshalBinary ¶ added in v0.7.0
MarshalBinary implements encoding.BinaryMarshaler interface
func (VLANs) MarshalText ¶ added in v0.6.1
MarshalText implements encoding.TextMarshaler interface
func (*VLANs) UnmarshalBinary ¶ added in v0.7.0
UnmarshalBinary implements encoding.BinaryUnmarshaler interface
func (*VLANs) UnmarshalText ¶ added in v0.6.1
UnmarshalText implements encoding.TextUnmarshaler interface, it accepts two formats: either "x.y" or "x|y", and it uses the DefaultVLANEtype
type XDPRelay ¶ added in v0.3.0
type XDPRelay struct {
// contains filtered or unexported fields
}
XDPRelay is a PacketRelay implementation that uses AF_XDP Socket
func NewXDPRelay ¶ added in v0.3.0
func NewXDPRelay(parentctx context.Context, ifname string, options ...XDPRelayOption) (*XDPRelay, error)
NewXDPRelay creates a new instance of XDPRelay, by default, the XDPRelay binds to all queues of the specified interface
func (*XDPRelay) Deregister ¶ added in v0.3.0
func (xr *XDPRelay) Deregister(ks []L2EndpointKey)
Deregister implements PacketRelay interface;
func (*XDPRelay) GetStats ¶ added in v0.3.0
func (xr *XDPRelay) GetStats() *RelayPacketStats
GetStats returns the stats
func (*XDPRelay) Register ¶ added in v0.3.0
func (xr *XDPRelay) Register(ks []L2EndpointKey, recvMulticast bool) (chan *RelayReceival, chan []byte, chan struct{})
Register implements PacketRelay interface;
func (*XDPRelay) RegisterDefault ¶ added in v0.3.0
func (xr *XDPRelay) RegisterDefault() (chan *RelayReceival, chan []byte, chan struct{})
RegisterDefault implements PacketRelay interface
type XDPRelayOption ¶ added in v0.3.0
type XDPRelayOption func(xr *XDPRelay)
XDPRelayOption could be used in NewXDPRelay to customize XDPRelay upon creation
func WithQueueID ¶ added in v0.3.0
func WithQueueID(qidlist []int) XDPRelayOption
WithQueueID specifies a list of interface queue id (start from 0) that the XDPRelay binds to; by default, XDPRelay will use all queues. note: only use this option if you know what you are doing, since this could cause lower performance or XDPRelay unable to receive some of packets.
func WithSendingMode ¶ added in v0.4.0
func WithSendingMode(m XDPSendingMode) XDPRelayOption
WithSendingMode set the XDPRelay's sending mode to m
func WithXDPDebug ¶ added in v0.3.0
func WithXDPDebug(debug bool) XDPRelayOption
WithXDPDebug enable/disable debug log output
func WithXDPDefaultReceival ¶ added in v0.3.0
func WithXDPDefaultReceival(mirroring bool) XDPRelayOption
WithXDPDefaultReceival creates a default receiving channel, all received pkt doesn't match any explicit EtherConn, will be sent to this channel; using RegisterDefault to get the default receiving channel. if mirroring is true, then every received pkt will be sent to this channel.
func WithXDPEtherTypes ¶ added in v0.4.2
func WithXDPEtherTypes(ets []uint16) XDPRelayOption
WithXDPEtherTypes specifies a list of EtherType that the relay accepts, if a rcvd packet doesn't have a expected EtherType, then it will be passed to kernel. the EtherType is the inner most EtherType in case there is vlan tag. the default accept EtherTypes is DefaultEtherTypes. Note: this requires the builtin XDP kernel program.
func WithXDPExtProg ¶ added in v0.4.0
func WithXDPExtProg(fname, prog, qmap, xskmap, etypemap string) XDPRelayOption
WithXDPExtProg loads an external XDP kernel program iso using the built-in one
func WithXDPPerClntRecvChanDepth ¶ added in v0.4.0
func WithXDPPerClntRecvChanDepth(depth uint) XDPRelayOption
WithXDPPerClntRecvChanDepth set the depth in recving channel for each registered
func WithXDPSendChanDepth ¶ added in v0.4.0
func WithXDPSendChanDepth(depth uint) XDPRelayOption
WithXDPSendChanDepth set the dep th in sending channel
func WithXDPUMEMChunkSize ¶ added in v0.4.0
func WithXDPUMEMChunkSize(fsize uint) XDPRelayOption
WithXDPUMEMChunkSize specifies the XDP UMEM size, which implicitly set the max packet size could be handled by XDPRelay, must be either 4096 or 2048 (kernel XDP limitation)
func WithXDPUMEMNumOfTrunk ¶ added in v0.3.0
func WithXDPUMEMNumOfTrunk(num uint) XDPRelayOption
WithXDPUMEMNumOfTrunk specifies the number of UMEM trunks, must be power of 2. the Fill/Completion/TX/RX ring size is half of specified value;
type XDPSendingMode ¶ added in v0.4.0
type XDPSendingMode string
XDPSendingMode is the TX mode of XDPRelay
const ( //XDPSendingModeSingle is the TX mode send a packet a time, this is the default mode; XDPSendingModeSingle XDPSendingMode = "single" //XDPSendingModeBatch is the TX mode sends a batch of packet a time, only use this mode when needed TX pps is high; XDPSendingModeBatch XDPSendingMode = "batch" )
type XDPSocketPktHandler ¶ added in v0.4.0
XDPSocketPktHandler is a handler function could be used for rx/tx packet of a XDP socket
type XdpSockStats ¶ added in v0.4.0
type XdpSockStats struct {
Sent, Recv uint64
}
XdpSockStats hold per XDP socket/queue stats
type XdpSockStatsList ¶ added in v0.4.0
type XdpSockStatsList map[int]*XdpSockStats
func (XdpSockStatsList) String ¶ added in v0.4.0
func (list XdpSockStatsList) String() string