frenetic-lang / pyretic

The Pyretic language and runtime system
http://frenetic-lang.org/pyretic/
159 stars 99 forks source link

Inport error in Pyretic #61

Closed Venkat136 closed 8 years ago

Venkat136 commented 8 years ago

I got an error saying this : 2:e7:90:2e:a8:23 ff:ff:ff:ff:ff:ff 1 error: uncaptured python exception, closing channel <pyretic.backend.backend.BackendChannel connected 127.0.0.1:57348 at 0x7f263a67ca28> (<type 'exceptions.KeyError'>:'inport' [/usr/lib/python2.7/asyncore.py|read|83] [/usr/lib/python2.7/asyncore.py|handle_read_event|449] [/usr/lib/python2.7/asynchat.py|handle_read|167] [/root/pyretic/pyretic/backend/backend.py|found_terminator|111] [/root/pyretic/pyretic/core/runtime.py|handle_packet_in|365] [/root/pyretic/pyretic/core/language.py|apply|770] [/root/pyretic/pyretic/tutorial/yen_ksp.py|mymac_learner|251] [/root/pyretic/pyretic/core/packet.py|getitem|530] [/root/pyretic/pyretic/core/util.py|getitem|127])

I have tried everything i can and I'm struck . Can anyone please help me out ?

SiGe commented 8 years ago

Hey @Venkat136,

Could you share a small example which reproduces the error please? Feel free to use gist.github.com.

Venkat136 commented 8 years ago

from pyretic.lib.corelib import from pyretic.lib.std import from pyretic.lib.pox_client import from multiprocessing import Lock from pyretic.lib.query import from collections import defaultdict from operator import itemgetter import random import copy

switches

switches = []

myhost[srcmac]->(switch, port)

myhost={}

adjacency map [sw1][sw2]->port from sw1 to sw2

adjacency=defaultdict(lambda:defaultdict(lambda:None))

ip1 = IPAddr('10.0.0.1') ip2 = IPAddr('10.0.0.2')

def minimum_distance(distance, Q): min = float('Inf') node = 0 for v in Q: if distance[v] <= min: min = distance[v] node = v return node

def path(previous, node_start, node_end): r=[] p=node_end r.append(p) q=previous[p] while q is not None: if q == node_start: r.append(q) break p=q r.append(p) q=previous[p]

r.reverse() if node_start==node_end: path=[node_start] else: path=r return r

def dijkstra(graph, node_start, node_end=None): distances = {}
previous = {}

for dpid in switches:
  distances[dpid] = float('Inf')
  previous[dpid] = None

distances[node_start]=0
Q=set(switches)

while len(Q)>0:
  u = minimum_distance(distances, Q)
  Q.remove(u)  

  for p in switches:
    if graph[u][p]!=None:
      w = 1
      if distances[u] + w < distances[p]:
        distances[p] = distances[u] + w
        previous[p] = u

if node_end:
    return {'cost': distances[node_end],
            'path': path(previous, node_start, node_end)}
else:
    return (distances, previous)

def yen_ksp(src,dst,first_port,final_port,max_k=2): print "YenKSP is called" print "src=",src," dst=",dst, " first_port=", first_port, " final_port=", final_port, " max_k=", max_k adjacency2=defaultdict(lambda:defaultdict(lambda:None))

distances, previous = dijkstra(adjacency,src) A = [{'cost': distances[dst], 'path': path(previous, src, dst)}] B = []

print "distances=", distances

print "previous=", previous

print "A=", A

if not A[0]['path']: return A

for k in range(1, max_k): adjacency2=copy.deepcopy(adjacency)

print "k=", k, " adjacency2=", adjacency2

for i in range(0, len(A[-1]['path']) - 1):
  node_spur = A[-1]['path'][i]
  path_root = A[-1]['path'][:i+1]
  #print "node_spur=", node_spur, " path_root=", path_root
  for path_k in A:
    curr_path = path_k['path']
    #print "curr_path=", curr_path, " i=", i
    if len(curr_path) > i and path_root == curr_path[:i+1]:
      adjacency2[curr_path[i]][curr_path[i+1]]=None
      #print "link[", curr_path[i],"][", curr_path[i+1], "] is removed"

  path_spur = dijkstra(adjacency2, node_spur, dst)
  #print "path_spur=", path_spur

  if path_spur['path']:
    path_total = path_root[:-1] + path_spur['path']
    #print "path_total=", path_total
    dist_total = distances[node_spur] + path_spur['cost']
    #print "dist_total=", path_total
    potential_k = {'cost': dist_total, 'path': path_total}
    #print "potential_k=", potential_k

    if not (potential_k in B):
      B.append(potential_k)
      #print "B=", B

if len(B):
  B = sorted(B, key=itemgetter('cost'))
  #print "after sorting, B=", B
  A.append(B[0])
  B.pop(0)
  #print "after poping out the first element, B=", B, " A=", A
else:
  break

tmp=[] print "YenKSP->" for path_k in A: selected_path = path_k['path'] print selected_path tmp.append(selected_path)

ChosenPath=random.choice(tmp) print "Chosen Path=", ChosenPath

Now add the ports

r = [] in_port = first_port for s1,s2 in zip(ChosenPath[:-1],ChosenPath[1:]): out_port = adjacency[s1][s2] r.append((s1,in_port,out_port)) in_port = adjacency[s2][s1] r.append((dst,in_port,final_port))

print r

return r

def get_path (src,dst,first_port,final_port): print "Dijkstra's algorithm" print "src=",src," dst=",dst, " first_port=", first_port, " final_port=", final_port distance = {} previous = {}

for dpid in switches: distance[dpid] = float('Inf') previous[dpid] = None

distance[src]=0 Q=set(switches)

while len(Q)>0: u = minimum_distance(distance, Q) Q.remove(u)

for p in switches:
  if adjacency[u][p]!=None:
    w = 1
    if distance[u] + w < distance[p]:
      distance[p] = distance[u] + w
      previous[p] = u

r=[] p=dst r.append(p) q=previous[p] while q is not None: if q == src: r.append(q) break p=q r.append(p) q=previous[p]

r.reverse() if src==dst: path=[src] else: path=r

Now add the ports

r = [] in_port = first_port for s1,s2 in zip(path[:-1],path[1:]): out_port = adjacency[s1][s2] r.append((s1,in_port,out_port)) in_port = adjacency[s2][s1] r.append((dst,in_port,final_port)) return r

class find_route(DynamicPolicy): def init(self): super(find_route,self).init() self.flood = flood() self.set_initial_state()

def set_initial_state(self): self.query = packets(1,['srcmac','dstmac', 'srcip', 'dstip']) self.query.register_callback(self.myroute) self.forward = self.flood self.update_policy()

def set_network(self,network): self.set_initial_state()

def update_policy(self): self.policy = self.forward + self.query

def myroute(self,pkt):

print pkt['srcmac'], pkt['dstmac'], pkt['srcip'], pkt['dstip']

if (pkt['srcmac'] not in myhost.keys()) or (pkt['dstmac'] not in myhost.keys()):
  return
#print myhost[pkt['srcmac']][0], myhost[pkt['dstmac']][0]
#if match(ethtype=IP_TYPE):
#  print "ipv4 packet"
if pkt['srcip']==ip1 and pkt['dstip']==ip2:
  # select 3 paths
  p1 = yen_ksp(myhost[pkt['srcmac']][0], myhost[pkt['dstmac']][0],myhost[pkt['srcmac']][1], myhost[pkt['dstmac']][1], 3)
else:
  p1 = get_path(myhost[pkt['srcmac']][0], myhost[pkt['dstmac']][0],myhost[pkt['srcmac']][1], myhost[pkt['dstmac']][1])
print p1

r1 = parallel([(match(switch=a,srcip=pkt['srcip'],dstip=pkt['dstip']) >> fwd(c)) for a,b,c in p1])

self.forward = if_(match(dstip=pkt['dstip'],srcip=pkt['srcip']),r1,self.forward)
self.update_policy()

def find_host(): q = packets(1,['srcmac','switch']) q.register_callback(mymac_learner) return q

def mymac_learner(pkt):

print pkt['srcmac'], pkt['dstmac'], pkt['switch'], pkt['inport']

if match(ethtype=ARP_TYPE):

print "arp packet"

if pkt['srcmac'] not in myhost.keys(): myhost[pkt['srcmac']]=( pkt['switch'], pkt['inport'])

class find_switch(DynamicPolicy): def init(self): self.last_topology = None self.lock = Lock() super(find_switch,self).init()

def set_network(self, network):
    with self.lock:
        for x in network.switch_list():
          switches.append(x)
        for (s1,s2,data) in network.topology.edges(data=True):
          adjacency[s1][s2]=data[s1]
          adjacency[s2][s1]=data[s2]
        self.last_topology = network.topology

def arp_andip(): return if(match(ethtype=ARP_TYPE), flood(), find_route())

def main():

return ( find_switch() + find_host() + arp_and_ip())

SiGe commented 8 years ago

Try just port instead of inport for the packet fields.

Venkat136 commented 8 years ago

thanks it worked.. but stilll i get an error message saying like this : ERROR PUSHING MESSAGE ['packet', {'raw': '\xbeF\xb1\xee\xd2\xa8\x92t\xc5\xd8A\x08\x06\x00\x01\x08\x00\x06\x04\x00\x02\x92t\xc5\xd8A\n\x00\x00\x01\xbeF\xb1\xee\xd2\xa8\n\x00\x00\x02', 'switch': 1, 'port': 1}, 0]