// LBInterfaceDown brings the load balancing interface down. func (ncc *SeesawNCC) LBInterfaceDown(iface *ncctypes.LBInterface, out *int) error { netIface, err := iface.Interface() if err != nil { return err } log.Infof("Bringing down LB interface %s", netIface.Name) return ifaceDown(netIface) }
// LBInterfaceUp brings the load balancing interface up. func (ncc *SeesawNCC) LBInterfaceUp(iface *ncctypes.LBInterface, out *int) error { // TODO(jsing): Handle IPv6-only, and improve IPv6 route setup. netIface, err := iface.Interface() if err != nil { return err } nodeIface, err := net.InterfaceByName(iface.NodeInterface) if err != nil { return fmt.Errorf("Failed to get node interface: %v", err) } nodeNet, err := findNetwork(nodeIface, iface.Node.IPv4Addr) if err != nil { return fmt.Errorf("Failed to get node network: %v", err) } log.Infof("Bringing up LB interface %s on %s", nodeNet, iface.Name) if !nodeNet.Contains(iface.ClusterVIP.IPv4Addr) { return fmt.Errorf("Node network %s does not contain cluster VIP %s", nodeNet, iface.ClusterVIP.IPv4Addr) } gateway, err := routeDefaultIPv4() if err != nil { return fmt.Errorf("Failed to get IPv4 default route: %v", err) } if err := ifaceUp(netIface); err != nil { return fmt.Errorf("Failed to bring interface up: %v", err) } // Configure routing. if err := ipRunIface(netIface, "route add %s dev %s table %d", nodeNet, iface.Name, iface.RoutingTableID); err != nil { return fmt.Errorf("Failed to configure routing: %v", err) } if err := ipRunIface(netIface, "route add 0/0 via %s dev %s table %d", gateway, iface.Name, iface.RoutingTableID); err != nil { return fmt.Errorf("Failed to configure routing: %v", err) } return nil }
// LBInterfaceInit initialises the load balancing interface for a Seesaw Node. func (ncc *SeesawNCC) LBInterfaceInit(iface *ncctypes.LBInterface, out *int) error { netIface, err := iface.Interface() if err != nil { return fmt.Errorf("Failed to get network interface: %v", err) } nodeIface, err := net.InterfaceByName(iface.NodeInterface) if err != nil { return fmt.Errorf("Failed to get node interface: %v", err) } if iface.RoutingTableID < 1 || iface.RoutingTableID > 250 { return fmt.Errorf("Invalid routing table ID: %d", iface.RoutingTableID) } vmac, err := net.ParseMAC(vrrpMAC) if err != nil { return fmt.Errorf("Failed to parse VRRP MAC %q: %v", vrrpMAC, err) } // The last byte of the VRRP MAC is determined by the VRID. vmac[len(vmac)-1] = iface.VRID netIface.HardwareAddr = vmac log.Infof("Initialising load balancing interface %s - VRID %d (VMAC %s)", iface.Name, iface.VRID, vmac) // Ensure interface is down and set VMAC address. if err := ifaceFastDown(netIface); err != nil { return fmt.Errorf("Failed to down interface: %v", err) } if err := ifaceSetMAC(netIface); err != nil { return fmt.Errorf("Failed to set MAC: %v", err) } // Remove VLAN interfaces associated with the load balancing interface. if err := ifaceFlushVLANs(netIface); err != nil { return fmt.Errorf("Failed to flush VLAN interfaces: %v", err) } // Configure sysctls for load balancing. if err := sysctlInitLB(nodeIface, netIface); err != nil { return fmt.Errorf("Failed to initialise sysctls: %v", err) } // Flush existing IP addresses and add cluster VIPs. if err := ifaceFlushIPAddr(netIface); err != nil { return fmt.Errorf("Failed to flush IP addresses: %v", err) } if iface.ClusterVIP.IPv4Addr != nil { if err := addClusterVIP(iface, netIface, nodeIface, iface.ClusterVIP.IPv4Addr); err != nil { return fmt.Errorf("Failed to add IPv4 cluster VIP: %v", err) } } if iface.ClusterVIP.IPv6Addr != nil { if err := addClusterVIP(iface, netIface, nodeIface, iface.ClusterVIP.IPv6Addr); err != nil { return fmt.Errorf("Failed to add IPv6 cluster VIP: %v", err) } } // Initialise iptables rules. if err := iptablesInit(iface.ClusterVIP); err != nil { return err } // Setup dummy interface. dummyIface, err := net.InterfaceByName(iface.DummyInterface) if err != nil { return fmt.Errorf("Failed to get dummy interface: %v", err) } if err := ifaceFastDown(dummyIface); err != nil { return fmt.Errorf("Failed to down dummy interface: %v", err) } if err := ifaceFlushIPAddr(dummyIface); err != nil { return fmt.Errorf("Failed to flush dummy interface: %v", err) } if err := ifaceUp(dummyIface); err != nil { return fmt.Errorf("Failed to up dummy interface: %v", err) } return nil }