Net App 2 - a simple firewall

In this section, we take the learning switch Net App and extend it to make packet forwarding decisions based on simple firewall rules that we install at the OpenFlow controller (POX). We are following two important goals in this Net App development. The first one is to demonstrate how easy it is to change the behavior of the network device (OpenFlow switch) by simply changing the Net App on the OpenFlow controller.

The second goal is to give more information about the POX controller. In our simple firewall Net App, we want the switch to make a drop or forwarding decisions based on the value of the source MAC address of the packets. The experimental network will be the one that is shown in the previous diagram. However, we augment the l2_learning.py Net App (L2 learning switch) to perform the functionality of a simple firewall. Therefore, we copy the l2_learning.py program with a new name (for instance, simple_firewall.py) and add the firewall logic and rules on top of the L2 learning switch intelligence. This extension simply checks the source MAC address of the incoming packets and based on the outcome of comparison with the firewall rules, it will forward or drop the packet. If the controller decides that the packet should be forwarded, then it proceeds to perform the L2 switching functions as earlier. So, the new step after updating the address/port table of the L2 learning switch will be to check the source MAC address of the incoming packet against the firewall rules.

This requires only a few simple additions to the learning switch code. First, we need a hash table to store the (switch, source MAC) pairs. It maps the (switch, source MAC) pair to a True or False logical value indicating whether the packet should be forwarded or dropped. The controller will decide to drop the incoming packet if there is a firewall entry that maps to False (FirewallTable(switch, Source MAC) == False), or if there is no firewall entry for that source MAC address in the firewall hash table. The controller will decide to forward the traffic only if there is a FirewallTable entry that maps to True. These checks can be added to the learning switch code as follows:

... 
    # Initializing our FirewallTable 
    self.firewallTable = {} 
    # Adding some sample firewall rules 
    self.AddRule('00-00-00-00-00-01',EthAddr('00:00:00:00:00:01')) 
    self.AddRule('00-00-00-00-00-01',EthAddr('00:00:00:00:00:03')) 
... 
... 
    # Check the Firewall Rules 
    if self.CheckFirewallRule(dpidstr, packet.src) == False: 
      drop() 
      return 

The CheckFirewallRule method simply performs the required firewalling operation. Basically, it only returns True if the firewall table has a rule for the given source MAC address.

# check if the incoming packet is compliant to the firewall rules before normal proceeding 
def CheckFirewallRule (self, dpidstr, src=0): 
    try: 
      entry = self.firewallTable[(dpidstr, src)] 
      if (entry == True): 
        log.debug("Rule (%s) found in %s: FORWARD", 
        src, dpidstr) 
      else: 
        log.debug("Rule (%s) found in %s: DROP", 
        src, dpidstr) 
      return entry 
      except KeyError: 
      log.debug("Rule (%s) NOT found in %s: DROP", 
      src, dpidstr) 
    return False 

In this example, the firewall rules are set in a way that only packets from MAC address 00:00:00:00:00:01 and 00:00:00:00:00:03 will be processed and forwarded by the switch, and other traffic is simply dropped. Now we can start Mininet and the POX controller with our firewall Net App as follows:

mininet@mininet-vm:~$ sudo mn --topo single,3 --mac --switch ovsk 
--
controller remote ...

Run the following command from another SSH terminal:

mininet@mininet-vm:~/pox$ ./pox.py log.level --DEBUG forwarding.simple_firewall.py  

Note that we have passed additional command-line parameters to the POX controller to be able to see detailed debugging messages of the POX controller while running our firewall Net App. Since there is no rule in the firewall table that allows h2 to forward its traffic, we should expect that the pingall command confirms this expected behavior:

mininet> pingall  

The following will be the output:

*** Ping: testing ping reachability
h1 -> X h3
h2 -> X X
h3 -> h1 X
*** Results: 66% dropped (4/6 lost)
  

We can also see from the POX debugging messages that the controller decided to forward or drop different packets depending on the value of the source MAC address of the incoming packets. It is also interesting to note that when the controller decides to forward a packet, it also caches a rule in the flow table of the OpenFlow switch that allows that packet to be forwarded.

As long as that entry remains in the flow table, all packets that match the flow entry table can continue to be forwarded to the switch. This caching (limited duration of flow entry existence in the flow table of the switch) introduces some performance impact on the switch operation. By caching, we are referring to the availability of a flow entry in the flow table of the switch, which allows the high-speed forwarding of packets without any controller involvement. Forwarding performance is degraded when the first packet of a flow (traffic stream of packets) needs to wait for the forwarding decision of the controller. This effect is usually referred to as the first-packet delay of a flow. Let's have it this way: host 1 pings host 3. From the ping output, we can observe that the first packet is facing high latency since the flow table of the switch is empty and the OpenFlow switch should contact the controller. After caching the instruction in the flow table of the switch, packets are forwarded by the switch. After about 30 seconds, the flow table entry expires and again we observe relatively higher latency between the two end hosts (which are h1 and h3) since once again the traffic is redirected to the controller. Following is the command:

mininet> h1 ping h3  

The following will be the output:

PING 10.0.0.3 (10.0.0.3) 56(84) bytes of data.
64 bytes from 10.0.0.3: icmp_req=1 ttl=64 time=38.6 ms
64 bytes from 10.0.0.3: icmp_req=2 ttl=64 time=0.264 ms
64 bytes from 10.0.0.3: icmp_req=3 ttl=64 time=0.056 ms
...
64 bytes from 10.0.0.3: icmp_req=32 ttl=64 time=26.8 ms
64 bytes from 10.0.0.3: icmp_req=33 ttl=64 time=0.263 ms
64 bytes from 10.0.0.3: icmp_req=34 ttl=64 time=0.053 ms  
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset