Example #1
0
func (sm *SubnetManager) applySubnetChange(action string, ipn ip.IP4Net, data string) Event {
	switch action {
	case "delete", "expire":
		for i, l := range sm.leases {
			if l.Network.Equal(ipn) {
				deleteLease(sm.leases, i)
				return Event{SubnetRemoved, l}
			}
		}

		log.Errorf("Removed subnet (%s) was not found", ipn)
		return Event{
			SubnetRemoved,
			SubnetLease{ipn, ""},
		}

	default:
		for i, l := range sm.leases {
			if l.Network.Equal(ipn) {
				sm.leases[i] = SubnetLease{ipn, data}
				return Event{SubnetAdded, sm.leases[i]}
			}
		}

		sm.leases = append(sm.leases, SubnetLease{ipn, data})
		return Event{SubnetAdded, sm.leases[len(sm.leases)-1]}
	}
}
Example #2
0
func Run(sm *subnet.SubnetManager, tepIface *net.Interface, tepIP net.IP, port int, ipMasq bool, ready backend.ReadyFunc) {
	sn, err := acquireLease(sm, tepIP)
	if err != nil {
		log.Error("Failed to acquire lease: ", err)
		return
	}

	tun, tunName, err := ip.OpenTun("rudder%d")
	if err != nil {
		log.Error("Failed to open TUN device: ", err)
		return
	}

	localAddr := net.UDPAddr{
		Port: port,
	}

	conn, err := net.ListenUDP("udp4", &localAddr)
	if err != nil {
		log.Error("Failed to start listening on UDP socket: ", err)
		return
	}

	// Interface's subnet is that of the whole overlay network (e.g. /16)
	// and not that of the individual host (e.g. /24)
	tunNet := ip.IP4Net{
		IP:        sn.IP,
		PrefixLen: sm.GetConfig().Network.PrefixLen,
	}

	// TUN MTU will be smaller b/c of encap (IP+UDP hdrs)
	var mtu int
	if tepIface.MTU > 0 {
		mtu = tepIface.MTU - encapOverhead
	} else {
		log.Errorf("Failed to determine MTU for %s interface", tepIP)
		return
	}

	err = configureIface(tunName, tunNet, mtu)
	if err != nil {
		return
	}

	if ipMasq {
		err = setupIpMasq(tunNet.Network(), tunName)
		if err != nil {
			return
		}
	}

	// all initialized and ready for business
	log.Info("UDP encapsulation initialized")
	ready(sn, mtu)

	fastProxy(sm, tun, conn, tunNet.IP, uint(mtu), port)
}
Example #3
0
func lookupIface() (*net.Interface, net.IP) {
	var iface *net.Interface
	var tep net.IP
	var err error

	if len(opts.iface) > 0 {
		if tep = net.ParseIP(opts.iface); tep != nil {
			iface, err = ip.GetInterfaceByIP(tep)
			if err != nil {
				log.Errorf("Error looking up interface %s: %s", opts.iface, err)
				return nil, nil
			}
		} else {
			iface, err = net.InterfaceByName(opts.iface)
			if err != nil {
				log.Errorf("Error looking up interface %s: %s", opts.iface, err)
				return nil, nil
			}
		}
	} else {
		log.Info("Determining IP address of default interface")
		for {
			if iface, err = ip.GetDefaultGatewayIface(); err == nil {
				break
			}
			log.Error("Failed to get default interface: ", err)
			time.Sleep(time.Second)
		}
	}

	if tep == nil {
		tep, err = ip.GetIfaceIP4Addr(iface)
		if err != nil {
			log.Error("Failed to find IPv4 address for interface ", iface.Name)
		}
	}

	return iface, tep
}
Example #4
0
func configureIface(ifname string, ipn ip.IP4Net, mtu int) error {
	iface, err := net.InterfaceByName(ifname)
	if err != nil {
		log.Error("Failed to lookup interface ", ifname)
		return err
	}

	n := ipn.ToIPNet()
	err = netlink.NetworkLinkAddIp(iface, n.IP, n)
	if err != nil {
		log.Errorf("Failed to add IP address %s to %s: %s", n.IP, ifname, err)
		return err
	}

	err = netlink.NetworkSetMTU(iface, mtu)
	if err != nil {
		log.Errorf("Failed to set MTU for %s: %v", ifname, err)
		return err
	}

	err = netlink.NetworkLinkUp(iface)
	if err != nil {
		log.Errorf("Failed to set interface %s to UP state: %s", ifname, err)
		return err
	}

	// explicitly add a route since there might be a route for a subnet already
	// installed by Docker and then it won't get auto added
	err = netlink.AddRoute(ipn.Network().String(), "", "", ifname)
	if err != nil && err != syscall.EEXIST {
		log.Errorf("Failed to add route (%s -> %s): %v", ipn.Network().String(), ifname, err)
		return err
	}

	return nil
}
Example #5
0
func (sm *SubnetManager) watchLeases(receiver chan EventBatch) {
	// "catch up" by replaying all the leases we discovered during
	// AcquireLease
	var batch EventBatch
	for _, l := range sm.leases {
		if !sm.myLease.Network.Equal(l.Network) {
			batch = append(batch, Event{SubnetAdded, l})
		}
	}
	if len(batch) > 0 {
		receiver <- batch
	}

	for {
		resp, err := sm.registry.watchSubnets(sm.lastIndex+1, sm.stop)

		// watchSubnets exited by stop chan being signaled
		if err == nil && resp == nil {
			return
		}

		var batch *EventBatch
		if err == nil {
			batch, err = sm.parseSubnetWatchResponse(resp)
		} else {
			batch, err = sm.parseSubnetWatchError(err)
		}

		if err != nil {
			log.Errorf("%v", err)
			time.Sleep(time.Second)
			continue
		}

		if batch != nil {
			receiver <- *batch
		}
	}
}