func CalculateOverlaySegment(underlayCIDR string, fan FanConfigEntry) (*net.IPNet, error) {
	_, underlayNet, err := net.ParseCIDR(underlayCIDR)
	if err != nil {
		return nil, errors.Trace(err)
	}
	subnetSize, _ := underlayNet.Mask.Size()
	underlaySize, _ := fan.Underlay.Mask.Size()
	if underlaySize <= subnetSize && fan.Underlay.Contains(underlayNet.IP) {
		overlaySize, _ := fan.Overlay.Mask.Size()
		newOverlaySize := overlaySize + (subnetSize - underlaySize)
		fanSize := uint(underlaySize - overlaySize)
		newFanIP := underlayNet.IP.To4()
		if newFanIP == nil {
			return nil, errors.New("fan address is not an IPv4 address.")
		}
		for i := 0; i < 4; i++ {
			newFanIP[i] &^= fan.Underlay.Mask[i]
		}
		numIp := binary.BigEndian.Uint32(newFanIP)
		numIp <<= fanSize
		binary.BigEndian.PutUint32(newFanIP, numIp)
		for i := 0; i < 4; i++ {
			newFanIP[i] += fan.Overlay.IP[i]
		}
		return &net.IPNet{IP: newFanIP, Mask: net.CIDRMask(newOverlaySize, 32)}, nil
	} else {
		return nil, nil
	}
}
// CalculateOverlaySegment takes underlay CIDR and FAN config entry and
// cuts the segment of overlay that corresponds to this underlay:
// eg. for FAN 172.31/16 -> 243/8 and physical subnet 172.31.64/20
// we get FAN subnet 243.64/12.
CalculateOverlaySegment takes underlay CIDR and FAN config entry and
cuts the segment of overlay that corresponds to this underlay:
eg.
// CalculateOverlaySegment takes underlay CIDR and FAN config entry and // cuts the segment of overlay that corresponds to this underlay : // eg . for FAN 172 . 31 / 16 - > 243 / 8 and physical subnet 172 . 31 . 64 / 20 // we get FAN subnet 243 . 64 / 12 .
func CalculateOverlaySegment(underlayCIDR string, fan FanConfigEntry) (*net.IPNet, error) {
	_, underlayNet, err := net.ParseCIDR(underlayCIDR)
	if err != nil {
		return nil, errors.Trace(err)
	}
	subnetSize, _ := underlayNet.Mask.Size()
	underlaySize, _ := fan.Underlay.Mask.Size()
	if underlaySize <= subnetSize && fan.Underlay.Contains(underlayNet.IP) {
		overlaySize, _ := fan.Overlay.Mask.Size()
		newOverlaySize := overlaySize + (subnetSize - underlaySize)
		fanSize := uint(underlaySize - overlaySize)
		newFanIP := underlayNet.IP.To4()
		if newFanIP == nil {
			return nil, errors.New("fan address is not an IPv4 address.")
		}
		for i := 0; i < 4; i++ {
			newFanIP[i] &^= fan.Underlay.Mask[i]
		}
		numIp := binary.BigEndian.Uint32(newFanIP)
		numIp <<= fanSize
		binary.BigEndian.PutUint32(newFanIP, numIp)
		for i := 0; i < 4; i++ {
			newFanIP[i] += fan.Overlay.IP[i]
		}
		return &net.IPNet{IP: newFanIP, Mask: net.CIDRMask(newOverlaySize, 32)}, nil
	} else {
		return nil, nil
	}
}
func CalculateOverlaySegment ( underlayCIDR string , fan FanConfigEntry ) ( * net . IPNet , error ) { _ , underlayNet , err := net . ParseCIDR ( underlayCIDR ) if err != nil { return nil , errors . Trace ( err ) } subnetSize , _ := underlayNet . Mask . Size ( ) underlaySize , _ := fan . Underlay . Mask . Size ( ) if underlaySize <= subnetSize && fan . Underlay . Contains ( underlayNet . IP ) { overlaySize , _ := fan . Overlay . Mask . Size ( ) newOverlaySize := overlaySize + ( subnetSize - underlaySize ) fanSize := uint ( underlaySize - overlaySize ) newFanIP := underlayNet . IP . To4 ( ) if newFanIP == nil { return nil , errors . New ( " " ) } for i := 0 ; i < 4 ; i ++ { newFanIP [ i ] &^= fan . Underlay . Mask [ i ] } numIp := binary . BigEndian . Uint32 ( newFanIP ) numIp <<= fanSize binary . BigEndian . PutUint32 ( newFanIP , numIp ) for i := 0 ; i < 4 ; i ++ { newFanIP [ i ] += fan . Overlay . IP [ i ] } return & net . IPNet { IP : newFanIP , Mask : net . CIDRMask ( newOverlaySize , 32 ) } , nil } else { return nil , nil } }
CalculateOverlaySegment takes underlay CIDR and FAN config entry and
cuts the segment of overlay that corresponds to this underlay:
eg.
CalculateOverlaySegment takes underlay CIDR and FAN config entry and cuts the segment of overlay that corresponds to this underlay : eg .