コード例 #1
0
  def handle_packet_in(self, ev):
    # The HP considers a successful Packet In as a probe, so we reset the heartbeat here as well
    self.last_heartbeat = time.time()

    msg = ev.msg
    dp = msg.datapath
    switch = self.nib.switch_for_dp(dp)
    ofproto = dp.ofproto
    parser = dp.ofproto_parser
    in_port = msg.match['in_port']

    # Interesting packet data
    pkt = packet.Packet(msg.data)
    eth = pkt.get_protocols(ethernet.ethernet)[0]
    dst = eth.dst
    src = eth.src    

    if not self.nib.learned(src):
      match_mac_src = parser.OFPMatch( vlan_vid = self.nib.vlan_for_switch(switch), eth_src = src )
      match_mac_dst = parser.OFPMatch( vlan_vid = self.nib.vlan_for_switch(switch), eth_dst = src )

      OpenflowUtils.add_goto_table(dp, priority=65535, match=match_mac_src, goto_table_id=1, table_id=0)

      # And a send-to-port instruction for a destination match in table 1
      actions = [ parser.OFPActionOutput(in_port) ]
      OpenflowUtils.add_flow(dp, priority=0, match=match_mac_dst, actions=actions, table_id=1)

      # Learn it for posterity 
      self.nib.learn(switch, self.nib.ENDHOST_PORT, in_port, src, "0.0.0.0")

    # Now we have to deal with the Mac destination.  If we know it already, send the packet out that port.
    # Otherwise flood it.   
    output_p = self.nib.port_for_mac(dst)
    if output_p == None:
      output_p = ofproto.OFPP_FLOOD

    out = parser.OFPPacketOut(datapath=dp, buffer_id=msg.buffer_id,
      in_port=in_port, actions=[ parser.OFPActionOutput(output_p) ], data=msg.data)
    dp.send_msg(out)
コード例 #2
0
  def packet_in(self, msg):
    dp = msg.datapath
    switch = self.nib.switch_for_dp(dp)
    ofproto = dp.ofproto
    parser = dp.ofproto_parser
    in_port = msg.match['in_port']

    # Interesting packet data
    pkt = packet.Packet(msg.data)
    eth = pkt.get_protocols(ethernet.ethernet)[0]
    dst = eth.dst
    src = eth.src    

    # As stated before, we only learn from packets with IP source info in them.  
    if not self.nib.learned(src) and (eth.ethertype == ether_types.ETH_TYPE_IP or eth.ethertype == ether_types.ETH_TYPE_ARP):

      if eth.ethertype == ether_types.ETH_TYPE_IP:
        p_ip = pkt.get_protocols(ipv4.ipv4)[0]
        src_ip = p_ip.src
      elif eth.ethertype == ether_types.ETH_TYPE_ARP:
        p_arp = pkt.get_protocols(arp.arp)[0]
        src_ip = p_arp.src_ip

      match_mac_src = parser.OFPMatch( vlan_vid = self.nib.vlan_for_switch(switch), eth_src = src )
      match_mac_dst = parser.OFPMatch( vlan_vid = self.nib.vlan_for_switch(switch), eth_dst = src )

      target_ip_net = self.nib.actual_net_for(switch)
      if src_ip == NetUtils.ip_for_network(target_ip_net, 1):   # .1 is always the router
        # If this is coming from a router, we add goto table 2 rules in tables 0 and 1 instead.  
        # All packets to/from the router go through table 2 to rewrite IP addresses instead. (See cross_campus_handler)
        OpenflowUtils.add_goto_table(dp, priority=0, match=match_mac_src, goto_table_id=2, table_id=0)
        OpenflowUtils.add_goto_table(dp, priority=0, match=match_mac_dst, goto_table_id=2, table_id=1)

        self.nib.learn(switch, self.nib.ROUTER_PORT, in_port, src, src_ip)

        # We also install path learning rules for table 3.  Since this is the responsibility of
        # cross_campus_handler, it would be better if we installed them there, but I don't know quite
        # how to do it.

        # Incoming Packet Capture (e.g Coscin Ith->NYC on the Ith side), Cookie INCOMING_FLOW_RULE
        match = parser.OFPMatch( eth_dst = src, eth_type=ether_types.ETH_TYPE_IP )
        actions = [ parser.OFPActionOutput(ofproto.OFPP_CONTROLLER) ]
        OpenflowUtils.add_flow(dp, priority=65535, match=match, actions=actions, 
          table_id=3, cookie=CrossCampusHandler.INCOMING_FLOW_RULE)    

        # Outgoing Packet Capture (e.g. Coscin Ith->NYC on the NYC side), Cookie OUTGOING_FLOW_RULE
        match = parser.OFPMatch( eth_src = src, eth_type=ether_types.ETH_TYPE_IP )
        OpenflowUtils.add_flow(dp, priority=65534, match=match, actions=actions, 
          table_id=3, cookie=CrossCampusHandler.OUTGOING_FLOW_RULE)  

      # We don't learn any hosts until we've learned the router.  Otherwise IP packets from the other
      # side of the switch might be learned as the router port.  Send another request just in case it missed
      # the first one.  

      elif self.nib.router_port_for_switch(switch) == None:
        self.arp_for_router(dp, switch)

      else:
        # The packet is from a host, not a router.  A new packet carries information on the mac address, 
        # which we turn into a GOTO-table 1 rule in table 0
        OpenflowUtils.add_goto_table(dp, priority=65535, match=match_mac_src, goto_table_id=1, table_id=0)

        # And a send-to-port instruction for a destination match in table 1
        actions = [ parser.OFPActionOutput(in_port) ]
        OpenflowUtils.add_flow(dp, priority=0, match=match_mac_dst, actions=actions, table_id=1)

        # Learn it for posterity 
        self.nib.learn(switch, self.nib.ENDHOST_PORT, in_port, src, src_ip)

    # Don't send the packet out here if it's coming to/from a router.  
    # Those will be handled by cross_campus_handler, which may rewrite IP's as well.
    cookie = msg.cookie
    if cookie == CrossCampusHandler.INCOMING_FLOW_RULE or cookie == CrossCampusHandler.OUTGOING_FLOW_RULE:
      return

    # Now we have to deal with the Mac destination.  If we know it already, send the packet out that port.
    # Otherwise flood it.   
    output_p = self.nib.port_for_mac(dst)
    if output_p == None:
      output_p = ofproto.OFPP_FLOOD

    out_data = msg.data if msg.buffer_id == 0xffffffff else None 
    out = parser.OFPPacketOut(datapath=dp, buffer_id=msg.buffer_id,
      in_port=in_port, actions=[ parser.OFPActionOutput(output_p) ], data=out_data)
    dp.send_msg(out)