-
Notifications
You must be signed in to change notification settings - Fork 431
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
efe3ee3
commit 91f76ed
Showing
7 changed files
with
661 additions
and
628 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,201 +1,36 @@ | ||
package ipam | ||
|
||
import ( | ||
"fmt" | ||
"math/big" | ||
"strings" | ||
|
||
"github.com/kubeovn/kube-ovn/pkg/util" | ||
"net" | ||
) | ||
|
||
type IP string | ||
type IP net.IP | ||
|
||
type IPRange struct { | ||
Start IP | ||
End IP | ||
func NewIP(s string) IP { | ||
return IP(net.ParseIP(s)) | ||
} | ||
|
||
func (a IP) Equal(b IP) bool { | ||
return a == b | ||
return net.IP(a).Equal(net.IP(b)) | ||
} | ||
|
||
func (a IP) LessThan(b IP) bool { | ||
return util.Ip2BigInt(string(a)).Cmp(util.Ip2BigInt(string(b))) == -1 | ||
return big.NewInt(0).SetBytes([]byte(a)).Cmp(big.NewInt(0).SetBytes([]byte(b))) < 0 | ||
} | ||
|
||
func (a IP) GreaterThan(b IP) bool { | ||
return util.Ip2BigInt(string(a)).Cmp(util.Ip2BigInt(string(b))) == 1 | ||
} | ||
|
||
func (a IP) Add(num int64) IP { | ||
return IP(util.BigInt2Ip(big.NewInt(0).Add(util.Ip2BigInt(string(a)), big.NewInt(num)))) | ||
} | ||
|
||
func (a IP) Sub(num int64) IP { | ||
return IP(util.BigInt2Ip(big.NewInt(0).Sub(util.Ip2BigInt(string(a)), big.NewInt(num)))) | ||
} | ||
|
||
func (ipr IPRange) IPExist(ip IP) bool { | ||
return (ipr.Start.LessThan(ip) || ipr.Start.Equal(ip)) && | ||
(ipr.End.GreaterThan(ip) || ipr.End.Equal(ip)) | ||
} | ||
|
||
type IPRangeList []*IPRange | ||
|
||
func (iprl IPRangeList) Contains(ip IP) bool { | ||
for _, ipr := range iprl { | ||
if ipr.IPExist(ip) { | ||
return true | ||
} | ||
} | ||
return false | ||
} | ||
|
||
func (iprl IPRangeList) Equal(iprl2 IPRangeList) bool { | ||
if len(iprl) != len(iprl2) { | ||
return false | ||
} | ||
|
||
for i, range1 := range iprl { | ||
range2 := iprl2[i] | ||
if !range1.Start.Equal(range2.Start) || !range1.End.Equal(range2.End) { | ||
return false | ||
} | ||
} | ||
|
||
return true | ||
} | ||
|
||
func (iprl IPRangeList) IpRangetoString() string { | ||
var ipRangeString []string | ||
for _, ipr := range iprl { | ||
if ipr.Start.Equal(ipr.End) { | ||
ipRangeString = append(ipRangeString, string(ipr.Start)) | ||
} else { | ||
ipRangeString = append(ipRangeString, fmt.Sprintf("%s-%s", ipr.Start, ipr.End)) | ||
} | ||
} | ||
return strings.Join(ipRangeString, ",") | ||
return big.NewInt(0).SetBytes([]byte(a)).Cmp(big.NewInt(0).SetBytes([]byte(b))) > 0 | ||
} | ||
|
||
func splitIPRangeList(iprl IPRangeList, ip IP) (bool, IPRangeList) { | ||
newIPRangeList := []*IPRange{} | ||
split := false | ||
for _, ipr := range iprl { | ||
if split { | ||
newIPRangeList = append(newIPRangeList, ipr) | ||
continue | ||
} | ||
|
||
if ipr.Start.Equal(ipr.End) && ipr.Start.Equal(ip) { | ||
split = true | ||
continue | ||
} | ||
|
||
if ipr.Start.Equal(ip) { | ||
newIPRangeList = append(newIPRangeList, &IPRange{Start: ip.Add(1), End: ipr.End}) | ||
split = true | ||
continue | ||
} | ||
|
||
if ipr.End.Equal(ip) { | ||
newIPRangeList = append(newIPRangeList, &IPRange{Start: ipr.Start, End: ip.Add(-1)}) | ||
split = true | ||
continue | ||
} | ||
|
||
if ipr.IPExist(ip) { | ||
newIpr1 := IPRange{Start: ipr.Start, End: ip.Add(-1)} | ||
newIpr2 := IPRange{Start: ip.Add(1), End: ipr.End} | ||
newIPRangeList = append(newIPRangeList, &newIpr1, &newIpr2) | ||
split = true | ||
continue | ||
} | ||
|
||
newIPRangeList = append(newIPRangeList, ipr) | ||
} | ||
return split, newIPRangeList | ||
} | ||
|
||
func mergeIPRangeList(iprl IPRangeList, ip IP) (bool, IPRangeList) { | ||
insertIPRangeList := []*IPRange{} | ||
inserted := false | ||
if iprl.Contains(ip) { | ||
return false, nil | ||
} | ||
|
||
for _, ipr := range iprl { | ||
if inserted || ipr.Start.LessThan(ip) { | ||
insertIPRangeList = append(insertIPRangeList, ipr) | ||
continue | ||
} | ||
|
||
if ipr.Start.GreaterThan(ip) { | ||
insertIPRangeList = append(insertIPRangeList, &IPRange{Start: ip, End: ip}, ipr) | ||
inserted = true | ||
continue | ||
} | ||
} | ||
if !inserted { | ||
newIpr := IPRange{Start: ip, End: ip} | ||
insertIPRangeList = append(insertIPRangeList, &newIpr) | ||
} | ||
|
||
mergedIPRangeList := []*IPRange{} | ||
for _, ipr := range insertIPRangeList { | ||
if len(mergedIPRangeList) == 0 { | ||
mergedIPRangeList = append(mergedIPRangeList, ipr) | ||
continue | ||
} | ||
|
||
if mergedIPRangeList[len(mergedIPRangeList)-1].End.Add(1).Equal(ipr.Start) { | ||
mergedIPRangeList[len(mergedIPRangeList)-1].End = ipr.End | ||
} else { | ||
mergedIPRangeList = append(mergedIPRangeList, ipr) | ||
} | ||
} | ||
|
||
return true, mergedIPRangeList | ||
func (a IP) Add(n int64) IP { | ||
return IP(big.NewInt(0).Add(big.NewInt(0).SetBytes([]byte(a)), big.NewInt(n)).Bytes()) | ||
} | ||
|
||
func convertExcludeIps(excludeIps []string) IPRangeList { | ||
newIPRangeList := make([]*IPRange, 0, len(excludeIps)) | ||
for _, ex := range excludeIps { | ||
ips := strings.Split(ex, "..") | ||
if len(ips) == 1 { | ||
ipr := IPRange{Start: IP(ips[0]), End: IP(ips[0])} | ||
newIPRangeList = append(newIPRangeList, &ipr) | ||
} else { | ||
ipr := IPRange{Start: IP(ips[0]), End: IP(ips[1])} | ||
newIPRangeList = append(newIPRangeList, &ipr) | ||
} | ||
} | ||
return newIPRangeList | ||
func (a IP) Sub(n int64) IP { | ||
return IP(big.NewInt(0).Sub(big.NewInt(0).SetBytes([]byte(a)), big.NewInt(n)).Bytes()) | ||
} | ||
|
||
func splitRange(a, b *IPRange) IPRangeList { | ||
if b.End.LessThan(a.Start) || b.Start.GreaterThan(a.End) { | ||
return IPRangeList{a} | ||
} | ||
|
||
if (a.Start.Equal(b.Start) || a.Start.GreaterThan(b.Start)) && | ||
(a.End.Equal(b.End) || a.End.LessThan(b.End)) { | ||
return nil | ||
} | ||
|
||
if (a.Start.Equal(b.Start) || a.Start.GreaterThan(b.Start)) && | ||
a.End.GreaterThan(b.End) { | ||
ipr := IPRange{Start: b.End.Add(1), End: a.End} | ||
return IPRangeList{&ipr} | ||
} | ||
|
||
if (a.End.Equal(b.End) || a.End.LessThan(b.End)) && | ||
a.Start.LessThan(b.Start) { | ||
ipr := IPRange{Start: a.Start, End: b.Start.Add(-1)} | ||
return IPRangeList{&ipr} | ||
} | ||
|
||
ipr1 := IPRange{Start: a.Start, End: b.Start.Add(-1)} | ||
ipr2 := IPRange{Start: b.End.Add(1), End: a.End} | ||
return IPRangeList{&ipr1, &ipr2} | ||
func (a IP) String() string { | ||
return net.IP(a).String() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
package ipam | ||
|
||
import ( | ||
"fmt" | ||
) | ||
|
||
// IPRange represents an IP range of [start, end] | ||
type IPRange struct { | ||
start, end IP | ||
} | ||
|
||
func NewIPRange(start, end IP) *IPRange { | ||
return &IPRange{start, end} | ||
} | ||
|
||
func (r *IPRange) Clone() *IPRange { | ||
return NewIPRange(r.start, r.end) | ||
} | ||
|
||
func (r *IPRange) Start() IP { | ||
return r.start | ||
} | ||
|
||
func (r *IPRange) End() IP { | ||
return r.end | ||
} | ||
|
||
func (r *IPRange) SetStart(ip IP) { | ||
r.start = ip | ||
} | ||
|
||
func (r *IPRange) SetEnd(ip IP) { | ||
r.end = ip | ||
} | ||
|
||
func (r *IPRange) Contains(ip IP) bool { | ||
return !r.start.GreaterThan(ip) && !r.end.LessThan(ip) | ||
} | ||
|
||
func (r *IPRange) Add(ip IP) bool { | ||
if newStart := r.start.Sub(1); newStart.Equal(ip) { | ||
r.start = newStart | ||
return true | ||
} | ||
if newEnd := r.end.Add(1); newEnd.Equal(ip) { | ||
r.end = newEnd | ||
return true | ||
} | ||
|
||
return false | ||
} | ||
|
||
func (r *IPRange) Remove(ip IP) ([]*IPRange, bool) { | ||
if !r.Contains(ip) { | ||
return nil, false | ||
} | ||
|
||
ret := make([]*IPRange, 0, 2) | ||
r1 := NewIPRange(r.start, ip.Sub(1)) | ||
r2 := NewIPRange(ip.Add(1), r.end) | ||
if !r1.start.GreaterThan(r1.end) { | ||
ret = append(ret, r1) | ||
} | ||
if !r2.start.GreaterThan(r2.end) { | ||
ret = append(ret, r2) | ||
} | ||
|
||
return ret, true | ||
} | ||
|
||
func (r *IPRange) String() string { | ||
if r.start.Equal(r.end) { | ||
return string(r.start) | ||
} | ||
return fmt.Sprintf("%s..%s", r.start, r.end) | ||
} |
Oops, something went wrong.