/* This is a helper function for find_paths and is invoked when we are interested in just the shortest path between two switches. It will find the shortest path, and then build a path structure which represents it. ssw is the starting switch and h2nm is the endpoint "name" (probably a mac that we are looking for. The usr_max value is the percentage (1-100) that indicates the maximum percentage of a link that the user may reserve. This function assumes that the switches have all been initialised with a reset of the visited flag, setting of inital cost, etc. */ func (n *Network) find_shortest_path(ssw *gizmos.Switch, h1 *gizmos.Host, h2 *gizmos.Host, usr *string, commence int64, conclude int64, inc_cap int64, usr_max int64) (path *gizmos.Path, cap_trip bool) { h1nm := h1.Get_mac() h2nm := h2.Get_mac() path = nil if usr_max <= 0 { i41, _ := h1.Get_addresses() i42, _ := h2.Get_addresses() net_sheep.Baa(1, "no path generated: user link capacity set to 0: attempt %s -> %s", *i41, *i42) return } ssw.Cost = 0 // seed the cost in the source switch tsw, cap_trip := ssw.Path_to(h2nm, commence, conclude, inc_cap, usr, usr_max) // discover the shortest path to terminating switch that has enough bandwidth if tsw != nil { // must walk from the term switch backwards collecting the links to set the path path = gizmos.Mk_path(h1, h2) path.Set_reverse(true) // indicate that the path is saved in reverse order path.Set_bandwidth(inc_cap) net_sheep.Baa(2, "find_spath: found target on %s", tsw.To_str()) lnk := n.find_vlink(*(tsw.Get_id()), h2.Get_port(tsw), -1, nil, nil) // add endpoint -- a virtual link out from switch to h2 lnk.Add_lbp(*h2nm) lnk.Set_forward(tsw) // endpoints have only a forward link path.Add_endpoint(lnk) for tsw != nil { if tsw.Prev != nil { // last node won't have a prev pointer so no link lnk = tsw.Prev.Get_link(tsw.Plink) path.Add_link(lnk) } path.Add_switch(tsw) net_sheep.Baa(3, "\t%s using link %d", tsw.Prev.To_str(), tsw.Plink) if tsw.Prev == nil { // last switch in the path, add endpoint lnk = n.find_vlink(*(tsw.Get_id()), h1.Get_port(tsw), -1, nil, nil) // endpoint is a virt link from switch to h1 lnk.Add_lbp(*h1nm) lnk.Set_forward(tsw) // endpoints have only a forward link path.Add_endpoint(lnk) } tsw = tsw.Prev } path.Flip_endpoints() // path expects them to be in h1,h2 order; we added them backwards so must flip } return }