// SVCAdd is the public method to add services. We assume the ID provided is not in // synced with the KVStore. If that's the case the service won't be used and an error is // returned to the caller. func (d *Daemon) SVCAdd(feL3n4Addr types.L3n4AddrID, beL3n4Addr []types.L3n4Addr, addRevNAT bool) error { if feL3n4Addr.ID == 0 { return fmt.Errorf("invalid service ID 0") } // Check if the service is already registered with this ID. feAddr, err := d.GetL3n4AddrID(uint32(feL3n4Addr.ID)) if err != nil { return fmt.Errorf("unable to get the service with ID %d: %s", feL3n4Addr.ID, err) } if feAddr == nil { feAddr, err = d.PutL3n4Addr(feL3n4Addr.L3n4Addr, uint32(feL3n4Addr.ID)) if err != nil { return fmt.Errorf("unable to put the service %s: %s", feL3n4Addr.L3n4Addr.String(), err) } // This won't be atomic so we need to check if the baseID, feL3n4Addr.ID was given to the service if feAddr.ID != feL3n4Addr.ID { return fmt.Errorf("the service provided %s is already registered with ID %d, please select that ID instead of %d", feL3n4Addr.L3n4Addr.String(), feAddr.ID, feL3n4Addr.ID) } } feAddr256Sum, err := feAddr.L3n4Addr.SHA256Sum() if err != nil { return fmt.Errorf("unable to calculate SHA256Sum of %s: %s", feAddr.String(), err) } feL3n4Addr256Sum, err := feL3n4Addr.L3n4Addr.SHA256Sum() if err != nil { return fmt.Errorf("unable to calculate SHA256Sum of %s: %s", feL3n4Addr.String(), err) } if feAddr256Sum != feL3n4Addr256Sum { return fmt.Errorf("service ID %d is already registered to service %s, please choose a different ID", feL3n4Addr.ID, feAddr.String()) } return d.svcAdd(feL3n4Addr, beL3n4Addr, addRevNAT) }