k8s.io/kubernetes@v1.31.0-alpha.0.0.20240520171757-56147500dadc/pkg/proxy/util/nfacct/handler.go (about) 1 //go:build linux 2 // +build linux 3 4 /* 5 Copyright 2024 The Kubernetes Authors. 6 7 Licensed under the Apache License, Version 2.0 (the "License"); 8 you may not use this file except in compliance with the License. 9 You may obtain a copy of the License at 10 11 http://www.apache.org/licenses/LICENSE-2.0 12 13 Unless required by applicable law or agreed to in writing, software 14 distributed under the License is distributed on an "AS IS" BASIS, 15 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 See the License for the specific language governing permissions and 17 limitations under the License. 18 */ 19 20 package nfacct 21 22 import ( 23 "github.com/vishvananda/netlink/nl" 24 "github.com/vishvananda/netns" 25 "golang.org/x/sys/unix" 26 ) 27 28 // handler is an injectable interface for creating netlink request. 29 type handler interface { 30 newRequest(cmd int, flags uint16) request 31 } 32 33 // request is an injectable interface representing a netlink request. 34 type request interface { 35 Serialize() []byte 36 AddData(data nl.NetlinkRequestData) 37 AddRawData(data []byte) 38 Execute(sockType int, resType uint16) ([][]byte, error) 39 } 40 41 // netlinkHandler is an implementation of the handler interface. It maintains a netlink socket 42 // for communication with the NFAcct subsystem. 43 type netlinkHandler struct { 44 socket *nl.NetlinkSocket 45 } 46 47 // newNetlinkHandler initializes a netlink socket in the current network namespace and returns 48 // an instance of netlinkHandler with the initialized socket. 49 func newNetlinkHandler() (handler, error) { 50 socket, err := nl.GetNetlinkSocketAt(netns.None(), netns.None(), unix.NETLINK_NETFILTER) 51 if err != nil { 52 return nil, err 53 } 54 return &netlinkHandler{socket: socket}, nil 55 } 56 57 // newRequest creates a netlink request tailored for the NFAcct subsystem encapsulating the 58 // specified cmd and flags. It incorporates the netlink header and netfilter generic header 59 // into the resulting request. 60 func (n *netlinkHandler) newRequest(cmd int, flags uint16) request { 61 req := &nl.NetlinkRequest{ 62 // netlink message header 63 // (definition: https://github.com/torvalds/linux/blob/v6.7/include/uapi/linux/netlink.h#L44-L58) 64 NlMsghdr: unix.NlMsghdr{ 65 Len: uint32(unix.SizeofNlMsghdr), 66 Type: uint16(cmd | (unix.NFNL_SUBSYS_ACCT << 8)), 67 Flags: flags, 68 }, 69 Sockets: map[int]*nl.SocketHandle{ 70 unix.NETLINK_NETFILTER: {Socket: n.socket}, 71 }, 72 Data: []nl.NetlinkRequestData{ 73 // netfilter generic message 74 // (definition: https://github.com/torvalds/linux/blob/v6.7/include/uapi/linux/netfilter/nfnetlink.h#L32-L38) 75 &nl.Nfgenmsg{ 76 NfgenFamily: uint8(unix.AF_NETLINK), 77 Version: nl.NFNETLINK_V0, 78 ResId: 0, 79 }, 80 }, 81 } 82 return req 83 }