Thursday, June 26, 2014

SDN - Using POX Openflow controller to program a Juniper EX switch Pt.2

The last blog entry I demonstrated how to configure a Juniper EX9200 switch to communicate with an Openflow controller (POX). The flow entry logic was very basic. It turned all the ports on the Openflow switch into a dumb hub. Flood out all ports except for the source.

In this post I'll demonstrate how to create a more unique flow entry.  This is based on the 10-tuple OpenFlow v1.0 header fields which are:

Ingress Port, Ethec Src, Ether Dst, Ether Type, Vlan ID, IP Dst, IP Src, TCP Dst, TCP Src, and IP Proto

First we need to figure out what a host does on a layer 2 network. If Host A wants to talk to Host B, it will first send out an ARP packet asking what is the mac address of Host B based on the IP address. After recieving a reply, Host A will send a unicast frame with the destnation Mac of Host B. Host B in turn will send unicast packets back to Host A. This means we need to program three types of flows.  One for ARP and two for unicast packets for each direction.

Below is the output in action:

jnpr@EX9200-RE0> show openflow flows detail   

jnpr@EX9200-RE0>

Next I startup the openflow controller:
jnpr@ubuntu:~/OPENFLOW-CONTROLLER$ ./pox.py misc.static
POX 0.2.0 (carp) / Copyright 2011-2013 James McCauley, et al.
INFO:core:POX 0.2.0 (carp) is up.
INFO:openflow.of_01:[3c-8a-b0-0d-c7-c0 1] connected
INFO:misc.static:sending to DPID ARP flow creation 
INFO:misc.static:sending to DPID flow creation->

INFO:misc.static:sending to DPID flow creation<-

On the EX switch:

jnpr@EX9200-RE0> show openflow flows detail   
Flow name: flow-16842752
Table ID: 1     Flow ID: 16842752           
Priority: 32768   Idle timeout(in sec):0        Hard timeout(in sec): 0     
Match: Input port: 1    
       Ethernet src addr: wildcard         
       Ethernet dst addr: wildcard         
       Input vlan id: 100               Input VLAN priority: wildcard
       Ether type: 0x800  
       IP ToS: wildcard                 IP protocol: wildcard
       IP src addr: wildcard            IP dst addr: 10.1.1.3/32     
       Source port: 0                   Destination port: 0     
Action: Output port 2,

Flow name: flow-33619968
Table ID: 1     Flow ID: 33619968           
Priority: 32768   Idle timeout(in sec):0        Hard timeout(in sec): 0     
Match: Input port: 2    
       Ethernet src addr: wildcard         
       Ethernet dst addr: wildcard         
       Input vlan id: 100               Input VLAN priority: wildcard
       Ether type: 0x800  
       IP ToS: wildcard                 IP protocol: wildcard
       IP src addr: wildcard            IP dst addr: 10.1.1.2/32     
       Source port: 0                   Destination port: 0     
Action: Output port 1,

Flow name: flow-83951616
Table ID: 1     Flow ID: 83951616           
Priority: 32768   Idle timeout(in sec):0        Hard timeout(in sec): 0     
Match: Input port: wildcard
       Ethernet src addr: wildcard         
       Ethernet dst addr: wildcard         
       Input vlan id: wildcard          Input VLAN priority: wildcard
       Ether type: 0x806  
       IP ToS: 0x0                      IP protocol: wildcard
       IP src addr: wildcard            IP dst addr: wildcard        
       Source port: 0                   Destination port: 0     
Action: Output port 65531,


jnpr@EX9200-RE0> show openflow flows          
Switch                 Flow      Number of packets    Priority Number of Number of
Name                   ID                                            match    action
oftest-92k             16842752      248                     32768    6         1       
oftest-92k             33619968      248                     32768    6         1       
oftest-92k             83951616        4                       32768    4         1      


Python code for POX

jnpr@ubuntu:~/OPENFLOW-CONTROLLER/pox/misc$ cat static.py

---------------------
from pox.core import core
from pox.lib.packet.ipv4 import ipv4
from pox.lib.packet.arp import arp
import pox.lib.packet as pkt
import pox.openflow.libopenflow_01 as of
import re

log = core.getLogger()

class Sdn (object):
  def __init__ (self, connection):
    self.connection = connection
    connection.addListeners(self)


    # FIRST OPENFLOW RULE - ARP
    #create an Openflow using flow table modification
    arp = of.ofp_flow_mod()
    #Define a match structure for your flow rules to follow
    #if ether type is 0x0806 or Arp
    arp.match.dl_type = 0x0806
    # Add an action to send to flood out all ports except the source
    arp.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD))
    # program flow on switch
    self.connection.send(arp)
    #Send debug message for controller
    log.info("sending to DPID ARP flow creation  " )

    # FIRST OPENFLOW RULE
    #create an Openflow using flow table modification
    msg = of.ofp_flow_mod()
    #Define a match structure for your flow rules to follow
    msg.match.in_port = 1
    msg.match.dl_vlan = 100
    msg.match.dl_type = 0x0800
    msg.match.nw_dst = "10.1.1.3/32"
    # Add an action to send to the specified port
    msg.actions.append(of.ofp_action_output(port = 2))
    # Send message to switch
    self.connection.send(msg)
    #Debug message for controller
    log.info("sending to DPID flow creation->" )

    # SECOND OPENFLOW RULE
    #create an Openflow using flow table modification
    msg2 = of.ofp_flow_mod()
    #Define a match structure for your flow rule
    msg2.match.in_port = 2
    msg2.match.dl_vlan = 100
    msg2.match.dl_type = 0x0800
    msg2.match.nw_dst = "10.1.1.2/32"
    # Add an action to send to the specified port
    msg2.actions.append(of.ofp_action_output(port = 1))
    # Send message to switch
    self.connection.send(msg2)
#Debug message for controller
    log.info("sending to DPID flow creation<-" )


def launch ():
  """
  Starts the component
  """
  def start_switch (event):
    log.debug("Controlling DPID %s" % (event.connection,))
    Sdn(event.connection)
  core.openflow.addListenerByName("ConnectionUp", start_switch)

No comments:

Post a Comment