func (h *intentHandler) Rcv(msg bh.Msg, ctx bh.RcvContext) error { hrq := msg.Data().(http.HTTPRequest) if hrq.AppName == "intent" && hrq.Verb == "build" { spd := shortestPathData{} err := json.Unmarshal(hrq.Data, &spd) if err != nil { glog.Errorf("Host list JSON unmarshaling: %v", err) return err } fmt.Println(spd) fmt.Println(discovery.ShortestPathCentralized(spd.From, spd.To, ctx)) hrs := http.HTTPResponse{ AppName: "host", Data: []byte{'A'}, } err = ctx.Reply(msg, hrs) if err != nil { glog.Errorf("Replay error: %v", err) return err } } return nil }
func genFlowsForPathlet(p nom.Pathlet, inport nom.UID, priority uint16, ctx bh.RcvContext) (flows []nom.FlowEntry, outports []nom.UID, err error) { fwdnps := forwardNodes(p.Actions) for _, ports := range fwdnps { outports = append(outports, ports...) } floodns := floodNodes(p.Actions) for n, p := range floodns { outports = append(outports, outPortsFromFloodNode(n, p, ctx)...) } port, matchHasPort := p.Match.InPort() if matchHasPort { if inport != nom.Nil && inport != nom.UID(port) { return nil, nil, fmt.Errorf("path: two different inports %v and %v", inport, port) } inport = nom.UID(port) } m := p.Match if inport != nom.Nil && !matchHasPort { m = p.Match.Clone() m.Fields = append(m.Fields, nom.InPort(inport)) } noinMatch := p.Match.Clone() for f := range m.Fields { if _, ok := m.Fields[f].(nom.InPort); ok { noinMatch.Fields = append(noinMatch.Fields[:f], m.Fields[f+1:]...) break } } nofwdActions := make([]nom.Action, 0, len(p.Actions)) for _, a := range p.Actions { switch a.(type) { case nom.ActionForward, nom.ActionFlood: continue default: nofwdActions = append(nofwdActions, a) } } var innodes []nom.UID if inport != nom.Nil { innodes = []nom.UID{nom.NodeFromPortUID(inport)} } else { innodes = discovery.NodesCentralized(ctx) } for _, inn := range innodes { for _, outp := range outports { outn := nom.NodeFromPortUID(outp) sps, l := discovery.ShortestPathCentralized(inn, outn, ctx) if l < 0 { // TODO(soheil): maybe just log this and continue installing other // flows. return nil, nil, fmt.Errorf("path: no path found from %v to %v", inport, outp) } if l == 0 { m := noinMatch.Clone() if inport != nom.Nil { m.Fields = append(m.Fields, nom.InPort(inport)) } flow := nom.FlowEntry{ Node: outn, Match: m, Actions: p.Actions, Priority: priority, } flows = append(flows, flow) continue } // TODO(soheil): maybe install multiple paths. lastInPort := inport for _, link := range sps[0] { m := noinMatch.Clone() if lastInPort != nom.Nil { m.Fields = append(m.Fields, nom.InPort(lastInPort)) } var a []nom.Action a = append(a, nofwdActions...) a = append(a, nom.ActionForward{Ports: []nom.UID{link.From}}) flow := nom.FlowEntry{ Node: nom.NodeFromPortUID(link.From), Match: m, Actions: a, Priority: priority, } flows = append(flows, flow) lastInPort = link.To } m := noinMatch.Clone() if lastInPort != nom.Nil { m.Fields = append(m.Fields, nom.InPort(lastInPort)) } flow := nom.FlowEntry{ Node: outn, Match: m, Actions: p.Actions, Priority: priority, } flows = append(flows, flow) } } return flows, outports, nil }