1package ipvlan 2 3import ( 4 "encoding/json" 5 "fmt" 6 "net" 7 8 "github.com/docker/libnetwork/datastore" 9 "github.com/docker/libnetwork/discoverapi" 10 "github.com/docker/libnetwork/netlabel" 11 "github.com/docker/libnetwork/types" 12 "github.com/sirupsen/logrus" 13) 14 15const ( 16 ipvlanPrefix = "ipvlan" 17 ipvlanNetworkPrefix = ipvlanPrefix + "/network" 18 ipvlanEndpointPrefix = ipvlanPrefix + "/endpoint" 19) 20 21// networkConfiguration for this driver's network specific configuration 22type configuration struct { 23 ID string 24 Mtu int 25 dbIndex uint64 26 dbExists bool 27 Internal bool 28 Parent string 29 IpvlanMode string 30 CreatedSlaveLink bool 31 Ipv4Subnets []*ipv4Subnet 32 Ipv6Subnets []*ipv6Subnet 33} 34 35type ipv4Subnet struct { 36 SubnetIP string 37 GwIP string 38} 39 40type ipv6Subnet struct { 41 SubnetIP string 42 GwIP string 43} 44 45// initStore drivers are responsible for caching their own persistent state 46func (d *driver) initStore(option map[string]interface{}) error { 47 if data, ok := option[netlabel.LocalKVClient]; ok { 48 var err error 49 dsc, ok := data.(discoverapi.DatastoreConfigData) 50 if !ok { 51 return types.InternalErrorf("incorrect data in datastore configuration: %v", data) 52 } 53 d.store, err = datastore.NewDataStoreFromConfig(dsc) 54 if err != nil { 55 return types.InternalErrorf("ipvlan driver failed to initialize data store: %v", err) 56 } 57 58 return d.populateNetworks() 59 } 60 61 return nil 62} 63 64// populateNetworks is invoked at driver init to recreate persistently stored networks 65func (d *driver) populateNetworks() error { 66 kvol, err := d.store.List(datastore.Key(ipvlanNetworkPrefix), &configuration{}) 67 if err != nil && err != datastore.ErrKeyNotFound { 68 return fmt.Errorf("failed to get ipvlan network configurations from store: %v", err) 69 } 70 // If empty it simply means no ipvlan networks have been created yet 71 if err == datastore.ErrKeyNotFound { 72 return nil 73 } 74 for _, kvo := range kvol { 75 config := kvo.(*configuration) 76 if err = d.createNetwork(config); err != nil { 77 logrus.Warnf("could not create ipvlan network for id %s from persistent state", config.ID) 78 } 79 } 80 81 return nil 82} 83 84func (d *driver) populateEndpoints() error { 85 kvol, err := d.store.List(datastore.Key(ipvlanEndpointPrefix), &endpoint{}) 86 if err != nil && err != datastore.ErrKeyNotFound { 87 return fmt.Errorf("failed to get ipvlan endpoints from store: %v", err) 88 } 89 90 if err == datastore.ErrKeyNotFound { 91 return nil 92 } 93 94 for _, kvo := range kvol { 95 ep := kvo.(*endpoint) 96 n, ok := d.networks[ep.nid] 97 if !ok { 98 logrus.Debugf("Network (%s) not found for restored ipvlan endpoint (%s)", ep.nid[0:7], ep.id[0:7]) 99 logrus.Debugf("Deleting stale ipvlan endpoint (%s) from store", ep.id[0:7]) 100 if err := d.storeDelete(ep); err != nil { 101 logrus.Debugf("Failed to delete stale ipvlan endpoint (%s) from store", ep.id[0:7]) 102 } 103 continue 104 } 105 n.endpoints[ep.id] = ep 106 logrus.Debugf("Endpoint (%s) restored to network (%s)", ep.id[0:7], ep.nid[0:7]) 107 } 108 109 return nil 110} 111 112// storeUpdate used to update persistent ipvlan network records as they are created 113func (d *driver) storeUpdate(kvObject datastore.KVObject) error { 114 if d.store == nil { 115 logrus.Warnf("ipvlan store not initialized. kv object %s is not added to the store", datastore.Key(kvObject.Key()...)) 116 return nil 117 } 118 if err := d.store.PutObjectAtomic(kvObject); err != nil { 119 return fmt.Errorf("failed to update ipvlan store for object type %T: %v", kvObject, err) 120 } 121 122 return nil 123} 124 125// storeDelete used to delete ipvlan network records from persistent cache as they are deleted 126func (d *driver) storeDelete(kvObject datastore.KVObject) error { 127 if d.store == nil { 128 logrus.Debugf("ipvlan store not initialized. kv object %s is not deleted from store", datastore.Key(kvObject.Key()...)) 129 return nil 130 } 131retry: 132 if err := d.store.DeleteObjectAtomic(kvObject); err != nil { 133 if err == datastore.ErrKeyModified { 134 if err := d.store.GetObject(datastore.Key(kvObject.Key()...), kvObject); err != nil { 135 return fmt.Errorf("could not update the kvobject to latest when trying to delete: %v", err) 136 } 137 goto retry 138 } 139 return err 140 } 141 142 return nil 143} 144 145func (config *configuration) MarshalJSON() ([]byte, error) { 146 nMap := make(map[string]interface{}) 147 nMap["ID"] = config.ID 148 nMap["Mtu"] = config.Mtu 149 nMap["Parent"] = config.Parent 150 nMap["IpvlanMode"] = config.IpvlanMode 151 nMap["Internal"] = config.Internal 152 nMap["CreatedSubIface"] = config.CreatedSlaveLink 153 if len(config.Ipv4Subnets) > 0 { 154 iis, err := json.Marshal(config.Ipv4Subnets) 155 if err != nil { 156 return nil, err 157 } 158 nMap["Ipv4Subnets"] = string(iis) 159 } 160 if len(config.Ipv6Subnets) > 0 { 161 iis, err := json.Marshal(config.Ipv6Subnets) 162 if err != nil { 163 return nil, err 164 } 165 nMap["Ipv6Subnets"] = string(iis) 166 } 167 168 return json.Marshal(nMap) 169} 170 171func (config *configuration) UnmarshalJSON(b []byte) error { 172 var ( 173 err error 174 nMap map[string]interface{} 175 ) 176 177 if err = json.Unmarshal(b, &nMap); err != nil { 178 return err 179 } 180 config.ID = nMap["ID"].(string) 181 config.Mtu = int(nMap["Mtu"].(float64)) 182 config.Parent = nMap["Parent"].(string) 183 config.IpvlanMode = nMap["IpvlanMode"].(string) 184 config.Internal = nMap["Internal"].(bool) 185 config.CreatedSlaveLink = nMap["CreatedSubIface"].(bool) 186 if v, ok := nMap["Ipv4Subnets"]; ok { 187 if err := json.Unmarshal([]byte(v.(string)), &config.Ipv4Subnets); err != nil { 188 return err 189 } 190 } 191 if v, ok := nMap["Ipv6Subnets"]; ok { 192 if err := json.Unmarshal([]byte(v.(string)), &config.Ipv6Subnets); err != nil { 193 return err 194 } 195 } 196 197 return nil 198} 199 200func (config *configuration) Key() []string { 201 return []string{ipvlanNetworkPrefix, config.ID} 202} 203 204func (config *configuration) KeyPrefix() []string { 205 return []string{ipvlanNetworkPrefix} 206} 207 208func (config *configuration) Value() []byte { 209 b, err := json.Marshal(config) 210 if err != nil { 211 return nil 212 } 213 return b 214} 215 216func (config *configuration) SetValue(value []byte) error { 217 return json.Unmarshal(value, config) 218} 219 220func (config *configuration) Index() uint64 { 221 return config.dbIndex 222} 223 224func (config *configuration) SetIndex(index uint64) { 225 config.dbIndex = index 226 config.dbExists = true 227} 228 229func (config *configuration) Exists() bool { 230 return config.dbExists 231} 232 233func (config *configuration) Skip() bool { 234 return false 235} 236 237func (config *configuration) New() datastore.KVObject { 238 return &configuration{} 239} 240 241func (config *configuration) CopyTo(o datastore.KVObject) error { 242 dstNcfg := o.(*configuration) 243 *dstNcfg = *config 244 return nil 245} 246 247func (config *configuration) DataScope() string { 248 return datastore.LocalScope 249} 250 251func (ep *endpoint) MarshalJSON() ([]byte, error) { 252 epMap := make(map[string]interface{}) 253 epMap["id"] = ep.id 254 epMap["nid"] = ep.nid 255 epMap["SrcName"] = ep.srcName 256 if len(ep.mac) != 0 { 257 epMap["MacAddress"] = ep.mac.String() 258 } 259 if ep.addr != nil { 260 epMap["Addr"] = ep.addr.String() 261 } 262 if ep.addrv6 != nil { 263 epMap["Addrv6"] = ep.addrv6.String() 264 } 265 return json.Marshal(epMap) 266} 267 268func (ep *endpoint) UnmarshalJSON(b []byte) error { 269 var ( 270 err error 271 epMap map[string]interface{} 272 ) 273 274 if err = json.Unmarshal(b, &epMap); err != nil { 275 return fmt.Errorf("Failed to unmarshal to ipvlan endpoint: %v", err) 276 } 277 278 if v, ok := epMap["MacAddress"]; ok { 279 if ep.mac, err = net.ParseMAC(v.(string)); err != nil { 280 return types.InternalErrorf("failed to decode ipvlan endpoint MAC address (%s) after json unmarshal: %v", v.(string), err) 281 } 282 } 283 if v, ok := epMap["Addr"]; ok { 284 if ep.addr, err = types.ParseCIDR(v.(string)); err != nil { 285 return types.InternalErrorf("failed to decode ipvlan endpoint IPv4 address (%s) after json unmarshal: %v", v.(string), err) 286 } 287 } 288 if v, ok := epMap["Addrv6"]; ok { 289 if ep.addrv6, err = types.ParseCIDR(v.(string)); err != nil { 290 return types.InternalErrorf("failed to decode ipvlan endpoint IPv6 address (%s) after json unmarshal: %v", v.(string), err) 291 } 292 } 293 ep.id = epMap["id"].(string) 294 ep.nid = epMap["nid"].(string) 295 ep.srcName = epMap["SrcName"].(string) 296 297 return nil 298} 299 300func (ep *endpoint) Key() []string { 301 return []string{ipvlanEndpointPrefix, ep.id} 302} 303 304func (ep *endpoint) KeyPrefix() []string { 305 return []string{ipvlanEndpointPrefix} 306} 307 308func (ep *endpoint) Value() []byte { 309 b, err := json.Marshal(ep) 310 if err != nil { 311 return nil 312 } 313 return b 314} 315 316func (ep *endpoint) SetValue(value []byte) error { 317 return json.Unmarshal(value, ep) 318} 319 320func (ep *endpoint) Index() uint64 { 321 return ep.dbIndex 322} 323 324func (ep *endpoint) SetIndex(index uint64) { 325 ep.dbIndex = index 326 ep.dbExists = true 327} 328 329func (ep *endpoint) Exists() bool { 330 return ep.dbExists 331} 332 333func (ep *endpoint) Skip() bool { 334 return false 335} 336 337func (ep *endpoint) New() datastore.KVObject { 338 return &endpoint{} 339} 340 341func (ep *endpoint) CopyTo(o datastore.KVObject) error { 342 dstEp := o.(*endpoint) 343 *dstEp = *ep 344 return nil 345} 346 347func (ep *endpoint) DataScope() string { 348 return datastore.LocalScope 349} 350