本文整理汇总了Golang中github.com/kandoo/beehive-netctrl/nom.UID函数的典型用法代码示例。如果您正苦于以下问题:Golang UID函数的具体用法?Golang UID怎么用?Golang UID使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了UID函数的13个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。
示例1: Rcv
func (p Poller) Rcv(msg bh.Msg, ctx bh.RcvContext) error {
dict := ctx.Dict(driversDict)
dict.ForEach(func(k string, v interface{}) {
node := nom.UID(k)
query := nom.FlowStatsQuery{
Node: node,
}
sendToMaster(query, node, ctx)
nd := v.(nodeDrivers)
for i := range nd.Drivers {
// TODO(soheil): remove the hardcoded value.
if nd.Drivers[i].OutPings > MaxPings {
ctx.SendToBee(nom.NodeDisconnected{
Node: nom.Node{ID: nom.NodeID(node)},
Driver: nd.Drivers[i].Driver,
}, ctx.ID())
continue
}
ctx.SendToBee(nom.Ping{}, nd.Drivers[i].BeeID)
nd.Drivers[i].OutPings++
}
if err := dict.Put(k, nd); err != nil {
glog.Warningf("error in encoding drivers: %v", err)
}
})
return nil
}
示例2: NodesCentralized
// NodesCentralized returns the nodes with outgoing links so far.
//
// Note that this methods should be used only when the GraphBuilderCentralized
// is in use.
func NodesCentralized(ctx bh.RcvContext) (nodes []nom.UID) {
ctx.Dict(GraphDict).ForEach(func(k string, v interface{}) bool {
nodes = append(nodes, nom.UID(k))
return true
})
return nodes
}
示例3: allPaths
func allPaths(from, to nom.UID, visited map[nom.UID]distAndLinks) (
[][]nom.Link, int) {
if from == to {
return nil, 0
}
todl, ok := visited[to]
if !ok {
return nil, -1
}
var paths [][]nom.Link
for _, l := range todl.BackLinks {
lfn, _ := nom.ParsePortUID(l.From)
prevpaths, _ := allPaths(from, nom.UID(lfn), visited)
if len(prevpaths) == 0 {
paths = append(paths, []nom.Link{l})
continue
}
for _, p := range prevpaths {
paths = append(paths, append(p, l))
}
}
return paths, todl.Dist
}
示例4: decodeLLDP
func decodeLLDP(b []byte) (nom.Node, nom.Port, error) {
h := lldp.NewLinkDiscoveryProtocolWithBuf(b)
size := h.Size()
tlvb := b[size:]
chTLV := lldp.NewChassisMacTLVWithBuf(tlvb)
if chTLV.Size() == 0 {
return nom.Node{}, nom.Port{}, errors.New("decodeLLDP: no chassis id")
}
n := nom.Node{
MACAddr: chTLV.MacAddr(),
}
size += chTLV.Size()
tlvb = b[size:]
pTLV := lldp.NewLinkDiscoveryTLVWithBuf(tlvb)
if pTLV.Size() == 0 || pTLV.Type() != uint8(lldp.TLV_PORT_ID) {
return nom.Node{}, nom.Port{}, errors.New("decodeLLDP: no port id")
}
v := pTLV.Value()
if v[0] != uint8(lldp.PORT_TLV_IFACE_NAME) {
return nom.Node{}, nom.Port{}, errors.New("decodeLLDP: no port iface name")
}
portUID := nom.UID(v[1:])
nID, pID := nom.ParsePortUID(portUID)
n.ID = nID
return n, nom.Port{ID: pID, Node: n.UID()}, nil
}
示例5: TestAddP2PPath
func TestAddP2PPath(t *testing.T) {
ctx := buildTopologyForTest()
p := addHandler{}
msg := &bh.MockMsg{
MsgData: nom.AddPath{},
}
err := p.Rcv(msg, ctx)
if err == nil {
t.Error("no error on invalid path")
}
msg.MsgData = nom.AddPath{
Path: nom.Path{
Pathlets: []nom.Pathlet{
{
Match: nom.Match{
Fields: []nom.Field{
nom.InPort("n1$$0"),
},
},
Actions: []nom.Action{
nom.ActionForward{
Ports: []nom.UID{"n6$$3"},
},
},
},
},
Priority: 1,
},
}
if err := p.Rcv(msg, ctx); err != nil {
t.Errorf("cannot install flows for path: %v", err)
}
if len(ctx.CtxMsgs) == 0 {
t.Error("no flows installed")
}
iports := []nom.UID{"n1$$0", "n2$$1", "n4$$1", "n6$$1"}
oports := []nom.UID{"n1$$1", "n2$$2", "n4$$2", "n6$$3"}
for i, msg := range ctx.CtxMsgs {
add := msg.Data().(nom.AddFlowEntry)
if add.Flow.Priority != 1 {
t.Errorf("invalid flow priority: actual=%v want=1", add.Flow.Priority)
}
iport, ok := add.Flow.Match.InPort()
if !ok {
t.Errorf("flow #%v has no in ports", i)
} else if nom.UID(iport) != iports[i] {
t.Errorf("invalid input port on flow #%v: actual=%v want=%v", i, iport,
iports[i])
}
oport := add.Flow.Actions[0].(nom.ActionForward).Ports[0]
if oport != oports[i] {
t.Errorf("invalid output port on flow #%v: actual=%v want=%v", i, oport,
oports[i])
}
}
}
示例6: Rcv
func (p Poller) Rcv(msg bh.Msg, ctx bh.RcvContext) error {
ctx.Dict("Switches").ForEach(func(k string, v interface{}) {
fmt.Printf("poller: polling switch %v\n", k)
ctx.Emit(nom.FlowStatsQuery{
Node: nom.UID(k),
})
})
return nil
}
示例7: ShortestPathCentralized
// ShortestPathCentralized calculates the shortest path from node "from" to node
// "to" according to the state stored in GraphDict by the
// GraphBuilderCentralized.
//
// This method is not go-routine safe and must be called within a handler of the
// application that uses the GraphBuilderCentralized as a handler. Otherwise,
// the user needs to synchronize the two.
func ShortestPathCentralized(from, to nom.UID, ctx bh.RcvContext) (
paths [][]nom.Link, length int) {
if from == to {
return nil, 0
}
visited := make(map[nom.UID]distAndLinks)
visited[from] = distAndLinks{Dist: 0}
pq := nodeAndDistSlice{{Dist: 0, Node: from}}
heap.Init(&pq)
dict := ctx.Dict(GraphDict)
for len(pq) != 0 {
nd := heap.Pop(&pq).(nodeAndDist)
if nd.Node == to {
continue
}
nodeLinks := make(map[nom.UID][]nom.Link)
if v, err := dict.Get(string(nd.Node)); err == nil {
nodeLinks = v.(map[nom.UID][]nom.Link)
}
nd.Dist = visited[nd.Node].Dist
for _, links := range nodeLinks {
for _, l := range links {
nid, _ := nom.ParsePortUID(l.To)
ton := nom.UID(nid)
if dl, ok := visited[ton]; ok {
switch {
case nd.Dist+1 < dl.Dist:
glog.Fatalf("invalid distance in BFS")
case nd.Dist+1 == dl.Dist:
dl.BackLinks = append(dl.BackLinks, l)
visited[ton] = dl
}
continue
}
visited[ton] = distAndLinks{
Dist: nd.Dist + 1,
BackLinks: []nom.Link{l},
}
ndto := nodeAndDist{
Dist: nd.Dist + 1,
Node: ton,
}
heap.Push(&pq, ndto)
}
}
}
return allPaths(from, to, visited)
}
示例8: Rcv
func (r LoadBalancer) Rcv(msg bh.Msg, ctx bh.RcvContext) error {
switch dm := msg.Data().(type) {
case setup:
return registerEndhosts2(ctx)
case nom.LinkAdded:
link := InterAreaLink(dm)
ctx.Emit(link)
return r.GraphBuilderCentralized.Rcv(msg, ctx)
case nom.LinkDeleted:
return r.GraphBuilderCentralized.Rcv(msg, ctx)
default:
in := msg.Data().(nom.PacketIn)
src := in.Packet.SrcMAC()
dst := in.Packet.DstMAC()
d := ctx.Dict(mac2port)
load_dict := ctx.Dict(load_on_nodes)
if dst.IsLLDP() {
return nil
}
// FIXME: Hardcoding the hardware address at the moment
srck := src.Key()
if dst.IsBroadcast() || dst.IsMulticast() {
fmt.Printf("Load Balancer: Received Broadcast or Multicast from %v\n", src)
return nil
}
sn := in.Node
dstk := dst.Key()
dst_port, dst_err := d.Get(dstk)
if dst_err != nil {
fmt.Printf("Load Balancer: Cant find dest node %v\n", dstk)
res, query_err := ctx.Sync(context.TODO(), InterAreaQuery{Src: srck, Dst: dstk})
if query_err != nil {
fmt.Printf("Load Balancer: received error when querying! %v\n", query_err)
}
fmt.Printf("Load Balancer: received response succesfully - %v\n", res)
dst_port = res.(nom.UID)
}
dn, _ := nom.ParsePortUID(dst_port.(nom.UID))
p := dst_port.(nom.UID)
if sn != nom.UID(dn) {
paths, _ := discovery.ShortestPathCentralized(sn, nom.UID(dn), ctx)
opt_path := paths[0]
min_load := calculate_load(ctx, paths[0])
for _, path := range paths[1:] {
load := calculate_load(ctx, path)
if load < min_load {
opt_path = path
min_load = load
}
}
fmt.Printf("Load Balancer: Routing flow from %v to %v - %v, %v\n", sn, nom.UID(dn), opt_path, len(opt_path))
p = opt_path[0].From
}
// Forward flow entry
add_forward := nom.AddFlowEntry{
Flow: nom.FlowEntry{
Node: in.Node,
Match: nom.Match{
Fields: []nom.Field{
nom.EthDst{
Addr: dst,
Mask: nom.MaskNoneMAC,
},
},
},
Actions: []nom.Action{
nom.ActionForward{
Ports: []nom.UID{p},
},
},
},
}
ctx.Reply(msg, add_forward)
// Reverse flow entry
add_reverse := nom.AddFlowEntry{
Flow: nom.FlowEntry{
Node: in.Node,
Match: nom.Match{
Fields: []nom.Field{
nom.EthDst{
Addr: src,
Mask: nom.MaskNoneMAC,
},
},
},
Actions: []nom.Action{
nom.ActionForward{
//.........这里部分代码省略.........
示例9: Rcv
func (r RouterM) Rcv(msg bh.Msg, ctx bh.RcvContext) error {
switch dm := msg.Data().(type) {
case area_setup:
fmt.Printf("Adding to ctx: %v\n", ctx)
d := ctx.Dict(cDict)
d.Put("master", "master")
return master_setup(ctx)
case InterAreaLink:
link := nom.Link(dm)
nf, _ := nom.ParsePortUID(link.From)
k := string(nf)
nt, _ := nom.ParsePortUID(link.To)
k2 := string(nt)
d := ctx.Dict(node2area)
nf_area, err := d.Get(k)
nt_area, err2 := d.Get(k2)
if err != nil || err2 != nil {
fmt.Printf("Node does not belong to any existing areas! %v, %v, %v\n", err, err2, ctx)
return nil
}
if nf_area != nt_area {
link.From = nom.UID(nf_area.(string) + "$$" + strings.Replace(string(link.From), "$$", tmpD, 1))
link.To = nom.UID(nt_area.(string) + "$$" + strings.Replace(string(link.To), "$$", tmpD, 1))
fmt.Printf("Received Links from different areas, building graphs for %v, %v\n", link.From, link.To)
ctx.Emit(nom.LinkAdded(link))
}
return nil
case InterAreaQuery:
query := msg.Data().(InterAreaQuery)
srck := query.Src
dstk := query.Dst
d := ctx.Dict(mac2area)
src_area, src_err := d.Get(srck)
dst_area, dst_err := d.Get(dstk)
if src_err != nil || dst_err != nil {
fmt.Printf("Error retriving area info: %v, %v\n", src_err, dst_err)
return nil
}
paths, shortest_len := discovery.ShortestPathCentralized(nom.UID(src_area.(string)), nom.UID(dst_area.(string)), ctx)
if shortest_len <= 0 {
fmt.Printf("No route exists between area %v and area %v\n", src_area, dst_area)
return nil
}
fmt.Printf("Path between area %v and area %v returned %v\n", src_area, dst_area, paths)
for _, path := range paths {
if len(path) != shortest_len {
continue
} else {
_, port := nom.ParsePortUID(path[0].From)
port_conv := strings.Replace(string(port), tmpD, "$$", 1)
fmt.Printf("Sending converted port: %v\n", port_conv)
ctx.Reply(msg, nom.UID(port_conv))
break
}
}
return nil
case setupM:
m := msg.Data().(setupM)
return registerEndhostsAll(ctx, m.area)
case nom.LinkAdded:
// link := InterAreaLink(dm)
cd := ctx.Dict(cDict)
_, cerr := cd.Get("master")
if cerr != nil {
// ctx.Emit(link)
return r.GraphBuilderCentralized.Rcv(msg, ctx)
} else {
link := nom.Link(dm)
nf, _ := nom.ParsePortUID(link.From)
k := string(nf)
nt, _ := nom.ParsePortUID(link.To)
k2 := string(nt)
d := ctx.Dict(node2area)
nf_area, err := d.Get(k)
nt_area, err2 := d.Get(k2)
if err != nil || err2 != nil {
fmt.Printf("Node does not belong to any existing areas! %v, %v, %v\n", err, err2, ctx)
return nil
}
if nf_area != nt_area {
link.From = nom.UID(nf_area.(string) + "$$" + strings.Replace(string(link.From), "$$", tmpD, 1))
link.To = nom.UID(nt_area.(string) + "$$" + strings.Replace(string(link.To), "$$", tmpD, 1))
fmt.Printf("Received Links from different areas, building graphs for %v, %v\n", link.From, link.To)
InterAreaLinkAdded(link, ctx)
}
//.........这里部分代码省略.........
示例10: Rcv
func (m MasterController) Rcv(msg bh.Msg, ctx bh.RcvContext) error {
switch dm := msg.Data().(type) {
case area_setup:
fmt.Printf("Adding to ctx: %v\n", ctx)
return master_setup(ctx)
case InterAreaLink:
link := nom.Link(dm)
nf, _ := nom.ParsePortUID(link.From)
k := string(nf)
nt, _ := nom.ParsePortUID(link.To)
k2 := string(nt)
d := ctx.Dict(node2area)
nf_area, err := d.Get(k)
nt_area, err2 := d.Get(k2)
if err != nil || err2 != nil {
fmt.Printf("Node does not belong to any existing areas! %v, %v, %v\n", err, err2, ctx)
return nil
}
if nf_area != nt_area {
link.From = nom.UID(nf_area.(string) + "$$" + strings.Replace(string(link.From), "$$", tmpDelimiter, 1))
link.To = nom.UID(nt_area.(string) + "$$" + strings.Replace(string(link.To), "$$", tmpDelimiter, 1))
fmt.Printf("Received Links from different areas, building graphs for %v, %v\n", link.From, link.To)
ctx.Emit(nom.LinkAdded(link))
}
return nil
case nom.LinkAdded:
return m.GraphBuilderCentralized.Rcv(msg, ctx)
case InterAreaQuery:
query := msg.Data().(InterAreaQuery)
srck := query.Src
dstk := query.Dst
d := ctx.Dict(mac2area)
src_area, src_err := d.Get(srck)
dst_area, dst_err := d.Get(dstk)
if src_err != nil || dst_err != nil {
fmt.Printf("Error retriving area info: %v, %v\n", src_err, dst_err)
return nil
}
paths, shortest_len := discovery.ShortestPathCentralized(nom.UID(src_area.(string)), nom.UID(dst_area.(string)), ctx)
if shortest_len <= 0 {
fmt.Printf("No route exists between area %v and area %v\n", src_area, dst_area)
return nil
}
fmt.Printf("Path between area %v and area %v returned %v\n", src_area, dst_area, paths)
for _, path := range paths {
if len(path) != shortest_len {
continue
} else {
_, port := nom.ParsePortUID(path[0].From)
port_conv := strings.Replace(string(port), tmpDelimiter, "$$", 1)
fmt.Printf("Sending converted port: %v\n", port_conv)
ctx.Reply(msg, nom.UID(port_conv))
break
}
}
return nil
// case nom.LinkDeleted:
// return r.GraphBuilderCentralized.Rcv(msg, ctx)
// default:
// in := msg.Data().(nom.PacketIn)
// src := in.Packet.SrcMAC()
// dst := in.Packet.DstMAC()
//
// d := ctx.Dict(mac2port)
//
// if dst.IsLLDP() {
// return nil
// }
//
// // FIXME: Hardcoding the hardware address at the moment
// srck := src.Key()
// _, src_err := d.Get(srck)
// if src_err != nil {
// fmt.Printf("Router: Error retrieving hosts %v\n", src)
// }
//
// if dst.IsBroadcast() || dst.IsMulticast() {
// fmt.Printf("Router: Received Broadcast or Multicast from %v\n", src)
// return nil
// }
//
// sn := in.Node
//
// dstk := dst.Key()
// dst_port, dst_err := d.Get(dstk)
// if dst_err != nil {
// fmt.Printf("Router: Cant find dest node %v\n", dstk)
// dst_port, _ = d.Get("default")
//.........这里部分代码省略.........
示例11: ofMatch
func (d *of12Driver) ofMatch(m nom.Match) (of12.Match, error) {
ofm := of12.NewOXMatch()
for _, f := range m.Fields {
switch f := f.(type) {
case nom.InPort:
p, ok := d.nomPorts[nom.UID(f)]
if !ok {
return of12.Match{}, fmt.Errorf("of12Driver: nom port not found %v", f)
}
off := of12.NewOxmInPort()
off.SetInPort(p)
ofm.AddFields(off.OxmField)
case nom.EthDst:
if f.Mask == nom.MaskNoneMAC {
off := of12.NewOxmEthDst()
off.SetMacAddr([6]byte(f.Addr))
ofm.AddFields(off.OxmField)
} else {
off := of12.NewOxmEthDstMasked()
off.SetMacAddr([6]byte(f.Addr))
off.SetMask([6]byte(f.Mask))
ofm.AddFields(off.OxmField)
}
case nom.EthSrc:
if f.Mask == nom.MaskNoneMAC {
off := of12.NewOxmEthSrc()
off.SetMacAddr([6]byte(f.Addr))
ofm.AddFields(off.OxmField)
} else {
off := of12.NewOxmEthSrcMasked()
off.SetMacAddr([6]byte(f.Addr))
off.SetMask([6]byte(f.Mask))
ofm.AddFields(off.OxmField)
}
case nom.EthType:
off := of12.NewOxmEthType()
off.SetType(uint16(f))
ofm.AddFields(off.OxmField)
case nom.IPProto:
off := of12.NewOxmIpProto()
off.SetProto(uint8(f))
ofm.AddFields(off.OxmField)
case nom.IPv4Src:
if f.Mask == nom.MaskNoneIPV4 {
off := of12.NewOxmIpV4Src()
off.SetAddr(f.Addr)
ofm.AddFields(off.OxmField)
} else {
off := of12.NewOxmIpV4SrcMasked()
off.SetAddr(f.Addr)
off.SetMask(f.Mask)
ofm.AddFields(off.OxmField)
}
case nom.IPv4Dst:
if f.Mask == nom.MaskNoneIPV4 {
off := of12.NewOxmIpV4Dst()
off.SetAddr(f.Addr)
ofm.AddFields(off.OxmField)
} else {
off := of12.NewOxmIpV4DstMasked()
off.SetAddr(f.Addr)
off.SetMask(f.Mask)
ofm.AddFields(off.OxmField)
}
case nom.IPv6Src:
if f.Mask == nom.MaskNoneIPV6 {
off := of12.NewOxmIpV6Src()
off.SetAddr(f.Addr)
ofm.AddFields(off.OxmField)
} else {
off := of12.NewOxmIpV6SrcMasked()
off.SetAddr(f.Addr)
off.SetMask(f.Mask)
ofm.AddFields(off.OxmField)
}
case nom.IPv6Dst:
if f.Mask == nom.MaskNoneIPV6 {
off := of12.NewOxmIpV6Dst()
off.SetAddr(f.Addr)
ofm.AddFields(off.OxmField)
} else {
off := of12.NewOxmIpV6DstMasked()
off.SetAddr(f.Addr)
off.SetMask(f.Mask)
ofm.AddFields(off.OxmField)
}
case nom.TransportPortSrc:
off := of12.NewOxmTcpSrc()
off.SetPort(uint16(f))
ofm.AddFields(off.OxmField)
//.........这里部分代码省略.........
示例12: Rcv
func (r Router) Rcv(msg bh.Msg, ctx bh.RcvContext) error {
switch dm := msg.Data().(type) {
case setup:
return registerEndhosts(ctx)
case nom.LinkAdded:
link := InterAreaLink(dm)
ctx.Emit(link)
return r.GraphBuilderCentralized.Rcv(msg, ctx)
case nom.LinkDeleted:
return r.GraphBuilderCentralized.Rcv(msg, ctx)
default:
in := msg.Data().(nom.PacketIn)
src := in.Packet.SrcMAC()
dst := in.Packet.DstMAC()
d := ctx.Dict(mac2port)
if dst.IsLLDP() {
return nil
}
// FIXME: Hardcoding the hardware address at the moment
srck := src.Key()
_, src_err := d.Get(srck)
if src_err != nil {
fmt.Printf("Router: Error retrieving hosts %v\n", src)
}
if dst.IsBroadcast() || dst.IsMulticast() {
fmt.Printf("Router: Received Broadcast or Multicast from %v\n", src)
return nil
}
sn := in.Node
dstk := dst.Key()
dst_port, dst_err := d.Get(dstk)
if dst_err != nil {
fmt.Printf("Router: Cant find dest node %v\n", dstk)
res, query_err := ctx.Sync(context.TODO(), InterAreaQuery{Src: srck, Dst: dstk})
if query_err != nil {
fmt.Printf("Router: received error when querying! %v\n", query_err)
}
fmt.Printf("Router: received response succesfully - %v\n", res)
dst_port = res.(nom.UID)
}
dn, _ := nom.ParsePortUID(dst_port.(nom.UID))
p := dst_port.(nom.UID)
if sn != nom.UID(dn) {
paths, shortest_len := discovery.ShortestPathCentralized(sn, nom.UID(dn), ctx)
fmt.Printf("Router: Path between %v and %v returns %v, %v\n", sn, nom.UID(dn), paths, shortest_len)
for _, path := range paths {
if len(path) != shortest_len {
continue
} else {
p = path[0].From
break
}
}
}
// Forward flow entry
add_forward := nom.AddFlowEntry{
Flow: nom.FlowEntry{
Node: in.Node,
Match: nom.Match{
Fields: []nom.Field{
nom.EthDst{
Addr: dst,
Mask: nom.MaskNoneMAC,
},
},
},
Actions: []nom.Action{
nom.ActionForward{
Ports: []nom.UID{p},
},
},
},
}
ctx.Reply(msg, add_forward)
// Reverse flow entry
add_reverse := nom.AddFlowEntry{
Flow: nom.FlowEntry{
Node: in.Node,
Match: nom.Match{
Fields: []nom.Field{
nom.EthDst{
Addr: src,
Mask: nom.MaskNoneMAC,
},
},
},
Actions: []nom.Action{
//.........这里部分代码省略.........
示例13: genFlowsForPathlet
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
}
//.........这里部分代码省略.........