Permalink
Browse files

pox/rfproxy: Add support for RouteMod

Signed-off-by: Joe Stringer <joestringernz@gmail.com>
  • Loading branch information...
1 parent d9a605a commit 79eafafeb4346aa8060f68768acd70260b642a6c @camowen camowen committed with joestringer Jan 9, 2013
Showing with 93 additions and 1 deletion.
  1. +11 −1 pox/ext/rfproxy.py
  2. +82 −0 rflib/openflow/rfofmsg.py
View
@@ -222,7 +222,17 @@ def process(self, from_, to, channel, msg):
msg.get_address(), msg.get_netmask(),
msg.get_src_hwaddress(), msg.get_dst_hwaddress(),
msg.get_dst_port())
-
+ elif type_ == ROUTE_MOD:
+ try:
+ ofmsg = create_flow_mod(msg)
+ except Warning as e:
+ log.info("Error creating FlowMod: {}" % str(e))
+ if send_of_msg(msg.get_id(), ofmsg) == SUCCESS:
+ log.info("routemod sent to datapath (dp_id=%s)",
+ format_id(msg.get_id()))
+ else:
+ log.info("Error sending routemod to datapath (dp_id=%s)",
+ format_id(msg.get_id()))
if type_ == DATA_PLANE_MAP:
table.update_dp_port(msg.get_dp_id(), msg.get_dp_port(),
msg.get_vs_id(), msg.get_vs_port())
@@ -1,7 +1,17 @@
+import binascii
+import logging
+from socket import inet_aton
+
from pox.openflow.libopenflow_01 import *
from pox.lib.addresses import *
+from pox.core import core
from rflib.defs import *
+from rflib.types.Match import *
+from rflib.types.Action import *
+from rflib.types.Option import *
+
+log = core.getLogger("rfproxy")
def ofm_match_dl(ofm, match, value):
ofm.match.wildcards &= ~match;
@@ -83,6 +93,78 @@ def create_config_msg(operation):
return ofm
+def create_flow_mod(routemod):
+ ofm = ofp_flow_mod()
+
+ mod = routemod.get_mod()
+
+ if mod == RMT_ADD:
+ ofm.command = OFPFC_ADD
+ elif mod == RMT_DELETE:
+ ofm.command = OFPFC_DELETE_STRICT
+ else:
+ log.error("Unrecognised RouteMod Type (type: %s)" % (mod))
+ return None
+
+ for match in routemod.get_matches():
+ match = Match.from_dict(match)
+ if match._type == RFMT_IPV4:
+ ofm_match_dl(ofm, OFPFW_DL_TYPE, ETHERTYPE_IP)
+ # OpenFlow 1.0 doesn't support arbitrary netmasks, so
+ # TODO calculate netmask CIDR prefix better than below...
+ nmprefix = bin(int(binascii.b2a_hex(inet_aton(match.get_value()[1])), 16))[2:].find('0')
+ nmprefix = 32 if nmprefix == -1 else nmprefix
+ ofm_match_nw(ofm, OFPFW_NW_DST_MASK, 0, 0, 0, str(match.get_value()[0]))
+ ofm.match.wildcards &= ~parseCIDR(str(match.get_value()[0]) + "/" + str(nmprefix))[1]
+ ofm.match.set_nw_dst(match.get_value()[0])
+ elif match._type == RFMT_ETHERNET:
+ ofm_match_dl(ofm, OFPFW_DL_DST, match.get_value())
+ elif match._type == RFMT_ETHERTYPE:
+ ofm_match_dl(ofm, OFPFW_DL_TYPE, match.get_value())
+ elif match._type == RFMT_NW_PROTO:
+ ofm_match_nw(ofm, OFPFW_NW_PROTO, match.get_value(), 0, 0, 0)
+ elif match._type == RFMT_TP_SRC:
+ ofm_match_tp(ofm, OFPFW_TP_SRC, match.get_value(), 0)
+ elif match._type == RFMT_TP_DST:
+ ofm_match_tp(ofm, OFPFW_TP_DST, 0, match.get_value())
+ elif match.optional():
+ log.debug("Dropping unsupported Match (type: %s)" % option._type)
+ else:
+ log.warning("Failed to serialise Match (type: %s)" % option._type)
+ return None
+
+
+ for action in routemod.get_actions():
+ action = Action.from_dict(action)
+ if action._type == RFAT_OUTPUT:
+ ofm.actions.append(ofp_action_output(port = action.get_value()))
+ elif action._type == RFAT_SET_ETH_SRC:
+ ofm.actions.append(ofp_action_dl_addr(type=OFPAT_SET_DL_SRC, dl_addr=EthAddr(action.get_value())))
+ elif action._type == RFAT_SET_ETH_DST:
+ ofm.actions.append(ofp_action_dl_addr(type=OFPAT_SET_DL_DST, dl_addr=EthAddr(action.get_value())))
+ elif action.optional():
+ log.debug("Dropping unsupported Action (type: %s)" % option._type)
+ else:
+ log.warning("Failed to serialise Action (type: %s)" % option._type)
+ return None
+
+ for option in routemod.get_options():
+ option = Option.from_dict(option)
+ if option._type == RFOT_PRIORITY:
+ ofm.priority = option.get_value()
+ elif option._type == RFOT_IDLE_TIMEOUT:
+ ofm.idle_timeout = option.get_value()
+ elif option._type == RFOT_HARD_TIMEOUT:
+ ofm.hard_timeout = option.get_value()
+ elif option.optional():
+ log.debug("Dropping unsupported Option (type: %s)" % option._type)
+ else:
+ log.warning("Failed to serialise Option (type: %s)" % option._type)
+ return None
+
+
+ return ofm
+
def create_flow_install_msg(ip, mask, srcMac, dstMac, dstPort):
ofm = ofp_flow_mod()

0 comments on commit 79eafaf

Please sign in to comment.