/* This is a helper function for find_paths(). It is used to find all possible paths between h1 and h2 starting at ssw. The resulting path is a "scramble" meaning that the set of links is a unique set of links that are traversed by one or more paths. The list of links can be traversed without the need to dup check which is beneficial for increasing/decreasing the utilisaition on the link. From a scramble, only end point queues can be set as the middle switches are NOT maintained. usr is the name of the user that the reservation is being processed for (project in openstack). The usr_max value is a percentage (1-100) that defines the maximum of any link that the user may have reservations against or a hard limit if larger than 100. */ func (n *Network) find_all_paths(ssw *gizmos.Switch, h1 *gizmos.Host, h2 *gizmos.Host, usr *string, commence int64, conclude int64, inc_cap int64, usr_max int64) (path *gizmos.Path, err error) { net_sheep.Baa(1, "find_all: searching for all paths between %s and %s", *(h1.Get_mac()), *(h2.Get_mac())) links, epsw, err := ssw.All_paths_to(h2.Get_mac(), commence, conclude, inc_cap, usr, usr_max) if err != nil { return } path = gizmos.Mk_path(h1, h2) path.Set_scramble(true) path.Set_bandwidth(inc_cap) path.Add_switch(ssw) path.Add_switch(epsw) lnk := n.find_vlink(*(ssw.Get_id()), h1.Get_port(ssw), -1, nil, nil) // add endpoint -- a virtual link out from switch to h1 lnk.Add_lbp(*(h1.Get_mac())) lnk.Set_forward(ssw) path.Add_endpoint(lnk) lnk = n.find_vlink(*(epsw.Get_id()), h2.Get_port(epsw), -1, nil, nil) // add endpoint -- a virtual link out from switch to h2 lnk.Add_lbp(*(h2.Get_mac())) lnk.Set_forward(epsw) path.Add_endpoint(lnk) for i := range links { path.Add_link(links[i]) } return }
/* Test some network pathfinding. Reads a topo from the static json file test_net.json and builds a network of hosts and links, then attempts to find all paths between them using the switch find all functions. */ func TestNet(t *testing.T) { // must use bloody camel case to be recognised by go testing var ( fsw *gizmos.Switch sw_list map[string]*gizmos.Switch ) sw_list = make(map[string]*gizmos.Switch) fmt.Fprintf(os.Stderr, "\n------------- net test starts -----------------\n") links, err := gizmos.Read_json_links("test_net.json") if err == nil { fmt.Fprintf(os.Stderr, "read %d links from the file\n", len(links)) } else { fmt.Fprintf(os.Stderr, "failed to read links: %s [FAIL]\n", err) t.Fail() return } last := "" fsw = nil for i := range links { // parse all links returned from the controller ssw := sw_list[links[i].Src_switch] if ssw == nil { ssw = gizmos.Mk_switch(&links[i].Src_switch) // source switch sw_list[links[i].Src_switch] = ssw } dsw := sw_list[links[i].Dst_switch] if dsw == nil { dsw = gizmos.Mk_switch(&links[i].Dst_switch) // dest switch sw_list[links[i].Dst_switch] = dsw } l := gizmos.Mk_link(ssw.Get_id(), dsw.Get_id(), 100000000, 95, nil) // link in forward direction l.Set_forward(dsw) l.Set_backward(ssw) ssw.Add_link(l) l = gizmos.Mk_link(dsw.Get_id(), ssw.Get_id(), 100000000, 95, nil) // link in backward direction l.Set_forward(ssw) l.Set_backward(dsw) dsw.Add_link(l) mac := fmt.Sprintf("00:00:00:00:00:%02d", i) ip := fmt.Sprintf("10.0.0.%02d", i) h := gizmos.Mk_host(mac, ip, "") h.Add_switch(ssw, i) // add a host to each src switch vmname := "foobar-name" ssw.Add_host(&ip, &vmname, i+200) fmt.Fprintf(os.Stderr, "adding host: %s\n", ip) if fsw == nil { // save first switch to use as start of search fsw = ssw } mac = fmt.Sprintf("%02d:00:00:00:00:00", i) ip = fmt.Sprintf("10.0.0.1%02d", i) h = gizmos.Mk_host(mac, ip, "") h.Add_switch(dsw, i) // add a host to each dest switch vmname2 := "foobar-name2" dsw.Add_host(&ip, &vmname2, i+200) fmt.Fprintf(os.Stderr, "adding host: %s\n", ip) last = ip } fmt.Fprintf(os.Stderr, ">>> searching for: %s\n", last) usrname := "username" fsw.All_paths_to(&last, 0, 0, 100, &usrname, 95) }