Composing SDN Policies (text)

by Sasha Shkrebets last modified Mar 20, 2023 08:06 AM
We are continuing our module on programming SDNs, and we are now starting a lesson on composing SDN control. This lesson will have two parts. The first part of the lesson will talk about the concepts of composing SDN control.
Welcome back.
We are continuing our module on programming SDNs, and
we are now starting a lesson on composing SDN control.
This lesson will have two parts.
The first part of the lesson will
talk about the concepts of composing SDN control.
The second part of the lesson will dive into a programing language
called Pyretic which allows a programmer to compose SDN control.
Networks perform many tasks.
And if we think about how we might write an application that
sits on top of an SDM controller that performs the wide variety of
network tasks that an operator might want to perform, we might first
consider writing a single monolithic application
that performs all of those functions together.
For example, the application might monitor or
count the traffic volumes for particular traffic flows.
It might route the traffic to different locations.
It might apply firewalling policies.
And it might also try to load balance the traffic across different servers.
Now, the problem with a single monolithic application like this is
it becomes very hard to program, test, debug, reuse, and port.
Imagine, for example, that we wanted to test a
certain component or reuse a particular component from this application.
Well, suddenly we have a very big control program that is relatively unmanageable.
A solution to this problem is to modularize the control so that
the programmer writes separate modules, each
of which performs a distinct operation.
So, the operator might write a module that performs monitoring that is separate
from the module that performs routing, firewalling, and so forth.
This is much easier to program, test, and debug.
And it's also easier for a programmer to
reuse or port different components of this control application.
However, getting the modules to play nice with one another is complicated.
The controller has to perform some amount of arbitration among these
modules because they're not just tenants that reside on the same control platform.
In a multitenant environment, each module would control a
different portion of the traffic guaranteeing that they wouldn't interfere.
So, it would be relatively easy to partition the rule
space, link bandwidth, and various network events across these different modules.
However, in a control program, such as the one that
we are talking about, different modules affect the same traffic.
For example, the same traffic that's being monitored is
also subjected to the routing, firewalling, and load balancing policies.
So, each of these modules partially specifies how to handle traffic.
And yet, these modules need to be combined, somehow, into a
single complete control application that correctly
implements the network operator's intended policy.
The approach to this problem is to apply what is called composition.
There are two types of composition operators.
One is parallel composition where the
control module performs multiple operations simultaneously.
For example, the operator might want the control program
to perform counting and forwarding on the same traffic stream.
The second type of composition is called sequential composition.
In this case, we perform one operation and then the next.
For example, the network operator might want to first apply firewalling rules
to the set of traffic before sending in the traffic through a learning switch.
Let's now look at some example applications
that use both parallel composition and sequential composition.
Let's first have a look at parallel composition.
Suppose that we would like to write a control
program that both monitors traffic arriving on a particular source
IP address and routes the traffic to different output
ports depending on the value of the destination IP address.
Now, in this case, we want both of these operations to happen at the same time.
So, we apply parallel composition which produces a set of rules that
effectively allows both of these operations to occur simultaneously.
Note that, with this paradigm, we do not have
to worry about which OpenFlow rules to install first.
The controller platform automatically takes care of that for us.
Let's now take a look at
an example application that requires sequential composition.
Suppose that we would like to implement a server load balancer whereby the
load balancer spreads client traffic across multiple server replicas.
There may be a public IP address for the service, for
example, in this case 1.2.3.4, to which clients send their traffic.
That load balancer then splits the traffic based on the client's source IP address
and then rewrites the destination server IP address based on the client's IP.
After rewriting the server's IP address, the load
balancer then routes the traffic to the appropriate replica.
This application requires what is known as sequential composition.
First, we need to perform the load balancing
operations of matching on a particular source IP address
and, subsequently, rewriting the destination IP address accordingly, and
then forwarding the traffic to the appropriate output port.
As before, the controller composes these rules into a single
set of rules that can be installed in the switches.
Traffic can also be divided over modules.
We can use certain predicates to specify which traffic traverses which
modules based on both the input port and other fields in the packet header.
For example, we can use a predicate to specify that if the destination port is
not port 80, then we would like to perform monitoring and routing in parallel.
But if the destination port is port 80,
we'd like to perform load balancing followed by routing.
Note that each module only partially specifies what should
happen to traffic, leaving some flexibility to other modules.
This avoids tying a particular module to a specific
setting, thus making the modules more self-contained and portable.
For example, when we applied load
balancing followed by routing, the load balancer
did not need to know how routing was being performed in that network.
Therefore, if we wanted to use the load
balancer in a different network, it would be relatively
easy to reuse that component, even in a network
where routing was performed in a completely different way.
Another important feature of policy composition is that each
module should have an abstract view of the topology.
This abstract topology can implicitly encode constraints.
For example, if the policy is intended
to prevent two hosts from communicating with one
another, we simply ensure that the logical
typology has no path between those two hosts.
The logical typology looks just like a normal network.
But it prevents each module from overstepping or performing actions
on parts of the network over which it has no purview.
In other words, the logical typology hides irrelevant details from the modules.
So, for example, the load balancer would not see such details
as the internal topology, or any routing changes, or any routing changes.
In summary, SDN control programs perform many tasks on the same traffic.
The requirements for composing SDN control are
compositional operators that specify how to compose
policies and a logical switch abstraction that
hides irrelevant details from each of these modules.
In the next part of the lesson, we will look
at a language called Pyretic that is built on POX.
Pyretic implements both compositional operators
and a logical switch abstraction.
Navigation