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