github.com/looshlee/beatles@v0.0.0-20220727174639-742810ab631c/pkg/maps/eppolicymap/eppolicymap.go (about) 1 // Copyright 2016-2019 Authors of Cilium 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package eppolicymap 16 17 import ( 18 "fmt" 19 "net" 20 "sync" 21 "unsafe" 22 23 "github.com/cilium/cilium/pkg/bpf" 24 "github.com/cilium/cilium/pkg/logging" 25 "github.com/cilium/cilium/pkg/logging/logfields" 26 "github.com/cilium/cilium/pkg/maps/lxcmap" 27 "github.com/cilium/cilium/pkg/maps/policymap" 28 "github.com/cilium/cilium/pkg/option" 29 ) 30 31 var ( 32 log = logging.DefaultLogger.WithField(logfields.LogSubsys, "map-ep-policy") 33 MapName = "cilium_ep_to_policy" 34 innerMapName = "ep-policy-inner-map" 35 ) 36 37 const ( 38 // MaxEntries represents the maximum number of endpoints in the map 39 MaxEntries = 65535 40 ) 41 42 // +k8s:deepcopy-gen=true 43 // +k8s:deepcopy-gen:interfaces=github.com/cilium/cilium/pkg/bpf.MapKey 44 type EndpointKey struct{ bpf.EndpointKey } 45 46 // +k8s:deepcopy-gen=true 47 // +k8s:deepcopy-gen:interfaces=github.com/cilium/cilium/pkg/bpf.MapValue 48 type EPPolicyValue struct{ Fd uint32 } 49 50 var ( 51 buildMap sync.Once 52 53 EpPolicyMap = bpf.NewMap(MapName, 54 bpf.MapTypeHashOfMaps, 55 &EndpointKey{}, 56 int(unsafe.Sizeof(EndpointKey{})), 57 &EPPolicyValue{}, 58 int(unsafe.Sizeof(EPPolicyValue{})), 59 MaxEntries, 60 0, 61 0, 62 bpf.ConvertKeyValue, 63 ).WithCache() 64 ) 65 66 // CreateEPPolicyMap will create both the innerMap (needed for map in map types) and 67 // then after BPFFS is mounted create the epPolicyMap. We only create the innerFd once 68 // to avoid having multiple inner maps. 69 func CreateEPPolicyMap() { 70 buildMap.Do(func() { 71 mapType := bpf.MapType(bpf.BPF_MAP_TYPE_HASH) 72 fd, err := bpf.CreateMap(bpf.BPF_MAP_TYPE_HASH, 73 uint32(unsafe.Sizeof(policymap.PolicyKey{})), 74 uint32(unsafe.Sizeof(policymap.PolicyEntry{})), 75 uint32(policymap.MaxEntries), 76 bpf.GetPreAllocateMapFlags(mapType), 77 0, innerMapName) 78 79 if err != nil { 80 log.WithError(err).Warning("unable to create EP to policy map") 81 return 82 } 83 84 EpPolicyMap.InnerID = uint32(fd) 85 }) 86 87 if _, err := EpPolicyMap.OpenOrCreate(); err != nil { 88 log.WithError(err).Warning("Unable to open or create endpoint policy map") 89 } 90 } 91 92 func (v EPPolicyValue) String() string { return fmt.Sprintf("fd=%d", v.Fd) } 93 94 // GetValuePtr returns the unsafe value pointer to the Endpoint Policy fd 95 func (v *EPPolicyValue) GetValuePtr() unsafe.Pointer { return unsafe.Pointer(v) } 96 97 // NewValue returns a new empty instance of the Endpoint Policy fd 98 func (k EndpointKey) NewValue() bpf.MapValue { return &EPPolicyValue{} } 99 100 // newEndpointKey return a new key from the IP address. 101 func newEndpointKey(ip net.IP) *EndpointKey { 102 return &EndpointKey{ 103 EndpointKey: bpf.NewEndpointKey(ip), 104 } 105 } 106 107 func writeEndpoint(keys []*lxcmap.EndpointKey, fd int) error { 108 if option.Config.SockopsEnable == false { 109 return nil 110 } 111 112 if fd < 0 { 113 return fmt.Errorf("WriteEndpoint invalid policy fd %d", fd) 114 } 115 116 /* Casting file desriptor into uint32 required by BPF syscall */ 117 epFd := &EPPolicyValue{Fd: uint32(fd)} 118 119 for _, v := range keys { 120 if err := EpPolicyMap.Update(v, epFd); err != nil { 121 return err 122 } 123 } 124 return nil 125 } 126 127 // WriteEndpoint writes the policy map file descriptor into the map so that 128 // the datapath side can do a lookup from EndpointKey->PolicyMap. Locking is 129 // handled in the usual way via Map lock. If sockops is disabled this will be 130 // a nop. 131 func WriteEndpoint(keys []*lxcmap.EndpointKey, pm *policymap.PolicyMap) error { 132 return writeEndpoint(keys, pm.GetFd()) 133 }