diff --git a/loxinet/layer3.go b/loxinet/layer3.go index 1bcee3ef3..27aae5ec3 100644 --- a/loxinet/layer3.go +++ b/loxinet/layer3.go @@ -71,12 +71,20 @@ func L3Init(zone *Zone) *L3H { // IfaAdd - Adds an interface IP address (primary or secondary) and associate it with Obj // Obj can be anything but usually it is the name of a valid interface func (l3 *L3H) IfaAdd(Obj string, Cidr string) (int, error) { - var sec bool = false + sec := false addr, network, err := net.ParseCIDR(Cidr) if err != nil { return L3AddrErr, errors.New("ip address parse error") } + dev := fmt.Sprintf("llb-rule-%s", addr.String()) + if Obj != dev { + ret, _ := l3.IfaFind(dev, addr) + if ret == 0 { + l3.IfaDelete(dev, addr.String()+"/32") + } + } + ifObjID := -1 pObj := l3.Zone.Ports.PortFindByName(Obj) if pObj != nil { @@ -294,11 +302,11 @@ func (l3 *L3H) IfaSelect(Obj string, addr net.IP, findAny bool) (int, net.IP, st return L3AddrErr, net.IPv4(0, 0, 0, 0), "" } -// IfaFindAny - Given any ip address, check if it matches ip address in any ifa list +// IfaAddrLocal - Given any ip address, check if it matches ip address in any ifa list // This is useful to determine if ip address is already assigned to some interface -func (l3 *L3H) IfaFindAny(addr net.IP) (int, net.IP) { +func (l3 *L3H) IfaAddrLocal(addr net.IP) (int, net.IP) { for ifName := range l3.IfaMap { - ret, rAddr := l3.IfaFind(ifName.Obj, addr) + ret, rAddr := l3.IfaFindAddr(ifName.Obj, addr) if ret == 0 { return 0, rAddr } @@ -306,6 +314,31 @@ func (l3 *L3H) IfaFindAny(addr net.IP) (int, net.IP) { return L3AddrErr, nil } +// IfaFindAddr - Given any ip address, check if it matches ip address from Obj's ifa list +// This is useful to determine if ip address is already assigned to some interface +func (l3 *L3H) IfaFindAddr(Obj string, addr net.IP) (int, net.IP) { + + key := IfaKey{Obj} + ifa := l3.IfaMap[key] + + if ifa == nil { + return L3ObjErr, net.IPv4(0, 0, 0, 0) + } + + for _, ifaEnt := range ifa.Ifas { + + if tk.IsNetIPv6(addr.String()) && tk.IsNetIPv4(ifaEnt.IfaNet.IP.String()) { + continue + } + + if ifaEnt.IfaAddr.Equal(addr) { + return 0, ifaEnt.IfaAddr + } + } + + return L3AddrErr, net.IPv4(0, 0, 0, 0) +} + // IfaFind - Given any ip address, check if it matches ip address from Obj's ifa list // This is useful to determine if ip address is already assigned to some interface func (l3 *L3H) IfaFind(Obj string, addr net.IP) (int, net.IP) { diff --git a/loxinet/rules.go b/loxinet/rules.go index 3145b9282..203a2d57e 100644 --- a/loxinet/rules.go +++ b/loxinet/rules.go @@ -2589,9 +2589,9 @@ func (R *RuleH) AdvRuleVIPIfL2(IP net.IP) error { ciState, _ := mh.has.CIStateGetInst(cmn.CIDefault) if ciState == "MASTER" { dev := fmt.Sprintf("llb-rule-%s", IP.String()) - ret, _ := mh.zr.L3.IfaFind(dev, IP) + ret, _ := R.zone.L3.IfaFind(dev, IP) if ret == 0 { - mh.zr.L3.IfaDelete(dev, IP.String()+"/32") + R.zone.L3.IfaDelete(dev, IP.String()+"/32") } ev, _, iface := R.zone.L3.IfaSelectAny(IP, false) if ev == 0 { @@ -2624,12 +2624,14 @@ func (R *RuleH) AdvRuleVIPIfL2(IP net.IP) error { } } } else { - dev := fmt.Sprintf("llb-rule-%s", IP.String()) - ret, _ := mh.zr.L3.IfaFind(dev, IP) - if ret != 0 { - _, err := mh.zr.L3.IfaAdd(dev, IP.String()+"/32") - if err != nil { - fmt.Printf("Failed to add IP : %s:%s\n", dev, err) + if _, foundIP := R.zone.L3.IfaAddrLocal(IP); foundIP == nil { + dev := fmt.Sprintf("llb-rule-%s", IP.String()) + ret, _ := R.zone.L3.IfaFind(dev, IP) + if ret != 0 { + _, err := R.zone.L3.IfaAdd(dev, IP.String()+"/32") + if err != nil { + fmt.Printf("Failed to add IP : %s:%s\n", dev, err) + } } } }