Example #1
0
// Set the IP addr of a netlink interface
func (driver *driver) setInterfaceIP(name string, rawIP string) error {
	var netlinkRetryTimer time.Duration
	netlinkRetryTimer = 2
	iface, err := netlink.LinkByName(name)
	if err != nil {
		log.Debugf("error retrieving new OVS bridge netlink link [ %s ] allowing another [ %d ] seconds for the host to finish creating it..", bridgeName, netlinkRetryTimer)
		time.Sleep(netlinkRetryTimer * time.Second)
		iface, err = netlink.LinkByName(name)
		if err != nil {
			log.Debugf("error retrieving new OVS bridge netlink link [ %s ] allowing another [ %d ] seconds for the host to finish creating it..", bridgeName, netlinkRetryTimer)
			time.Sleep(netlinkRetryTimer * time.Second)
			iface, err = netlink.LinkByName(name)
			if err != nil {
				log.Fatalf("Abandoning retrieving the new OVS bridge link from netlink, Run [ ip link ] to troubleshoot the error: %s", err)
				return err
			}
		}
	}
	ipNet, err := netlink.ParseIPNet(rawIP)
	if err != nil {
		return err
	}
	addr := &netlink.Addr{ipNet, ""}
	return netlink.AddrAdd(iface, addr)
}
Example #2
0
func New(version string) (server.Driver, error) {
	network, _ := netlink.ParseIPNet("10.46.0.0/16")
	gateway, _ := netlink.ParseIPNet("10.46.0.1/32")
	pool := &routedPool{
		id:           "myPool",
		subnet:       network,
		allocatedIPs: make(map[string]bool),
		gateway:      gateway,
	}
	rnet := &routedNetwork{
		endpoints: make(map[string]*routedEndpoint),
	}
	pool.allocatedIPs[fmt.Sprintf("%s", gateway)] = true
	return &driver{
		version: version,
		pool:    pool,
		network: rnet,
	}, nil
}
Example #3
0
// Set the IP addr of a link
func (driver *driver) setInterfaceIP(name string, rawIP string) error {
	iface, err := netlink.LinkByName(name)
	if err != nil {
		return err
	}
	ipNet, err := netlink.ParseIPNet(rawIP)
	if err != nil {
		return err
	}
	addr := &netlink.Addr{IPNet: ipNet, Label: ""}
	return netlink.AddrAdd(iface, addr)
}
Example #4
0
func (driver *driver) CreateEndpoint(create *netApi.CreateEndpointRequest) (*netApi.CreateEndpointResponse, error) {
	log.Debugf("Create endpoint request %+v", create)
	var aliases []*net.IPNet
	endID := create.EndpointID
	reqIface := create.Interface
	log.Debugf("Requested Interface %+v", reqIface)
	log.Debugf("IP Aliases: %+v", reqIface.IPAliases)

	for _, ipa := range reqIface.IPAliases {
		ip, _ := netlink.ParseIPNet(ipa)
		aliases = append(aliases, ip)
	}
	addr, _ := netlink.ParseIPNet(reqIface.Address)
	ep := &routedEndpoint{
		ipv4Address: addr,
		ipAliases:   aliases,
	}
	driver.network.endpoints[endID] = ep

	log.Infof("Creating endpoint %s %+v", endID, nil)
	return nil, nil
}
Example #5
0
// Set the IP addr of a netlink interface
func (driver *driver) setInterfaceIP(name string, rawIP string) error {
	iface, err := netlink.LinkByName(name)
	if err != nil {
		log.Debugf("error retrieving new OVS bridge link [ %s ] likely a race issue between ovs and netlink, retrying in 1 second..", bridgeName)
		time.Sleep(2 * time.Second)
		iface, err = netlink.LinkByName(name)
		if err != nil {
			log.Errorf("Error retrieving the new OVS bridge from netlink: %s", err)
			return err
		}
	}
	ipNet, err := netlink.ParseIPNet(rawIP)
	if err != nil {
		return err
	}
	addr := &netlink.Addr{ipNet, ""}
	return netlink.AddrAdd(iface, addr)
}
Example #6
0
func NewNetlinkRoute(ifname, dst, src, gw string, scope netlink.Scope) (*netlink.Route, error) {
	link, err := netlink.LinkByName(ifname)
	if err != nil {
		return nil, err
	}

	dstNet, err := netlink.ParseIPNet(dst)
	if err != nil {
		return nil, err
	}

	r := netlink.Route{
		LinkIndex: link.Attrs().Index,
		Dst:       dstNet,
		Src:       net.ParseIP(src),
		Gw:        net.ParseIP(gw),
		Scope:     scope,
	}

	return &r, nil
}
Example #7
0
// Set the IP addr of a netlink interface
func setInterfaceIP(name string, rawIP string) error {
	retries := 2
	var iface netlink.Link
	var err error
	for i := 0; i < retries; i++ {
		iface, err = netlink.LinkByName(name)
		if err == nil {
			break
		}
		log.Debugf("error retrieving new OVS bridge netlink link [ %s ]... retrying", name)
		time.Sleep(2 * time.Second)
	}
	if err != nil {
		log.Fatalf("Abandoning retrieving the new OVS bridge link from netlink, Run [ ip link ] to troubleshoot the error: %s", err)
		return err
	}
	ipNet, err := netlink.ParseIPNet(rawIP)
	if err != nil {
		return err
	}
	addr := &netlink.Addr{ipNet, ""}
	return netlink.AddrAdd(iface, addr)
}
Example #8
0
//modrib receives route updates from BGP server and adds the endpoint
func (self *OfnetBgp) modRib(path *api.Path) error {
	var nlri bgp.AddrPrefixInterface
	var nextHop string
	var macAddrStr string
	var portNo uint32
	if len(path.Nlri) > 0 {
		nlri = &bgp.IPAddrPrefix{}
		err := nlri.DecodeFromBytes(path.Nlri)
		if err != nil {
			return err
		}
	}

	for _, attr := range path.Pattrs {
		p, err := bgp.GetPathAttribute(attr)
		if err != nil {
			return err
		}

		err = p.DecodeFromBytes(attr)
		if err != nil {
			return err
		}

		if p.GetType() == bgp.BGP_ATTR_TYPE_NEXT_HOP {
			nextHop = p.(*bgp.PathAttributeNextHop).Value.String()
			break
		}
	}
	if nextHop == "0.0.0.0" {
		return nil
	}

	if nlri == nil {
		return fmt.Errorf("no nlri")
	}

	endpointIPNet, _ := netlink.ParseIPNet(nlri.String())
	log.Infof("Bgp Rib Received endpoint update for %v , with nexthop %v",
		endpointIPNet, nextHop)

	//check if bgp published a route local to the host
	epid := endpointIPNet.IP.Mask(endpointIPNet.Mask).String()

	//Check if the route is local
	if nextHop == self.routerIP {
		log.Info("This is a local route skipping endpoint create! ")
		return nil
	}

	if self.agent.endpointDb[nextHop] == nil {
		//the nexthop is not the directly connected eBgp peer
		macAddrStr = ""
		portNo = 0
	} else {
		macAddrStr = self.agent.endpointDb[nextHop].MacAddrStr
		portNo = self.agent.endpointDb[nextHop].PortNo
	}

	ipmask := net.ParseIP("255.255.255.255").Mask(endpointIPNet.Mask)

	if path.IsWithdraw != true {
		epreg := &OfnetEndpoint{
			EndpointID:   epid,
			EndpointType: "external",
			IpAddr:       endpointIPNet.IP,
			IpMask:       ipmask,
			VrfId:        0, // FIXME set VRF correctly
			MacAddrStr:   macAddrStr,
			Vlan:         1,
			OriginatorIp: self.agent.localIp,
			PortNo:       portNo,
			Timestamp:    time.Now(),
		}

		// Install the endpoint in datapath
		// First, add the endpoint to local routing table
		self.agent.endpointDb[epreg.EndpointID] = epreg
		err := self.agent.datapath.AddEndpoint(epreg)
		if err != nil {
			log.Errorf("Error adding endpoint: {%+v}. Err: %v", epreg, err)
			return err
		}
	} else {
		log.Info("Received route withdraw from BGP for ", endpointIPNet)
		endpoint := self.agent.getEndpointByIp(endpointIPNet.IP)
		if endpoint != nil {
			self.agent.datapath.RemoveEndpoint(endpoint)
			delete(self.agent.endpointDb, endpoint.EndpointID)
		}
	}
	return nil
}
Example #9
0
//modrib receives route updates from BGP server and adds the endpoint
func (self *OfnetBgp) modRib(path *table.Path) error {
	var nlri bgp.AddrPrefixInterface
	var nextHop string
	var macAddrStr string
	var portNo uint32

	nlri = path.GetNlri()
	nextHop = path.GetNexthop().String()

	if nextHop == "0.0.0.0" {
		return nil
	}

	if nlri == nil {
		return fmt.Errorf("no nlri")
	}

	endpointIPNet, _ := netlink.ParseIPNet(nlri.String())
	log.Infof("Bgp Rib Received endpoint update for path %s", path.String())

	//check if bgp published a route local to the host
	epid := self.agent.getEndpointIdByIpVrf(endpointIPNet.IP.Mask(endpointIPNet.Mask), "default")

	//Check if the route is local
	if nextHop == self.routerIP {
		log.Debugf("This is a local route skipping endpoint create! ")
		return nil
	} else if ep := self.agent.getEndpointByID(epid); ep != nil {
		if ep.EndpointType != "external" {
			log.Debugf("Endpoint was learnt via internal protocol. skipping update! ")
			return nil
		}
	}

	nhEpid := self.agent.getEndpointIdByIpVrf(net.ParseIP(nextHop), "default")

	if ep := self.agent.getEndpointByID(nhEpid); ep == nil {
		//the nexthop is not the directly connected eBgp peer
		macAddrStr = ""
		portNo = 0
	} else {
		macAddrStr = ep.MacAddrStr
		portNo = ep.PortNo
	}

	ipmask := net.ParseIP("255.255.255.255").Mask(endpointIPNet.Mask)

	if path.IsWithdraw != true {
		epreg := &OfnetEndpoint{
			EndpointID:   epid,
			EndpointType: "external",
			IpAddr:       endpointIPNet.IP,
			IpMask:       ipmask,
			Vrf:          "default", // FIXME set VRF correctly
			MacAddrStr:   macAddrStr,
			Vlan:         1,
			OriginatorIp: self.agent.localIp,
			PortNo:       portNo,
			Timestamp:    time.Now(),
		}

		// Install the endpoint in datapath
		// First, add the endpoint to local routing table

		self.agent.endpointDb.Set(epreg.EndpointID, epreg)
		err := self.agent.datapath.AddEndpoint(epreg)
		if err != nil {
			log.Errorf("Error adding endpoint: {%+v}. Err: %v", epreg, err)
			return err
		}
	} else {
		log.Info("Received route withdraw from BGP for ", endpointIPNet)
		endpoint := self.agent.getEndpointByIpVrf(endpointIPNet.IP, "default")
		if endpoint != nil {
			self.agent.datapath.RemoveEndpoint(endpoint)
			self.agent.endpointDb.Remove(endpoint.EndpointID)
		}
	}
	return nil
}
Example #10
0
func TestSetIpAddress(t *testing.T) {
	_, mocker := testSetup(t)
	defer testTeardown(t, mocker)

	hFile, err := ioutil.TempFile("", "vic_set_ip_test_hosts")
	if err != nil {
		t.Errorf("Failed to create tmp hosts file: %s", err)
	}
	rFile, err := ioutil.TempFile("", "vic_set_ip_test_resolv")
	if err != nil {
		t.Errorf("Failed to create tmp resolv file: %s", err)
	}

	// give us a hosts file we can modify
	defer func(hosts, resolv string) {
		hostsFile = hosts
		resolvFile = resolv
	}(hostsFile, resolvFile)

	hostsFile = hFile.Name()
	resolvFile = rFile.Name()

	bridge := AddInterface("eth1", mocker)
	external := AddInterface("eth2", mocker)

	secondIP, _ := netlink.ParseIPNet("172.16.0.10/24")
	gwIP, _ := netlink.ParseIPNet("172.16.0.1/24")
	cfg := executor.ExecutorConfig{
		Common: executor.Common{
			ID:   "ipconfig",
			Name: "tether_test_executor",
		},
		Networks: map[string]*executor.NetworkEndpoint{
			"bridge": &executor.NetworkEndpoint{
				Common: executor.Common{
					ID: bridge,
					// interface rename
					Name: "bridge",
				},
				Network: executor.ContainerNetwork{
					Common: executor.Common{
						Name: "bridge",
					},
					Default: true,
					Gateway: *gwIP,
				},
				Static: &net.IPNet{
					IP:   localhost,
					Mask: lmask.Mask,
				},
			},
			"cnet": &executor.NetworkEndpoint{
				Common: executor.Common{
					ID: bridge,
					// no interface rename
				},
				Network: executor.ContainerNetwork{
					Common: executor.Common{
						Name: "cnet",
					},
				},
				Static: secondIP,
			},
			"external": &executor.NetworkEndpoint{
				Common: executor.Common{
					ID: external,
					// interface rename
					Name: "external",
				},
				Network: executor.ContainerNetwork{
					Common: executor.Common{
						Name: "external",
					},
				},
				Static: &net.IPNet{
					IP:   gateway,
					Mask: gmask.Mask,
				},
			},
		},
	}

	tthr, _ := StartTether(t, &cfg, mocker)

	defer func() {
		// prevent indefinite wait in tether - normally session exit would trigger this
		tthr.Stop()

		// wait for tether to exit
		<-mocker.Cleaned
	}()

	<-mocker.Started

	assert.NotNil(t, mocker.Interfaces["bridge"], "Expected bridge network if endpoints applied correctly")
	// check addresses
	bIface, _ := mocker.Interfaces["bridge"].(*Interface)
	assert.NotNil(t, bIface)

	assert.Equal(t, 2, len(bIface.Addrs), "Expected two addresses on bridge interface")

	eIface, _ := mocker.Interfaces["external"].(*Interface)
	assert.NotNil(t, eIface)

	assert.Equal(t, 1, len(eIface.Addrs), "Expected one address on external interface")
}
Example #11
0
func TestSetIpAddress(t *testing.T) {
	testSetup(t)
	defer testTeardown(t)

	bridge := AddInterface("eno1")
	external := AddInterface("eno2")

	secondIP, _ := netlink.ParseIPNet("172.16.0.10/24")
	gwIP, _ := netlink.ParseIPNet("172.16.0.1/24")
	cfg := metadata.ExecutorConfig{
		Common: metadata.Common{
			ID:   "ipconfig",
			Name: "tether_test_executor",
		},
		Networks: map[string]*metadata.NetworkEndpoint{
			"bridge": &metadata.NetworkEndpoint{
				Common: metadata.Common{
					ID: bridge,
					// interface rename
					Name: "bridge",
				},
				Network: metadata.ContainerNetwork{
					Common: metadata.Common{
						Name: "bridge",
					},
					Default: true,
					Gateway: gwIP,
				},
				Static: &net.IPNet{
					IP:   localhost,
					Mask: lmask.Mask,
				},
			},
			"cnet": &metadata.NetworkEndpoint{
				Common: metadata.Common{
					ID: bridge,
					// no interface rename
				},
				Network: metadata.ContainerNetwork{
					Common: metadata.Common{
						Name: "cnet",
					},
				},
				Static: secondIP,
			},
			"external": &metadata.NetworkEndpoint{
				Common: metadata.Common{
					ID: external,
					// interface rename
					Name: "external",
				},
				Network: metadata.ContainerNetwork{
					Common: metadata.Common{
						Name: "external",
					},
				},
				Static: &net.IPNet{
					IP:   gateway,
					Mask: gmask.Mask,
				},
			},
		},
	}

	tthr, _ := StartTether(t, &cfg)

	<-Mocked.Started

	// check addresses
	bIface := Mocked.Interfaces["bridge"].(*Interface)
	assert.NotNil(t, bIface)

	assert.Equal(t, 2, len(bIface.Addrs), "Expected two addresses on bridge interface")

	eIface := Mocked.Interfaces["external"].(*Interface)
	assert.NotNil(t, eIface)

	assert.Equal(t, 1, len(eIface.Addrs), "Expected one address on external interface")

	// prevent indefinite wait in tether - normally session exit would trigger this
	tthr.Stop()

	// wait for tether to exit
	<-Mocked.Cleaned
}
Example #12
0
// NewVeth creates a veth pair with the given name, moves the peer into the
// namespace n, then renames the peer to dstName and assigns the provided ip.
// If insideFn is not nil, also executes that function in the context of the
// given namespace.
func NewVeth(n netns.NsHandle, name, dstName, ip string, insideFn func(netlink.Link) error) (link *netlink.Veth, err error) {
	l := &netlink.Veth{
		LinkAttrs: netlink.LinkAttrs{
			Name: name,
		},
		PeerName: name + "_",
	}
	if err = netlink.LinkAdd(l); err != nil {
		return
	}
	defer func() {
		if err != nil {
			netlink.LinkDel(l)
		}
	}()

	otherL, err := netlink.LinkByName(l.PeerName)
	if err != nil {
		return
	}
	if err = netlink.LinkSetNsFd(otherL, int(n)); err != nil {
		return
	}
	err = RunInNs(n, func() error {
		lo, err := netlink.LinkByName("lo")
		if err != nil {
			return err
		}
		err = netlink.LinkSetUp(lo)
		if err != nil {
			return err
		}
		l, err := netlink.LinkByName(name + "_")
		if err != nil {
			return err
		}
		if err = netlink.LinkSetName(l, dstName); err != nil {
			return err
		}
		l.Attrs().Name = dstName
		a, err := netlink.ParseIPNet(ip)
		if err != nil {
			return err
		}
		if err := netlink.AddrAdd(l, &netlink.Addr{IPNet: a}); err != nil {
			return err
		}
		if insideFn != nil {
			if err := insideFn(l); err != nil {
				return err
			}
		}
		if err = netlink.LinkSetUp(l); err != nil {
			return err
		}
		return nil
	})
	if err != nil {
		return
	}
	if err = netlink.LinkSetUp(l); err != nil {
		return
	}
	link = l
	return
}