0

I am working on implemanting mpls in ryu, I have written the app using openflow actions: Push Mpls; Pop.. But I don't know why somehow I am getting only 1/2 of ping when pinging.

As I am working in a looped topology, I used networkx in order to get the out port through which the packets will be forwarded.

def push_mpls(self, ev, out_port):
    msg = ev.msg
    datapath = msg.datapath
    ofproto = datapath.ofproto
    parser = datapath.ofproto_parser
    in_port = msg.match['in_port']
    dpid = format(datapath.id, "d").zfill(16)
    pkt = packet.Packet(msg.data)
    eth = pkt.get_protocols(ethernet.ethernet)[0]
    dst = eth.dst
    src = eth.src
    ethtype = eth.ethertype
    ip_header= ipv4.ipv4(dst='10.0.0.2', src='10.0.0.1')
    match = parser.OFPMatch(in_port=in_port, eth_dst=dst, eth_type=ethtype)
    self.label = self.label + 1
    self.logger.info("Flow actions: push MPLS=%s, out_port=%s, dst=%s, dpid=%s ", self.label, out_port, dst, dpid)
    pkt_mpls= packet.Packet()
    pkt_mpls.add_protocol(ethernet.ethernet(ethertype=ether_types.ETH_TYPE_MPLS,
                              dst=eth.dst,src= eth.src))
    pkt_mpls.add_protocol(mpls.mpls(label= self.label ))
    pkt_mpls.add_protocol(ip_header)
     

    pkt_mpls.serialize()
    data=msg.data
    #actions = [parser.OFPActionOutput(out_port)]
    actions = [ parser.OFPActionPushMpls(ethertype=ether_types.ETH_TYPE_MPLS ),parser.OFPActionSetField(mpls_label=self.label),parser.OFPActionOutput(3)]
    

    out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id,in_port=in_port, actions=actions,data=data)
    datapath.send_msg(out)
    
    self.add_flow(datapath, 1, match, actions)
   
    
def swap_mpls(self, ev, out_port):
    msg = ev.msg
    datapath = msg.datapath
    ofproto = datapath.ofproto
    parser = datapath.ofproto_parser
    in_port = msg.match['in_port']
    dpid = format(datapath.id, "d").zfill(16)
    pkt = packet.Packet(msg.data)
    eth = pkt.get_protocols(ethernet.ethernet)[0]
    dst = eth.dst
    src = eth.src
    ethtype = eth.ethertype
    ip_header= ipv4.ipv4(dst='10.0.0.2', src='10.0.0.1')
    mpls_proto = pkt.get_protocol(mpls.mpls)
    match = parser.OFPMatch(in_port=in_port, eth_dst=dst, eth_type=ethtype, mpls_label=mpls_proto.label )
    
    self.label = self.label + 1
    self.logger.info("Flow actions:  swap MPLS=%s, out_port=%s, dst=%s,  dpid=%s", self.label, out_port, dst, dpid)
    pkt_mpls= packet.Packet()
    pkt_mpls.add_protocol(ethernet.ethernet(ethertype=ether_types.ETH_TYPE_MPLS,
                              dst=eth.dst,src= eth.src))
    pkt_mpls.add_protocol(mpls.mpls(label= self.label))
    pkt_mpls.add_protocol(ip_header)
  
    pkt_mpls.serialize()
   
    data=msg.data
    
    
    #actions = [parser.OFPActionOutput(2)]
    actions = [parser.OFPActionPopMpls(), parser.OFPActionPushMpls(ethertype=ether_types.ETH_TYPE_MPLS),parser.OFPActionSetField(mpls_label=self.label), parser.OFPActionOutput(2)]
    
    out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id,in_port=in_port, actions=actions, data= msg.data)
    datapath.send_msg(out)
    self.add_flow(datapath, 1, match, actions)
    
def pop_mpls(self, ev, out_port):
    msg = ev.msg
    datapath = msg.datapath
    ofproto = datapath.ofproto
    parser = datapath.ofproto_parser
    in_port = msg.match['in_port']
    dpid = format(datapath.id, "d").zfill(16)
    pkt = packet.Packet(msg.data)
    eth = pkt.get_protocols(ethernet.ethernet)[0]
    dst = eth.dst
    src = eth.src
    ethtype = eth.ethertype
    ip_header= ipv4.ipv4(dst='10.0.0.2', src='10.0.0.1')
    mpls_proto = pkt.get_protocol(mpls.mpls)
    
    if mpls_proto is not None:
        mpls_label=mpls_proto.label
        match = parser.OFPMatch(in_port=in_port, eth_dst=dst, eth_type=ethtype, mpls_label=mpls_proto.label )
    else:
        match = parser.OFPMatch(in_port=in_port, eth_dst=dst, eth_type=ethtype)
    self.logger.info("Flow actions:  Pop MPLS=%s, out_port=%s, dst=%s , dpid=%s", self.label, out_port, dst, dpid)
    
    data = msg.data
    #actions = [parser.OFPActionOutput(3)]
    actions = [parser.OFPActionPopMpls(),parser.OFPActionOutput(3)]
    out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id,in_port=in_port, actions=actions, data=data)
    
    datapath.send_msg(out)
    self.add_flow(datapath, 1, match, actions)

//Path function
def get_path(self, ev):
    
    msg = ev.msg
    datapath = msg.datapath
    pkt = packet.Packet(msg.data)
    eth = pkt.get_protocols(ethernet.ethernet)[0]
    dst = eth.dst
    src = eth.src

    dpid = format(datapath.id, "d").zfill(16)
    self.net=nx.DiGraph()
    
    if src not in self.net: #Learn it
        self.net.add_node(src) # Add a node to the graph
        self.net.add_edge(src,dpid) # Add a link from the node to it's edge switch
        self.net.add_edge(dpid,src,port=msg.match['in_port'])  # Add link from switch to node and make sure you are identifying the output port.
    if dst in self.net:
        path=nx.shortest_path(self.net,src,dst) # get shortest path  
        next=path[path.index(dpid)+1] #get next hop
        out_port=self.net[dpid][next]['port'] #get output port
        
        
        print ('---the path is :----')
        print (path)
        return out_port
    return None

///Packet In 
@set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)
def _packet_in_handler(self, ev):
        # If you hit this you might want to increase
    # the "miss_send_length" of your switch
    if ev.msg.msg_len < ev.msg.total_len:
        self.logger.debug("packet truncated: only %s of %s bytes",
                         ev.msg.msg_len, ev.msg.total_len)
    msg = ev.msg
    
    datapath = msg.datapath
    ofproto = datapath.ofproto
    parser = datapath.ofproto_parser
    in_port = msg.match['in_port']

    pkt = packet.Packet(msg.data)
    eth = pkt.get_protocols(ethernet.ethernet)[0]
  
    if eth.ethertype == ether_types.ETH_TYPE_LLDP:
        # ignore lldp packet
        return
    if eth.ethertype == ether_types.ETH_TYPE_IPV6:
        return
    dst = eth.dst
    src = eth.src
    ethtype = eth.ethertype 
    dpid = format(datapath.id, "d").zfill(16)
    self.mac_to_port.setdefault(dpid, {})
    mpls_proto = pkt.get_protocol(mpls.mpls)
    out_port = self.get_path(ev)
    if  out_port is not None:
        
        out_port = out_port
        
    else: 
        out_port = ofproto.OFPP_FLOOD
    
   
    if ethtype == ether_types.ETH_TYPE_IP and dpid == "0000000000000001":
        self.push_mpls(ev, out_port)
    
    if ethtype ==ether_types.ETH_TYPE_MPLS and dpid == "0000000000000003":
        self.swap_mpls(ev, out_port)
    if ethtype ==ether_types.ETH_TYPE_MPLS and dpid == "0000000000000002":
        self.swap_mpls(ev, out_port)
    if  ethtype ==ether_types.ETH_TYPE_MPLS and dpid == "0000000000000004":
        self.pop_mpls(ev, out_port)
    
    
    data = msg.data
    actions = [parser.OFPActionOutput(out_port)]
    out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id,in_port=in_port, actions=actions, data=data)
    datapath.send_msg(out)
James Z
  • 12,209
  • 10
  • 24
  • 44

0 Answers0