示例#1
0
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

}
示例#2
0
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
}