• No results found

Traffic Engineering with SDN Optimising traffic Load-Balancing with OpenFlow

N/A
N/A
Protected

Academic year: 2021

Share "Traffic Engineering with SDN Optimising traffic Load-Balancing with OpenFlow"

Copied!
44
0
0

Loading.... (view fulltext now)

Full text

(1)

Ahmed Warsama

Computer Engineering (B), Individual Assignment Main field of study: Network Engineering Credits: 15 hp

Semester, year: 4, 2020 Supervisor: Magnus Eriksson Examiner: Lennart Franked

(2)

Abstract

(3)

1 Introduction 1

1.1 Background and problem motivation . . . 1

1.2 Overall aim . . . 2

1.3 Scope . . . 2

1.4 Concrete and verifiable goals . . . 2

1.5 Outline . . . 2

2 Theory 3 2.1 Traditional Layer 2 Load Balancing . . . 3

2.2 Traditional Layer 3 Load Balancing . . . 4

2.3 SDN and Traffic Engineering . . . 5

2.3.1 Switch Planes . . . 5

2.3.2 The Separation of the Control Plane . . . 6

2.3.3 North- and Southbound API . . . 6

2.4 OpenFlow . . . 7

2.4.1 OpenFlow controller-Switch Communication . . . 8

2.4.2 The OpenFlow Switch . . . 9

2.4.3 The Flow Table . . . 11

3 Method 13 3.1 Hardware and Software . . . 13

3.2 The Topology. . . 13

3.3 Installation . . . 14

3.4 The Test Implementation . . . 15

3.4.1 Test 1: The Baseline . . . 15

3.4.2 Test 2: The Equal-Cost Multipath script . . . 15

3.4.3 The Bandwidth Load Balancer script . . . 16

4 Construction 17 5 Result 18 5.1 The Bandwidth Load-Balancer . . . 18

5.1.1 sw1LB.py . . . 18

5.1.2 sw5LB.py . . . 20

5.2 Comparison with ECMP . . . 23

5.3 The Increase in Throughput . . . 24

6 Discussion 25 6.1 The Bandwidth load balancer . . . 25

6.2 The Comparison . . . 25

(4)
(5)

1

Introduction

1.1

Background and problem motivation

The rapid increase of Internet usage and network traffic is continuously placing further requirements on modern enterprise, and data center net-works. It is estimated that by 2023 around two-thirds (5.3 billion) of the world’s population will have Internet access [1]. Many trends have devel-oped and gotten firmly established in the recent decade, which have fur-thered the load on our networks. Examples of such trends are:

• Bring Your Own Device (BYOD) • The Internet of Things (IoT) • Virtualization

• Cloud Computing

The advent of connected handheld devices, such as the smartphone, ush-ered in the era of BYOD. This trend has contributed to a significant increase in traffic loads on the enterprise networks. Employees and students con-nect their devices to the network, which use various applications, each with their own requirements and loads on the network. The Internet of Things is also a trend that is on the increase. This includes all kinds of devices that are starting to get connected to the Internet. In 2019 there were over 26 billion active IoT devices, and it is estimated to reach around 35 billion by 2021 [2]. All these devices introduce new traffic that the enterprise net-works have to handle. Cloud Computing is another trend that came as a result of virtualization. Data centers owned by large organisations have started to provide different types of services such as virtual servers, virtual storage, virtual platforms, to their customers. These services rely on vir-tualization to provide each customer with their own isolated environment. Due to the many benefits of leasing cloud services, many organisations have moved their infrastructure to the cloud. This has resulted in a tremendous increase in cloud data center traffic. In 2015 the global cloud data center traf-fic reached 3.8 zettabytes, and by 2021 it is estimated to reach 19.5 zettabytes [3].

(6)

1.2

Overall aim

The aim of this study is to give insight on how Software-Defined Network-ing can improve network load balancNetwork-ing, in comparison to the traditional methods such as Equal-Cost Load Balancing. This study will aim at doing that by creating an SDN solution in a test environment where these methods can be compared in action.

1.3

Scope

The solution will not be a complete and holistic solution that can be imple-mented on any network. The solution is only intended to give insight to the possibilities of SDN and the way it can improve load-balancing, and will therefore be catered for a specific scenario and topology.

1.4

Concrete and verifiable goals

The specific goals of this project is to:

• create a dynamic bandwidth load-balancing program with OpenFlow, that can load-balance based on the leased used path,

• compare this load-balancer with an Equal-Cost Multipath Load-Balancer, • increase the network throughput by, at least, 20 %.

1.5

Outline

(7)

2

Theory

2.1

Traditional Layer 2 Load Balancing

In legacy networks, such as Spanning-Tree Protocol (802.1D) networks, the traffic would only use a single path to the destination. The redundant paths were only used for failovers. This was done in order to avoid layer 2 loops [4, p.120]. However this presented certain problems. The primary path could easily get congested if it was being used by multiple users at once, and the redundant paths would get left unused, wasting precious resources. The Spanning-Tree Protocol would continue to get developed and would eventu-ally release Rapid Spanning-Tree Protocol (802.1w) and Multiple Spanning Tree Protocol (802.1s), among others. Ultimately, these protocols load-balance traffic based on the VLANs [4, p.130]. Traffic from the VLANs gets sent over different uplinks depending on the STP configuration. This method does not take into consideration the amount of traffic being generated by the VLANs.

Figure 1: STP load balancing [5].

(8)

fac-tors, such as the amount of connected users and the network usage of each user.

2.2

Traditional Layer 3 Load Balancing

Load-balancing can also be achieved in the layer 3 routing protocols. The usual load-balancing method is Cost Load-Balancing (also called Equal-Cost Multipath). This method works by first calculating the best paths based on the specific metric used by the routing protocol (can also be manually configured), and then load-balance the traffic over those paths [6, p.123]. The problem with this method is that it sends traffic over the redundant links without taking into consideration the traffic load that exists along those paths [7].

Figure 2: ECMP load-balancing [8].

(9)

Router R1 does not have a global view of the network, and can therefore not take things like, the bandwidth usage along the path, into consideration.

2.3

SDN and Traffic Engineering

2.3.1

Switch Planes

Traditional switches are made up of three planes, namely the management plane, the control plane and the data plane. The management plane is the plane that is used to access, configure and monitor the switch. The control plane runs protocols that control the way traffic is forwarded. The data plane is the plane that receives and transmits the packets, based on the information it gets from the control plane [4, s p.28]. Figure 3 shows the different protocols that run on the planes.

Figure 3: The planes within a switch, and the protocols associated with them [9].

(10)

decades, it has increased the amount of intelligence needed in each device. This has increased the complexity and reduced the simplicity [10, p.25].

2.3.2

The Separation of the Control Plane

One of the goals of SDN is to simplify network management. One of the ways it does that is by separating the control plane from the network devices. In an SDN network the control plane is centralized and is handled by an external server. The switches are controlled by this central controller which has full view of the network. Figure 4 shows an example of the operations of an SDN network.

Figure 4: SDN network operation [10, p.62].

All the computation and calculation are done by this one device. The con-troller decides the policy of the network and how it will function. Since the controller has a global view of the network it can forward traffic in a more optimal way [10, p.25-26]. It can take into consideration the amount of bandwidth that is used by different paths when making forwarding deci-sions [10, p.158]. This is one of the major benefits of SDN traffic engineering, which solves many problems of earlier traffic forwarding methods. Switch CPUs are usually single-core CPUs, while a modern server could host many more cores and more GHz. Thus letting a central controller with a stronger CPU do the computing is more optimal [10, p.63].

2.3.3

North- and Southbound API

(11)

below it. APIs are interfaces that are used for communication between pro-grams [11]. Figure 5 shows the APIs of the SDN controller.

Figure 5: Different parts of the controller. [10, p.69].

The southbound API is used for the communication between the controller and the network devices. A very common API for the southbound interface is the OpenFlow protocol [10, p.69]. More on OpenFlow will come in the next chapter.

The northbound API is the interface that is used to communicate with the applications [10, p.69]. An example of an application that communicates with the controllers northbound API is the Graphical User Interface (GUI), which makes accessing the SDN controller more user friendly. There are various APIs that can be used for the northbound interface, such as REST API. REST API is an API that uses the HTTP requests to retrieve and send data [12].

2.4

OpenFlow

(12)

to the OpenFlow protocol that implemented SDN features, OpenFlow is still considered the birth of SDN [10, p.50-51].

Figure 6: The centralized OpenFlow controller and the switches [10, p.50].

Figure 6 shows the network design of the OpenFlow standard. The control is taken away from the switches and placed on a central controller that decides the action of the switches. The controller populates the switches flow tables, which in turn allows the switch to forward traffic based on the entries spec-ified in the tables. More on flow tables will be explained in the subsequent sections.

2.4.1

OpenFlow controller-Switch Communication

(13)

Figure 7: The communication process between the controller and the switch [10, p.93].

After the communication session has been established they exchange differ-ent message types for differdiffer-ent purposes. There are message types to com-municate things like statistics, flow addition/modification/removal, errors, configuration, packet handling requests, and many more [10, p.93].

2.4.2

The OpenFlow Switch

(14)

modifies the packet header if need be, drops the packets, etc. The controller sends messages that define, modify and delete flows from the switch [10, p.85]. Paul Göransson and Chuck Black, the authors of the book “Software Defined Networks: A Comprehensive Approach” define a flow as:

“a set of packets transferred from one network endpoint (or set of endpoints) to another endpoint (or set of endpoints). The endpoints may be defined as IP address-TCP/UDP port pairs, VLAN endpoints, layer three tunnel endpoints, or input ports, among other things.” [10, p.85]

The controller defines the flows and sets the actions that the switch will take for the specified flows.

Figure 8: The OpenFlow switch [10, p.83].

(15)

is trying to find a match for the packet in the switches flow table. If there is a match for the packet in the flow table, then it will be directed to the action box. The action box will contain an action to either send the packet out through a local port, drop the packet, or send the packet to the controller [10, p.83-84].

2.4.3

The Flow Table

The flow table contains flow entries from the controller which tell the switch what to do with the packets that enter it. Flow tables contain flow entries, and these entries in turn contain header fields, counters and actions. The incoming packets are matched to the information in the header field of the flow entries. If there is a match for the packet in one of the flow entries of the table it will be considered part of that flow, and will be forwarded or dropped based on the action set by that particular flow entry. Flow entry counters are used to keep track of the statistics related to the specific flow entry [10, p.88]. An example of this could be the amount of packet matches a flow entry has had. Figure 6 shows an example of the information that can be stored in each flow entry.

Figure 9: Information contained in a flow entry [13].

(16)

the subsequent flows from the same source [14, p.20]. Flows that have been set on the flow table after a table miss are called reactive flows. Flows that were set on the switches flow table, before a packet from that specific flow entered the switch, are called proactive flows [10, p.63].

(17)

3

Method

3.1

Hardware and Software

I installed all the programs and did the tests on a single Ubuntu 18.04 desk-top. The following is a list of the software and tools that I used to build the test environment, and to create the load-balancer program:

• Mininet 2.2.2 - The network emulator program used to create the vir-tual network.

• Open vSwitch 2.9.5 - The virtual switch used in the virtual network. • Floodlight Controller (Master) - The OpenFlow controller.

• Python 2.7 - The programming language to write the program.

• Bash - The shell used for the execution and automation of the scripts. • Iperf - A traffic generator for testing throughput.

3.2

The Topology

(18)

Figure 10: The topology of the virtual network.

The hosts connected to the core switch are the Iperf servers that will be the destination of traffic sent by the two end devices, host 1 and host 2.

3.3

Installation

To install Mininet I followed the guide from their official website that can be found here [15]. The Mininet installation automatically comes with Open vSwitch. To install the Floodlight controller I followed the guide from their of-ficial website that can be found here [16]. Python and bash come with Ubuntu 18.04 so I didn’t need to install them. Iperf can be installed on Ubuntu run-ning the following commands:

Listing 1: Bash commands sudo apt u p d a t e

(19)

3.4

The Test Implementation

To assess the hypothesis of this study I will implement three different tests. The tests will go on for five minutes each. During those five minutes traffic will be sent from host 1 and host 2 using Iperf. Host 3 and host 4 will act as

Iperfservers while host 1 and 2 will be the clients. Host 1 will send traffic to host 4, while host 2 will send traffic to host 3. Each flow that is generated by the hosts will be equally demanding on the links. Meaning that every flow will try to use up the entire bandwidth in the path, which in this case is 100 Mb/s per link. There will however be a difference in the time-length of the flows from host 1 and 2. Host 1 will send 5 second flows, while host 2 will send 30 second flows. The 30 second flow from host 2 will be considered the elephant flow that will congest the path. Host 1 will be sending the traffic that represents normal user traffic with shorter flows (mice flow). The Iperf command will be automated using the watch bash command which executes a command/script after 2 seconds (default value). Refer to appendix B for a guide on the procedure and commands needed to do the tests.

The purpose of the traffic from host 2 is to put load on the network. Hence the 30 second duration of the Iperf flows. The traffic that will be measured for throughput in the tests is going to be the traffic from host 1. After the five minute test duration is finished, the average throughput of the Iperf generated traffic will be calculated and then compared to the results from the other tests. The results will then be presented in a graph.

3.4.1

Test 1: The Baseline

To make the efficiency of the load-balancers easier to measure, I made a test to measure the throughput of the network when forwarding traffic on a single-path. The default metric for choosing the best path in the floodlight controller is hop-count. The two paths are equal-cost, and the traffic will go through path 1 if no load-balancing is implemented. This will create a base-line on how much throughput the topology has without load-balancing.

3.4.2

Test 2: The Equal-Cost Multipath script

(20)

3.4.3

The Bandwidth Load Balancer script

This program is dynamic and uses REST API calls to gather information from the controller, and uses this information to push new flow entries. The program will make sure that the traffic is forwarded on the least used path. The way the program calculates this is by requesting statistics from the con-troller regarding the amount of bytes going in and out of the ports in each path. It then deletes the flow entries from the switches and pushes new en-tries for the new path. This program is automated by using the watch bash command to run the program every 5 seconds. The execution of the pro-gram is done in the following way: The BWLB.sh is executed in the follow-ing manner:

Listing 2: The contents of the BWLB.sh program w a t c h - n 5 ./ BWLB . sh

(21)

4

Construction

The goal of the bandwidth load-balancing script is to avoid congested paths. Since the topology for this test will only consist of two uplinks, it will only calculate the bandwidth of these two paths. The script will find the best path by first calculating the total bandwidth usage of both uplinks, and then send new flows to the switch, telling it to send the traffic of the least used path.

Figure 11: Flowchart explaining the actions of the script.

(22)

5

Result

5.1

The Bandwidth Load-Balancer

The bandwidth load-balancer is basically a shell script, named BWLB.sh, that contains two python scripts. When the BWLB.sh program is executed, it will in turn execute two other scripts.

Listing 3: The contents of the BWLB.sh file ./ s w 1 L B . py

./ s w 5 L B . py

The sw1LB.py script contains the flow entries and load-balancing for switch 1. The sw5LB.py script contains the flow entries and load-balancing for switch 5. The first script will load-balance to the core, while the second script will load-balance back to switch 1.

5.1.1

sw1LB.py

Listing 4: sw1LB.py # ! / usr/bin/env python import os import h t t p l i b import j s o n import u r l l i b c l a s s S t a t i c F l o w P u s h e r (o b j e c t) : def _ _ i n i t _ _ ( s e l f , s e r v e r ) : s e l f . s e r v e r = s e r v e r def g e t ( s e l f , data ) : r e t = s e l f . r e s t _ c a l l ( { } , "GET" ) r e t u r n j s o n . l o a d s ( r e t [ 2 ] ) def s e t( s e l f , data ) : r e t = s e l f . r e s t _ c a l l ( data , "POST" ) r e t u r n r e t [ 0 ] == 200

def remove ( s e l f , o b j t y p e , data ) : r e t = s e l f . r e s t _ c a l l ( data , "DELETE" ) r e t u r n r e t [ 0 ] == 200 def r e s t _ c a l l ( s e l f , data , a c t i o n ) : path = " /wm/ s t a t i c f l o w p u s h e r / j s o n " headers = { " Content −type " : " a p p l i c a t i o n / j s o n " , " Accept " : " a p p l i c a t i o n / j s o n " , }

body = j s o n . dumps ( data )

conn = h t t p l i b . HTTPConnection ( s e l f . s e r v e r , 8 0 8 0 ) conn . r e q u e s t ( a c t i o n , path , body , headers ) response = conn . g e t r e s p o n s e ( )

r e t = ( response . s t a t u s , response . reason , response . read ( ) )

(23)

" i n _ p o r t " : " 1 " , " a c t i v e " : " t r u e " , " a c t i o n s " : " output =2 " } flow211 = { ’ s w i t c h ’ : " 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 1 " , " name " : " flow_mod_21 " , " c o o k i e " : " 0 " , " p r i o r i t y " : " 32768 " , " e t h _ t y p e " : " 0 x0800 " , " i p v 4 _ d s t " : " 1 0 . 0 . 0 . 3 / 3 2 " , " i n _ p o r t " : " 1 " , " a c t i v e " : " t r u e " , " a c t i o n s " : " output =3 " } flow22 = { ’ s w i t c h ’ : " 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 1 " , " name " : " flow_mod_22 " , " c o o k i e " : " 0 " , " p r i o r i t y " : " 32768 " , " e t h _ t y p e " : " 0 x0800 " , " i p v 4 _ d s t " : " 1 0 . 0 . 0 . 4 / 3 2 " , " i n _ p o r t " : " 1 " , " a c t i v e " : " t r u e " , " a c t i o n s " : " output =2 " } flow222 = { ’ s w i t c h ’ : " 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 1 " , " name " : " flow_mod_22 " , " c o o k i e " : " 0 " , " p r i o r i t y " : " 32768 " , " e t h _ t y p e " : " 0 x0800 " , " i p v 4 _ d s t " : " 1 0 . 0 . 0 . 4 / 3 2 " , " i n _ p o r t " : " 1 " , " a c t i v e " : " t r u e " , " a c t i o n s " : " output =3 " } flow23 = { ’ s w i t c h ’ : " 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 1 " , " name " : " flow_mod_23 " , " c o o k i e " : " 0 " , " p r i o r i t y " : " 32768 " , " e t h _ t y p e " : " 0 x0800 " , " i p v 4 _ d s t " : " 1 0 . 0 . 0 . 1 / 3 2 " , " i n _ p o r t " : " 2 " , " a c t i v e " : " t r u e " , " a c t i o n s " : " output =1 " } flow24 = { ’ s w i t c h ’ : " 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 1 " , " name " : " flow_mod_24 " , " c o o k i e " : " 0 " , " p r i o r i t y " : " 32768 " , " e t h _ t y p e " : " 0 x0800 " , " i p v 4 _ d s t " : " 1 0 . 0 . 0 . 1 / 3 2 " , " i n _ p o r t " : " 3 " , " a c t i v e " : " t r u e " , " a c t i o n s " : " output =1 " }

# Function t o c a l c u l a t e t h e c u r r e n t bandwidth usage o f t h e l i n k s #−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

def link_bandwidth ( switch , p o r t ) :

g l o b a l t o t a l _ b w s w i tc h = s t r( s w i t ch ) p o r t = s t r( p o r t ) u r l = ’ h t t p : / / 1 2 7 . 0 . 0 . 1 : 8 0 8 0 /wm/ s t a t i s t i c s /bandwidth / 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 ’ + sw i t c h + ’ / ’ + p o r t + ’ / j s o n ’ j s o n _ u r l = u r l l i b . urlopen ( u r l ) data = j s o n . l o a d s ( j s o n _ u r l . read ( ) ) rx = data [ 0 ] [ " b i t s −per −second −rx " ] t x = data [ 0 ] [ " b i t s −per −second − t x " ] t o t a l _ b w = i n t( rx ) + i n t( t x )

r e t u r n

# G e t t i n g t h e t o t a l bandwidth from path 1 , i n t o a v a r i a b l e #−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

(24)

p a t h 1 _ l i n k 2 = t o t a l _ b w

path1_total_BW = p a t h 1 _ l i n k 2 − p a t h 1 _ l i n k 1

# G e t t i n g t h e t o t a l bandwidth from path 2 , i n t o a v a r i a b l e #−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− link_bandwidth ( 1 , 3 ) p a t h 2 _ l i n k 1 = t o t a l _ b w link_bandwidth ( 4 , 3 ) p a t h 2 _ l i n k 2 = t o t a l _ b w path2_total_BW = p a t h 2 _ l i n k 2 − p a t h 2 _ l i n k 1 p r i n t path1_total_BW p r i n t path2_total_BW # Load− b a l a n c i n g #−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− i f path2_total_BW >= path1_total_BW : os . popen ( ’ c u r l h t t p : / / 1 2 7 . 0 . 0 . 1 : 8 0 8 0 /wm/ s t a t i c f l o w p u s h e r / c l e a r / 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 1 / j s o n ’ ) pusher .s e t( flow21 ) pusher .s e t( flow22 ) pusher .s e t( flow23 ) pusher .s e t( flow24 ) e l s e: os . popen ( ’ c u r l h t t p : / / 1 2 7 . 0 . 0 . 1 : 8 0 8 0 /wm/ s t a t i c f l o w p u s h e r / c l e a r / 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 1 / j s o n ’ ) pusher .s e t( flow211 ) pusher .s e t( flow222 ) pusher .s e t( flow23 ) pusher .s e t( flow24 )

5.1.2

sw5LB.py

Listing 5: sw5LB.py # ! / usr/bin/env python import os import h t t p l i b import j s o n import u r l l i b c l a s s S t a t i c F l o w P u s h e r (o b j e c t) : def _ _ i n i t _ _ ( s e l f , s e r v e r ) : s e l f . s e r v e r = s e r v e r def g e t ( s e l f , data ) : r e t = s e l f . r e s t _ c a l l ( { } , "GET" ) r e t u r n j s o n . l o a d s ( r e t [ 2 ] ) def s e t( s e l f , data ) : r e t = s e l f . r e s t _ c a l l ( data , "POST" ) r e t u r n r e t [ 0 ] == 200

def remove ( s e l f , o b j t y p e , data ) : r e t = s e l f . r e s t _ c a l l ( data , "DELETE" ) r e t u r n r e t [ 0 ] == 200 def r e s t _ c a l l ( s e l f , data , a c t i o n ) : path = " /wm/ s t a t i c f l o w p u s h e r / j s o n " headers = { " Content −type " : " a p p l i c a t i o n / j s o n " , " Accept " : " a p p l i c a t i o n / j s o n " , }

body = j s o n . dumps ( data )

conn = h t t p l i b . HTTPConnection ( s e l f . s e r v e r , 8 0 8 0 ) conn . r e q u e s t ( a c t i o n , path , body , headers ) response = conn . g e t r e s p o n s e ( )

r e t = ( response . s t a t u s , response . reason , response . read ( ) )

p r i n t r e t conn . c l o s e ( )

(25)
(26)

} flow16 = { ’ s w i t c h ’ : " 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 5 " , " name " : " flow_mod_16 " , " c o o k i e " : " 0 " , " p r i o r i t y " : " 32768 " , " e t h _ t y p e " : " 0 x0800 " , " i p v 4 _ d s t " : " 1 0 . 0 . 0 . 2 / 3 2 " , " i n _ p o r t " : " 3 " , " a c t i v e " : " t r u e " , " a c t i o n s " : " group=3 " } flow17 = { ’ s w i t c h ’ : " 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 5 " , " name " : " flow_mod_17 " , " c o o k i e " : " 0 " , " p r i o r i t y " : " 32768 " , " e t h _ t y p e " : " 0 x0800 " , " i p v 4 _ d s t " : " 1 0 . 0 . 0 . 3 / 3 2 " , " i n _ p o r t " : " 1 " , " a c t i v e " : " t r u e " , " a c t i o n s " : " output =3 " } flow18 = { ’ s w i t c h ’ : " 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 5 " , " name " : " flow_mod_18 " , " c o o k i e " : " 0 " , " p r i o r i t y " : " 32768 " , " e t h _ t y p e " : " 0 x0800 " , " i p v 4 _ d s t " : " 1 0 . 0 . 0 . 3 / 3 2 " , " i n _ p o r t " : " 2 " , " a c t i v e " : " t r u e " , " a c t i o n s " : " output =3 " } flow19 = { ’ s w i t c h ’ : " 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 5 " , " name " : " flow_mod_19 " , " c o o k i e " : " 0 " , " p r i o r i t y " : " 32768 " , " e t h _ t y p e " : " 0 x0800 " , " i p v 4 _ d s t " : " 1 0 . 0 . 0 . 4 / 3 2 " , " i n _ p o r t " : " 1 " , " a c t i v e " : " t r u e " , " a c t i o n s " : " output =4 " } flow20 = { ’ s w i t c h ’ : " 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 5 " , " name " : " flow_mod_20 " , " c o o k i e " : " 0 " , " p r i o r i t y " : " 32768 " , " e t h _ t y p e " : " 0 x0800 " , " i p v 4 _ d s t " : " 1 0 . 0 . 0 . 4 / 3 2 " , " i n _ p o r t " : " 2 " , " a c t i v e " : " t r u e " , " a c t i o n s " : " output =4 " }

# Function t o c a l c u l a t e t h e c u r r e n t bandwidth usage o f t h e l i n k s #−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

def link_bandwidth ( switch , p o r t ) :

g l o b a l t o t a l _ b w s w i tc h = s t r( s w i t ch ) p o r t = s t r( p o r t ) u r l = ’ h t t p : / / 1 2 7 . 0 . 0 . 1 : 8 0 8 0 /wm/ s t a t i s t i c s /bandwidth / 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 ’ + sw i t c h + ’ / ’ + p o r t + ’ / j s o n ’ j s o n _ u r l = u r l l i b . urlopen ( u r l ) data = j s o n . l o a d s ( j s o n _ u r l . read ( ) ) rx = data [ 0 ] [ " b i t s −per −second −rx " ] t x = data [ 0 ] [ " b i t s −per −second − t x " ] t o t a l _ b w = i n t( rx ) + i n t( t x )

r e t u r n

(27)

# G e t t i n g t h e t o t a l bandwidth from path 2 , t o a v a r i a b l e #−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− link_bandwidth ( 5 , 2 ) p a t h 2 _ l i n k 1 = t o t a l _ b w link_bandwidth ( 4 , 1 ) p a t h 2 _ l i n k 2 = t o t a l _ b w path2_total_BW = p a t h 2 _ l i n k 2 − p a t h 2 _ l i n k 1 p r i n t path1_total_BW p r i n t path2_total_BW # Load− b a l a n c i n g #−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− i f path2_total_BW >= path1_total_BW : os . popen ( ’ c u r l h t t p : / / 1 2 7 . 0 . 0 . 1 : 8 0 8 0 /wm/ s t a t i c f l o w p u s h e r / c l e a r / 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 5 / j s o n ’ ) pusher .s e t( flowgroup3 ) pusher .s e t( flow13 ) pusher .s e t( flow14 ) pusher .s e t( flow15 ) pusher .s e t( flow16 ) pusher .s e t( flow17 ) pusher .s e t( flow18 ) pusher .s e t( flow19 ) pusher .s e t( flow20 ) e l s e: os . popen ( ’ c u r l h t t p : / / 1 2 7 . 0 . 0 . 1 : 8 0 8 0 /wm/ s t a t i c f l o w p u s h e r / c l e a r / 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 5 / j s o n ’ ) pusher .s e t( flowgroup3 ) pusher .s e t( flow133 ) pusher .s e t( flow155 ) pusher .s e t( flow17 ) pusher .s e t( flow18 ) pusher .s e t( flow19 ) pusher .s e t( flow20 )

5.2

Comparison with ECMP

(28)

5.3

The Increase in Throughput

Figure 12: The result of the tests.

(29)

6

Discussion

6.1

The Bandwidth load balancer

The script is a bit hard coded and won’t be able to dynamically adapt to a changing network. It was, however, able to dynamically detect the band-width usage and change the path of the traffic. The purpose of the script was not to be used in all kinds of networks, but rather for this specific net-work in order to test the hypothesis. For that reason it fulfilled it’s purpose.

6.2

The Comparison

I made sure the comparison with ECMP was done in the same environment, using the same protocol, namely OpenFlow. This is essential if the results are to be fairly assessed. The group entries implemented ECMP on a per flow basis. This worked well for load-balancing shorter flows, but for longer and larger flows, such as the flow that was coming from host 2 (30 sec flow), not so well.

The duration of the tests was 5 min each and i feel that was a good time to get a nice average of the throughput. I felt that longer than 5 min wasn’t necessary to get a good average.

6.3

The Increase in Throughput

(30)

7

Conclusions

The results confirmed the hypothesis of the study, namely that SDN traffic engineering can improve network performance in comparison to older load-balancing methods such as ECMP. However, there are still many important and vital factors that this study didn’t encompass. The tests were done in a small test environment with a script that was hard-coded to fit the network topology. A real and holistic solution would have to be scalable and be able to dynamically adapt to network changes for it to be truly usable. The bandwidth load-balancing program that i created assumed that all the paths in the network were equal-cost. For this program to really be dynamic it would first have to be able find all the paths in the network, and then calculate the best and equal-cost paths before starting the link-usage calculations. The good part is that this can automatically be done by the floodlight controller which has built-in metrics such as hop-count and link speed.

The study also didn’t encompass factors such as the CPU load on the con-troller. The statistics collector interval was changed from 10 seconds to 3 sec-onds. This will increase the computations and calculations on the controller. The CPU load might not be very significant in small networks, but for larger networks it would be a serious problem. The statistics collections will also introduce new traffic on the network as the controller requests statistics from the switches. There are also other factors such as security, controller redundancy, and other challenges that have been left out by this study. Each of these areas require proper attention before an SDN implementation can take place.

7.1

Ethics

Today’s networks carry all kinds of information, from less important infor-mation to very critical inforinfor-mation. Consider the example of a modern hos-pital that has invested in IoT devices. A known IoT device that hoshos-pitals are starting to invest in is the IntelliVue Guardian Solution product released by Philips. This device can keep track of the patient’s pulse, temperature, res-piratory rate, and much more. If any of patients’ normal rates are exceeded, it will send an alert to the nurses. This device sends these pieces of informa-tion and alerts through the hospital network. This is vital informainforma-tion that can’t get lost due to congestions or other network issues.

(31)

7.2

Future works

(32)

References

[1] cisco.com. Cisco Annual Internet Report (2018–2023) White Paper. URL:

https://www.cisco.com/c/en/us/solutions/collateral/executive-perspectives/annual-internet-report/white-paper-c11-741490. html(cit. on p. 1).

[2] G. Maayan. 16 Internet of Things (IoT) Statistics.URL: https://securitytoday. com/Articles/2020/01/13/The-IoT-Rundown-for-2020.aspx?Page=

2(cit. on p. 1).

[3] statista.com. Global cloud data center IP traffic from 2015 to 2021. URL:

https://www.statista.com/statistics/227267/global-cloud-ip-traffic-growth-by-segment/(cit. on p. 1).

[4] Richard Froom and Erum Frahim. Implementing Cisco IP switched net-works (SWITCH) foundation learning guide:(CCNP SWITCH 300-115). Cisco Press, 2015 (cit. on pp. 3, 5).

[5] learncisco.net. Cisco Per VLAN Spanning Tree Plus.URL: https://www.

learncisco.net/courses/icnd-2/vlans-and-spanning-tree/pvst. html(cit. on p. 3).

[6] Diane Teare, Bob Vachon, and Rick Graziani. Implementing Cisco IP routing (ROUTE) foundation learning guide:(CCNP ROUTE 300-101). Cisco Press, 2014 (cit. on p. 4).

[7] D Thaler and C Hopps. 2991 RFC. 2000 (cit. on p. 4).

[8] N. Bhardwaj. Hash based ECMP load balancing algorithm. URL: https:

//www.talentica.com/blogs/hash- based- ecmp- load- balancing-algorithm/(cit. on p. 4).

[9] Global Knowledge. How to Secure Cisco Routers and Switches.URL: https: //www.globalknowledge.com/us-en/resources/resource-library/ articles/how- to- secure- cisco- routers- and- switches/ (cit. on p. 5).

[10] Paul Goransson and Chuck Black. Software Defined Networks: A Com-prehensive Approach. 1st. San Francisco, CA, USA: Morgan Kaufmann Publishers Inc., 2014.ISBN: 012416675X (cit. on pp. 5–12).

[11] britannica.com. API.URL: https://www.britannica.com/technology/

API(cit. on p. 6).

[12] M. Rouse. RESTful API (REST API).URL: https://searchapparchitecture.

techtarget.com/definition/RESTful-API(cit. on p. 7).

(33)

[14] ONF. OpenFlow Switch Specification. Tech. rep. Open Networking Foun-dation, Oct. 2013. URL: https://www.opennetworking.org/images/

stories/downloads/sdn-resources/onf-specifications/openflow/ openflow-spec-v1.4.0.pdf(cit. on p. 12).

[15] mininet.org. Download/Get Started With Mininet.URL: http://mininet.

org/download/(cit. on p. 14).

[16] Q. Wang. Installation Guide. URL: https:/ /floodlight .atlassian. net/wiki/spaces/floodlightcontroller/pages/1343544/Installation+ Guide(cit. on p. 14).

[17] https://floodlight.atlassian.net/. Floodlight REST API.URL: https://

(34)
(35)

A

Appendice A

Listing 6: The script for creating the test network.

from m i n i n e t . topo i m p o r t Topo

c l a s s M y T o p o ( Topo ): " S i m p l e t o p o l o g y e x a m p l e . " def b u i l d ( self ): " C r e a t e c u s t o m topo . " # Add h o s t s and s w i t c h e s h o s t O n e = self . a d d H o s t ( ’ h1 ’ ) h o s t T w o = self . a d d H o s t ( ’ h2 ’ ) h o s t T h r e e = self . a d d H o s t ( ’ h3 ’ ) h o s t F o u r = self . a d d H o s t ( ’ h4 ’ ) h 1 S w i t c h = self . a d d S w i t c h ( ’ s1 ’ ) h 2 S w i t c h = self . a d d S w i t c h ( ’ s2 ’ ) d i s t 1 S w i t c h = self . a d d S w i t c h ( ’ s3 ’ ) d i s t 2 S w i t c h = self . a d d S w i t c h ( ’ s4 ’ ) c o r e S w i t c h = self . a d d S w i t c h ( ’ s5 ’ ) # Add l i n k s

self . a d d L i n k ( hostOne , h1Switch , bw =100 ) self . a d d L i n k ( hostTwo , h2Switch , bw =100 ) self . a d d L i n k ( h1Switch , d i s t 1 S w i t c h , bw =100 ) self . a d d L i n k ( h1Switch , d i s t 2 S w i t c h , bw =100 ) self . a d d L i n k ( h2Switch , d i s t 1 S w i t c h , bw =100 ) self . a d d L i n k ( h2Switch , d i s t 2 S w i t c h , bw =100 ) self . a d d L i n k ( d i s t 1 S w i t c h , c o r e S w i t c h , bw =100 ) self . a d d L i n k ( d i s t 2 S w i t c h , c o r e S w i t c h , bw =100 ) self . a d d L i n k ( c o r e S w i t c h , h o s t T h r e e , bw =100 ) self . a d d L i n k ( c o r e S w i t c h , hostFour , bw =100 ) t o p o s = { ’ m y t o p o ’ : ( l a m b d a: M y T o p o () ) }

B

Appendice B

The first step is to start the floodlight controller with the following command: Listing 7: Starting the floodlight controller.

(36)

This must be done in the floodlight directory. The next step after this is to start a new terminal, and from there start the mininet topology program with the following command:

Listing 8: The command to start the mininet virtual network.

sudo mn −− c o n t r o l l e r =remote , i p = 1 2 7 . 0 . 0 . 1 −−custom ~/mininet/custom/topology . py −−topo mytopo −− l i n k = t c

Now that the network is created, the next step is to start the host terminals. This is done from the mininet terminal window. The following commands start terminals for each host:

Listing 9: Starting terminals for the hosts. x t e r m h1

x t e r m h2 x t e r m h3 x t e r m h4

The next step is to start the Iperf servers on host 3 and host 4. Host 4 will be saving the output on a log file. The reason for this is to calculate the average amount of bandwidth that went through the network. The following is the

Iperfcommands that will be used on the server hosts: Listing 10: Iperf command for host 3. i p e r f - s - p 5555 - i 1

Listing 11: Iperf command for host 4. i p e r f - s - p 5566 - i 1 >> log1

The next step is to initiate the Iperf traffic from the client hosts, host 1 and 2. The following is the commands for the client hosts:

Listing 12: Iperf command for host 1. w a t c h i p e r f - c 1 0 . 0 . 0 . 4 - p 5566 - t 5

Listing 13: Iperf command for host 2. w a t c h i p e r f - c 1 0 . 0 . 0 . 3 - p 5555 - t 30

Host 1 will be sending 5 second flows, while host 2 will send 30 second flows.

The first test only requires the previously mentioned commands to run. The second test will require the ECMP.sh script to be run before the Iperf traffic is sent. Refer to Appendice C for the script. The third test will require the BWLB.sh script to be run together with the bash command watch, before the

(37)

collection interval needs to be reduced from 10 seconds to 3 seconds. This has to be done before starting the controller in the first step. The path of the configuration file is the following:

Listing 14: Path to configuration file.

/ f l o o d l i g h t / src / main / r e s o u r c e s / f l o o d l i g h t d e f a u l t . p r o p e r t i e s

Look for the following line, or add it to the file. Reduce the interval from 10 seconds (the default) to 3 seconds.

Listing 15: The stats collecector interval.

n e t . f l o o d l i g h t c o n t r o l l e r . s t a t i s t i c s . S t a t i s t i c s C o l l e c t o r . c o l l e c t i o n I n t e r v a l P o r t S t a t s S e c o n d s =3

C

Appendice C

When the ECMP.sh program is executed, it will in turn execute three other scripts.

Listing 16: The contents of the ECMP.sh program ./ a c c e s s . py

./ dist . py ./ s w i t c h 5 . py

The access.py script contains the flow entries for the access switches, namely switch 1 and switch 2. The dist.py script contains flow entries for the distri-bution switches, namely switch 3 and switch 4. The last script, switch5.py, contains flow entries for the core switch, namely switch 5.

C.1

access.py

Listing 17: access.py

# ! / usr/bin/env python

import h t t p l i b

import j s o

#The d e f i n i t i o n s and t h e v a r i a b l e s were taken from # f l o o d l i g h t c o n t r o l l e r s o f f i c i a l webbsite . # I only changed and added t h e flows .

c l a s s S t a t i c F l o w P u s h e r (o b j e c t) : def _ _ i n i t _ _ ( s e l f , s e r v e r ) : s e l f . s e r v e r = s e r v e r def g e t ( s e l f , data ) : r e t = s e l f . r e s t _ c a l l ( { } , "GET" ) r e t u r n j s o n . l o a d s ( r e t [ 2 ] ) def s e t( s e l f , data ) : r e t = s e l f . r e s t _ c a l l ( data , "POST" ) r e t u r n r e t [ 0 ] == 200

def remove ( s e l f , o b j t y p e , data ) : r e t = s e l f . r e s t _ c a l l ( data , "DELETE" )

r e t u r n r e t [ 0 ] == 200

(38)

path = " /wm/ s t a t i c f l o w p u s h e r / j s o n " headers = {

" Content −type " : " a p p l i c a t i o n / j s o n " , " Accept " : " a p p l i c a t i o n / j s o n " , }

body = j s o n . dumps ( data )

conn = h t t p l i b . HTTPConnection ( s e l f . s e r v e r , 8 0 8 0 ) conn . r e q u e s t ( a c t i o n , path , body , headers ) response = conn . g e t r e s p o n s e ( )

r e t = ( response . s t a t u s , response . reason , response . read ( ) )

(39)
(40)

pusher .s e t( flow27 ) pusher .s e t( flow28 )

C.2

dist.py

Listing 18: dist.py # ! / usr/bin/env python import h t t p l i b import j s o n

#The d e f i n i t i o n s and t h e v a r i a b l e s were taken from # f l o o d l i g h t c o n t r o l l e r s o f f i c i a l webbsite . # I only changed and added t h e flows .

c l a s s S t a t i c F l o w P u s h e r (o b j e c t) : def _ _ i n i t _ _ ( s e l f , s e r v e r ) : s e l f . s e r v e r = s e r v e r def g e t ( s e l f , data ) : r e t = s e l f . r e s t _ c a l l ( { } , "GET" ) r e t u r n j s o n . l o a d s ( r e t [ 2 ] ) def s e t( s e l f , data ) : r e t = s e l f . r e s t _ c a l l ( data , "POST" ) r e t u r n r e t [ 0 ] == 200

def remove ( s e l f , o b j t y p e , data ) : r e t = s e l f . r e s t _ c a l l ( data , "DELETE" ) r e t u r n r e t [ 0 ] == 200 def r e s t _ c a l l ( s e l f , data , a c t i o n ) : path = " /wm/ s t a t i c f l o w p u s h e r / j s o n " headers = { " Content −type " : " a p p l i c a t i o n / j s o n " , " Accept " : " a p p l i c a t i o n / j s o n " , }

body = j s o n . dumps ( data )

conn = h t t p l i b . HTTPConnection ( s e l f . s e r v e r , 8 0 8 0 ) conn . r e q u e s t ( a c t i o n , path , body , headers ) response = conn . g e t r e s p o n s e ( )

r e t = ( response . s t a t u s , response . reason , response . read ( ) )

(41)
(42)

’ s w i t c h ’ : " 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 4 " , " name " : " flow_mod_11 " , " c o o k i e " : " 0 " , " p r i o r i t y " : " 32768 " , " e t h _ t y p e " : " 0 x0800 " , " i p v 4 _ d s t " : " 1 0 . 0 . 0 . 1 / 3 2 " , " i n _ p o r t " : " 3 " , " a c t i v e " : " t r u e " , " a c t i o n s " : " output =1 " } flow12 = { ’ s w i t c h ’ : " 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 4 " , " name " : " flow_mod_12 " , " c o o k i e " : " 0 " , " p r i o r i t y " : " 32768 " , " e t h _ t y p e " : " 0 x0800 " , " i p v 4 _ d s t " : " 1 0 . 0 . 0 . 2 / 3 2 " , " i n _ p o r t " : " 3 " , " a c t i v e " : " t r u e " , " a c t i o n s " : " output =2 " } # Pushing t h e flows t o t h e s w i t c h e s pusher .s e t( flow1 ) pusher .s e t( flow2 ) pusher .s e t( flow3 ) pusher .s e t( flow4 ) pusher .s e t( flow5 ) pusher .s e t( flow6 ) pusher .s e t( flow7 ) pusher .s e t( flow8 ) pusher .s e t( flow9 ) pusher .s e t( flow10 ) pusher .s e t( flow11 ) pusher .s e t( flow12 )

C.3

switch5.py

Listing 19: switch5.py # ! / usr/bin/env python import h t t p l i b import j s o n

#The d e f i n i t i o n s and t h e v a r i a b l e s were taken from # f l o o d l i g h t c o n t r o l l e r s o f f i c i a l webbsite . # I only changed and added t h e flows .

c l a s s S t a t i c F l o w P u s h e r (o b j e c t) : def _ _ i n i t _ _ ( s e l f , s e r v e r ) : s e l f . s e r v e r = s e r v e r def g e t ( s e l f , data ) : r e t = s e l f . r e s t _ c a l l ( { } , "GET" ) r e t u r n j s o n . l o a d s ( r e t [ 2 ] ) def s e t( s e l f , data ) : r e t = s e l f . r e s t _ c a l l ( data , "POST" ) r e t u r n r e t [ 0 ] == 200

def remove ( s e l f , o b j t y p e , data ) : r e t = s e l f . r e s t _ c a l l ( data , "DELETE" ) r e t u r n r e t [ 0 ] == 200 def r e s t _ c a l l ( s e l f , data , a c t i o n ) : path = " /wm/ s t a t i c f l o w p u s h e r / j s o n " headers = { " Content −type " : " a p p l i c a t i o n / j s o n " , " Accept " : " a p p l i c a t i o n / j s o n " , }

body = j s o n . dumps ( data )

conn = h t t p l i b . HTTPConnection ( s e l f . s e r v e r , 8 0 8 0 ) conn . r e q u e s t ( a c t i o n , path , body , headers ) response = conn . g e t r e s p o n s e ( )

r e t = ( response . s t a t u s , response . reason , response . read ( ) )

(43)
(44)

References

Related documents

In the part of the questionnaire that is focused on customers’ overall attitude respondents answered a question: “When you look at the 2 designs of e-mail, which are

Lucas DFA method - Manual Handling Analysis Handling Index

This thesis is an effort to analyze the importance of business network partners for successful participation in trade shows for small firms to grow more in international

Orphan innovations developed on individual level follow the same process and alternatives as stated for when orphan innovations have occurred at project level due to a

D exp = ∑ D 90 ( wd, ws ) · Probability ( wd, ws ) (3.17) In contrast to the design wind conditions in the strain measurement data not every combination of wind speed and wind

The lack of understanding of the ice throw phenomenon among authorities leads to the fact that there is no coherence in the applied ice throw mitigation policies in various

Dougherty Introduction to Econometrics (second edition 2002, Oxford University Press, Oxford), They may be reproduced freely provided that this attribution is retained..

Ingold 2007b; Latour, 1988, 2005; Orlikowski, 2007; Scott & Orlikowski, 2014), I argue in this thesis that traditional dualistic assumptions, and the consequential tendency