Beispiel #1
0
func IpAddrDel(cResp chan<- *Response, rawArgs *json.RawMessage, tag string) {
	args := &struct {
		Ifname string `json:"ifname"`
		IpCidr string `json:"ip"`
	}{}

	json.Unmarshal(*rawArgs, &args)

	iface, err := netlink.LinkByName(args.Ifname)
	if err != nil {
		cResp <- &Response{nil, tag, NewRTNetlinkError(err)}
		return
	}

	ip, err := netlink.ParseAddr(args.IpCidr)
	if err != nil {
		cResp <- &Response{nil, tag, NewRTNetlinkError(err)}
		return
	}

	if err := netlink.AddrDel(iface, ip); err != nil {
		cResp <- &Response{nil, tag, NewRTNetlinkError(err)}
		return
	}

	cResp <- &Response{true, tag, nil}
}
Beispiel #2
0
func main() {
	lo, _ := netlink.LinkByName("lo")
	fmt.Println(lo)
	addr, _ := netlink.ParseAddr("127.0.0.2/8")
	fmt.Println(addr)
	netlink.AddrAdd(lo, addr)
	fmt.Println(netlink.AddrList(lo, netlink.FAMILY_ALL))

	req := nl.NewNetlinkRequest(syscall.NLMSG_MIN_TYPE, syscall.NLM_F_REQUEST)

	data := append([]byte("TASKSTATS"), 0)
	a := &Attr{
		Type: 2,
		Data: data,
	}
	Hdr := []byte{
		3,
		0,
		0,
		0,
	}
	m := &Message{
		Type:    16,
		Pid:     -1,
		Seq:     -1,
		Flags:   NLM_F_REQUEST,
		Payload: append(Hdr, a.Dump()...),
	}

	req.AddData(m)
	res, _ := req.Execute(syscall.NETLINK_GENERIC, 0)
	fmt.Println(res)
	fmt.Println(parse_attributes(res[0][4:])[1])
}
Beispiel #3
0
func applyNetConf(link netlink.Link, netConf config.InterfaceConfig) error {
	if netConf.DHCP {
		log.Infof("Running DHCP on %s", link.Attrs().Name)
		cmd := exec.Command("dhcpcd", "-A4", "-e", "force_hostname=true", link.Attrs().Name)
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stderr
		if err := cmd.Run(); err != nil {
			log.Error(err)
		}
	} else if netConf.IPV4LL {
		if err := AssignLinkLocalIP(link); err != nil {
			log.Error("IPV4LL set failed")
			return err
		}
	} else if netConf.Address == "" {
		return nil
	} else {
		addr, err := netlink.ParseAddr(netConf.Address)
		if err != nil {
			return err
		}
		if err := netlink.AddrAdd(link, addr); err != nil {
			log.Error("addr add failed")
			return err
		}
		log.Infof("Set %s on %s", netConf.Address, link.Attrs().Name)
	}

	if netConf.MTU > 0 {
		if err := netlink.LinkSetMTU(link, netConf.MTU); err != nil {
			log.Error("set MTU Failed")
			return err
		}
	}

	if err := netlink.LinkSetUp(link); err != nil {
		log.Error("failed to setup link")
		return err
	}

	if netConf.Gateway != "" {
		gatewayIp := net.ParseIP(netConf.Gateway)
		if gatewayIp == nil {
			return errors.New("Invalid gateway address " + netConf.Gateway)
		}

		route := netlink.Route{
			Scope: netlink.SCOPE_UNIVERSE,
			Gw:    net.ParseIP(netConf.Gateway),
		}
		if err := netlink.RouteAdd(&route); err != nil {
			log.Error("gateway set failed")
			return err
		}

		log.Infof("Set default gateway %s", netConf.Gateway)
	}

	return nil
}
Beispiel #4
0
/*   SetupNetwork()
 */
func SetupNetwork(addr string) error {
	// Bring up loop back interface.
	lo, e := netlink.LinkByName("lo")
	if e != nil {
		return fmt.Errorf("Failed to find loopback interface: %v", e)
	}

	if e := netlink.LinkSetUp(lo); e != nil {
		return fmt.Errorf("Failed to setup loopback interface: %v", e)
	}

	if len(addr) > 0 {
		veth, e := netlink.LinkByName("veth0")
		if e != nil {
			return fmt.Errorf("Failed to find veth interface: %v", e)
		}

		addr, e := netlink.ParseAddr(addr)
		if e != nil {
			return fmt.Errorf("Failed to parse NetworkAddr: %v", e)
		}

		netlink.AddrAdd(veth, addr)
		if e := netlink.LinkSetUp(veth); e != nil {
			return fmt.Errorf("Network link failed to come up: %v", e)
		}
	}

	return nil
}
Beispiel #5
0
func routingUp() {
	veth, err := netlink.LinkByName("myveth1")
	if err != nil {
		panic(err)
	}

	err = netlink.LinkSetUp(veth)
	if err != nil {
		panic(err)
	}

	addr, _ := netlink.ParseAddr("172.19.80.2/24")
	err = netlink.AddrAdd(veth, addr)
	if err != nil {
		panic(err)
	}

	routes := createRoutes(veth)

	for _, route := range routes {
		fmt.Println("Adding route", route)
		err := netlink.RouteAdd(route)
		if err != nil {
			fmt.Println(err)
			// panic(err)
		}
	}
}
func addrAdd(t *testing.T, l netlink.Link, a string) {
	addr, err := netlink.ParseAddr(a)
	if err != nil {
		t.Fatal(err)
	}

	err = netlink.AddrAdd(l, addr)
	if err != nil && err != syscall.EEXIST {
		t.Fatal(err)
	}
}
func applyNetConf(link netlink.Link, netConf InterfaceConfig) error {
	if netConf.IPV4LL {
		if err := AssignLinkLocalIP(link); err != nil {
			log.Errorf("IPV4LL set failed: %v", err)
			return err
		}
	} else if netConf.Address == "" {
		return nil
	} else {
		addr, err := netlink.ParseAddr(netConf.Address)
		if err != nil {
			return err
		}
		if err := netlink.AddrAdd(link, addr); err != nil {
			//Ignore this error
			log.Errorf("addr add failed: %v", err)
		} else {
			log.Infof("Set %s on %s", netConf.Address, link.Attrs().Name)
		}
	}

	if netConf.MTU > 0 {
		if err := netlink.LinkSetMTU(link, netConf.MTU); err != nil {
			log.Errorf("set MTU Failed: %v", err)
			return err
		}
	}

	if err := netlink.LinkSetUp(link); err != nil {
		log.Errorf("failed to setup link: %v", err)
		return err
	}

	if netConf.Gateway != "" {
		gatewayIp := net.ParseIP(netConf.Gateway)
		if gatewayIp == nil {
			return errors.New("Invalid gateway address " + netConf.Gateway)
		}

		route := netlink.Route{
			Scope: netlink.SCOPE_UNIVERSE,
			Gw:    net.ParseIP(netConf.Gateway),
		}
		if err := netlink.RouteAdd(&route); err != nil {
			log.Errorf("gateway set failed: %v", err)
			return err
		}

		log.Infof("Set default gateway %s", netConf.Gateway)
	}

	return nil
}
Beispiel #8
0
func TestPortInformation(t *testing.T) {
	mockContainerInfo := &plmodels.ContainerInfo{}
	mockContainerConfig := &plmodels.ContainerConfig{}
	containerID := "foo"
	mockContainerConfig.ContainerID = &containerID

	mockHostConfig := &container.HostConfig{}

	portMap := nat.PortMap{}
	port, _ := nat.NewPort("tcp", "80")
	portBinding := nat.PortBinding{
		HostIP:   "127.0.0.1",
		HostPort: "8000",
	}
	portBindings := []nat.PortBinding{portBinding}
	portMap[port] = portBindings
	mockHostConfig.PortBindings = portMap

	mockContainerInfo.ContainerConfig = mockContainerConfig

	ip, _ := netlink.ParseAddr("192.168.1.1/24")
	ips := []netlink.Addr{*ip}

	co := viccontainer.NewVicContainer()
	co.HostConfig = mockHostConfig
	co.ContainerID = containerID
	co.Name = "bar"
	cache.ContainerCache().AddContainer(co)

	ports := portInformation(mockContainerInfo, ips)

	assert.NotEmpty(t, ports, "There should be bound IPs")
	assert.Equal(t, len(ports), 1, "Expected 1 port binding, found %d", len(ports))

	port, _ = nat.NewPort("tcp", "80")
	portBinding = nat.PortBinding{
		HostIP:   "127.0.0.1",
		HostPort: "00",
	}
	portMap[port] = portBindings
	ports = portInformation(mockContainerInfo, ips)
	assert.NotEmpty(t, ports, "There should be 1 bound IP")
	assert.Equal(t, len(ports), 1, "Expected 1 port binding, found %d", len(ports))

	port, _ = nat.NewPort("tcp", "800")
	portBinding = nat.PortBinding{
		HostIP:   "127.0.0.1",
		HostPort: "800",
	}
	portMap[port] = portBindings
	ports = portInformation(mockContainerInfo, ips)
	assert.Equal(t, len(ports), 2, "Expected 2 port binding, found %d", len(ports))
}
Beispiel #9
0
// SetInterfaceIP : Set IP address of an interface
func SetInterfaceIP(name string, ipstr string) error {
	iface, err := netlink.LinkByName(name)
	if err != nil {
		return err
	}
	ipaddr, err := netlink.ParseAddr(ipstr)
	if err != nil {
		return err
	}
	netlink.LinkSetUp(iface)
	return netlink.AddrAdd(iface, ipaddr)
}
Beispiel #10
0
func DelIp(ip, iface string) error {
	link, err := netlink.LinkByName(iface)
	if err != nil {
		return err
	}

	addr, err := netlink.ParseAddr(ip)
	if err != nil {
		return err
	}

	return netlink.AddrDel(link, addr)
}
Beispiel #11
0
func AssignLinkLocalIP(link netlink.Link) error {
	ifaceName := link.Attrs().Name
	iface, err := net.InterfaceByName(ifaceName)
	if err != nil {
		log.Error("could not get information about interface")
		return err
	}
	addrs, err := iface.Addrs()
	if err != nil {
		log.Error("Error fetching existing ip on interface")
	}
	for _, addr := range addrs {
		if addr.String()[:7] == "169.254" {
			log.Info("Link Local IP already set on interface")
			return nil
		}
	}
	randSource, err := getPseudoRandomGenerator(link.Attrs().HardwareAddr)
	if err != nil {
		return err
	}
	// try a random address upto 10 times
	for i := 0; i < 10; i++ {
		randGenerator := rand.New(*randSource)
		randomNum := randGenerator.Uint32()
		dstIP := getNewIPV4LLAddr(randomNum)
		if dstIP[2] == 0 || dstIP[2] == 255 {
			i--
			continue
		}
		_, _, err := arping.PingOverIfaceByName(dstIP, ifaceName)
		if err != nil {
			// this ip is not being used
			addr, err := netlink.ParseAddr(dstIP.String() + "/16")
			if err != nil {
				log.Errorf("error while parsing ipv4ll addr, err = %v", err)
				return err
			}
			if err := netlink.AddrAdd(link, addr); err != nil {
				log.Error("ipv4ll addr add failed")
				return err
			}
			log.Infof("Set %s on %s", dstIP.String(), link.Attrs().Name)
			return nil
		}
	}
	log.Error("Could not find a suitable ipv4ll")
	return fmt.Errorf("Could not find a suitable ipv4ll")
}
Beispiel #12
0
func BindAndSetup(veth netlink.Link, ips string) error {
	addr, err := netlink.ParseAddr(ips)
	if err != nil {
		return err
	}

	if err := netlink.AddrAdd(veth, addr); err != nil {
		return err
	}

	if err := netlink.LinkSetUp(veth); err != nil {
		return err
	}
	return nil
}
Beispiel #13
0
func setupIface(link netlink.Link, cfg Cfg) error {
	// up loopback
	lo, err := netlink.LinkByName("lo")
	if err != nil {
		return fmt.Errorf("lo interface: %v", err)
	}
	if err := netlink.LinkSetUp(lo); err != nil {
		return fmt.Errorf("up veth: %v", err)
	}
	addr, err := netlink.ParseAddr(cfg.IP)
	if err != nil {
		return fmt.Errorf("parse IP: %v", err)
	}
	return netlink.AddrAdd(link, addr)
}
Beispiel #14
0
func applyAddress(address string, link netlink.Link, netConf InterfaceConfig) error {
	addr, err := netlink.ParseAddr(address)
	if err != nil {
		return err
	}
	if err := netlink.AddrAdd(link, addr); err == syscall.EEXIST {
		//Ignore this error
	} else if err != nil {
		log.Errorf("addr add failed: %v", err)
	} else {
		log.Infof("Set %s on %s", netConf.Address, link.Attrs().Name)
	}

	return nil
}
Beispiel #15
0
// initBridge creates a bridge if it does not exist
func initBridge() error {
	_, err := net.InterfaceByName(bridgeName)
	if err == nil {
		return nil
	}
	if !strings.Contains(err.Error(), "no such network interface") {
		return err
	}

	// Create *netlink.Bridge object
	la := netlink.NewLinkAttrs()
	la.Name = bridgeName
	la.MTU = mtu
	br := &netlink.Bridge{LinkAttrs: la}
	if err := netlink.LinkAdd(br); err != nil {
		return fmt.Errorf("Bridge creation failed: %v", err)
	}

	// Setup ip address for bridge
	addr, err := netlink.ParseAddr(ipAddr)
	if err != nil {
		return fmt.Errorf("Parsing address %s: %v", ipAddr, err)
	}
	if err := netlink.AddrAdd(br, addr); err != nil {
		return fmt.Errorf("Adding address %v to bridge %s failed: %v", addr, bridgeName, err)
	}

	// Validate that the IPAddress is there!
	_, err = getIfaceAddr(bridgeName)
	if err != nil {
		return fmt.Errorf("No IP address found on bridge %s", bridgeName)
	}

	// Add NAT rules for iptables
	if err = natOut(ipAddr, iptables.Insert); err != nil {
		return fmt.Errorf("Could not set NAT rules for bridge %s", bridgeName)
	}

	// Bring the bridge up
	if err := netlink.LinkSetUp(br); err != nil {
		return err
	}

	return nil
}
Beispiel #16
0
func bridgeCreate() {
	la := netlink.NewLinkAttrs()
	la.Name = "mycbridge"
	mybridge := &netlink.Bridge{la}
	err := netlink.LinkAdd(mybridge)
	if err != nil {
		panic(err)
	}

	addr, _ := netlink.ParseAddr("172.19.80.1/24")
	err = netlink.AddrAdd(mybridge, addr)
	if err != nil {
		panic(err)
	}

	err = netlink.LinkSetUp(mybridge)
	if err != nil {
		panic(err)
	}
}
Beispiel #17
0
func setUpVLan(cid, ips string, pid int, veth netlink.Link) bool {
	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	origns, err := netns.Get()
	if err != nil {
		logs.Info("Get orignal namespace failed", err)
		return false
	}
	defer origns.Close()

	ns, err := netns.GetFromPid(pid)
	if err != nil {
		logs.Info("Get container namespace failed", err)
		return false
	}

	netns.Set(ns)
	defer ns.Close()
	defer netns.Set(origns)

	addr, err := netlink.ParseAddr(ips)
	if err != nil {
		logs.Info("Parse CIDR failed", err)
		return false
	}

	if err := netlink.AddrAdd(veth, addr); err != nil {
		logs.Info("Add addr to veth failed", err)
		return false
	}

	if err := netlink.LinkSetUp(veth); err != nil {
		logs.Info("Setup veth failed", err)
		return false
	}

	logs.Info("Add vlan device success", cid[:12])
	return true
}
Beispiel #18
0
/* Configure @iface with address @cidr. Deletes any existing addresses */
func SetAddr(iface string, cidr string) {
	if strings.Index(cidr, "/") == -1 {
		/* No scope given: assume full netmask */
		cidr = cidr + "/32"
	}
	addr, err := netlink.ParseAddr(cidr)
	if err != nil {
		log.Fatalf("failed to parse %s interface address %s: %s", iface, cidr, err)
	}
	link, err := netlink.LinkByName(iface)
	if err != nil {
		log.Fatalf("failed to look up interface %s: %s", iface, err)
	}

	addrs, err := netlink.AddrList(link, 0)
	if err != nil {
		log.Fatalf("failed to get %s interface addresses: %s", iface, err)
	}

	already_configured := false
	for _, old_addr := range addrs {
		/* Test if already configured, otherwise EEXISTS */
		if old_addr.Equal(*addr) {
			already_configured = true
		} else {
			log.Printf("removing %s from %s", old_addr.IPNet, iface)
			if err := netlink.AddrDel(link, &old_addr); err != nil {
				log.Fatalf("failed to remove address from %s: %s", iface, err)
			}
		}
	}

	log.Printf("configuring %s on %s", addr.IPNet, iface)
	if !already_configured {
		if err := netlink.AddrAdd(link, addr); err != nil {
			log.Fatalf("failed to add address to %s: %s", iface, err)
		}
	}
}
Beispiel #19
0
//netlink is not avaible in MAC OS, build fail.
func AddContainerNetworking() {
	if CliIF == "" {
		log.Fatal("the host-interface is missing,please give one")
	}
	if ok := utils.ValidateHostIface(CliIF); !ok {
		log.Fatalf("the host-interface [ %s ] was not found.", CliIF)
	}

	hostmacvlanname, _ := utils.GenerateRandomName(hostprefix, hostlen)
	hostEth, _ := netlink.LinkByName(CliIF)

	//create the macvlan device
	macvlandev := &netlink.Macvlan{
		LinkAttrs: netlink.LinkAttrs{
			Name:        hostmacvlanname,
			ParentIndex: hostEth.Attrs().Index,
		},
		Mode: netlink.MACVLAN_MODE_BRIDGE,
	}
	if err := netlink.LinkAdd(macvlandev); err != nil {
		log.Fatalf("failed to create Macvlan: [ %v ] with the error: %s", macvlandev.Attrs().Name, err)
	}
	//	log.Infof("Created Macvlan port: [ %s ] using the mode: [ %s ]", macvlan.Name, macvlanMode)
	// ugly, actually ,can get the ns from netns.getfromDocker. the netns have many function, netns.getformpid
	// netns.getfromdocker the arg can not be the container name
	dockerPid := utils.DockerPid(CliCName)
	//the macvlandev can be use directly, don't get netlink.byname again.
	netlink.LinkSetNsPid(macvlandev, dockerPid)

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	//get root network namespace
	origns, _ := netns.Get()
	defer origns.Close()

	//enter the docker container network
	dockerNS, _ := netns.GetFromPid(dockerPid)
	defer dockerNS.Close()

	netns.Set(dockerNS)

	// use macvlandev can cause error,need type assertion. netlink.Macvlan not must be netlink.Link,fmz(realy? the vlan action add)
	// it is wrong,
	macvlandev1, _ := netlink.LinkByName(macvlandev.Attrs().Name)

	// when the eth is up, set name fail,: Device or resource busy
	netlink.LinkSetDown(macvlandev1)
	netlink.LinkSetName(macvlandev1, "eth1")

	addr, err := netlink.ParseAddr(CliIP)
	if err != nil {
		log.Fatalf("failed to parse the ip address %v", CliIP)
	}
	netlink.AddrAdd(macvlandev1, addr)
	netlink.LinkSetUp(macvlandev1)

	/* set the default route, have some problem. Dst == 0.0.0.0/0? no
	defaultgw := &netlink.Route{
		Dst: nil,
	}
	netlink.RouteDel(defaultgw)
	ip, _ := net.ParseIP("8.8.8.8")
	routes, _ := netlink.RouteGet(ip)
	for _, r := range routes {
		netlink.RouteDel(&r)
	}
	*/

	//if use ip instruction,  it also can config the container, --privileged have no effect.
	// The sublime test code(test this function) is strange, it only can avaiable in first time. And then fail(even need to reboot)
	// got it,

	//following code successfully delete the default route in docker container,but error in my host ,no such process
	routes, _ := netlink.RouteList(nil, netlink.FAMILY_V4)
	for _, r := range routes {
		if r.Dst == nil {
			if err := netlink.RouteDel(&r); err != nil {
				log.Warnf("delete the default error: ", err)
			}
		}
	}

	if CligwIP == "" {
		log.Fatal("container gw is null")
	}

	defaultRoute := &netlink.Route{
		Dst:       nil,
		Gw:        net.ParseIP(CligwIP),
		LinkIndex: macvlandev1.Attrs().Index,
	}
	if err := netlink.RouteAdd(defaultRoute); err != nil {
		log.Warnf("create default route error: ", err)
	}
	netns.Set(origns)
}
Beispiel #20
0
func main() {
	if len(os.Args) != 3 {
		panic("not enough args")
	}

	intf, err := net.InterfaceByName(os.Args[1])
	if err != nil {
		panic(err)
	}

	containerID := os.Args[2]

	log.Infof("Requesting for container ID %q on interface %q", containerID, intf.Name)

	contPid := getContainerInfo(containerID)
	log.Infof("Container has PID %s", contPid)

	runtime.LockOSThread()
	f, err := os.Open(fmt.Sprintf("/proc/%s/ns/net", contPid))
	if err != nil {
		panic(err)
	}

	if _, _, err := unix.RawSyscall(unix.SYS_SETNS, f.Fd(), syscall.CLONE_NEWNET, 0); err != 0 {
		panic(err)
	}

	link, err := netlink.LinkByName("eth0")
	if err != nil {
		panic(err)
	}

	chaddr := link.Attrs().HardwareAddr

	p := dhcp.RequestPacket(dhcp.Discover, chaddr, nil, []byte{1, 2, 3, 4}, true, []dhcp.Option{})
	conn, err := net.ListenPacket("udp", ":68")
	if err != nil {
		panic(err)
	}

	ipc := ipv4.NewPacketConn(conn)
	ipc.SetControlMessage(ipv4.FlagInterface, true)
	to := &net.UDPAddr{
		IP:   net.IPv4(255, 255, 255, 255),
		Port: 67,
	}

	eth0, err := net.InterfaceByName("eth0")
	if err != nil {
		panic(err)
	}

	if _, err := ipc.WriteTo(p, &ipv4.ControlMessage{IfIndex: eth0.Index}, to); err != nil {
		panic(err)
	}

	newPacket := dhcp.NewPacket(dhcp.BootReply)

	for {
		_, cm, _, err := ipc.ReadFrom(newPacket)
		if err != nil {
			panic(err)
		}

		if cm != nil && cm.IfIndex == eth0.Index {
			log.Infof("Received reply: %q", newPacket.YIAddr().String())
			break
		}
	}

	addr, err := netlink.ParseAddr(newPacket.YIAddr().String() + "/16")
	if err != nil {
		panic(err)
	}

	log.Infof("Setting interface eth0...")

	if err := netlink.AddrAdd(link, addr); err != nil {
		panic(err)
	}
}
Beispiel #21
0
/*
Bgp serve routine does the following:
1) Creates inb01 router port
2) Add MyBgp endpoint
3) Kicks off routines to monitor route updates and peer state
*/
func (self *OfnetBgp) StartProtoServer(routerInfo *OfnetProtoRouterInfo) error {
	log.Infof("Starting the Bgp Server with %v", routerInfo)
	//go routine to start gobgp server
	var len uint
	var err error
	self.routerIP, len, err = ParseCIDR(routerInfo.RouterIP)
	as, _ := strconv.Atoi(routerInfo.As)
	self.myBgpAs = uint32(as)

	self.modRibCh = make(chan *api.Path, 16)
	self.advPathCh = make(chan *api.Path, 16)

	timeout := grpc.WithTimeout(time.Second)
	conn, err := grpc.Dial("127.0.0.1:8080", timeout, grpc.WithBlock(), grpc.WithInsecure())
	if err != nil {
		log.Fatal(err)
	}
	self.cc = conn
	defer self.cc.Close()

	client := api.NewGobgpApiClient(self.cc)
	if client == nil {
		log.Errorf("Invalid Gobgpapi client")
		return errors.New("Error creating Gobgpapiclient")
	}
	path := &api.Path{
		Pattrs: make([][]byte, 0),
	}

	path.Nlri, _ = bgp.NewIPAddrPrefix(uint8(32), self.routerIP).Serialize()
	n, _ := bgp.NewPathAttributeNextHop("0.0.0.0").Serialize()
	path.Pattrs = append(path.Pattrs, n)
	origin, _ := bgp.NewPathAttributeOrigin(bgp.BGP_ORIGIN_ATTR_TYPE_INCOMPLETE).Serialize()
	path.Pattrs = append(path.Pattrs, origin)

	log.Debugf("Creating the loopback port ")
	err = self.agent.ovsDriver.CreatePort(self.intfName, "internal", 1)
	if err != nil {
		log.Errorf("Error creating the port", err)
	}

	intfIP := fmt.Sprintf("%s/%d", self.routerIP, len)
	log.Debugf("Creating inb01 with ", intfIP)
	ofPortno, _ := self.agent.ovsDriver.GetOfpPortNo(self.intfName)

	link, err := netlink.LinkByName(self.intfName)
	if err != nil {
		log.Errorf("error finding link by name %v", self.intfName)
		return err
	}
	linkIP, err := netlink.ParseAddr(intfIP)
	if err != nil {
		log.Errorf("invalid ip ", intfIP)
	}
	netlink.AddrAdd(link, linkIP)

	if link == nil || ofPortno == 0 {
		log.Errorf("Error fetching %v information", self.intfName, link, ofPortno)
		return errors.New("Unable to fetch inb01 info")
	}

	intf, _ := net.InterfaceByName(self.intfName)

	epreg := &OfnetEndpoint{
		EndpointID:   self.routerIP,
		EndpointType: "internal-bgp",
		IpAddr:       net.ParseIP(self.routerIP),
		IpMask:       net.ParseIP("255.255.255.255"),
		VrfId:        0,                          // FIXME set VRF correctly
		MacAddrStr:   intf.HardwareAddr.String(), //link.Attrs().HardwareAddr.String(),
		Vlan:         1,
		PortNo:       ofPortno,
		Timestamp:    time.Now(),
	}

	// Add the endpoint to local routing table
	self.agent.endpointDb[self.routerIP] = epreg
	self.agent.localEndpointDb[epreg.PortNo] = epreg
	fmt.Println(epreg)
	err = self.agent.datapath.AddLocalEndpoint(*epreg)

	//Add bgp router id as well
	bgpGlobalCfg := &bgpconf.Global{}
	setDefaultGlobalConfigValues(bgpGlobalCfg)
	bgpGlobalCfg.GlobalConfig.RouterId = net.ParseIP(self.routerIP)
	bgpGlobalCfg.GlobalConfig.As = self.myBgpAs
	self.bgpServer.SetGlobalType(*bgpGlobalCfg)

	self.advPathCh <- path

	//monitor route updates from peer
	go self.monitorBest()
	//monitor peer state
	go self.monitorPeer()
	self.start <- true
	for {
		select {
		case p := <-self.modRibCh:
			err = self.modRib(p)
			if err != nil {
				log.Error("failed to mod rib: ", err)
			}
		case <-self.stop:
			return nil
		}
	}
	return nil
}
Beispiel #22
0
/*
Bgp serve routine does the following:
1) Creates inb01 router port
2) Add MyBgp endpoint
3) Kicks off routines to monitor route updates and peer state
*/
func (self *OfnetBgp) StartProtoServer(routerInfo *OfnetProtoRouterInfo) error {

	log.Infof("Starting the Bgp Server with %v", routerInfo)
	//go routine to start gobgp server
	var len uint
	var err error
	self.routerIP, len, err = ParseCIDR(routerInfo.RouterIP)
	as, _ := strconv.Atoi(routerInfo.As)
	self.myBgpAs = uint32(as)

	timeout := grpc.WithTimeout(time.Second)
	conn, err := grpc.Dial("127.0.0.1:50051", timeout, grpc.WithBlock(), grpc.WithInsecure())
	if err != nil {
		log.Fatal(err)
	}
	self.cc = conn
	log.Debugf("Creating the loopback port ")
	err = self.agent.ovsDriver.CreatePort(self.intfName, "internal", 1)
	if err != nil {
		log.Errorf("Error creating the port: %v", err)
	}

	intfIP := fmt.Sprintf("%s/%d", self.routerIP, len)
	log.Debugf("Creating inb01 with ", intfIP)
	ofPortno, _ := self.agent.ovsDriver.GetOfpPortNo(self.intfName)

	link, err := netlink.LinkByName(self.intfName)
	if err != nil {
		log.Errorf("error finding link by name %v", self.intfName)
		return err
	}
	linkIP, err := netlink.ParseAddr(intfIP)
	if err != nil {
		log.Errorf("invalid ip: %s", intfIP)
		return err
	}
	netlink.AddrAdd(link, linkIP)
	netlink.LinkSetUp(link)
	if link == nil || ofPortno == 0 {
		log.Errorf("Error fetching %v/%v/%v information", self.intfName, link, ofPortno)
		return errors.New("Unable to fetch inb01 info")
	}

	intf, _ := net.InterfaceByName(self.intfName)
	vrf := "default"
	epid := self.agent.getEndpointIdByIpVrf(net.ParseIP(self.routerIP), vrf)
	default_vlan := uint16(1)
	_, ok := self.agent.createVrf(vrf)
	if !ok {
		log.Errorf("Error Creating default vrf for Bgp")
		return errors.New("Error creating default vrf")
	}
	self.agent.vlanVrf[default_vlan] = &vrf

	ep := &OfnetEndpoint{
		EndpointID:   epid,
		EndpointType: "internal-bgp",
		IpAddr:       net.ParseIP(self.routerIP),
		IpMask:       net.ParseIP("255.255.255.255"),
		Vrf:          "default",                  // FIXME set VRF correctly
		MacAddrStr:   intf.HardwareAddr.String(), //link.Attrs().HardwareAddr.String(),
		Vlan:         default_vlan,
		PortNo:       ofPortno,
		Timestamp:    time.Now(),
	}

	// Add the endpoint to local routing table

	err = self.agent.datapath.AddLocalEndpoint(*ep)
	if err != nil {
		log.Errorf("Error Adding Local Bgp Endpoint for endpoint %+v,err: %v", ep, err)
		return err
	}
	self.agent.endpointDb.Set(epid, ep)
	self.agent.localEndpointDb.Set(string(ep.PortNo), ep)

	// global configuration
	global := &bgpconf.Global{
		Config: bgpconf.GlobalConfig{
			As:       self.myBgpAs,
			RouterId: self.routerIP,
			Port:     179,
		},
	}

	if err := self.bgpServer.Start(global); err != nil {
		return err
	}

	//monitor route updates from peer, peer state
	go self.watch()
	// register for link ups on uplink and inb01 intf
	self.start <- true
	return nil
}
Beispiel #23
0
func AddVlannetwork(etcdval string, vlanid string, containerName string) {
	ss := strings.Split(etcdval, ",")
	hostif := ss[0]
	if ok := utils.ValidateHostIface(hostif); !ok {
		log.Warnf("the host interface not exist")
		return
	}

	vlandevName := hostif + "." + vlanid
	hostEth, _ := netlink.LinkByName(hostif)

	intvlanid, err := strconv.Atoi(vlanid)
	if err != nil {
		log.Warnf("the vlan id convert error: \n")
		return
	}

	var vlandev *netlink.Vlan
	if ok := utils.ValidateHostIface(vlandevName); ok {

	} else {
		//not exist ,create the vlan device
		vlandev = &netlink.Vlan{
			LinkAttrs: netlink.LinkAttrs{
				Name:        vlandevName,
				ParentIndex: hostEth.Attrs().Index,
			},
			VlanId: intvlanid,
		}
		if err := netlink.LinkAdd(vlandev); err != nil {
			log.Warnf("failed to create vlandev: [ %v ] with the error: %s", vlandev, err)
			return
		}
	}

	netlink.LinkSetUp(vlandev)
	macvlanname, _ := utils.GenerateRandomName("vlan"+vlanid, 5)
	//create the macvlan device
	macvlandev := &netlink.Macvlan{
		LinkAttrs: netlink.LinkAttrs{
			Name:        macvlanname,
			ParentIndex: vlandev.Attrs().Index,
		},
		Mode: netlink.MACVLAN_MODE_BRIDGE,
	}

	if err := netlink.LinkAdd(macvlandev); err != nil {
		log.Warnf("failed to create Macvlan: [ %v ] with the error: %s", macvlandev, err)
		return
	}

	dockerPid := utils.DockerPid(containerName)
	//the macvlandev can be use directly, don't get netlink.byname again.
	netlink.LinkSetNsPid(macvlandev, dockerPid)

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	//get root network naAddVlannetworkmespace
	origns, _ := netns.Get()
	defer origns.Close()

	//enter the docker container network
	dockerNS, _ := netns.GetFromPid(dockerPid)
	defer dockerNS.Close()

	netns.Set(dockerNS)

	netlink.LinkSetDown(macvlandev)
	netlink.LinkSetName(macvlandev, "eth1")

	_, network, _ := net.ParseCIDR(ss[1])
	if _, ok := ipallocs[vlanid]; !ok {
		log.Fatalf("the ipallocator is null \n")
	}
	ip, _ := ipallocs[vlanid].RequestIP(network, nil)
	ind := strings.LastIndex(ss[1], "/")
	ipstring := ip.String() + ss[1][ind:]

	addr, err := netlink.ParseAddr(ipstring)

	netlink.AddrAdd(macvlandev, addr)
	netlink.LinkSetUp(macvlandev)

	/*
		routes, _ := netlink.RouteList(nil, netlink.FAMILY_V4)
		for _, r := range routes {
			if r.Dst == nil {
				if err := netlink.RouteDel(&r); err != nil {
					log.Warnf("delete the default error: ", err)
				}
			}
		}

		if CligwIP == "" {
			log.Fatal("container gw is null")
		}

		defaultRoute := &netlink.Route{
			Dst:       nil,
			Gw:        net.ParseIP(CligwIP),
			LinkIndex: macvlandev1.Attrs().Index,
		}
		if err := netlink.RouteAdd(defaultRoute); err != nil {
			log.Warnf("create default route error: ", err)
		}
	*/
	netns.Set(origns)
}
func (v *veth) initialize(config *network) error {
	peer := config.TempVethPeerName
	if peer == "" {
		return fmt.Errorf("peer is not specified")
	}
	child, err := netlink.LinkByName(peer)
	if err != nil {
		return err
	}
	if err := netlink.LinkSetDown(child); err != nil {
		return err
	}
	if err := netlink.LinkSetName(child, config.Name); err != nil {
		return err
	}
	// get the interface again after we changed the name as the index also changes.
	if child, err = netlink.LinkByName(config.Name); err != nil {
		return err
	}
	if config.MacAddress != "" {
		mac, err := net.ParseMAC(config.MacAddress)
		if err != nil {
			return err
		}
		if err := netlink.LinkSetHardwareAddr(child, mac); err != nil {
			return err
		}
	}
	ip, err := netlink.ParseAddr(config.Address)
	if err != nil {
		return err
	}
	if err := netlink.AddrAdd(child, ip); err != nil {
		return err
	}
	if config.IPv6Address != "" {
		ip6, err := netlink.ParseAddr(config.IPv6Address)
		if err != nil {
			return err
		}
		if err := netlink.AddrAdd(child, ip6); err != nil {
			return err
		}
	}
	if err := netlink.LinkSetMTU(child, config.Mtu); err != nil {
		return err
	}
	if err := netlink.LinkSetUp(child); err != nil {
		return err
	}
	if config.Gateway != "" {
		gw := net.ParseIP(config.Gateway)
		if err := netlink.RouteAdd(&netlink.Route{
			Scope:     netlink.SCOPE_UNIVERSE,
			LinkIndex: child.Attrs().Index,
			Gw:        gw,
		}); err != nil {
			return err
		}
	}
	if config.IPv6Gateway != "" {
		gw := net.ParseIP(config.IPv6Gateway)
		if err := netlink.RouteAdd(&netlink.Route{
			Scope:     netlink.SCOPE_UNIVERSE,
			LinkIndex: child.Attrs().Index,
			Gw:        gw,
		}); err != nil {
			return err
		}
	}
	return nil
}
Beispiel #25
0
// configureInterface is used to configure an individual interface against a
// matched configuration. It sets up the addresses, the MTU, and invokes DHCP if
// necessary.
func configureInterface(link netlink.Link, netconf *kurmaNetworkInterface) error {
	linkName := link.Attrs().Name
	addressConfigured := true

	// configure using DHCP
	if netconf.DHCP {
		cmd := exec.Command("udhcpc", "-i", linkName, "-t", "20", "-n")
		cmd.Stdin = nil
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stderr
		if err := cmd.Run(); err != nil {
			return fmt.Errorf("failed to configure %s with DHCP: %v", linkName, err)
		}
		addressConfigured = true
	}

	// single address
	if netconf.Address != "" {
		addr, err := netlink.ParseAddr(netconf.Address)
		if err != nil {
			return fmt.Errorf("failed to parse address %q on %s", netconf.Address, linkName)
		}
		if err := netlink.AddrAdd(link, addr); err != nil {
			return fmt.Errorf("failed to configure address %q on %s: %v",
				netconf.Address, linkName, err)
		}
		addressConfigured = true
	}

	// list of addresses
	for _, address := range netconf.Addresses {
		addr, err := netlink.ParseAddr(address)
		if err != nil {
			return fmt.Errorf("failed to parse address %q on %s", address, linkName)
		}
		if err := netlink.AddrAdd(link, addr); err != nil {
			return fmt.Errorf("failed to configure address %q on %s: %v",
				address, linkName, err)
		}
		addressConfigured = true
	}

	if !addressConfigured {
		return fmt.Errorf("no address configured to %s: unable to set link up", linkName)
	}

	if netconf.MTU > 0 {
		if err := netlink.LinkSetMTU(link, netconf.MTU); err != nil {
			return fmt.Errorf("failed to set mtu on %s: %v", linkName, err)
		}
	}

	// verify it is up at the end
	if link.Attrs().Flags&net.FlagUp == 0 {
		if err := netlink.LinkSetUp(link); err != nil {
			return fmt.Errorf("failed to set link %s up: %v", linkName, err)
		}
	}

	return nil
}
Beispiel #26
0
/*
Bgp serve routine does the following:
1) Creates inb01 router port
2) Add MyBgp endpoint
3) Kicks off routines to monitor route updates and peer state
*/
func (self *OfnetBgp) StartProtoServer(routerInfo *OfnetProtoRouterInfo) error {
	log.Infof("Starting the Bgp Server with %v", routerInfo)
	//go routine to start gobgp server
	var len uint
	var err error
	self.routerIP, len, err = ParseCIDR(routerInfo.RouterIP)
	as, _ := strconv.Atoi(routerInfo.As)
	self.myBgpAs = uint32(as)
	log.Infof("Starting the Bgp Server for AS %v", self.myBgpAs)

	self.modRibCh = make(chan *api.Path, 16)
	self.advPathCh = make(chan *api.Path, 16)

	timeout := grpc.WithTimeout(time.Second)
	conn, err := grpc.Dial("127.0.0.1:50051", timeout, grpc.WithBlock(), grpc.WithInsecure())
	if err != nil {
		log.Infof("GRPC timeout")
		log.Fatal(err)
	}
	self.cc = conn
	defer self.cc.Close()

	client := api.NewGobgpApiClient(self.cc)
	if client == nil {
		log.Errorf("Invalid Gobgpapi client")
		return errors.New("Error creating Gobgpapiclient")
	}
	path := &api.Path{
		Pattrs: make([][]byte, 0),
	}

	path.Nlri, _ = bgp.NewIPAddrPrefix(uint8(32), self.routerIP).Serialize()
	n, _ := bgp.NewPathAttributeNextHop("0.0.0.0").Serialize()
	path.Pattrs = append(path.Pattrs, n)
	origin, _ := bgp.NewPathAttributeOrigin(bgp.BGP_ORIGIN_ATTR_TYPE_INCOMPLETE).Serialize()
	path.Pattrs = append(path.Pattrs, origin)

	log.Infof("Creating the loopback port ")
	err = self.agent.ovsDriver.CreatePort(self.intfName, "internal", 1)
	if err != nil {
		log.Errorf("Error creating the port: %v", err)
	}
	defer self.agent.ovsDriver.DeletePort(self.intfName)

	intfIP := fmt.Sprintf("%s/%d", self.routerIP, len)
	log.Infof("Creating inb01 with ", intfIP)
	ofPortno, _ := self.agent.ovsDriver.GetOfpPortNo(self.intfName)

	link, err := netlink.LinkByName(self.intfName)
	if err != nil {
		log.Errorf("error finding link by name %v", self.intfName)
		return err
	}
	linkIP, err := netlink.ParseAddr(intfIP)
	if err != nil {
		log.Errorf("invalid ip: %s", intfIP)
		return err
	}
	netlink.AddrAdd(link, linkIP)
	netlink.LinkSetUp(link)
	if link == nil || ofPortno == 0 {
		log.Errorf("Error fetching %v/%v/%v information", self.intfName, link, ofPortno)
		return errors.New("Unable to fetch inb01 info")
	}

	intf, _ := net.InterfaceByName(self.intfName)
	log.Infof("routerIP ", self.routerIP)
	epid := self.agent.getEndpointIdByIpVrf(net.ParseIP(self.routerIP), "default")
	log.Infof("Create VRF ")
	_, ok := self.agent.createVrf("default")
	if !ok {
		log.Errorf("Error Creating default vrf for Bgp")
		return errors.New("Error creating default vrf")
	}

	epreg := &OfnetEndpoint{
		EndpointID:   epid,
		EndpointType: "internal-bgp",
		IpAddr:       net.ParseIP(self.routerIP),
		IpMask:       net.ParseIP("255.255.255.255"),
		Vrf:          "default",                  // FIXME set VRF correctly
		MacAddrStr:   intf.HardwareAddr.String(), //link.Attrs().HardwareAddr.String(),
		Vlan:         1,
		PortNo:       ofPortno,
		Timestamp:    time.Now(),
	}

	// Add the endpoint to local routing table

	self.agent.endpointDb[epid] = epreg
	//log.Infof("self.agent.endpointDb[epid] %v " , self.agent.endpointDb[epid] )
	self.agent.localEndpointDb[epreg.PortNo] = epreg
	fmt.Println(epreg)
	err = self.agent.datapath.AddLocalEndpoint(*epreg)
	//Add bgp router id as well
	bgpGlobalCfg := &bgpconf.Global{}
	setDefaultGlobalConfigValues(bgpGlobalCfg)
	bgpGlobalCfg.Config.RouterId = self.routerIP
	bgpGlobalCfg.Config.As = self.myBgpAs
	//self.bgpServer.SetGlobalType(*bgpGlobalCfg)
	_, err2 := client.StartServer(context.Background(), &api.StartServerRequest{
		Global: &api.Global{
			As:              uint32(self.myBgpAs),
			RouterId:        self.routerIP,
			ListenPort:      int32(epreg.PortNo),
			ListenAddresses: []string{self.routerIP},
			MplsLabelMin:    uint32(16000),
			MplsLabelMax:    uint32(1048575),
		},
	})
	log.Info("BGP -StartServer ERR  %v", err2)

	self.advPathCh <- path
	log.Infof("start monitoring ")
	//monitor route updates from peer
	go self.monitorBest()
	//monitor peer state
	go self.monitorPeer()
	self.start <- true
	for {
		select {
		case p := <-self.modRibCh:
			err = self.modRib(p)
			if err != nil {
				log.Error("failed to mod rib: ", err)
			}
		case <-self.stop:
			return nil
		}
	}
}