Skip to content

Commit

Permalink
modify ip count for dual
Browse files Browse the repository at this point in the history
  • Loading branch information
hongzhen-ma committed Feb 20, 2021
1 parent b4560b9 commit 3021743
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 43 deletions.
2 changes: 2 additions & 0 deletions pkg/controller/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,7 @@ func (c *Controller) initDefaultVlan() error {
}

func (c *Controller) initSyncCrdIPs() error {
klog.Info("start to sync ips")
ips, err := c.config.KubeOvnClient.KubeovnV1().IPs().List(context.Background(), metav1.ListOptions{})
if err != nil {
if k8serrors.IsNotFound(err) {
Expand Down Expand Up @@ -363,6 +364,7 @@ func (c *Controller) initSyncCrdIPs() error {
}

func (c *Controller) initSyncCrdSubnets() error {
klog.Info("start to sync subnets")
subnets, err := c.subnetsLister.List(labels.Everything())
if err != nil {
if k8serrors.IsNotFound(err) {
Expand Down
19 changes: 8 additions & 11 deletions pkg/controller/subnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -376,11 +376,8 @@ func checkAndUpdateExcludeIps(subnet *kubeovnv1.Subnet) bool {
} else {
for _, gw := range excludeIps {
gwExists := false
for _, ip := range ovs.ExpandExcludeIPs(subnet.Spec.ExcludeIps, subnet.Spec.CIDRBlock) {
if util.CheckProtocol(gw) != util.CheckProtocol(ip) {
continue
}
if ip == gw {
for _, excludeIP := range subnet.Spec.ExcludeIps {
if util.ContainsIPs(excludeIP, gw) {
gwExists = true
break
}
Expand Down Expand Up @@ -1020,8 +1017,8 @@ func calcDualSubnetStatusIP(subnet *kubeovnv1.Subnet, c *Controller) error {
v4ExcludeIps, v6ExcludeIps := util.SplitIpsByProtocol(subnet.Spec.ExcludeIps)
// gateway always in excludeIPs
cidrBlocks := strings.Split(subnet.Spec.CIDRBlock, ",")
v4toSubIPs := ovs.ExpandExcludeIPs(v4ExcludeIps, cidrBlocks[0])
v6toSubIPs := ovs.ExpandExcludeIPs(v6ExcludeIps, cidrBlocks[1])
v4toSubIPs := util.ExpandExcludeIPs(v4ExcludeIps, cidrBlocks[0])
v6toSubIPs := util.ExpandExcludeIPs(v6ExcludeIps, cidrBlocks[1])
_, v4CIDR, _ := net.ParseCIDR(cidrBlocks[0])
_, v6CIDR, _ := net.ParseCIDR(cidrBlocks[1])
v4UsingIPs := make([]string, 0, len(podUsedIPs.Items))
Expand All @@ -1036,11 +1033,11 @@ func calcDualSubnetStatusIP(subnet *kubeovnv1.Subnet, c *Controller) error {
v6UsingIPs = append(v6UsingIPs, splitIPs[1])
}
}
v4availableIPs := util.AddressCount(v4CIDR) - float64(len(util.UniqString(v4toSubIPs)))
v4availableIPs := util.AddressCount(v4CIDR) - float64(util.CountIpNums(v4toSubIPs))
if v4availableIPs < 0 {
v4availableIPs = 0
}
v6availableIPs := util.AddressCount(v6CIDR) - float64(len(util.UniqString(v6toSubIPs)))
v6availableIPs := util.AddressCount(v6CIDR) - float64(util.CountIpNums(v6toSubIPs))
if v6availableIPs < 0 {
v6availableIPs = 0
}
Expand Down Expand Up @@ -1072,11 +1069,11 @@ func calcSubnetStatusIP(subnet *kubeovnv1.Subnet, c *Controller) error {
return err
}
// gateway always in excludeIPs
toSubIPs := ovs.ExpandExcludeIPs(subnet.Spec.ExcludeIps, subnet.Spec.CIDRBlock)
toSubIPs := util.ExpandExcludeIPs(subnet.Spec.ExcludeIps, subnet.Spec.CIDRBlock)
for _, podUsedIP := range podUsedIPs.Items {
toSubIPs = append(toSubIPs, podUsedIP.Spec.IPAddress)
}
availableIPs := util.AddressCount(cidr) - float64(len(util.UniqString(toSubIPs)))
availableIPs := util.AddressCount(cidr) - float64(util.CountIpNums(toSubIPs))
if availableIPs < 0 {
availableIPs = 0
}
Expand Down
29 changes: 0 additions & 29 deletions pkg/ovs/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@ package ovs

import (
"fmt"
"math/big"
"strings"

"github.com/alauda/kube-ovn/pkg/util"
)

// PodNameToPortName return the ovn port name for a given pod
Expand All @@ -21,29 +18,3 @@ func trimCommandOutput(raw []byte) string {
output := strings.TrimSpace(string(raw))
return strings.Trim(output, "\"")
}

// ExpandExcludeIPs parse ovn exclude_ips to ip slice
func ExpandExcludeIPs(excludeIPs []string, cidr string) []string {
rv := []string{}
for _, excludeIP := range excludeIPs {
if strings.Index(excludeIP, "..") != -1 {
for _, cidrBlock := range strings.Split(cidr, ",") {
subnetNum := util.SubnetNumber(cidrBlock)
broadcast := util.SubnetBroadCast(cidrBlock)
parts := strings.Split(excludeIP, "..")
s := util.Ip2BigInt(parts[0])
e := util.Ip2BigInt(parts[1])
for s.Cmp(e) <= 0 {
ipStr := util.BigInt2Ip(s)
if ipStr != subnetNum && ipStr != broadcast && util.CIDRContainIP(cidrBlock, ipStr) && !util.ContainsString(rv, ipStr) {
rv = append(rv, ipStr)
}
s.Add(s, big.NewInt(1))
}
}
} else {
rv = append(rv, excludeIP)
}
}
return rv
}
92 changes: 92 additions & 0 deletions pkg/util/net.go
Original file line number Diff line number Diff line change
Expand Up @@ -314,3 +314,95 @@ func SplitStringIP(ipStr string) (string, string) {

return v4IP, v6IP
}

// How to distinguish repeat values
func ExpandExcludeIPs(excludeIPs []string, cidr string) []string {
rv := []string{}
for _, excludeIP := range excludeIPs {
if strings.Contains(excludeIP, "..") {
for _, cidrBlock := range strings.Split(cidr, ",") {
subnetNum := SubnetNumber(cidrBlock)
broadcast := SubnetBroadCast(cidrBlock)
parts := strings.Split(excludeIP, "..")
s := Ip2BigInt(parts[0])
e := Ip2BigInt(parts[1])

// limit range in cidr
firstIP, _ := FirstSubnetIP(cidrBlock)
lastIP, _ := LastIP(cidrBlock)
if s.Cmp(Ip2BigInt(firstIP)) < 0 {
s = Ip2BigInt(firstIP)
}
if e.Cmp(Ip2BigInt(lastIP)) > 0 {
e = Ip2BigInt(lastIP)
}

changed := false
// exclude cidr and broadcast address
if ContainsIPs(excludeIP, subnetNum) {
v := Ip2BigInt(subnetNum)
if s.Cmp(v) == 0 {
s.Add(s, big.NewInt(1))
rv = append(rv, BigInt2Ip(s)+".."+BigInt2Ip(e))
} else if e.Cmp(v) == 0 {
e.Sub(e, big.NewInt(1))
rv = append(rv, BigInt2Ip(s)+".."+BigInt2Ip(e))
} else {
var low, high big.Int
lowp := (&low).Sub(v, big.NewInt(1))
highp := (&high).Add(v, big.NewInt(1))
rv = append(rv, BigInt2Ip(s)+".."+BigInt2Ip(lowp))
rv = append(rv, BigInt2Ip(highp)+".."+BigInt2Ip(e))
}
changed = true
}
if ContainsIPs(excludeIP, broadcast) {
v := Ip2BigInt(broadcast)
v.Sub(v, big.NewInt(1))
rv = append(rv, BigInt2Ip(s)+".."+BigInt2Ip(v))
changed = true
}
if !changed && s.Cmp(e) < 0 {
rv = append(rv, BigInt2Ip(s)+".."+BigInt2Ip(e))
}
}
} else {
rv = append(rv, excludeIP)
}
}
klog.V(3).Infof("expand exclude ips %v", rv)
return rv
}

func ContainsIPs(excludeIP string, ip string) bool {
if strings.Contains(excludeIP, "..") {
parts := strings.Split(excludeIP, "..")
s := Ip2BigInt(parts[0])
e := Ip2BigInt(parts[1])
ipv := Ip2BigInt(ip)
if s.Cmp(ipv) <= 0 && e.Cmp(ipv) >= 0 {
return true
}
} else {
if excludeIP == ip {
return true
}
}
return false
}

func CountIpNums(excludeIPs []string) int64 {
var count int64
for _, excludeIP := range excludeIPs {
if strings.Contains(excludeIP, "..") {
var val big.Int
parts := strings.Split(excludeIP, "..")
s := Ip2BigInt(parts[0])
e := Ip2BigInt(parts[1])
count = val.Add(val.Sub(e, s), big.NewInt(1)).Int64()
} else {
count++
}
}
return count
}
6 changes: 3 additions & 3 deletions pkg/webhook/static_ip.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ func (v *ValidatingHook) PodCreateHook(ctx context.Context, req admission.Reques
if err != nil {
return ctrlwebhook.Errored(http.StatusBadRequest, err)
}
parsedExcludeIPs := ovs.ExpandExcludeIPs(excludeIPs, subnet.Spec.CIDRBlock)
parsedExcludeIPs := util.ExpandExcludeIPs(excludeIPs, subnet.Spec.CIDRBlock)
usedIPs = append(usedIPs, parsedExcludeIPs...)
// Check static ips overlap
if util.IsStringsOverlap([]string{staticIP}, usedIPs) {
Expand Down Expand Up @@ -318,7 +318,7 @@ func (v *ValidatingHook) podControllerCreate(ctx context.Context, staticIPSAnno,
if err != nil {
return ctrlwebhook.Errored(http.StatusBadRequest, err)
}
parsedExcludeIPs := ovs.ExpandExcludeIPs(excludeIPs, subnet.Spec.CIDRBlock)
parsedExcludeIPs := util.ExpandExcludeIPs(excludeIPs, subnet.Spec.CIDRBlock)
usedIPs = append(usedIPs, parsedExcludeIPs...)
// Check static ips overlap
if util.IsStringsOverlap(staticIPs, usedIPs) {
Expand Down Expand Up @@ -383,7 +383,7 @@ func (v *ValidatingHook) podControllerUpdate(ctx context.Context, oldStaticIPSAn
if err != nil {
return ctrlwebhook.Errored(http.StatusBadRequest, err)
}
parsedExcludeIPs := ovs.ExpandExcludeIPs(excludeIPs, subnet.Spec.CIDRBlock)
parsedExcludeIPs := util.ExpandExcludeIPs(excludeIPs, subnet.Spec.CIDRBlock)
// Check static ips overlap
if util.IsStringsOverlap(toAdd, parsedExcludeIPs) {
return ctrlwebhook.Denied("overlap")
Expand Down

0 comments on commit 3021743

Please sign in to comment.