Example #1
0
// 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)
}