github.com/adityamillind98/moby@v23.0.0-rc.4+incompatible/libnetwork/drivers/overlay/ov_endpoint.go (about) 1 //go:build linux 2 // +build linux 3 4 package overlay 5 6 import ( 7 "encoding/json" 8 "fmt" 9 "net" 10 11 "github.com/docker/docker/libnetwork/datastore" 12 "github.com/docker/docker/libnetwork/driverapi" 13 "github.com/docker/docker/libnetwork/netutils" 14 "github.com/docker/docker/libnetwork/ns" 15 "github.com/docker/docker/libnetwork/types" 16 "github.com/sirupsen/logrus" 17 ) 18 19 type endpointTable map[string]*endpoint 20 21 const overlayEndpointPrefix = "overlay/endpoint" 22 23 type endpoint struct { 24 id string 25 nid string 26 ifName string 27 mac net.HardwareAddr 28 addr *net.IPNet 29 dbExists bool 30 dbIndex uint64 31 } 32 33 func (n *network) endpoint(eid string) *endpoint { 34 n.Lock() 35 defer n.Unlock() 36 37 return n.endpoints[eid] 38 } 39 40 func (n *network) addEndpoint(ep *endpoint) { 41 n.Lock() 42 n.endpoints[ep.id] = ep 43 n.Unlock() 44 } 45 46 func (n *network) deleteEndpoint(eid string) { 47 n.Lock() 48 delete(n.endpoints, eid) 49 n.Unlock() 50 } 51 52 func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo, 53 epOptions map[string]interface{}) error { 54 var err error 55 56 if err = validateID(nid, eid); err != nil { 57 return err 58 } 59 60 // Since we perform lazy configuration make sure we try 61 // configuring the driver when we enter CreateEndpoint since 62 // CreateNetwork may not be called in every node. 63 if err := d.configure(); err != nil { 64 return err 65 } 66 67 n := d.network(nid) 68 if n == nil { 69 return fmt.Errorf("network id %q not found", nid) 70 } 71 72 ep := &endpoint{ 73 id: eid, 74 nid: n.id, 75 addr: ifInfo.Address(), 76 mac: ifInfo.MacAddress(), 77 } 78 if ep.addr == nil { 79 return fmt.Errorf("create endpoint was not passed interface IP address") 80 } 81 82 if s := n.getSubnetforIP(ep.addr); s == nil { 83 return fmt.Errorf("no matching subnet for IP %q in network %q", ep.addr, nid) 84 } 85 86 if ep.mac == nil { 87 ep.mac = netutils.GenerateMACFromIP(ep.addr.IP) 88 if err := ifInfo.SetMacAddress(ep.mac); err != nil { 89 return err 90 } 91 } 92 93 n.addEndpoint(ep) 94 95 if err := d.writeEndpointToStore(ep); err != nil { 96 return fmt.Errorf("failed to update overlay endpoint %.7s to local store: %v", ep.id, err) 97 } 98 99 return nil 100 } 101 102 func (d *driver) DeleteEndpoint(nid, eid string) error { 103 nlh := ns.NlHandle() 104 105 if err := validateID(nid, eid); err != nil { 106 return err 107 } 108 109 n := d.network(nid) 110 if n == nil { 111 return fmt.Errorf("network id %q not found", nid) 112 } 113 114 ep := n.endpoint(eid) 115 if ep == nil { 116 return fmt.Errorf("endpoint id %q not found", eid) 117 } 118 119 n.deleteEndpoint(eid) 120 121 if err := d.deleteEndpointFromStore(ep); err != nil { 122 logrus.Warnf("Failed to delete overlay endpoint %.7s from local store: %v", ep.id, err) 123 } 124 125 if ep.ifName == "" { 126 return nil 127 } 128 129 link, err := nlh.LinkByName(ep.ifName) 130 if err != nil { 131 logrus.Debugf("Failed to retrieve interface (%s)'s link on endpoint (%s) delete: %v", ep.ifName, ep.id, err) 132 return nil 133 } 134 if err := nlh.LinkDel(link); err != nil { 135 logrus.Debugf("Failed to delete interface (%s)'s link on endpoint (%s) delete: %v", ep.ifName, ep.id, err) 136 } 137 138 return nil 139 } 140 141 func (d *driver) EndpointOperInfo(nid, eid string) (map[string]interface{}, error) { 142 return make(map[string]interface{}), nil 143 } 144 145 func (d *driver) deleteEndpointFromStore(e *endpoint) error { 146 if d.localStore == nil { 147 return fmt.Errorf("overlay local store not initialized, ep not deleted") 148 } 149 150 return d.localStore.DeleteObjectAtomic(e) 151 } 152 153 func (d *driver) writeEndpointToStore(e *endpoint) error { 154 if d.localStore == nil { 155 return fmt.Errorf("overlay local store not initialized, ep not added") 156 } 157 158 return d.localStore.PutObjectAtomic(e) 159 } 160 161 func (ep *endpoint) DataScope() string { 162 return datastore.LocalScope 163 } 164 165 func (ep *endpoint) New() datastore.KVObject { 166 return &endpoint{} 167 } 168 169 func (ep *endpoint) CopyTo(o datastore.KVObject) error { 170 dstep := o.(*endpoint) 171 *dstep = *ep 172 return nil 173 } 174 175 func (ep *endpoint) Key() []string { 176 return []string{overlayEndpointPrefix, ep.id} 177 } 178 179 func (ep *endpoint) KeyPrefix() []string { 180 return []string{overlayEndpointPrefix} 181 } 182 183 func (ep *endpoint) Index() uint64 { 184 return ep.dbIndex 185 } 186 187 func (ep *endpoint) SetIndex(index uint64) { 188 ep.dbIndex = index 189 ep.dbExists = true 190 } 191 192 func (ep *endpoint) Exists() bool { 193 return ep.dbExists 194 } 195 196 func (ep *endpoint) Skip() bool { 197 return false 198 } 199 200 func (ep *endpoint) Value() []byte { 201 b, err := json.Marshal(ep) 202 if err != nil { 203 return nil 204 } 205 return b 206 } 207 208 func (ep *endpoint) SetValue(value []byte) error { 209 return json.Unmarshal(value, ep) 210 } 211 212 func (ep *endpoint) MarshalJSON() ([]byte, error) { 213 epMap := make(map[string]interface{}) 214 215 epMap["id"] = ep.id 216 epMap["nid"] = ep.nid 217 if ep.ifName != "" { 218 epMap["ifName"] = ep.ifName 219 } 220 if ep.addr != nil { 221 epMap["addr"] = ep.addr.String() 222 } 223 if len(ep.mac) != 0 { 224 epMap["mac"] = ep.mac.String() 225 } 226 227 return json.Marshal(epMap) 228 } 229 230 func (ep *endpoint) UnmarshalJSON(value []byte) error { 231 var ( 232 err error 233 epMap map[string]interface{} 234 ) 235 236 json.Unmarshal(value, &epMap) 237 238 ep.id = epMap["id"].(string) 239 ep.nid = epMap["nid"].(string) 240 if v, ok := epMap["mac"]; ok { 241 if ep.mac, err = net.ParseMAC(v.(string)); err != nil { 242 return types.InternalErrorf("failed to decode endpoint interface mac address after json unmarshal: %s", v.(string)) 243 } 244 } 245 if v, ok := epMap["addr"]; ok { 246 if ep.addr, err = types.ParseCIDR(v.(string)); err != nil { 247 return types.InternalErrorf("failed to decode endpoint interface ipv4 address after json unmarshal: %v", err) 248 } 249 } 250 if v, ok := epMap["ifName"]; ok { 251 ep.ifName = v.(string) 252 } 253 254 return nil 255 }