// RequestPort requests new port from global ports pool for specified ip and proto. // If port is 0 it returns first free port. Otherwise it cheks port availability // in pool and return that port or error if port is already busy. func RequestPort(ip net.IP, proto string, port int) (int, error) { mutex.Lock() defer mutex.Unlock() if proto != "tcp" && proto != "udp" { return 0, ErrUnknownProtocol } if ip == nil { ip = defaultIP } ipstr := ip.String() protomap, ok := globalMap[ipstr] if !ok { protomap = newProtoMap() globalMap[ipstr] = protomap } mapping := protomap[proto] if port > 0 { if _, ok := mapping.p[port]; !ok { mapping.p[port] = struct{}{} return port, nil } return 0, NewErrPortAlreadyAllocated(ipstr, port) } port, err := mapping.findPort() if err != nil { return 0, err } return port, nil }
func (n *network) deleteSvcRecords(name string, epIP net.IP, ipMapUpdate bool) { c := n.getController() c.Lock() defer c.Unlock() sr, ok := c.svcDb[n.ID()] if !ok { return } if ipMapUpdate { delete(sr.ipMap, netutils.ReverseIP(epIP.String())) } ipList := sr.svcMap[name] for i, ip := range ipList { if ip.Equal(epIP) { ipList = append(ipList[:i], ipList[i+1:]...) break } } sr.svcMap[name] = ipList if len(ipList) == 0 { delete(sr.svcMap, name) } }
// NodeAddresses returns the NodeAddresses of the instance with the specified nodeName. func (v *OVirtCloud) NodeAddresses(nodeName types.NodeName) ([]api.NodeAddress, error) { name := mapNodeNameToInstanceName(nodeName) instance, err := v.fetchInstance(name) if err != nil { return nil, err } var address net.IP if instance.IPAddress != "" { address = net.ParseIP(instance.IPAddress) if address == nil { return nil, fmt.Errorf("couldn't parse address: %s", instance.IPAddress) } } else { resolved, err := net.LookupIP(name) if err != nil || len(resolved) < 1 { return nil, fmt.Errorf("couldn't lookup address: %s", name) } address = resolved[0] } return []api.NodeAddress{ {Type: api.NodeLegacyHostIP, Address: address.String()}, {Type: api.NodeInternalIP, Address: address.String()}, {Type: api.NodeExternalIP, Address: address.String()}, }, nil }
// findLoopbackDevice iterates through all the interfaces on a machine and // returns the ip addr, mask of the loopback device func (a *Agent) findLoopbackDevice() (string, string, string, error) { var ifcs []net.Interface var err error ifcs, err = net.Interfaces() if err != nil { return "", "", "", err } for _, ifc := range ifcs { addrs, err := ifc.Addrs() if err != nil { return "", "", "", err } for _, addr := range addrs { var ip net.IP switch v := addr.(type) { case *net.IPNet: ip = v.IP case *net.IPAddr: ip = v.IP } if ip.IsLoopback() { if ip.To4() == nil { continue } return ifc.Name, ip.String(), addr.String(), nil } } } return "", "", "", fmt.Errorf("no loopback devices with IPV4 addr found") }
func interfaceGot(index int, pciAddr int, name string, inf *network.Settings) (*InterfaceCreated, error) { ip, nw, err := net.ParseCIDR(fmt.Sprintf("%s/%d", inf.IPAddress, inf.IPPrefixLen)) if err != nil { glog.Error("can not parse cidr") return &InterfaceCreated{Index: index, PCIAddr: pciAddr, DeviceName: name}, err } var tmp []byte = nw.Mask var mask net.IP = tmp rt := []*RouteRule{} /* Route rule is generated automaticly on first interface, * or generated on the gateway configured interface. */ if (index == 0 && inf.Automatic) || (!inf.Automatic && inf.Gateway != "") { rt = append(rt, &RouteRule{ Destination: "0.0.0.0/0", Gateway: inf.Gateway, ViaThis: true, }) } return &InterfaceCreated{ Index: index, PCIAddr: pciAddr, Bridge: inf.Bridge, HostDevice: inf.Device, DeviceName: name, Fd: inf.File, MacAddr: inf.Mac, IpAddr: ip.String(), NetMask: mask.String(), RouteTable: rt, }, nil }
// Allocate a network interface func Allocate(job *engine.Job) engine.Status { var ( ip *net.IP err error id = job.Args[0] requestedIP = net.ParseIP(job.Getenv("RequestedIP")) ) if requestedIP != nil { ip, err = ipallocator.RequestIP(bridgeNetwork, &requestedIP) } else { ip, err = ipallocator.RequestIP(bridgeNetwork, nil) } if err != nil { return job.Error(err) } out := engine.Env{} out.Set("IP", ip.String()) out.Set("Mask", bridgeNetwork.Mask.String()) out.Set("Gateway", bridgeNetwork.IP.String()) out.Set("Bridge", bridgeIface) size, _ := bridgeNetwork.Mask.Size() out.SetInt("IPPrefixLen", size) currentInterfaces.Set(id, &networkInterface{ IP: *ip, }) out.WriteTo(job.Stdout) return engine.StatusOK }
// Build a slice of iptables args that are common to from-container and from-host portal rules. func iptablesCommonPortalArgs(destIP net.IP, addPhysicalInterfaceMatch bool, addDstLocalMatch bool, destPort int, protocol api.Protocol, service proxy.ServicePortName) []string { // This list needs to include all fields as they are eventually spit out // by iptables-save. This is because some systems do not support the // 'iptables -C' arg, and so fall back on parsing iptables-save output. // If this does not match, it will not pass the check. For example: // adding the /32 on the destination IP arg is not strictly required, // but causes this list to not match the final iptables-save output. // This is fragile and I hope one day we can stop supporting such old // iptables versions. args := []string{ "-m", "comment", "--comment", service.String(), "-p", strings.ToLower(string(protocol)), "-m", strings.ToLower(string(protocol)), "--dport", fmt.Sprintf("%d", destPort), } if destIP != nil { args = append(args, "-d", fmt.Sprintf("%s/32", destIP.String())) } if addPhysicalInterfaceMatch { args = append(args, "-m", "physdev", "!", "--physdev-is-in") } if addDstLocalMatch { args = append(args, "-m", "addrtype", "--dst-type", "LOCAL") } return args }
func (d *driver) resolvePeer(nid string, peerIP net.IP) (net.HardwareAddr, net.IPMask, net.IP, error) { qPayload := fmt.Sprintf("%s %s", string(nid), peerIP.String()) resp, err := d.serfInstance.Query("peerlookup", []byte(qPayload), nil) if err != nil { return nil, nil, nil, fmt.Errorf("resolving peer by querying the cluster failed: %v", err) } respCh := resp.ResponseCh() select { case r := <-respCh: var macStr, maskStr, vtepStr string if _, err := fmt.Sscan(string(r.Payload), &macStr, &maskStr, &vtepStr); err != nil { return nil, nil, nil, fmt.Errorf("bad response %q for the resolve query: %v", string(r.Payload), err) } mac, err := net.ParseMAC(macStr) if err != nil { return nil, nil, nil, fmt.Errorf("failed to parse mac: %v", err) } return mac, net.IPMask(net.ParseIP(maskStr).To4()), net.ParseIP(vtepStr), nil case <-time.After(time.Second): return nil, nil, nil, fmt.Errorf("timed out resolving peer by querying the cluster") } }
// GetIfacesByIP searches for and returns the interfaces with the given IP // Disregards the subnet mask since not every net.IP object contains // On success it will return the list of found interfaces func (n *Networking) GetIfacesByIP(ifaceIP net.IP) ([]net.Interface, error) { ifaces, err := net.Interfaces() if err != nil { return nil, err } searchAddr := strings.Split(ifaceIP.String(), "/")[0] resultInterfaces := make([]net.Interface, 0) for _, iface := range ifaces { if iface.Flags&net.FlagLoopback != 0 { continue } addrs, err := iface.Addrs() if err != nil { return nil, errwrap.Wrap(fmt.Errorf("cannot get addresses for interface %v", iface.Name), err) } for _, addr := range addrs { currentAddr := strings.Split(addr.String(), "/")[0] if searchAddr == currentAddr { resultInterfaces = append(resultInterfaces, iface) break } } } if len(resultInterfaces) == 0 { return nil, fmt.Errorf("no interface found with IP %q", ifaceIP) } return resultInterfaces, nil }
func get_ips() ([]string, error) { ips := make([]string, 0) ifaces, err := net.Interfaces() if err != nil { log.Println(err) return ips, nil } for _, iface := range ifaces { // log.Println(iface.Name) addrs, err := iface.Addrs() if err != nil { return ips, nil } for _, addr := range addrs { // log.Println(addr.Network(), addr.String()) var ip net.IP switch v := addr.(type) { case *net.IPNet: ip = v.IP case *net.IPAddr: ip = v.IP } // 只保留ipv4地址 if ip.To4() != nil && ip.String() != "127.0.0.1" { ips = append(ips, ip.String()) } } } return ips, nil }
func lookup(stmt *sql.Stmt, IP net.IP, nIP uint32) (*GeoIP, error) { var reserved bool for _, net := range reservedIPs { if net.Contains(IP) { reserved = true break } } geoip := GeoIP{Ip: IP.String()} if reserved { geoip.CountryCode = "RD" geoip.CountryName = "Reserved" } else { if err := stmt.QueryRow(nIP).Scan( &geoip.CountryCode, &geoip.CountryName, &geoip.RegionCode, &geoip.RegionName, &geoip.CityName, &geoip.ZipCode, &geoip.Latitude, &geoip.Longitude, &geoip.MetroCode, &geoip.AreaCode, ); err != nil { return nil, err } } return &geoip, nil }
// Request answers a dhcp request // Uses etcd as backend // part of DHCPDataSource interface implementation func (ds *EtcdDataSource) Request(nic string, currentIP net.IP) (net.IP, error) { ds.lockDHCPAssign() defer ds.unlockdhcpAssign() machines, _ := ds.Machines() macExists, ipExists := false, false for _, node := range machines { thisNodeIP, _ := node.IP() ipMatch := thisNodeIP.String() == currentIP.String() macMatch := nic == node.Mac().String() if ipMatch && macMatch { ds.store(node, thisNodeIP) return currentIP, nil } ipExists = ipExists || ipMatch macExists = macExists || macMatch } if ipExists || macExists { return nil, errors.New("Missmatch in lease pool") } macAddress, _ := net.ParseMAC(nic) ds.CreateMachine(macAddress, currentIP) return currentIP, nil }
func (n *network) addSvcRecords(name string, epIP net.IP, ipMapUpdate bool) { c := n.getController() c.Lock() defer c.Unlock() sr, ok := c.svcDb[n.ID()] if !ok { sr = svcInfo{ svcMap: make(map[string][]net.IP), ipMap: make(map[string]string), } c.svcDb[n.ID()] = sr } if ipMapUpdate { reverseIP := netutils.ReverseIP(epIP.String()) if _, ok := sr.ipMap[reverseIP]; !ok { sr.ipMap[reverseIP] = name } } ipList := sr.svcMap[name] for _, ip := range ipList { if ip.Equal(epIP) { return } } sr.svcMap[name] = append(sr.svcMap[name], epIP) }
func newProxyCommand(proto string, hostIP net.IP, hostPort int, containerIP net.IP, containerPort int, proxyPath string) (userlandProxy, error) { path := proxyPath if proxyPath == "" { cmd, err := exec.LookPath(userlandProxyCommandName) if err != nil { return nil, err } path = cmd } args := []string{ path, "-proto", proto, "-host-ip", hostIP.String(), "-host-port", strconv.Itoa(hostPort), "-container-ip", containerIP.String(), "-container-port", strconv.Itoa(containerPort), } return &proxyCommand{ cmd: &exec.Cmd{ Path: path, Args: args, SysProcAttr: &syscall.SysProcAttr{ Pdeathsig: syscall.SIGTERM, // send a sigterm to the proxy if the daemon process dies }, }, }, nil }
// 一个接口上的所有ip4地址 func addrsOfOneInterface(iface net.Interface) (addrs []*net.IPAddr) { ifaddrs, err := iface.Addrs() if (err != nil) || (len(ifaddrs) == 0) { return } for _, ifaddr := range ifaddrs { var ip net.IP switch v := ifaddr.(type) { case *net.IPNet: ip = v.IP case *net.IPAddr: ip = v.IP default: continue } if ip.IsLoopback() { return } ip = ip.To4() if ip != nil { addr, _ := net.ResolveIPAddr("ip", ip.String()) addrs = append(addrs, addr) } } return }
// // 获取带有指定Prefix的Ip // func GetIpWithPrefix(prefix string) string { ifaces, _ := net.Interfaces() // handle err for _, i := range ifaces { addrs, _ := i.Addrs() // handle err for _, addr := range addrs { var ip net.IP switch v := addr.(type) { case *net.IPNet: ip = v.IP case *net.IPAddr: ip = v.IP } ipAddr := ip.String() // fmt.Println("ipAddr: ", ipAddr) if strings.HasPrefix(ipAddr, prefix) { return ipAddr } } } return "" }
// Gets the ipv4 addr for a network interface func (f *NetworkFingerprint) ipAddress(intf *net.Interface) (string, error) { var addrs []net.Addr var err error if addrs, err = f.interfaceDetector.Addrs(intf); err != nil { return "", err } if len(addrs) == 0 { return "", errors.New(fmt.Sprintf("Interface %s has no IP address", intf.Name)) } for _, addr := range addrs { var ip net.IP switch v := (addr).(type) { case *net.IPNet: ip = v.IP case *net.IPAddr: ip = v.IP } if ip.To4() != nil { return ip.String(), nil } } return "", fmt.Errorf("Couldn't parse IP address for interface %s", intf.Name) }
// CreateMasterServiceIfNeeded will create the specified service if it // doesn't already exist. func (c *Controller) CreateMasterServiceIfNeeded(serviceName string, serviceIP net.IP, servicePort int) error { ctx := api.NewDefaultContext() if _, err := c.ServiceRegistry.GetService(ctx, serviceName); err == nil { // The service already exists. return nil } svc := &api.Service{ ObjectMeta: api.ObjectMeta{ Name: serviceName, Namespace: api.NamespaceDefault, Labels: map[string]string{"provider": "kubernetes", "component": "apiserver"}, }, Spec: api.ServiceSpec{ Ports: []api.ServicePort{{Port: servicePort, Protocol: api.ProtocolTCP, TargetPort: util.NewIntOrStringFromInt(servicePort)}}, // maintained by this code, not by the pod selector Selector: nil, ClusterIP: serviceIP.String(), SessionAffinity: api.ServiceAffinityNone, Type: api.ServiceTypeClusterIP, }, } if err := rest.BeforeCreate(rest.Services, ctx, svc); err != nil { return err } _, err := c.ServiceRegistry.CreateService(ctx, svc) if err != nil && errors.IsAlreadyExists(err) { err = nil } return err }
// Build a slice of iptables args for a portal rule. func iptablesPortalArgs(destIP net.IP, destPort int, protocol api.Protocol, proxyIP net.IP, proxyPort int, service string) []string { args := []string{ "-m", "comment", "--comment", service, "-p", strings.ToLower(string(protocol)), "-d", destIP.String(), "--dport", fmt.Sprintf("%d", destPort), } // This is tricky. If the proxy is bound (see Proxier.listenAddress) // to 0.0.0.0 ("any interface") or 127.0.0.1, we can use REDIRECT, // which will bring packets back to the host's loopback interface. If // the proxy is bound to any other interface, then it is not listening // on the hosts's loopback, so we have to use DNAT to that specific // IP. We can not simply use DNAT to 127.0.0.1 in the first case // because from within a container, 127.0.0.1 is the container's // loopback interface, not the host's. // // Why would anyone bind to an address that is not inclusive of // localhost? Apparently some cloud environments have their public IP // exposed as a real network interface AND do not have firewalling. We // don't want to expose everything out to the world. // // Unfortunately, I don't know of any way to listen on some (N > 1) // interfaces but not ALL interfaces, short of doing it manually, and // this is simpler than that. if proxyIP.Equal(zeroIP) || proxyIP.Equal(localhostIP) { args = append(args, "-j", "REDIRECT", "--to-ports", fmt.Sprintf("%d", proxyPort)) } else { args = append(args, "-j", "DNAT", "--to-destination", fmt.Sprintf("%s:%d", proxyIP.String(), proxyPort)) } return args }
// setEndpoints sets the endpoints for the given service. // in a multi-master scenario only the master will be publishing an endpoint. // see SchedulerServer.bootstrap. func (m *SchedulerServer) setEndpoints(serviceName string, ip net.IP, port int) error { // The setting we want to find. want := []api.EndpointSubset{{ Addresses: []api.EndpointAddress{{IP: ip.String()}}, Ports: []api.EndpointPort{{Port: port, Protocol: api.ProtocolTCP}}, }} ctx := api.NewDefaultContext() e, err := m.client.Endpoints(api.NamespaceValue(ctx)).Get(serviceName) createOrUpdate := m.client.Endpoints(api.NamespaceValue(ctx)).Update if err != nil { if errors.IsNotFound(err) { createOrUpdate = m.client.Endpoints(api.NamespaceValue(ctx)).Create } e = &api.Endpoints{ ObjectMeta: api.ObjectMeta{ Name: serviceName, Namespace: api.NamespaceDefault, }, } } if !reflect.DeepEqual(e.Subsets, want) { e.Subsets = want glog.Infof("setting endpoints for master service %q to %#v", serviceName, e) _, err = createOrUpdate(e) return err } // We didn't make any changes, no need to actually call update. return nil }
// Marks a port as being owned by a particular service, or returns error if already claimed. // Idempotent: reclaiming with the same owner is not an error func (proxier *Proxier) claimNodePort(ip net.IP, port int, protocol api.Protocol, owner proxy.ServicePortName) error { proxier.portMapMutex.Lock() defer proxier.portMapMutex.Unlock() // TODO: We could pre-populate some reserved ports into portMap and/or blacklist some well-known ports key := portMapKey{ip: ip.String(), port: port, protocol: protocol} existing, found := proxier.portMap[key] if !found { // Hold the actual port open, even though we use iptables to redirect // it. This ensures that a) it's safe to take and b) that stays true. // NOTE: We should not need to have a real listen()ing socket - bind() // should be enough, but I can't figure out a way to e2e test without // it. Tools like 'ss' and 'netstat' do not show sockets that are // bind()ed but not listen()ed, and at least the default debian netcat // has no way to avoid about 10 seconds of retries. socket, err := newProxySocket(protocol, ip, port) if err != nil { return fmt.Errorf("can't open node port for %s: %v", key.String(), err) } proxier.portMap[key] = &portMapValue{owner: owner, socket: socket} glog.V(2).Infof("Claimed local port %s", key.String()) return nil } if existing.owner == owner { // We are idempotent return nil } return fmt.Errorf("Port conflict detected on port %s. %v vs %v", key.String(), owner, existing) }
func GetServerIP() string { ifaces, err := net.Interfaces() if err != nil { log.Panic("Can't acess the network interfaces.") } var ip net.IP for _, i := range ifaces { addrs, err := i.Addrs() if err != nil { log.Panic("Can't read the IP.") } for _, addr := range addrs { switch v := addr.(type) { case *net.IPNet: //log.Printf("Evaluating IPNet: %v\r\n", v.IP) if (v.IP.To4() != nil) && !v.IP.IsLinkLocalUnicast() && !v.IP.IsLoopback() && !v.IP.IsMulticast() { ip = v.IP } case *net.IPAddr: //log.Printf("Evaluating IPAddr: %v\r\n", v.IP) if (v.IP.To4() != nil) && !v.IP.IsLinkLocalUnicast() && !v.IP.IsLoopback() && !v.IP.IsMulticast() { ip = v.IP } } } } // process IP address return ip.String() }
// Build a slice of iptables args for a from-host portal rule. func (proxier *Proxier) iptablesHostPortalArgs(destIP net.IP, addDstLocalMatch bool, destPort int, protocol api.Protocol, proxyIP net.IP, proxyPort int, service proxy.ServicePortName) []string { args := iptablesCommonPortalArgs(destIP, false, addDstLocalMatch, destPort, protocol, service) // This is tricky. // // If the proxy is bound (see Proxier.listenIP) to 0.0.0.0 ("any // interface") we want to do the same as from-container traffic and use // REDIRECT. Except that it doesn't work (empirically). REDIRECT on // local packets sends the traffic to localhost (special case, but it is // documented) but the response comes from the eth0 IP (not sure why, // truthfully), which makes DNS unhappy. // // So we have to use DNAT. DNAT to 127.0.0.1 can't work for the same // reason. // // So we do our best to find an interface that is not a loopback and // DNAT to that. This works (again, empirically). // // If the proxy is bound to a specific IP, then we have to use DNAT to // that IP. Unlike the previous case, this works because the proxy is // ONLY listening on that IP, not the bridge. // // If the proxy is bound to localhost only, this should work, but we // don't allow it for now. if proxyIP.Equal(zeroIPv4) || proxyIP.Equal(zeroIPv6) { proxyIP = proxier.hostIP } // TODO: Can we DNAT with IPv6? args = append(args, "-j", "DNAT", "--to-destination", net.JoinHostPort(proxyIP.String(), strconv.Itoa(proxyPort))) return args }
func newProxySocket(protocol api.Protocol, ip net.IP, port int) (proxySocket, error) { host := "" if ip != nil { host = ip.String() } switch strings.ToUpper(string(protocol)) { case "TCP": listener, err := net.Listen("tcp", net.JoinHostPort(host, strconv.Itoa(port))) if err != nil { return nil, err } return &tcpProxySocket{Listener: listener, port: port}, nil case "UDP": addr, err := net.ResolveUDPAddr("udp", net.JoinHostPort(host, strconv.Itoa(port))) if err != nil { return nil, err } conn, err := net.ListenUDP("udp", addr) if err != nil { return nil, err } return &udpProxySocket{UDPConn: conn, port: port}, nil } return nil, fmt.Errorf("unknown protocol %q", protocol) }
func (s *Session) handleNodeUp(ip net.IP, port int, waitForBinary bool) { if gocqlDebug { log.Printf("gocql: Session.handleNodeUp: %s:%d\n", ip.String(), port) } addr := ip.String() host := s.ring.getHost(addr) if host != nil { if s.cfg.IgnorePeerAddr && host.Peer() != addr { host.setPeer(addr) } if s.cfg.HostFilter != nil { if !s.cfg.HostFilter.Accept(host) { return } } else if !s.cfg.Discovery.matchFilter(host) { // TODO: remove this when the host selection policy is more sophisticated return } if t := host.Version().nodeUpDelay(); t > 0 && waitForBinary { time.Sleep(t) } host.setPort(port) s.pool.hostUp(host) s.policy.HostUp(host) host.setState(NodeUp) return } s.handleNewNode(ip, port, waitForBinary) }
func getIP() string { ifaces, err := net.Interfaces() if err != nil { logger.WithField("_block", "getIP").Error(err) return "127.0.0.1" } for _, i := range ifaces { addrs, err := i.Addrs() if err != nil { logger.WithField("_block", "getIP").Error(err) return "127.0.0.1" } for _, addr := range addrs { var ip net.IP switch v := addr.(type) { case *net.IPAddr: ip = v.IP case *net.IPNet: ip = v.IP } if ip == nil || ip.IsLoopback() { continue } ip = ip.To4() if ip == nil { continue // not an ipv4 address } return ip.String() } } return "127.0.0.1" }
func removeEncryption(localIP, remoteIP net.IP, em *encrMap) error { em.Lock() indices, ok := em.nodes[remoteIP.String()] em.Unlock() if !ok { return nil } for i, idxs := range indices { dir := reverse if i == 0 { dir = bidir } fSA, rSA, err := programSA(localIP, remoteIP, idxs, nil, dir, false) if err != nil { logrus.Warn(err) } if i != 0 { continue } err = programSP(fSA, rSA, false) if err != nil { logrus.Warn(err) } } return nil }
// GetPrivateIP is used to return the first private IP address // associated with an interface on the machine func GetPrivateIP() (net.IP, error) { addresses, err := net.InterfaceAddrs() if err != nil { return nil, fmt.Errorf("Failed to get interface addresses: %v", err) } // Find private IPv4 address for _, rawAddr := range addresses { var ip net.IP switch addr := rawAddr.(type) { case *net.IPAddr: ip = addr.IP case *net.IPNet: ip = addr.IP default: continue } if ip.To4() == nil { continue } if !isPrivateIP(ip.String()) { continue } return ip, nil } return nil, fmt.Errorf("No private IP address found") }
// GetPrivateIP returns the first private IP address found in a list of // addresses. func GetPrivateIP(addresses []net.Addr) (net.IP, error) { var candidates []net.IP // Find private IPv4 address for _, rawAddr := range addresses { var ip net.IP switch addr := rawAddr.(type) { case *net.IPAddr: ip = addr.IP case *net.IPNet: ip = addr.IP default: continue } if ip.To4() == nil { continue } if !IsPrivateIP(ip.String()) { continue } candidates = append(candidates, ip) } numIps := len(candidates) switch numIps { case 0: return nil, fmt.Errorf("No private IP address found") case 1: return candidates[0], nil default: return nil, fmt.Errorf("Multiple private IPs found. Please configure one.") } }
// Add virtual tunnel end point. This is mainly used for mapping remote vtep IP // to ofp port number. func (self *Vrouter) AddVtepPort(portNo uint32, remoteIp net.IP) error { // Install a flow entry for default VNI/vlan and point it to IP table portVlanFlow, err := self.vlanTable.NewFlow(ofctrl.FlowMatch{ Priority: FLOW_MATCH_PRIORITY, InputPort: portNo, }) if err != nil && strings.Contains(err.Error(), "Flow already exists") { log.Infof("VTEP %s already exists", remoteIp.String()) return nil } else if err != nil { log.Errorf("Error adding Flow for VTEP %v. Err: %v", remoteIp, err) return err } // FIXME: Need to match on tunnelId and set vlan-id per VRF // FIXME: not needed till multi-vrf support. We cant pop vlan unless flow matches on vlan // portVlanFlow.SetVlan(1) // Point it to next table. // Note that we bypass policy lookup on dest host. portVlanFlow.Next(self.ipTable) // FIXME: walk all the routes and see if we can install it // This could happen if a route made it to us before VTEP return nil }