Created
July 30, 2013 16:34
-
-
Save wh5a/6114586 to your computer and use it in GitHub Desktop.
SDN Module 6 Pyresonance Load Balancer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
''' | |
Coursera: | |
- Software Defined Networking (SDN) course | |
-- Module 7 Programming Assignment | |
Professor: Nick Feamster | |
Teaching Assistant: Muhammad Shahbaz | |
''' | |
################################################################################ | |
# Resonance Project # | |
# Resonance implemented with Pyretic platform # | |
# author: Hyojoon Kim ([email protected]) # | |
# author: Nick Feamster ([email protected]) # | |
################################################################################ | |
from pyretic.lib.corelib import * | |
from pyretic.lib.std import * | |
from pyretic.examples.load_balancer import * | |
class ResonancePolicy(): | |
state_policy_map = {} | |
def __init__(self): | |
self.state_policy_map['default'] = self.default_policy | |
def get_policy(self, state): | |
if self.state_policy_map.has_key(state): | |
return self.state_policy_map[state] | |
else: | |
return self.default_policy | |
""" Default state policy """ | |
def default_policy(self): | |
return drop | |
class LBPolicy(ResonancePolicy): | |
def __init__(self, fsm): | |
self.fsm = fsm | |
def portA_policy(self): | |
public_ip = IP('10.0.0.100') | |
client_ips = [IP('10.0.0.1')] | |
repeating_R = [IP('10.0.0.2')] | |
# This will replace the incoming packet[src=10.0.0.1, dst=10.0.0.100] to packet[src=10.0.0.1, dst=10.0.0.2] and | |
# and packet[src=10.0.0.1, dst=10.0.0.2] back to packet[src=10.0.0.1, dst=10.0.0.100] | |
return rewrite(zip(client_ips, repeating_R), public_ip) | |
def portB_policy(self): | |
public_ip = IP('10.0.0.100') | |
client_ips = [IP('10.0.0.1')] | |
repeating_R = [IP('10.0.0.3')] | |
# This will replace the incoming packet[src=10.0.0.1, dst=10.0.0.100] to packet[src=10.0.0.1, dst=10.0.0.3] and | |
# and packet[src=10.0.0.1, dst=10.0.0.3] back to packet[src=10.0.0.1, dst=10.0.0.100] | |
return rewrite(zip(client_ips, repeating_R), public_ip) | |
def default_policy(self): | |
# Add the logic to return the right policy (i.e., portA_policy or portB_policy | |
# based on the state of the FSMs) | |
#hint: | |
# 1. get the list of hosts in portA state | |
aHosts = self.fsm.get_portA_hosts() | |
# 2. match the incoming packet's source and destination ip against that list of hosts (using pyretic predicates i.e., "match", "modify", and "if_" etc) | |
matchAHosts = parallel([match(srcip=aHost) for aHost in aHosts]) + parallel([match(dstip=aHost) for aHost in aHosts]) | |
# 3. if there is a match apply portA policy else apply portB policy | |
return if_(matchAHosts, self.portA_policy(), self.portB_policy()) | |
# return (matchAHosts >> self.portA_policy()) + (~matchAHosts >> self.portB_policy()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
''' | |
Coursera: | |
- Software Defined Networking (SDN) course | |
-- Module 3 Programming Assignment | |
Professor: Nick Feamster | |
Teaching Assistant: Muhammad Shahbaz | |
''' | |
################################################################################ | |
# Resonance Project # | |
# Resonance implemented with Pyretic platform # | |
# author: Hyojoon Kim ([email protected]) # | |
# author: Nick Feamster ([email protected]) # | |
################################################################################ | |
from pyretic.lib.corelib import * | |
from pyretic.lib.std import * | |
import json | |
from multiprocessing import Process, Manager | |
DEBUG = True | |
EVENT_TYPE_LB = 0 | |
class ResonanceStateMachine(): | |
def __init__(self): | |
manager = Manager() | |
self.flow_state_map = manager.dict() | |
self.flow_state_map.clear() | |
return | |
def transition_callback(self, cb, arg): | |
self.cb = cb | |
self.cbarg = arg | |
def parse_json(self, msg): | |
json_msg = json.loads(msg) | |
event_msg = json_msg['event'] | |
state = event_msg['data'] | |
msgtype = event_msg['event_type'] | |
host = state['data'] | |
next_state = state['value'] | |
return (msgtype, host, next_state) | |
def handleMessage(self, msg, queue): | |
msgtype, host, next_state = self.parse_json(msg) | |
if DEBUG == True: | |
print "HANDLE", next_state, host | |
# In the parent class, we just do the transition. | |
# We don't type check the message type | |
self.state_transition(next_state, host, queue) | |
def check_state(self, host): | |
host_str = str(host) | |
if self.flow_state_map.has_key(host_str): | |
state = self.flow_state_map[host_str] | |
else: | |
state = 'default' | |
if DEBUG == True: | |
print "check_state", host_str, state | |
return state | |
def get_hosts_in_state(self, state): | |
hosts = [] | |
for host in self.flow_state_map.keys(): | |
if (self.flow_state_map[host] == state): | |
hosts.append(host) | |
return hosts | |
def state_transition(self, next_state, host, queue, previous_state=None): | |
state = self.check_state(host) | |
if previous_state is not None: | |
if state != previous_state: | |
print 'Given previous state is incorrect! Do nothing.' | |
return | |
else: | |
print "state_transition ->", str(host), next_state | |
queue.put('transition') | |
self.flow_state_map[str(host)] = next_state | |
if DEBUG == True: | |
print "CURRENT STATES: ", self.flow_state_map | |
# --------- Update the code below ------------ | |
class LBStateMachine(ResonanceStateMachine): | |
def handleMessage(self, msg, queue): | |
msgtype, host, next_state = self.parse_json(msg) | |
# Add the state transition logic | |
# hint: use the state_transition function | |
if msgtype == EVENT_TYPE_LB: | |
self.state_transition(next_state, host, queue) | |
def get_portA_hosts(self): | |
return self.get_hosts_in_state('portA') | |
def get_portB_hosts(self): | |
return self.get_hosts_in_state('portB') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment